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