Coverage Report

Created: 2025-10-12 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tpm2/CpriRSA.c
Line
Count
Source
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
32
RsaPrivateExponent(
33
   RSA_KEY             *key                  // IN: the key to augment with the private
34
                                             //     exponent
35
   )
36
0
{
37
0
   BN_CTX              *context;
38
0
   BIGNUM              *bnD;
39
0
   BIGNUM              *bnN;
40
0
   BIGNUM              *bnP;
41
0
   BIGNUM              *bnE;
42
0
   BIGNUM              *bnPhi;
43
0
   BIGNUM              *bnQ;
44
0
   BIGNUM              *bnQr;
45
0
   UINT32               fill;
46
0
   CRYPT_RESULT         retVal = CRYPT_SUCCESS;                // Assume success
47
0
   pAssert(key != NULL && key->privateKey != NULL && key->publicKey != NULL);
48
0
   context = BN_CTX_new();
49
0
   if(context == NULL)
50
0
       FAIL(FATAL_ERROR_ALLOCATION);
51
0
   BN_CTX_start(context);
52
0
   bnE = BN_CTX_get(context);
53
0
   bnD = BN_CTX_get(context);
54
0
   bnN = BN_CTX_get(context);
55
0
   bnP = BN_CTX_get(context);
56
0
   bnPhi = BN_CTX_get(context);
57
0
   bnQ = BN_CTX_get(context);
58
0
   bnQr = BN_CTX_get(context);
59
0
   if(bnQr == NULL)
60
0
       FAIL(FATAL_ERROR_ALLOCATION);
61
   // Assume the size of the public key value is within range
62
0
   pAssert(key->publicKey->size <= MAX_RSA_KEY_BYTES);
63
0
   if(   BN_bin2bn(key->publicKey->buffer, key->publicKey->size, bnN) == NULL
64
0
      || BN_bin2bn(key->privateKey->buffer, key->privateKey->size, bnP) == NULL)
65
0
        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
0
   if(BN_num_bits(bnP) < BN_num_bits(bnN)/2)
71
0
   {
72
0
       retVal = CRYPT_PARAMETER;
73
0
       goto Cleanup;
74
0
   }
75
   // Get q = n/p;
76
0
   if (BN_div(bnQ, bnQr, bnN, bnP, context) != 1)
77
0
       FAIL(FATAL_ERROR_INTERNAL);
78
   // If there is a remainder, then this is not a valid n
79
0
   if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP))
80
0
   {
81
0
       retVal = CRYPT_PARAMETER;      // problem may be recoverable
82
0
       goto Cleanup;
83
0
   }
84
   // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
85
0
   if(   BN_copy(bnPhi, bnN) == NULL
86
0
      || !BN_sub(bnPhi, bnPhi, bnP)
87
0
      || !BN_sub(bnPhi, bnPhi, bnQ)
88
0
      || !BN_add_word(bnPhi, 1))
89
0
       FAIL(FATAL_ERROR_INTERNAL);
90
   // Compute the multiplicative inverse
91
0
   BN_set_word(bnE, key->exponent);
92
0
   if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL)
93
0
   {
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
0
        retVal = CRYPT_PARAMETER;
102
0
        goto Cleanup;
103
0
   }
104
0
   fill = key->publicKey->size - BN_num_bytes(bnD);
105
0
   BN_bn2bin(bnD, &key->privateKey->buffer[fill]);
106
0
   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
0
   key->privateKey->size = key->publicKey->size;
110
0
Cleanup:
111
0
   BN_CTX_end(context);
112
0
   BN_CTX_free(context);
113
0
   return retVal;
114
0
}
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
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
35
{
142
35
   BN_CTX             *context;
143
35
   BIGNUM             *bnD;
144
35
   BIGNUM             *bnN;
145
35
   BIGNUM             *bnP;
146
35
   BIGNUM             *bnE;
147
35
   BIGNUM             *bnPhi;
148
35
   BIGNUM             *bnQ;
149
35
   BIGNUM             *bnQr;
150
35
   UINT32             fill;
151
35
   CRYPT_RESULT       retVal = CRYPT_SUCCESS;               // Assume success
152
35
   pAssert(publicKey != NULL && prime1 != NULL);
153
   // Make sure that the sizes are within range
154
35
   pAssert(   prime1->size <= MAX_RSA_KEY_BYTES/2
155
35
           && publicKey->size <= MAX_RSA_KEY_BYTES);
156
35
   pAssert( prime2 == NULL || prime2->size < MAX_RSA_KEY_BYTES/2);
157
35
   if(publicKey->size/2 != prime1->size)
158
0
       return CRYPT_PARAMETER;
159
35
   context = BN_CTX_new();
160
35
   if(context == NULL)
161
0
       FAIL(FATAL_ERROR_ALLOCATION);
162
35
   BN_CTX_start(context);
163
35
   bnE = BN_CTX_get(context);       //   public exponent (e)
164
35
   bnD = BN_CTX_get(context);       //   private exponent (d)
165
35
   bnN = BN_CTX_get(context);       //   public modulus (n)
166
35
   bnP = BN_CTX_get(context);       //   prime1 (p)
167
35
   bnPhi = BN_CTX_get(context);     //   (p-1)(q-1)
168
35
   bnQ = BN_CTX_get(context);       //   prime2 (q)
169
35
   bnQr = BN_CTX_get(context);      //   n mod p
170
35
   if(bnQr == NULL)
171
0
       FAIL(FATAL_ERROR_ALLOCATION);
172
35
   if(BN_bin2bn(prime1->buffer, prime1->size, bnP) == NULL)
173
0
       FAIL(FATAL_ERROR_INTERNAL);
174
   // If prime2 is provided, then compute n
175
35
   if(prime2 != NULL)
176
0
   {
177
       // Two primes provided so use them to compute n
178
0
       if(BN_bin2bn(prime2->buffer, prime2->size, bnQ) == NULL)
179
0
           FAIL(FATAL_ERROR_INTERNAL);
180
        // Make sure that the sizes of the primes are compatible
181
0
        if(BN_num_bits(bnQ) != BN_num_bits(bnP))
182
0
        {
183
0
            retVal = CRYPT_PARAMETER;
184
0
            goto Cleanup;
185
0
        }
186
        // Multiply the primes to get the public modulus
187
0
        if(BN_mul(bnN, bnP, bnQ, context) != 1)
188
0
            FAIL(FATAL_ERROR_INTERNAL);
189
        // if the space provided for the public modulus is large enough,
190
        // save the created value
191
0
        if(BN_num_bits(bnN) != (publicKey->size * 8))
192
0
        {
193
0
            retVal = CRYPT_PARAMETER;
194
0
            goto Cleanup;
195
0
        }
196
0
        BN_bn2bin(bnN, publicKey->buffer);
197
0
   }
198
35
   else
199
35
   {
200
35
       if (BN_is_zero(bnP))
201
2
       {
202
2
           retVal = CRYPT_PARAMETER;
203
2
           goto Cleanup;
204
2
       }
205
       // One prime provided so find the second prime by division
206
33
       BN_bin2bn(publicKey->buffer, publicKey->size, bnN);
207
        // Get q = n/p;
208
33
        if(BN_div(bnQ, bnQr, bnN, bnP, context) != 1)
209
0
            FAIL(FATAL_ERROR_INTERNAL);
210
        // If there is a remainder, then this is not a valid n
211
33
        if(BN_num_bytes(bnQr) != 0 || BN_num_bits(bnQ) != BN_num_bits(bnP))
212
31
        {
213
31
            retVal = CRYPT_PARAMETER;      // problem may be recoverable
214
31
            goto Cleanup;
215
31
        }
216
33
   }
217
   // Get compute Phi = (p - 1)(q - 1) = pq - p - q + 1 = n - p - q + 1
218
2
   BN_copy(bnPhi, bnN);
219
2
   BN_sub(bnPhi, bnPhi, bnP);
220
2
   BN_sub(bnPhi, bnPhi, bnQ);
221
2
   BN_add_word(bnPhi, 1);
222
   // Compute the multiplicative inverse
223
2
   BN_set_word(bnE, exponent);
224
2
   if(BN_mod_inverse(bnD, bnE, bnPhi, context) == NULL)
225
1
   {
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
1
        retVal = CRYPT_PARAMETER;
233
1
        goto Cleanup;
234
1
   }
235
   // Return the private exponent.
236
   // Make sure it is normalized to have the correct size.
237
1
   d->size = publicKey->size;
238
1
   fill = d->size - BN_num_bytes(bnD);
239
1
   BN_bn2bin(bnD, &d->buffer[fill]);
240
1
   memset(d->buffer, 0, fill);
241
35
Cleanup:
242
35
   BN_CTX_end(context);
243
35
   BN_CTX_free(context);
244
35
   return retVal;
245
1
}
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
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
0
{
265
0
   UINT32       e;
266
0
   BYTE         exponent[4];
267
0
   CRYPT_RESULT retVal;
268
0
   e = key->exponent;
269
0
   if(e == 0)
270
0
       e = RSA_DEFAULT_PUBLIC_EXPONENT;
271
0
   UINT32_TO_BYTE_ARRAY(e, exponent);
272
   //!!! Can put check for test of RSA here
273
0
   retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut, 4, exponent,
274
0
                          key->publicKey->size, key->publicKey->buffer);
275
   // Exponentiation result is stored in-place, thus no space shortage is possible.
276
0
   pAssert(retVal != CRYPT_UNDERFLOW);
277
0
   return retVal;
278
0
}
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
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
0
{
301
0
   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
0
   pAssert(key != NULL && dInOut != NULL &&
307
0
           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
0
   if(_math__uComp(key->publicKey->size, key->publicKey->buffer,
312
0
                   dInOutSize, dInOut) <= 0)
313
0
       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
0
   retVal = _math__ModExp(dInOutSize, dInOut, dInOutSize, dInOut,
317
0
                          key->privateKey->size, key->privateKey->buffer,
318
0
                          key->publicKey->size, key->publicKey->buffer);
319
   // Exponentiation result is stored in-place, thus no space shortage is possible.
320
0
   pAssert(retVal != CRYPT_UNDERFLOW);
321
0
   return retVal;
322
0
}
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
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
0
{
349
0
   UINT32       padLen;
350
0
   UINT32       dbSize;
351
0
   UINT32       i;
352
0
   BYTE         mySeed[MAX_DIGEST_SIZE];
353
0
   BYTE        *seed = mySeed;
354
0
   INT32        hLen = _cpri__GetDigestSize(hashAlg);
355
0
   BYTE         mask[MAX_RSA_KEY_BYTES];
356
0
   BYTE        *pp;
357
0
   BYTE        *pm;
358
0
   UINT32       lSize = 0;
359
0
   CRYPT_RESULT retVal = CRYPT_SUCCESS;
360
0
   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
0
   if(hLen <= 0)
364
0
       return CRYPT_PARAMETER;
365
   // If a label is provided, get the length of the string, including the
366
   // terminator
367
0
   if(label != NULL)
368
0
       lSize = (UINT32)strlen(label) + 1;
369
   // Basic size check
370
   // messageSize <= k 2hLen 2
371
0
   if(messageSize > paddedSize - 2 * hLen - 2)
372
0
       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
0
   pp = &padded[hLen + 1];
376
0
   retVal = _cpri__HashBlock(hashAlg, lSize, (BYTE *)label, hLen, pp);
377
   // concatenate PS of k mLen 2hLen 2
378
0
   padLen = paddedSize - messageSize - (2 * hLen) - 2;
379
0
   memset(&pp[hLen], 0, padLen);
380
0
   pp[hLen+padLen] = 0x01;
381
0
   padLen += 1;
382
0
   memcpy(&pp[hLen+padLen], message, messageSize);
383
   // The total size of db = hLen + pad + mSize;
384
0
   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
0
       _cpri__GenerateRandom(hLen, mySeed);
393
   // mask = MGF1 (seed, nSize hLen 1)
394
0
   if((retVal = _cpri__MGF1(dbSize, mask, hashAlg, hLen, seed)) < 0)
395
0
       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
0
    pm = mask;
399
0
    for(i = dbSize; i > 0; i--)
400
0
        *pp++ ^= *pm++;
401
0
    pp = &padded[hLen + 1];
402
    // Run the masked data through MGF1
403
0
    if((retVal = _cpri__MGF1(hLen, &padded[1], hashAlg, dbSize, pp)) < 0)
404
0
        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
0
    pp = &padded[1];
408
0
    pm = seed;
409
0
    for(i = hLen; i > 0; i--)
410
0
        *pp++ ^= *pm++;
411
    // Set the first byte to zero
412
0
    *padded = 0x00;
413
0
    return CRYPT_SUCCESS;
414
0
}
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
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
0
{
440
0
    UINT32          dSizeSave;
441
0
    UINT32          i;
442
0
    BYTE            seedMask[MAX_DIGEST_SIZE];
443
0
    INT32           hLen = _cpri__GetDigestSize(hashAlg);
444
0
    BYTE         mask[MAX_RSA_KEY_BYTES];
445
0
    BYTE        *pp;
446
0
    BYTE        *pm;
447
0
    UINT32       lSize = 0;
448
0
    CRYPT_RESULT retVal = CRYPT_SUCCESS;
449
    // Unknown hash
450
0
    pAssert(hLen > 0 && dataOutSize != NULL && dataOut != NULL && padded != NULL);
451
    // If there is a label, get its size including the terminating 0x00
452
0
    if(label != NULL)
453
0
        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
0
   dSizeSave = *dataOutSize;
457
0
   *dataOutSize = 0;
458
   // Strange size (anything smaller can't be an OAEP padded block)
459
   // Also check for no leading 0
460
0
   if(paddedSize < (unsigned)((2 * hLen) + 2) || *padded != 0)
461
0
       return CRYPT_FAIL;
462
   // Use the hash size to determine what to put through MGF1 in order
463
   // to recover the seedMask
464
0
   if((retVal = _cpri__MGF1(hLen, seedMask, hashAlg,
465
0
                            paddedSize-hLen-1, &padded[hLen+1])) < 0)
466
0
       return retVal;
467
   // Recover the seed into seedMask
468
0
   pp = &padded[1];
469
0
   pm = seedMask;
470
0
   for(i = hLen; i > 0; i--)
471
0
       *pm++ ^= *pp++;
472
   // Use the seed to generate the data mask
473
0
   if((retVal = _cpri__MGF1(paddedSize-hLen-1, mask,     hashAlg,
474
0
                            hLen, seedMask)) < 0)
475
0
       return retVal;
476
   // Use the mask generated from seed to recover the padded data
477
0
   pp = &padded[hLen+1];
478
0
   pm = mask;
479
0
   for(i = paddedSize-hLen-1; i > 0; i--)
480
0
       *pm++ ^= *pp++;
481
   // Make sure that the recovered data has the hash of the label
482
   // Put trial value in the seed mask
483
0
   if((retVal=_cpri__HashBlock(hashAlg, lSize,(BYTE *)label, hLen, seedMask)) < 0)
484
0
       return retVal;
485
0
   if(memcmp(seedMask, mask, hLen) != 0)
486
0
       return CRYPT_FAIL;
487
   // find the start of the data
488
0
   pm = &mask[hLen];
489
0
   for(i = paddedSize-(2*hLen)-1; i > 0; i--)
490
0
   {
491
0
       if(*pm++ != 0)
492
0
           break;
493
0
   }
494
495
   // Magic value in the end of the fill area must be 1, anything else must be
496
   // rejected.
497
0
   if (pm[-1] != 1)
498
0
     return CRYPT_FAIL;
499
500
0
   if(i == 0)
501
0
       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
0
   i--;
505
0
   if(i > dSizeSave)
506
0
   {
507
        // Restore dSize
508
0
        *dataOutSize = dSizeSave;
509
0
        return CRYPT_FAIL;
510
0
   }
511
0
   memcpy(dataOut, pm, i);
512
0
   *dataOutSize = i;
513
0
   return CRYPT_SUCCESS;
514
0
}
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
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
0
{
534
0
   UINT32      ps = paddedSize - messageSize - 3;
535
0
   if(messageSize > paddedSize - 11)
536
0
       return CRYPT_PARAMETER;
537
   // move the message to the end of the buffer
538
0
   memcpy(&padded[paddedSize - messageSize], message, messageSize);
539
   // Set the first byte to 0x00 and the second to 0x02
540
0
   *padded = 0;
541
0
   padded[1] = 2;
542
   // Fill with random bytes
543
0
   _cpri__GenerateRandom(ps, &padded[2]);
544
   // Set the delimiter for the random field to 0
545
0
   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
0
   for(ps++; ps > 1; ps--)
549
0
   {
550
0
       if(padded[ps] == 0)
551
0
           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
0
   }
555
0
   return CRYPT_SUCCESS;
556
0
}
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
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
0
{
576
0
   BOOL           fail = FALSE;
577
0
   UINT32         ps;
578
0
   fail = (codedSize < 11);
579
0
   fail |= (coded[0] != 0x00) || (coded[1] != 0x02);
580
0
   for(ps = 2; ps < codedSize; ps++)
581
0
   {
582
0
       if(coded[ps] == 0)
583
0
           break;
584
0
   }
585
0
   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
0
   fail |= ((ps >= codedSize) || ((ps-2) < 8));
589
0
   if((*messageSize < codedSize - ps) || fail)
590
0
       return CRYPT_FAIL;
591
0
   *messageSize = codedSize - ps;
592
0
   memcpy(message, &coded[ps], codedSize - ps);
593
0
   return CRYPT_SUCCESS;
594
0
}
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
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
0
{
619
0
   INT32                  hLen = _cpri__GetDigestSize(hashAlg);
620
0
   BYTE                   salt[MAX_RSA_KEY_BYTES - 1];
621
0
   UINT16                 saltSize;
622
0
   BYTE                 *ps = salt;
623
0
   CRYPT_RESULT           retVal;
624
0
   UINT16                 mLen;
625
0
   CPRI_HASH_STATE        hashState;
626
   // These are fatal errors indicating bad TPM firmware
627
0
   pAssert(eOut != NULL && hLen > 0 && hashIn != NULL );
628
   // Get the size of the mask
629
0
   mLen = (UINT16)(eOutSize - hLen - 1);
630
   // Maximum possible salt size is mask length - 1
631
0
   saltSize = mLen - 1;
632
   // Use the maximum salt size allowed by FIPS 186-4
633
0
   if(saltSize > hLen)
634
0
       saltSize = (UINT16)hLen;
635
//using eOut for scratch space
636
   // Set the first 8 bytes to zero
637
0
   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
0
       _cpri__GenerateRandom(saltSize, salt);
648
   // Create the hash of the pad || input hash || salt
649
0
   _cpri__StartHash(hashAlg, FALSE, &hashState);
650
0
   _cpri__UpdateHash(&hashState, 8, eOut);
651
0
   _cpri__UpdateHash(&hashState, hashInSize, hashIn);
652
0
   _cpri__UpdateHash(&hashState, saltSize, salt);
653
0
   _cpri__CompleteHash(&hashState, hLen, &eOut[eOutSize - hLen - 1]);
654
   // Create a mask
655
0
   if((retVal = _cpri__MGF1(mLen, eOut, hashAlg, hLen, &eOut[mLen])) < 0)
656
0
   {
657
       // Currently _cpri__MGF1 is not expected to return a CRYPT_RESULT error.
658
0
       pAssert(0);
659
0
   }
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
0
   eOut[0] &= 0x7f;
663
   // Before we mess up the eOut value, set the last byte to 0xbc
664
0
   eOut[eOutSize - 1] = 0xbc;
665
   // XOR a byte of 0x01 at the position just before where the salt will be XOR'ed
666
0
   eOut = &eOut[mLen - saltSize - 1];
667
0
   *eOut++ ^= 0x01;
668
   // XOR the salt data into the buffer
669
0
   for(; saltSize > 0; saltSize--)
670
0
       *eOut++ ^= *ps++;
671
   // and we are done
672
0
   return CRYPT_SUCCESS;
673
0
}
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
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
0
{
704
0
   INT32            hLen = _cpri__GetDigestSize(hashAlg);
705
0
   BYTE             mask[MAX_RSA_KEY_BYTES];
706
0
   BYTE            *pm = mask;
707
0
   BYTE             pad[8] = {0};
708
0
   UINT32           i;
709
0
   UINT32           mLen;
710
0
   BOOL             fail = FALSE;
711
0
   CRYPT_RESULT     retVal;
712
0
   CPRI_HASH_STATE hashState;
713
   // These errors are indicative of failures due to programmer error
714
0
   pAssert(dIn != NULL && eIn != NULL);
715
   // check the hash scheme
716
0
   if(hLen == 0)
717
0
       return CRYPT_SCHEME;
718
   // most significant bit must be zero
719
0
   fail = ((eIn[0] & 0x80) != 0);
720
   // last byte must be 0xbc
721
0
   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
0
   mLen = eInSize - hLen - 1;
725
0
   if((retVal = _cpri__MGF1(mLen, mask, hashAlg, hLen, &eIn[mLen])) < 0)
726
0
       return retVal;
727
0
   if(retVal == 0)
728
0
       return CRYPT_FAIL;
729
   // Clear the MSO of the mask to make it consistent with the encoding.
730
0
   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
0
   for(i = mLen; i > 0; i--)
735
0
       *pm++ ^= *eIn++;
736
   // Find the first byte of 0x01 after a string of all 0x00
737
0
   for(pm = mask, i = mLen; i > 0; i--)
738
0
   {
739
0
       if(*pm == 0x01)
740
0
            break;
741
0
       else
742
0
            fail |= (*pm++ != 0);
743
0
   }
744
0
   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
0
   if(fail)
750
0
   {
751
0
       i = mLen;
752
0
       pm = mask;
753
0
   }
754
0
   else
755
0
   {
756
0
       pm++;
757
0
       i--;
758
0
   }
759
   // If the salt size was provided, then the recovered size must match
760
0
   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
0
   _cpri__StartHash(hashAlg, FALSE, &hashState);
764
   // add the pad of 8 zeros
765
0
   _cpri__UpdateHash(&hashState, 8, pad);
766
   // add the provided digest value
767
0
   _cpri__UpdateHash(&hashState, dInSize, dIn);
768
   // and the salt
769
0
   _cpri__UpdateHash(&hashState, i, pm);
770
   // get the result
771
0
   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
0
   fail |= (retVal != hLen);
775
0
   fail |= (memcmp(mask, eIn, hLen) != 0);
776
0
   if(fail)
777
0
       return CRYPT_FAIL;
778
0
   else
779
0
       return CRYPT_SUCCESS;
780
0
}
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
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
0
{
803
0
   const BYTE         *der;
804
0
   INT32               derSize = _cpri__GetHashDER(hashAlg, &der);
805
0
   INT32               fillSize;
806
0
   pAssert(eOut != NULL && hIn != NULL);
807
   // Can't use this scheme if the algorithm doesn't have a DER string defined.
808
0
   if(
809
0
#if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES
810
0
       hashAlg != TPM_ALG_NULL &&
811
0
#endif
812
0
       derSize == 0)
813
0
       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
0
   if(
817
0
#if defined(SUPPORT_PADDING_ONLY_RSASSA) && SUPPORT_PADDING_ONLY_RSASSA == YES
818
0
       hashAlg != TPM_ALG_NULL &&
819
0
#endif
820
0
       (unsigned)_cpri__GetDigestSize(hashAlg) != hInSize)
821
0
       return CRYPT_PARAMETER;
822
0
   fillSize = eOutSize - derSize - hInSize - 3;
823
   // Make sure that this combination will fit in the provided space
824
0
   if(fillSize < 8)
825
0
       return CRYPT_PARAMETER;
826
   // Start filling
827
0
   *eOut++ = 0; // initial byte of zero
828
0
   *eOut++ = 1; // byte of 0x01
829
0
   for(; fillSize > 0; fillSize--)
830
0
       *eOut++ = 0xff; // bunch of 0xff
831
0
   *eOut++ = 0; // another 0
832
0
   for(; derSize > 0; derSize--)
833
0
       *eOut++ = *der++;   // copy the DER
834
0
   for(; hInSize > 0; hInSize--)
835
0
       *eOut++ = *hIn++;   // copy the hash
836
0
   return CRYPT_SUCCESS;
837
0
}
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
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
0
{
859
0
   BOOL                fail = FALSE;
860
0
   const BYTE         *der;
861
0
   INT32               derSize = _cpri__GetHashDER(hashAlg, &der);
862
0
   INT32               hashSize = _cpri__GetDigestSize(hashAlg);
863
0
   INT32               fillSize;
864
0
   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
0
    if(derSize == 0 || (unsigned)hashSize != hInSize)
868
0
        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
0
    fillSize = eInSize - derSize - hashSize - 3;
874
    // Start checking
875
0
    fail |= (*eIn++ != 0); // initial byte of zero
876
0
    fail |= (*eIn++ != 1); // byte of 0x01
877
0
    for(; fillSize > 0; fillSize--)
878
0
        fail |= (*eIn++ != 0xff); // bunch of 0xff
879
0
    fail |= (*eIn++ != 0); // another 0
880
0
    for(; derSize > 0; derSize--)
881
0
        fail |= (*eIn++ != *der++); // match the DER
882
0
    for(; hInSize > 0; hInSize--)
883
0
        fail |= (*eIn++ != *hIn++); // match the hash
884
0
    if(fail)
885
0
        return CRYPT_FAIL;
886
0
    return CRYPT_SUCCESS;
887
0
}
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
898
_cpri__RsaStartup(
899
    void
900
    )
901
495
{
902
495
    return TRUE;
903
495
}
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
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
0
{
940
0
   CRYPT_RESULT          retVal = CRYPT_SUCCESS;
941
0
   pAssert(cOutSize != NULL);
942
   // All encryption schemes return the same size of data
943
0
   if(*cOutSize < key->publicKey->size)
944
0
       return CRYPT_PARAMETER;
945
0
   *cOutSize = key->publicKey->size;
946
0
   switch (padType)
947
0
   {
948
0
   case TPM_ALG_NULL: // 'raw' encryption
949
0
       {
950
           // dIn can have more bytes than cOut as long as the extra bytes
951
           // are zero
952
0
           for(; dInSize > *cOutSize; dInSize--)
953
0
           {
954
0
               if(*dIn++ != 0)
955
0
                   return CRYPT_PARAMETER;
956
0
              }
957
              // If dIn is smaller than cOut, fill cOut with zeros
958
0
              if(dInSize < *cOutSize)
959
0
                  memset(cOut, 0, *cOutSize - dInSize);
960
              // Copy the rest of the value
961
0
              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
0
       }
965
0
       break;
966
0
   case TPM_ALG_RSAES:
967
0
       retVal = RSAES_PKSC1v1_5Encode(*cOutSize, cOut, dInSize, dIn);
968
0
       break;
969
0
   case TPM_ALG_OAEP:
970
0
       retVal = OaepEncode(*cOutSize, cOut, hashAlg, label, dInSize, dIn
971
#ifdef TEST_RSA
972
                           ,NULL
973
#endif
974
0
                          );
975
0
       break;
976
0
   default:
977
0
       return CRYPT_SCHEME;
978
0
   }
979
   // All the schemes that do padding will come here for the encryption step
980
   // Check that the Encoding worked
981
0
   if(retVal != CRYPT_SUCCESS)
982
0
       return retVal;
983
   // Padding OK so do the encryption
984
0
   return RSAEP(*cOutSize, cOut, key);
985
0
}
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
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
0
{
1013
0
   CRYPT_RESULT        retVal;
1014
   // Make sure that the necessary parameters are provided
1015
0
   pAssert(cIn != NULL && dOut != NULL && dOutSize != NULL && key != NULL);
1016
   // Size is checked to make sure that the decryption works properly
1017
0
   if(cInSize != key->publicKey->size)
1018
0
       return CRYPT_PARAMETER;
1019
   // For others that do padding, do the decryption in place and then
1020
   // go handle the decoding.
1021
0
   if((retVal = RSADP(cInSize, cIn, key)) != CRYPT_SUCCESS)
1022
0
       return retVal;      // Decryption failed
1023
   // Remove padding
1024
0
   switch (padType)
1025
0
   {
1026
0
   case TPM_ALG_NULL:
1027
0
       if(*dOutSize < key->publicKey->size)
1028
0
           return CRYPT_FAIL;
1029
0
       *dOutSize = key->publicKey->size;
1030
0
       memcpy(dOut, cIn, *dOutSize);
1031
0
       return CRYPT_SUCCESS;
1032
0
   case TPM_ALG_RSAES:
1033
0
       return RSAES_Decode(dOutSize, dOut, cInSize, cIn);
1034
0
       break;
1035
0
   case TPM_ALG_OAEP:
1036
0
       return OaepDecode(dOutSize, dOut, hashAlg, label, cInSize, cIn);
1037
0
       break;
1038
0
   default:
1039
0
       return CRYPT_SCHEME;
1040
0
       break;
1041
0
   }
1042
0
}
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
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
0
{
1066
0
   CRYPT_RESULT        retVal;
1067
   // Parameter checks
1068
0
   pAssert(sigOutSize != NULL && sigOut != NULL && key != NULL && hIn != NULL);
1069
   // For all signatures the size is the size of the key modulus
1070
0
   *sigOutSize = key->publicKey->size;
1071
0
   switch (scheme)
1072
0
   {
1073
0
   case TPM_ALG_NULL:
1074
0
       *sigOutSize = 0;
1075
0
       return CRYPT_SUCCESS;
1076
0
   case TPM_ALG_RSAPSS:
1077
       // PssEncode can return CRYPT_PARAMETER
1078
0
       retVal = PssEncode(*sigOutSize, sigOut, hashAlg, hInSize, hIn
1079
#ifdef TEST_RSA
1080
                          , NULL
1081
#endif
1082
0
                         );
1083
0
       break;
1084
0
   case TPM_ALG_RSASSA:
1085
       // RSASSA_Encode can return CRYPT_PARAMETER or CRYPT_SCHEME
1086
0
       retVal = RSASSA_Encode(*sigOutSize, sigOut, hashAlg, hInSize, hIn);
1087
0
       break;
1088
0
   default:
1089
0
       return CRYPT_SCHEME;
1090
0
   }
1091
0
   if(retVal != CRYPT_SUCCESS)
1092
0
       return retVal;
1093
   // Do the encryption using the private key
1094
   // RSADP can return CRYPT_PARAMETR
1095
0
   return RSADP(*sigOutSize,sigOut, key);
1096
0
}
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
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
0
{
1123
0
   CRYPT_RESULT        retVal;
1124
   // Fatal programming errors
1125
0
   pAssert(key != NULL && sigIn != NULL && hIn != NULL);
1126
   // Errors that might be caused by calling parameters
1127
0
   if(sigInSize != key->publicKey->size)
1128
0
       return CRYPT_FAIL;
1129
   // Decrypt the block
1130
0
   if((retVal = RSAEP(sigInSize, sigIn, key)) != CRYPT_SUCCESS)
1131
0
       return CRYPT_FAIL;
1132
0
   switch (scheme)
1133
0
   {
1134
0
   case TPM_ALG_NULL:
1135
0
       return CRYPT_SCHEME;
1136
0
       break;
1137
0
   case TPM_ALG_RSAPSS:
1138
0
       return PssDecode(hashAlg, hInSize, hIn, sigInSize, sigIn, saltSize);
1139
0
       break;
1140
0
   case TPM_ALG_RSASSA:
1141
0
       return RSASSA_Decode(hashAlg, hInSize, hIn, sigInSize, sigIn);
1142
0
       break;
1143
0
   default:
1144
0
       break;
1145
0
   }
1146
0
   return CRYPT_SCHEME;
1147
0
}
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
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
3
{
1179
3
   UINT32              lLen;          // length of the label
1180
                                      // (counting the terminating 0);
1181
3
   UINT16              digestSize = _cpri__GetDigestSize(hashAlg);
1182
3
   TPM2B_HASH_BLOCK         oPadKey;
1183
3
   UINT32             outer;
1184
3
   UINT32             inner;
1185
3
   BYTE               swapped[4];
1186
3
   CRYPT_RESULT    retVal;
1187
3
   int             i, fill;
1188
3
   const static char     defaultLabel[] = "RSA key";
1189
3
   BYTE            *pb;
1190
3
   CPRI_HASH_STATE     h1;                    // contains the hash of the
1191
                                              //   HMAC key w/ iPad
1192
3
   CPRI_HASH_STATE     h2;                    // contains the hash of the
1193
                                              //   HMAC key w/ oPad
1194
3
   CPRI_HASH_STATE     h;                     // the working hash context
1195
3
   BIGNUM             *bnP;
1196
3
   BIGNUM             *bnQ;
1197
3
   BIGNUM             *bnT;
1198
3
   BIGNUM             *bnE;
1199
3
   BIGNUM             *bnN;
1200
3
   BN_CTX             *context;
1201
3
   UINT32              rem;
1202
   // Make sure that hashAlg is valid hash
1203
3
   pAssert(digestSize != 0);
1204
   // if present, use externally provided counter
1205
3
   if(counter != NULL)
1206
3
       outer = *counter;
1207
0
   else
1208
0
       outer = 1;
1209
   // Validate exponent
1210
3
   UINT32_TO_BYTE_ARRAY(e, swapped);
1211
   // Need to check that the exponent is prime and not less than 3
1212
3
   if( e != 0 && (e < 3 || !_math__IsPrime(e)))
1213
0
        return CRYPT_FAIL;
1214
   // Get structures for the big number representations
1215
3
   context = BN_CTX_new();
1216
3
   if(context == NULL)
1217
0
       FAIL(FATAL_ERROR_ALLOCATION);
1218
3
   BN_CTX_start(context);
1219
3
   bnP = BN_CTX_get(context);
1220
3
   bnQ = BN_CTX_get(context);
1221
3
   bnT = BN_CTX_get(context);
1222
3
   bnE = BN_CTX_get(context);
1223
3
   bnN = BN_CTX_get(context);
1224
3
   if(bnN == NULL)
1225
0
       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
3
   BN_zero(bnQ);
1234
   // Need to have some label
1235
3
   if(label == NULL)
1236
0
       label = (const char *)&defaultLabel;
1237
   // Get the label size
1238
54
   for(lLen = 0; label[lLen++] != 0;);
1239
   // Start the hash using the seed and get the intermediate hash value
1240
3
   _cpri__StartHMAC(hashAlg, FALSE, &h1, seed->size, seed->buffer, &oPadKey.b);
1241
3
   _cpri__StartHash(hashAlg, FALSE, &h2);
1242
3
   _cpri__UpdateHash(&h2, oPadKey.b.size, oPadKey.b.buffer);
1243
3
   n->size = (keySizeInBits +7)/8;
1244
3
   pAssert(n->size <= MAX_RSA_KEY_BYTES);
1245
3
   p->size = n->size / 2;
1246
3
   if(e == 0)
1247
0
       e = RSA_DEFAULT_PUBLIC_EXPONENT;
1248
3
   BN_set_word(bnE, e);
1249
   // The first test will increment the counter from zero.
1250
1.19k
   for(outer += 1; outer != 0; outer++)
1251
1.19k
   {
1252
1.19k
       if(_plat__IsCanceled())
1253
0
       {
1254
0
           retVal = CRYPT_CANCEL;
1255
0
           goto Cleanup;
1256
0
       }
1257
        // Need to fill in the candidate with the hash
1258
1.19k
        fill = digestSize;
1259
1.19k
        pb = p->buffer;
1260
        // Reset the inner counter
1261
1.19k
        inner = 0;
1262
5.73k
        for(i = p->size; i > 0; i -= digestSize)
1263
4.53k
        {
1264
4.53k
            inner++;
1265
            // Initialize the HMAC with saved state
1266
4.53k
            _cpri__CopyHashState(&h, &h1);
1267
              // Hash the inner counter (the one that changes on each HMAC iteration)
1268
4.53k
              UINT32_TO_BYTE_ARRAY(inner, swapped);
1269
4.53k
             _cpri__UpdateHash(&h, 4, swapped);
1270
4.53k
             _cpri__UpdateHash(&h, lLen, (BYTE *)label);
1271
             // Is there any party 1 data
1272
4.53k
             if(extra != NULL)
1273
4.53k
                 _cpri__UpdateHash(&h, extra->size, extra->buffer);
1274
             // Include the outer counter (the one that changes on each prime
1275
             // prime candidate generation
1276
4.53k
             UINT32_TO_BYTE_ARRAY(outer, swapped);
1277
4.53k
             _cpri__UpdateHash(&h, 4, swapped);
1278
4.53k
             _cpri__UpdateHash(&h, 2, (BYTE *)&keySizeInBits);
1279
4.53k
             if(i < fill)
1280
0
                 fill = i;
1281
4.53k
             _cpri__CompleteHash(&h, fill, pb);
1282
             // Restart the oPad hash
1283
4.53k
             _cpri__CopyHashState(&h, &h2);
1284
             // Add the last hashed data
1285
4.53k
             _cpri__UpdateHash(&h, fill, pb);
1286
             // gives a completed HMAC
1287
4.53k
             _cpri__CompleteHash(&h, fill, pb);
1288
4.53k
             pb += fill;
1289
4.53k
        }
1290
        // Set the Most significant 2 bits and the low bit of the candidate
1291
1.19k
        p->buffer[0] |= 0xC0;
1292
1.19k
        p->buffer[p->size - 1] |= 1;
1293
        // Convert the candidate to a BN
1294
1.19k
        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
1.19k
        if(!BN_is_zero(bnQ))
1298
407
        {
1299
            // bnQ is non-zero if we already found it
1300
407
            if(BN_ucmp(bnP, bnQ) < 0)
1301
38
                BN_sub(bnT, bnQ, bnP);
1302
369
            else
1303
369
                BN_sub(bnT, bnP, bnQ);
1304
407
            if(BN_num_bits(bnT) < 100) // Difference has to be at least 100 bits
1305
0
                continue;
1306
407
        }
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
1.19k
        rem = BN_mod_word(bnP, e);
1311
1.19k
        if(rem == 0) // evenly divisible so add two keeping the number odd and
1312
            // making sure that 1 != p mod e
1313
0
            BN_add_word(bnP, 2);
1314
1.19k
        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
0
            BN_sub_word(bnP, 2);
1317
        // Have a candidate, check for primality
1318
1.19k
        if((retVal = (CRYPT_RESULT)BN_is_prime_ex(bnP,
1319
1.19k
                     BN_prime_checks, NULL, NULL)) < 0)
1320
0
            FAIL(FATAL_ERROR_INTERNAL);
1321
1.19k
        if(retVal != 1)
1322
1.19k
            continue;
1323
        // Found a prime, is this the first or second.
1324
6
        if(BN_is_zero(bnQ))
1325
3
        {
1326
              // copy p to q and compute another prime in p
1327
3
              BN_copy(bnQ, bnP);
1328
3
              continue;
1329
3
        }
1330
        //Form the public modulus
1331
3
        BN_mul(bnN, bnP, bnQ, context);
1332
3
        if(BN_num_bits(bnN) != keySizeInBits)
1333
0
            FAIL(FATAL_ERROR_INTERNAL);
1334
        // Save the public modulus
1335
3
        BnTo2B(n, bnN, n->size); // Will pad the buffer to the correct size
1336
3
        pAssert((n->buffer[0] & 0x80) != 0);
1337
        // And one prime
1338
3
        BnTo2B(p, bnP, p->size);
1339
3
        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
3
        BN_sub(bnT, bnN, bnP);
1345
3
        BN_sub(bnT, bnT, bnQ);
1346
3
        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
3
        if(BN_mod_inverse(bnT, bnE, bnT, context) == NULL || BN_is_zero(bnT))
1352
0
            FAIL(FATAL_ERROR_INTERNAL);
1353
        // And, finally, do a trial encryption decryption
1354
3
        {
1355
3
            TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES);
1356
3
            TPM2B_RSA_KEY        r;
1357
3
            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
3
              if(seed == NULL)
1361
0
                  _cpri__GenerateRandom(n->size, r.t.buffer);
1362
3
              else
1363
3
              {
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
3
                  int          i;
1368
                  // Generate a random-ish number starting with the public modulus
1369
                  // XORed with the MSO of the seed
1370
643
                  for(i = 0; i < n->size; i++)
1371
640
                      r.t.buffer[i] = n->buffer[i] ^ seed->buffer[0];
1372
3
              }
1373
              // Make sure that the number is smaller than the public modulus
1374
3
              r.t.buffer[0] &= 0x7F;
1375
                     // Convert
1376
3
              if(    BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL
1377
                     // Encrypt with the public exponent
1378
3
                  || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1
1379
                     // Decrypt with the private exponent
1380
3
                  || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1)
1381
0
                   FAIL(FATAL_ERROR_INTERNAL);
1382
              // If the starting and ending values are not the same, start over )-;
1383
3
              if(BN_ucmp(bnP, bnQ) != 0)
1384
0
              {
1385
0
                   BN_zero(bnQ);
1386
0
                   continue;
1387
0
             }
1388
3
         }
1389
3
         retVal = CRYPT_SUCCESS;
1390
3
         goto Cleanup;
1391
3
    }
1392
0
    retVal = CRYPT_FAIL;
1393
3
Cleanup:
1394
   // Close out the hash sessions
1395
3
   _cpri__CompleteHash(&h2, 0, NULL);
1396
3
   _cpri__CompleteHash(&h1, 0, NULL);
1397
    // Free up allocated BN values
1398
3
    BN_CTX_end(context);
1399
3
    BN_CTX_free(context);
1400
3
    if(counter != NULL)
1401
3
        *counter = outer;
1402
3
    return retVal;
1403
0
}
1404
#endif      // RSA_KEY_SIEVE
1405
#endif // TPM_ALG_RSA