• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file was extracted from the TCG Published
2 // Trusted Platform Module Library
3 // Part 4: Supporting Routines
4 // Family "2.0"
5 // Level 00 Revision 01.16
6 // October 30, 2014
7 
8 #include <string.h>
9 
10 #include "OsslCryptoEngine.h"
11 #ifdef TPM_ALG_RSA
12 //
13 //
14 //      Local Functions
15 //
16 //      RsaPrivateExponent()
17 //
18 //     This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus
19 //     and one of the primes.
20 //     The results are returned in the key->private structure. The size of that structure is expanded to hold the
21 //     private exponent. If the computed value is smaller than the public modulus, the private exponent is de-
22 //     normalized.
23 //
24 //     Return Value                      Meaning
25 //
26 //     CRYPT_SUCCESS                     private exponent computed
27 //     CRYPT_PARAMETER                   prime is not half the size of the modulus, or the modulus is not evenly
28 //                                       divisible by the prime, or no private exponent could be computed
29 //                                       from the input parameters
30 //
31 CRYPT_RESULT
RsaPrivateExponent(RSA_KEY * key)32 RsaPrivateExponent(
33    RSA_KEY             *key                  // IN: the key to augment with the private
34                                              //     exponent
35    )
36 {
37    BN_CTX              *context;
38    BIGNUM              *bnD;
39    BIGNUM              *bnN;
40    BIGNUM              *bnP;
41    BIGNUM              *bnE;
42    BIGNUM              *bnPhi;
43    BIGNUM              *bnQ;
44    BIGNUM              *bnQr;
45    UINT32               fill;
46    CRYPT_RESULT         retVal = CRYPT_SUCCESS;                // Assume success
47    pAssert(key != NULL && key->privateKey != NULL && key->publicKey != NULL);
48    context = BN_CTX_new();
49    if(context == NULL)
50        FAIL(FATAL_ERROR_ALLOCATION);
51    BN_CTX_start(context);
52    bnE = BN_CTX_get(context);
53    bnD = BN_CTX_get(context);
54    bnN = BN_CTX_get(context);
55    bnP = BN_CTX_get(context);
56    bnPhi = BN_CTX_get(context);
57    bnQ = BN_CTX_get(context);
58    bnQr = BN_CTX_get(context);
59    if(bnQr == NULL)
60        FAIL(FATAL_ERROR_ALLOCATION);
61    // Assume the size of the public key value is within range
62    pAssert(key->publicKey->size <= MAX_RSA_KEY_BYTES);
63    if(   BN_bin2bn(key->publicKey->buffer, key->publicKey->size, bnN) == NULL
64       || BN_bin2bn(key->privateKey->buffer, key->privateKey->size, bnP) == NULL)
65         FAIL(FATAL_ERROR_INTERNAL);
66    // If P size is not 1/2 of n size, then this is not a valid value for this
67    // implementation. This will also catch the case were P is input as zero.
68    // This generates a return rather than an assert because the key being loaded
69    // might be SW generated and wrong.
70    if(BN_num_bits(bnP) < BN_num_bits(bnN)/2)
71    {
72        retVal = CRYPT_PARAMETER;
73        goto Cleanup;
74    }
75    // Get q = n/p;
76    if (BN_div(bnQ, bnQr, bnN, bnP, context) != 1)
77        FAIL(FATAL_ERROR_INTERNAL);
78    // If there is a remainder, then this is not a valid n
79    if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP))
80    {
81        retVal = CRYPT_PARAMETER;      // problem may be recoverable
82        goto Cleanup;
83    }
84    // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
85    if(   BN_copy(bnPhi, bnN) == NULL
86       || !BN_sub(bnPhi, bnPhi, bnP)
87       || !BN_sub(bnPhi, bnPhi, bnQ)
88       || !BN_add_word(bnPhi, 1))
89        FAIL(FATAL_ERROR_INTERNAL);
90    // Compute the multiplicative inverse
91    BN_set_word(bnE, key->exponent);
92    if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL)
93    {
94        // Going to assume that the error is caused by a bad
95        // set of parameters. Specifically, an exponent that is
96        // not compatible with the primes. In an implementation that
97        // has better visibility to the error codes, this might be
98        // refined so that failures in the library would return
99        // a more informative value. Should not assume here that
100        // the error codes will remain unchanged.
101         retVal = CRYPT_PARAMETER;
102         goto Cleanup;
103    }
104    fill = key->publicKey->size - BN_num_bytes(bnD);
105    BN_bn2bin(bnD, &key->privateKey->buffer[fill]);
106    memset(key->privateKey->buffer, 0, fill);
107    // Change the size of the private key so that it is known to contain
108    // a private exponent rather than a prime.
109    key->privateKey->size = key->publicKey->size;
110 Cleanup:
111    BN_CTX_end(context);
112    BN_CTX_free(context);
113    return retVal;
114 }
115 //
116 //
117 //       _cpri__TestKeyRSA()
118 //
119 //      This function computes the private exponent de = 1 mod (p-1)*(q-1) The inputs are the public modulus
120 //      and one of the primes or two primes.
121 //      If both primes are provided, the public modulus is computed. If only one prime is provided, the second
122 //      prime is computed. In either case, a private exponent is produced and placed in d.
123 //      If no modular inverse exists, then CRYPT_PARAMETER is returned.
124 //
125 //      Return Value                      Meaning
126 //
127 //      CRYPT_SUCCESS                     private exponent (d) was generated
128 //      CRYPT_PARAMETER                   one or more parameters are invalid
129 //
130 LIB_EXPORT CRYPT_RESULT
_cpri__TestKeyRSA(TPM2B * d,UINT32 exponent,TPM2B * publicKey,TPM2B * prime1,TPM2B * prime2)131 _cpri__TestKeyRSA(
132    TPM2B              *d,                    //   OUT: the address to receive the private
133                                              //       exponent
134    UINT32              exponent,             //   IN: the public modulu
135    TPM2B              *publicKey,            //   IN/OUT: an input if only one prime is
136                                              //       provided. an output if both primes are
137                                              //       provided
138    TPM2B              *prime1,               //   IN: a first prime
139    TPM2B              *prime2                //   IN: an optional second prime
140    )
141 {
142    BN_CTX             *context;
143    BIGNUM             *bnD;
144    BIGNUM             *bnN;
145    BIGNUM             *bnP;
146    BIGNUM             *bnE;
147    BIGNUM             *bnPhi;
148    BIGNUM             *bnQ;
149    BIGNUM             *bnQr;
150    UINT32             fill;
151    CRYPT_RESULT       retVal = CRYPT_SUCCESS;               // Assume success
152    pAssert(publicKey != NULL && prime1 != NULL);
153    // Make sure that the sizes are within range
154    pAssert(   prime1->size <= MAX_RSA_KEY_BYTES/2
155            && publicKey->size <= MAX_RSA_KEY_BYTES);
156    pAssert( prime2 == NULL || prime2->size < MAX_RSA_KEY_BYTES/2);
157    if(publicKey->size/2 != prime1->size)
158        return CRYPT_PARAMETER;
159    context = BN_CTX_new();
160    if(context == NULL)
161        FAIL(FATAL_ERROR_ALLOCATION);
162    BN_CTX_start(context);
163    bnE = BN_CTX_get(context);       //   public exponent (e)
164    bnD = BN_CTX_get(context);       //   private exponent (d)
165    bnN = BN_CTX_get(context);       //   public modulus (n)
166    bnP = BN_CTX_get(context);       //   prime1 (p)
167    bnPhi = BN_CTX_get(context);     //   (p-1)(q-1)
168    bnQ = BN_CTX_get(context);       //   prime2 (q)
169    bnQr = BN_CTX_get(context);      //   n mod p
170    if(bnQr == NULL)
171        FAIL(FATAL_ERROR_ALLOCATION);
172    if(BN_bin2bn(prime1->buffer, prime1->size, bnP) == NULL)
173        FAIL(FATAL_ERROR_INTERNAL);
174    // If prime2 is provided, then compute n
175    if(prime2 != NULL)
176    {
177        // Two primes provided so use them to compute n
178        if(BN_bin2bn(prime2->buffer, prime2->size, bnQ) == NULL)
179            FAIL(FATAL_ERROR_INTERNAL);
180         // Make sure that the sizes of the primes are compatible
181         if(BN_num_bits(bnQ) != BN_num_bits(bnP))
182         {
183             retVal = CRYPT_PARAMETER;
184             goto Cleanup;
185         }
186         // Multiply the primes to get the public modulus
187         if(BN_mul(bnN, bnP, bnQ, context) != 1)
188             FAIL(FATAL_ERROR_INTERNAL);
189         // if the space provided for the public modulus is large enough,
190         // save the created value
191         if(BN_num_bits(bnN) != (publicKey->size * 8))
192         {
193             retVal = CRYPT_PARAMETER;
194             goto Cleanup;
195         }
196         BN_bn2bin(bnN, publicKey->buffer);
197    }
198    else
199    {
200        if (BN_is_zero(bnP))
201        {
202            retVal = CRYPT_PARAMETER;
203            goto Cleanup;
204        }
205        // One prime provided so find the second prime by division
206        BN_bin2bn(publicKey->buffer, publicKey->size, bnN);
207         // Get q = n/p;
208         if(BN_div(bnQ, bnQr, bnN, bnP, context) != 1)
209             FAIL(FATAL_ERROR_INTERNAL);
210         // If there is a remainder, then this is not a valid n
211         if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP))
212         {
213             retVal = CRYPT_PARAMETER;      // problem may be recoverable
214             goto Cleanup;
215         }
216    }
217    // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
218    BN_copy(bnPhi, bnN);
219    BN_sub(bnPhi, bnPhi, bnP);
220    BN_sub(bnPhi, bnPhi, bnQ);
221    BN_add_word(bnPhi, 1);
222    // Compute the multiplicative inverse
223    BN_set_word(bnE, exponent);
224    if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL)
225    {
226         // Going to assume that the error is caused by a bad set of parameters.
227         // Specifically, an exponent that is not compatible with the primes.
228         // In an implementation that has better visibility to the error codes,
229         // this might be refined so that failures in the library would return
230         // a more informative value.
231         // Do not assume that the error codes will remain unchanged.
232         retVal = CRYPT_PARAMETER;
233         goto Cleanup;
234    }
235    // Return the private exponent.
236    // Make sure it is normalized to have the correct size.
237    d->size = publicKey->size;
238    fill = d->size - BN_num_bytes(bnD);
239    BN_bn2bin(bnD, &d->buffer[fill]);
240    memset(d->buffer, 0, fill);
241 Cleanup:
242    BN_CTX_end(context);
243    BN_CTX_free(context);
244    return retVal;
245 }
246 //
247 //
248 //       RSAEP()
249 //
250 //      This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a value
251 //      (m) with the public exponent (e), modulo the public (n).
252 //
253 //      Return Value                      Meaning
254 //
255 //      CRYPT_SUCCESS                     encryption complete
256 //      CRYPT_PARAMETER                   number to exponentiate is larger than the modulus
257 //
258 static CRYPT_RESULT
RSAEP(UINT32 dInOutSize,BYTE * dInOut,RSA_KEY * key)259 RSAEP (
260    UINT32              dInOutSize,           // OUT size of the encrypted block
261    BYTE               *dInOut,               // OUT: the encrypted data
262    RSA_KEY            *key                   // IN: the key to use
263    )
264 {
265    UINT32       e;
266    BYTE         exponent[4];
267    CRYPT_RESULT retVal;
268    e = key->exponent;
269    if(e == 0)
270        e = RSA_DEFAULT_PUBLIC_EXPONENT;
271    UINT32_TO_BYTE_ARRAY(e, exponent);
272    //!!! Can put check for test of RSA here
273    retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut, 4, exponent,
274                           key->publicKey->size, key->publicKey->buffer);
275    // Exponentiation result is stored in-place, thus no space shortage is possible.
276    pAssert(retVal != CRYPT_UNDERFLOW);
277    return retVal;
278 }
279 //
280 //
281 //       RSADP()
282 //
283 //      This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a value (c)
284 //      with the private exponent (d), modulo the public modulus (n). The decryption is in place.
285 //
286 //      This function also checks the size of the private key. If the size indicates that only a prime value is
287 //      present, the key is converted to being a private exponent.
288 //
289 //      Return Value                   Meaning
290 //
291 //      CRYPT_SUCCESS                  decryption succeeded
292 //      CRYPT_PARAMETER                the value to decrypt is larger than the modulus
293 //
294 static CRYPT_RESULT
RSADP(UINT32 dInOutSize,BYTE * dInOut,RSA_KEY * key)295 RSADP (
296    UINT32              dInOutSize,        // IN/OUT: size of decrypted data
297    BYTE               *dInOut,            // IN/OUT: the decrypted data
298    RSA_KEY            *key                // IN: the key
299    )
300 {
301    CRYPT_RESULT retVal;
302    //!!! Can put check for RSA tested here
303    // Make sure that the pointers are provided and that the private key is present
304    // If the private key is present it is assumed to have been created by
305    // so is presumed good _cpri__PrivateExponent
306    pAssert(key != NULL && dInOut != NULL &&
307            key->publicKey->size == key->publicKey->size);
308    // make sure that the value to be decrypted is smaller than the modulus
309    // note: this check is redundant as is also performed by _math__ModExp()
310    // which is optimized for use in RSA operations
311    if(_math__uComp(key->publicKey->size, key->publicKey->buffer,
312                    dInOutSize, dInOut) <= 0)
313        return CRYPT_PARAMETER;
314    // _math__ModExp can return CRYPT_PARAMTER or CRYPT_UNDERFLOW but actual
315    // underflow is not possible because everything is in the same buffer.
316    retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut,
317                           key->privateKey->size, key->privateKey->buffer,
318                           key->publicKey->size, key->publicKey->buffer);
319    // Exponentiation result is stored in-place, thus no space shortage is possible.
320    pAssert(retVal != CRYPT_UNDERFLOW);
321    return retVal;
322 }
323 //
324 //
325 //       OaepEncode()
326 //
327 //      This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must
328 //      equal the size of the modulus
329 //
330 //      Return Value                   Meaning
331 //
332 //      CRYPT_SUCCESS                  encode successful
333 //      CRYPT_PARAMETER                hashAlg is not valid
334 //      CRYPT_FAIL                     message size is too large
335 //
336 static CRYPT_RESULT
OaepEncode(UINT32 paddedSize,BYTE * padded,TPM_ALG_ID hashAlg,const char * label,UINT32 messageSize,BYTE * message,BYTE * testSeed)337 OaepEncode(
338    UINT32          paddedSize,       //   IN: pad value size
339    BYTE           *padded,           //   OUT: the pad data
340    TPM_ALG_ID      hashAlg,          //   IN: algorithm to use for padding
341    const char     *label,            //   IN: null-terminated string (may be NULL)
342    UINT32       messageSize,   // IN: the message size
343    BYTE        *message        // IN: the message being padded
344 #ifdef TEST_RSA                 //
345    , BYTE          *testSeed   // IN: optional seed used for testing.
346 #endif // TEST_RSA              //
347 )
348 {
349    UINT32       padLen;
350    UINT32       dbSize;
351    UINT32       i;
352    BYTE         mySeed[MAX_DIGEST_SIZE];
353    BYTE        *seed = mySeed;
354    INT32        hLen = _cpri__GetDigestSize(hashAlg);
355    BYTE         mask[MAX_RSA_KEY_BYTES];
356    BYTE        *pp;
357    BYTE        *pm;
358    UINT32       lSize = 0;
359    CRYPT_RESULT retVal = CRYPT_SUCCESS;
360    pAssert(padded != NULL && message != NULL);
361    // A value of zero is not allowed because the KDF can't produce a result
362    // if the digest size is zero.
363    if(hLen <= 0)
364        return CRYPT_PARAMETER;
365    // If a label is provided, get the length of the string, including the
366    // terminator
367    if(label != NULL)
368        lSize = (UINT32)strlen(label) + 1;
369    // Basic size check
370    // messageSize <= k 2hLen 2
371    if(messageSize > paddedSize - 2 * hLen - 2)
372        return CRYPT_FAIL;
373    // Hash L even if it is null
374    // Offset into padded leaving room for masked seed and byte of zero
375    pp = &padded[hLen + 1];
376    retVal = _cpri__HashBlock(hashAlg, lSize, (BYTE *)label, hLen, pp);
377    // concatenate PS of k mLen 2hLen 2
378    padLen = paddedSize - messageSize - (2 * hLen) - 2;
379    memset(&pp[hLen], 0, padLen);
380    pp[hLen+padLen] = 0x01;
381    padLen += 1;
382    memcpy(&pp[hLen+padLen], message, messageSize);
383    // The total size of db = hLen + pad + mSize;
384    dbSize = hLen+padLen+messageSize;
385    // If testing, then use the provided seed. Otherwise, use values
386    // from the RNG
387 #ifdef TEST_RSA
388    if(testSeed != NULL)
389        seed = testSeed;
390    else
391 #endif // TEST_RSA
392        _cpri__GenerateRandom(hLen, mySeed);
393    // mask = MGF1 (seed, nSize hLen 1)
394    if((retVal = _cpri__MGF1(dbSize, mask, hashAlg, hLen, seed)) < 0)
395        return retVal; // Don't expect an error because hash size is not zero
396                       // was detected in the call to _cpri__HashBlock() above.
397    // Create the masked db
398     pm = mask;
399     for(i = dbSize; i > 0; i--)
400         *pp++ ^= *pm++;
401     pp = &padded[hLen + 1];
402     // Run the masked data through MGF1
403     if((retVal = _cpri__MGF1(hLen, &padded[1], hashAlg, dbSize, pp)) < 0)
404         return retVal; // Don't expect zero here as the only case for zero
405                        // was detected in the call to _cpri__HashBlock() above.
406     // Now XOR the seed to create masked seed
407     pp = &padded[1];
408     pm = seed;
409     for(i = hLen; i > 0; i--)
410         *pp++ ^= *pm++;
411     // Set the first byte to zero
412     *padded = 0x00;
413     return CRYPT_SUCCESS;
414 }
415 //
416 //
417 //       OaepDecode()
418 //
419 //      This function performs OAEP padding checking. The size of the buffer to receive the recovered data. If
420 //      the padding is not valid, the dSize size is set to zero and the function returns CRYPT_NO_RESULTS.
421 //      The dSize parameter is used as an input to indicate the size available in the buffer. If insufficient space is
422 //      available, the size is not changed and the return code is CRYPT_FAIL.
423 //
424 //      Return Value                     Meaning
425 //
426 //      CRYPT_SUCCESS                    decode complete
427 //      CRYPT_PARAMETER                  the value to decode was larger than the modulus
428 //      CRYPT_FAIL                       the padding is wrong or the buffer to receive the results is too small
429 //
430 static CRYPT_RESULT
OaepDecode(UINT32 * dataOutSize,BYTE * dataOut,TPM_ALG_ID hashAlg,const char * label,UINT32 paddedSize,BYTE * padded)431 OaepDecode(
432     UINT32              *dataOutSize,        //   IN/OUT: the recovered data size
433     BYTE                *dataOut,            //   OUT: the recovered data
434     TPM_ALG_ID           hashAlg,            //   IN: algorithm to use for padding
435     const char          *label,              //   IN: null-terminated string (may be NULL)
436     UINT32               paddedSize,         //   IN: the size of the padded data
437     BYTE                *padded              //   IN: the padded data
438     )
439 {
440     UINT32          dSizeSave;
441     UINT32          i;
442     BYTE            seedMask[MAX_DIGEST_SIZE];
443     INT32           hLen = _cpri__GetDigestSize(hashAlg);
444     BYTE         mask[MAX_RSA_KEY_BYTES];
445     BYTE        *pp;
446     BYTE        *pm;
447     UINT32       lSize = 0;
448     CRYPT_RESULT retVal = CRYPT_SUCCESS;
449     // Unknown hash
450     pAssert(hLen > 0 && dataOutSize != NULL && dataOut != NULL && padded != NULL);
451     // If there is a label, get its size including the terminating 0x00
452     if(label != NULL)
453         lSize = (UINT32)strlen(label) + 1;
454    // Set the return size to zero so that it doesn't have to be done on each
455    // failure
456    dSizeSave = *dataOutSize;
457    *dataOutSize = 0;
458    // Strange size (anything smaller can't be an OAEP padded block)
459    // Also check for no leading 0
460    if(paddedSize < (unsigned)((2 * hLen) + 2) || *padded != 0)
461        return CRYPT_FAIL;
462    // Use the hash size to determine what to put through MGF1 in order
463    // to recover the seedMask
464    if((retVal = _cpri__MGF1(hLen, seedMask, hashAlg,
465                             paddedSize-hLen-1, &padded[hLen+1])) < 0)
466        return retVal;
467    // Recover the seed into seedMask
468    pp = &padded[1];
469    pm = seedMask;
470    for(i = hLen; i > 0; i--)
471        *pm++ ^= *pp++;
472    // Use the seed to generate the data mask
473    if((retVal = _cpri__MGF1(paddedSize-hLen-1, mask,     hashAlg,
474                             hLen, seedMask)) < 0)
475        return retVal;
476    // Use the mask generated from seed to recover the padded data
477    pp = &padded[hLen+1];
478    pm = mask;
479    for(i = paddedSize-hLen-1; i > 0; i--)
480        *pm++ ^= *pp++;
481    // Make sure that the recovered data has the hash of the label
482    // Put trial value in the seed mask
483    if((retVal=_cpri__HashBlock(hashAlg, lSize,(BYTE *)label, hLen, seedMask)) < 0)
484        return retVal;
485    if(memcmp(seedMask, mask, hLen) != 0)
486        return CRYPT_FAIL;
487    // find the start of the data
488    pm = &mask[hLen];
489    for(i = paddedSize-(2*hLen)-1; i > 0; i--)
490    {
491        if(*pm++ != 0)
492            break;
493    }
494 
495    // Magic value in the end of the fill area must be 1, anything else must be
496    // rejected.
497    if (pm[-1] != 1)
498      return CRYPT_FAIL;
499 
500    if(i == 0)
501        return CRYPT_PARAMETER;
502    // pm should be pointing at the first part of the data
503    // and i is one greater than the number of bytes to move
504    i--;
505    if(i > dSizeSave)
506    {
507         // Restore dSize
508         *dataOutSize = dSizeSave;
509         return CRYPT_FAIL;
510    }
511    memcpy(dataOut, pm, i);
512    *dataOutSize = i;
513    return CRYPT_SUCCESS;
514 }
515 //
516 //
517 //       PKSC1v1_5Encode()
518 //
519 //      This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1
520 //
521 //      Return Value                  Meaning
522 //
523 //      CRYPT_SUCCESS                 data encoded
524 //      CRYPT_PARAMETER               message size is too large
525 //
526 static CRYPT_RESULT
RSAES_PKSC1v1_5Encode(UINT32 paddedSize,BYTE * padded,UINT32 messageSize,BYTE * message)527 RSAES_PKSC1v1_5Encode(
528    UINT32              paddedSize,        //   IN: pad value size
529    BYTE               *padded,            //   OUT: the pad data
530    UINT32              messageSize,       //   IN: the message size
531    BYTE               *message            //   IN: the message being padded
532    )
533 {
534    UINT32      ps = paddedSize - messageSize - 3;
535    if(messageSize > paddedSize - 11)
536        return CRYPT_PARAMETER;
537    // move the message to the end of the buffer
538    memcpy(&padded[paddedSize - messageSize], message, messageSize);
539    // Set the first byte to 0x00 and the second to 0x02
540    *padded = 0;
541    padded[1] = 2;
542    // Fill with random bytes
543    _cpri__GenerateRandom(ps, &padded[2]);
544    // Set the delimiter for the random field to 0
545    padded[2+ps] = 0;
546    // Now, the only messy part. Make sure that all the ps bytes are non-zero
547    // In this implementation, use the value of the current index
548    for(ps++; ps > 1; ps--)
549    {
550        if(padded[ps] == 0)
551            padded[ps] = 0x55;    // In the < 0.5% of the cases that the random
552                                  // value is 0, just pick a value to put into
553                                  // the spot.
554    }
555    return CRYPT_SUCCESS;
556 }
557 //
558 //
559 //       RSAES_Decode()
560 //
561 //      This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1
562 //
563 //      Return Value                  Meaning
564 //
565 //      CRYPT_SUCCESS                 decode successful
566 //      CRYPT_FAIL                    decoding error or results would no fit into provided buffer
567 //
568 static CRYPT_RESULT
RSAES_Decode(UINT32 * messageSize,BYTE * message,UINT32 codedSize,BYTE * coded)569 RSAES_Decode(
570    UINT32             *messageSize,       //   IN/OUT: recovered message size
571    BYTE               *message,           //   OUT: the recovered message
572    UINT32              codedSize,         //   IN: the encoded message size
573    BYTE               *coded              //   IN: the encoded message
574    )
575 {
576    BOOL           fail = FALSE;
577    UINT32         ps;
578    fail = (codedSize < 11);
579    fail |= (coded[0] != 0x00) || (coded[1] != 0x02);
580    for(ps = 2; ps < codedSize; ps++)
581    {
582        if(coded[ps] == 0)
583            break;
584    }
585    ps++;
586    // Make sure that ps has not gone over the end and that there are at least 8
587    // bytes of pad data.
588    fail |= ((ps >= codedSize) || ((ps-2) < 8));
589    if((*messageSize < codedSize - ps) || fail)
590        return CRYPT_FAIL;
591    *messageSize = codedSize - ps;
592    memcpy(message, &coded[ps], codedSize - ps);
593    return CRYPT_SUCCESS;
594 }
595 //
596 //
597 //       PssEncode()
598 //
599 //      This function creates an encoded block of data that is the size of modulus. The function uses the
600 //      maximum salt size that will fit in the encoded block.
601 //
602 //      Return Value                      Meaning
603 //
604 //      CRYPT_SUCCESS                     encode successful
605 //      CRYPT_PARAMETER                   hashAlg is not a supported hash algorithm
606 //
607 static CRYPT_RESULT
PssEncode(UINT32 eOutSize,BYTE * eOut,TPM_ALG_ID hashAlg,UINT32 hashInSize,BYTE * hashIn,BYTE * saltIn)608 PssEncode   (
609    UINT32        eOutSize,        // IN: size of the encode data buffer
610    BYTE         *eOut,            // OUT: encoded data buffer
611    TPM_ALG_ID    hashAlg,         // IN: hash algorithm to use for the encoding
612    UINT32        hashInSize,      // IN: size of digest to encode
613    BYTE         *hashIn           // IN: the digest
614 #ifdef TEST_RSA                    //
615    , BYTE          *saltIn        // IN: optional parameter for testing
616 #endif // TEST_RSA                 //
617 )
618 {
619    INT32                  hLen = _cpri__GetDigestSize(hashAlg);
620    BYTE                   salt[MAX_RSA_KEY_BYTES - 1];
621    UINT16                 saltSize;
622    BYTE                 *ps = salt;
623    CRYPT_RESULT           retVal;
624    UINT16                 mLen;
625    CPRI_HASH_STATE        hashState;
626    // These are fatal errors indicating bad TPM firmware
627    pAssert(eOut != NULL && hLen > 0 && hashIn != NULL );
628    // Get the size of the mask
629    mLen = (UINT16)(eOutSize - hLen - 1);
630    // Maximum possible salt size is mask length - 1
631    saltSize = mLen - 1;
632    // Use the maximum salt size allowed by FIPS 186-4
633    if(saltSize > hLen)
634        saltSize = (UINT16)hLen;
635 //using eOut for scratch space
636    // Set the first 8 bytes to zero
637    memset(eOut, 0, 8);
638    // Get set the salt
639 #ifdef TEST_RSA
640    if(saltIn != NULL)
641    {
642        saltSize = hLen;
643        memcpy(salt, saltIn, hLen);
644    }
645    else
646 #endif // TEST_RSA
647        _cpri__GenerateRandom(saltSize, salt);
648    // Create the hash of the pad || input hash || salt
649    _cpri__StartHash(hashAlg, FALSE, &hashState);
650    _cpri__UpdateHash(&hashState, 8, eOut);
651    _cpri__UpdateHash(&hashState, hashInSize, hashIn);
652    _cpri__UpdateHash(&hashState, saltSize, salt);
653    _cpri__CompleteHash(&hashState, hLen, &eOut[eOutSize - hLen - 1]);
654    // Create a mask
655    if((retVal = _cpri__MGF1(mLen, eOut, hashAlg, hLen, &eOut[mLen])) < 0)
656    {
657        // Currently _cpri__MGF1 is not expected to return a CRYPT_RESULT error.
658        pAssert(0);
659    }
660    // Since this implementation uses key sizes that are all even multiples of
661    // 8, just need to make sure that the most significant bit is CLEAR
662    eOut[0] &= 0x7f;
663    // Before we mess up the eOut value, set the last byte to 0xbc
664    eOut[eOutSize - 1] = 0xbc;
665    // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed
666    eOut = &eOut[mLen - saltSize - 1];
667    *eOut++ ^= 0x01;
668    // XOR the salt data into the buffer
669    for(; saltSize > 0; saltSize--)
670        *eOut++ ^= *ps++;
671    // and we are done
672    return CRYPT_SUCCESS;
673 }
674 //
675 //
676 //       PssDecode()
677 //
678 //      This function checks that the PSS encoded block was built from the provided digest. If the check is
679 //      successful, CRYPT_SUCCESS is returned. Any other value indicates an error.
680 //      This implementation of PSS decoding is intended for the reference TPM implementation and is not at all
681 //      generalized. It is used to check signatures over hashes and assumptions are made about the sizes of
682 //      values. Those assumptions are enforce by this implementation. This implementation does allow for a
683 //      variable size salt value to have been used by the creator of the signature.
684 //
685 //
686 //
687 //
688 //      Return Value                      Meaning
689 //
690 //      CRYPT_SUCCESS                     decode successful
691 //      CRYPT_SCHEME                      hashAlg is not a supported hash algorithm
692 //      CRYPT_FAIL                        decode operation failed
693 //
694 static CRYPT_RESULT
PssDecode(TPM_ALG_ID hashAlg,UINT32 dInSize,BYTE * dIn,UINT32 eInSize,BYTE * eIn,UINT32 saltSize)695 PssDecode(
696    TPM_ALG_ID          hashAlg,              //   IN:   hash algorithm to use for the encoding
697    UINT32              dInSize,              //   IN:   size of the digest to compare
698    BYTE               *dIn,                  //   In:   the digest to compare
699    UINT32              eInSize,              //   IN:   size of the encoded data
700    BYTE               *eIn,                  //   IN:   the encoded data
701    UINT32              saltSize              //   IN:   the expected size of the salt
702    )
703 {
704    INT32            hLen = _cpri__GetDigestSize(hashAlg);
705    BYTE             mask[MAX_RSA_KEY_BYTES];
706    BYTE            *pm = mask;
707    BYTE             pad[8] = {0};
708    UINT32           i;
709    UINT32           mLen;
710    BOOL             fail = FALSE;
711    CRYPT_RESULT     retVal;
712    CPRI_HASH_STATE hashState;
713    // These errors are indicative of failures due to programmer error
714    pAssert(dIn != NULL && eIn != NULL);
715    // check the hash scheme
716    if(hLen == 0)
717        return CRYPT_SCHEME;
718    // most significant bit must be zero
719    fail = ((eIn[0] & 0x80) != 0);
720    // last byte must be 0xbc
721    fail |= (eIn[eInSize - 1] != 0xbc);
722    // Use the hLen bytes at the end of the buffer to generate a mask
723    // Doesn't start at the end which is a flag byte
724    mLen = eInSize - hLen - 1;
725    if((retVal = _cpri__MGF1(mLen, mask, hashAlg, hLen, &eIn[mLen])) < 0)
726        return retVal;
727    if(retVal == 0)
728        return CRYPT_FAIL;
729    // Clear the MSO of the mask to make it consistent with the encoding.
730    mask[0] &= 0x7F;
731    // XOR the data into the mask to recover the salt. This sequence
732    // advances eIn so that it will end up pointing to the seed data
733    // which is the hash of the signature data
734    for(i = mLen; i > 0; i--)
735        *pm++ ^= *eIn++;
736    // Find the first byte of 0x01 after a string of all 0x00
737    for(pm = mask, i = mLen; i > 0; i--)
738    {
739        if(*pm == 0x01)
740             break;
741        else
742             fail |= (*pm++ != 0);
743    }
744    fail |= (i == 0);
745    // if we have failed, will continue using the entire mask as the salt value so
746    // that the timing attacks will not disclose anything (I don't think that this
747    // is a problem for TPM applications but, usually, we don't fail so this
748    // doesn't cost anything).
749    if(fail)
750    {
751        i = mLen;
752        pm = mask;
753    }
754    else
755    {
756        pm++;
757        i--;
758    }
759    // If the salt size was provided, then the recovered size must match
760    fail |= (saltSize != 0 && i != saltSize);
761    // i contains the salt size and pm points to the salt. Going to use the input
762    // hash and the seed to recreate the hash in the lower portion of eIn.
763    _cpri__StartHash(hashAlg, FALSE, &hashState);
764    // add the pad of 8 zeros
765    _cpri__UpdateHash(&hashState, 8, pad);
766    // add the provided digest value
767    _cpri__UpdateHash(&hashState, dInSize, dIn);
768    // and the salt
769    _cpri__UpdateHash(&hashState, i, pm);
770    // get the result
771    retVal = _cpri__CompleteHash(&hashState, MAX_DIGEST_SIZE, mask);
772    // retVal will be the size of the digest or zero. If not equal to the indicated
773    // digest size, then the signature doesn't match
774    fail |= (retVal != hLen);
775    fail |= (memcmp(mask, eIn, hLen) != 0);
776    if(fail)
777        return CRYPT_FAIL;
778    else
779        return CRYPT_SUCCESS;
780 }
781 //
782 //
783 //       PKSC1v1_5SignEncode()
784 //
785 //      Encode a message using PKCS1v1().5 method.
786 //
787 //      Return Value                  Meaning
788 //
789 //      CRYPT_SUCCESS                 encode complete
790 //      CRYPT_SCHEME                  hashAlg is not a supported hash algorithm
791 //      CRYPT_PARAMETER               eOutSize is not large enough or hInSize does not match the digest
792 //                                    size of hashAlg
793 //
794 static CRYPT_RESULT
RSASSA_Encode(UINT32 eOutSize,BYTE * eOut,TPM_ALG_ID hashAlg,UINT32 hInSize,BYTE * hIn)795 RSASSA_Encode(
796    UINT32              eOutSize,         //   IN: the size of the resulting block
797    BYTE               *eOut,             //   OUT: the encoded block
798    TPM_ALG_ID          hashAlg,          //   IN: hash algorithm for PKSC1v1_5
799    UINT32              hInSize,          //   IN: size of hash to be signed
800    BYTE               *hIn               //   IN: hash buffer
801    )
802 {
803    const BYTE         *der;
804    INT32               derSize = _cpri__GetHashDER(hashAlg, &der);
805    INT32               fillSize;
806    pAssert(eOut != NULL && hIn != NULL);
807    // Can't use this scheme if the algorithm doesn't have a DER string defined.
808    if(
809 #if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES
810        hashAlg != TPM_ALG_NULL &&
811 #endif
812        derSize == 0)
813        return CRYPT_SCHEME;
814    // If the digest size of 'hashAl' doesn't match the input digest size, then
815    // the DER will misidentify the digest so return an error
816    if(
817 #if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES
818        hashAlg != TPM_ALG_NULL &&
819 #endif
820        (unsigned)_cpri__GetDigestSize(hashAlg) != hInSize)
821        return CRYPT_PARAMETER;
822    fillSize = eOutSize - derSize - hInSize - 3;
823    // Make sure that this combination will fit in the provided space
824    if(fillSize < 8)
825        return CRYPT_PARAMETER;
826    // Start filling
827    *eOut++ = 0; // initial byte of zero
828    *eOut++ = 1; // byte of 0x01
829    for(; fillSize > 0; fillSize--)
830        *eOut++ = 0xff; // bunch of 0xff
831    *eOut++ = 0; // another 0
832    for(; derSize > 0; derSize--)
833        *eOut++ = *der++;   // copy the DER
834    for(; hInSize > 0; hInSize--)
835        *eOut++ = *hIn++;   // copy the hash
836    return CRYPT_SUCCESS;
837 }
838 //
839 //
840 //       RSASSA_Decode()
841 //
842 //      This function performs the RSASSA decoding of a signature.
843 //
844 //      Return Value                      Meaning
845 //
846 //      CRYPT_SUCCESS                     decode successful
847 //      CRYPT_FAIL                        decode unsuccessful
848 //      CRYPT_SCHEME                      haslAlg is not supported
849 //
850 static CRYPT_RESULT
RSASSA_Decode(TPM_ALG_ID hashAlg,UINT32 hInSize,BYTE * hIn,UINT32 eInSize,BYTE * eIn)851 RSASSA_Decode(
852    TPM_ALG_ID          hashAlg,              //   IN:   hash algorithm to use for the encoding
853    UINT32              hInSize,              //   IN:   size of the digest to compare
854    BYTE               *hIn,                  //   In:   the digest to compare
855    UINT32              eInSize,              //   IN:   size of the encoded data
856    BYTE               *eIn                   //   IN:   the encoded data
857    )
858 {
859    BOOL                fail = FALSE;
860    const BYTE         *der;
861    INT32               derSize = _cpri__GetHashDER(hashAlg, &der);
862    INT32               hashSize = _cpri__GetDigestSize(hashAlg);
863    INT32               fillSize;
864    pAssert(hIn != NULL && eIn != NULL);
865    // Can't use this scheme if the algorithm doesn't have a DER string
866     // defined or if the provided hash isn't the right size
867     if(derSize == 0 || (unsigned)hashSize != hInSize)
868         return CRYPT_SCHEME;
869     // Make sure that this combination will fit in the provided space
870     // Since no data movement takes place, can just walk though this
871     // and accept nearly random values. This can only be called from
872     // _cpri__ValidateSignature() so eInSize is known to be in range.
873     fillSize = eInSize - derSize - hashSize - 3;
874     // Start checking
875     fail |= (*eIn++ != 0); // initial byte of zero
876     fail |= (*eIn++ != 1); // byte of 0x01
877     for(; fillSize > 0; fillSize--)
878         fail |= (*eIn++ != 0xff); // bunch of 0xff
879     fail |= (*eIn++ != 0); // another 0
880     for(; derSize > 0; derSize--)
881         fail |= (*eIn++ != *der++); // match the DER
882     for(; hInSize > 0; hInSize--)
883         fail |= (*eIn++ != *hIn++); // match the hash
884     if(fail)
885         return CRYPT_FAIL;
886     return CRYPT_SUCCESS;
887 }
888 //
889 //
890 //       Externally Accessible Functions
891 //
892 //       _cpri__RsaStartup()
893 //
894 //      Function that is called to initialize the hash service. In this implementation, this function does nothing but
895 //      it is called by the CryptUtilStartup() function and must be present.
896 //
897 LIB_EXPORT BOOL
_cpri__RsaStartup(void)898 _cpri__RsaStartup(
899     void
900     )
901 {
902     return TRUE;
903 }
904 //
905 //
906 //       _cpri__EncryptRSA()
907 //
908 //      This is the entry point for encryption using RSA. Encryption is use of the public exponent. The padding
909 //      parameter determines what padding will be used.
910 //      The cOutSize parameter must be at least as large as the size of the key.
911 //      If the padding is RSA_PAD_NONE, dIn is treaded as a number. It must be lower in value than the key
912 //      modulus.
913 //
914 //
915 //
916 //      NOTE:           If dIn has fewer bytes than cOut, then we don't add low-order zeros to dIn to make it the size of the RSA key for
917 //                      the call to RSAEP. This is because the high order bytes of dIn might have a numeric value that is greater than
918 //                      the value of the key modulus. If this had low-order zeros added, it would have a numeric value larger than the
919 //                      modulus even though it started out with a lower numeric value.
920 //
921 //
922 //      Return Value                        Meaning
923 //
924 //      CRYPT_SUCCESS                       encryption complete
925 //      CRYPT_PARAMETER                     cOutSize is too small (must be the size of the modulus)
926 //      CRYPT_SCHEME                        padType is not a supported scheme
927 //
928 LIB_EXPORT CRYPT_RESULT
_cpri__EncryptRSA(UINT32 * cOutSize,BYTE * cOut,RSA_KEY * key,TPM_ALG_ID padType,UINT32 dInSize,BYTE * dIn,TPM_ALG_ID hashAlg,const char * label)929 _cpri__EncryptRSA(
930    UINT32                *cOutSize,              //   OUT: the size of the encrypted data
931    BYTE                  *cOut,                  //   OUT: the encrypted data
932    RSA_KEY               *key,                   //   IN: the key to use for encryption
933    TPM_ALG_ID             padType,               //   IN: the type of padding
934    UINT32                 dInSize,               //   IN: the amount of data to encrypt
935    BYTE                  *dIn,                   //   IN: the data to encrypt
936    TPM_ALG_ID             hashAlg,               //   IN: in case this is needed
937    const char            *label                  //   IN: in case it is needed
938    )
939 {
940    CRYPT_RESULT          retVal = CRYPT_SUCCESS;
941    pAssert(cOutSize != NULL);
942    // All encryption schemes return the same size of data
943    if(*cOutSize < key->publicKey->size)
944        return CRYPT_PARAMETER;
945    *cOutSize = key->publicKey->size;
946    switch (padType)
947    {
948    case TPM_ALG_NULL: // 'raw' encryption
949        {
950            // dIn can have more bytes than cOut as long as the extra bytes
951            // are zero
952            for(; dInSize > *cOutSize; dInSize--)
953            {
954                if(*dIn++ != 0)
955                    return CRYPT_PARAMETER;
956               }
957               // If dIn is smaller than cOut, fill cOut with zeros
958               if(dInSize < *cOutSize)
959                   memset(cOut, 0, *cOutSize - dInSize);
960               // Copy the rest of the value
961               memcpy(&cOut[*cOutSize-dInSize], dIn, dInSize);
962               // If the size of dIn is the same as cOut dIn could be larger than
963               // the modulus. If it is, then RSAEP() will catch it.
964        }
965        break;
966    case TPM_ALG_RSAES:
967        retVal = RSAES_PKSC1v1_5Encode(*cOutSize, cOut, dInSize, dIn);
968        break;
969    case TPM_ALG_OAEP:
970        retVal = OaepEncode(*cOutSize, cOut, hashAlg, label, dInSize, dIn
971 #ifdef TEST_RSA
972                            ,NULL
973 #endif
974                           );
975        break;
976    default:
977        return CRYPT_SCHEME;
978    }
979    // All the schemes that do padding will come here for the encryption step
980    // Check that the Encoding worked
981    if(retVal != CRYPT_SUCCESS)
982        return retVal;
983    // Padding OK so do the encryption
984    return RSAEP(*cOutSize, cOut, key);
985 }
986 //
987 //
988 //       _cpri__DecryptRSA()
989 //
990 //      This is the entry point for decryption using RSA. Decryption is use of the private exponent. The padType
991 //      parameter determines what padding was used.
992 //
993 //      Return Value                    Meaning
994 //
995 //      CRYPT_SUCCESS                   successful completion
996 //      CRYPT_PARAMETER                 cInSize is not the same as the size of the public modulus of key; or
997 //                                      numeric value of the encrypted data is greater than the modulus
998 //      CRYPT_FAIL                      dOutSize is not large enough for the result
999 //      CRYPT_SCHEME                    padType is not supported
1000 //
1001 LIB_EXPORT CRYPT_RESULT
_cpri__DecryptRSA(UINT32 * dOutSize,BYTE * dOut,RSA_KEY * key,TPM_ALG_ID padType,UINT32 cInSize,BYTE * cIn,TPM_ALG_ID hashAlg,const char * label)1002 _cpri__DecryptRSA(
1003    UINT32              *dOutSize,          //   OUT: the size of the decrypted data
1004    BYTE                *dOut,              //   OUT: the decrypted data
1005    RSA_KEY             *key,               //   IN: the key to use for decryption
1006    TPM_ALG_ID           padType,           //   IN: the type of padding
1007    UINT32               cInSize,           //   IN: the amount of data to decrypt
1008    BYTE                *cIn,               //   IN: the data to decrypt
1009    TPM_ALG_ID           hashAlg,           //   IN: in case this is needed for the scheme
1010    const char          *label              //   IN: in case it is needed for the scheme
1011    )
1012 {
1013    CRYPT_RESULT        retVal;
1014    // Make sure that the necessary parameters are provided
1015    pAssert(cIn != NULL && dOut != NULL && dOutSize != NULL && key != NULL);
1016    // Size is checked to make sure that the decryption works properly
1017    if(cInSize != key->publicKey->size)
1018        return CRYPT_PARAMETER;
1019    // For others that do padding, do the decryption in place and then
1020    // go handle the decoding.
1021    if((retVal = RSADP(cInSize, cIn, key)) != CRYPT_SUCCESS)
1022        return retVal;      // Decryption failed
1023    // Remove padding
1024    switch (padType)
1025    {
1026    case TPM_ALG_NULL:
1027        if(*dOutSize < key->publicKey->size)
1028            return CRYPT_FAIL;
1029        *dOutSize = key->publicKey->size;
1030        memcpy(dOut, cIn, *dOutSize);
1031        return CRYPT_SUCCESS;
1032    case TPM_ALG_RSAES:
1033        return RSAES_Decode(dOutSize, dOut, cInSize, cIn);
1034        break;
1035    case TPM_ALG_OAEP:
1036        return OaepDecode(dOutSize, dOut, hashAlg, label, cInSize, cIn);
1037        break;
1038    default:
1039        return CRYPT_SCHEME;
1040        break;
1041    }
1042 }
1043 //
1044 //
1045 //       _cpri__SignRSA()
1046 //
1047 //      This function is used to generate an RSA signature of the type indicated in scheme.
1048 //
1049 //      Return Value                      Meaning
1050 //
1051 //      CRYPT_SUCCESS                     sign operation completed normally
1052 //      CRYPT_SCHEME                      scheme or hashAlg are not supported
1053 //      CRYPT_PARAMETER                   hInSize does not match hashAlg (for RSASSA)
1054 //
1055 LIB_EXPORT CRYPT_RESULT
_cpri__SignRSA(UINT32 * sigOutSize,BYTE * sigOut,RSA_KEY * key,TPM_ALG_ID scheme,TPM_ALG_ID hashAlg,UINT32 hInSize,BYTE * hIn)1056 _cpri__SignRSA(
1057    UINT32              *sigOutSize,          //   OUT: size of signature
1058    BYTE                *sigOut,              //   OUT: signature
1059    RSA_KEY             *key,                 //   IN: key to use
1060    TPM_ALG_ID           scheme,              //   IN: the scheme to use
1061    TPM_ALG_ID           hashAlg,             //   IN: hash algorithm for PKSC1v1_5
1062    UINT32               hInSize,             //   IN: size of digest to be signed
1063    BYTE                *hIn                  //   IN: digest buffer
1064    )
1065 {
1066    CRYPT_RESULT        retVal;
1067    // Parameter checks
1068    pAssert(sigOutSize != NULL && sigOut != NULL && key != NULL && hIn != NULL);
1069    // For all signatures the size is the size of the key modulus
1070    *sigOutSize = key->publicKey->size;
1071    switch (scheme)
1072    {
1073    case TPM_ALG_NULL:
1074        *sigOutSize = 0;
1075        return CRYPT_SUCCESS;
1076    case TPM_ALG_RSAPSS:
1077        // PssEncode can return CRYPT_PARAMETER
1078        retVal = PssEncode(*sigOutSize, sigOut, hashAlg, hInSize, hIn
1079 #ifdef TEST_RSA
1080                           , NULL
1081 #endif
1082                          );
1083        break;
1084    case TPM_ALG_RSASSA:
1085        // RSASSA_Encode can return CRYPT_PARAMETER or CRYPT_SCHEME
1086        retVal = RSASSA_Encode(*sigOutSize, sigOut, hashAlg, hInSize, hIn);
1087        break;
1088    default:
1089        return CRYPT_SCHEME;
1090    }
1091    if(retVal != CRYPT_SUCCESS)
1092        return retVal;
1093    // Do the encryption using the private key
1094    // RSADP can return CRYPT_PARAMETR
1095    return RSADP(*sigOutSize,sigOut, key);
1096 }
1097 //
1098 //
1099 //       _cpri__ValidateSignatureRSA()
1100 //
1101 //      This function is used to validate an RSA signature. If the signature is valid CRYPT_SUCCESS is
1102 //      returned. If the signature is not valid, CRYPT_FAIL is returned. Other return codes indicate either
1103 //      parameter problems or fatal errors.
1104 //
1105 //      Return Value                  Meaning
1106 //
1107 //      CRYPT_SUCCESS                 the signature checks
1108 //      CRYPT_FAIL                    the signature does not check
1109 //      CRYPT_SCHEME                  unsupported scheme or hash algorithm
1110 //
1111 LIB_EXPORT CRYPT_RESULT
_cpri__ValidateSignatureRSA(RSA_KEY * key,TPM_ALG_ID scheme,TPM_ALG_ID hashAlg,UINT32 hInSize,BYTE * hIn,UINT32 sigInSize,BYTE * sigIn,UINT16 saltSize)1112 _cpri__ValidateSignatureRSA(
1113    RSA_KEY            *key,               //   IN:   key to use
1114    TPM_ALG_ID          scheme,            //   IN:   the scheme to use
1115    TPM_ALG_ID          hashAlg,           //   IN:   hash algorithm
1116    UINT32              hInSize,           //   IN:   size of digest to be checked
1117    BYTE               *hIn,               //   IN:   digest buffer
1118    UINT32              sigInSize,         //   IN:   size of signature
1119    BYTE               *sigIn,             //   IN:   signature
1120    UINT16              saltSize           //   IN:   salt size for PSS
1121    )
1122 {
1123    CRYPT_RESULT        retVal;
1124    // Fatal programming errors
1125    pAssert(key != NULL && sigIn != NULL && hIn != NULL);
1126    // Errors that might be caused by calling parameters
1127    if(sigInSize != key->publicKey->size)
1128        return CRYPT_FAIL;
1129    // Decrypt the block
1130    if((retVal = RSAEP(sigInSize, sigIn, key)) != CRYPT_SUCCESS)
1131        return CRYPT_FAIL;
1132    switch (scheme)
1133    {
1134    case TPM_ALG_NULL:
1135        return CRYPT_SCHEME;
1136        break;
1137    case TPM_ALG_RSAPSS:
1138        return PssDecode(hashAlg, hInSize, hIn, sigInSize, sigIn, saltSize);
1139        break;
1140    case TPM_ALG_RSASSA:
1141        return RSASSA_Decode(hashAlg, hInSize, hIn, sigInSize, sigIn);
1142        break;
1143    default:
1144        break;
1145    }
1146    return CRYPT_SCHEME;
1147 }
1148 #ifndef RSA_KEY_SIEVE
1149 //
1150 //
1151 //       _cpri__GenerateKeyRSA()
1152 //
1153 //      Generate an RSA key from a provided seed
1154 //
1155 //
1156 //
1157 //
1158 //       Return Value                      Meaning
1159 //
1160 //       CRYPT_FAIL                        exponent is not prime or is less than 3; or could not find a prime using
1161 //                                         the provided parameters
1162 //       CRYPT_CANCEL                      operation was canceled
1163 //
1164 LIB_EXPORT CRYPT_RESULT
_cpri__GenerateKeyRSA(TPM2B * n,TPM2B * p,UINT16 keySizeInBits,UINT32 e,TPM_ALG_ID hashAlg,TPM2B * seed,const char * label,TPM2B * extra,UINT32 * counter)1165 _cpri__GenerateKeyRSA(
1166    TPM2B              *n,                     //   OUT: The public modulu
1167    TPM2B              *p,                     //   OUT: One of the prime factors of n
1168    UINT16              keySizeInBits,         //   IN: Size of the public modulus in bit
1169    UINT32              e,                     //   IN: The public exponent
1170    TPM_ALG_ID          hashAlg,               //   IN: hash algorithm to use in the key
1171                                               //       generation proce
1172    TPM2B              *seed,                  //   IN: the seed to use
1173    const char         *label,                 //   IN: A label for the generation process.
1174    TPM2B              *extra,                 //   IN: Party 1 data for the KDF
1175    UINT32             *counter                //   IN/OUT: Counter value to allow KFD iteration
1176                                               //       to be propagated across multiple routine
1177    )
1178 {
1179    UINT32              lLen;          // length of the label
1180                                       // (counting the terminating 0);
1181    UINT16              digestSize = _cpri__GetDigestSize(hashAlg);
1182    TPM2B_HASH_BLOCK         oPadKey;
1183    UINT32             outer;
1184    UINT32             inner;
1185    BYTE               swapped[4];
1186    CRYPT_RESULT    retVal;
1187    int             i, fill;
1188    const static char     defaultLabel[] = "RSA key";
1189    BYTE            *pb;
1190    CPRI_HASH_STATE     h1;                    // contains the hash of the
1191                                               //   HMAC key w/ iPad
1192    CPRI_HASH_STATE     h2;                    // contains the hash of the
1193                                               //   HMAC key w/ oPad
1194    CPRI_HASH_STATE     h;                     // the working hash context
1195    BIGNUM             *bnP;
1196    BIGNUM             *bnQ;
1197    BIGNUM             *bnT;
1198    BIGNUM             *bnE;
1199    BIGNUM             *bnN;
1200    BN_CTX             *context;
1201    UINT32              rem;
1202    // Make sure that hashAlg is valid hash
1203    pAssert(digestSize != 0);
1204    // if present, use externally provided counter
1205    if(counter != NULL)
1206        outer = *counter;
1207    else
1208        outer = 1;
1209    // Validate exponent
1210    UINT32_TO_BYTE_ARRAY(e, swapped);
1211    // Need to check that the exponent is prime and not less than 3
1212    if( e != 0 && (e < 3 || !_math__IsPrime(e)))
1213         return CRYPT_FAIL;
1214    // Get structures for the big number representations
1215    context = BN_CTX_new();
1216    if(context == NULL)
1217        FAIL(FATAL_ERROR_ALLOCATION);
1218    BN_CTX_start(context);
1219    bnP = BN_CTX_get(context);
1220    bnQ = BN_CTX_get(context);
1221    bnT = BN_CTX_get(context);
1222    bnE = BN_CTX_get(context);
1223    bnN = BN_CTX_get(context);
1224    if(bnN == NULL)
1225        FAIL(FATAL_ERROR_INTERNAL);
1226    // Set Q to zero. This is used as a flag. The prime is computed in P. When a
1227    // new prime is found, Q is checked to see if it is zero. If so, P is copied
1228    // to Q and a new P is found. When both P and Q are non-zero, the modulus and
1229    // private exponent are computed and a trial encryption/decryption is
1230    // performed. If the encrypt/decrypt fails, assume that at least one of the
1231    // primes is composite. Since we don't know which one, set Q to zero and start
1232    // over and find a new pair of primes.
1233    BN_zero(bnQ);
1234    // Need to have some label
1235    if(label == NULL)
1236        label = (const char *)&defaultLabel;
1237    // Get the label size
1238    for(lLen = 0; label[lLen++] != 0;);
1239    // Start the hash using the seed and get the intermediate hash value
1240    _cpri__StartHMAC(hashAlg, FALSE, &h1, seed->size, seed->buffer, &oPadKey.b);
1241    _cpri__StartHash(hashAlg, FALSE, &h2);
1242    _cpri__UpdateHash(&h2, oPadKey.b.size, oPadKey.b.buffer);
1243    n->size = (keySizeInBits +7)/8;
1244    pAssert(n->size <= MAX_RSA_KEY_BYTES);
1245    p->size = n->size / 2;
1246    if(e == 0)
1247        e = RSA_DEFAULT_PUBLIC_EXPONENT;
1248    BN_set_word(bnE, e);
1249    // The first test will increment the counter from zero.
1250    for(outer += 1; outer != 0; outer++)
1251    {
1252        if(_plat__IsCanceled())
1253        {
1254            retVal = CRYPT_CANCEL;
1255            goto Cleanup;
1256        }
1257         // Need to fill in the candidate with the hash
1258         fill = digestSize;
1259         pb = p->buffer;
1260         // Reset the inner counter
1261         inner = 0;
1262         for(i = p->size; i > 0; i -= digestSize)
1263         {
1264             inner++;
1265             // Initialize the HMAC with saved state
1266             _cpri__CopyHashState(&h, &h1);
1267               // Hash the inner counter (the one that changes on each HMAC iteration)
1268               UINT32_TO_BYTE_ARRAY(inner, swapped);
1269              _cpri__UpdateHash(&h, 4, swapped);
1270              _cpri__UpdateHash(&h, lLen, (BYTE *)label);
1271              // Is there any party 1 data
1272              if(extra != NULL)
1273                  _cpri__UpdateHash(&h, extra->size, extra->buffer);
1274              // Include the outer counter (the one that changes on each prime
1275              // prime candidate generation
1276              UINT32_TO_BYTE_ARRAY(outer, swapped);
1277              _cpri__UpdateHash(&h, 4, swapped);
1278              _cpri__UpdateHash(&h, 2, (BYTE *)&keySizeInBits);
1279              if(i < fill)
1280                  fill = i;
1281              _cpri__CompleteHash(&h, fill, pb);
1282              // Restart the oPad hash
1283              _cpri__CopyHashState(&h, &h2);
1284              // Add the last hashed data
1285              _cpri__UpdateHash(&h, fill, pb);
1286              // gives a completed HMAC
1287              _cpri__CompleteHash(&h, fill, pb);
1288              pb += fill;
1289         }
1290         // Set the Most significant 2 bits and the low bit of the candidate
1291         p->buffer[0] |= 0xC0;
1292         p->buffer[p->size - 1] |= 1;
1293         // Convert the candidate to a BN
1294         BN_bin2bn(p->buffer, p->size, bnP);
1295         // If this is the second prime, make sure that it differs from the
1296         // first prime by at least 2^100
1297         if(!BN_is_zero(bnQ))
1298         {
1299             // bnQ is non-zero if we already found it
1300             if(BN_ucmp(bnP, bnQ) < 0)
1301                 BN_sub(bnT, bnQ, bnP);
1302             else
1303                 BN_sub(bnT, bnP, bnQ);
1304             if(BN_num_bits(bnT) < 100) // Difference has to be at least 100 bits
1305                 continue;
1306         }
1307         // Make sure that the prime candidate (p) is not divisible by the exponent
1308         // and that (p-1) is not divisible by the exponent
1309         // Get the remainder after dividing by the modulus
1310         rem = BN_mod_word(bnP, e);
1311         if(rem == 0) // evenly divisible so add two keeping the number odd and
1312             // making sure that 1 != p mod e
1313             BN_add_word(bnP, 2);
1314         else if(rem == 1) // leaves a remainder of 1 so subtract two keeping the
1315             // number odd and making (e-1) = p mod e
1316             BN_sub_word(bnP, 2);
1317         // Have a candidate, check for primality
1318         if((retVal = (CRYPT_RESULT)BN_is_prime_ex(bnP,
1319                      BN_prime_checks, NULL, NULL)) < 0)
1320             FAIL(FATAL_ERROR_INTERNAL);
1321         if(retVal != 1)
1322             continue;
1323         // Found a prime, is this the first or second.
1324         if(BN_is_zero(bnQ))
1325         {
1326               // copy p to q and compute another prime in p
1327               BN_copy(bnQ, bnP);
1328               continue;
1329         }
1330         //Form the public modulus
1331         BN_mul(bnN, bnP, bnQ, context);
1332         if(BN_num_bits(bnN) != keySizeInBits)
1333             FAIL(FATAL_ERROR_INTERNAL);
1334         // Save the public modulus
1335         BnTo2B(n, bnN, n->size); // Will pad the buffer to the correct size
1336         pAssert((n->buffer[0] & 0x80) != 0);
1337         // And one prime
1338         BnTo2B(p, bnP, p->size);
1339         pAssert((p->buffer[0] & 0x80) != 0);
1340         // Finish by making sure that we can form the modular inverse of PHI
1341         // with respect to the public exponent
1342         // Compute PHI = (p - 1)(q - 1) = n - p - q + 1
1343         // Make sure that we can form the modular inverse
1344         BN_sub(bnT, bnN, bnP);
1345         BN_sub(bnT, bnT, bnQ);
1346         BN_add_word(bnT, 1);
1347         // find d such that (Phi * d) mod e ==1
1348         // If there isn't then we are broken because we took the step
1349         // of making sure that the prime != 1 mod e so the modular inverse
1350         // must exist
1351         if(BN_mod_inverse(bnT, bnE, bnT, context) == NULL || BN_is_zero(bnT))
1352             FAIL(FATAL_ERROR_INTERNAL);
1353         // And, finally, do a trial encryption decryption
1354         {
1355             TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES);
1356             TPM2B_RSA_KEY        r;
1357             r.t.size = sizeof(n->size);
1358               // If we are using a seed, then results must be reproducible on each
1359               // call. Otherwise, just get a random number
1360               if(seed == NULL)
1361                   _cpri__GenerateRandom(n->size, r.t.buffer);
1362               else
1363               {
1364                   // this this version does not have a deterministic RNG, XOR the
1365                   // public key and private exponent to get a deterministic value
1366                   // for testing.
1367                   int          i;
1368                   // Generate a random-ish number starting with the public modulus
1369                   // XORed with the MSO of the seed
1370                   for(i = 0; i < n->size; i++)
1371                       r.t.buffer[i] = n->buffer[i] ^ seed->buffer[0];
1372               }
1373               // Make sure that the number is smaller than the public modulus
1374               r.t.buffer[0] &= 0x7F;
1375                      // Convert
1376               if(    BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL
1377                      // Encrypt with the public exponent
1378                   || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1
1379                      // Decrypt with the private exponent
1380                   || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1)
1381                    FAIL(FATAL_ERROR_INTERNAL);
1382               // If the starting and ending values are not the same, start over )-;
1383               if(BN_ucmp(bnP, bnQ) != 0)
1384               {
1385                    BN_zero(bnQ);
1386                    continue;
1387              }
1388          }
1389          retVal = CRYPT_SUCCESS;
1390          goto Cleanup;
1391     }
1392     retVal = CRYPT_FAIL;
1393 Cleanup:
1394    // Close out the hash sessions
1395    _cpri__CompleteHash(&h2, 0, NULL);
1396    _cpri__CompleteHash(&h1, 0, NULL);
1397     // Free up allocated BN values
1398     BN_CTX_end(context);
1399     BN_CTX_free(context);
1400     if(counter != NULL)
1401         *counter = outer;
1402     return retVal;
1403 }
1404 #endif      // RSA_KEY_SIEVE
1405 #endif // TPM_ALG_RSA
1406