blob: 0b08aad8618c0e2630f3482f8c755736ed50eae0 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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
Vadim Bendebury7c2f61d2015-05-31 15:58:25 -07008#include <string.h>
9
nagendra modadugu24f8b192016-03-07 20:59:23 -080010#include "CryptoEngine.h"
11
12#ifndef EMBEDDED_MODE
Vadim Bendebury56797522015-05-20 10:32:25 -070013#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//
28LIB_EXPORT UINT16
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//
55LIB_EXPORT BOOL
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//
95LIB_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{
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//
161LIB_EXPORT int
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//
181LIB_EXPORT void
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//
208LIB_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{
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//
278LIB_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{
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 }
326Done:
327 BN_CTX_end(context);
328 BN_CTX_free(context);
329 return retVal;
330}
nagendra modadugu24f8b192016-03-07 20:59:23 -0800331#endif // ! EMBEDDED_MODE
Vadim Bendebury56797522015-05-20 10:32:25 -0700332//
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//
344LIB_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{
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//
396LIB_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{
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//
nagendra modadugu24f8b192016-03-07 20:59:23 -0800439#ifndef EMBEDDED_MODE
Vadim Bendebury56797522015-05-20 10:32:25 -0700440LIB_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{
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);
495Cleanup:
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//
512LIB_EXPORT BOOL
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}
nagendra modadugu24f8b192016-03-07 20:59:23 -0800536#endif // ! EMBEDDED_MODE