in unittest/lib/testDl_cng.cpp [284:382]
template<> VOID algImpTestInteropFillKeyEntryBuffers< ImpCng >(PBYTE pKeyEntry)
{
PTEST_DL_KEYENTRY pKE = (PTEST_DL_KEYENTRY) pKeyEntry;
NTSTATUS ntStatus = STATUS_SUCCESS;
BCRYPT_DSA_KEY_BLOB * pDsaKeyBlobV1 = NULL;
BCRYPT_DSA_KEY_BLOB_V2 * pDsaKeyBlobV2 = NULL;
BYTE rbKeyBlob[ TEST_DL_MAX_SIZEOF_DSA_BLOB ] = { 0 };
UINT32 cbKeyBlob = 0;
SIZE_T cbTmp = 0;
BCRYPT_DH_KEY_BLOB * pDhKeyBlob = NULL;
BYTE rbDhKeyBlob[ TEST_DL_MAX_SIZEOF_DH_BLOB ] = { 0 };
UINT32 cbDhKeyBlob = 0;
// Export the DSA key
CHECK(pKE->pKeysDsa[IMPCNG_INDEX]!=NULL, "?");
ntStatus = BCryptExportKey(
(BCRYPT_KEY_HANDLE) pKE->pKeysDsa[IMPCNG_INDEX],
NULL, // Export key
BCRYPT_DSA_PRIVATE_BLOB,
(PUCHAR) rbKeyBlob,
sizeof( rbKeyBlob ),
(ULONG*) &cbKeyBlob,
0 );
CHECK3( ntStatus == STATUS_SUCCESS, "BCryptExportKey failed with 0x%x", ntStatus );
if (pKE->nBitsOfP>1024)
{
pDsaKeyBlobV2 = (BCRYPT_DSA_KEY_BLOB_V2 *) &rbKeyBlob[0];
CHECK( pDsaKeyBlobV2->cbKey==pKE->cbPrimeP, "?" );
CHECK( pDsaKeyBlobV2->cbGroupSize==pKE->cbPrimeQ, "?" );
CHECK( pDsaKeyBlobV2->cbSeedLength==pKE->cbPrimeQ, "?" );
CHECK( testDlCng_HashAlgEnumToScHash(pDsaKeyBlobV2->hashAlgorithm)==pKE->pHashAlgorithm, "?" );
CHECK( testDlCng_FipsVersionEnumToScFipsVersion(pDsaKeyBlobV2->standardVersion)==pKE->eFipsStandard, "?" );
// Get the gencounter
testInteropReverseMemCopy((PBYTE)&(pKE->dwGenCounter), &(pDsaKeyBlobV2->Count[0]), sizeof(UINT32));
// Fill each individual buffer
cbTmp = sizeof(BCRYPT_DSA_KEY_BLOB_V2);
memcpy( pKE->rbSeed, &rbKeyBlob[cbTmp], pKE->cbPrimeQ ); cbTmp += pKE->cbPrimeQ;
memcpy( pKE->rbPrimeQ, &rbKeyBlob[cbTmp], pKE->cbPrimeQ ); cbTmp += pKE->cbPrimeQ;
memcpy( pKE->rbPrimeP, &rbKeyBlob[cbTmp], pKE->cbPrimeP ); cbTmp += pKE->cbPrimeP;
memcpy( pKE->rbGenG, &rbKeyBlob[cbTmp], pKE->cbPrimeP ); cbTmp += pKE->cbPrimeP;
memcpy( pKE->rbPublicKeyA, &rbKeyBlob[cbTmp], pKE->cbPrimeP ); cbTmp += pKE->cbPrimeP;
memcpy( pKE->rbPrivateKeyA, &rbKeyBlob[cbTmp], pKE->cbPrimeQ ); cbTmp += pKE->cbPrimeQ;
}
else
{
pDsaKeyBlobV1 = (BCRYPT_DSA_KEY_BLOB *) &rbKeyBlob[0];
CHECK( pDsaKeyBlobV1->cbKey==pKE->cbPrimeP, "?" );
CHECK( TEST_DL_DSA_V1_GROUPSIZE==pKE->cbPrimeQ, "?" ); // Hard-coded for V1 keys in CNG
CHECK( NULL==pKE->pHashAlgorithm, "?" ); // Hard-coded for V1 keys in CNG
CHECK( SYMCRYPT_DLGROUP_FIPS_186_2==pKE->eFipsStandard, "?" ); // Hard-coded for V1 keys in CNG
// Get Q, seed and gencounter
testInteropReverseMemCopy( (PBYTE)&(pKE->dwGenCounter), &(pDsaKeyBlobV1->Count[0]), sizeof(UINT32) );
memcpy( pKE->rbSeed, &(pDsaKeyBlobV1->Seed[0]), TEST_DL_DSA_V1_GROUPSIZE );
memcpy( pKE->rbPrimeQ, &(pDsaKeyBlobV1->q[0]), TEST_DL_DSA_V1_GROUPSIZE );
// Fill each individual buffer
cbTmp = sizeof(BCRYPT_DSA_KEY_BLOB);
memcpy( pKE->rbPrimeP, &rbKeyBlob[cbTmp], pKE->cbPrimeP ); cbTmp += pKE->cbPrimeP;
memcpy( pKE->rbGenG, &rbKeyBlob[cbTmp], pKE->cbPrimeP ); cbTmp += pKE->cbPrimeP;
memcpy( pKE->rbPublicKeyA, &rbKeyBlob[cbTmp], pKE->cbPrimeP ); cbTmp += pKE->cbPrimeP;
memcpy( pKE->rbPrivateKeyA, &rbKeyBlob[cbTmp], pKE->cbPrimeQ ); cbTmp += pKE->cbPrimeQ;
}
// Export the DH key B (we only care about the public and private key)
CHECK(pKE->pKeysDhB[IMPCNG_INDEX]!=NULL, "?");
ntStatus = BCryptExportKey(
(BCRYPT_KEY_HANDLE) pKE->pKeysDhB[IMPCNG_INDEX],
NULL, // Export key
BCRYPT_DH_PRIVATE_BLOB,
(PUCHAR) rbDhKeyBlob,
sizeof( rbDhKeyBlob ),
(ULONG*) &cbDhKeyBlob,
0 );
CHECK3( ntStatus == STATUS_SUCCESS, "BCryptExportKey failed with 0x%x", ntStatus );
pDhKeyBlob = (BCRYPT_DH_KEY_BLOB *) &rbDhKeyBlob[0];
CHECK( pDhKeyBlob->cbKey==pKE->cbPrimeP, "?" );
cbTmp = sizeof(BCRYPT_DH_KEY_BLOB) + 2*pDhKeyBlob->cbKey; // Move over the P and G
pKE->cbPrivateKeyB = pDhKeyBlob->cbKey; // Bigger key
memcpy( pKE->rbPublicKeyB, &rbDhKeyBlob[cbTmp], pDhKeyBlob->cbKey ); cbTmp += pDhKeyBlob->cbKey;
memcpy( pKE->rbPrivateKeyB,&rbDhKeyBlob[cbTmp], pDhKeyBlob->cbKey ); cbTmp += pDhKeyBlob->cbKey;
}