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