tpm2-software/tpm2-tss

TPM import OpenSSL AES key and persist the key via ESYS APIs

Opened this issue · 0 comments

Hi TSS team,
I am a new in TPM field. I am trying to use TPM to do key protection, encryption and decryption on computer.
I can create RSA primary storage key by TPM engine, and do encryption/decryption operations by the TSS.MSR C++ library (https://github.com/microsoft/TSS.MSR).

Now, I want to use your tpm2-tss software stack to import an AES key generated by OpenSSL, then import that key into TPM device. I am working on Windows (no Linux).
I descript what I am doing:

  1. Create AES key by OpenSSL RAND command, the key is aes_key.bin. I want tpm2-tss can import this key.
  2. Successfully create TCTI context via the TCTILdr, like: rc = Tss2_TctiLdr_Initialize("tbs", &tctiContext);
  3. Successfully initialize the system context, like: rc = Tss2_Sys_Initialize(sysContext, contextSize, tctiContext, &abiVersion);
  4. Successfully retrieve the TPM features by Tss2_Sys_GetCapability.
  5. Create a primary key to protect imported key.
  6. Read aes_key.bin file into std::vector
  7. import and load the key file on tpm2-tss side.
  8. Finally persist the key via Tss2_Sys_EvictControl function.

I have 2 blockers:

  • I failed at Tss2_Sys_CreatePrimary. The function failed and return error code: 0xa1 (Bat Auth?)
  • If I successfully create the primary key, then how can I import the key and persist into TPM? I am not sure my step 6, 7, 8 are correct.

Here I post my key snippet:

    std::string tpm_aes_key_id = "0x810003E9"; // equal to TPM_HANDLE persistHandle = TPM_HANDLE::Persistent(1001);

    TSS2_SYS_CONTEXT* sysContext;
    TSS2_ABI_VERSION abiVersion = TSS2_ABI_VERSION_CURRENT;
    TSS2_RC rc;
    size_t contextSize;

    contextSize = Tss2_Sys_GetContextSize(0);
    sysContext = (TSS2_SYS_CONTEXT*)malloc(contextSize);
    if (sysContext == NULL) {
        fprintf(stderr, "Failed to allocate memory for TPM context.\n");
        return;
    }
    rc = Tss2_TctiLdr_Initialize("tbs", &tctiContext);
    handleTpmErrors(rc);
    std::cout << "SUCCESS: TCTI Loader load tbs tcti-device" << std::endl;

    rc = Tss2_Sys_Initialize(sysContext, contextSize, tctiContext, &abiVersion);
    handleTpmErrors(rc);
    std::cout << "SUCCESS: Initial system context" << std::endl;
    
    // Read the key file.
    std::vector<unsigned char> aesKey = read_file("aes_key.bin");
    if (aesKey.size() != 32) {
        std::cerr << "Invalid AES key size. Expected 256-bit key." << std::endl;
        exit(1);
    }

    // Get the TPM properties
    TPMS_CAPABILITY_DATA capability_data;
    TPMI_YES_NO more_data;

    rc = Tss2_Sys_GetCapability(sysContext, NULL, TPM2_CAP_TPM_PROPERTIES, 
                                TPM2_PT_MANUFACTURER, 10, &more_data, &capability_data, NULL);
    handleTpmErrors(rc);
    std::cout << "SUCCESS: Get TPM capabilities" << std::endl;

    // Create Primary key to protect imported key
    TSS2_RC rval = TPM2_RC_SUCCESS;
    TPM2B_SENSITIVE_CREATE  in_sensitive;
    TPM2B_PUBLIC            in_public = { 0 };
    TPM2B_DATA              outside_info = { 0, };
    TPML_PCR_SELECTION      creation_pcr;
    TPM2B_NAME name = { sizeof(TPM2B_NAME) - 2, };
    TPM2B_PRIVATE out_private = { sizeof(TPM2B_PRIVATE) - 2, };
    TPM2B_PUBLIC out_public = { 0, };
    TPM2B_CREATION_DATA creation_data = { 0, };
    TPM2B_DIGEST creation_hash = { sizeof(TPM2B_DIGEST) - 2, };
    TPMT_TK_CREATION creation_ticket = { 0, };
    TPM2_HANDLE loaded_sym_handle;
    TPM2_HANDLE sym_handle;
    const char message[] = "my message";
    TPMT_RSA_DECRYPT in_scheme;
    TPM2B_PUBLIC_KEY_RSA input_message = { sizeof(TPM2B_PUBLIC_KEY_RSA) - 2, };
    TPM2B_PUBLIC_KEY_RSA output_message = { sizeof(TPM2B_PUBLIC_KEY_RSA) - 2, };
    TPM2B_PUBLIC_KEY_RSA output_data = { sizeof(TPM2B_PUBLIC_KEY_RSA) - 2, };

    TSS2L_SYS_AUTH_RESPONSE sessions_data_out;
    TSS2L_SYS_AUTH_COMMAND sessions_data;
    sessions_data.count = 1;
    sessions_data.auths->sessionHandle = TPM2_RH_PW;
    sessions_data.auths->nonce.size = 0;
    sessions_data.auths->hmac.size = 0;

    in_sensitive.size = 0;
    in_sensitive.sensitive.userAuth.size = 0;
    in_sensitive.sensitive.data.size = 0;

    in_public.publicArea.type = TPM2_ALG_RSA;
    in_public.publicArea.nameAlg = TPM2_ALG_SHA256;
    *(UINT32*)&(in_public.publicArea.objectAttributes) = 0;
    in_public.publicArea.objectAttributes |= TPMA_OBJECT_RESTRICTED;
    in_public.publicArea.objectAttributes |= TPMA_OBJECT_USERWITHAUTH;
    in_public.publicArea.objectAttributes |= TPMA_OBJECT_DECRYPT;
    in_public.publicArea.objectAttributes |= TPMA_OBJECT_FIXEDTPM;
    in_public.publicArea.objectAttributes |= TPMA_OBJECT_FIXEDPARENT;
    in_public.publicArea.objectAttributes |= TPMA_OBJECT_SENSITIVEDATAORIGIN;

    in_public.publicArea.authPolicy.size = 0;

    in_public.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM2_ALG_AES;
    in_public.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
    in_public.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM2_ALG_CFB;
    in_public.publicArea.parameters.rsaDetail.scheme.scheme = TPM2_ALG_NULL;
    in_public.publicArea.parameters.rsaDetail.keyBits = 2048;
    in_public.publicArea.parameters.rsaDetail.exponent = 0;

    in_public.publicArea.unique.rsa.size = 0;

    outside_info.size = 0;
    creation_pcr.count = 0;
    out_public.size = 0;
    creation_data.size = 0;

    rval = Tss2_Sys_CreatePrimary(sysContext, TPM2_RH_OWNER, &sessions_data, 
                                    &in_sensitive, &in_public, &outside_info, 
                                    &creation_pcr, &sym_handle, &out_public, 
                                    &creation_data, &creation_hash, &creation_ticket, 
                                    &name, &sessions_data_out);
    handleTpmErrors(rval);

The Tss2_Sys_CreatePrimary always return 0xa1 code. I copied the code of key generation from your \test\tpmclient\tpmclient.int.c file.
I hope I can got your help soon, much appreciate! Thanks!