]> git.proxmox.com Git - libtpms.git/blame - src/tpm2/crypto/openssl/Helpers.c
tpm2: Do not set RSA_FLAG_NO_BLINDING on RSA keys anymore
[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"
fdb9ad3b 62#include "ExpDCache_fp.h"
8de7f334 63#include "Helpers_fp.h"
afbb3274 64#include "TpmToOsslMath_fp.h"
8de7f334 65
bc681a1b
SB
66#include "config.h"
67
8de7f334 68#include <openssl/evp.h>
a572dbc4 69#include <openssl/rsa.h>
8de7f334 70
6905e8a2
SB
71/* to enable RSA_check_key() on private keys set to != 0 */
72#ifndef DO_RSA_CHECK_KEY
73#define DO_RSA_CHECK_KEY 0
74#endif
75
4e1cd261 76#if USE_OPENSSL_FUNCTIONS_SYMMETRIC
8de7f334 77
fee2ae97
SB
78TPM_RC
79OpenSSLCryptGenerateKeyDes(
80 TPMT_SENSITIVE *sensitive // OUT: sensitive area
81 )
82{
83 DES_cblock *key;
84 size_t offset;
85 size_t limit;
86
87 limit = MIN(sizeof(sensitive->sensitive.sym.t.buffer),
88 sensitive->sensitive.sym.t.size);
89 limit = TPM2_ROUNDUP(limit, sizeof(*key));
90 pAssert(limit < sizeof(sensitive->sensitive.sym.t.buffer));
91
92 for (offset = 0; offset < limit; offset += sizeof(*key)) {
93 key = (DES_cblock *)&sensitive->sensitive.sym.t.buffer[offset];
94 if (DES_random_key(key) != 1)
95 return TPM_RC_NO_RESULT;
96 }
97 return TPM_RC_SUCCESS;
98}
99
8de7f334
SB
100evpfunc GetEVPCipher(TPM_ALG_ID algorithm, // IN
101 UINT16 keySizeInBits, // IN
102 TPM_ALG_ID mode, // IN
103 const BYTE *key, // IN
104 BYTE *keyToUse, // OUT same as key or stretched key
105 UINT16 *keyToUseLen // IN/OUT
106 )
107{
108 int i;
109 UINT16 keySizeInBytes = keySizeInBits / 8;
110 evpfunc evpfn = NULL;
111
112 // key size to array index: 128 -> 0, 192 -> 1, 256 -> 2
113 i = (keySizeInBits >> 6) - 2;
114 if (i < 0 || i > 2)
115 return NULL;
116
117 pAssert(*keyToUseLen >= keySizeInBytes)
118 memcpy(keyToUse, key, keySizeInBytes);
119
120 switch (algorithm) {
121#if ALG_AES
122 case TPM_ALG_AES:
123 *keyToUseLen = keySizeInBytes;
124 switch (mode) {
125#if ALG_CTR
9137a773 126 case TPM_ALG_CTR:
8de7f334
SB
127 evpfn = (evpfunc []){EVP_aes_128_ctr, EVP_aes_192_ctr,
128 EVP_aes_256_ctr}[i];
129 break;
130#endif
131#if ALG_OFB
9137a773 132 case TPM_ALG_OFB:
8de7f334
SB
133 evpfn = (evpfunc[]){EVP_aes_128_ofb, EVP_aes_192_ofb,
134 EVP_aes_256_ofb}[i];
135 break;
136#endif
137#if ALG_CBC
9137a773 138 case TPM_ALG_CBC:
8de7f334
SB
139 evpfn = (evpfunc[]){EVP_aes_128_cbc, EVP_aes_192_cbc,
140 EVP_aes_256_cbc}[i];
141 break;
142#endif
143#if ALG_CFB
9137a773 144 case TPM_ALG_CFB:
8de7f334
SB
145 evpfn = (evpfunc[]){EVP_aes_128_cfb, EVP_aes_192_cfb,
146 EVP_aes_256_cfb}[i];
147 break;
148#endif
149#if ALG_ECB
9137a773 150 case TPM_ALG_ECB:
8de7f334
SB
151 evpfn = (evpfunc[]){EVP_aes_128_ecb, EVP_aes_192_ecb,
152 EVP_aes_256_ecb}[i];
153 break;
154#endif
155 }
156 break;
157#endif
158#if ALG_TDES
159 case TPM_ALG_TDES:
160 if (keySizeInBits == 128) {
161 pAssert(*keyToUseLen >= BITS_TO_BYTES(192))
162 // stretch the key
163 memcpy(&keyToUse[16], &keyToUse[0], 8);
164 *keyToUseLen = BITS_TO_BYTES(192);
165 }
166
167 switch (mode) {
168#if ALG_CTR
9137a773 169 case TPM_ALG_CTR:
8de7f334
SB
170 evpfn = (evpfunc[]){EVP_des_ede3, EVP_des_ede3, NULL}[i];
171 break;
172#endif
173#if ALG_OFB
9137a773 174 case TPM_ALG_OFB:
8de7f334
SB
175 evpfn = (evpfunc[]){EVP_des_ede3_ofb, EVP_des_ede3_ofb, NULL}[i];
176 break;
177#endif
178#if ALG_CBC
9137a773 179 case TPM_ALG_CBC:
8de7f334
SB
180 evpfn = (evpfunc[]){EVP_des_ede3_cbc, EVP_des_ede3_cbc, NULL}[i];
181 break;
182#endif
183#if ALG_CFB
9137a773 184 case TPM_ALG_CFB:
8de7f334
SB
185 evpfn = (evpfunc[]){EVP_des_ede3_cfb64, EVP_des_ede3_cfb64, NULL}[i];
186 break;
187#endif
188#if ALG_ECB
9137a773 189 case TPM_ALG_ECB:
8de7f334
SB
190 evpfn = (evpfunc[]){EVP_des_ede3_ecb, EVP_des_ede3_ecb, NULL}[i];
191 break;
192#endif
8d68e403
SB
193 }
194 break;
8de7f334 195#endif
8d68e403 196
8de7f334 197#if ALG_SM4
8de7f334 198 case TPM_ALG_SM4:
5f0e2aef
SB
199 *keyToUseLen = keySizeInBytes;
200 switch (mode) {
201#if ALG_CTR
9137a773 202 case TPM_ALG_CTR:
5f0e2aef
SB
203 evpfn = (evpfunc[]){EVP_sm4_ctr, NULL, NULL}[i];
204 break;
205#endif
206#if ALG_OFB
9137a773 207 case TPM_ALG_OFB:
5f0e2aef
SB
208 evpfn = (evpfunc[]){EVP_sm4_ofb, NULL, NULL}[i];
209 break;
210#endif
211#if ALG_CBC
9137a773 212 case TPM_ALG_CBC:
5f0e2aef
SB
213 evpfn = (evpfunc[]){EVP_sm4_cbc, NULL, NULL}[i];
214 break;
215#endif
216#if ALG_CFB
9137a773 217 case TPM_ALG_CFB:
5f0e2aef
SB
218 evpfn = (evpfunc[]){EVP_sm4_cfb, NULL, NULL}[i];
219 break;
220#endif
221#if ALG_ECB
9137a773 222 case TPM_ALG_ECB:
5f0e2aef
SB
223 evpfn = (evpfunc[]){EVP_sm4_ecb, NULL, NULL}[i];
224 break;
225#endif
226 }
8de7f334
SB
227 break;
228#endif
8d68e403 229
8de7f334 230#if ALG_CAMELLIA
8de7f334 231 case TPM_ALG_CAMELLIA:
15687b63
SB
232 *keyToUseLen = keySizeInBytes;
233 switch (mode) {
234#if ALG_CTR
9137a773 235 case TPM_ALG_CTR:
15687b63
SB
236 evpfn = (evpfunc []){EVP_camellia_128_ctr, EVP_camellia_192_ctr,
237 EVP_camellia_256_ctr}[i];
238 break;
239#endif
240#if ALG_OFB
9137a773 241 case TPM_ALG_OFB:
15687b63
SB
242 evpfn = (evpfunc[]){EVP_camellia_128_ofb, EVP_camellia_192_ofb,
243 EVP_camellia_256_ofb}[i];
244 break;
245#endif
246#if ALG_CBC
9137a773 247 case TPM_ALG_CBC:
15687b63
SB
248 evpfn = (evpfunc[]){EVP_camellia_128_cbc, EVP_camellia_192_cbc,
249 EVP_camellia_256_cbc}[i];
250 break;
251#endif
252#if ALG_CFB
9137a773 253 case TPM_ALG_CFB:
15687b63
SB
254 evpfn = (evpfunc[]){EVP_camellia_128_cfb, EVP_camellia_192_cfb,
255 EVP_camellia_256_cfb}[i];
256 break;
257#endif
258#if ALG_ECB
9137a773 259 case TPM_ALG_ECB:
15687b63
SB
260 evpfn = (evpfunc[]){EVP_camellia_128_ecb, EVP_camellia_192_ecb,
261 EVP_camellia_256_ecb}[i];
262 break;
263#endif
264 }
8de7f334
SB
265 break;
266#endif
267 }
268
269 if (evpfn == NULL)
270 MemorySet(keyToUse, 0, *keyToUseLen);
271
272 return evpfn;
273}
274
4e1cd261 275#endif // USE_OPENSSL_FUNCTIONS_SYMMETRIC
afbb3274
SB
276
277#if USE_OPENSSL_FUNCTIONS_EC
278BOOL
279OpenSSLEccGetPrivate(
280 bigNum dOut, // OUT: the qualified random value
9b434a5f
SB
281 const EC_GROUP *G, // IN: the EC_GROUP to use
282 const UINT32 requestedBits // IN: if not 0, then dOut must have that many bits
afbb3274
SB
283 )
284{
285 BOOL OK = FALSE;
286 const BIGNUM *D;
287 EC_KEY *eckey = EC_KEY_new();
9b434a5f
SB
288 UINT32 requestedBytes = BITS_TO_BYTES(requestedBits);
289 int repeats = 0;
290 int maxRepeats;
291 int numBytes;
afbb3274
SB
292
293 pAssert(G != NULL);
294
295 if (!eckey)
296 return FALSE;
297
298 if (EC_KEY_set_group(eckey, G) != 1)
299 goto Exit;
300
9b434a5f
SB
301 maxRepeats = 8;
302 // non-byte boundary order'ed curves, like NIST P521, need more loops to
303 // have a result with topmost byte != 0
304 if (requestedBits & 7)
305 maxRepeats += (9 - (requestedBits & 7));
306
307 while (true) {
308 if (EC_KEY_generate_key(eckey) == 1) {
309 D = EC_KEY_get0_private_key(eckey);
310 // if we need a certain amount of bytes and we are below a threshold
311 // of loops, check the number of bytes we have, otherwise take the
312 // result
313 if ((requestedBytes != 0) && (repeats < maxRepeats)) {
314 numBytes = BN_num_bytes(D);
315 if ((int)requestedBytes != numBytes) {
316 // result does not have enough bytes
317 repeats++;
318 continue;
319 }
320 // result is sufficient
321 }
322 OK = TRUE;
323 OsslToTpmBn(dOut, D);
324 }
325 break;
afbb3274
SB
326 }
327
328 Exit:
329 EC_KEY_free(eckey);
330
331 return OK;
332}
333#endif // USE_OPENSSL_FUNCTIONS_EC
bc681a1b
SB
334
335#if USE_OPENSSL_FUNCTIONS_RSA
336
337static const struct hnames {
338 const char *name;
339 TPM_ALG_ID hashAlg;
340} hnames[HASH_COUNT + 1] = {
341 {
342#if ALG_SHA1
343 .name = "sha1",
344 .hashAlg = ALG_SHA1_VALUE,
345 }, {
346#endif
347#if ALG_SHA256
348 .name = "sha256",
349 .hashAlg = ALG_SHA256_VALUE,
350 }, {
351#endif
352#if ALG_SHA384
353 .name = "sha384",
354 .hashAlg = ALG_SHA384_VALUE,
355 }, {
356#endif
357#if ALG_SHA512
358 .name = "sha512",
359 .hashAlg = ALG_SHA512_VALUE,
360 }, {
361#endif
362 .name = NULL,
363 }
364};
365#if HASH_COUNT != ALG_SHA1 + ALG_SHA256 + ALG_SHA384 + ALG_SHA512
366# error Missing entry in hnames array!
367#endif
368
369LIB_EXPORT const char *
370GetDigestNameByHashAlg(const TPM_ALG_ID hashAlg)
371{
372 unsigned i;
373
374 for (i = 0; i < HASH_COUNT; i++) {
375 if (hashAlg == hnames[i].hashAlg)
376 return hnames[i].name;
377 }
378 return NULL;
379}
380
a572dbc4
SB
381static BOOL
382ComputePrivateExponentD(
383 const BIGNUM *P, // IN: first prime (size is 1/2 of bnN)
384 const BIGNUM *Q, // IN: second prime (size is 1/2 of bnN)
385 const BIGNUM *E, // IN: the public exponent
386 const BIGNUM *N, // IN: the public modulus
387 BIGNUM **D // OUT:
388 )
389{
390 BOOL pOK = FALSE;
391 BIGNUM *phi;
392 BN_CTX *ctx;
393 //
394 // compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
395 phi = BN_dup(N);
396 ctx = BN_CTX_new();
397 if (phi && ctx) {
398 pOK = BN_sub(phi, phi, P);
399 pOK = pOK && BN_sub(phi, phi, Q);
400 pOK = pOK && BN_add_word(phi, 1);
401 // Compute the multiplicative inverse d = 1/e mod Phi
85fe93a8 402 BN_set_flags(phi, BN_FLG_CONSTTIME); // phi is secret
a572dbc4
SB
403 pOK = pOK && (*D = BN_mod_inverse(NULL, E, phi, ctx)) != NULL;
404 }
405 BN_CTX_free(ctx);
406 BN_clear_free(phi);
407
408 return pOK;
409}
410
411LIB_EXPORT TPM_RC
412InitOpenSSLRSAPublicKey(OBJECT *key, // IN
413 EVP_PKEY **pkey // OUT
414 )
415{
416 TPM_RC retVal;
417 RSA *rsakey = RSA_new();
418 BIGNUM *N = NULL;
419 BIGNUM *E = BN_new();
420 BN_ULONG eval;
421
422 *pkey = EVP_PKEY_new();
423
424 if (rsakey == NULL || *pkey == NULL || E == NULL)
425 ERROR_RETURN(TPM_RC_FAILURE);
426
427 if(key->publicArea.parameters.rsaDetail.exponent != 0)
428 eval = key->publicArea.parameters.rsaDetail.exponent;
429 else
430 eval = RSA_DEFAULT_PUBLIC_EXPONENT;
431
432 if (BN_set_word(E, eval) != 1)
433 ERROR_RETURN(TPM_RC_FAILURE);
434
435 N = BN_bin2bn(key->publicArea.unique.rsa.b.buffer,
436 key->publicArea.unique.rsa.b.size, NULL);
437 if (N == NULL ||
438 RSA_set0_key(rsakey, N, E, NULL) != 1 ||
439 EVP_PKEY_assign_RSA(*pkey, rsakey) == 0)
440 ERROR_RETURN(TPM_RC_FAILURE)
441
a572dbc4
SB
442 retVal = TPM_RC_SUCCESS;
443
444 Exit:
445 if (retVal != TPM_RC_SUCCESS) {
446 RSA_free(rsakey);
447 EVP_PKEY_free(*pkey);
448 *pkey = NULL;
449 }
450
451 return retVal;
452}
453
6905e8a2
SB
454static void DoRSACheckKey(const BIGNUM *P, const BIGNUM *Q, const BIGNUM *N,
455 const BIGNUM *E, const BIGNUM *D)
456{
457 RSA *mykey;
458 static int disp;
459
460 if (!DO_RSA_CHECK_KEY)
461 return;
462 if (!disp) {
463 fprintf(stderr, "RSA key checking is enabled\n");
464 disp = 1;
465 }
466
467 mykey = RSA_new();
468 RSA_set0_factors(mykey, BN_dup(P), BN_dup(Q));
469 RSA_set0_key(mykey, BN_dup(N), BN_dup(E), BN_dup(D));
470 if (RSA_check_key(mykey) != 1) {
471 fprintf(stderr, "Detected bad RSA key. STOP.\n");
472 while (1);
473 }
474 RSA_free(mykey);
475}
476
a572dbc4
SB
477LIB_EXPORT TPM_RC
478InitOpenSSLRSAPrivateKey(OBJECT *rsaKey, // IN
479 EVP_PKEY **pkey // OUT
480 )
481{
482 const BIGNUM *N = NULL;
483 const BIGNUM *E = NULL;
484 BIGNUM *P = NULL;
485 BIGNUM *Q = NULL;
486 BIGNUM *Qr = NULL;
487 BIGNUM *D = NULL;
488#if CRT_FORMAT_RSA == YES
0be25cbb
SB
489 BIGNUM *dP = BN_new();
490 BIGNUM *dQ = BN_new();
491 BIGNUM *qInv = BN_new();
a572dbc4 492#endif
c8a7074b 493 RSA *key = NULL;
a572dbc4
SB
494 BN_CTX *ctx = NULL;
495 TPM_RC retVal = InitOpenSSLRSAPublicKey(rsaKey, pkey);
496
497 if (retVal != TPM_RC_SUCCESS)
498 return retVal;
499
500 if(!rsaKey->attributes.privateExp)
501 CryptRsaLoadPrivateExponent(rsaKey);
502
a572dbc4
SB
503 P = BN_bin2bn(rsaKey->sensitive.sensitive.rsa.t.buffer,
504 rsaKey->sensitive.sensitive.rsa.t.size, NULL);
fdb9ad3b 505 if (P == NULL)
a572dbc4
SB
506 ERROR_RETURN(TPM_RC_FAILURE)
507
c8a7074b 508 key = EVP_PKEY_get1_RSA(*pkey);
a572dbc4
SB
509 if (key == NULL)
510 ERROR_RETURN(TPM_RC_FAILURE);
511 RSA_get0_key(key, &N, &E, NULL);
512
fdb9ad3b
SB
513 D = ExpDCacheFind(P, N, E, &Q);
514 if (D == NULL) {
515 ctx = BN_CTX_new();
516 Q = BN_new();
517 Qr = BN_new();
518 if (ctx == NULL || Q == NULL || Qr == NULL)
519 ERROR_RETURN(TPM_RC_FAILURE);
520 /* Q = N/P; no remainder */
521 BN_set_flags(P, BN_FLG_CONSTTIME); // P is secret
897c8f86 522 if (!BN_div(Q, Qr, N, P, ctx) || !BN_is_zero(Qr))
fdb9ad3b
SB
523 ERROR_RETURN(TPM_RC_BINDING);
524 BN_set_flags(Q, BN_FLG_CONSTTIME); // Q is secret
525
526 if (ComputePrivateExponentD(P, Q, E, N, &D) == FALSE)
527 ERROR_RETURN(TPM_RC_FAILURE);
528 ExpDCacheAdd(P, N, E, Q, D);
529 }
530 if (RSA_set0_key(key, NULL, NULL, D) != 1)
a572dbc4 531 ERROR_RETURN(TPM_RC_FAILURE);
6905e8a2
SB
532
533 DoRSACheckKey(P, Q, N, E, D);
534
a572dbc4
SB
535 D = NULL;
536
537#if CRT_FORMAT_RSA == YES
538 /* CRT parameters are not absolutely needed but may speed up ops */
0be25cbb
SB
539 dP = BigInitialized(dP, (bigConst)&rsaKey->privateExponent.dP);
540 dQ = BigInitialized(dQ, (bigConst)&rsaKey->privateExponent.dQ);
541 qInv = BigInitialized(qInv, (bigConst)&rsaKey->privateExponent.qInv);
a572dbc4
SB
542 if (dP == NULL || dQ == NULL || qInv == NULL ||
543 RSA_set0_crt_params(key, dP, dQ, qInv) != 1)
544 ERROR_RETURN(TPM_RC_FAILURE);
545#endif
546
547 retVal = TPM_RC_SUCCESS;
548
549 Exit:
550 BN_CTX_free(ctx);
551 BN_clear_free(P);
552 BN_clear_free(Q);
553 BN_free(Qr);
c8a7074b 554 RSA_free(key); // undo reference from EVP_PKEY_get1_RSA()
a572dbc4
SB
555
556 if (retVal != TPM_RC_SUCCESS) {
557 BN_clear_free(D);
558#if CRT_FORMAT_RSA == YES
559 BN_clear_free(dP);
560 BN_clear_free(dQ);
561 BN_clear_free(qInv);
562#endif
563 EVP_PKEY_free(*pkey);
564 *pkey = NULL;
565 }
566
567 return retVal;
568}
569
6ae0d8c5
SB
570LIB_EXPORT TPM_RC
571OpenSSLCryptRsaGenerateKey(
572 OBJECT *rsaKey, // IN/OUT: The object structure in which
573 // the key is created.
574 UINT32 e,
575 int keySizeInBits
576 )
577{
578 TPMT_PUBLIC *publicArea = &rsaKey->publicArea;
579 TPMT_SENSITIVE *sensitive = &rsaKey->sensitive;
580 TPM_RC retVal = TPM_RC_SUCCESS;
581 int rc;
582 RSA *rsa = NULL;
583 const BIGNUM *bnP = NULL;
584 const BIGNUM *bnN = NULL;
585 BIGNUM *bnE = BN_new();
586 BN_RSA(tmp);
587
588 if (bnE == NULL || BN_set_word(bnE, e) != 1)
589 ERROR_RETURN(TPM_RC_FAILURE);
590
591 // Need to initialize the privateExponent structure
592 RsaInitializeExponent(&rsaKey->privateExponent);
593
594 rsa = RSA_new();
595 if (rsa == NULL)
596 ERROR_RETURN(TPM_RC_FAILURE);
597
598 rc = RSA_generate_key_ex(rsa, keySizeInBits, bnE, NULL);
599 if (rc == 0)
600 ERROR_RETURN(TPM_RC_NO_RESULT);
601
602 RSA_get0_key(rsa, &bnN, NULL, NULL);
603 RSA_get0_factors(rsa, &bnP, NULL);
604
605 OsslToTpmBn(tmp, bnN);
606 BnTo2B((bigNum)tmp, &publicArea->unique.rsa.b, 0);
607
608 OsslToTpmBn(tmp, bnP);
609 BnTo2B((bigNum)tmp, &sensitive->sensitive.rsa.b, 0);
610
611 // CryptRsaGenerateKey calls ComputePrivateExponent; we have to call
612 // it via CryptRsaLoadPrivateExponent
613 retVal = CryptRsaLoadPrivateExponent(rsaKey);
614
615 Exit:
616 BN_free(bnE);
617 RSA_free(rsa);
618
619 return retVal;
620}
621
bc681a1b 622#endif // USE_OPENSSL_FUNCTIONS_RSA