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