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