]>
Commit | Line | Data |
---|---|---|
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" | |
63 | #include "TpmToOsslMath_fp.h" | |
64 | ||
65 | #include "config.h" | |
66 | ||
67 | #include <openssl/evp.h> | |
68 | #include <openssl/rsa.h> | |
69 | ||
70 | #if USE_OPENSSL_FUNCTIONS_SYMMETRIC | |
71 | ||
72 | TPM_RC | |
73 | OpenSSLCryptGenerateKeyDes( | |
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 | ||
94 | evpfunc 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 | |
187 | } | |
188 | break; | |
189 | #endif | |
190 | ||
191 | #if ALG_SM4 | |
192 | case TPM_ALG_SM4: | |
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 | } | |
221 | break; | |
222 | #endif | |
223 | ||
224 | #if ALG_CAMELLIA | |
225 | case TPM_ALG_CAMELLIA: | |
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 | } | |
259 | break; | |
260 | #endif | |
261 | } | |
262 | ||
263 | if (evpfn == NULL) | |
264 | MemorySet(keyToUse, 0, *keyToUseLen); | |
265 | ||
266 | return evpfn; | |
267 | } | |
268 | ||
269 | #endif // USE_OPENSSL_FUNCTIONS_SYMMETRIC | |
270 | ||
271 | #if USE_OPENSSL_FUNCTIONS_EC | |
272 | BOOL | |
273 | OpenSSLEccGetPrivate( | |
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 | |
302 | ||
303 | #if USE_OPENSSL_FUNCTIONS_RSA | |
304 | ||
305 | static 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 | ||
337 | LIB_EXPORT const char * | |
338 | GetDigestNameByHashAlg(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 | ||
349 | static BOOL | |
350 | ComputePrivateExponentD( | |
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 | |
370 | BN_set_flags(phi, BN_FLG_CONSTTIME); // phi is secret | |
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 | ||
379 | LIB_EXPORT TPM_RC | |
380 | InitOpenSSLRSAPublicKey(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 | ||
424 | LIB_EXPORT TPM_RC | |
425 | InitOpenSSLRSAPrivateKey(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 | |
436 | BIGNUM *dP = BN_new(); | |
437 | BIGNUM *dQ = BN_new(); | |
438 | BIGNUM *qInv = BN_new(); | |
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 */ | |
464 | BN_set_flags(P, BN_FLG_CONSTTIME); // P is secret | |
465 | BN_div(Q, Qr, N, P, ctx); | |
466 | if(!BN_is_zero(Qr)) | |
467 | ERROR_RETURN(TPM_RC_BINDING); | |
468 | BN_set_flags(Q, BN_FLG_CONSTTIME); // Q is secret | |
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 */ | |
478 | dP = BigInitialized(dP, (bigConst)&rsaKey->privateExponent.dP); | |
479 | dQ = BigInitialized(dQ, (bigConst)&rsaKey->privateExponent.dQ); | |
480 | qInv = BigInitialized(qInv, (bigConst)&rsaKey->privateExponent.qInv); | |
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 | ||
508 | LIB_EXPORT TPM_RC | |
509 | OpenSSLCryptRsaGenerateKey( | |
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 | ||
560 | #endif // USE_OPENSSL_FUNCTIONS_RSA |