Пример #1
0
static uint32_t
TpmUtilCreateAuthority(
    char* authorityName,
    ANY_OBJECT* sigkey
    )
{
    DEFINE_CALL_BUFFERS;
    UINT32 result = TPM_RC_SUCCESS;
    union
    {
        CreatePrimary_In createPrimary;
    } in;
    union
    {
        CreatePrimary_Out createPrimary;
    } out;

    // This is set up to create an SM2 key that is using SM3 payload hashing
    INITIALIZE_CALL_BUFFERS(TPM2_CreatePrimary, &in.createPrimary, &out.createPrimary);
    parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle = TPM_RH_ENDORSEMENT;
    in.createPrimary.inPublic.t.publicArea.nameAlg = TPM_ALG_SHA256;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.sensitiveDataOrigin = SET;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.userWithAuth = SET;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.noDA = SET;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.sign = SET;
#ifdef NTZTPM
    in.createPrimary.inPublic.t.publicArea.type = TPM_ALG_ECC;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_SM2;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = TPM_ALG_SM3_256;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.curveID = TPM_ECC_SM2_P256;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL;
#else
    in.createPrimary.inPublic.t.publicArea.type = TPM_ALG_ECC;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_ECDSA;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.scheme.details.ecdsa.hashAlg = TPM_ALG_SHA256;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
    in.createPrimary.inPublic.t.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL;
//    in.createPrimary.inPublic.t.publicArea.type = TPM_ALG_RSA;
//    in.createPrimary.inPublic.t.publicArea.parameters.rsaDetail.keyBits = MAX_RSA_KEY_BITS;
//    in.createPrimary.inPublic.t.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_RSAPSS;
//    in.createPrimary.inPublic.t.publicArea.parameters.rsaDetail.scheme.details.rsapss.hashAlg = TPM_ALG_SHA256;
//    in.createPrimary.inPublic.t.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL;
#endif
    in.createPrimary.inPublic.t.publicArea.unique.ecc.x.t.size = CryptHashBlock(TPM_ALG_SHA256, strlen(authorityName), (BYTE*)authorityName, sizeof(in.createPrimary.inPublic.t.publicArea.unique.ecc.x.t.buffer), in.createPrimary.inPublic.t.publicArea.unique.ecc.x.t.buffer);
    EXECUTE_TPM_CALL(FALSE, TPM2_CreatePrimary);
    *sigkey = parms.objectTableOut[TPM2_CreatePrimary_HdlOut_ObjectHandle];

Cleanup:
    return result;
}
Пример #2
0
/* This does the name computation from a public area (can be marshaled or not). */
TPM2B_NAME *
ObjectComputeName(
		  UINT32           size,          // IN: the size of the area to digest
		  BYTE            *publicArea,    // IN: the public area to digest
		  TPM_ALG_ID       nameAlg,       // IN: the hash algorithm to use
		  TPM2B_NAME      *name           // OUT: Computed name
		  )
{
    // Hash the publicArea into the name buffer leaving room for the nameAlg
    name->t.size = CryptHashBlock(nameAlg, size, publicArea,
				  sizeof(name->t.name) - 2,
				  &name->t.name[2]);
    // set the nameAlg
    UINT16_TO_BYTE_ARRAY(nameAlg, name->t.name);
    name->t.size += 2;
    return name;
}
Пример #3
0
static uint32_t
TpmUtilIssueBootPolicy(
    ANY_OBJECT* platformAuthority,
    TPM2B_MAX_NV_BUFFER* policy,
    TPM2B_NAME* deviceId,
    TPMT_SIGNATURE* authorizationSignature
    )
{
    DEFINE_CALL_BUFFERS;
    UINT32 result = TPM_RC_SUCCESS;
    union
    {
        PolicyAuthorize_In policyAuthorize;
        PolicyGetDigest_In policyGetDigest;
        PolicyCpHash_In policyCpHash;
        Sign_In sign;
    } in;
    union
    {
        Sign_Out sign;
    } out;
    TPM2B_NV_PUBLIC nvPublicInfo = {0};
    TPM2B_NAME nvIndexName = {0};
    const TPM_CC commandCode = TPM_CC_NV_Write;
    const UINT16 offset = 0;
    TPM2B_DIGEST cpHash = {0};
    TPM2B_DIGEST approvedPolicy = {0};
    TPM2B_DIGEST authorization = {0};
    HASH_STATE hash = {0};

    // Next we predict the NV storage Name that this policy will be hosted in
    nvPublicInfo.t.nvPublic.dataSize = policy->t.size;
    nvPublicInfo.t.nvPublic.nameAlg = TPM_ALG_SHA256;
    nvPublicInfo.t.nvPublic.nvIndex = TPM_PLATFORM_LOCKDOWN_POLICY_NV_INDEX;
    nvPublicInfo.t.nvPublic.attributes.TPMA_NV_AUTHREAD = SET;
    nvPublicInfo.t.nvPublic.attributes.TPMA_NV_OWNERREAD = SET;
    nvPublicInfo.t.nvPublic.attributes.TPMA_NV_NO_DA = SET;
    nvPublicInfo.t.nvPublic.attributes.TPMA_NV_PLATFORMCREATE = SET;
    nvPublicInfo.t.nvPublic.attributes.TPMA_NV_POLICYWRITE = SET;

    // Calculate the authPolicy for the index
    MemorySet(&in.policyAuthorize, 0x00, sizeof(in.policyAuthorize));
    in.policyAuthorize.approvedPolicy.t.size = SHA256_DIGEST_SIZE;
    in.policyAuthorize.policyRef.t.size = SHA256_DIGEST_SIZE;
    MemoryCopy(in.policyAuthorize.policyRef.t.buffer, &deviceId->t.name[sizeof(UINT16)], in.policyAuthorize.policyRef.t.size, sizeof(in.policyAuthorize.policyRef.t.buffer));
    in.policyAuthorize.keySign = platformAuthority->obj.name;
    in.policyAuthorize.checkTicket.tag = TPM_ST_VERIFIED;
    in.policyAuthorize.checkTicket.hierarchy = TPM_RH_NULL;
    nvPublicInfo.t.nvPublic.authPolicy.t.size = SHA256_DIGEST_SIZE;
    TPM2_PolicyAuthorize_CalculateUpdate(TPM_ALG_SHA256, &nvPublicInfo.t.nvPublic.authPolicy, &in.policyAuthorize);

    // Serialize the public index to get it's name
    buffer = pbCmd;
    size = sizeof(pbCmd);
    if(TPMS_NV_PUBLIC_Marshal(&nvPublicInfo.t.nvPublic, &buffer, &size) < 0)
    {
        result = TPM_RC_FAILURE;
        goto Cleanup;
    }
    UINT16_TO_BYTE_ARRAY(TPM_ALG_SHA256, nvIndexName.t.name);
    nvIndexName.t.size = sizeof(UINT16) + CryptHashBlock(TPM_ALG_SHA256, sizeof(pbCmd) - size, pbCmd, sizeof(nvIndexName.t.name) - sizeof(UINT16), &nvIndexName.t.name[sizeof(UINT16)]);

    // Next we are calculating cpHash for the write command we want to execute later
    cpHash.t.size = CryptStartHash(TPM_ALG_SHA256, &hash);
    CryptUpdateDigestInt(&hash, sizeof(commandCode), (void*)&commandCode);
    CryptUpdateDigest2B(&hash, &nvIndexName.b);
    CryptUpdateDigest2B(&hash, &nvIndexName.b);
    CryptUpdateDigestInt(&hash, sizeof(UINT16), &policy->t.size);
    CryptUpdateDigest2B(&hash, (TPM2B*)policy);
    CryptUpdateDigestInt(&hash, sizeof(UINT16), (void*)&offset);
    CryptCompleteHash2B(&hash, &cpHash.b);

    // We calculate the policy digest of PolicyCpHash(cpHash)
    MemorySet(&in.policyCpHash, 0x00, sizeof(in.policyCpHash));
    approvedPolicy.t.size = SHA256_DIGEST_SIZE;
    in.policyCpHash.cpHashA = cpHash;
    TPM2_PolicyCpHash_CalculateUpdate(TPM_ALG_SHA256, &approvedPolicy, &in.policyCpHash);

    // Calculate the authorization
    authorization.t.size = CryptStartHash(TPM_ALG_SHA256, &hash);
    CryptUpdateDigest2B(&hash, (TPM2B*)&approvedPolicy);
    CryptUpdateDigest(&hash, SHA256_DIGEST_SIZE, &deviceId->t.name[sizeof(UINT16)]);
    CryptCompleteHash2B(&hash, &authorization.b);

    // Sign the authorization
    INITIALIZE_CALL_BUFFERS(TPM2_Sign, &in.sign, &out.sign);
    parms.objectTableIn[TPM2_Sign_HdlIn_KeyHandle] = *platformAuthority;
    in.sign.digest = authorization;
    in.sign.inScheme.scheme = TPM_ALG_NULL; // Use whatever the key demands
    in.sign.validation.tag = TPM_ST_HASHCHECK;
    in.sign.validation.hierarchy = TPM_RH_NULL;
    EXECUTE_TPM_CALL(FALSE, TPM2_Sign);

    *authorizationSignature = out.sign.signature;

Cleanup:
    return result;
}
Пример #4
0
UINT32
CreatePlatformDataProtectionKey(
    void
    )
{
    DEFINE_CALL_BUFFERS;
    UINT32 result = TPM_RC_SUCCESS;
    union
    {
        PolicyPCR_In policyPcr;
        PolicyAuthValue_In policyAuthValue;
        StartAuthSession_In startAuthSession;
        CreatePrimary_In createPrimary;
        EvictControl_In evictControl;
    } in;
    union
    {
        CreatePrimary_Out createPrimary;
        EvictControl_Out evictControl;
    } out;
    SESSION policySession = {0};
    TPM2B_DIGEST policyDigest = {0};
    HASH_STATE hash = {0};
    TPM2B_DIGEST pcrDigest = {0};
    TPML_PCR_SELECTION pcrs = {0};
    TPML_DIGEST pcrValues = {0};
    ANY_OBJECT aesDpkObject = {0};

    // Best effort free the NV index if there is already a key
    INITIALIZE_CALL_BUFFERS(TPM2_EvictControl, &in.evictControl, &out.evictControl);
    parms.objectTableIn[TPM2_EvictControl_HdlIn_Auth].entity.handle = TPM_RH_PLATFORM;
    parms.objectTableIn[TPM2_EvictControl_HdlIn_ObjectHandle].obj.handle = TPM_PLATFORM_DPK_HANDLE;
    in.evictControl.persistentHandle = TPM_PLATFORM_DPK_HANDLE;
    TRY_TPM_CALL(FALSE, TPM2_EvictControl);

    // Calculate the expected PCR table for the policy
    pcrs.count = 1;
    pcrs.pcrSelections[0].hash = TPM_ALG_SHA256;
    pcrs.pcrSelections[0].sizeofSelect = 3;
    pcrs.pcrSelections[0].pcrSelect[0] = 0xFF;
    pcrs.pcrSelections[0].pcrSelect[1] = 0x00;
    pcrs.pcrSelections[0].pcrSelect[2] = 0x00;
    pcrValues.count = 8;
    for(UINT32 n = 0; n < pcrValues.count; n++)
    {
        pcrValues.digests[n].t.size = SHA256_DIGEST_SIZE;
    }
    pcrValues.digests[0].t.size = CryptStartHash(TPM_ALG_SHA256, &hash);
    CryptUpdateDigest2B(&hash, (TPM2B*)&pcrValues.digests[0]);
    CryptHashBlock(TPM_ALG_SHA256, persistedData.compoundIdentity.t.size, persistedData.compoundIdentity.t.buffer, pcrValues.digests[0].t.size, pcrValues.digests[0].t.buffer);
    CryptUpdateDigest2B(&hash, (TPM2B*)&pcrValues.digests[0]);
    CryptCompleteHash2B(&hash, (TPM2B*)&pcrValues.digests[0]);
    pcrDigest.t.size = CryptStartHash(TPM_ALG_SHA256, &hash);
    for(UINT32 n = 0; n < pcrValues.count; n++)
    {
        CryptUpdateDigest(&hash, pcrValues.digests[n].t.size, pcrValues.digests[n].t.buffer);
    }
    CryptCompleteHash2B(&hash, (TPM2B*)&pcrDigest);

    // Calculate the PCR policy - Any change here will result in a different key
    // policydigest = PolicyAuthValue() || PolicyPCR(PCR[0..7])
    policyDigest.t.size = SHA256_DIGEST_SIZE;
    TPM2_PolicyAuthValue_CalculateUpdate(TPM_ALG_SHA256, &policyDigest, &in.policyAuthValue);
    in.policyPcr.pcrs = pcrs;
    in.policyPcr.pcrDigest = pcrDigest;
    TPM2_PolicyPCR_CalculateUpdate(TPM_ALG_SHA256, &policyDigest, &in.policyPcr);

    // Create the PCR bound AES key
    sessionTable[0] = volatileData.ekSeededSession;
    sessionTable[0].attributes.decrypt = YES;
    INITIALIZE_CALL_BUFFERS(TPM2_CreatePrimary, &in.createPrimary, &out.createPrimary);
    parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle = TPM_RH_PLATFORM;
    UINT32_TO_BYTE_ARRAY(parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle, parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.name.t.name);
    parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.name.t.size = sizeof(parms.objectTableIn[TPM2_CreatePrimary_HdlIn_PrimaryHandle].entity.handle);
    in.createPrimary.inSensitive.t.sensitive.data.t.size = CryptGenerateRandom(16, in.createPrimary.inSensitive.t.sensitive.data.t.buffer);
    in.createPrimary.inSensitive.t.sensitive.userAuth = persistedData.compoundIdentity;
    in.createPrimary.inPublic.t.publicArea.type = TPM_ALG_SYMCIPHER;
    in.createPrimary.inPublic.t.publicArea.nameAlg = TPM_ALG_SHA256;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.fixedTPM = SET;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.fixedParent = SET;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.adminWithPolicy = SET;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.noDA = SET;
    in.createPrimary.inPublic.t.publicArea.objectAttributes.decrypt = SET;
#ifndef NTZTPM
    in.createPrimary.inPublic.t.publicArea.objectAttributes.sign = SET;
#endif
    in.createPrimary.inPublic.t.publicArea.parameters.symDetail.algorithm = TPM_ALG_AES;
    in.createPrimary.inPublic.t.publicArea.parameters.symDetail.keyBits.sym = 128;
    in.createPrimary.inPublic.t.publicArea.parameters.symDetail.mode.sym = TPM_ALG_CFB;
    in.createPrimary.inPublic.t.publicArea.authPolicy = policyDigest;
    EXECUTE_TPM_CALL(FALSE, TPM2_CreatePrimary);
    sessionTable[0].attributes = volatileData.ekSeededSession.attributes;
    volatileData.ekSeededSession = sessionTable[0];
    aesDpkObject = parms.objectTableOut[TPM2_CreatePrimary_HdlOut_ObjectHandle];
    PrintTPM2B("PlatformDPKeyName", (TPM2B*)&aesDpkObject.obj.name);

    // Persist the key
    sessionTable[0] = volatileData.ekSeededSession;
    INITIALIZE_CALL_BUFFERS(TPM2_EvictControl, &in.evictControl, &out.evictControl);
    parms.objectTableIn[TPM2_EvictControl_HdlIn_Auth].entity.handle = TPM_RH_PLATFORM;
    parms.objectTableIn[TPM2_EvictControl_HdlIn_ObjectHandle] = aesDpkObject;
    in.evictControl.persistentHandle = TPM_PLATFORM_DPK_HANDLE;
    EXECUTE_TPM_CALL(FALSE, TPM2_EvictControl);
    volatileData.ekSeededSession = sessionTable[0];

Cleanup:
    if(aesDpkObject.obj.handle != 0)
    {
        FlushContext(&aesDpkObject);
    }
    if(result != TPM_RC_SUCCESS)
    {
        // Copy the EKSeeded session back out in case of an error
        volatileData.ekSeededSession = sessionTable[0];
    }
    return result;
}