• 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 "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
_math__Normalize2B(TPM2B * b)29 _math__Normalize2B(
30      TPM2B               *b                  // IN/OUT: number to normalize
31      )
32 {
33      UINT16        from;
34      UINT16        to;
35      UINT16        size = b->size;
36      for(from = 0; b->buffer[from] == 0 && from < size; from++);
37      b->size -= from;
38      for(to = 0; from < size; to++, from++ )
39          b->buffer[to] = b->buffer[from];
40      return b->size;
41 }
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
_math__Denormalize2B(TPM2B * in,UINT32 size)56 _math__Denormalize2B(
57     TPM2B              *in,                   // IN:OUT TPM2B number to de-normalize
58     UINT32              size                  // IN: the desired size
59     )
60 {
61     UINT32       to;
62     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     if(in->size > size)
66     {
67         _math__Normalize2B(in);
68         if(in->size > size)
69             return FALSE;
70     }
71     // If the size is already what is requested, leave
72     if(in->size == size)
73         return TRUE;
74     // move the bytes to the 'right'
75     for(from = in->size, to = size; from > 0;)
76         in->buffer[--to] = in->buffer[--from];
77     // 'to' will always be greater than 0 because we checked for equal above.
78     for(; to > 0;)
79         in->buffer[--to] = 0;
80     in->size = (UINT16)size;
81     return TRUE;
82 }
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
_math__sub(const UINT32 aSize,const BYTE * a,const UINT32 bSize,const BYTE * b,UINT16 * cSize,BYTE * c)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 {
105     int               borrow = 0;
106     int               notZero = 0;
107     int               i;
108     int               i2;
109     // set c to the longer of a or b
110     *cSize = (UINT16)((aSize > bSize) ? aSize : bSize);
111     // pick the shorter of a and b
112     i = (aSize > bSize) ? bSize : aSize;
113     i2 = *cSize - i;
114     a = &a[aSize - 1];
115     b = &b[bSize - 1];
116     c = &c[*cSize - 1];
117     for(; i > 0; i--)
118     {
119         borrow = *a-- - *b-- + borrow;
120         *c-- = (BYTE)borrow;
121         notZero = notZero || borrow;
122         borrow >>= 8;
123     }
124     if(aSize > bSize)
125     {
126         for(;i2 > 0; i2--)
127         {
128             borrow = *a-- + borrow;
129             *c-- = (BYTE)borrow;
130             notZero = notZero || borrow;
131             borrow >>= 8;
132         }
133     }
134     else if(aSize < bSize)
135     {
136         for(;i2 > 0; i2--)
137         {
138             borrow = 0 - *b-- + borrow;
139             *c-- = (BYTE)borrow;
140             notZero = notZero || borrow;
141             borrow >>= 8;
142         }
143     }
144     // if there is a borrow, then b > a
145     if(borrow)
146         return -1;
147     // either a > b or they are the same
148     return notZero;
149 }
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
_math__Inc(UINT32 aSize,BYTE * a)162 _math__Inc(
163     UINT32             aSize,              // IN: size of a
164     BYTE              *a                   // IN: a
165     )
166 {
167 //
168       for(a = &a[aSize-1];aSize > 0; aSize--)
169       {
170           if((*a-- += 1) != 0)
171               return 1;
172       }
173       return 0;
174 }
175 //
176 //
177 //          _math__Dec()
178 //
179 //      This function decrements a large, ENDIAN value by one.
180 //
181 LIB_EXPORT void
_math__Dec(UINT32 aSize,BYTE * a)182 _math__Dec(
183       UINT32            aSize,                // IN: size of a
184       BYTE             *a                     // IN: a
185       )
186 {
187       for(a = &a[aSize-1]; aSize > 0; aSize--)
188       {
189           if((*a-- -= 1) != 0xff)
190               return;
191       }
192       return;
193 }
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
_math__Mul(const UINT32 aSize,const BYTE * a,const UINT32 bSize,const BYTE * b,UINT32 * pSize,BYTE * p)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 {
219       BIGNUM           *bnA;
220       BIGNUM           *bnB;
221       BIGNUM           *bnP;
222       BN_CTX           *context;
223       int              retVal = 0;
224       // First check that pSize is large enough if present
225       if((pSize != NULL) && (*pSize < (aSize + bSize)))
226           return CRYPT_PARAMETER;
227       pAssert(pSize == NULL || *pSize <= MAX_2B_BYTES);
228       //
229 //
230     // Allocate space for BIGNUM context
231     //
232     context = BN_CTX_new();
233     if(context == NULL)
234         FAIL(FATAL_ERROR_ALLOCATION);
235     bnA = BN_CTX_get(context);
236     bnB = BN_CTX_get(context);
237     bnP = BN_CTX_get(context);
238     if (bnP == NULL)
239         FAIL(FATAL_ERROR_ALLOCATION);
240     // Convert the inputs to BIGNUMs
241     //
242     if (BN_bin2bn(a, aSize, bnA) == NULL || BN_bin2bn(b, bSize, bnB) == NULL)
243         FAIL(FATAL_ERROR_INTERNAL);
244     // Perform the multiplication
245     //
246     if (BN_mul(bnP, bnA, bnB, context) != 1)
247         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     retVal = BN_num_bytes(bnP);
251     if(pSize == NULL)
252     {
253         BN_bn2bin(bnP, &p[aSize + bSize - retVal]);
254         memset(p, 0, aSize + bSize - retVal);
255         retVal = aSize + bSize;
256     }
257     else
258     {
259         BN_bn2bin(bnP, p);
260         *pSize = retVal;
261     }
262     BN_CTX_end(context);
263     BN_CTX_free(context);
264     return retVal;
265 }
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
_math__Div(const TPM2B * n,const TPM2B * d,TPM2B * q,TPM2B * r)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 {
286     BIGNUM              *bnN;
287     BIGNUM              *bnD;
288     BIGNUM              *bnQ;
289     BIGNUM              *bnR;
290     BN_CTX            *context;
291     CRYPT_RESULT       retVal = CRYPT_SUCCESS;
292     // Get structures for the big number representations
293     context = BN_CTX_new();
294     if(context == NULL)
295         FAIL(FATAL_ERROR_ALLOCATION);
296     BN_CTX_start(context);
297     bnN = BN_CTX_get(context);
298     bnD = BN_CTX_get(context);
299     bnQ = BN_CTX_get(context);
300     bnR = BN_CTX_get(context);
301     // Errors in BN_CTX_get() are sticky so only need to check the last allocation
302     if (    bnR == NULL
303          || BN_bin2bn(n->buffer, n->size, bnN) == NULL
304          || BN_bin2bn(d->buffer, d->size, bnD) == NULL)
305              FAIL(FATAL_ERROR_INTERNAL);
306     // Check for divide by zero.
307     if(BN_num_bits(bnD) == 0)
308         FAIL(FATAL_ERROR_DIVIDE_ZERO);
309     // Perform the division
310     if (BN_div(bnQ, bnR, bnN, bnD, context) != 1)
311         FAIL(FATAL_ERROR_INTERNAL);
312     // Convert the BIGNUM result back to our format
313     if(q != NULL)   // If the quotient is being returned
314     {
315         if(!BnTo2B(q, bnQ, q->size))
316         {
317             retVal = CRYPT_UNDERFLOW;
318             goto Done;
319         }
320       }
321     if(r != NULL)   // If the remainder is being returned
322     {
323         if(!BnTo2B(r, bnR, r->size))
324             retVal = CRYPT_UNDERFLOW;
325     }
326 Done:
327    BN_CTX_end(context);
328    BN_CTX_free(context);
329     return retVal;
330 }
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
_math__uComp(const UINT32 aSize,const BYTE * a,const UINT32 bSize,const BYTE * b)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 {
352     int              borrow = 0;
353     int              notZero = 0;
354     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     if((i = (int)aSize - (int)bSize) > 0)
358         for(; i > 0; i--)
359             if(*a++) // means a > b
360                  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     if(i < 0) // Means that b is longer than a
364         for(; i < 0; i++)
365             if(*b++) // means that b > a
366                  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     i = (aSize > bSize) ? bSize : aSize;
370     a = &a[i-1];
371     b = &b[i-1];
372     for(; i > 0; i--)
373     {
374         borrow = *a-- - *b-- + borrow;
375         notZero = notZero || borrow;
376         borrow >>= 8;
377     }
378     // if there is a borrow, then b > a
379     if(borrow)
380         return -1;
381     // either a > b or they are the same
382     return notZero;
383 }
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
_math__Comp(const UINT32 aSize,const BYTE * a,const UINT32 bSize,const BYTE * b)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 {
404     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     signA = ((a[0] & 0x80) == 0) ? 1 : 0;
408     // For positive or 0, sign_b is 1
409     // for negative, sign_b is 0
410    signB = ((b[0] & 0x80) == 0) ? 1 : 0;
411    if(signA != signB)
412    {
413        return signA - signB;
414    }
415    if(signA == 1)
416        // do unsigned compare function
417        return _math__uComp(aSize, a, bSize, b);
418    else
419        // do unsigned compare the other way
420        return 0 - _math__uComp(aSize, a, bSize, b);
421 }
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
_math__ModExp(UINT32 cSize,BYTE * c,const UINT32 mSize,const BYTE * m,const UINT32 eSize,const BYTE * e,const UINT32 nSize,const BYTE * n)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 {
452    CRYPT_RESULT         retVal = CRYPT_SUCCESS;
453    BN_CTX              *context;
454    BIGNUM              *bnC;
455    BIGNUM              *bnM;
456    BIGNUM              *bnE;
457    BIGNUM              *bnN;
458    INT32                i;
459    context = BN_CTX_new();
460    if(context == NULL)
461        FAIL(FATAL_ERROR_ALLOCATION);
462    BN_CTX_start(context);
463    bnC = BN_CTX_get(context);
464    bnM = BN_CTX_get(context);
465    bnE = BN_CTX_get(context);
466    bnN = BN_CTX_get(context);
467    // Errors for BN_CTX_get are sticky so only need to check last allocation
468    if(bnN == NULL)
469          FAIL(FATAL_ERROR_ALLOCATION);
470     //convert arguments
471     if (    BN_bin2bn(m, mSize, bnM) == NULL
472          || BN_bin2bn(e, eSize, bnE) == NULL
473          || BN_bin2bn(n, nSize, bnN) == NULL)
474              FAIL(FATAL_ERROR_INTERNAL);
475     // Don't do exponentiation if the number being exponentiated is
476     // larger than the modulus.
477     if(BN_ucmp(bnM, bnN) >= 0)
478     {
479         retVal = CRYPT_PARAMETER;
480         goto Cleanup;
481     }
482     // Perform the exponentiation
483     if(!(BN_mod_exp(bnC, bnM, bnE, bnN, context)))
484         FAIL(FATAL_ERROR_INTERNAL);
485     // Convert the results
486     // Make sure that the results will fit in the provided buffer.
487     if((unsigned)BN_num_bytes(bnC) > cSize)
488     {
489         retVal = CRYPT_UNDERFLOW;
490         goto Cleanup;
491     }
492     i = cSize - BN_num_bytes(bnC);
493     BN_bn2bin(bnC, &c[i]);
494     memset(c, 0, i);
495 Cleanup:
496    // Free up allocated BN values
497    BN_CTX_end(context);
498    BN_CTX_free(context);
499    return retVal;
500 }
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
_math__IsPrime(const UINT32 prime)513 _math__IsPrime(
514     const UINT32         prime
515     )
516 {
517     int       isPrime;
518     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     if((p = BN_new()) == NULL)
522         FAIL(FATAL_ERROR_ALLOCATION);
523     if(!BN_set_word(p, prime))
524         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    if((isPrime = BN_is_prime_ex(p, BN_prime_checks, NULL, NULL)) < 0)
531        FAIL(FATAL_ERROR_INTERNAL);
532    if(p != NULL)
533        BN_clear_free(p);
534    return (isPrime == 1);
535 }
536 #endif // ! EMBEDDED_MODE
537