3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2006
14
#include <openssl/bn.h>
15
#include <openssl/engine.h>
17
typedef struct bignum_st bi_t[1];
19
typedef struct bignum_st *bi_ptr;
21
extern BN_CTX *context;
24
INLINE_DECL bi_ptr bi_new(bi_ptr result) {
29
/* create a big integer pointer */
30
INLINE_DECL bi_ptr bi_new_ptr(void) {
34
/* free resources allocated to the big integer <i> */
35
INLINE_DECL void bi_free(const bi_ptr i) {
39
/* free resources allocated to the big integer pointer <i> */
40
INLINE_DECL void bi_free_ptr(const bi_ptr i) {
44
/* <result> := result++ */
45
INLINE_DECL bi_ptr bi_inc(bi_ptr result) {
46
BN_add_word( result, 1);
50
/* <result> := result-- */
51
INLINE_DECL bi_ptr bi_dec(bi_ptr result) {
52
BN_sub_word( result, 1);
56
/* return the current number of bits of the number */
57
INLINE_DECL long bi_length( const bi_ptr res) {
58
return BN_num_bits( res);
61
/***********************************************************************************
63
*************************************************************************************/
64
/* <result> := - <result> */
65
INLINE_DECL bi_ptr bi_negate( bi_ptr result) {
67
n->neg = ( n->neg == 0 ? 1 : 0);
71
INLINE_DECL bi_ptr bi_mul_si( bi_ptr result, const bi_ptr i, const long n) {
73
BN_mul_word( result, n);
77
/* <result> := <i> * <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);
83
INLINE_DECL bi_ptr bi_add_si( bi_ptr result, const bi_ptr i, const long n) {
85
BN_add_word( result, n);
89
/* <result> := <i> + <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);
95
/* <result> := <i> - <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
103
/* <result> := <i> - <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);
109
/* <result> := ( <g> ^ <e> ) mod <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
115
/* set <result> by the division of <i> by the long <n> */
116
/* <result> := <i> / <n> */
117
INLINE_DECL bi_ptr bi_div_si( bi_ptr result, const bi_ptr i, const long n) {
119
BN_div_word( result, n);
123
/* <result> := <i> / <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);
129
/***********************************************************************************
131
*************************************************************************************/
132
/* n1<n2 return negative value
134
* n1>n2 return positive value
136
INLINE_DECL int bi_cmp( const bi_ptr n1, const bi_ptr n2) {
137
return BN_cmp( n1, n2);
140
/* n1<n2 return negative value
142
* n1>n2 return positive value
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);
152
/* n1 == n2 return 1 (true)
155
INLINE_DECL int bi_equals( const bi_ptr n1, const bi_ptr n2) {
156
return BN_cmp( n1, n2) == 0 ? 1 :0;
159
/* n1 == n2 return 1 (true)
162
INLINE_DECL int bi_equals_si( const bi_ptr n1, const int n2) {
163
return BN_is_word( n1, n2);
166
/***********************************************************************************
168
*************************************************************************************/
170
INLINE_DECL char *bi_2_hex_char(const bi_ptr i) {
171
char *result = BN_bn2hex( i);
173
if( result == NULL) {
176
list_add( allocs, result);
180
INLINE_DECL char *bi_2_dec_char(const bi_ptr i) {
181
char *result = BN_bn2dec( i);
183
if( result == NULL) {
186
list_add( allocs, result);
190
INLINE_DECL bi_ptr bi_set( bi_ptr result, const bi_ptr value) {
191
BN_copy( result, value);
195
INLINE_DECL bi_ptr bi_set_as_hex( bi_ptr result, const char *value) {
196
BN_hex2bn( &result, value);
200
INLINE_DECL bi_ptr bi_set_as_dec( bi_ptr result, const char *value) {
201
BN_dec2bn( &result, value);
205
/* set <i> with the value represented by unsigned int <value> */
207
INLINE_DECL bi_ptr bi_set_as_si( bi_ptr result, const int value) {
209
BN_set_word( result, -value);
212
BN_set_word( result, value);
216
/* return (long)bi_t */
217
INLINE_DECL long bi_get_si(const bi_ptr i) {
218
long result = BN_get_word( i);
226
/* return the size of a network byte order representation of <i> */
227
INLINE_DECL long bi_nbin_size(const bi_ptr i) {
228
return BN_num_bytes( i);
231
/* return a BYTE * in network byte order - big endian - and update the length <length> */
232
INLINE_DECL unsigned char *bi_2_nbin( int *length, const bi_ptr i) {
235
*length = BN_num_bytes( i);
236
ret = (unsigned char *)bi_alloc( *length * 2);
237
if( ret == NULL) return NULL;
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 */
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);
249
/* return a bi_ptr that correspond to the big endian encoded BYTE array of length <n_length> */
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();
253
if( ret_bi == NULL) return NULL;
254
if( BN_bin2bn( buffer, length, ret_bi) == NULL) {
261
/* convert a bi to a openssl BIGNUM struct */
262
INLINE_DECL BIGNUM *bi_2_BIGNUM( const bi_ptr i) {
266
/* set <i> with the value represented by the given openssl BIGNUM struct */
267
INLINE_DECL bi_ptr bi_set_as_BIGNUM( bi_ptr i, BIGNUM *bn) {
268
return bi_set( i, bn);
271
/***********************************************************************************
273
*************************************************************************************/
274
/* set the bit to 1 */
275
INLINE_DECL bi_ptr bi_setbit(bi_ptr result, const int bit) {
276
BN_set_bit( result, bit);
280
/* <result> := <i> << <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);
286
/* <result> := <i> >> <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);
292
/* create a random of length <length> bits */
293
/* res := random( length) */
294
INLINE_DECL bi_ptr bi_urandom( bi_ptr result, const long length) {
296
* <result> will be a generated cryptographically strong pseudo-random number of length
299
BN_rand( result, length, -1, 0);
304
/* res := <n> mod <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);
313
/* res := <n> mod <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) {
318
BN_sub( result, m, result);
323
/* result := (inverse of <i>) mod <m> */
324
/* if the inverse exist, return >0, otherwise 0 */
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;
331
/* generate a prime number of <length> bits */
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);
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 */
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);
344
/* return in <result> the greatest common divisor of <a> and <b> */
345
/* <result> := gcd( <a>, <b>) */
346
INLINE_DECL bi_ptr bi_gcd( bi_ptr result, bi_ptr a, bi_ptr b) {
347
BN_gcd( result, a, b, context);
352
#endif /*BI_OPENSSL_*/