template VOID algImpTestInteropImportKeyEntryBuffers()

in unittest/lib/testDl_cng.cpp [384:539]


template<> VOID algImpTestInteropImportKeyEntryBuffers< ImpCng >(PBYTE pKeyEntry)
{
    PTEST_DL_KEYENTRY pKE = (PTEST_DL_KEYENTRY) pKeyEntry;

    NTSTATUS ntStatus = STATUS_SUCCESS;
    BCRYPT_ALG_HANDLE hAlg = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;

    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 };
    SIZE_T cbDhKeyBlob = 0;

    CHECK(pKE->pGroups[IMPCNG_INDEX]==NULL, "?");
    CHECK(pKE->pKeysDsa[IMPCNG_INDEX]==NULL, "?");
    CHECK(pKE->pKeysDhA[IMPCNG_INDEX]==NULL, "?");
    CHECK(pKE->pKeysDhB[IMPCNG_INDEX]==NULL, "?");

    ntStatus = BCryptOpenAlgorithmProvider(
                    &hAlg,
                    BCRYPT_DSA_ALGORITHM,
                    MS_PRIMITIVE_PROVIDER,
                    0 );
    CHECK3( ntStatus == STATUS_SUCCESS, "BCryptOpenAlgorithmProvider with 0x%x", ntStatus );

    // Fix DSA key blob
    if (pKE->nBitsOfP>1024)
    {
        pDsaKeyBlobV2 = (BCRYPT_DSA_KEY_BLOB_V2 *) &rbKeyBlob[0];
        pDsaKeyBlobV2->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC_V2;
        pDsaKeyBlobV2->cbKey = pKE->cbPrimeP;
        pDsaKeyBlobV2->hashAlgorithm = DSA_HASH_ALGORITHM_SHA256;        // Hard-coded for CNG
        pDsaKeyBlobV2->standardVersion = DSA_FIPS186_3;
        pDsaKeyBlobV2->cbSeedLength = pKE->cbPrimeQ;
        pDsaKeyBlobV2->cbGroupSize = pKE->cbPrimeQ;

        CHECK( testDlCng_HashAlgEnumToScHash(pDsaKeyBlobV2->hashAlgorithm)==pKE->pHashAlgorithm, "?" );
        CHECK( testDlCng_FipsVersionEnumToScFipsVersion(pDsaKeyBlobV2->standardVersion)==pKE->eFipsStandard, "?" );

        cbTmp = sizeof(BCRYPT_DSA_KEY_BLOB_V2);

        // Set the gencounter
        testInteropReverseMemCopy(&(pDsaKeyBlobV2->Count[0]), (PBYTE)&(pKE->dwGenCounter), sizeof(UINT32));

        memcpy( &rbKeyBlob[cbTmp], pKE->rbSeed,   pKE->cbPrimeQ  ); cbTmp += pKE->cbPrimeQ;
        memcpy( &rbKeyBlob[cbTmp], pKE->rbPrimeQ, pKE->cbPrimeQ  ); cbTmp += pKE->cbPrimeQ;
        memcpy( &rbKeyBlob[cbTmp], pKE->rbPrimeP, pKE->cbPrimeP  ); cbTmp += pKE->cbPrimeP;
        memcpy( &rbKeyBlob[cbTmp], pKE->rbGenG,   pKE->cbPrimeP  ); cbTmp += pKE->cbPrimeP;

        memcpy( &rbKeyBlob[cbTmp], pKE->rbPublicKeyA,   pKE->cbPrimeP  );   cbTmp += pKE->cbPrimeP;
        memcpy( &rbKeyBlob[cbTmp], pKE->rbPrivateKeyA,  pKE->cbPrimeQ  );   cbTmp += pKE->cbPrimeQ;
    }
    else
    {
        pDsaKeyBlobV1 = (BCRYPT_DSA_KEY_BLOB *) &rbKeyBlob[0];
        pDsaKeyBlobV1->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC;
        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

        // Set Q, seed and gencounter
        testInteropReverseMemCopy( &(pDsaKeyBlobV1->Count[0]), (PBYTE)&(pKE->dwGenCounter), sizeof(UINT32) );
        memcpy( &(pDsaKeyBlobV1->Seed[0]), pKE->rbSeed, TEST_DL_DSA_V1_GROUPSIZE );
        memcpy( &(pDsaKeyBlobV1->q[0]), pKE->rbPrimeQ, TEST_DL_DSA_V1_GROUPSIZE  );

        cbTmp = sizeof(BCRYPT_DSA_KEY_BLOB);

        memcpy( &rbKeyBlob[cbTmp], pKE->rbPrimeP, pKE->cbPrimeP  ); cbTmp += pKE->cbPrimeP;
        memcpy( &rbKeyBlob[cbTmp], pKE->rbGenG,   pKE->cbPrimeP  ); cbTmp += pKE->cbPrimeP;

        memcpy( &rbKeyBlob[cbTmp], pKE->rbPublicKeyA,   pKE->cbPrimeP  );   cbTmp += pKE->cbPrimeP;
        memcpy( &rbKeyBlob[cbTmp], pKE->rbPrivateKeyA,  pKE->cbPrimeQ  );   cbTmp += pKE->cbPrimeQ;
    }

    cbKeyBlob = (ULONG)cbTmp;

    // Import the key
    ntStatus = BCryptImportKeyPair(
                    hAlg,
                    NULL,       // Import key
                    BCRYPT_DSA_PRIVATE_BLOB,
                    &hKey,
                    rbKeyBlob,
                    cbKeyBlob,
                    0 );
    CHECK3( ntStatus == STATUS_SUCCESS, "BCryptImportKeyPair failed with 0x%x", ntStatus );

    pKE->pKeysDsa[IMPCNG_INDEX] = (PBYTE) hKey;

    ntStatus = BCryptCloseAlgorithmProvider( hAlg, 0 );
    CHECK( ntStatus == STATUS_SUCCESS, "?" );

    // DH key A
    ntStatus = BCryptOpenAlgorithmProvider(
                    &hAlg,
                    BCRYPT_DH_ALGORITHM,
                    MS_PRIMITIVE_PROVIDER,
                    0 );
    CHECK3( ntStatus == STATUS_SUCCESS, "BCryptOpenAlgorithmProvider with 0x%x", ntStatus );

    // Fix DH blob for key A
    testDlCng_DsaToDhBlob( pKE->nBitsOfP, rbKeyBlob, rbDhKeyBlob, &cbDhKeyBlob );

    ntStatus = BCryptImportKeyPair(
                    hAlg,
                    NULL,       // Import key
                    BCRYPT_DH_PRIVATE_BLOB,
                    &hKey,
                    rbDhKeyBlob,
                    (ULONG) cbDhKeyBlob,
                    BCRYPT_NO_KEY_VALIDATION );
    CHECK3( ntStatus == STATUS_SUCCESS, "BCryptImportKeyPair failed with 0x%x", ntStatus );

    pKE->pKeysDhA[IMPCNG_INDEX] = (PBYTE) hKey;

    // Fix DH blob for key B
    pDhKeyBlob = (BCRYPT_DH_KEY_BLOB *) &rbDhKeyBlob[0];

    cbTmp = sizeof(BCRYPT_DH_KEY_BLOB) + 2*pDhKeyBlob->cbKey;       // Move over the P and G

    // Copy the public key
    CHECK( pDhKeyBlob->cbKey==pKE->cbPrimeP, "?" );
    memcpy( &rbDhKeyBlob[cbTmp], pKE->rbPublicKeyB,   pKE->cbPrimeP  );   cbTmp += pKE->cbPrimeP;

    // For the private key pad with zeros if needed
    SymCryptWipe(&rbDhKeyBlob[cbTmp],  pDhKeyBlob->cbKey);

    // Set the key in the correct location
    CHECK( pKE->cbPrimeP >= pKE->cbPrivateKeyB, "?");
    cbTmp += (pKE->cbPrimeP - pKE->cbPrivateKeyB);
    memcpy( &rbDhKeyBlob[cbTmp], pKE->rbPrivateKeyB,  pKE->cbPrivateKeyB  );   cbTmp += pKE->cbPrivateKeyB;

    ntStatus = BCryptImportKeyPair(
                    hAlg,
                    NULL,       // Import key
                    BCRYPT_DH_PRIVATE_BLOB,
                    &hKey,
                    rbDhKeyBlob,
                    (ULONG) cbDhKeyBlob,
                    BCRYPT_NO_KEY_VALIDATION );
    CHECK3( ntStatus == STATUS_SUCCESS, "BCryptImportKeyPair failed with 0x%x", ntStatus );

    pKE->pKeysDhB[IMPCNG_INDEX] = (PBYTE) hKey;

    ntStatus = BCryptCloseAlgorithmProvider( hAlg, 0 );
    CHECK( ntStatus == STATUS_SUCCESS, "?" );
}