1 2/* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2004-2006 8 * 9 */ 10 11 12#include <stdlib.h> 13#include <stdio.h> 14#include <string.h> 15 16#include "trousers/tss.h" 17#include "trousers/trousers.h" 18#include "trousers_types.h" 19#include "trousers_types.h" 20#include "spi_utils.h" 21#include "capabilities.h" 22#include "tsplog.h" 23#include "obj.h" 24 25 26TSS_RESULT 27Tspi_Key_CertifyKey(TSS_HKEY hKey, /* in */ 28 TSS_HKEY hCertifyingKey, /* in */ 29 TSS_VALIDATION * pValidationData) /* in, out */ 30{ 31 TCPA_RESULT result; 32 TPM_AUTH certAuth; 33 TPM_AUTH keyAuth; 34 TCPA_DIGEST digest; 35 TCPA_NONCE antiReplay; 36 UINT32 CertifyInfoSize; 37 BYTE *CertifyInfo; 38 UINT32 outDataSize; 39 BYTE *outData; 40 TSS_HPOLICY hPolicy; 41 TSS_HPOLICY hCertPolicy; 42 TCS_KEY_HANDLE certifyTCSKeyHandle, keyTCSKeyHandle; 43 TSS_BOOL useAuthCert; 44 TSS_BOOL useAuthKey; 45 TPM_AUTH *pCertAuth = &certAuth; 46 TPM_AUTH *pKeyAuth = &keyAuth; 47 TSS_HCONTEXT tspContext; 48 Trspi_HashCtx hashCtx; 49 50 51 if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) 52 return result; 53 54 if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, 55 &hPolicy, &useAuthKey))) 56 return result; 57 58 if ((result = obj_rsakey_get_policy(hCertifyingKey, TSS_POLICY_USAGE, 59 &hCertPolicy, &useAuthCert))) 60 return result; 61 62 if ((result = obj_rsakey_get_tcs_handle(hCertifyingKey, &certifyTCSKeyHandle))) 63 return result; 64 65 if ((result = obj_rsakey_get_tcs_handle(hKey, &keyTCSKeyHandle))) 66 return result; 67 68 if (pValidationData == NULL) { 69 LogDebug("Internal Verify"); 70 if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), 71 (BYTE **)antiReplay.nonce))) 72 return result; 73 } else { 74 LogDebug("External Verify"); 75 if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) 76 return TSPERR(TSS_E_BAD_PARAMETER); 77 78 memcpy(antiReplay.nonce, pValidationData->rgbExternalData, 79 sizeof(antiReplay.nonce)); 80 } 81 82 if (useAuthCert && !useAuthKey) 83 return TSPERR(TSS_E_BAD_PARAMETER); 84 85 /* Setup the auths */ 86 if (useAuthCert || useAuthKey) { 87 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 88 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifyKey); 89 result |= Trspi_HashUpdate(&hashCtx, sizeof(antiReplay.nonce), antiReplay.nonce); 90 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 91 return result; 92 } 93 94 if (useAuthKey) { 95 if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_CertifyKey, hPolicy, FALSE, 96 &digest, &keyAuth))) 97 return result; 98 } else 99 pKeyAuth = NULL; 100 101 if (useAuthCert) { 102 if ((result = secret_PerformAuth_OIAP(hCertifyingKey, TPM_ORD_CertifyKey, 103 hCertPolicy, FALSE, &digest, 104 &certAuth))) 105 return result; 106 } else 107 pCertAuth = NULL; 108 109 /* XXX free CertifyInfo */ 110 if ((result = TCS_API(tspContext)->CertifyKey(tspContext, certifyTCSKeyHandle, 111 keyTCSKeyHandle, &antiReplay, pCertAuth, 112 pKeyAuth, &CertifyInfoSize, &CertifyInfo, 113 &outDataSize, &outData))) 114 return result; 115 116 /* Validate auth */ 117 if (useAuthCert || useAuthKey) { 118 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 119 result |= Trspi_Hash_UINT32(&hashCtx, result); 120 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifyKey); 121 result |= Trspi_HashUpdate(&hashCtx, CertifyInfoSize, CertifyInfo); 122 result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); 123 result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); 124 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 125 goto cleanup; 126 127 if (useAuthKey) 128 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &keyAuth))) 129 goto cleanup; 130 131 if (useAuthCert) 132 if ((result = obj_policy_validate_auth_oiap(hCertPolicy, &digest, 133 &certAuth))) 134 goto cleanup; 135 } 136 137 if (pValidationData == NULL) { 138 if ((result = Trspi_Hash(TSS_HASH_SHA1, CertifyInfoSize, CertifyInfo, 139 digest.digest))) 140 goto cleanup; 141 142 143 if ((result = __tspi_rsa_verify(hCertifyingKey, TSS_HASH_SHA1, TPM_SHA1_160_HASH_LEN, 144 digest.digest, outDataSize, outData))){ 145 result = TSPERR(TSS_E_VERIFICATION_FAILED); 146 goto cleanup; 147 } 148 } else { 149 pValidationData->ulDataLength = CertifyInfoSize; 150 pValidationData->rgbData = calloc_tspi(tspContext, CertifyInfoSize); 151 if (pValidationData->rgbData == NULL) { 152 LogError("malloc of %u bytes failed.", CertifyInfoSize); 153 result = TSPERR(TSS_E_OUTOFMEMORY); 154 goto cleanup; 155 } 156 memcpy(pValidationData->rgbData, CertifyInfo, CertifyInfoSize); 157 pValidationData->ulValidationDataLength = outDataSize; 158 pValidationData->rgbValidationData = calloc_tspi(tspContext, outDataSize); 159 if (pValidationData->rgbValidationData == NULL) { 160 LogError("malloc of %u bytes failed.", outDataSize); 161 result = TSPERR(TSS_E_OUTOFMEMORY); 162 goto cleanup; 163 } 164 memcpy(pValidationData->rgbValidationData, outData, outDataSize); 165 } 166 167 result = TSS_SUCCESS; 168 169 cleanup: 170 free(CertifyInfo); 171 free(outData); 172 return result; 173} 174 175