VirtualBox

source: vbox/trunk/src/libs/libtpms-0.9.0/src/tpm2/crypto/openssl/CryptRsa.c@ 91612

最後變更 在這個檔案從91612是 91612,由 vboxsync 提交於 3 年 前

src/libs: Export libtpms-0.9.0, bugref:10078

檔案大小: 59.3 KB
 
1/********************************************************************************/
2/* */
3/* Implementation of cryptographic primitives for RSA */
4/* Written by Ken Goldman */
5/* IBM Thomas J. Watson Research Center */
6/* $Id: CryptRsa.c 1658 2021-01-22 23:14:01Z kgoldman $ */
7/* */
8/* Licenses and Notices */
9/* */
10/* 1. Copyright Licenses: */
11/* */
12/* - Trusted Computing Group (TCG) grants to the user of the source code in */
13/* this specification (the "Source Code") a worldwide, irrevocable, */
14/* nonexclusive, royalty free, copyright license to reproduce, create */
15/* derivative works, distribute, display and perform the Source Code and */
16/* derivative works thereof, and to grant others the rights granted herein. */
17/* */
18/* - The TCG grants to the user of the other parts of the specification */
19/* (other than the Source Code) the rights to reproduce, distribute, */
20/* display, and perform the specification solely for the purpose of */
21/* developing products based on such documents. */
22/* */
23/* 2. Source Code Distribution Conditions: */
24/* */
25/* - Redistributions of Source Code must retain the above copyright licenses, */
26/* this list of conditions and the following disclaimers. */
27/* */
28/* - Redistributions in binary form must reproduce the above copyright */
29/* licenses, this list of conditions and the following disclaimers in the */
30/* documentation and/or other materials provided with the distribution. */
31/* */
32/* 3. Disclaimers: */
33/* */
34/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
38/* Contact TCG Administration ([email protected]) for */
39/* information on specification licensing rights available through TCG */
40/* membership agreements. */
41/* */
42/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
43/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
44/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
45/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
46/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
47/* */
48/* - Without limitation, TCG and its members and licensors disclaim all */
49/* liability, including liability for infringement of any proprietary */
50/* rights, relating to use of information in this specification and to the */
51/* implementation of this specification, and TCG disclaims all liability for */
52/* cost of procurement of substitute goods or services, lost profits, loss */
53/* of use, loss of data or any incidental, consequential, direct, indirect, */
54/* or special damages, whether under contract, tort, warranty or otherwise, */
55/* arising in any way out of use or reliance upon this specification or any */
56/* information herein. */
57/* */
58/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
59/* */
60/********************************************************************************/
61
62/* 10.2.17 CryptRsa.c */
63/* 10.2.17.1 Introduction */
64/* This file contains implementation of cryptographic primitives for RSA. Vendors may replace the
65 implementation in this file with their own library functions. */
66/* 10.2.17.2 Includes */
67/* Need this define to get the private defines for this function */
68#define CRYPT_RSA_C
69#include "Tpm.h"
70#include "Helpers_fp.h" // libtpms added
71
72#include <openssl/rsa.h> // libtpms added
73
74#if ALG_RSA
75/* 10.2.17.3 Obligatory Initialization Functions */
76/* 10.2.17.3.1 CryptRsaInit() */
77/* Function called at _TPM_Init(). */
78BOOL
79CryptRsaInit(
80 void
81 )
82{
83 return TRUE;
84}
85/* 10.2.17.3.2 CryptRsaStartup() */
86/* Function called at TPM2_Startup() */
87BOOL
88CryptRsaStartup(
89 void
90 )
91{
92 return TRUE;
93}
94/* 10.2.17.4 Internal Functions */
95void
96RsaInitializeExponent(
97 privateExponent_t *pExp
98 )
99{
100#if CRT_FORMAT_RSA == NO
101 BN_INIT(pExp->D);
102#else
103 BN_INIT(pExp->Q);
104 BN_INIT(pExp->dP);
105 BN_INIT(pExp->dQ);
106 BN_INIT(pExp->qInv);
107#endif
108}
109/* 10.2.17.4.1 ComputePrivateExponent() */
110/* This function computes the private exponent from the primes. */
111/* Return Value Meaning */
112/* TRUE(1) success */
113/* FALSE(0) failure */
114static BOOL
115ComputePrivateExponent(
116 bigNum P, // IN: first prime (size is 1/2 of bnN)
117 bigNum Q, // IN: second prime (size is 1/2 of bnN)
118 bigNum E, // IN: the public exponent
119 bigNum N, // IN: the public modulus
120 privateExponent_t *pExp // OUT:
121 )
122{
123 BOOL pOK;
124 BOOL qOK;
125#if CRT_FORMAT_RSA == NO
126 BN_RSA(bnPhi);
127 //
128 RsaInitializeExponent(pExp);
129 // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
130 pOK = BnCopy(bnPhi, N);
131 pOK = pOK && BnSub(bnPhi, bnPhi, P);
132 pOK = pOK && BnSub(bnPhi, bnPhi, Q);
133 pOK = pOK && BnAddWord(bnPhi, bnPhi, 1);
134 // Compute the multiplicative inverse d = 1/e mod Phi
135 pOK = pOK && BnModInverse((bigNum)&pExp->D, E, bnPhi);
136 qOK = pOK;
137#else
138 BN_PRIME(temp);
139 bigNum pT;
140 //
141 NOT_REFERENCED(N);
142 RsaInitializeExponent(pExp);
143 BnCopy((bigNum)&pExp->Q, Q);
144 // make p the larger value so that m2 is always less than p
145 if(BnUnsignedCmp(P, Q) < 0)
146 {
147 pT = P;
148 P = Q;
149 Q = pT;
150 }
151 //dP = (1/e) mod (p-1) = d mod (p-1)
152 pOK = BnSubWord(temp, P, 1);
153 pOK = pOK && BnModInverse((bigNum)&pExp->dP, E, temp);
154 //dQ = (1/e) mod (q-1) = d mod (q-1)
155 qOK = BnSubWord(temp, Q, 1);
156 qOK = qOK && BnModInverse((bigNum)&pExp->dQ, E, temp);
157 // qInv = (1/q) mod p
158 if(pOK && qOK)
159 pOK = qOK = BnModInverse((bigNum)&pExp->qInv, Q, P);
160#endif
161 if(!pOK)
162 BnSetWord(P, 0);
163 if(!qOK)
164 BnSetWord(Q, 0);
165 return pOK && qOK;
166}
167/* 10.2.17.4.2 RsaPrivateKeyOp() */
168/* This function is called to do the exponentiation with the private key. Compile options allow use
169 of the simple (but slow) private exponent, or the more complex but faster CRT method. */
170/* Return Value Meaning */
171/* TRUE(1) success */
172/* FALSE(0) failure */
173static BOOL
174RsaPrivateKeyOp(
175 bigNum inOut, // IN/OUT: number to be exponentiated
176 bigNum N, // IN: public modulus (can be NULL if CRT)
177 bigNum P, // IN: one of the primes (can be NULL if not CRT)
178 privateExponent_t *pExp
179 )
180{
181 BOOL OK;
182#if CRT_FORMAT_RSA == NO
183 (P);
184 OK = BnModExp(inOut, inOut, (bigNum)&pExp->D, N);
185#else
186 BN_RSA(M1);
187 BN_RSA(M2);
188 BN_RSA(M);
189 BN_RSA(H);
190 bigNum Q = (bigNum)&pExp->Q;
191 NOT_REFERENCED(N);
192 // Make P the larger prime.
193 // NOTE that when the CRT form of the private key is created, dP will always
194 // be computed using the larger of p and q so the only thing needed here is that
195 // the primes be selected so that they agree with dP.
196 if(BnUnsignedCmp(P, Q) < 0)
197 {
198 bigNum T = P;
199 P = Q;
200 Q = T;
201 }
202 // m1 = cdP mod p
203 OK = BnModExp(M1, inOut, (bigNum)&pExp->dP, P);
204 // m2 = cdQ mod q
205 OK = OK && BnModExp(M2, inOut, (bigNum)&pExp->dQ, Q);
206 // h = qInv * (m1 - m2) mod p = qInv * (m1 + P - m2) mod P because Q < P
207 // so m2 < P
208 OK = OK && BnSub(H, P, M2);
209 OK = OK && BnAdd(H, H, M1);
210 OK = OK && BnModMult(H, H, (bigNum)&pExp->qInv, P);
211 // m = m2 + h * q
212 OK = OK && BnMult(M, H, Q);
213 OK = OK && BnAdd(inOut, M2, M);
214#endif
215 return OK;
216}
217/* 10.2.17.4.3 RSAEP() */
218/* This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a
219 value (m) with the public exponent (e), modulo the public (n). */
220/* Error Returns Meaning */
221/* TPM_RC_VALUE number to exponentiate is larger than the modulus */
222#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
223static TPM_RC
224RSAEP(
225 TPM2B *dInOut, // IN: size of the encrypted block and the size of
226 // the encrypted value. It must be the size of
227 // the modulus.
228 // OUT: the encrypted data. Will receive the
229 // decrypted value
230 OBJECT *key // IN: the key to use
231 )
232{
233 TPM2B_TYPE(4BYTES, 4);
234 TPM2B_4BYTES(e) = {{4, {(BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 24) & 0xff),
235 (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 16) & 0xff),
236 (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT >> 8) & 0xff),
237 (BYTE)((RSA_DEFAULT_PUBLIC_EXPONENT)& 0xff)}}};
238 //
239 if(key->publicArea.parameters.rsaDetail.exponent != 0)
240 UINT32_TO_BYTE_ARRAY(key->publicArea.parameters.rsaDetail.exponent,
241 e.t.buffer);
242 return ModExpB(dInOut->size, dInOut->buffer, dInOut->size, dInOut->buffer,
243 e.t.size, e.t.buffer, key->publicArea.unique.rsa.t.size,
244 key->publicArea.unique.rsa.t.buffer);
245}
246/* 10.2.17.4.4 RSADP() */
247/* This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a
248 value (c) with the private exponent (d), modulo the public modulus (n). The decryption is in
249 place. */
250/* This function also checks the size of the private key. If the size indicates that only a prime
251 value is present, the key is converted to being a private exponent. */
252/* Error Returns Meaning */
253/* TPM_RC_SIZE the value to decrypt is larger than the modulus */
254static TPM_RC
255RSADP(
256 TPM2B *inOut, // IN/OUT: the value to encrypt
257 OBJECT *key // IN: the key
258 )
259{
260 BN_RSA_INITIALIZED(bnM, inOut);
261 BN_RSA_INITIALIZED(bnN, &key->publicArea.unique.rsa);
262 BN_RSA_INITIALIZED(bnP, &key->sensitive.sensitive.rsa);
263 if(BnUnsignedCmp(bnM, bnN) >= 0)
264 return TPM_RC_SIZE;
265 // private key operation requires that private exponent be loaded
266 // During self-test, this might not be the case so load it up if it hasn't
267 // already done
268 // been done
269 if(!key->attributes.privateExp)
270 CryptRsaLoadPrivateExponent(key);
271 if(!RsaPrivateKeyOp(bnM, bnN, bnP, &key->privateExponent))
272 FAIL(FATAL_ERROR_INTERNAL);
273 BnTo2B(bnM, inOut, inOut->size);
274 return TPM_RC_SUCCESS;
275}
276/* 10.2.17.4.5 OaepEncode() */
277/* This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must
278 equal the size of the modulus */
279/* Error Returns Meaning */
280/* TPM_RC_VALUE hashAlg is not valid or message size is too large */
281static TPM_RC
282OaepEncode(
283 TPM2B *padded, // OUT: the pad data
284 TPM_ALG_ID hashAlg, // IN: algorithm to use for padding
285 const TPM2B *label, // IN: null-terminated string (may be NULL)
286 TPM2B *message, // IN: the message being padded
287 RAND_STATE *rand // IN: the random number generator to use
288 )
289{
290 INT32 padLen;
291 INT32 dbSize;
292 INT32 i;
293 BYTE mySeed[MAX_DIGEST_SIZE];
294 BYTE *seed = mySeed;
295 UINT16 hLen = CryptHashGetDigestSize(hashAlg);
296 BYTE mask[MAX_RSA_KEY_BYTES];
297 BYTE *pp;
298 BYTE *pm;
299 TPM_RC retVal = TPM_RC_SUCCESS;
300 pAssert(padded != NULL && message != NULL);
301 // A value of zero is not allowed because the KDF can't produce a result
302 // if the digest size is zero.
303 if(hLen == 0)
304 return TPM_RC_VALUE;
305 // Basic size checks
306 // make sure digest isn't too big for key size
307 if(padded->size < (2 * hLen) + 2)
308 ERROR_RETURN(TPM_RC_HASH);
309 // and that message will fit messageSize <= k - 2hLen - 2
310 if(message->size > (padded->size - (2 * hLen) - 2))
311 ERROR_RETURN(TPM_RC_VALUE);
312 // Hash L even if it is null
313 // Offset into padded leaving room for masked seed and byte of zero
314 pp = &padded->buffer[hLen + 1];
315 if(CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
316 hLen, pp) != hLen)
317 ERROR_RETURN(TPM_RC_FAILURE);
318 // concatenate PS of k mLen 2hLen 2
319 padLen = padded->size - message->size - (2 * hLen) - 2;
320 MemorySet(&pp[hLen], 0, padLen);
321 pp[hLen + padLen] = 0x01;
322 padLen += 1;
323 memcpy(&pp[hLen + padLen], message->buffer, message->size);
324 // The total size of db = hLen + pad + mSize;
325 dbSize = hLen + padLen + message->size;
326 // If testing, then use the provided seed. Otherwise, use values
327 // from the RNG
328 CryptRandomGenerate(hLen, mySeed);
329 DRBG_Generate(rand, mySeed, (UINT16)hLen);
330 // mask = MGF1 (seed, nSize hLen 1)
331 CryptMGF_KDF(dbSize, mask, hashAlg, hLen, seed, 0);
332 // Create the masked db
333 pm = mask;
334 for(i = dbSize; i > 0; i--)
335 *pp++ ^= *pm++;
336 pp = &padded->buffer[hLen + 1];
337 // Run the masked data through MGF1
338 if(CryptMGF_KDF(hLen, &padded->buffer[1], hashAlg, dbSize, pp, 0) != (unsigned)hLen)
339 ERROR_RETURN(TPM_RC_VALUE);
340 // Now XOR the seed to create masked seed
341 pp = &padded->buffer[1];
342 pm = seed;
343 for(i = hLen; i > 0; i--)
344 *pp++ ^= *pm++;
345 // Set the first byte to zero
346 padded->buffer[0] = 0x00;
347 Exit:
348 return retVal;
349}
350/* 10.2.17.4.6 OaepDecode() */
351/* This function performs OAEP padding checking. The size of the buffer to receive the recovered
352 data. If the padding is not valid, the dSize size is set to zero and the function returns
353 TPM_RC_VALUE. */
354/* The dSize parameter is used as an input to indicate the size available in the buffer. If
355 insufficient space is available, the size is not changed and the return code is TPM_RC_VALUE. */
356/* Error Returns Meaning */
357/* TPM_RC_VALUE the value to decode was larger than the modulus, or the padding is wrong or the
358 buffer to receive the results is too small */
359static TPM_RC
360OaepDecode(
361 TPM2B *dataOut, // OUT: the recovered data
362 TPM_ALG_ID hashAlg, // IN: algorithm to use for padding
363 const TPM2B *label, // IN: null-terminated string (may be NULL)
364 TPM2B *padded // IN: the padded data
365 )
366{
367 UINT32 i;
368 BYTE seedMask[MAX_DIGEST_SIZE];
369 UINT32 hLen = CryptHashGetDigestSize(hashAlg);
370 BYTE mask[MAX_RSA_KEY_BYTES];
371 BYTE *pp;
372 BYTE *pm;
373 TPM_RC retVal = TPM_RC_SUCCESS;
374 // Strange size (anything smaller can't be an OAEP padded block)
375 // Also check for no leading 0
376 if((padded->size < (unsigned)((2 * hLen) + 2)) || (padded->buffer[0] != 0))
377 ERROR_RETURN(TPM_RC_VALUE);
378 // Use the hash size to determine what to put through MGF1 in order
379 // to recover the seedMask
380 CryptMGF_KDF(hLen, seedMask, hashAlg, padded->size - hLen - 1,
381 &padded->buffer[hLen + 1], 0);
382 // Recover the seed into seedMask
383 pAssert(hLen <= sizeof(seedMask));
384 pp = &padded->buffer[1];
385 pm = seedMask;
386 for(i = hLen; i > 0; i--)
387 *pm++ ^= *pp++;
388 // Use the seed to generate the data mask
389 CryptMGF_KDF(padded->size - hLen - 1, mask, hashAlg, hLen, seedMask, 0);
390 // Use the mask generated from seed to recover the padded data
391 pp = &padded->buffer[hLen + 1];
392 pm = mask;
393 for(i = (padded->size - hLen - 1); i > 0; i--)
394 *pm++ ^= *pp++;
395 // Make sure that the recovered data has the hash of the label
396 // Put trial value in the seed mask
397 if((CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
398 hLen, seedMask)) != hLen)
399 FAIL(FATAL_ERROR_INTERNAL);
400 if(memcmp(seedMask, mask, hLen) != 0)
401 ERROR_RETURN(TPM_RC_VALUE);
402 // find the start of the data
403 pm = &mask[hLen];
404 for(i = (UINT32)padded->size - (2 * hLen) - 1; i > 0; i--)
405 {
406 if(*pm++ != 0)
407 break;
408 }
409 // If we ran out of data or didn't end with 0x01, then return an error
410 if(i == 0 || pm[-1] != 0x01)
411 ERROR_RETURN(TPM_RC_VALUE);
412 // pm should be pointing at the first part of the data
413 // and i is one greater than the number of bytes to move
414 i--;
415 if(i > dataOut->size)
416 // Special exit to preserve the size of the output buffer
417 return TPM_RC_VALUE;
418 memcpy(dataOut->buffer, pm, i);
419 dataOut->size = (UINT16)i;
420 Exit:
421 if(retVal != TPM_RC_SUCCESS)
422 dataOut->size = 0;
423 return retVal;
424}
425/* 10.2.17.4.7 PKCS1v1_5Encode() */
426/* This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
427/* Error Returns Meaning */
428/* TPM_RC_VALUE message size is too large */
429static TPM_RC
430RSAES_PKCS1v1_5Encode(
431 TPM2B *padded, // OUT: the pad data
432 TPM2B *message, // IN: the message being padded
433 RAND_STATE *rand
434 )
435{
436 UINT32 ps = padded->size - message->size - 3;
437 //
438 if(message->size > padded->size - 11)
439 return TPM_RC_VALUE;
440 // move the message to the end of the buffer
441 memcpy(&padded->buffer[padded->size - message->size], message->buffer,
442 message->size);
443 // Set the first byte to 0x00 and the second to 0x02
444 padded->buffer[0] = 0;
445 padded->buffer[1] = 2;
446 // Fill with random bytes
447 DRBG_Generate(rand, &padded->buffer[2], (UINT16)ps);
448 // Set the delimiter for the random field to 0
449 padded->buffer[2 + ps] = 0;
450 // Now, the only messy part. Make sure that all the 'ps' bytes are non-zero
451 // In this implementation, use the value of the current index
452 for(ps++; ps > 1; ps--)
453 {
454 if(padded->buffer[ps] == 0)
455 padded->buffer[ps] = 0x55; // In the < 0.5% of the cases that the
456 // random value is 0, just pick a value to
457 // put into the spot.
458 }
459 return TPM_RC_SUCCESS;
460}
461/* 10.2.17.4.8 RSAES_Decode() */
462/* This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
463/* Error Returns Meaning */
464/* TPM_RC_FAIL decoding error or results would no fit into provided buffer */
465static TPM_RC
466RSAES_Decode(
467 TPM2B *message, // OUT: the recovered message
468 TPM2B *coded // IN: the encoded message
469 )
470{
471 BOOL fail = FALSE;
472 UINT16 pSize;
473 fail = (coded->size < 11);
474 fail = (coded->buffer[0] != 0x00) | fail;
475 fail = (coded->buffer[1] != 0x02) | fail;
476 for(pSize = 2; pSize < coded->size; pSize++)
477 {
478 if(coded->buffer[pSize] == 0)
479 break;
480 }
481 pSize++;
482 // Make sure that pSize has not gone over the end and that there are at least 8
483 // bytes of pad data.
484 fail = (pSize > coded->size) | fail;
485 fail = ((pSize - 2) <= 8) | fail;
486 if((message->size < (UINT16)(coded->size - pSize)) || fail)
487 return TPM_RC_VALUE;
488 message->size = coded->size - pSize;
489 memcpy(message->buffer, &coded->buffer[pSize], coded->size - pSize);
490 return TPM_RC_SUCCESS;
491}
492#endif // libtpms added
493/* 10.2.17.4.13 CryptRsaPssSaltSize() */
494/* This function computes the salt size used in PSS. It is broken out so that the X509 code can get
495 the same value that is used by the encoding function in this module. */
496INT16
497CryptRsaPssSaltSize(
498 INT16 hashSize,
499 INT16 outSize
500)
501{
502 INT16 saltSize;
503 //
504 // (Mask Length) = (outSize - hashSize - 1);
505 // Max saltSize is (Mask Length) - 1
506 saltSize = (outSize - hashSize - 1) - 1;
507 // Use the maximum salt size allowed by FIPS 186-4
508 if (saltSize > hashSize)
509 saltSize = hashSize;
510 else if (saltSize < 0)
511 saltSize = 0;
512 return saltSize;
513}
514
515#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
516/* 10.2.17.4.9 PssEncode() */
517/* This function creates an encoded block of data that is the size of modulus. The function uses the
518 maximum salt size that will fit in the encoded block. */
519/* Returns TPM_RC_SUCCESS or goes into failure mode. */
520static TPM_RC
521PssEncode(
522 TPM2B *out, // OUT: the encoded buffer
523 TPM_ALG_ID hashAlg, // IN: hash algorithm for the encoding
524 TPM2B *digest, // IN: the digest
525 RAND_STATE *rand // IN: random number source
526 )
527{
528 UINT32 hLen = CryptHashGetDigestSize(hashAlg);
529 BYTE salt[MAX_RSA_KEY_BYTES - 1];
530 UINT16 saltSize;
531 BYTE *ps = salt;
532 BYTE *pOut;
533 UINT16 mLen;
534 HASH_STATE hashState;
535 // These are fatal errors indicating bad TPM firmware
536 pAssert(out != NULL && hLen > 0 && digest != NULL);
537 // Get the size of the mask
538 mLen = (UINT16)(out->size - hLen - 1);
539 // Maximum possible salt size is mask length - 1
540 saltSize = mLen - 1;
541 // Use the maximum salt size allowed by FIPS 186-4
542 if(saltSize > hLen)
543 saltSize = (UINT16)hLen;
544 //using eOut for scratch space
545 // Set the first 8 bytes to zero
546 pOut = out->buffer;
547 memset(pOut, 0, 8);
548 // Get set the salt
549 DRBG_Generate(rand, salt, saltSize);
550 // Create the hash of the pad || input hash || salt
551 CryptHashStart(&hashState, hashAlg);
552 CryptDigestUpdate(&hashState, 8, pOut);
553 CryptDigestUpdate2B(&hashState, digest);
554 CryptDigestUpdate(&hashState, saltSize, salt);
555 CryptHashEnd(&hashState, hLen, &pOut[out->size - hLen - 1]);
556 // Create a mask
557 if(CryptMGF_KDF(mLen, pOut, hashAlg, hLen, &pOut[mLen], 0) != mLen)
558 FAIL(FATAL_ERROR_INTERNAL);
559 // Since this implementation uses key sizes that are all even multiples of
560 // 8, just need to make sure that the most significant bit is CLEAR
561 *pOut &= 0x7f;
562 // Before we mess up the pOut value, set the last byte to 0xbc
563 pOut[out->size - 1] = 0xbc;
564 // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed
565 pOut = &pOut[mLen - saltSize - 1];
566 *pOut++ ^= 0x01;
567 // XOR the salt data into the buffer
568 for(; saltSize > 0; saltSize--)
569 *pOut++ ^= *ps++;
570 // and we are done
571 return TPM_RC_SUCCESS;
572}
573/* 10.2.17.4.10 PssDecode() */
574/* This function checks that the PSS encoded block was built from the provided digest. If the check
575 is successful, TPM_RC_SUCCESS is returned. Any other value indicates an error. */
576/* This implementation of PSS decoding is intended for the reference TPM implementation and is not
577 at all generalized. It is used to check signatures over hashes and assumptions are made about
578 the sizes of values. Those assumptions are enforce by this implementation. This implementation
579 does allow for a variable size salt value to have been used by the creator of the signature. */
580/* Error Returns Meaning */
581/* TPM_RC_SCHEME hashAlg is not a supported hash algorithm */
582/* TPM_RC_VALUE decode operation failed */
583static TPM_RC
584PssDecode(
585 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding
586 TPM2B *dIn, // In: the digest to compare
587 TPM2B *eIn // IN: the encoded data
588 )
589{
590 UINT32 hLen = CryptHashGetDigestSize(hashAlg);
591 BYTE mask[MAX_RSA_KEY_BYTES];
592 BYTE *pm = mask;
593 BYTE *pe;
594 BYTE pad[8] = {0};
595 UINT32 i;
596 UINT32 mLen;
597 BYTE fail;
598 TPM_RC retVal = TPM_RC_SUCCESS;
599 HASH_STATE hashState;
600 // These errors are indicative of failures due to programmer error
601 pAssert(dIn != NULL && eIn != NULL);
602 pe = eIn->buffer;
603 // check the hash scheme
604 if(hLen == 0)
605 ERROR_RETURN(TPM_RC_SCHEME);
606 // most significant bit must be zero
607 fail = pe[0] & 0x80;
608 // last byte must be 0xbc
609 fail |= pe[eIn->size - 1] ^ 0xbc;
610 // Use the hLen bytes at the end of the buffer to generate a mask
611 // Doesn't start at the end which is a flag byte
612 mLen = eIn->size - hLen - 1;
613 CryptMGF_KDF(mLen, mask, hashAlg, hLen, &pe[mLen], 0);
614 // Clear the MSO of the mask to make it consistent with the encoding.
615 mask[0] &= 0x7F;
616 pAssert(mLen <= sizeof(mask));
617 // XOR the data into the mask to recover the salt. This sequence
618 // advances eIn so that it will end up pointing to the seed data
619 // which is the hash of the signature data
620 for(i = mLen; i > 0; i--)
621 *pm++ ^= *pe++;
622 // Find the first byte of 0x01 after a string of all 0x00
623 for(pm = mask, i = mLen; i > 0; i--)
624 {
625 if(*pm == 0x01)
626 break;
627 else
628 fail |= *pm++;
629 }
630 // i should not be zero
631 fail |= (i == 0);
632 // if we have failed, will continue using the entire mask as the salt value so
633 // that the timing attacks will not disclose anything (I don't think that this
634 // is a problem for TPM applications but, usually, we don't fail so this
635 // doesn't cost anything).
636 if(fail)
637 {
638 i = mLen;
639 pm = mask;
640 }
641 else
642 {
643 pm++;
644 i--;
645 }
646 // i contains the salt size and pm points to the salt. Going to use the input
647 // hash and the seed to recreate the hash in the lower portion of eIn.
648 CryptHashStart(&hashState, hashAlg);
649 // add the pad of 8 zeros
650 CryptDigestUpdate(&hashState, 8, pad);
651 // add the provided digest value
652 CryptDigestUpdate(&hashState, dIn->size, dIn->buffer);
653 // and the salt
654 CryptDigestUpdate(&hashState, i, pm);
655 // get the result
656 fail |= (CryptHashEnd(&hashState, hLen, mask) != hLen);
657 // Compare all bytes
658 for(pm = mask; hLen > 0; hLen--)
659 // don't use fail = because that could skip the increment and compare
660 // operations after the first failure and that gives away timing
661 // information.
662 fail |= *pm++ ^ *pe++;
663 retVal = (fail != 0) ? TPM_RC_VALUE : TPM_RC_SUCCESS;
664 Exit:
665 return retVal;
666}
667/* 10.2.17.4.16 MakeDerTag() */
668/* Construct the DER value that is used in RSASSA */
669/* Return Value Meaning */
670/* > 0 size of value */
671/* <= 0 no hash exists */
672INT16
673MakeDerTag(
674 TPM_ALG_ID hashAlg,
675 INT16 sizeOfBuffer,
676 BYTE *buffer
677 )
678{
679 // 0x30, 0x31, // SEQUENCE (2 elements) 1st
680 // 0x30, 0x0D, // SEQUENCE (2 elements)
681 // 0x06, 0x09, // HASH OID
682 // 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
683 // 0x05, 0x00, // NULL
684 // 0x04, 0x20 // OCTET STRING
685 HASH_DEF *info = CryptGetHashDef(hashAlg);
686 INT16 oidSize;
687 // If no OID, can't do encode
688 VERIFY(info != NULL);
689 oidSize = 2 + (info->OID)[1];
690 // make sure this fits in the buffer
691 VERIFY(sizeOfBuffer >= (oidSize + 8));
692 *buffer++ = 0x30; // 1st SEQUENCE
693 // Size of the 1st SEQUENCE is 6 bytes + size of the hash OID + size of the
694 // digest size
695 *buffer++ = (BYTE)(6 + oidSize + info->digestSize); //
696 *buffer++ = 0x30; // 2nd SEQUENCE
697 // size is 4 bytes of overhead plus the side of the OID
698 *buffer++ = (BYTE)(2 + oidSize);
699 MemoryCopy(buffer, info->OID, oidSize);
700 buffer += oidSize;
701 *buffer++ = 0x05; // Add a NULL
702 *buffer++ = 0x00;
703
704 *buffer++ = 0x04;
705 *buffer++ = (BYTE)(info->digestSize);
706 return oidSize + 8;
707 Error:
708 return 0;
709
710}
711
712/* 10.2.17.4.17 RSASSA_Encode() */
713/* Encode a message using PKCS1v1.5 method. */
714/* Error Returns Meaning */
715/* TPM_RC_SCHEME hashAlg is not a supported hash algorithm */
716/* TPM_RC_SIZE eOutSize is not large enough */
717/* TPM_RC_VALUE hInSize does not match the digest size of hashAlg */
718static TPM_RC
719RSASSA_Encode(
720 TPM2B *pOut, // IN:OUT on in, the size of the public key
721 // on out, the encoded area
722 TPM_ALG_ID hashAlg, // IN: hash algorithm for PKCS1v1_5
723 TPM2B *hIn // IN: digest value to encode
724 )
725{
726 BYTE DER[20];
727 BYTE *der = DER;
728 INT32 derSize = MakeDerTag(hashAlg, sizeof(DER), DER);
729 BYTE *eOut;
730 INT32 fillSize;
731 TPM_RC retVal = TPM_RC_SUCCESS;
732
733 // Can't use this scheme if the algorithm doesn't have a DER string defined.
734 if(derSize == 0)
735 ERROR_RETURN(TPM_RC_SCHEME);
736
737 // If the digest size of 'hashAl' doesn't match the input digest size, then
738 // the DER will misidentify the digest so return an error
739 if(CryptHashGetDigestSize(hashAlg) != hIn->size)
740 ERROR_RETURN(TPM_RC_VALUE);
741 fillSize = pOut->size - derSize - hIn->size - 3;
742 eOut = pOut->buffer;
743
744 // Make sure that this combination will fit in the provided space
745 if(fillSize < 8)
746 ERROR_RETURN(TPM_RC_SIZE);
747
748 // Start filling
749 *eOut++ = 0; // initial byte of zero
750 *eOut++ = 1; // byte of 0x01
751 for(; fillSize > 0; fillSize--)
752 *eOut++ = 0xff; // bunch of 0xff
753 *eOut++ = 0; // another 0
754 for(; derSize > 0; derSize--)
755 *eOut++ = *der++; // copy the DER
756 der = hIn->buffer;
757 for(fillSize = hIn->size; fillSize > 0; fillSize--)
758 *eOut++ = *der++; // copy the hash
759 Exit:
760 return retVal;
761}
762
763/* 10.2.17.4.18 RSASSA_Decode() */
764/* This function performs the RSASSA decoding of a signature. */
765/* Error Returns Meaning */
766/* TPM_RC_VALUE decode unsuccessful */
767/* TPM_RC_SCHEME haslAlg is not supported */
768static TPM_RC
769RSASSA_Decode(
770 TPM_ALG_ID hashAlg, // IN: hash algorithm to use for the encoding
771 TPM2B *hIn, // In: the digest to compare
772 TPM2B *eIn // IN: the encoded data
773 )
774{
775 BYTE fail;
776 BYTE DER[20];
777 BYTE *der = DER;
778 INT32 derSize = MakeDerTag(hashAlg, sizeof(DER), DER);
779 BYTE *pe;
780 INT32 hashSize = CryptHashGetDigestSize(hashAlg);
781 INT32 fillSize;
782 TPM_RC retVal;
783 BYTE *digest;
784 UINT16 digestSize;
785
786 pAssert(hIn != NULL && eIn != NULL);
787 pe = eIn->buffer;
788
789 // Can't use this scheme if the algorithm doesn't have a DER string
790 // defined or if the provided hash isn't the right size
791 if(derSize == 0 || (unsigned)hashSize != hIn->size)
792 ERROR_RETURN(TPM_RC_SCHEME);
793
794 // Make sure that this combination will fit in the provided space
795 // Since no data movement takes place, can just walk though this
796 // and accept nearly random values. This can only be called from
797 // CryptValidateSignature() so eInSize is known to be in range.
798 fillSize = eIn->size - derSize - hashSize - 3;
799
800 // Start checking (fail will become non-zero if any of the bytes do not have
801 // the expected value.
802 fail = *pe++; // initial byte of zero
803 fail |= *pe++ ^ 1; // byte of 0x01
804 for(; fillSize > 0; fillSize--)
805 fail |= *pe++ ^ 0xff; // bunch of 0xff
806 fail |= *pe++; // another 0
807 for(; derSize > 0; derSize--)
808 fail |= *pe++ ^ *der++; // match the DER
809 digestSize = hIn->size;
810 digest = hIn->buffer;
811 for(; digestSize > 0; digestSize--)
812 fail |= *pe++ ^ *digest++; // match the hash
813 retVal = (fail != 0) ? TPM_RC_VALUE : TPM_RC_SUCCESS;
814 Exit:
815 return retVal;
816}
817#endif // libtpms added
818
819/* 10.2.17.4.13 CryptRsaSelectScheme() */
820/* This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to
821 select a scheme between input and object default. This function assume the RSA object is
822 loaded. If a default scheme is defined in object, the default scheme should be chosen, otherwise,
823 the input scheme should be chosen. In the case that both the object and scheme are not
824 TPM_ALG_NULL, then if the schemes are the same, the input scheme will be chosen. if the scheme
825 are not compatible, a NULL pointer will be returned. */
826/* The return pointer may point to a TPM_ALG_NULL scheme. */
827TPMT_RSA_DECRYPT*
828CryptRsaSelectScheme(
829 TPMI_DH_OBJECT rsaHandle, // IN: handle of an RSA key
830 TPMT_RSA_DECRYPT *scheme // IN: a sign or decrypt scheme
831 )
832{
833 OBJECT *rsaObject;
834 TPMT_ASYM_SCHEME *keyScheme;
835 TPMT_RSA_DECRYPT *retVal = NULL;
836 // Get sign object pointer
837 rsaObject = HandleToObject(rsaHandle);
838 keyScheme = &rsaObject->publicArea.parameters.asymDetail.scheme;
839 // if the default scheme of the object is TPM_ALG_NULL, then select the
840 // input scheme
841 if(keyScheme->scheme == TPM_ALG_NULL)
842 {
843 retVal = scheme;
844 }
845 // if the object scheme is not TPM_ALG_NULL and the input scheme is
846 // TPM_ALG_NULL, then select the default scheme of the object.
847 else if(scheme->scheme == TPM_ALG_NULL)
848 {
849 // if input scheme is NULL
850 retVal = (TPMT_RSA_DECRYPT *)keyScheme;
851 }
852 // get here if both the object scheme and the input scheme are
853 // not TPM_ALG_NULL. Need to insure that they are the same.
854 // IMPLEMENTATION NOTE: This could cause problems if future versions have
855 // schemes that have more values than just a hash algorithm. A new function
856 // (IsSchemeSame()) might be needed then.
857 else if(keyScheme->scheme == scheme->scheme
858 && keyScheme->details.anySig.hashAlg == scheme->details.anySig.hashAlg)
859 {
860 retVal = scheme;
861 }
862 // two different, incompatible schemes specified will return NULL
863 return retVal;
864}
865/* 10.2.17.4.14 CryptRsaLoadPrivateExponent() */
866/* Error Returns Meaning */
867/* TPM_RC_BINDING public and private parts of rsaKey are not matched */
868TPM_RC
869CryptRsaLoadPrivateExponent(
870 OBJECT *rsaKey // IN: the RSA key object
871 )
872{
873 BN_RSA_INITIALIZED(bnN, &rsaKey->publicArea.unique.rsa);
874 BN_PRIME_INITIALIZED(bnP, &rsaKey->sensitive.sensitive.rsa);
875 BN_RSA(bnQ);
876 BN_PRIME(bnQr);
877 BN_WORD_INITIALIZED(bnE, (rsaKey->publicArea.parameters.rsaDetail.exponent == 0)
878 ? RSA_DEFAULT_PUBLIC_EXPONENT
879 : rsaKey->publicArea.parameters.rsaDetail.exponent);
880 TPM_RC retVal = TPM_RC_SUCCESS;
881 if(!rsaKey->attributes.privateExp)
882 {
883 TEST(TPM_ALG_NULL);
884 // Make sure that the bigNum used for the exponent is properly initialized
885 RsaInitializeExponent(&rsaKey->privateExponent);
886 // Find the second prime by division
887 BnDiv(bnQ, bnQr, bnN, bnP);
888 if(!BnEqualZero(bnQr))
889 ERROR_RETURN(TPM_RC_BINDING);
890 // Compute the private exponent and return it if found
891 if(!ComputePrivateExponent(bnP, bnQ, bnE, bnN,
892 &rsaKey->privateExponent))
893 ERROR_RETURN(TPM_RC_BINDING);
894 }
895 Exit:
896 rsaKey->attributes.privateExp = (retVal == TPM_RC_SUCCESS);
897 return retVal;
898}
899#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
900/* 10.2.17.4.15 CryptRsaEncrypt() */
901/* This is the entry point for encryption using RSA. Encryption is use of the public exponent. The
902 padding parameter determines what padding will be used. */
903/* The cOutSize parameter must be at least as large as the size of the key. */
904/* If the padding is RSA_PAD_NONE, dIn is treated as a number. It must be lower in value than the
905 key modulus. */
906/* NOTE: If dIn has fewer bytes than cOut, then we don't add low-order zeros to dIn to make it the
907 size of the RSA key for the call to RSAEP. This is because the high order bytes of dIn might have
908 a numeric value that is greater than the value of the key modulus. If this had low-order zeros
909 added, it would have a numeric value larger than the modulus even though it started out with a
910 lower numeric value. */
911/* Error Returns Meaning */
912/* TPM_RC_VALUE cOutSize is too small (must be the size of the modulus) */
913/* TPM_RC_SCHEME padType is not a supported scheme */
914LIB_EXPORT TPM_RC
915CryptRsaEncrypt(
916 TPM2B_PUBLIC_KEY_RSA *cOut, // OUT: the encrypted data
917 TPM2B *dIn, // IN: the data to encrypt
918 OBJECT *key, // IN: the key used for encryption
919 TPMT_RSA_DECRYPT *scheme, // IN: the type of padding and hash
920 // if needed
921 const TPM2B *label, // IN: in case it is needed
922 RAND_STATE *rand // IN: random number generator
923 // state (mostly for testing)
924 )
925{
926 TPM_RC retVal = TPM_RC_SUCCESS;
927 TPM2B_PUBLIC_KEY_RSA dataIn;
928 //
929 // if the input and output buffers are the same, copy the input to a scratch
930 // buffer so that things don't get messed up.
931 if(dIn == &cOut->b)
932 {
933 MemoryCopy2B(&dataIn.b, dIn, sizeof(dataIn.t.buffer));
934 dIn = &dataIn.b;
935 }
936 // All encryption schemes return the same size of data
937 cOut->t.size = key->publicArea.unique.rsa.t.size;
938 TEST(scheme->scheme);
939 switch(scheme->scheme)
940 {
941 case TPM_ALG_NULL: // 'raw' encryption
942 {
943 INT32 i;
944 INT32 dSize = dIn->size;
945 // dIn can have more bytes than cOut as long as the extra bytes
946 // are zero. Note: the more significant bytes of a number in a byte
947 // buffer are the bytes at the start of the array.
948 for(i = 0; (i < dSize) && (dIn->buffer[i] == 0); i++);
949 dSize -= i;
950 if(dSize > cOut->t.size)
951 ERROR_RETURN(TPM_RC_VALUE);
952 // Pad cOut with zeros if dIn is smaller
953 memset(cOut->t.buffer, 0, cOut->t.size - dSize);
954 // And copy the rest of the value
955 memcpy(&cOut->t.buffer[cOut->t.size - dSize], &dIn->buffer[i], dSize);
956 // If the size of dIn is the same as cOut dIn could be larger than
957 // the modulus. If it is, then RSAEP() will catch it.
958 }
959 break;
960 case TPM_ALG_RSAES:
961 retVal = RSAES_PKCS1v1_5Encode(&cOut->b, dIn, rand);
962 break;
963 case TPM_ALG_OAEP:
964 retVal = OaepEncode(&cOut->b, scheme->details.oaep.hashAlg, label, dIn,
965 rand);
966 break;
967 default:
968 ERROR_RETURN(TPM_RC_SCHEME);
969 break;
970 }
971 // All the schemes that do padding will come here for the encryption step
972 // Check that the Encoding worked
973 if(retVal == TPM_RC_SUCCESS)
974 // Padding OK so do the encryption
975 retVal = RSAEP(&cOut->b, key);
976 Exit:
977 return retVal;
978}
979/* 10.2.17.4.16 CryptRsaDecrypt() */
980/* This is the entry point for decryption using RSA. Decryption is use of the private exponent. The
981 padType parameter determines what padding was used. */
982/* Error Returns Meaning */
983/* TPM_RC_SIZE cInSize is not the same as the size of the public modulus of key; or numeric value of
984 the encrypted data is greater than the modulus */
985/* TPM_RC_VALUE dOutSize is not large enough for the result */
986/* TPM_RC_SCHEME padType is not supported */
987LIB_EXPORT TPM_RC
988CryptRsaDecrypt(
989 TPM2B *dOut, // OUT: the decrypted data
990 TPM2B *cIn, // IN: the data to decrypt
991 OBJECT *key, // IN: the key to use for decryption
992 TPMT_RSA_DECRYPT *scheme, // IN: the padding scheme
993 const TPM2B *label // IN: in case it is needed for the scheme
994 )
995{
996 TPM_RC retVal;
997 // Make sure that the necessary parameters are provided
998 pAssert(cIn != NULL && dOut != NULL && key != NULL);
999 // Size is checked to make sure that the encrypted value is the right size
1000 if(cIn->size != key->publicArea.unique.rsa.t.size)
1001 ERROR_RETURN(TPM_RC_SIZE);
1002 TEST(scheme->scheme);
1003 // For others that do padding, do the decryption in place and then
1004 // go handle the decoding.
1005 retVal = RSADP(cIn, key);
1006 if(retVal == TPM_RC_SUCCESS)
1007 {
1008 // Remove padding
1009 switch(scheme->scheme)
1010 {
1011 case TPM_ALG_NULL:
1012 if(dOut->size < cIn->size)
1013 return TPM_RC_VALUE;
1014 MemoryCopy2B(dOut, cIn, dOut->size);
1015 break;
1016 case TPM_ALG_RSAES:
1017 retVal = RSAES_Decode(dOut, cIn);
1018 break;
1019 case TPM_ALG_OAEP:
1020 retVal = OaepDecode(dOut, scheme->details.oaep.hashAlg, label, cIn);
1021 break;
1022 default:
1023 retVal = TPM_RC_SCHEME;
1024 break;
1025 }
1026 }
1027 Exit:
1028 return retVal;
1029}
1030/* 10.2.17.4.17 CryptRsaSign() */
1031/* This function is used to generate an RSA signature of the type indicated in scheme. */
1032/* Error Returns Meaning */
1033/* TPM_RC_SCHEME scheme or hashAlg are not supported */
1034/* TPM_RC_VALUE hInSize does not match hashAlg (for RSASSA) */
1035LIB_EXPORT TPM_RC
1036CryptRsaSign(
1037 TPMT_SIGNATURE *sigOut,
1038 OBJECT *key, // IN: key to use
1039 TPM2B_DIGEST *hIn, // IN: the digest to sign
1040 RAND_STATE *rand // IN: the random number generator
1041 // to use (mostly for testing)
1042 )
1043{
1044 TPM_RC retVal = TPM_RC_SUCCESS;
1045 UINT16 modSize;
1046 // parameter checks
1047 pAssert(sigOut != NULL && key != NULL && hIn != NULL);
1048 modSize = key->publicArea.unique.rsa.t.size;
1049 // for all non-null signatures, the size is the size of the key modulus
1050 sigOut->signature.rsapss.sig.t.size = modSize;
1051 TEST(sigOut->sigAlg);
1052 switch(sigOut->sigAlg)
1053 {
1054 case TPM_ALG_NULL:
1055 sigOut->signature.rsapss.sig.t.size = 0;
1056 return TPM_RC_SUCCESS;
1057 case TPM_ALG_RSAPSS:
1058 retVal = PssEncode(&sigOut->signature.rsapss.sig.b,
1059 sigOut->signature.rsapss.hash, &hIn->b, rand);
1060 break;
1061 case TPM_ALG_RSASSA:
1062 retVal = RSASSA_Encode(&sigOut->signature.rsassa.sig.b,
1063 sigOut->signature.rsassa.hash, &hIn->b);
1064 break;
1065 default:
1066 retVal = TPM_RC_SCHEME;
1067 }
1068 if(retVal == TPM_RC_SUCCESS)
1069 {
1070 // Do the encryption using the private key
1071 retVal = RSADP(&sigOut->signature.rsapss.sig.b, key);
1072 }
1073 return retVal;
1074}
1075/* 10.2.17.4.18 CryptRsaValidateSignature() */
1076/* This function is used to validate an RSA signature. If the signature is valid TPM_RC_SUCCESS is
1077 returned. If the signature is not valid, TPM_RC_SIGNATURE is returned. Other return codes
1078 indicate either parameter problems or fatal errors. */
1079/* Error Returns Meaning */
1080/* TPM_RC_SIGNATURE the signature does not check */
1081/* TPM_RC_SCHEME unsupported scheme or hash algorithm */
1082LIB_EXPORT TPM_RC
1083CryptRsaValidateSignature(
1084 TPMT_SIGNATURE *sig, // IN: signature
1085 OBJECT *key, // IN: public modulus
1086 TPM2B_DIGEST *digest // IN: The digest being validated
1087 )
1088{
1089 TPM_RC retVal;
1090 //
1091 // Fatal programming errors
1092 pAssert(key != NULL && sig != NULL && digest != NULL);
1093 switch(sig->sigAlg)
1094 {
1095 case TPM_ALG_RSAPSS:
1096 case TPM_ALG_RSASSA:
1097 break;
1098 default:
1099 return TPM_RC_SCHEME;
1100 }
1101 // Errors that might be caused by calling parameters
1102 if(sig->signature.rsassa.sig.t.size != key->publicArea.unique.rsa.t.size)
1103 ERROR_RETURN(TPM_RC_SIGNATURE);
1104 TEST(sig->sigAlg);
1105 // Decrypt the block
1106 retVal = RSAEP(&sig->signature.rsassa.sig.b, key);
1107 if(retVal == TPM_RC_SUCCESS)
1108 {
1109 switch(sig->sigAlg)
1110 {
1111 case TPM_ALG_RSAPSS:
1112 retVal = PssDecode(sig->signature.any.hashAlg, &digest->b,
1113 &sig->signature.rsassa.sig.b);
1114 break;
1115 case TPM_ALG_RSASSA:
1116 retVal = RSASSA_Decode(sig->signature.any.hashAlg, &digest->b,
1117 &sig->signature.rsassa.sig.b);
1118 break;
1119 default:
1120 return TPM_RC_SCHEME;
1121 }
1122 }
1123 Exit:
1124 return (retVal != TPM_RC_SUCCESS) ? TPM_RC_SIGNATURE : TPM_RC_SUCCESS;
1125}
1126#endif // libtpms added
1127#if SIMULATION && USE_RSA_KEY_CACHE
1128extern int s_rsaKeyCacheEnabled;
1129int GetCachedRsaKey(OBJECT *key, RAND_STATE *rand);
1130#define GET_CACHED_KEY(key, rand) \
1131 (s_rsaKeyCacheEnabled && GetCachedRsaKey(key, rand))
1132#else
1133#define GET_CACHED_KEY(key, rand)
1134#endif
1135/* 10.2.17.4.19 CryptRsaGenerateKey() */
1136/* Generate an RSA key from a provided seed */
1137/* Error Returns Meaning */
1138/* TPM_RC_CANCELED operation was canceled */
1139/* TPM_RC_RANGE public exponent is not supported */
1140/* TPM_RC_VALUE could not find a prime using the provided parameters */
1141LIB_EXPORT TPM_RC
1142CryptRsaGenerateKey(
1143 OBJECT *rsaKey, // IN/OUT: The object structure in which
1144 // the key is created.
1145 RAND_STATE *rand // IN: if not NULL, the deterministic
1146 // RNG state
1147 )
1148{
1149 UINT32 i;
1150 BN_PRIME(bnP); // These four declarations initialize the number to 0
1151 BN_PRIME(bnQ);
1152 BN_RSA(bnD);
1153 BN_RSA(bnN);
1154 BN_WORD(bnE);
1155 UINT32 e;
1156 int keySizeInBits;
1157 TPMT_PUBLIC *publicArea = &rsaKey->publicArea;
1158 TPMT_SENSITIVE *sensitive = &rsaKey->sensitive;
1159 TPM_RC retVal = TPM_RC_NO_RESULT;
1160 //
1161 // Need to make sure that the caller did not specify an exponent that is
1162 // not supported
1163 e = publicArea->parameters.rsaDetail.exponent;
1164 if(e == 0)
1165 e = RSA_DEFAULT_PUBLIC_EXPONENT;
1166 if(e < 65537)
1167 ERROR_RETURN(TPM_RC_RANGE);
1168 if(e != RSA_DEFAULT_PUBLIC_EXPONENT && !IsPrimeInt(e))
1169 ERROR_RETURN(TPM_RC_RANGE);
1170 BnSetWord(bnE, e);
1171 // Check that e is prime
1172 // check for supported key size.
1173 keySizeInBits = publicArea->parameters.rsaDetail.keyBits;
1174 if(((keySizeInBits % 1024) != 0)
1175 || (keySizeInBits > MAX_RSA_KEY_BITS) // this might be redundant, but...
1176 || (keySizeInBits == 0))
1177 ERROR_RETURN(TPM_RC_VALUE);
1178 // Set the prime size for instrumentation purposes
1179 INSTRUMENT_SET(PrimeIndex, PRIME_INDEX(keySizeInBits / 2));
1180#if SIMULATION && USE_RSA_KEY_CACHE
1181 if(GET_CACHED_KEY(rsaKey, rand))
1182 return TPM_RC_SUCCESS;
1183#endif
1184 // Make sure that key generation has been tested
1185 TEST(TPM_ALG_NULL);
1186#if USE_OPENSSL_FUNCTIONS_RSA // libtpms added begin
1187 if (rand == NULL)
1188 return OpenSSLCryptRsaGenerateKey(rsaKey, e, keySizeInBits);
1189#endif // libtpms added end
1190 // Need to initialize the privateExponent structure
1191 RsaInitializeExponent(&rsaKey->privateExponent);
1192 // The prime is computed in P. When a new prime is found, Q is checked to
1193 // see if it is zero. If so, P is copied to Q and a new P is found.
1194 // When both P and Q are non-zero, the modulus and
1195 // private exponent are computed and a trial encryption/decryption is
1196 // performed. If the encrypt/decrypt fails, assume that at least one of the
1197 // primes is composite. Since we don't know which one, set Q to zero and start
1198 // over and find a new pair of primes.
1199 for(i = 1; (retVal != TPM_RC_SUCCESS) && (i != 100); i++)
1200 {
1201 if(_plat__IsCanceled())
1202 ERROR_RETURN(TPM_RC_CANCELED);
1203 BnGeneratePrimeForRSA(bnP, keySizeInBits / 2, e, rand);
1204 INSTRUMENT_INC(PrimeCounts[PrimeIndex]);
1205 // If this is the second prime, make sure that it differs from the
1206 // first prime by at least 2^100
1207 if(BnEqualZero(bnQ))
1208 {
1209 // copy p to q and compute another prime in p
1210 BnCopy(bnQ, bnP);
1211 continue;
1212 }
1213 // Make sure that the difference is at least 100 bits. Need to do it this
1214 // way because the big numbers are only positive values
1215 if(BnUnsignedCmp(bnP, bnQ) < 0)
1216 BnSub(bnD, bnQ, bnP);
1217 else
1218 BnSub(bnD, bnP, bnQ);
1219 if(BnMsb(bnD) < 100)
1220 continue;
1221 //Form the public modulus and set the unique value
1222 BnMult(bnN, bnP, bnQ);
1223 BnTo2B(bnN, &publicArea->unique.rsa.b,
1224 (NUMBYTES)BITS_TO_BYTES(keySizeInBits));
1225 // And the prime to the sensitive area
1226 BnTo2B(bnP, &sensitive->sensitive.rsa.b,
1227 (NUMBYTES)BITS_TO_BYTES(keySizeInBits) / 2);
1228 // Make sure everything came out right. The MSb of the values must be
1229 // one
1230 if(((publicArea->unique.rsa.t.buffer[0] & 0x80) == 0)
1231 || ((sensitive->sensitive.rsa.t.buffer[0] & 0x80) == 0))
1232 FAIL(FATAL_ERROR_INTERNAL);
1233 // Make sure that we can form the private exponent values
1234 if(ComputePrivateExponent(bnP, bnQ, bnE, bnN, &rsaKey->privateExponent)
1235 != TRUE)
1236 {
1237 // If ComputePrivateExponent could not find an inverse for
1238 // Q, then copy P and recompute P. This might
1239 // cause both to be recomputed if P is also zero
1240 if(BnEqualZero(bnQ))
1241 BnCopy(bnQ, bnP);
1242 continue;
1243 }
1244 retVal = TPM_RC_SUCCESS;
1245 // Do a trial encryption decryption if this is a signing key
1246 if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
1247 {
1248 BN_RSA(temp1);
1249 BN_RSA(temp2);
1250 BnGenerateRandomInRange(temp1, bnN, rand);
1251 // Encrypt with public exponent...
1252 BnModExp(temp2, temp1, bnE, bnN);
1253 // ... then decrypt with private exponent
1254 RsaPrivateKeyOp(temp2, bnN, bnP, &rsaKey->privateExponent);
1255 // If the starting and ending values are not the same,
1256 // start over )-;
1257 if(BnUnsignedCmp(temp2, temp1) != 0)
1258 {
1259 BnSetWord(bnQ, 0);
1260 retVal = TPM_RC_NO_RESULT;
1261 }
1262 }
1263 }
1264 Exit:
1265 if(retVal == TPM_RC_SUCCESS)
1266 rsaKey->attributes.privateExp = SET;
1267 return retVal;
1268}
1269
1270#if USE_OPENSSL_FUNCTIONS_RSA // libtpms added begin
1271LIB_EXPORT TPM_RC
1272CryptRsaEncrypt(
1273 TPM2B_PUBLIC_KEY_RSA *cOut, // OUT: the encrypted data
1274 TPM2B *dIn, // IN: the data to encrypt
1275 OBJECT *key, // IN: the key used for encryption
1276 TPMT_RSA_DECRYPT *scheme, // IN: the type of padding and hash
1277 // if needed
1278 const TPM2B *label, // IN: in case it is needed
1279 RAND_STATE *rand // IN: random number generator
1280 // state (mostly for testing)
1281 )
1282{
1283 TPM_RC retVal;
1284 TPM2B_PUBLIC_KEY_RSA dataIn;
1285 TPM2B_PUBLIC_KEY_RSA scratch;
1286 size_t outlen;
1287 EVP_PKEY *pkey = NULL;
1288 EVP_PKEY_CTX *ctx = NULL;
1289 const EVP_MD *md;
1290 const char *digestname;
1291 unsigned char *tmp = NULL;
1292 //
1293 // if the input and output buffers are the same, copy the input to a scratch
1294 // buffer so that things don't get messed up.
1295 if(dIn == &cOut->b)
1296 {
1297 MemoryCopy2B(&dataIn.b, dIn, sizeof(dataIn.t.buffer));
1298 dIn = &dataIn.b;
1299 }
1300 // All encryption schemes return the same size of data
1301 pAssert(sizeof(cOut->t.buffer) >= key->publicArea.unique.rsa.t.size);
1302 cOut->t.size = key->publicArea.unique.rsa.t.size;
1303 TEST(scheme->scheme);
1304
1305 retVal = InitOpenSSLRSAPublicKey(key, &pkey);
1306 if (retVal != TPM_RC_SUCCESS)
1307 return retVal;
1308
1309 ctx = EVP_PKEY_CTX_new(pkey, NULL);
1310 if (ctx == NULL ||
1311 EVP_PKEY_encrypt_init(ctx) <= 0)
1312 ERROR_RETURN(TPM_RC_FAILURE);
1313
1314 switch(scheme->scheme)
1315 {
1316 case TPM_ALG_NULL: // 'raw' encryption
1317 {
1318 INT32 i;
1319 INT32 dSize = dIn->size;
1320 // dIn can have more bytes than cOut as long as the extra bytes
1321 // are zero. Note: the more significant bytes of a number in a byte
1322 // buffer are the bytes at the start of the array.
1323 for(i = 0; (i < dSize) && (dIn->buffer[i] == 0); i++);
1324 dSize -= i;
1325 scratch.t.size = cOut->t.size;
1326 pAssert(scratch.t.size <= sizeof(scratch.t.buffer));
1327 if(dSize > scratch.t.size)
1328 ERROR_RETURN(TPM_RC_VALUE);
1329 // Pad cOut with zeros if dIn is smaller
1330 memset(scratch.t.buffer, 0, scratch.t.size - dSize);
1331 // And copy the rest of the value; value is then right-aligned
1332 memcpy(&scratch.t.buffer[scratch.t.size - dSize], &dIn->buffer[i], dSize);
1333
1334 dIn = &scratch.b;
1335 }
1336 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING) <= 0)
1337 ERROR_RETURN(TPM_RC_FAILURE);
1338 break;
1339 case TPM_ALG_RSAES:
1340 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
1341 ERROR_RETURN(TPM_RC_FAILURE);
1342 break;
1343 case TPM_ALG_OAEP:
1344 digestname = GetDigestNameByHashAlg(scheme->details.oaep.hashAlg);
1345 if (digestname == NULL)
1346 ERROR_RETURN(TPM_RC_VALUE);
1347
1348 md = EVP_get_digestbyname(digestname);
1349 if (md == NULL ||
1350 EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
1351 EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0)
1352 ERROR_RETURN(TPM_RC_FAILURE);
1353
1354 if (label->size > 0) {
1355 tmp = malloc(label->size);
1356 if (tmp == NULL)
1357 ERROR_RETURN(TPM_RC_FAILURE);
1358 memcpy(tmp, label->buffer, label->size);
1359 }
1360 // label->size == 0 is supported
1361 if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, tmp, label->size) <= 0)
1362 ERROR_RETURN(TPM_RC_FAILURE);
1363 tmp = NULL;
1364 break;
1365 default:
1366 ERROR_RETURN(TPM_RC_SCHEME);
1367 break;
1368 }
1369
1370 outlen = cOut->t.size;
1371
1372 if (EVP_PKEY_encrypt(ctx, cOut->t.buffer, &outlen,
1373 dIn->buffer, dIn->size) <= 0)
1374 ERROR_RETURN(TPM_RC_FAILURE);
1375
1376 cOut->t.size = outlen;
1377
1378 Exit:
1379 EVP_PKEY_free(pkey);
1380 EVP_PKEY_CTX_free(ctx);
1381 free(tmp);
1382
1383 return retVal;
1384}
1385
1386LIB_EXPORT TPM_RC
1387CryptRsaDecrypt(
1388 TPM2B *dOut, // OUT: the decrypted data
1389 TPM2B *cIn, // IN: the data to decrypt
1390 OBJECT *key, // IN: the key to use for decryption
1391 TPMT_RSA_DECRYPT *scheme, // IN: the padding scheme
1392 const TPM2B *label // IN: in case it is needed for the scheme
1393 )
1394{
1395 TPM_RC retVal;
1396 EVP_PKEY *pkey = NULL;
1397 EVP_PKEY_CTX *ctx = NULL;
1398 const EVP_MD *md = NULL;
1399 const char *digestname;
1400 size_t outlen;
1401 unsigned char *tmp = NULL;
1402 unsigned char buffer[MAX_RSA_KEY_BYTES];
1403
1404 // Make sure that the necessary parameters are provided
1405 pAssert(cIn != NULL && dOut != NULL && key != NULL);
1406 // Size is checked to make sure that the encrypted value is the right size
1407 if(cIn->size != key->publicArea.unique.rsa.t.size)
1408 ERROR_RETURN(TPM_RC_SIZE);
1409 TEST(scheme->scheme);
1410
1411 retVal = InitOpenSSLRSAPrivateKey(key, &pkey);
1412 if (retVal != TPM_RC_SUCCESS)
1413 return retVal;
1414
1415 ctx = EVP_PKEY_CTX_new(pkey, NULL);
1416 if (ctx == NULL ||
1417 EVP_PKEY_decrypt_init(ctx) <= 0)
1418 ERROR_RETURN(TPM_RC_FAILURE);
1419
1420 switch(scheme->scheme)
1421 {
1422 case TPM_ALG_NULL: // 'raw' encryption
1423 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING) <= 0)
1424 ERROR_RETURN(TPM_RC_FAILURE);
1425 break;
1426 case TPM_ALG_RSAES:
1427 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
1428 ERROR_RETURN(TPM_RC_FAILURE);
1429 break;
1430 case TPM_ALG_OAEP:
1431 digestname = GetDigestNameByHashAlg(scheme->details.oaep.hashAlg);
1432 if (digestname == NULL)
1433 ERROR_RETURN(TPM_RC_VALUE);
1434
1435 md = EVP_get_digestbyname(digestname);
1436 if (md == NULL ||
1437 EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0 ||
1438 EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0)
1439 ERROR_RETURN(TPM_RC_FAILURE);
1440
1441 if (label->size > 0) {
1442 tmp = malloc(label->size);
1443 if (tmp == NULL)
1444 ERROR_RETURN(TPM_RC_FAILURE);
1445 memcpy(tmp, label->buffer, label->size);
1446
1447 if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, tmp, label->size) <= 0)
1448 ERROR_RETURN(TPM_RC_FAILURE);
1449 tmp = NULL;
1450 }
1451 break;
1452 default:
1453 ERROR_RETURN(TPM_RC_SCHEME);
1454 break;
1455 }
1456
1457 /* cannot use cOut->buffer */
1458 outlen = sizeof(buffer);
1459 if (EVP_PKEY_decrypt(ctx, buffer, &outlen,
1460 cIn->buffer, cIn->size) <= 0)
1461 ERROR_RETURN(TPM_RC_FAILURE);
1462
1463 if (outlen > dOut->size)
1464 ERROR_RETURN(TPM_RC_FAILURE);
1465
1466 memcpy(dOut->buffer, buffer, outlen);
1467 dOut->size = outlen;
1468
1469 retVal = TPM_RC_SUCCESS;
1470
1471 Exit:
1472 EVP_PKEY_free(pkey);
1473 EVP_PKEY_CTX_free(ctx);
1474 free(tmp);
1475
1476 return retVal;
1477}
1478
1479LIB_EXPORT TPM_RC
1480CryptRsaSign(
1481 TPMT_SIGNATURE *sigOut,
1482 OBJECT *key, // IN: key to use
1483 TPM2B_DIGEST *hIn, // IN: the digest to sign
1484 RAND_STATE *rand // IN: the random number generator
1485 // to use (mostly for testing)
1486 )
1487{
1488 TPM_RC retVal = TPM_RC_SUCCESS;
1489 UINT16 modSize;
1490 size_t outlen;
1491 int padding;
1492 EVP_PKEY *pkey = NULL;
1493 EVP_PKEY_CTX *ctx = NULL;
1494 const EVP_MD *md;
1495 const char *digestname;
1496 TPMI_ALG_HASH hashAlg;
1497
1498 // parameter checks
1499 pAssert(sigOut != NULL && key != NULL && hIn != NULL);
1500 modSize = key->publicArea.unique.rsa.t.size;
1501 // for all non-null signatures, the size is the size of the key modulus
1502 sigOut->signature.rsapss.sig.t.size = modSize;
1503 TEST(sigOut->sigAlg);
1504
1505 switch(sigOut->sigAlg)
1506 {
1507 case TPM_ALG_NULL:
1508 sigOut->signature.rsapss.sig.t.size = 0;
1509 return TPM_RC_SUCCESS;
1510 case TPM_ALG_RSAPSS:
1511 padding = RSA_PKCS1_PSS_PADDING;
1512 hashAlg = sigOut->signature.rsapss.hash;
1513 break;
1514 case TPM_ALG_RSASSA:
1515 padding = RSA_PKCS1_PADDING;
1516 hashAlg = sigOut->signature.rsassa.hash;
1517 break;
1518 default:
1519 ERROR_RETURN(TPM_RC_SCHEME);
1520 }
1521
1522 digestname = GetDigestNameByHashAlg(hashAlg);
1523 if (digestname == NULL)
1524 ERROR_RETURN(TPM_RC_VALUE);
1525
1526 md = EVP_get_digestbyname(digestname);
1527 if (md == NULL)
1528 ERROR_RETURN(TPM_RC_FAILURE);
1529
1530 retVal = InitOpenSSLRSAPrivateKey(key, &pkey);
1531 if (retVal != TPM_RC_SUCCESS)
1532 return retVal;
1533
1534 ctx = EVP_PKEY_CTX_new(pkey, NULL);
1535 if (ctx == NULL ||
1536 EVP_PKEY_sign_init(ctx) <= 0)
1537 ERROR_RETURN(TPM_RC_FAILURE);
1538
1539 if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1540 EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
1541 ERROR_RETURN(TPM_RC_FAILURE);
1542
1543 /* careful with PSS padding: Use salt length = hash length (-1) if
1544 * length(digest) + length(hash-to-sign) + 2 <= modSize
1545 * otherwise use the max. possible salt length, which is the default (-2)
1546 * test case: 1024 bit key PSS signing sha512 hash
1547 */
1548 if (padding == RSA_PKCS1_PSS_PADDING &&
1549 EVP_MD_size(md) + hIn->b.size + 2 <= modSize && /* OSSL: RSA_padding_add_PKCS1_PSS_mgf1 */
1550 EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) <= 0)
1551 ERROR_RETURN(TPM_RC_FAILURE);
1552
1553 outlen = sigOut->signature.rsapss.sig.t.size;
1554 if (EVP_PKEY_sign(ctx,
1555 sigOut->signature.rsapss.sig.t.buffer, &outlen,
1556 hIn->b.buffer, hIn->b.size) <= 0)
1557 ERROR_RETURN(TPM_RC_FAILURE);
1558
1559 sigOut->signature.rsapss.sig.t.size = outlen;
1560
1561 Exit:
1562 EVP_PKEY_free(pkey);
1563 EVP_PKEY_CTX_free(ctx);
1564
1565 return retVal;
1566}
1567
1568LIB_EXPORT TPM_RC
1569CryptRsaValidateSignature(
1570 TPMT_SIGNATURE *sig, // IN: signature
1571 OBJECT *key, // IN: public modulus
1572 TPM2B_DIGEST *digest // IN: The digest being validated
1573 )
1574{
1575 TPM_RC retVal;
1576 int padding;
1577 EVP_PKEY *pkey = NULL;
1578 EVP_PKEY_CTX *ctx = NULL;
1579 const EVP_MD *md;
1580 const char *digestname;
1581
1582 //
1583 // Fatal programming errors
1584 pAssert(key != NULL && sig != NULL && digest != NULL);
1585 switch(sig->sigAlg)
1586 {
1587 case TPM_ALG_RSAPSS:
1588 padding = RSA_PKCS1_PSS_PADDING;
1589 break;
1590 case TPM_ALG_RSASSA:
1591 padding = RSA_PKCS1_PADDING;
1592 break;
1593 default:
1594 return TPM_RC_SCHEME;
1595 }
1596 // Errors that might be caused by calling parameters
1597 if(sig->signature.rsassa.sig.t.size != key->publicArea.unique.rsa.t.size)
1598 ERROR_RETURN(TPM_RC_SIGNATURE);
1599 TEST(sig->sigAlg);
1600
1601 retVal = InitOpenSSLRSAPublicKey(key, &pkey);
1602 if (retVal != TPM_RC_SUCCESS)
1603 return retVal;
1604
1605 digestname = GetDigestNameByHashAlg(sig->signature.any.hashAlg);
1606 if (digestname == NULL)
1607 ERROR_RETURN(TPM_RC_VALUE);
1608
1609 md = EVP_get_digestbyname(digestname);
1610 ctx = EVP_PKEY_CTX_new(pkey, NULL);
1611 if (md == NULL || ctx == NULL ||
1612 EVP_PKEY_verify_init(ctx) <= 0)
1613 ERROR_RETURN(TPM_RC_FAILURE);
1614
1615 if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1616 EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
1617 ERROR_RETURN(TPM_RC_FAILURE);
1618
1619 if (EVP_PKEY_verify(ctx,
1620 sig->signature.rsassa.sig.t.buffer, sig->signature.rsassa.sig.t.size,
1621 digest->t.buffer, digest->t.size) <= 0)
1622 ERROR_RETURN(TPM_RC_SIGNATURE);
1623
1624 retVal = TPM_RC_SUCCESS;
1625
1626 Exit:
1627 EVP_PKEY_free(pkey);
1628 EVP_PKEY_CTX_free(ctx);
1629
1630 return (retVal != TPM_RC_SUCCESS) ? TPM_RC_SIGNATURE : TPM_RC_SUCCESS;
1631}
1632#endif // USE_OPENSSL_FUNCTIONS_RSA libtpms added end
1633
1634#endif // TPM_ALG_RSA
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette