xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tspi_transport.c (revision 2d5f7628c5531eb583b9313ac2fd1cf8582b4479)
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 #include <inttypes.h>
16 
17 #include "trousers/tss.h"
18 #include "trousers/trousers.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 
26 TSS_RESULT
Tspi_Context_SetTransEncryptionKey(TSS_HCONTEXT hContext,TSS_HKEY hIdentKey)27 Tspi_Context_SetTransEncryptionKey(TSS_HCONTEXT hContext,	/* in */
28 				   TSS_HKEY     hIdentKey)	/* in */
29 {
30 	if (!obj_is_rsakey(hIdentKey))
31 		return TSPERR(TSS_E_INVALID_HANDLE);
32 
33 	return obj_context_set_transport_key(hContext, hIdentKey);
34 }
35 
36 TSS_RESULT
Tspi_Context_CloseSignTransport(TSS_HCONTEXT hContext,TSS_HKEY hSigningKey,TSS_VALIDATION * pValidationData)37 Tspi_Context_CloseSignTransport(TSS_HCONTEXT    hContext,		/* in */
38 				TSS_HKEY        hSigningKey,		/* in */
39 				TSS_VALIDATION* pValidationData)	/* in, out */
40 {
41 	TSS_RESULT result;
42 	TSS_HPOLICY hPolicy;
43 	TSS_BOOL usesAuth;
44 	UINT32 sigLen;
45 	BYTE *sig;
46 	UINT64 offset;
47 	Trspi_HashCtx hashCtx;
48 	TPM_DIGEST digest;
49 	TPM_SIGN_INFO signInfo;
50 
51 	if (!obj_is_context(hContext))
52 		return TSPERR(TSS_E_INVALID_HANDLE);
53 
54 	if ((result = obj_rsakey_get_policy(hSigningKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
55 		return result;
56 
57 	if (pValidationData) {
58 		if (pValidationData->ulExternalDataLength != sizeof(TPM_NONCE))
59 			return TSPERR(TSS_E_BAD_PARAMETER);
60 
61 		memcpy(signInfo.replay.nonce, pValidationData->rgbExternalData, sizeof(TPM_NONCE));
62 	} else {
63 		if ((result = get_local_random(hContext, FALSE, sizeof(TPM_NONCE),
64 					       (BYTE **)&signInfo.replay.nonce)))
65 			return result;
66 	}
67 
68 	/* the transport sessions properties are kept in the context object itself, so just pass
69 	 * in what this function provides and let it call ReleaseTransportSigned */
70 	if ((result = obj_context_transport_close(hContext, hSigningKey, hPolicy, usesAuth,
71 						  &signInfo, &sigLen, &sig)))
72 		return result;
73 
74 	/* inside obj_context_transport_close we set up all the fields of the sign info structure
75 	 * other than the tag and 'fixed' */
76 	signInfo.tag = TPM_TAG_SIGNINFO;
77 	signInfo.fixed[0] = 'T';
78 	signInfo.fixed[1] = 'R';
79 	signInfo.fixed[2] = 'A';
80 	signInfo.fixed[3] = 'N';
81 
82 	/* hash the sign info struct for use in verifying the TPM's signature */
83 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
84 	result |= Trspi_Hash_SIGN_INFO(&hashCtx, &signInfo);
85 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
86 		free(sig);
87 		return TSPERR(TSS_E_INTERNAL_ERROR);
88 	}
89 
90 	offset = 0;
91 	if (pValidationData) {
92 		/* tag the returned allocated memory as alloc'd by the TSP */
93 		if ((result = __tspi_add_mem_entry(hContext, sig))) {
94 			free(sig);
95 			return TSPERR(TSS_E_INTERNAL_ERROR);
96 		}
97 		pValidationData->rgbValidationData = sig;
98 		pValidationData->ulValidationDataLength = sigLen;
99 
100 		/* passing a NULL blob here puts the exact size of TPM_SIGN_INFO into offset */
101 		Trspi_LoadBlob_SIGN_INFO(&offset, NULL, &signInfo);
102 		pValidationData->rgbData = calloc_tspi(hContext, offset);
103 		if (pValidationData->rgbData == NULL) {
104 			LogError("malloc of %" PRIu64 " bytes failed.", offset);
105 			free_tspi(hContext, pValidationData->rgbValidationData);
106 			pValidationData->rgbValidationData = NULL;
107 			pValidationData->ulValidationDataLength = 0;
108 			return TSPERR(TSS_E_OUTOFMEMORY);
109 		}
110 		pValidationData->ulDataLength = (UINT32)offset;
111 
112 		offset = 0;
113 		Trspi_LoadBlob_SIGN_INFO(&offset, pValidationData->rgbData, &signInfo);
114 	} else
115 		result = __tspi_rsa_verify(hSigningKey, TSS_HASH_SHA1, sizeof(TPM_DIGEST), digest.digest,
116 				    sigLen, sig);
117 
118 	return result;
119 }
120