in unittest/lib/old-testRsa.cpp [859:977]
VOID testRsaRunAlgs()
{
BYTE rbInput[TEST_RSA_MAX_NUMOF_BYTES] = { 0 };
SIZE_T cbInput = 0;
BYTE rbOutput[TEST_RSA_MAX_NUMOF_BYTES] = { 0 };
SIZE_T cbOutput = 0;
BYTE rbExtra[TEST_RSA_MAX_NUMOF_BYTES] = { 0 };
SIZE_T cbExtra = 0;
PSYMCRYPT_HASH pHashAlgorithm = NULL;
FuncRandFn randFunc = NULL;
FuncDataFn queryFn = NULL; // Encryption/Sign function
FuncDataFn replyFn = NULL; // Decryption/Verify function
UINT32 iImplFrom = 0;
UINT32 iImplTo = 0;
vprint( g_verbose, "\n");
for( std::vector<AlgorithmImplementation *>::iterator i = g_AlgList.begin(); i != g_AlgList.end(); i++ )
{
iImplFrom = ImplToInd( *i );
vprint( g_verbose, " > Algorithm: %s From: %s\n", (*i)->m_algorithmName.c_str(), g_ImplNames[iImplFrom] );
randFunc = ((FunctionalRsaImplementation *)(*i))->m_funcRandFunction;
CHECK( randFunc != NULL, "TestRsa: No randomizing function.\n");
queryFn = ((FunctionalRsaImplementation *)(*i))->m_funcQueryFunction;
CHECK( queryFn != NULL, "TestRsa: No encryption / signing function.\n");
for( std::vector<AlgorithmImplementation *>::iterator j = g_AlgList.begin(); j != g_AlgList.end(); j++ )
{
// Run tests if the algorithms are the same and at least one implementation is SymCrypt
if (( (*i)->m_algorithmName == (*j)->m_algorithmName ) &&
( ((*i)->m_implementationName == ImpSc::name) || ((*j)->m_implementationName == ImpSc::name) ))
{
// If the algorithm is sign PKCS1 and the verifying implementation is CNG then
// there is a bug in CNG's verification code in the case of small key, big hash algorithm,
// and second OID in the list (e.g. 732 bits / SHA512 / 2nd OID of size 0xb bytes).
// Then the first OID in the list with size 0xd bytes overflows the buffer and CNG
// aborts (erroneously) the verification without checking the second OID. Therefore
// we skip the scenario SymCrypt Signing => Cng Verification.
if ( ((*i)->m_algorithmName == AlgRsaSignPkcs1::name) &&
((*i)->m_implementationName == ImpSc::name) &&
((*j)->m_implementationName == ImpCng::name) )
{
continue;
}
iImplTo = ImplToInd( *j );
replyFn = ((FunctionalRsaImplementation *)(*j))->m_funcReplyFunction;
CHECK( replyFn != NULL, "TestRsa: No decryption/verify function.\n");
vprint( g_verbose, " >>>> To: %s\n", g_ImplNames[iImplTo] );
for (UINT32 entry = 0; entry < TEST_RSA_NUMOF_ENTRIES; entry++)
{
// If the algorithm is sign PSS and the bitsize is not a multiple of 8, then
// Cng cannot process it (due to the Cng PSS padding accepting only byte aligned values).
// In these cases skip the tests.
if ( ((*i)->m_algorithmName == AlgRsaSignPss::name) &&
(g_KeyEntries[entry].bitSize % 8 != 0) &&
( ((*i)->m_implementationName == ImpCng::name) || ((*j)->m_implementationName == ImpCng::name) ) )
{
continue;
}
for (UINT32 nTries = 0; nTries<TEST_RSA_NUMOF_RANDOM_TRIES; nTries++)
{
// For all algorithm pass in the bitsize of the modulus in cbExtra.
// Currently, raw encrypt and sign PSS use it:
// For raw encrypt the randomizing function can create an input that is at the edge of the
// modulus' bits.
// For PSS sign it can pick a salt size that is at the edge of the available buffer.
cbExtra = g_KeyEntries[entry].bitSize;
(*randFunc)(
g_KeyEntries[entry].keySize,
rbInput,
&cbInput,
&cbOutput,
rbExtra,
&cbExtra,
&pHashAlgorithm );
(*queryFn)(
g_KeyEntries[entry].keySize,
g_KeyEntries[entry].pKeys[iImplFrom],
rbInput,
cbInput,
rbOutput,
cbOutput,
rbExtra,
cbExtra,
pHashAlgorithm );
(*replyFn)(
g_KeyEntries[entry].keySize,
g_KeyEntries[entry].pKeys[iImplTo],
rbInput,
cbInput,
rbOutput,
cbOutput,
rbExtra,
cbExtra,
pHashAlgorithm );
(*i)->m_nResults ++;
}
}
}
}
}
}