]>
Commit | Line | Data |
---|---|---|
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 |
78 | TPM_RC |
79 | OpenSSLCryptGenerateKeyDes( | |
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 |
100 | evpfunc 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 | |
278 | BOOL | |
279 | OpenSSLEccGetPrivate( | |
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 | ||
337 | static 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 | ||
369 | LIB_EXPORT const char * | |
370 | GetDigestNameByHashAlg(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 |
381 | static BOOL |
382 | ComputePrivateExponentD( | |
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 | ||
411 | LIB_EXPORT TPM_RC | |
412 | InitOpenSSLRSAPublicKey(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 |
454 | static 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 |
477 | LIB_EXPORT TPM_RC |
478 | InitOpenSSLRSAPrivateKey(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 |
570 | LIB_EXPORT TPM_RC |
571 | OpenSSLCryptRsaGenerateKey( | |
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 |