DllExport TpmAttWrapPlatformKey()

in PCPTool.v11/dll/AttestationApi.cpp [3742:3884]


DllExport TpmAttWrapPlatformKey(
    NCRYPT_KEY_HANDLE hInKey,
    BCRYPT_KEY_HANDLE hStorageKey,
    UINT32 tpmVersion,
    UINT32 keyUsage,
    _In_reads_opt_(cbPIN) PBYTE pbPIN,
    UINT32 cbPIN,
    UINT32 pcrMask,
    UINT16 pcrAlgId,
    _In_reads_opt_(cbPcrTable) PBYTE pcrTable,
    UINT32 cbPcrTable,
    _Out_writes_to_opt_(cbOutput, *pcbResult) PBYTE pbOutput,
    UINT32 cbOutput,
    _Deref_out_range_(0,cbOutput) PUINT32 pcbResult
    )
{
    HRESULT hr = S_OK;
    UINT32 cbRequired = 0;
    PBYTE pbKeyPair = NULL;
    UINT32 cbKeyPair = 0;
    UINT32 exportPolicy = 0;
    BOOLEAN tUsageAuthSet = FALSE;
    BYTE usageAuth[SHA1_DIGEST_SIZE] = {0};

    // Check the parameters
    if((hInKey == NULL) ||
       (hStorageKey == NULL) ||
       ((pcrTable != NULL) && (cbPcrTable < AVAILABLE_PLATFORM_PCRS * SHA1_DIGEST_SIZE)) ||
       ((tpmVersion != TPM_VERSION_20) && (tpmVersion != TPM_VERSION_12)) ||
       ((keyUsage & 0x0000ffff & ~(NCRYPT_PCP_GENERIC_KEY | NCRYPT_PCP_STORAGE_KEY)) != 0))
    {
        hr = E_INVALIDARG;
        goto Cleanup;
    }

    // Is the InKey exportable?
    if(FAILED(hr = HRESULT_FROM_WIN32(NCryptGetProperty(
                                        hInKey,
                                        NCRYPT_EXPORT_POLICY_PROPERTY ,
                                        (PUCHAR)&exportPolicy,
                                        sizeof(exportPolicy),
                                        (PULONG)&cbRequired,
                                        0))))
    {
        goto Cleanup;
    }

    if(((exportPolicy & NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG) == 0) ||
       ((exportPolicy & NCRYPT_ALLOW_EXPORT_FLAG) == 0))
    {
        hr = E_INVALIDARG;
        goto Cleanup;
    }

    // Export the key pair
    if(FAILED(hr = HRESULT_FROM_WIN32(NCryptExportKey(
                                        hInKey,
                                        NULL,
                                        BCRYPT_RSAPRIVATE_BLOB,
                                        NULL,
                                        NULL,
                                        0,
                                        (PDWORD)&cbKeyPair,
                                        0))))
    {
        goto Cleanup;
    }

    if(FAILED(hr = AllocateAndZero((PVOID*)&pbKeyPair, cbKeyPair)))
    {
        goto Cleanup;
    }

    if(FAILED(hr = HRESULT_FROM_WIN32(NCryptExportKey(
                                        hInKey,
                                        NULL,
                                        BCRYPT_RSAPRIVATE_BLOB,
                                        NULL,
                                        pbKeyPair,
                                        cbKeyPair,
                                        (PDWORD)&cbKeyPair,
                                        0))))
    {
        goto Cleanup;
    }

    // Create the usageAuth from the PIN
    if((pbPIN != NULL) && (cbPIN != 0))
    {
        if(FAILED(hr = TpmAttiShaHash(BCRYPT_SHA1_ALGORITHM,
                                      NULL,
                                      0,
                                      pbPIN,
                                      cbPIN,
                                      usageAuth,
                                      sizeof(usageAuth),
                                      &cbRequired)))
        {
            goto Cleanup;
        }
        tUsageAuthSet = TRUE;
    }

    if(tpmVersion == TPM_VERSION_12)
    {
        if(FAILED(hr = WrapPlatformKey12(pbKeyPair,
                                         cbKeyPair,
                                         hStorageKey,
                                         keyUsage,
                                         tUsageAuthSet ? usageAuth : NULL,
                                         tUsageAuthSet ? sizeof(usageAuth) : 0,
                                         pcrMask,
                                         pcrTable,
                                         pbOutput,
                                         cbOutput,
                                         pcbResult)))
        {
            goto Cleanup;
        }
    }
    else if(tpmVersion == TPM_VERSION_20)
    {
        if(FAILED(hr = WrapPlatformKey20(pbKeyPair,
                                         cbKeyPair,
                                         hStorageKey,
                                         keyUsage,
                                         tUsageAuthSet ? usageAuth : NULL,
                                         tUsageAuthSet ? sizeof(usageAuth) : 0,
                                         pcrMask,
                                         pcrAlgId,
                                         pcrTable,
                                         pbOutput,
                                         cbOutput,
                                         pcbResult)))
        {
            goto Cleanup;
        }
    }

Cleanup:
    ZeroAndFree((PVOID*)&pbKeyPair, cbKeyPair);
    return hr;
}