1*758e9fbaSOystein Eftevaag /* SPDX-License-Identifier: BSD-2-Clause */
2*758e9fbaSOystein Eftevaag /*******************************************************************************
3*758e9fbaSOystein Eftevaag * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
4*758e9fbaSOystein Eftevaag * All rights reserved.
5*758e9fbaSOystein Eftevaag ******************************************************************************/
6*758e9fbaSOystein Eftevaag
7*758e9fbaSOystein Eftevaag #ifdef HAVE_CONFIG_H
8*758e9fbaSOystein Eftevaag #include <config.h>
9*758e9fbaSOystein Eftevaag #endif
10*758e9fbaSOystein Eftevaag
11*758e9fbaSOystein Eftevaag #include <stdio.h>
12*758e9fbaSOystein Eftevaag
13*758e9fbaSOystein Eftevaag #include "tss2_esys.h"
14*758e9fbaSOystein Eftevaag
15*758e9fbaSOystein Eftevaag #include "esys_crypto.h"
16*758e9fbaSOystein Eftevaag #include "esys_iutil.h"
17*758e9fbaSOystein Eftevaag #include "esys_mu.h"
18*758e9fbaSOystein Eftevaag #define LOGMODULE esys_crypto
19*758e9fbaSOystein Eftevaag #include "util/log.h"
20*758e9fbaSOystein Eftevaag #include "util/aux_util.h"
21*758e9fbaSOystein Eftevaag
22*758e9fbaSOystein Eftevaag /** Provide the digest size for a given hash algorithm.
23*758e9fbaSOystein Eftevaag *
24*758e9fbaSOystein Eftevaag * This function provides the size of the digest for a given hash algorithm.
25*758e9fbaSOystein Eftevaag *
26*758e9fbaSOystein Eftevaag * @param[in] hashAlg The hash algorithm to get the size for.
27*758e9fbaSOystein Eftevaag * @param[out] size The side of a digest of the hash algorithm.
28*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS on success.
29*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_BAD_VALUE if hashAlg is unknown or unsupported.
30*758e9fbaSOystein Eftevaag */
31*758e9fbaSOystein Eftevaag TSS2_RC
iesys_crypto_hash_get_digest_size(TPM2_ALG_ID hashAlg,size_t * size)32*758e9fbaSOystein Eftevaag iesys_crypto_hash_get_digest_size(TPM2_ALG_ID hashAlg, size_t * size)
33*758e9fbaSOystein Eftevaag {
34*758e9fbaSOystein Eftevaag LOG_TRACE("call: hashAlg=%"PRIu16" size=%p", hashAlg, size);
35*758e9fbaSOystein Eftevaag if (size == NULL) {
36*758e9fbaSOystein Eftevaag LOG_ERROR("Null-Pointer passed");
37*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_REFERENCE;
38*758e9fbaSOystein Eftevaag }
39*758e9fbaSOystein Eftevaag switch (hashAlg) {
40*758e9fbaSOystein Eftevaag case TPM2_ALG_SHA1:
41*758e9fbaSOystein Eftevaag *size = TPM2_SHA1_DIGEST_SIZE;
42*758e9fbaSOystein Eftevaag break;
43*758e9fbaSOystein Eftevaag case TPM2_ALG_SHA256:
44*758e9fbaSOystein Eftevaag *size = TPM2_SHA256_DIGEST_SIZE;
45*758e9fbaSOystein Eftevaag break;
46*758e9fbaSOystein Eftevaag case TPM2_ALG_SHA384:
47*758e9fbaSOystein Eftevaag *size = TPM2_SHA384_DIGEST_SIZE;
48*758e9fbaSOystein Eftevaag break;
49*758e9fbaSOystein Eftevaag case TPM2_ALG_SHA512:
50*758e9fbaSOystein Eftevaag *size = TPM2_SHA512_DIGEST_SIZE;
51*758e9fbaSOystein Eftevaag break;
52*758e9fbaSOystein Eftevaag case TPM2_ALG_SM3_256:
53*758e9fbaSOystein Eftevaag *size = TPM2_SM3_256_DIGEST_SIZE;
54*758e9fbaSOystein Eftevaag break;
55*758e9fbaSOystein Eftevaag default:
56*758e9fbaSOystein Eftevaag LOG_ERROR("Unsupported hash algorithm (%"PRIu16")", hashAlg);
57*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_VALUE;
58*758e9fbaSOystein Eftevaag }
59*758e9fbaSOystein Eftevaag LOG_TRACE("return: *size=%zu", *size);
60*758e9fbaSOystein Eftevaag return TSS2_RC_SUCCESS;
61*758e9fbaSOystein Eftevaag }
62*758e9fbaSOystein Eftevaag
63*758e9fbaSOystein Eftevaag /** Compute the command or response parameter hash.
64*758e9fbaSOystein Eftevaag *
65*758e9fbaSOystein Eftevaag * These hashes are needed for the computation of the HMAC used for the
66*758e9fbaSOystein Eftevaag * authorization of commands, or for the HMAC used for checking the responses.
67*758e9fbaSOystein Eftevaag * The name parameters are only used for the command parameter hash (cp) and
68*758e9fbaSOystein Eftevaag * must be NULL for the computation of the response parameter rp hash (rp).
69*758e9fbaSOystein Eftevaag * @param[in] alg The hash algorithm.
70*758e9fbaSOystein Eftevaag * @param[in] rcBuffer The response code in marshaled form.
71*758e9fbaSOystein Eftevaag * @param[in] ccBuffer The command code in marshaled form.
72*758e9fbaSOystein Eftevaag * @param[in] name1, name2, name3 The names associated with the corresponding
73*758e9fbaSOystein Eftevaag * handle. Must be NULL if no handle is passed.
74*758e9fbaSOystein Eftevaag * @param[in] pBuffer The byte buffer or the command or the response.
75*758e9fbaSOystein Eftevaag * @param[in] pBuffer_size The size of the command or response.
76*758e9fbaSOystein Eftevaag * @param[out] pHash The result digest.
77*758e9fbaSOystein Eftevaag * @param[out] pHash_size The size of the result digest.
78*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS on success.
79*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
80*758e9fbaSOystein Eftevaag */
81*758e9fbaSOystein Eftevaag
82*758e9fbaSOystein Eftevaag TSS2_RC
iesys_crypto_pHash(TPM2_ALG_ID alg,const uint8_t rcBuffer[4],const uint8_t ccBuffer[4],const TPM2B_NAME * name1,const TPM2B_NAME * name2,const TPM2B_NAME * name3,const uint8_t * pBuffer,size_t pBuffer_size,uint8_t * pHash,size_t * pHash_size)83*758e9fbaSOystein Eftevaag iesys_crypto_pHash(TPM2_ALG_ID alg,
84*758e9fbaSOystein Eftevaag const uint8_t rcBuffer[4],
85*758e9fbaSOystein Eftevaag const uint8_t ccBuffer[4],
86*758e9fbaSOystein Eftevaag const TPM2B_NAME * name1,
87*758e9fbaSOystein Eftevaag const TPM2B_NAME * name2,
88*758e9fbaSOystein Eftevaag const TPM2B_NAME * name3,
89*758e9fbaSOystein Eftevaag const uint8_t * pBuffer,
90*758e9fbaSOystein Eftevaag size_t pBuffer_size, uint8_t * pHash, size_t * pHash_size)
91*758e9fbaSOystein Eftevaag {
92*758e9fbaSOystein Eftevaag LOG_TRACE("called");
93*758e9fbaSOystein Eftevaag if (ccBuffer == NULL || pBuffer == NULL || pHash == NULL
94*758e9fbaSOystein Eftevaag || pHash_size == NULL) {
95*758e9fbaSOystein Eftevaag LOG_ERROR("Null-Pointer passed");
96*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_REFERENCE;
97*758e9fbaSOystein Eftevaag }
98*758e9fbaSOystein Eftevaag
99*758e9fbaSOystein Eftevaag IESYS_CRYPTO_CONTEXT_BLOB *cryptoContext;
100*758e9fbaSOystein Eftevaag
101*758e9fbaSOystein Eftevaag TSS2_RC r = iesys_crypto_hash_start(&cryptoContext, alg);
102*758e9fbaSOystein Eftevaag return_if_error(r, "Error");
103*758e9fbaSOystein Eftevaag
104*758e9fbaSOystein Eftevaag if (rcBuffer != NULL) {
105*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update(cryptoContext, &rcBuffer[0], 4);
106*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
107*758e9fbaSOystein Eftevaag }
108*758e9fbaSOystein Eftevaag
109*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update(cryptoContext, &ccBuffer[0], 4);
110*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
111*758e9fbaSOystein Eftevaag
112*758e9fbaSOystein Eftevaag if (name1 != NULL) {
113*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update2b(cryptoContext, (TPM2B *) name1);
114*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
115*758e9fbaSOystein Eftevaag }
116*758e9fbaSOystein Eftevaag
117*758e9fbaSOystein Eftevaag if (name2 != NULL) {
118*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update2b(cryptoContext, (TPM2B *) name2);
119*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
120*758e9fbaSOystein Eftevaag }
121*758e9fbaSOystein Eftevaag
122*758e9fbaSOystein Eftevaag if (name3 != NULL) {
123*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update2b(cryptoContext, (TPM2B *) name3);
124*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
125*758e9fbaSOystein Eftevaag }
126*758e9fbaSOystein Eftevaag
127*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update(cryptoContext, pBuffer, pBuffer_size);
128*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
129*758e9fbaSOystein Eftevaag
130*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_finish(&cryptoContext, pHash, pHash_size);
131*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
132*758e9fbaSOystein Eftevaag
133*758e9fbaSOystein Eftevaag return r;
134*758e9fbaSOystein Eftevaag
135*758e9fbaSOystein Eftevaag error:
136*758e9fbaSOystein Eftevaag iesys_crypto_hash_abort(&cryptoContext);
137*758e9fbaSOystein Eftevaag return r;
138*758e9fbaSOystein Eftevaag }
139*758e9fbaSOystein Eftevaag
140*758e9fbaSOystein Eftevaag /** Compute the HMAC for authorization.
141*758e9fbaSOystein Eftevaag *
142*758e9fbaSOystein Eftevaag * Based on the session nonces, caller nonce, TPM nonce, if used encryption and
143*758e9fbaSOystein Eftevaag * decryption nonce, the command parameter hash, and the session attributes the
144*758e9fbaSOystein Eftevaag * HMAC used for authorization is computed.
145*758e9fbaSOystein Eftevaag * @param[in] alg The hash algorithm used for HMAC computation.
146*758e9fbaSOystein Eftevaag * @param[in] hmacKey The HMAC key byte buffer.
147*758e9fbaSOystein Eftevaag * @param[in] hmacKeySize The size of the HMAC key byte buffer.
148*758e9fbaSOystein Eftevaag * @param[in] pHash The command parameter hash byte buffer.
149*758e9fbaSOystein Eftevaag * @param[in] pHash_size The size of the command parameter hash byte buffer.
150*758e9fbaSOystein Eftevaag * @param[in] nonceNewer The TPM nonce.
151*758e9fbaSOystein Eftevaag * @param[in] nonceOlder The caller nonce.
152*758e9fbaSOystein Eftevaag * @param[in] nonceDecrypt The decrypt nonce (NULL if not used).
153*758e9fbaSOystein Eftevaag * @param[in] nonceEncrypt The encrypt nonce (NULL if not used).
154*758e9fbaSOystein Eftevaag * @param[in] sessionAttributes The attributes used for the current
155*758e9fbaSOystein Eftevaag * authentication.
156*758e9fbaSOystein Eftevaag * @param[out] hmac The computed HMAC.
157*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS on success
158*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_BAD_REFERENCE If a pointer is invalid.
159*758e9fbaSOystein Eftevaag */
160*758e9fbaSOystein Eftevaag TSS2_RC
iesys_crypto_authHmac(TPM2_ALG_ID alg,uint8_t * hmacKey,size_t hmacKeySize,const uint8_t * pHash,size_t pHash_size,const TPM2B_NONCE * nonceNewer,const TPM2B_NONCE * nonceOlder,const TPM2B_NONCE * nonceDecrypt,const TPM2B_NONCE * nonceEncrypt,TPMA_SESSION sessionAttributes,TPM2B_AUTH * hmac)161*758e9fbaSOystein Eftevaag iesys_crypto_authHmac(TPM2_ALG_ID alg,
162*758e9fbaSOystein Eftevaag uint8_t * hmacKey, size_t hmacKeySize,
163*758e9fbaSOystein Eftevaag const uint8_t * pHash,
164*758e9fbaSOystein Eftevaag size_t pHash_size,
165*758e9fbaSOystein Eftevaag const TPM2B_NONCE * nonceNewer,
166*758e9fbaSOystein Eftevaag const TPM2B_NONCE * nonceOlder,
167*758e9fbaSOystein Eftevaag const TPM2B_NONCE * nonceDecrypt,
168*758e9fbaSOystein Eftevaag const TPM2B_NONCE * nonceEncrypt,
169*758e9fbaSOystein Eftevaag TPMA_SESSION sessionAttributes, TPM2B_AUTH * hmac)
170*758e9fbaSOystein Eftevaag {
171*758e9fbaSOystein Eftevaag LOG_TRACE("called");
172*758e9fbaSOystein Eftevaag if (hmacKey == NULL || pHash == NULL || nonceNewer == NULL ||
173*758e9fbaSOystein Eftevaag nonceOlder == NULL || hmac == NULL) {
174*758e9fbaSOystein Eftevaag LOG_ERROR("Null-Pointer passed");
175*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_REFERENCE;
176*758e9fbaSOystein Eftevaag }
177*758e9fbaSOystein Eftevaag
178*758e9fbaSOystein Eftevaag uint8_t sessionAttribs[sizeof(sessionAttributes)];
179*758e9fbaSOystein Eftevaag size_t sessionAttribs_size = 0;
180*758e9fbaSOystein Eftevaag
181*758e9fbaSOystein Eftevaag IESYS_CRYPTO_CONTEXT_BLOB *cryptoContext;
182*758e9fbaSOystein Eftevaag
183*758e9fbaSOystein Eftevaag TSS2_RC r =
184*758e9fbaSOystein Eftevaag iesys_crypto_hmac_start(&cryptoContext, alg, hmacKey, hmacKeySize);
185*758e9fbaSOystein Eftevaag return_if_error(r, "Error");
186*758e9fbaSOystein Eftevaag
187*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update(cryptoContext, pHash, pHash_size);
188*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
189*758e9fbaSOystein Eftevaag
190*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update2b(cryptoContext, (TPM2B *) nonceNewer);
191*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
192*758e9fbaSOystein Eftevaag
193*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update2b(cryptoContext, (TPM2B *) nonceOlder);
194*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
195*758e9fbaSOystein Eftevaag
196*758e9fbaSOystein Eftevaag if (nonceDecrypt != NULL) {
197*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update2b(cryptoContext, (TPM2B *) nonceDecrypt);
198*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
199*758e9fbaSOystein Eftevaag }
200*758e9fbaSOystein Eftevaag
201*758e9fbaSOystein Eftevaag if (nonceEncrypt != NULL) {
202*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update2b(cryptoContext, (TPM2B *) nonceEncrypt);
203*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
204*758e9fbaSOystein Eftevaag }
205*758e9fbaSOystein Eftevaag
206*758e9fbaSOystein Eftevaag r = Tss2_MU_TPMA_SESSION_Marshal(sessionAttributes,
207*758e9fbaSOystein Eftevaag &sessionAttribs[0],
208*758e9fbaSOystein Eftevaag sizeof(sessionAttribs),
209*758e9fbaSOystein Eftevaag &sessionAttribs_size);
210*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
211*758e9fbaSOystein Eftevaag
212*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update(cryptoContext, &sessionAttribs[0],
213*758e9fbaSOystein Eftevaag sessionAttribs_size);
214*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
215*758e9fbaSOystein Eftevaag
216*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_finish2b(&cryptoContext, (TPM2B *) hmac);
217*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
218*758e9fbaSOystein Eftevaag
219*758e9fbaSOystein Eftevaag return r;
220*758e9fbaSOystein Eftevaag
221*758e9fbaSOystein Eftevaag error:
222*758e9fbaSOystein Eftevaag iesys_crypto_hmac_abort(&cryptoContext);
223*758e9fbaSOystein Eftevaag return r;
224*758e9fbaSOystein Eftevaag
225*758e9fbaSOystein Eftevaag }
226*758e9fbaSOystein Eftevaag
227*758e9fbaSOystein Eftevaag /**
228*758e9fbaSOystein Eftevaag * HMAC computation for inner loop of KDFa key derivation.
229*758e9fbaSOystein Eftevaag *
230*758e9fbaSOystein Eftevaag * Except of ECDH this function is used for key derivation.
231*758e9fbaSOystein Eftevaag * @param[in] alg The algorithm used for the HMAC.
232*758e9fbaSOystein Eftevaag * @param[in] hmacKey The hmacKey used in KDFa.
233*758e9fbaSOystein Eftevaag * @param[in] hmacKeySize The size of the HMAC key.
234*758e9fbaSOystein Eftevaag * @param[in] counter The curren iteration step.
235*758e9fbaSOystein Eftevaag * @param[in] label Indicates the use of the produced key.
236*758e9fbaSOystein Eftevaag * @param[in] contextU, contextV are used for construction of a binary string
237*758e9fbaSOystein Eftevaag * containing information related to the derived key.
238*758e9fbaSOystein Eftevaag * @param[in] bitlength The size of the generated key in bits.
239*758e9fbaSOystein Eftevaag * @param[out] hmac Byte buffer for the generated HMAC key (caller-allocated).
240*758e9fbaSOystein Eftevaag * @param[out] hmacSize Size of the generated HMAC key.
241*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS on success.
242*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
243*758e9fbaSOystein Eftevaag */
244*758e9fbaSOystein Eftevaag TSS2_RC
iesys_crypto_KDFaHmac(TPM2_ALG_ID alg,uint8_t * hmacKey,size_t hmacKeySize,uint32_t counter,const char * label,TPM2B_NONCE * contextU,TPM2B_NONCE * contextV,uint32_t bitlength,uint8_t * hmac,size_t * hmacSize)245*758e9fbaSOystein Eftevaag iesys_crypto_KDFaHmac(TPM2_ALG_ID alg,
246*758e9fbaSOystein Eftevaag uint8_t * hmacKey,
247*758e9fbaSOystein Eftevaag size_t hmacKeySize,
248*758e9fbaSOystein Eftevaag uint32_t counter,
249*758e9fbaSOystein Eftevaag const char *label,
250*758e9fbaSOystein Eftevaag TPM2B_NONCE * contextU,
251*758e9fbaSOystein Eftevaag TPM2B_NONCE * contextV,
252*758e9fbaSOystein Eftevaag uint32_t bitlength, uint8_t * hmac, size_t * hmacSize)
253*758e9fbaSOystein Eftevaag {
254*758e9fbaSOystein Eftevaag LOG_TRACE("called");
255*758e9fbaSOystein Eftevaag if (hmacKey == NULL || contextU == NULL || contextV == NULL) {
256*758e9fbaSOystein Eftevaag LOG_ERROR("Null-Pointer passed");
257*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_REFERENCE;
258*758e9fbaSOystein Eftevaag }
259*758e9fbaSOystein Eftevaag
260*758e9fbaSOystein Eftevaag uint8_t buffer32[sizeof(uint32_t)];
261*758e9fbaSOystein Eftevaag size_t buffer32_size = 0;
262*758e9fbaSOystein Eftevaag
263*758e9fbaSOystein Eftevaag IESYS_CRYPTO_CONTEXT_BLOB *cryptoContext;
264*758e9fbaSOystein Eftevaag
265*758e9fbaSOystein Eftevaag TSS2_RC r =
266*758e9fbaSOystein Eftevaag iesys_crypto_hmac_start(&cryptoContext, alg, hmacKey, hmacKeySize);
267*758e9fbaSOystein Eftevaag return_if_error(r, "Error");
268*758e9fbaSOystein Eftevaag
269*758e9fbaSOystein Eftevaag r = Tss2_MU_UINT32_Marshal(counter, &buffer32[0], sizeof(UINT32),
270*758e9fbaSOystein Eftevaag &buffer32_size);
271*758e9fbaSOystein Eftevaag goto_if_error(r, "Marsahling", error);
272*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update(cryptoContext, &buffer32[0], buffer32_size);
273*758e9fbaSOystein Eftevaag goto_if_error(r, "HMAC-Update", error);
274*758e9fbaSOystein Eftevaag
275*758e9fbaSOystein Eftevaag if (label != NULL) {
276*758e9fbaSOystein Eftevaag size_t lsize = strlen(label) + 1;
277*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update(cryptoContext, (uint8_t *) label, lsize);
278*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
279*758e9fbaSOystein Eftevaag }
280*758e9fbaSOystein Eftevaag
281*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update2b(cryptoContext, (TPM2B *) contextU);
282*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
283*758e9fbaSOystein Eftevaag
284*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update2b(cryptoContext, (TPM2B *) contextV);
285*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
286*758e9fbaSOystein Eftevaag
287*758e9fbaSOystein Eftevaag buffer32_size = 0;
288*758e9fbaSOystein Eftevaag r = Tss2_MU_UINT32_Marshal(bitlength, &buffer32[0], sizeof(UINT32),
289*758e9fbaSOystein Eftevaag &buffer32_size);
290*758e9fbaSOystein Eftevaag goto_if_error(r, "Marsahling", error);
291*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_update(cryptoContext, &buffer32[0], buffer32_size);
292*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
293*758e9fbaSOystein Eftevaag
294*758e9fbaSOystein Eftevaag r = iesys_crypto_hmac_finish(&cryptoContext, hmac, hmacSize);
295*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
296*758e9fbaSOystein Eftevaag
297*758e9fbaSOystein Eftevaag return r;
298*758e9fbaSOystein Eftevaag
299*758e9fbaSOystein Eftevaag error:
300*758e9fbaSOystein Eftevaag iesys_crypto_hmac_abort(&cryptoContext);
301*758e9fbaSOystein Eftevaag return r;
302*758e9fbaSOystein Eftevaag }
303*758e9fbaSOystein Eftevaag
304*758e9fbaSOystein Eftevaag /**
305*758e9fbaSOystein Eftevaag * KDFa Key derivation.
306*758e9fbaSOystein Eftevaag *
307*758e9fbaSOystein Eftevaag * Except of ECDH this function is used for key derivation.
308*758e9fbaSOystein Eftevaag * @param[in] hashAlg The hash algorithm to use.
309*758e9fbaSOystein Eftevaag * @param[in] hmacKey The hmacKey used in KDFa.
310*758e9fbaSOystein Eftevaag * @param[in] hmacKeySize The size of the HMAC key.
311*758e9fbaSOystein Eftevaag * @param[in] label Indicates the use of the produced key.
312*758e9fbaSOystein Eftevaag * @param[in] contextU, contextV are used for construction of a binary string
313*758e9fbaSOystein Eftevaag * containing information related to the derived key.
314*758e9fbaSOystein Eftevaag * @param[in] bitLength The size of generated key in bits.
315*758e9fbaSOystein Eftevaag * @param[in,out] counterInOut Counter for the KDFa iterations. If set, the
316*758e9fbaSOystein Eftevaag * value will be used for the firt iteration step. The final
317*758e9fbaSOystein Eftevaag * counter value will be written to counterInOut.
318*758e9fbaSOystein Eftevaag * @param[out] outKey Byte buffer for the derived key (caller-allocated).
319*758e9fbaSOystein Eftevaag * @param[in] use_digest_size Indicate whether the digest size of hashAlg is
320*758e9fbaSOystein Eftevaag * used as size of the generated key or the bitLength parameter is
321*758e9fbaSOystein Eftevaag * used.
322*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS on success.
323*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_BAD_VALUE if hashAlg is unknown or unsupported.
324*758e9fbaSOystein Eftevaag */
325*758e9fbaSOystein Eftevaag TSS2_RC
iesys_crypto_KDFa(TPM2_ALG_ID hashAlg,uint8_t * hmacKey,size_t hmacKeySize,const char * label,TPM2B_NONCE * contextU,TPM2B_NONCE * contextV,uint32_t bitLength,uint32_t * counterInOut,BYTE * outKey,BOOL use_digest_size)326*758e9fbaSOystein Eftevaag iesys_crypto_KDFa(TPM2_ALG_ID hashAlg,
327*758e9fbaSOystein Eftevaag uint8_t * hmacKey,
328*758e9fbaSOystein Eftevaag size_t hmacKeySize,
329*758e9fbaSOystein Eftevaag const char *label,
330*758e9fbaSOystein Eftevaag TPM2B_NONCE * contextU,
331*758e9fbaSOystein Eftevaag TPM2B_NONCE * contextV,
332*758e9fbaSOystein Eftevaag uint32_t bitLength,
333*758e9fbaSOystein Eftevaag uint32_t * counterInOut,
334*758e9fbaSOystein Eftevaag BYTE * outKey,
335*758e9fbaSOystein Eftevaag BOOL use_digest_size)
336*758e9fbaSOystein Eftevaag {
337*758e9fbaSOystein Eftevaag LOG_DEBUG("IESYS KDFa hmac key hashAlg: %i label: %s bitLength: %i",
338*758e9fbaSOystein Eftevaag hashAlg, label, bitLength);
339*758e9fbaSOystein Eftevaag if (counterInOut != NULL)
340*758e9fbaSOystein Eftevaag LOG_TRACE("IESYS KDFa hmac key counterInOut: %i", *counterInOut);
341*758e9fbaSOystein Eftevaag LOGBLOB_DEBUG(hmacKey, hmacKeySize, "IESYS KDFa hmac key");
342*758e9fbaSOystein Eftevaag
343*758e9fbaSOystein Eftevaag LOGBLOB_DEBUG(&contextU->buffer[0], contextU->size,
344*758e9fbaSOystein Eftevaag "IESYS KDFa contextU key");
345*758e9fbaSOystein Eftevaag LOGBLOB_DEBUG(&contextV->buffer[0], contextV->size,
346*758e9fbaSOystein Eftevaag "IESYS KDFa contextV key");
347*758e9fbaSOystein Eftevaag BYTE *subKey = outKey;
348*758e9fbaSOystein Eftevaag UINT32 counter = 0;
349*758e9fbaSOystein Eftevaag INT32 bytes = 0;
350*758e9fbaSOystein Eftevaag size_t hlen = 0;
351*758e9fbaSOystein Eftevaag TSS2_RC r = iesys_crypto_hash_get_digest_size(hashAlg, &hlen);
352*758e9fbaSOystein Eftevaag return_if_error(r, "Error");
353*758e9fbaSOystein Eftevaag if (counterInOut != NULL)
354*758e9fbaSOystein Eftevaag counter = *counterInOut;
355*758e9fbaSOystein Eftevaag bytes = use_digest_size ? hlen : (bitLength + 7) / 8;
356*758e9fbaSOystein Eftevaag LOG_DEBUG("IESYS KDFa hmac key bytes: %i", bytes);
357*758e9fbaSOystein Eftevaag
358*758e9fbaSOystein Eftevaag /* Fill outKey with results from KDFaHmac */
359*758e9fbaSOystein Eftevaag for (; bytes > 0; subKey = &subKey[hlen], bytes = bytes - hlen) {
360*758e9fbaSOystein Eftevaag LOG_TRACE("IESYS KDFa hmac key bytes: %i", bytes);
361*758e9fbaSOystein Eftevaag //if(bytes < (INT32)hlen)
362*758e9fbaSOystein Eftevaag // hlen = bytes;
363*758e9fbaSOystein Eftevaag counter++;
364*758e9fbaSOystein Eftevaag r = iesys_crypto_KDFaHmac(hashAlg, hmacKey,
365*758e9fbaSOystein Eftevaag hmacKeySize, counter, label, contextU,
366*758e9fbaSOystein Eftevaag contextV, bitLength, &subKey[0], &hlen);
367*758e9fbaSOystein Eftevaag return_if_error(r, "Error");
368*758e9fbaSOystein Eftevaag }
369*758e9fbaSOystein Eftevaag if ((bitLength % 8) != 0)
370*758e9fbaSOystein Eftevaag outKey[0] &= ((1 << (bitLength % 8)) - 1);
371*758e9fbaSOystein Eftevaag if (counterInOut != NULL)
372*758e9fbaSOystein Eftevaag *counterInOut = counter;
373*758e9fbaSOystein Eftevaag LOGBLOB_DEBUG(outKey, (bitLength + 7) / 8, "IESYS KDFa key");
374*758e9fbaSOystein Eftevaag return TPM2_RC_SUCCESS;
375*758e9fbaSOystein Eftevaag }
376*758e9fbaSOystein Eftevaag
377*758e9fbaSOystein Eftevaag /** Compute KDFe as described in TPM spec part 1 C 6.1
378*758e9fbaSOystein Eftevaag *
379*758e9fbaSOystein Eftevaag * @param hashAlg [in] The nameAlg of the recipient key.
380*758e9fbaSOystein Eftevaag * @param Z [in] the x coordinate (xP) of the product (P) of a public point and a
381*758e9fbaSOystein Eftevaag * private key.
382*758e9fbaSOystein Eftevaag * @param label [in] KDF label.
383*758e9fbaSOystein Eftevaag * @param partyUInfo [in] The x-coordinate of the secret exchange value (Qe,U).
384*758e9fbaSOystein Eftevaag * @param partyVInfo [in] The x-coordinate of a public key (Qs,V).
385*758e9fbaSOystein Eftevaag * @param bit_size [in] Bit size of generated key.
386*758e9fbaSOystein Eftevaag * @param key [out] Key buffer.
387*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS on success
388*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters
389*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_MEMORY Memory cannot be allocated.
390*758e9fbaSOystein Eftevaag */
391*758e9fbaSOystein Eftevaag TSS2_RC
iesys_crypto_KDFe(TPM2_ALG_ID hashAlg,TPM2B_ECC_PARAMETER * Z,const char * label,TPM2B_ECC_PARAMETER * partyUInfo,TPM2B_ECC_PARAMETER * partyVInfo,UINT32 bit_size,BYTE * key)392*758e9fbaSOystein Eftevaag iesys_crypto_KDFe(TPM2_ALG_ID hashAlg,
393*758e9fbaSOystein Eftevaag TPM2B_ECC_PARAMETER *Z,
394*758e9fbaSOystein Eftevaag const char *label,
395*758e9fbaSOystein Eftevaag TPM2B_ECC_PARAMETER *partyUInfo,
396*758e9fbaSOystein Eftevaag TPM2B_ECC_PARAMETER *partyVInfo,
397*758e9fbaSOystein Eftevaag UINT32 bit_size,
398*758e9fbaSOystein Eftevaag BYTE *key)
399*758e9fbaSOystein Eftevaag {
400*758e9fbaSOystein Eftevaag TSS2_RC r = TSS2_RC_SUCCESS;
401*758e9fbaSOystein Eftevaag size_t hash_len;
402*758e9fbaSOystein Eftevaag INT16 byte_size = (INT16)((bit_size +7) / 8);
403*758e9fbaSOystein Eftevaag BYTE *stream = key;
404*758e9fbaSOystein Eftevaag IESYS_CRYPTO_CONTEXT_BLOB *cryptoContext;
405*758e9fbaSOystein Eftevaag BYTE counter_buffer[4];
406*758e9fbaSOystein Eftevaag UINT32 counter = 0;
407*758e9fbaSOystein Eftevaag size_t offset;
408*758e9fbaSOystein Eftevaag
409*758e9fbaSOystein Eftevaag LOG_DEBUG("IESYS KDFe hashAlg: %i label: %s bitLength: %i",
410*758e9fbaSOystein Eftevaag hashAlg, label, bit_size);
411*758e9fbaSOystein Eftevaag if (partyUInfo != NULL)
412*758e9fbaSOystein Eftevaag LOGBLOB_DEBUG(&partyUInfo->buffer[0], partyUInfo->size, "partyUInfo");
413*758e9fbaSOystein Eftevaag if (partyVInfo != NULL)
414*758e9fbaSOystein Eftevaag LOGBLOB_DEBUG(&partyVInfo->buffer[0], partyVInfo->size, "partyVInfo");
415*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_get_digest_size(hashAlg, &hash_len);
416*758e9fbaSOystein Eftevaag return_if_error(r, "Hash algorithm not supported.");
417*758e9fbaSOystein Eftevaag
418*758e9fbaSOystein Eftevaag if(hashAlg == TPM2_ALG_NULL || byte_size == 0) {
419*758e9fbaSOystein Eftevaag LOG_DEBUG("Bad parameters for KDFe");
420*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_VALUE;
421*758e9fbaSOystein Eftevaag }
422*758e9fbaSOystein Eftevaag
423*758e9fbaSOystein Eftevaag /* Fill seed key with hash of counter, Z, label, partyUInfo, and partyVInfo */
424*758e9fbaSOystein Eftevaag for (; byte_size > 0; stream = &stream[hash_len], byte_size = byte_size - hash_len)
425*758e9fbaSOystein Eftevaag {
426*758e9fbaSOystein Eftevaag counter ++;
427*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_start(&cryptoContext, hashAlg);
428*758e9fbaSOystein Eftevaag return_if_error(r, "Error hash start");
429*758e9fbaSOystein Eftevaag
430*758e9fbaSOystein Eftevaag offset = 0;
431*758e9fbaSOystein Eftevaag r = Tss2_MU_UINT32_Marshal(counter, &counter_buffer[0], 4, &offset);
432*758e9fbaSOystein Eftevaag goto_if_error(r, "Error marshaling counter", error);
433*758e9fbaSOystein Eftevaag
434*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update(cryptoContext, &counter_buffer[0], 4);
435*758e9fbaSOystein Eftevaag goto_if_error(r, "Error hash update", error);
436*758e9fbaSOystein Eftevaag
437*758e9fbaSOystein Eftevaag if (Z != NULL) {
438*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update2b(cryptoContext, (TPM2B *) Z);
439*758e9fbaSOystein Eftevaag goto_if_error(r, "Error hash update2b", error);
440*758e9fbaSOystein Eftevaag }
441*758e9fbaSOystein Eftevaag
442*758e9fbaSOystein Eftevaag if (label != NULL) {
443*758e9fbaSOystein Eftevaag size_t lsize = strlen(label) + 1;
444*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update(cryptoContext, (uint8_t *) label, lsize);
445*758e9fbaSOystein Eftevaag goto_if_error(r, "Error hash update", error);
446*758e9fbaSOystein Eftevaag }
447*758e9fbaSOystein Eftevaag
448*758e9fbaSOystein Eftevaag if (partyUInfo != NULL) {
449*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update2b(cryptoContext, (TPM2B *) partyUInfo);
450*758e9fbaSOystein Eftevaag goto_if_error(r, "Error hash update2b", error);
451*758e9fbaSOystein Eftevaag }
452*758e9fbaSOystein Eftevaag
453*758e9fbaSOystein Eftevaag if (partyVInfo != NULL) {
454*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_update2b(cryptoContext, (TPM2B *) partyVInfo);
455*758e9fbaSOystein Eftevaag goto_if_error(r, "Error hash update2b", error);
456*758e9fbaSOystein Eftevaag }
457*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_finish(&cryptoContext, (uint8_t *) stream, &hash_len);
458*758e9fbaSOystein Eftevaag goto_if_error(r, "Error", error);
459*758e9fbaSOystein Eftevaag }
460*758e9fbaSOystein Eftevaag LOGBLOB_DEBUG(key, bit_size/8, "Result KDFe");
461*758e9fbaSOystein Eftevaag if((bit_size % 8) != 0)
462*758e9fbaSOystein Eftevaag key[0] &= ((1 << (bit_size % 8)) - 1);
463*758e9fbaSOystein Eftevaag return r;
464*758e9fbaSOystein Eftevaag
465*758e9fbaSOystein Eftevaag error:
466*758e9fbaSOystein Eftevaag iesys_crypto_hmac_abort(&cryptoContext);
467*758e9fbaSOystein Eftevaag return r;
468*758e9fbaSOystein Eftevaag }
469*758e9fbaSOystein Eftevaag
470*758e9fbaSOystein Eftevaag /** Encryption/Decryption using XOR obfuscation.
471*758e9fbaSOystein Eftevaag *
472*758e9fbaSOystein Eftevaag * The application of this function to data encrypted with this function will
473*758e9fbaSOystein Eftevaag * produce the origin data. The key for XOR obfuscation will be derived with
474*758e9fbaSOystein Eftevaag * KDFa form the passed key the session nonces, and the hash algorithm.
475*758e9fbaSOystein Eftevaag * @param[in] hash_alg The algorithm used for key derivation.
476*758e9fbaSOystein Eftevaag * @param[in] key key used for obfuscation
477*758e9fbaSOystein Eftevaag * @param[in] key_size Key size in bits.
478*758e9fbaSOystein Eftevaag * @param[in] contextU, contextV are used for construction of a binary string
479*758e9fbaSOystein Eftevaag * containing information related to the derived key.
480*758e9fbaSOystein Eftevaag * @param[in,out] data Data to be encrypted/decrypted the result will be
481*758e9fbaSOystein Eftevaag * will be stored in this buffer.
482*758e9fbaSOystein Eftevaag * @param[in] data_size size of data to be encrypted/decrypted.
483*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and
484*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters.
485*758e9fbaSOystein Eftevaag */
486*758e9fbaSOystein Eftevaag TSS2_RC
iesys_xor_parameter_obfuscation(TPM2_ALG_ID hash_alg,uint8_t * key,size_t key_size,TPM2B_NONCE * contextU,TPM2B_NONCE * contextV,BYTE * data,size_t data_size)487*758e9fbaSOystein Eftevaag iesys_xor_parameter_obfuscation(TPM2_ALG_ID hash_alg,
488*758e9fbaSOystein Eftevaag uint8_t *key,
489*758e9fbaSOystein Eftevaag size_t key_size,
490*758e9fbaSOystein Eftevaag TPM2B_NONCE * contextU,
491*758e9fbaSOystein Eftevaag TPM2B_NONCE * contextV,
492*758e9fbaSOystein Eftevaag BYTE *data,
493*758e9fbaSOystein Eftevaag size_t data_size)
494*758e9fbaSOystein Eftevaag {
495*758e9fbaSOystein Eftevaag TSS2_RC r;
496*758e9fbaSOystein Eftevaag uint32_t counter = 0;
497*758e9fbaSOystein Eftevaag BYTE kdfa_result[TPM2_MAX_DIGEST_BUFFER];
498*758e9fbaSOystein Eftevaag size_t digest_size;
499*758e9fbaSOystein Eftevaag size_t data_size_bits = data_size * 8;
500*758e9fbaSOystein Eftevaag size_t rest_size = data_size;
501*758e9fbaSOystein Eftevaag BYTE *kdfa_byte_ptr;
502*758e9fbaSOystein Eftevaag
503*758e9fbaSOystein Eftevaag if (key == NULL || data == NULL) {
504*758e9fbaSOystein Eftevaag LOG_ERROR("Bad reference");
505*758e9fbaSOystein Eftevaag return TSS2_ESYS_RC_BAD_REFERENCE;
506*758e9fbaSOystein Eftevaag }
507*758e9fbaSOystein Eftevaag
508*758e9fbaSOystein Eftevaag r = iesys_crypto_hash_get_digest_size(hash_alg, &digest_size);
509*758e9fbaSOystein Eftevaag return_if_error(r, "Hash alg not supported");
510*758e9fbaSOystein Eftevaag while(rest_size > 0) {
511*758e9fbaSOystein Eftevaag r = iesys_crypto_KDFa(hash_alg, key, key_size, "XOR",
512*758e9fbaSOystein Eftevaag contextU, contextV, data_size_bits, &counter,
513*758e9fbaSOystein Eftevaag kdfa_result, TRUE);
514*758e9fbaSOystein Eftevaag return_if_error(r, "iesys_crypto_KDFa failed");
515*758e9fbaSOystein Eftevaag /* XOR next data sub block with KDFa result */
516*758e9fbaSOystein Eftevaag kdfa_byte_ptr = kdfa_result;
517*758e9fbaSOystein Eftevaag LOGBLOB_TRACE(data, data_size, "Parameter data before XOR");
518*758e9fbaSOystein Eftevaag for(size_t i = digest_size < rest_size ? digest_size : rest_size; i > 0;
519*758e9fbaSOystein Eftevaag i--)
520*758e9fbaSOystein Eftevaag *data++ ^= *kdfa_byte_ptr++;
521*758e9fbaSOystein Eftevaag LOGBLOB_TRACE(data, data_size, "Parameter data after XOR");
522*758e9fbaSOystein Eftevaag rest_size = rest_size < digest_size ? 0 : rest_size - digest_size;
523*758e9fbaSOystein Eftevaag }
524*758e9fbaSOystein Eftevaag return TSS2_RC_SUCCESS;
525*758e9fbaSOystein Eftevaag }
526*758e9fbaSOystein Eftevaag
527*758e9fbaSOystein Eftevaag
528*758e9fbaSOystein Eftevaag /** Initialize crypto backend.
529*758e9fbaSOystein Eftevaag *
530*758e9fbaSOystein Eftevaag * Initialize internal tables of crypto backend.
531*758e9fbaSOystein Eftevaag *
532*758e9fbaSOystein Eftevaag * @retval TSS2_RC_SUCCESS ong success.
533*758e9fbaSOystein Eftevaag * @retval TSS2_ESYS_RC_GENERAL_FAILURE if backend can't be initialized.
534*758e9fbaSOystein Eftevaag */
535*758e9fbaSOystein Eftevaag TSS2_RC
iesys_initialize_crypto()536*758e9fbaSOystein Eftevaag iesys_initialize_crypto() {
537*758e9fbaSOystein Eftevaag return iesys_crypto_init();
538*758e9fbaSOystein Eftevaag }
539