Coverage Report

Created: 2025-07-18 06:04

/src/tpm2/MathFunctions.c
Line
Count
Source (jump to first uncovered line)
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 "CryptoEngine.h"
11
12
#ifndef EMBEDDED_MODE
13
#include "OsslCryptoEngine.h"
14
//
15
//
16
//          Externally Accessible Functions
17
//
18
//           _math__Normalize2B()
19
//
20
//     This function will normalize the value in a TPM2B. If there are leading bytes of zero, the first non-zero
21
//     byte is shifted up.
22
//
23
//     Return Value                     Meaning
24
//
25
//     0                                no significant bytes, value is zero
26
//     >0                               number of significant bytes
27
//
28
LIB_EXPORT UINT16
29
_math__Normalize2B(
30
     TPM2B               *b                  // IN/OUT: number to normalize
31
     )
32
0
{
33
0
     UINT16        from;
34
0
     UINT16        to;
35
0
     UINT16        size = b->size;
36
0
     for(from = 0; b->buffer[from] == 0 && from < size; from++);
37
0
     b->size -= from;
38
0
     for(to = 0; from < size; to++, from++ )
39
0
         b->buffer[to] = b->buffer[from];
40
0
     return b->size;
41
0
}
42
//
43
//
44
//
45
//        _math__Denormalize2B()
46
//
47
//     This function is used to adjust a TPM2B so that the number has the desired number of bytes. This is
48
//     accomplished by adding bytes of zero at the start of the number.
49
//
50
//     Return Value                      Meaning
51
//
52
//     TRUE                              number de-normalized
53
//     FALSE                             number already larger than the desired size
54
//
55
LIB_EXPORT BOOL
56
_math__Denormalize2B(
57
    TPM2B              *in,                   // IN:OUT TPM2B number to de-normalize
58
    UINT32              size                  // IN: the desired size
59
    )
60
0
{
61
0
    UINT32       to;
62
0
    UINT32       from;
63
    // If the current size is greater than the requested size, see if this can be
64
    // normalized to a value smaller than the requested size and then de-normalize
65
0
    if(in->size > size)
66
0
    {
67
0
        _math__Normalize2B(in);
68
0
        if(in->size > size)
69
0
            return FALSE;
70
0
    }
71
    // If the size is already what is requested, leave
72
0
    if(in->size == size)
73
0
        return TRUE;
74
    // move the bytes to the 'right'
75
0
    for(from = in->size, to = size; from > 0;)
76
0
        in->buffer[--to] = in->buffer[--from];
77
    // 'to' will always be greater than 0 because we checked for equal above.
78
0
    for(; to > 0;)
79
0
        in->buffer[--to] = 0;
80
0
    in->size = (UINT16)size;
81
0
    return TRUE;
82
0
}
83
//
84
//
85
//        _math__sub()
86
//
87
//     This function to subtract one unsigned value from another c = a - b. c may be the same as a or b.
88
//
89
//     Return Value                      Meaning
90
//
91
//     1                                 if (a > b) so no borrow
92
//     0                                 if (a = b) so no borrow and b == a
93
//     -1                                if (a < b) so there was a borrow
94
//
95
LIB_EXPORT int
96
_math__sub(
97
    const UINT32        aSize,                //   IN: size   of a
98
    const BYTE         *a,                    //   IN: a
99
    const UINT32        bSize,                //   IN: size   of b
100
    const BYTE         *b,                    //   IN: b
101
    UINT16             *cSize,                //   OUT: set   to MAX(aSize, bSize)
102
    BYTE               *c                     //   OUT: the   difference
103
    )
104
0
{
105
0
    int               borrow = 0;
106
0
    int               notZero = 0;
107
0
    int               i;
108
0
    int               i2;
109
    // set c to the longer of a or b
110
0
    *cSize = (UINT16)((aSize > bSize) ? aSize : bSize);
111
    // pick the shorter of a and b
112
0
    i = (aSize > bSize) ? bSize : aSize;
113
0
    i2 = *cSize - i;
114
0
    a = &a[aSize - 1];
115
0
    b = &b[bSize - 1];
116
0
    c = &c[*cSize - 1];
117
0
    for(; i > 0; i--)
118
0
    {
119
0
        borrow = *a-- - *b-- + borrow;
120
0
        *c-- = (BYTE)borrow;
121
0
        notZero = notZero || borrow;
122
0
        borrow >>= 8;
123
0
    }
124
0
    if(aSize > bSize)
125
0
    {
126
0
        for(;i2 > 0; i2--)
127
0
        {
128
0
            borrow = *a-- + borrow;
129
0
            *c-- = (BYTE)borrow;
130
0
            notZero = notZero || borrow;
131
0
            borrow >>= 8;
132
0
        }
133
0
    }
134
0
    else if(aSize < bSize)
135
0
    {
136
0
        for(;i2 > 0; i2--)
137
0
        {
138
0
            borrow = 0 - *b-- + borrow;
139
0
            *c-- = (BYTE)borrow;
140
0
            notZero = notZero || borrow;
141
0
            borrow >>= 8;
142
0
        }
143
0
    }
144
    // if there is a borrow, then b > a
145
0
    if(borrow)
146
0
        return -1;
147
    // either a > b or they are the same
148
0
    return notZero;
149
0
}
150
//
151
//
152
//         _math__Inc()
153
//
154
//      This function increments a large, big-endian number value by one.
155
//
156
//      Return Value                   Meaning
157
//
158
//      0                              result is zero
159
//      !0                             result is not zero
160
//
161
LIB_EXPORT int
162
_math__Inc(
163
    UINT32             aSize,              // IN: size of a
164
    BYTE              *a                   // IN: a
165
    )
166
0
{
167
//
168
0
      for(a = &a[aSize-1];aSize > 0; aSize--)
169
0
      {
170
0
          if((*a-- += 1) != 0)
171
0
              return 1;
172
0
      }
173
0
      return 0;
174
0
}
175
//
176
//
177
//          _math__Dec()
178
//
179
//      This function decrements a large, ENDIAN value by one.
180
//
181
LIB_EXPORT void
182
_math__Dec(
183
      UINT32            aSize,                // IN: size of a
184
      BYTE             *a                     // IN: a
185
      )
186
0
{
187
0
      for(a = &a[aSize-1]; aSize > 0; aSize--)
188
0
      {
189
0
          if((*a-- -= 1) != 0xff)
190
0
              return;
191
0
      }
192
0
      return;
193
0
}
194
//
195
//
196
//          _math__Mul()
197
//
198
//      This function is used to multiply two large integers: p = a* b. If the size of p is not specified (pSize ==
199
//      NULL), the size of the results p is assumed to be aSize + bSize and the results are de-normalized so that
200
//      the resulting size is exactly aSize + bSize. If pSize is provided, then the actual size of the result is
201
//      returned. The initial value for pSize must be at least aSize + pSize.
202
//
203
//      Return Value                      Meaning
204
//
205
//      <0                                indicates an error
206
//      >= 0                              the size of the product
207
//
208
LIB_EXPORT int
209
_math__Mul(
210
      const UINT32      aSize,                //   IN: size of a
211
      const BYTE       *a,                    //   IN: a
212
      const UINT32      bSize,                //   IN: size of b
213
      const BYTE       *b,                    //   IN: b
214
      UINT32           *pSize,                //   IN/OUT: size of the product
215
      BYTE             *p                     //   OUT: product. length of product = aSize +
216
                                              //       bSize
217
      )
218
0
{
219
0
      BIGNUM           *bnA;
220
0
      BIGNUM           *bnB;
221
0
      BIGNUM           *bnP;
222
0
      BN_CTX           *context;
223
0
      int              retVal = 0;
224
      // First check that pSize is large enough if present
225
0
      if((pSize != NULL) && (*pSize < (aSize + bSize)))
226
0
          return CRYPT_PARAMETER;
227
0
      pAssert(pSize == NULL || *pSize <= MAX_2B_BYTES);
228
      //
229
//
230
    // Allocate space for BIGNUM context
231
    //
232
0
    context = BN_CTX_new();
233
0
    if(context == NULL)
234
0
        FAIL(FATAL_ERROR_ALLOCATION);
235
0
    bnA = BN_CTX_get(context);
236
0
    bnB = BN_CTX_get(context);
237
0
    bnP = BN_CTX_get(context);
238
0
    if (bnP == NULL)
239
0
        FAIL(FATAL_ERROR_ALLOCATION);
240
    // Convert the inputs to BIGNUMs
241
    //
242
0
    if (BN_bin2bn(a, aSize, bnA) == NULL || BN_bin2bn(b, bSize, bnB) == NULL)
243
0
        FAIL(FATAL_ERROR_INTERNAL);
244
    // Perform the multiplication
245
    //
246
0
    if (BN_mul(bnP, bnA, bnB, context) != 1)
247
0
        FAIL(FATAL_ERROR_INTERNAL);
248
    // If the size of the results is allowed to float, then set the return
249
    // size. Otherwise, it might be necessary to de-normalize the results
250
0
    retVal = BN_num_bytes(bnP);
251
0
    if(pSize == NULL)
252
0
    {
253
0
        BN_bn2bin(bnP, &p[aSize + bSize - retVal]);
254
0
        memset(p, 0, aSize + bSize - retVal);
255
0
        retVal = aSize + bSize;
256
0
    }
257
0
    else
258
0
    {
259
0
        BN_bn2bin(bnP, p);
260
0
        *pSize = retVal;
261
0
    }
262
0
    BN_CTX_end(context);
263
0
    BN_CTX_free(context);
264
0
    return retVal;
265
0
}
266
//
267
//
268
//         _math__Div()
269
//
270
//      Divide an integer (n) by an integer (d) producing a quotient (q) and a remainder (r). If q or r is not needed,
271
//      then the pointer to them may be set to NULL.
272
//
273
//      Return Value                     Meaning
274
//
275
//      CRYPT_SUCCESS                    operation complete
276
//      CRYPT_UNDERFLOW                  q or r is too small to receive the result
277
//
278
LIB_EXPORT CRYPT_RESULT
279
_math__Div(
280
    const TPM2B         *n,                  //   IN: numerator
281
    const TPM2B         *d,                  //   IN: denominator
282
    TPM2B               *q,                  //   OUT: quotient
283
    TPM2B               *r                   //   OUT: remainder
284
    )
285
0
{
286
0
    BIGNUM              *bnN;
287
0
    BIGNUM              *bnD;
288
0
    BIGNUM              *bnQ;
289
0
    BIGNUM              *bnR;
290
0
    BN_CTX            *context;
291
0
    CRYPT_RESULT       retVal = CRYPT_SUCCESS;
292
    // Get structures for the big number representations
293
0
    context = BN_CTX_new();
294
0
    if(context == NULL)
295
0
        FAIL(FATAL_ERROR_ALLOCATION);
296
0
    BN_CTX_start(context);
297
0
    bnN = BN_CTX_get(context);
298
0
    bnD = BN_CTX_get(context);
299
0
    bnQ = BN_CTX_get(context);
300
0
    bnR = BN_CTX_get(context);
301
    // Errors in BN_CTX_get() are sticky so only need to check the last allocation
302
0
    if (    bnR == NULL
303
0
         || BN_bin2bn(n->buffer, n->size, bnN) == NULL
304
0
         || BN_bin2bn(d->buffer, d->size, bnD) == NULL)
305
0
             FAIL(FATAL_ERROR_INTERNAL);
306
    // Check for divide by zero.
307
0
    if(BN_num_bits(bnD) == 0)
308
0
        FAIL(FATAL_ERROR_DIVIDE_ZERO);
309
    // Perform the division
310
0
    if (BN_div(bnQ, bnR, bnN, bnD, context) != 1)
311
0
        FAIL(FATAL_ERROR_INTERNAL);
312
    // Convert the BIGNUM result back to our format
313
0
    if(q != NULL)   // If the quotient is being returned
314
0
    {
315
0
        if(!BnTo2B(q, bnQ, q->size))
316
0
        {
317
0
            retVal = CRYPT_UNDERFLOW;
318
0
            goto Done;
319
0
        }
320
0
      }
321
0
    if(r != NULL)   // If the remainder is being returned
322
0
    {
323
0
        if(!BnTo2B(r, bnR, r->size))
324
0
            retVal = CRYPT_UNDERFLOW;
325
0
    }
326
0
Done:
327
0
   BN_CTX_end(context);
328
0
   BN_CTX_free(context);
329
0
    return retVal;
330
0
}
331
#endif // ! EMBEDDED_MODE
332
//
333
//
334
//         _math__uComp()
335
//
336
//      This function compare two unsigned values.
337
//
338
//      Return Value                      Meaning
339
//
340
//      1                                 if (a > b)
341
//      0                                 if (a = b)
342
//      -1                                if (a < b)
343
//
344
LIB_EXPORT int
345
_math__uComp(
346
    const UINT32       aSize,                 // IN: size of a
347
    const BYTE        *a,                     // IN: a
348
    const UINT32       bSize,                // IN: size of b
349
    const BYTE        *b                     // IN: b
350
    )
351
0
{
352
0
    int              borrow = 0;
353
0
    int              notZero = 0;
354
0
    int              i;
355
    // If a has more digits than b, then a is greater than b if
356
    // any of the more significant bytes is non zero
357
0
    if((i = (int)aSize - (int)bSize) > 0)
358
0
        for(; i > 0; i--)
359
0
            if(*a++) // means a > b
360
0
                 return 1;
361
    // If b has more digits than a, then b is greater if any of the
362
    // more significant bytes is non zero
363
0
    if(i < 0) // Means that b is longer than a
364
0
        for(; i < 0; i++)
365
0
            if(*b++) // means that b > a
366
0
                 return -1;
367
    // Either the vales are the same size or the upper bytes of a or b are
368
    // all zero, so compare the rest
369
0
    i = (aSize > bSize) ? bSize : aSize;
370
0
    a = &a[i-1];
371
0
    b = &b[i-1];
372
0
    for(; i > 0; i--)
373
0
    {
374
0
        borrow = *a-- - *b-- + borrow;
375
0
        notZero = notZero || borrow;
376
0
        borrow >>= 8;
377
0
    }
378
    // if there is a borrow, then b > a
379
0
    if(borrow)
380
0
        return -1;
381
    // either a > b or they are the same
382
0
    return notZero;
383
0
}
384
//
385
//
386
//           _math__Comp()
387
//
388
//      Compare two signed integers:
389
//
390
//      Return Value                    Meaning
391
//
392
//      1                               if a > b
393
//      0                               if a = b
394
//      -1                              if a < b
395
//
396
LIB_EXPORT int
397
_math__Comp(
398
    const   UINT32     aSize,                //   IN:   size of a
399
    const   BYTE      *a,                    //   IN:   a buffer
400
    const   UINT32     bSize,                //   IN:   size of b
401
    const   BYTE      *b                     //   IN:   b buffer
402
    )
403
0
{
404
0
    int        signA, signB;              // sign of a and b
405
    // For positive or 0, sign_a is 1
406
    // for negative, sign_a is 0
407
0
    signA = ((a[0] & 0x80) == 0) ? 1 : 0;
408
    // For positive or 0, sign_b is 1
409
    // for negative, sign_b is 0
410
0
   signB = ((b[0] & 0x80) == 0) ? 1 : 0;
411
0
   if(signA != signB)
412
0
   {
413
0
       return signA - signB;
414
0
   }
415
0
   if(signA == 1)
416
       // do unsigned compare function
417
0
       return _math__uComp(aSize, a, bSize, b);
418
0
   else
419
       // do unsigned compare the other way
420
0
       return 0 - _math__uComp(aSize, a, bSize, b);
421
0
}
422
//
423
//
424
//       _math__ModExp
425
//
426
//      This function is used to do modular exponentiation in support of RSA. The most typical uses are: c = m^e
427
//      mod n (RSA encrypt) and m = c^d mod n (RSA decrypt). When doing decryption, the e parameter of the
428
//      function will contain the private exponent d instead of the public exponent e.
429
//      If the results will not fit in the provided buffer, an error is returned (CRYPT_ERROR_UNDERFLOW). If
430
//      the results is smaller than the buffer, the results is de-normalized.
431
//      This version is intended for use with RSA and requires that m be less than n.
432
//
433
//      Return Value                      Meaning
434
//
435
//      CRYPT_SUCCESS                     exponentiation succeeded
436
//      CRYPT_PARAMETER                   number to exponentiate is larger than the modulus
437
//      CRYPT_UNDERFLOW                   result will not fit into the provided buffer
438
//
439
#ifndef EMBEDDED_MODE
440
LIB_EXPORT CRYPT_RESULT
441
_math__ModExp(
442
   UINT32               cSize,                 //   IN: size of the result
443
   BYTE                *c,                     //   OUT: results buffer
444
   const UINT32         mSize,                 //   IN: size of number to be exponentiated
445
   const BYTE          *m,                     //   IN: number to be exponentiated
446
   const UINT32         eSize,                 //   IN: size of power
447
   const BYTE          *e,                     //   IN: power
448
   const UINT32         nSize,                 //   IN: modulus size
449
   const BYTE          *n                      //   IN: modulu
450
   )
451
0
{
452
0
   CRYPT_RESULT         retVal = CRYPT_SUCCESS;
453
0
   BN_CTX              *context;
454
0
   BIGNUM              *bnC;
455
0
   BIGNUM              *bnM;
456
0
   BIGNUM              *bnE;
457
0
   BIGNUM              *bnN;
458
0
   INT32                i;
459
0
   context = BN_CTX_new();
460
0
   if(context == NULL)
461
0
       FAIL(FATAL_ERROR_ALLOCATION);
462
0
   BN_CTX_start(context);
463
0
   bnC = BN_CTX_get(context);
464
0
   bnM = BN_CTX_get(context);
465
0
   bnE = BN_CTX_get(context);
466
0
   bnN = BN_CTX_get(context);
467
   // Errors for BN_CTX_get are sticky so only need to check last allocation
468
0
   if(bnN == NULL)
469
0
         FAIL(FATAL_ERROR_ALLOCATION);
470
    //convert arguments
471
0
    if (    BN_bin2bn(m, mSize, bnM) == NULL
472
0
         || BN_bin2bn(e, eSize, bnE) == NULL
473
0
         || BN_bin2bn(n, nSize, bnN) == NULL)
474
0
             FAIL(FATAL_ERROR_INTERNAL);
475
    // Don't do exponentiation if the number being exponentiated is
476
    // larger than the modulus.
477
0
    if(BN_ucmp(bnM, bnN) >= 0)
478
0
    {
479
0
        retVal = CRYPT_PARAMETER;
480
0
        goto Cleanup;
481
0
    }
482
    // Perform the exponentiation
483
0
    if(!(BN_mod_exp(bnC, bnM, bnE, bnN, context)))
484
0
        FAIL(FATAL_ERROR_INTERNAL);
485
    // Convert the results
486
    // Make sure that the results will fit in the provided buffer.
487
0
    if((unsigned)BN_num_bytes(bnC) > cSize)
488
0
    {
489
0
        retVal = CRYPT_UNDERFLOW;
490
0
        goto Cleanup;
491
0
    }
492
0
    i = cSize - BN_num_bytes(bnC);
493
0
    BN_bn2bin(bnC, &c[i]);
494
0
    memset(c, 0, i);
495
0
Cleanup:
496
   // Free up allocated BN values
497
0
   BN_CTX_end(context);
498
0
   BN_CTX_free(context);
499
0
   return retVal;
500
0
}
501
//
502
//
503
//       _math__IsPrime()
504
//
505
//      Check if an 32-bit integer is a prime.
506
//
507
//      Return Value                      Meaning
508
//
509
//      TRUE                              if the integer is probably a prime
510
//      FALSE                             if the integer is definitely not a prime
511
//
512
LIB_EXPORT BOOL
513
_math__IsPrime(
514
    const UINT32         prime
515
    )
516
3
{
517
3
    int       isPrime;
518
3
    BIGNUM    *p;
519
    // Assume the size variables are not overflow, which should not happen in
520
    // the contexts that this function will be called.
521
3
    if((p = BN_new()) == NULL)
522
0
        FAIL(FATAL_ERROR_ALLOCATION);
523
3
    if(!BN_set_word(p, prime))
524
0
        FAIL(FATAL_ERROR_INTERNAL);
525
    //
526
    // BN_is_prime returning -1 means that it ran into an error.
527
//
528
   // It should only return 0 or 1
529
   //
530
3
   if((isPrime = BN_is_prime_ex(p, BN_prime_checks, NULL, NULL)) < 0)
531
0
       FAIL(FATAL_ERROR_INTERNAL);
532
3
   if(p != NULL)
533
3
       BN_clear_free(p);
534
3
   return (isPrime == 1);
535
3
}
536
#endif // ! EMBEDDED_MODE