]> git.proxmox.com Git - libtpms.git/blame - src/tpm2/crypto/openssl/Helpers.c
tpm2: Leave notes in code about Nonces that may have leading zeros
[libtpms.git] / src / tpm2 / crypto / openssl / Helpers.c
CommitLineData
8de7f334
SB
1/********************************************************************************/
2/* */
3/* OpenSSL helper functions */
4/* Written by Stefan Berger */
5/* IBM Thomas J. Watson Research Center */
6/* */
7/* Licenses and Notices */
8/* */
9/* 1. Copyright Licenses: */
10/* */
11/* - Trusted Computing Group (TCG) grants to the user of the source code in */
12/* this specification (the "Source Code") a worldwide, irrevocable, */
13/* nonexclusive, royalty free, copyright license to reproduce, create */
14/* derivative works, distribute, display and perform the Source Code and */
15/* derivative works thereof, and to grant others the rights granted herein. */
16/* */
17/* - The TCG grants to the user of the other parts of the specification */
18/* (other than the Source Code) the rights to reproduce, distribute, */
19/* display, and perform the specification solely for the purpose of */
20/* developing products based on such documents. */
21/* */
22/* 2. Source Code Distribution Conditions: */
23/* */
24/* - Redistributions of Source Code must retain the above copyright licenses, */
25/* this list of conditions and the following disclaimers. */
26/* */
27/* - Redistributions in binary form must reproduce the above copyright */
28/* licenses, this list of conditions and the following disclaimers in the */
29/* documentation and/or other materials provided with the distribution. */
30/* */
31/* 3. Disclaimers: */
32/* */
33/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
34/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
35/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
36/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
37/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
38/* information on specification licensing rights available through TCG */
39/* membership agreements. */
40/* */
41/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
42/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
43/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
44/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
45/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
46/* */
47/* - Without limitation, TCG and its members and licensors disclaim all */
48/* liability, including liability for infringement of any proprietary */
49/* rights, relating to use of information in this specification and to the */
50/* implementation of this specification, and TCG disclaims all liability for */
51/* cost of procurement of substitute goods or services, lost profits, loss */
52/* of use, loss of data or any incidental, consequential, direct, indirect, */
53/* or special damages, whether under contract, tort, warranty or otherwise, */
54/* arising in any way out of use or reliance upon this specification or any */
55/* information herein. */
56/* */
57/* (c) Copyright IBM Corp. and others, 2019 */
58/* */
59/********************************************************************************/
60
61#include "Tpm.h"
62#include "Helpers_fp.h"
afbb3274 63#include "TpmToOsslMath_fp.h"
8de7f334 64
bc681a1b
SB
65#include "config.h"
66
8de7f334 67#include <openssl/evp.h>
a572dbc4 68#include <openssl/rsa.h>
8de7f334 69
4e1cd261 70#if USE_OPENSSL_FUNCTIONS_SYMMETRIC
8de7f334 71
fee2ae97
SB
72TPM_RC
73OpenSSLCryptGenerateKeyDes(
74 TPMT_SENSITIVE *sensitive // OUT: sensitive area
75 )
76{
77 DES_cblock *key;
78 size_t offset;
79 size_t limit;
80
81 limit = MIN(sizeof(sensitive->sensitive.sym.t.buffer),
82 sensitive->sensitive.sym.t.size);
83 limit = TPM2_ROUNDUP(limit, sizeof(*key));
84 pAssert(limit < sizeof(sensitive->sensitive.sym.t.buffer));
85
86 for (offset = 0; offset < limit; offset += sizeof(*key)) {
87 key = (DES_cblock *)&sensitive->sensitive.sym.t.buffer[offset];
88 if (DES_random_key(key) != 1)
89 return TPM_RC_NO_RESULT;
90 }
91 return TPM_RC_SUCCESS;
92}
93
8de7f334
SB
94evpfunc GetEVPCipher(TPM_ALG_ID algorithm, // IN
95 UINT16 keySizeInBits, // IN
96 TPM_ALG_ID mode, // IN
97 const BYTE *key, // IN
98 BYTE *keyToUse, // OUT same as key or stretched key
99 UINT16 *keyToUseLen // IN/OUT
100 )
101{
102 int i;
103 UINT16 keySizeInBytes = keySizeInBits / 8;
104 evpfunc evpfn = NULL;
105
106 // key size to array index: 128 -> 0, 192 -> 1, 256 -> 2
107 i = (keySizeInBits >> 6) - 2;
108 if (i < 0 || i > 2)
109 return NULL;
110
111 pAssert(*keyToUseLen >= keySizeInBytes)
112 memcpy(keyToUse, key, keySizeInBytes);
113
114 switch (algorithm) {
115#if ALG_AES
116 case TPM_ALG_AES:
117 *keyToUseLen = keySizeInBytes;
118 switch (mode) {
119#if ALG_CTR
120 case ALG_CTR_VALUE:
121 evpfn = (evpfunc []){EVP_aes_128_ctr, EVP_aes_192_ctr,
122 EVP_aes_256_ctr}[i];
123 break;
124#endif
125#if ALG_OFB
126 case ALG_OFB_VALUE:
127 evpfn = (evpfunc[]){EVP_aes_128_ofb, EVP_aes_192_ofb,
128 EVP_aes_256_ofb}[i];
129 break;
130#endif
131#if ALG_CBC
132 case ALG_CBC_VALUE:
133 evpfn = (evpfunc[]){EVP_aes_128_cbc, EVP_aes_192_cbc,
134 EVP_aes_256_cbc}[i];
135 break;
136#endif
137#if ALG_CFB
138 case ALG_CFB_VALUE:
139 evpfn = (evpfunc[]){EVP_aes_128_cfb, EVP_aes_192_cfb,
140 EVP_aes_256_cfb}[i];
141 break;
142#endif
143#if ALG_ECB
144 case ALG_ECB_VALUE:
145 evpfn = (evpfunc[]){EVP_aes_128_ecb, EVP_aes_192_ecb,
146 EVP_aes_256_ecb}[i];
147 break;
148#endif
149 }
150 break;
151#endif
152#if ALG_TDES
153 case TPM_ALG_TDES:
154 if (keySizeInBits == 128) {
155 pAssert(*keyToUseLen >= BITS_TO_BYTES(192))
156 // stretch the key
157 memcpy(&keyToUse[16], &keyToUse[0], 8);
158 *keyToUseLen = BITS_TO_BYTES(192);
159 }
160
161 switch (mode) {
162#if ALG_CTR
163 case ALG_CTR_VALUE:
164 evpfn = (evpfunc[]){EVP_des_ede3, EVP_des_ede3, NULL}[i];
165 break;
166#endif
167#if ALG_OFB
168 case ALG_OFB_VALUE:
169 evpfn = (evpfunc[]){EVP_des_ede3_ofb, EVP_des_ede3_ofb, NULL}[i];
170 break;
171#endif
172#if ALG_CBC
173 case ALG_CBC_VALUE:
174 evpfn = (evpfunc[]){EVP_des_ede3_cbc, EVP_des_ede3_cbc, NULL}[i];
175 break;
176#endif
177#if ALG_CFB
178 case ALG_CFB_VALUE:
179 evpfn = (evpfunc[]){EVP_des_ede3_cfb64, EVP_des_ede3_cfb64, NULL}[i];
180 break;
181#endif
182#if ALG_ECB
183 case ALG_ECB_VALUE:
184 evpfn = (evpfunc[]){EVP_des_ede3_ecb, EVP_des_ede3_ecb, NULL}[i];
185 break;
186#endif
8d68e403
SB
187 }
188 break;
8de7f334 189#endif
8d68e403 190
8de7f334 191#if ALG_SM4
8de7f334 192 case TPM_ALG_SM4:
5f0e2aef
SB
193 *keyToUseLen = keySizeInBytes;
194 switch (mode) {
195#if ALG_CTR
196 case ALG_CTR_VALUE:
197 evpfn = (evpfunc[]){EVP_sm4_ctr, NULL, NULL}[i];
198 break;
199#endif
200#if ALG_OFB
201 case ALG_OFB_VALUE:
202 evpfn = (evpfunc[]){EVP_sm4_ofb, NULL, NULL}[i];
203 break;
204#endif
205#if ALG_CBC
206 case ALG_CBC_VALUE:
207 evpfn = (evpfunc[]){EVP_sm4_cbc, NULL, NULL}[i];
208 break;
209#endif
210#if ALG_CFB
211 case ALG_CFB_VALUE:
212 evpfn = (evpfunc[]){EVP_sm4_cfb, NULL, NULL}[i];
213 break;
214#endif
215#if ALG_ECB
216 case ALG_ECB_VALUE:
217 evpfn = (evpfunc[]){EVP_sm4_ecb, NULL, NULL}[i];
218 break;
219#endif
220 }
8de7f334
SB
221 break;
222#endif
8d68e403 223
8de7f334 224#if ALG_CAMELLIA
8de7f334 225 case TPM_ALG_CAMELLIA:
15687b63
SB
226 *keyToUseLen = keySizeInBytes;
227 switch (mode) {
228#if ALG_CTR
229 case ALG_CTR_VALUE:
230 evpfn = (evpfunc []){EVP_camellia_128_ctr, EVP_camellia_192_ctr,
231 EVP_camellia_256_ctr}[i];
232 break;
233#endif
234#if ALG_OFB
235 case ALG_OFB_VALUE:
236 evpfn = (evpfunc[]){EVP_camellia_128_ofb, EVP_camellia_192_ofb,
237 EVP_camellia_256_ofb}[i];
238 break;
239#endif
240#if ALG_CBC
241 case ALG_CBC_VALUE:
242 evpfn = (evpfunc[]){EVP_camellia_128_cbc, EVP_camellia_192_cbc,
243 EVP_camellia_256_cbc}[i];
244 break;
245#endif
246#if ALG_CFB
247 case ALG_CFB_VALUE:
248 evpfn = (evpfunc[]){EVP_camellia_128_cfb, EVP_camellia_192_cfb,
249 EVP_camellia_256_cfb}[i];
250 break;
251#endif
252#if ALG_ECB
253 case ALG_ECB_VALUE:
254 evpfn = (evpfunc[]){EVP_camellia_128_ecb, EVP_camellia_192_ecb,
255 EVP_camellia_256_ecb}[i];
256 break;
257#endif
258 }
8de7f334
SB
259 break;
260#endif
261 }
262
263 if (evpfn == NULL)
264 MemorySet(keyToUse, 0, *keyToUseLen);
265
266 return evpfn;
267}
268
4e1cd261 269#endif // USE_OPENSSL_FUNCTIONS_SYMMETRIC
afbb3274
SB
270
271#if USE_OPENSSL_FUNCTIONS_EC
272BOOL
273OpenSSLEccGetPrivate(
274 bigNum dOut, // OUT: the qualified random value
275 const EC_GROUP *G // IN: the EC_GROUP to use
276 )
277{
278 BOOL OK = FALSE;
279 const BIGNUM *D;
280 EC_KEY *eckey = EC_KEY_new();
281
282 pAssert(G != NULL);
283
284 if (!eckey)
285 return FALSE;
286
287 if (EC_KEY_set_group(eckey, G) != 1)
288 goto Exit;
289
290 if (EC_KEY_generate_key(eckey) == 1) {
291 OK = TRUE;
292 D = EC_KEY_get0_private_key(eckey);
293 OsslToTpmBn(dOut, D);
294 }
295
296 Exit:
297 EC_KEY_free(eckey);
298
299 return OK;
300}
301#endif // USE_OPENSSL_FUNCTIONS_EC
bc681a1b
SB
302
303#if USE_OPENSSL_FUNCTIONS_RSA
304
305static const struct hnames {
306 const char *name;
307 TPM_ALG_ID hashAlg;
308} hnames[HASH_COUNT + 1] = {
309 {
310#if ALG_SHA1
311 .name = "sha1",
312 .hashAlg = ALG_SHA1_VALUE,
313 }, {
314#endif
315#if ALG_SHA256
316 .name = "sha256",
317 .hashAlg = ALG_SHA256_VALUE,
318 }, {
319#endif
320#if ALG_SHA384
321 .name = "sha384",
322 .hashAlg = ALG_SHA384_VALUE,
323 }, {
324#endif
325#if ALG_SHA512
326 .name = "sha512",
327 .hashAlg = ALG_SHA512_VALUE,
328 }, {
329#endif
330 .name = NULL,
331 }
332};
333#if HASH_COUNT != ALG_SHA1 + ALG_SHA256 + ALG_SHA384 + ALG_SHA512
334# error Missing entry in hnames array!
335#endif
336
337LIB_EXPORT const char *
338GetDigestNameByHashAlg(const TPM_ALG_ID hashAlg)
339{
340 unsigned i;
341
342 for (i = 0; i < HASH_COUNT; i++) {
343 if (hashAlg == hnames[i].hashAlg)
344 return hnames[i].name;
345 }
346 return NULL;
347}
348
a572dbc4
SB
349static BOOL
350ComputePrivateExponentD(
351 const BIGNUM *P, // IN: first prime (size is 1/2 of bnN)
352 const BIGNUM *Q, // IN: second prime (size is 1/2 of bnN)
353 const BIGNUM *E, // IN: the public exponent
354 const BIGNUM *N, // IN: the public modulus
355 BIGNUM **D // OUT:
356 )
357{
358 BOOL pOK = FALSE;
359 BIGNUM *phi;
360 BN_CTX *ctx;
361 //
362 // compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
363 phi = BN_dup(N);
364 ctx = BN_CTX_new();
365 if (phi && ctx) {
366 pOK = BN_sub(phi, phi, P);
367 pOK = pOK && BN_sub(phi, phi, Q);
368 pOK = pOK && BN_add_word(phi, 1);
369 // Compute the multiplicative inverse d = 1/e mod Phi
85fe93a8 370 BN_set_flags(phi, BN_FLG_CONSTTIME); // phi is secret
a572dbc4
SB
371 pOK = pOK && (*D = BN_mod_inverse(NULL, E, phi, ctx)) != NULL;
372 }
373 BN_CTX_free(ctx);
374 BN_clear_free(phi);
375
376 return pOK;
377}
378
379LIB_EXPORT TPM_RC
380InitOpenSSLRSAPublicKey(OBJECT *key, // IN
381 EVP_PKEY **pkey // OUT
382 )
383{
384 TPM_RC retVal;
385 RSA *rsakey = RSA_new();
386 BIGNUM *N = NULL;
387 BIGNUM *E = BN_new();
388 BN_ULONG eval;
389
390 *pkey = EVP_PKEY_new();
391
392 if (rsakey == NULL || *pkey == NULL || E == NULL)
393 ERROR_RETURN(TPM_RC_FAILURE);
394
395 if(key->publicArea.parameters.rsaDetail.exponent != 0)
396 eval = key->publicArea.parameters.rsaDetail.exponent;
397 else
398 eval = RSA_DEFAULT_PUBLIC_EXPONENT;
399
400 if (BN_set_word(E, eval) != 1)
401 ERROR_RETURN(TPM_RC_FAILURE);
402
403 N = BN_bin2bn(key->publicArea.unique.rsa.b.buffer,
404 key->publicArea.unique.rsa.b.size, NULL);
405 if (N == NULL ||
406 RSA_set0_key(rsakey, N, E, NULL) != 1 ||
407 EVP_PKEY_assign_RSA(*pkey, rsakey) == 0)
408 ERROR_RETURN(TPM_RC_FAILURE)
409
410 RSA_set_flags(rsakey, RSA_FLAG_NO_BLINDING);
411
412 retVal = TPM_RC_SUCCESS;
413
414 Exit:
415 if (retVal != TPM_RC_SUCCESS) {
416 RSA_free(rsakey);
417 EVP_PKEY_free(*pkey);
418 *pkey = NULL;
419 }
420
421 return retVal;
422}
423
424LIB_EXPORT TPM_RC
425InitOpenSSLRSAPrivateKey(OBJECT *rsaKey, // IN
426 EVP_PKEY **pkey // OUT
427 )
428{
429 const BIGNUM *N = NULL;
430 const BIGNUM *E = NULL;
431 BIGNUM *P = NULL;
432 BIGNUM *Q = NULL;
433 BIGNUM *Qr = NULL;
434 BIGNUM *D = NULL;
435#if CRT_FORMAT_RSA == YES
0be25cbb
SB
436 BIGNUM *dP = BN_new();
437 BIGNUM *dQ = BN_new();
438 BIGNUM *qInv = BN_new();
a572dbc4
SB
439#endif
440 RSA *key;
441 BN_CTX *ctx = NULL;
442 TPM_RC retVal = InitOpenSSLRSAPublicKey(rsaKey, pkey);
443
444 if (retVal != TPM_RC_SUCCESS)
445 return retVal;
446
447 if(!rsaKey->attributes.privateExp)
448 CryptRsaLoadPrivateExponent(rsaKey);
449
450 ctx = BN_CTX_new();
451 Q = BN_new();
452 Qr = BN_new();
453 P = BN_bin2bn(rsaKey->sensitive.sensitive.rsa.t.buffer,
454 rsaKey->sensitive.sensitive.rsa.t.size, NULL);
455 if (ctx == NULL || Q == NULL || Qr == NULL || P == NULL)
456 ERROR_RETURN(TPM_RC_FAILURE)
457
458 key = EVP_PKEY_get0_RSA(*pkey);
459 if (key == NULL)
460 ERROR_RETURN(TPM_RC_FAILURE);
461 RSA_get0_key(key, &N, &E, NULL);
462
463 /* Q = N/P; no remainder */
85fe93a8 464 BN_set_flags(P, BN_FLG_CONSTTIME); // P is secret
a572dbc4
SB
465 BN_div(Q, Qr, N, P, ctx);
466 if(!BN_is_zero(Qr))
467 ERROR_RETURN(TPM_RC_BINDING);
85fe93a8 468 BN_set_flags(Q, BN_FLG_CONSTTIME); // Q is secret
a572dbc4
SB
469
470 // TODO(stefanb): consider caching D in the OBJECT
471 if (ComputePrivateExponentD(P, Q, E, N, &D) == FALSE ||
472 RSA_set0_key(key, NULL, NULL, D) != 1)
473 ERROR_RETURN(TPM_RC_FAILURE);
474 D = NULL;
475
476#if CRT_FORMAT_RSA == YES
477 /* CRT parameters are not absolutely needed but may speed up ops */
0be25cbb
SB
478 dP = BigInitialized(dP, (bigConst)&rsaKey->privateExponent.dP);
479 dQ = BigInitialized(dQ, (bigConst)&rsaKey->privateExponent.dQ);
480 qInv = BigInitialized(qInv, (bigConst)&rsaKey->privateExponent.qInv);
a572dbc4
SB
481 if (dP == NULL || dQ == NULL || qInv == NULL ||
482 RSA_set0_crt_params(key, dP, dQ, qInv) != 1)
483 ERROR_RETURN(TPM_RC_FAILURE);
484#endif
485
486 retVal = TPM_RC_SUCCESS;
487
488 Exit:
489 BN_CTX_free(ctx);
490 BN_clear_free(P);
491 BN_clear_free(Q);
492 BN_free(Qr);
493
494 if (retVal != TPM_RC_SUCCESS) {
495 BN_clear_free(D);
496#if CRT_FORMAT_RSA == YES
497 BN_clear_free(dP);
498 BN_clear_free(dQ);
499 BN_clear_free(qInv);
500#endif
501 EVP_PKEY_free(*pkey);
502 *pkey = NULL;
503 }
504
505 return retVal;
506}
507
6ae0d8c5
SB
508LIB_EXPORT TPM_RC
509OpenSSLCryptRsaGenerateKey(
510 OBJECT *rsaKey, // IN/OUT: The object structure in which
511 // the key is created.
512 UINT32 e,
513 int keySizeInBits
514 )
515{
516 TPMT_PUBLIC *publicArea = &rsaKey->publicArea;
517 TPMT_SENSITIVE *sensitive = &rsaKey->sensitive;
518 TPM_RC retVal = TPM_RC_SUCCESS;
519 int rc;
520 RSA *rsa = NULL;
521 const BIGNUM *bnP = NULL;
522 const BIGNUM *bnN = NULL;
523 BIGNUM *bnE = BN_new();
524 BN_RSA(tmp);
525
526 if (bnE == NULL || BN_set_word(bnE, e) != 1)
527 ERROR_RETURN(TPM_RC_FAILURE);
528
529 // Need to initialize the privateExponent structure
530 RsaInitializeExponent(&rsaKey->privateExponent);
531
532 rsa = RSA_new();
533 if (rsa == NULL)
534 ERROR_RETURN(TPM_RC_FAILURE);
535
536 rc = RSA_generate_key_ex(rsa, keySizeInBits, bnE, NULL);
537 if (rc == 0)
538 ERROR_RETURN(TPM_RC_NO_RESULT);
539
540 RSA_get0_key(rsa, &bnN, NULL, NULL);
541 RSA_get0_factors(rsa, &bnP, NULL);
542
543 OsslToTpmBn(tmp, bnN);
544 BnTo2B((bigNum)tmp, &publicArea->unique.rsa.b, 0);
545
546 OsslToTpmBn(tmp, bnP);
547 BnTo2B((bigNum)tmp, &sensitive->sensitive.rsa.b, 0);
548
549 // CryptRsaGenerateKey calls ComputePrivateExponent; we have to call
550 // it via CryptRsaLoadPrivateExponent
551 retVal = CryptRsaLoadPrivateExponent(rsaKey);
552
553 Exit:
554 BN_free(bnE);
555 RSA_free(rsa);
556
557 return retVal;
558}
559
bc681a1b 560#endif // USE_OPENSSL_FUNCTIONS_RSA