Home | History | Annotate | Line # | Download | only in tspi
      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-2007
      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 "spi_utils.h"
     20 #include "capabilities.h"
     21 #include "tsplog.h"
     22 #include "obj.h"
     23 #include "authsess.h"
     24 
     25 
     26 TSS_RESULT
     27 Tspi_Data_Seal(TSS_HENCDATA hEncData,	/* in */
     28 	       TSS_HKEY hEncKey,	/* in */
     29 	       UINT32 ulDataLength,	/* in */
     30 	       BYTE * rgbDataToSeal,	/* in */
     31 	       TSS_HPCRS hPcrComposite)	/* in */
     32 {
     33 	TPM_DIGEST digest;
     34 	TSS_RESULT result;
     35 	TSS_HPOLICY hPolicy, hEncPolicy;
     36 	BYTE *encData = NULL;
     37 	BYTE *pcrData = NULL;
     38 	UINT32 encDataSize;
     39 	UINT32 pcrDataSize;
     40 	UINT32 pcrInfoType = TSS_PCRS_STRUCT_DEFAULT;
     41 	UINT32 sealOrdinal = TPM_ORD_Seal;
     42 	TCS_KEY_HANDLE tcsKeyHandle;
     43 	TSS_HCONTEXT tspContext;
     44 	Trspi_HashCtx hashCtx;
     45 	BYTE *sealData = NULL;
     46 	struct authsess *xsap = NULL;
     47 #ifdef TSS_BUILD_SEALX
     48 	UINT32 protectMode;
     49 #endif
     50 
     51 	if (rgbDataToSeal == NULL)
     52 		return TSPERR(TSS_E_BAD_PARAMETER);
     53 
     54 	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
     55 		return result;
     56 
     57 	if ((result = obj_rsakey_get_policy(hEncKey, TSS_POLICY_USAGE,
     58 					    &hPolicy, NULL)))
     59 		return result;
     60 
     61 	if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE,
     62 					     &hEncPolicy)))
     63 		return result;
     64 
     65 	if ((result = obj_rsakey_get_tcs_handle(hEncKey, &tcsKeyHandle)))
     66 		return result;
     67 
     68 #ifdef TSS_BUILD_SEALX
     69 	/* Get the TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE attribute
     70 	   to determine the seal function to invoke */
     71 	if ((result = obj_encdata_get_seal_protect_mode(hEncData, &protectMode)))
     72 		return result;
     73 
     74 	if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT) {
     75 		sealOrdinal = TPM_ORD_Seal;
     76 		pcrInfoType = 0;
     77 	} else if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_PROTECT) {
     78 		sealOrdinal = TPM_ORD_Sealx;
     79 		pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG;
     80 	} else
     81 		return TSPERR(TSS_E_INTERNAL_ERROR);
     82 #endif
     83 
     84 	/* If PCR's are of interest */
     85 	pcrDataSize = 0;
     86 	if (hPcrComposite) {
     87 		if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrInfoType, &pcrDataSize,
     88 							&pcrData)))
     89 			return result;
     90 	}
     91 
     92 	if ((result = authsess_xsap_init(tspContext, hEncKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
     93 					 sealOrdinal, TPM_ET_KEYHANDLE, &xsap)))
     94 		goto error;
     95 
     96 #ifdef TSS_BUILD_SEALX
     97 	if (sealOrdinal == TPM_ORD_Seal)
     98 		sealData = rgbDataToSeal;
     99 	else {
    100 		if ((sealData = (BYTE *)calloc(1, ulDataLength)) == NULL) {
    101 			LogError("malloc of %u bytes failed", ulDataLength);
    102 			result = TSPERR(TSS_E_OUTOFMEMORY);
    103 			goto error;
    104 		}
    105 
    106 		if ((result =
    107 		     ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
    108 		     UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
    109 		     BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hEncKey, hEncData,
    110 						      xsap->cb_sealx.alg, sizeof(TPM_NONCE),
    111 						      xsap->auth.NonceEven.nonce,
    112 						      xsap->auth.NonceOdd.nonce,
    113 						      xsap->nonceEvenxSAP.nonce,
    114 						      xsap->nonceOddxSAP.nonce, ulDataLength,
    115 						      rgbDataToSeal, sealData)))
    116 			goto error;
    117 	}
    118 #else
    119 	sealData = rgbDataToSeal;
    120 #endif
    121 
    122 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    123 	result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
    124 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
    125 	result |= Trspi_Hash_UINT32(&hashCtx, pcrDataSize);
    126 	result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData);
    127 	result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
    128 	result |= Trspi_HashUpdate(&hashCtx, ulDataLength, sealData);
    129 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
    130 		goto error;
    131 	}
    132 
    133 	if ((result = authsess_xsap_hmac(xsap, &digest)))
    134 		goto error;
    135 
    136 #ifdef TSS_BUILD_SEALX
    137 	if (sealOrdinal == TPM_ORD_Seal) {
    138 		if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
    139 							pcrDataSize, pcrData, ulDataLength,
    140 							sealData, xsap->pAuth, &encDataSize,
    141 							&encData))) {
    142 			goto error;
    143 		}
    144 	} else if (sealOrdinal == TPM_ORD_Sealx) {
    145 		if ((result = TCS_API(tspContext)->Sealx(tspContext, tcsKeyHandle, &xsap->encAuthUse,
    146 						    pcrDataSize, pcrData, ulDataLength, sealData,
    147 						    xsap->pAuth, &encDataSize, &encData))) {
    148 			goto error;
    149 		}
    150 	} else {
    151 		result = TSPERR(TSS_E_INTERNAL_ERROR);
    152 		goto error;
    153 	}
    154 #else
    155 	if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
    156 						pcrDataSize, pcrData, ulDataLength, sealData,
    157 						xsap->pAuth, &encDataSize, &encData)))
    158 		goto error;
    159 #endif
    160 
    161 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    162 	result |= Trspi_Hash_UINT32(&hashCtx, result);
    163 	result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
    164 	result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData);
    165 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
    166 		goto error;
    167 
    168 	if ((result = authsess_xsap_verify(xsap, &digest)))
    169 		goto error;
    170 
    171 	/* Need to set the object with the blob and the pcr's */
    172 	if ((result = obj_encdata_set_data(hEncData, encDataSize, encData)))
    173 		goto error;
    174 
    175 	if (pcrDataSize)
    176 		result = obj_encdata_set_pcr_info(hEncData, pcrInfoType, pcrData);
    177 
    178 error:
    179 	authsess_free(xsap);
    180 	free(encData);
    181 	free(pcrData);
    182 	if (sealData != rgbDataToSeal)
    183 		free(sealData);
    184 	return result;
    185 }
    186 
    187 TSS_RESULT
    188 Tspi_Data_Unseal(TSS_HENCDATA hEncData,		/* in */
    189 		 TSS_HKEY hKey,			/* in */
    190 		 UINT32 * pulUnsealedDataLength,/* out */
    191 		 BYTE ** prgbUnsealedData)	/* out */
    192 {
    193 	UINT64 offset;
    194 	TPM_AUTH privAuth2;
    195 	TPM_DIGEST digest;
    196 	TPM_NONCE authLastNonceEven;
    197 	TSS_RESULT result;
    198 	TSS_HPOLICY hPolicy, hEncPolicy;
    199 	TCS_KEY_HANDLE tcsKeyHandle;
    200         TSS_HCONTEXT tspContext;
    201 	UINT32 ulDataLen, unSealedDataLen;
    202 	BYTE *data = NULL, *unSealedData = NULL, *maskedData;
    203 	UINT16 mask;
    204 	Trspi_HashCtx hashCtx;
    205 	struct authsess *xsap = NULL;
    206 
    207 	if (pulUnsealedDataLength == NULL || prgbUnsealedData == NULL)
    208 		return TSPERR(TSS_E_BAD_PARAMETER);
    209 
    210 	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
    211 		return result;
    212 
    213 	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, NULL)))
    214 		return result;
    215 
    216 	if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, &hEncPolicy)))
    217 		return result;
    218 
    219 	if ((result = obj_encdata_get_data(hEncData, &ulDataLen, &data)))
    220 		return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ?
    221 		       TSPERR(TSS_E_ENC_NO_DATA) :
    222 		       result;
    223 
    224 	offset = 0;
    225 	Trspi_UnloadBlob_UINT16(&offset, &mask, data);
    226 	if (mask == TPM_TAG_STORED_DATA12) {
    227 		/* The second UINT16 in a TPM_STORED_DATA12 is the entity type. If its non-zero
    228 		 * then we must unmask the unsealed data after it returns from the TCS */
    229 		Trspi_UnloadBlob_UINT16(&offset, &mask, data);
    230 	} else
    231 		mask = 0;
    232 
    233 	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
    234 		goto error;
    235 
    236 	if ((result = authsess_xsap_init(tspContext, hKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
    237 					 TPM_ORD_Unseal, TPM_ET_KEYHANDLE, &xsap)))
    238 		goto error;
    239 
    240 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    241 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
    242 	result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data);
    243 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
    244 		goto error;
    245 
    246 	if ((result = authsess_xsap_hmac(xsap, &digest)))
    247 		goto error;
    248 
    249 	if ((result = secret_PerformAuth_OIAP(hEncData, TPM_ORD_Unseal, hEncPolicy, FALSE, &digest,
    250 					      &privAuth2)))
    251 		goto error;
    252 
    253 	if (mask) {
    254 		/* save off last nonce even to pass to sealx callback */
    255 		   memcpy(authLastNonceEven.nonce, xsap->auth.NonceEven.nonce, sizeof(TPM_NONCE));
    256 	}
    257 
    258 	if ((result = TCS_API(tspContext)->Unseal(tspContext, tcsKeyHandle, ulDataLen, data,
    259 						  xsap->pAuth, &privAuth2, &unSealedDataLen,
    260 						  &unSealedData)))
    261 		goto error;
    262 
    263 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    264 	result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
    265 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
    266 	result |= Trspi_Hash_UINT32(&hashCtx, unSealedDataLen);
    267 	result |= Trspi_HashUpdate(&hashCtx, unSealedDataLen, unSealedData);
    268 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
    269 		free(unSealedData);
    270 		goto error;
    271 	}
    272 
    273 	if ((result = authsess_xsap_verify(xsap, &digest))) {
    274 		free(unSealedData);
    275 		goto error;
    276 	}
    277 
    278 	if ((result = obj_policy_validate_auth_oiap(hEncPolicy, &digest, &privAuth2))) {
    279 		free(unSealedData);
    280 		goto error;
    281 	}
    282 
    283 	/* If the data is masked, use the callback set up in authsess_xsap_init */
    284 	if (mask) {
    285 		maskedData = unSealedData;
    286 
    287 		if ((unSealedData = calloc_tspi(tspContext, unSealedDataLen)) == NULL) {
    288 			free(maskedData);
    289 			LogError("malloc of %u bytes failed", unSealedDataLen);
    290 			result = TSPERR(TSS_E_OUTOFMEMORY);
    291 			goto error;
    292 		}
    293 
    294 		/* XXX pass in out saved-off authLastNonceEven. This conflicts with the
    295 		 * description of the rgbNonceEven parameter in the spec, but without it, its not
    296 		 * possible to compute the MGF1 key */
    297 		if ((result =
    298 		     ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
    299 		       UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
    300 		       BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hKey, hEncData,
    301 							 xsap->cb_sealx.alg, sizeof(TPM_NONCE),
    302 							 authLastNonceEven.nonce,
    303 							 xsap->auth.NonceOdd.nonce,
    304 							 xsap->nonceEvenxSAP.nonce,
    305 							 xsap->nonceOddxSAP.nonce,
    306 							 unSealedDataLen, maskedData,
    307 							 unSealedData))) {
    308 			free(maskedData);
    309 			goto error;
    310 		}
    311 
    312 		free(maskedData);
    313 	} else {
    314 		if ((result = __tspi_add_mem_entry(tspContext, unSealedData)))
    315 			goto error;
    316 	}
    317 
    318 	*pulUnsealedDataLength = unSealedDataLen;
    319 	*prgbUnsealedData = unSealedData;
    320 
    321 error:
    322 	authsess_free(xsap);
    323 	if (data)
    324 		free_tspi(tspContext, data);
    325 
    326 	return result;
    327 }
    328