1*0861b331Schristos 
2*0861b331Schristos /*
3*0861b331Schristos  * Licensed Materials - Property of IBM
4*0861b331Schristos  *
5*0861b331Schristos  * trousers - An open source TCG Software Stack
6*0861b331Schristos  *
7*0861b331Schristos  * (C) Copyright International Business Machines Corp. 2006
8*0861b331Schristos  *
9*0861b331Schristos  */
10*0861b331Schristos 
11*0861b331Schristos #ifndef BI_OPENSSL_
12*0861b331Schristos #define BI_OPENSSL_
13*0861b331Schristos 
14*0861b331Schristos #include <openssl/bn.h>
15*0861b331Schristos #include <openssl/engine.h>
16*0861b331Schristos 
17*0861b331Schristos typedef struct bignum_st bi_t[1];
18*0861b331Schristos 
19*0861b331Schristos typedef struct bignum_st *bi_ptr;
20*0861b331Schristos 
21*0861b331Schristos extern BN_CTX *context;
22*0861b331Schristos 
23*0861b331Schristos 
bi_new(bi_ptr result)24*0861b331Schristos INLINE_DECL bi_ptr bi_new(bi_ptr result) {
25*0861b331Schristos 	BN_init( result);
26*0861b331Schristos 	return result;
27*0861b331Schristos }
28*0861b331Schristos 
29*0861b331Schristos /* create a big integer pointer */
bi_new_ptr(void)30*0861b331Schristos INLINE_DECL bi_ptr bi_new_ptr(void) {
31*0861b331Schristos 	return BN_new();
32*0861b331Schristos }
33*0861b331Schristos 
34*0861b331Schristos /* free resources allocated to the big integer <i> */
bi_free(const bi_ptr i)35*0861b331Schristos INLINE_DECL void bi_free(const bi_ptr i) {
36*0861b331Schristos 	BN_free( i);
37*0861b331Schristos }
38*0861b331Schristos 
39*0861b331Schristos /* free resources allocated to the big integer pointer <i> */
bi_free_ptr(const bi_ptr i)40*0861b331Schristos INLINE_DECL void bi_free_ptr(const bi_ptr i) {
41*0861b331Schristos 	BN_free( i);
42*0861b331Schristos }
43*0861b331Schristos 
44*0861b331Schristos /* <result> := result++ */
bi_inc(bi_ptr result)45*0861b331Schristos INLINE_DECL bi_ptr bi_inc(bi_ptr result) {
46*0861b331Schristos 	BN_add_word( result, 1);
47*0861b331Schristos 	return result;
48*0861b331Schristos }
49*0861b331Schristos 
50*0861b331Schristos /* <result> := result-- */
bi_dec(bi_ptr result)51*0861b331Schristos INLINE_DECL bi_ptr bi_dec(bi_ptr result) {
52*0861b331Schristos 	BN_sub_word( result, 1);
53*0861b331Schristos 	return result;
54*0861b331Schristos }
55*0861b331Schristos 
56*0861b331Schristos /* return the current number of bits of the number */
bi_length(const bi_ptr res)57*0861b331Schristos INLINE_DECL long bi_length( const bi_ptr res) {
58*0861b331Schristos 	return BN_num_bits( res);
59*0861b331Schristos }
60*0861b331Schristos 
61*0861b331Schristos /***********************************************************************************
62*0861b331Schristos 	BASIC MATH OPERATION
63*0861b331Schristos *************************************************************************************/
64*0861b331Schristos /* <result> := - <result> */
bi_negate(bi_ptr result)65*0861b331Schristos INLINE_DECL bi_ptr bi_negate( bi_ptr result) {
66*0861b331Schristos 	BIGNUM *n = result;
67*0861b331Schristos 	n->neg = ( n->neg == 0 ? 1 : 0);
68*0861b331Schristos 	return result;
69*0861b331Schristos }
70*0861b331Schristos 
bi_mul_si(bi_ptr result,const bi_ptr i,const long n)71*0861b331Schristos INLINE_DECL bi_ptr bi_mul_si( bi_ptr result, const bi_ptr i, const long n) {
72*0861b331Schristos 	BN_copy( result, i);
73*0861b331Schristos 	BN_mul_word( result, n);
74*0861b331Schristos 	return result;
75*0861b331Schristos }
76*0861b331Schristos 
77*0861b331Schristos /*  <result> := <i> * <n>   */
bi_mul(bi_ptr result,const bi_ptr i,const bi_ptr n)78*0861b331Schristos INLINE_DECL bi_ptr bi_mul( bi_ptr result, const bi_ptr i, const bi_ptr n) {
79*0861b331Schristos 	BN_mul( result, i, n, context);
80*0861b331Schristos 	return result;
81*0861b331Schristos }
82*0861b331Schristos 
bi_add_si(bi_ptr result,const bi_ptr i,const long n)83*0861b331Schristos INLINE_DECL bi_ptr bi_add_si( bi_ptr result, const bi_ptr i, const long n) {
84*0861b331Schristos 	BN_copy( result, i);
85*0861b331Schristos 	BN_add_word( result, n);
86*0861b331Schristos 	return result;
87*0861b331Schristos }
88*0861b331Schristos 
89*0861b331Schristos /*  <result> := <i> + <n>  */
bi_add(bi_ptr result,const bi_ptr i,const bi_ptr n)90*0861b331Schristos INLINE_DECL bi_ptr bi_add( bi_ptr result, const bi_ptr i, const bi_ptr n) {
91*0861b331Schristos 	BN_add( result, i, n);
92*0861b331Schristos 	return result;
93*0861b331Schristos }
94*0861b331Schristos 
95*0861b331Schristos /*  <result> := <i> - <n>   */
bi_sub_si(bi_ptr result,const bi_ptr i,const long n)96*0861b331Schristos INLINE_DECL bi_ptr bi_sub_si( bi_ptr result, const bi_ptr i, const long n) {
97*0861b331Schristos 	// n should be unsigned
98*0861b331Schristos 	BN_copy( result, i);  			  // result := i
99*0861b331Schristos 	BN_sub_word( result, n);   // result := result - n
100*0861b331Schristos 	return result;
101*0861b331Schristos }
102*0861b331Schristos 
103*0861b331Schristos /*  <result> := <i> - <n>  */
bi_sub(bi_ptr result,const bi_ptr i,const bi_ptr n)104*0861b331Schristos INLINE_DECL bi_ptr bi_sub( bi_ptr result, const bi_ptr i, const bi_ptr n) {
105*0861b331Schristos 	BN_sub( result, i, n);
106*0861b331Schristos 	return result;
107*0861b331Schristos }
108*0861b331Schristos 
109*0861b331Schristos /*  <result> := ( <g> ^ <e> ) mod <m>  */
bi_mod_exp(bi_ptr result,const bi_ptr g,const bi_ptr e,const bi_ptr m)110*0861b331Schristos INLINE_DECL bi_ptr bi_mod_exp( bi_ptr result, const bi_ptr g, const bi_ptr e, const bi_ptr m) {
111*0861b331Schristos 	BN_mod_exp( result, g, e, m, context);	// result := (g ^ e) mod bi_m
112*0861b331Schristos 	return result;
113*0861b331Schristos }
114*0861b331Schristos 
115*0861b331Schristos /* set <result> by the division of <i> by the long <n>  */
116*0861b331Schristos /*  <result> := <i> / <n>   */
bi_div_si(bi_ptr result,const bi_ptr i,const long n)117*0861b331Schristos INLINE_DECL bi_ptr bi_div_si( bi_ptr result, const bi_ptr i, const long n) {
118*0861b331Schristos 	BN_copy( result, i);
119*0861b331Schristos 	BN_div_word( result, n);
120*0861b331Schristos 	return result;
121*0861b331Schristos }
122*0861b331Schristos 
123*0861b331Schristos /*  <result> := <i> / <n>   */
bi_div(bi_ptr result,const bi_ptr i,const bi_ptr n)124*0861b331Schristos INLINE_DECL bi_ptr bi_div( bi_ptr result, const bi_ptr i, const bi_ptr n) {
125*0861b331Schristos 	BN_div( result, NULL, i, n, context);
126*0861b331Schristos 	return result;
127*0861b331Schristos }
128*0861b331Schristos 
129*0861b331Schristos /***********************************************************************************
130*0861b331Schristos 	COMPARAISON
131*0861b331Schristos *************************************************************************************/
132*0861b331Schristos /*  n1<n2   return negative value
133*0861b331Schristos  *  n1 = n2 return 0
134*0861b331Schristos  *  n1>n2   return positive value
135*0861b331Schristos */
bi_cmp(const bi_ptr n1,const bi_ptr n2)136*0861b331Schristos INLINE_DECL int bi_cmp( const bi_ptr n1, const bi_ptr n2) {
137*0861b331Schristos 	return BN_cmp( n1, n2);
138*0861b331Schristos }
139*0861b331Schristos 
140*0861b331Schristos /*  n1<n2   return negative value
141*0861b331Schristos  *  n1 = n2 return 0
142*0861b331Schristos  *  n1>n2   return positive value
143*0861b331Schristos */
bi_cmp_si(const bi_ptr n1,const int n2)144*0861b331Schristos INLINE_DECL int bi_cmp_si( const bi_ptr n1, const int n2) {
145*0861b331Schristos 	BIGNUM *temp = BN_new();
146*0861b331Schristos 	BN_set_word( temp, n2);
147*0861b331Schristos 	int res = BN_cmp( n1, temp);
148*0861b331Schristos 	BN_free( temp);
149*0861b331Schristos 	return res;
150*0861b331Schristos }
151*0861b331Schristos 
152*0861b331Schristos /*  n1 == n2   return 1 (true)
153*0861b331Schristos  *  else return 0
154*0861b331Schristos */
bi_equals(const bi_ptr n1,const bi_ptr n2)155*0861b331Schristos INLINE_DECL int bi_equals( const bi_ptr n1, const bi_ptr n2) {
156*0861b331Schristos 	return BN_cmp( n1, n2) == 0 ? 1 :0;
157*0861b331Schristos }
158*0861b331Schristos 
159*0861b331Schristos /*  n1 == n2   return 1 (true)
160*0861b331Schristos  *  else return 0
161*0861b331Schristos */
bi_equals_si(const bi_ptr n1,const int n2)162*0861b331Schristos INLINE_DECL int bi_equals_si( const bi_ptr n1, const int n2) {
163*0861b331Schristos 	return BN_is_word( n1, n2);
164*0861b331Schristos }
165*0861b331Schristos 
166*0861b331Schristos /***********************************************************************************
167*0861b331Schristos 	CONVERSIONS
168*0861b331Schristos *************************************************************************************/
169*0861b331Schristos 
bi_2_hex_char(const bi_ptr i)170*0861b331Schristos INLINE_DECL char *bi_2_hex_char(const bi_ptr i) {
171*0861b331Schristos 	char *result = BN_bn2hex( i);
172*0861b331Schristos 
173*0861b331Schristos 	if( result == NULL) {
174*0861b331Schristos 		return NULL;
175*0861b331Schristos 	}
176*0861b331Schristos 	list_add( allocs, result);
177*0861b331Schristos 	return result;
178*0861b331Schristos }
179*0861b331Schristos 
bi_2_dec_char(const bi_ptr i)180*0861b331Schristos INLINE_DECL char *bi_2_dec_char(const bi_ptr i) {
181*0861b331Schristos 	char *result = BN_bn2dec( i);
182*0861b331Schristos 
183*0861b331Schristos 	if( result == NULL) {
184*0861b331Schristos 		return NULL;
185*0861b331Schristos 	}
186*0861b331Schristos 	list_add( allocs, result);
187*0861b331Schristos 	return result;
188*0861b331Schristos }
189*0861b331Schristos 
bi_set(bi_ptr result,const bi_ptr value)190*0861b331Schristos INLINE_DECL bi_ptr bi_set( bi_ptr result, const bi_ptr value) {
191*0861b331Schristos 	BN_copy( result, value);
192*0861b331Schristos 	return result;
193*0861b331Schristos }
194*0861b331Schristos 
bi_set_as_hex(bi_ptr result,const char * value)195*0861b331Schristos INLINE_DECL bi_ptr bi_set_as_hex( bi_ptr result, const char *value) {
196*0861b331Schristos 	BN_hex2bn( &result, value);
197*0861b331Schristos 	return result;
198*0861b331Schristos }
199*0861b331Schristos 
bi_set_as_dec(bi_ptr result,const char * value)200*0861b331Schristos INLINE_DECL bi_ptr bi_set_as_dec( bi_ptr result, const char *value) {
201*0861b331Schristos 	BN_dec2bn( &result, value);
202*0861b331Schristos 	return result;
203*0861b331Schristos }
204*0861b331Schristos 
205*0861b331Schristos /* set <i> with the value represented by unsigned int <value> */
206*0861b331Schristos  /*    <i> := <value>          */
bi_set_as_si(bi_ptr result,const int value)207*0861b331Schristos INLINE_DECL bi_ptr bi_set_as_si( bi_ptr result, const int value) {
208*0861b331Schristos 	if( value < 0) {
209*0861b331Schristos 		BN_set_word( result, -value);
210*0861b331Schristos 		result->neg=1;
211*0861b331Schristos 	} else
212*0861b331Schristos 		BN_set_word( result, value);
213*0861b331Schristos 	return result;
214*0861b331Schristos }
215*0861b331Schristos 
216*0861b331Schristos /* return (long)bi_t  */
bi_get_si(const bi_ptr i)217*0861b331Schristos INLINE_DECL long bi_get_si(const bi_ptr i) {
218*0861b331Schristos 	long result =  BN_get_word( i);
219*0861b331Schristos 
220*0861b331Schristos 	if( i->neg == 1) {
221*0861b331Schristos 		return -result;
222*0861b331Schristos 	}
223*0861b331Schristos 	return result;
224*0861b331Schristos }
225*0861b331Schristos 
226*0861b331Schristos /* return the size of a network byte order representation of <i>  */
bi_nbin_size(const bi_ptr i)227*0861b331Schristos INLINE_DECL long bi_nbin_size(const bi_ptr i) {
228*0861b331Schristos 	return BN_num_bytes( i);
229*0861b331Schristos }
230*0861b331Schristos 
231*0861b331Schristos /* return a BYTE *  in network byte order - big endian - and update the length <length>  */
bi_2_nbin(int * length,const bi_ptr i)232*0861b331Schristos INLINE_DECL unsigned char *bi_2_nbin( int *length, const bi_ptr i) {
233*0861b331Schristos 	unsigned char *ret;
234*0861b331Schristos 
235*0861b331Schristos 	*length = BN_num_bytes( i);
236*0861b331Schristos 	ret = (unsigned char *)bi_alloc( *length * 2);
237*0861b331Schristos 	if( ret == NULL) return NULL;
238*0861b331Schristos 	BN_bn2bin( i, ret);
239*0861b331Schristos 	return ret;
240*0861b331Schristos }
241*0861b331Schristos 
242*0861b331Schristos /* return a BYTE * - in network byte order -  and update the length <length>  */
243*0861b331Schristos /* different from bi_2_nbin: you should reserve enough memory for the storage */
bi_2_nbin1(int * length,unsigned char * buffer,const bi_ptr i)244*0861b331Schristos INLINE_DECL void bi_2_nbin1( int *length, unsigned char *buffer, const bi_ptr i) {
245*0861b331Schristos 	*length = BN_num_bytes( i);
246*0861b331Schristos 	BN_bn2bin( i, buffer);
247*0861b331Schristos }
248*0861b331Schristos 
249*0861b331Schristos /* return a bi_ptr that correspond to the big endian encoded BYTE array of length <n_length> */
bi_set_as_nbin(const unsigned long length,const unsigned char * buffer)250*0861b331Schristos INLINE_DECL bi_ptr bi_set_as_nbin( const unsigned long length, const unsigned char *buffer) {
251*0861b331Schristos 	bi_ptr ret_bi = bi_new_ptr();
252*0861b331Schristos 
253*0861b331Schristos 	if( ret_bi == NULL) return NULL;
254*0861b331Schristos 	if( BN_bin2bn( buffer, length, ret_bi) == NULL) {
255*0861b331Schristos 		bi_free( ret_bi);
256*0861b331Schristos 		return NULL;
257*0861b331Schristos 	}
258*0861b331Schristos 	return ret_bi;
259*0861b331Schristos }
260*0861b331Schristos 
261*0861b331Schristos /* convert a bi to a openssl BIGNUM struct */
bi_2_BIGNUM(const bi_ptr i)262*0861b331Schristos INLINE_DECL BIGNUM *bi_2_BIGNUM( const bi_ptr i) {
263*0861b331Schristos 	return i;
264*0861b331Schristos }
265*0861b331Schristos 
266*0861b331Schristos /* set <i> with the value represented by the given openssl BIGNUM struct */
bi_set_as_BIGNUM(bi_ptr i,BIGNUM * bn)267*0861b331Schristos INLINE_DECL bi_ptr bi_set_as_BIGNUM( bi_ptr i, BIGNUM *bn) {
268*0861b331Schristos 	return bi_set( i, bn);
269*0861b331Schristos }
270*0861b331Schristos 
271*0861b331Schristos /***********************************************************************************
272*0861b331Schristos 	BITS OPERATION
273*0861b331Schristos *************************************************************************************/
274*0861b331Schristos /* set the bit to 1 */
bi_setbit(bi_ptr result,const int bit)275*0861b331Schristos INLINE_DECL bi_ptr bi_setbit(bi_ptr result, const int bit) {
276*0861b331Schristos 	BN_set_bit( result, bit);
277*0861b331Schristos 	return result;
278*0861b331Schristos }
279*0861b331Schristos 
280*0861b331Schristos /* <result> := <i> << <n> */
bi_shift_left(bi_ptr result,const bi_ptr i,const int n)281*0861b331Schristos INLINE_DECL bi_ptr bi_shift_left( bi_ptr result, const bi_ptr i, const int n) {
282*0861b331Schristos 	BN_lshift( result, i, n);
283*0861b331Schristos 	return result;
284*0861b331Schristos }
285*0861b331Schristos 
286*0861b331Schristos /* <result> := <i> >> <n> */
bi_shift_right(bi_ptr result,const bi_ptr i,const int n)287*0861b331Schristos INLINE_DECL bi_ptr bi_shift_right( bi_ptr result, const bi_ptr i, const int n) {
288*0861b331Schristos 	BN_rshift( result, i, n);
289*0861b331Schristos 	return result;
290*0861b331Schristos }
291*0861b331Schristos 
292*0861b331Schristos /* create a random of length <length> bits */
293*0861b331Schristos /*  res := random( length)  */
bi_urandom(bi_ptr result,const long length)294*0861b331Schristos INLINE_DECL bi_ptr bi_urandom( bi_ptr result, const long length) {
295*0861b331Schristos 	/*
296*0861b331Schristos 	 *  <result> will be a  generated cryptographically strong pseudo-random number of length
297*0861b331Schristos 	 *  <length>
298*0861b331Schristos 	 */
299*0861b331Schristos 	BN_rand( result, length, -1, 0);
300*0861b331Schristos 	return result;
301*0861b331Schristos }
302*0861b331Schristos 
303*0861b331Schristos 
304*0861b331Schristos /* res := <n> mod <m> */
bi_mod_si(bi_ptr result,const bi_ptr n,const long m)305*0861b331Schristos INLINE_DECL bi_ptr bi_mod_si( bi_ptr result, const bi_ptr n, const long m) {
306*0861b331Schristos 	BIGNUM *mod = BN_new();
307*0861b331Schristos 	BN_set_word( mod, m);
308*0861b331Schristos 	BN_mod( result, n, mod, context);
309*0861b331Schristos 	BN_free( mod);
310*0861b331Schristos 	return result;
311*0861b331Schristos }
312*0861b331Schristos 
313*0861b331Schristos /* res := <n> mod <m> */
bi_mod(bi_ptr result,const bi_ptr n,const bi_ptr m)314*0861b331Schristos INLINE_DECL bi_ptr bi_mod( bi_ptr result, const bi_ptr n, const bi_ptr m) {
315*0861b331Schristos 	BN_mod( result, n, m, context);
316*0861b331Schristos 	if( result->neg == 1) {
317*0861b331Schristos 		result->neg=0;
318*0861b331Schristos 		BN_sub( result, m, result);
319*0861b331Schristos 	}
320*0861b331Schristos 	return result;
321*0861b331Schristos }
322*0861b331Schristos 
323*0861b331Schristos /* result := (inverse of <i>) mod <m> */
324*0861b331Schristos /* if the inverse exist, return >0, otherwise 0 */
bi_invert_mod(bi_ptr result,const bi_ptr i,const bi_ptr m)325*0861b331Schristos INLINE_DECL int bi_invert_mod( bi_ptr result, const bi_ptr i, const bi_ptr m) {
326*0861b331Schristos 	while( ERR_get_error() != 0);
327*0861b331Schristos 	BN_mod_inverse( result, i, m, context);
328*0861b331Schristos 	return ERR_get_error() == 0 ? 1 : 0;
329*0861b331Schristos }
330*0861b331Schristos 
331*0861b331Schristos /* generate a prime number of <length> bits  */
bi_generate_prime(bi_ptr result,const long bit_length)332*0861b331Schristos INLINE_DECL bi_ptr bi_generate_prime( bi_ptr result, const long bit_length) {
333*0861b331Schristos 	BN_generate_prime(result, bit_length, 0, NULL, NULL, NULL, NULL);
334*0861b331Schristos 	return result;
335*0861b331Schristos }
336*0861b331Schristos 
337*0861b331Schristos /* generate a safe prime number of <length> bits  */
338*0861b331Schristos /* by safe we mean a prime p so that (p-1)/2 is also prime */
bi_generate_safe_prime(bi_ptr result,const long bit_length)339*0861b331Schristos INLINE_DECL bi_ptr bi_generate_safe_prime( bi_ptr result, const long bit_length) {
340*0861b331Schristos 	BN_generate_prime(result, bit_length, 1, NULL, NULL, NULL, NULL);
341*0861b331Schristos 	return result;
342*0861b331Schristos }
343*0861b331Schristos 
344*0861b331Schristos /* return in <result> the greatest common divisor of <a> and <b> */
345*0861b331Schristos /* <result> := gcd( <a>, <b>) */
bi_gcd(bi_ptr result,bi_ptr a,bi_ptr b)346*0861b331Schristos INLINE_DECL bi_ptr bi_gcd( bi_ptr result, bi_ptr a, bi_ptr b) {
347*0861b331Schristos 	BN_gcd( result, a, b, context);
348*0861b331Schristos 	return result;
349*0861b331Schristos }
350*0861b331Schristos 
351*0861b331Schristos 
352*0861b331Schristos #endif /*BI_OPENSSL_*/
353