/* * Licensed Materials - Property of IBM * * trousers - An open source TCG Software Stack * * (C) Copyright International Business Machines Corp. 2006 * */ #ifndef BI_OPENSSL_ #define BI_OPENSSL_ #include #include typedef struct bignum_st bi_t[1]; typedef struct bignum_st *bi_ptr; extern BN_CTX *context; INLINE_DECL bi_ptr bi_new(bi_ptr result) { BN_init( result); return result; } /* create a big integer pointer */ INLINE_DECL bi_ptr bi_new_ptr(void) { return BN_new(); } /* free resources allocated to the big integer */ INLINE_DECL void bi_free(const bi_ptr i) { BN_free( i); } /* free resources allocated to the big integer pointer */ INLINE_DECL void bi_free_ptr(const bi_ptr i) { BN_free( i); } /* := result++ */ INLINE_DECL bi_ptr bi_inc(bi_ptr result) { BN_add_word( result, 1); return result; } /* := result-- */ INLINE_DECL bi_ptr bi_dec(bi_ptr result) { BN_sub_word( result, 1); return result; } /* return the current number of bits of the number */ INLINE_DECL long bi_length( const bi_ptr res) { return BN_num_bits( res); } /*********************************************************************************** BASIC MATH OPERATION *************************************************************************************/ /* := - */ INLINE_DECL bi_ptr bi_negate( bi_ptr result) { BIGNUM *n = result; n->neg = ( n->neg == 0 ? 1 : 0); return result; } INLINE_DECL bi_ptr bi_mul_si( bi_ptr result, const bi_ptr i, const long n) { BN_copy( result, i); BN_mul_word( result, n); return result; } /* := * */ INLINE_DECL bi_ptr bi_mul( bi_ptr result, const bi_ptr i, const bi_ptr n) { BN_mul( result, i, n, context); return result; } INLINE_DECL bi_ptr bi_add_si( bi_ptr result, const bi_ptr i, const long n) { BN_copy( result, i); BN_add_word( result, n); return result; } /* := + */ INLINE_DECL bi_ptr bi_add( bi_ptr result, const bi_ptr i, const bi_ptr n) { BN_add( result, i, n); return result; } /* := - */ INLINE_DECL bi_ptr bi_sub_si( bi_ptr result, const bi_ptr i, const long n) { // n should be unsigned BN_copy( result, i); // result := i BN_sub_word( result, n); // result := result - n return result; } /* := - */ INLINE_DECL bi_ptr bi_sub( bi_ptr result, const bi_ptr i, const bi_ptr n) { BN_sub( result, i, n); return result; } /* := ( ^ ) mod */ INLINE_DECL bi_ptr bi_mod_exp( bi_ptr result, const bi_ptr g, const bi_ptr e, const bi_ptr m) { BN_mod_exp( result, g, e, m, context); // result := (g ^ e) mod bi_m return result; } /* set by the division of by the long */ /* := / */ INLINE_DECL bi_ptr bi_div_si( bi_ptr result, const bi_ptr i, const long n) { BN_copy( result, i); BN_div_word( result, n); return result; } /* := / */ INLINE_DECL bi_ptr bi_div( bi_ptr result, const bi_ptr i, const bi_ptr n) { BN_div( result, NULL, i, n, context); return result; } /*********************************************************************************** COMPARAISON *************************************************************************************/ /* n1n2 return positive value */ INLINE_DECL int bi_cmp( const bi_ptr n1, const bi_ptr n2) { return BN_cmp( n1, n2); } /* n1n2 return positive value */ INLINE_DECL int bi_cmp_si( const bi_ptr n1, const int n2) { BIGNUM *temp = BN_new(); BN_set_word( temp, n2); int res = BN_cmp( n1, temp); BN_free( temp); return res; } /* n1 == n2 return 1 (true) * else return 0 */ INLINE_DECL int bi_equals( const bi_ptr n1, const bi_ptr n2) { return BN_cmp( n1, n2) == 0 ? 1 :0; } /* n1 == n2 return 1 (true) * else return 0 */ INLINE_DECL int bi_equals_si( const bi_ptr n1, const int n2) { return BN_is_word( n1, n2); } /*********************************************************************************** CONVERSIONS *************************************************************************************/ INLINE_DECL char *bi_2_hex_char(const bi_ptr i) { char *result = BN_bn2hex( i); if( result == NULL) { return NULL; } list_add( allocs, result); return result; } INLINE_DECL char *bi_2_dec_char(const bi_ptr i) { char *result = BN_bn2dec( i); if( result == NULL) { return NULL; } list_add( allocs, result); return result; } INLINE_DECL bi_ptr bi_set( bi_ptr result, const bi_ptr value) { BN_copy( result, value); return result; } INLINE_DECL bi_ptr bi_set_as_hex( bi_ptr result, const char *value) { BN_hex2bn( &result, value); return result; } INLINE_DECL bi_ptr bi_set_as_dec( bi_ptr result, const char *value) { BN_dec2bn( &result, value); return result; } /* set with the value represented by unsigned int */ /* := */ INLINE_DECL bi_ptr bi_set_as_si( bi_ptr result, const int value) { if( value < 0) { BN_set_word( result, -value); result->neg=1; } else BN_set_word( result, value); return result; } /* return (long)bi_t */ INLINE_DECL long bi_get_si(const bi_ptr i) { long result = BN_get_word( i); if( i->neg == 1) { return -result; } return result; } /* return the size of a network byte order representation of */ INLINE_DECL long bi_nbin_size(const bi_ptr i) { return BN_num_bytes( i); } /* return a BYTE * in network byte order - big endian - and update the length */ INLINE_DECL unsigned char *bi_2_nbin( int *length, const bi_ptr i) { unsigned char *ret; *length = BN_num_bytes( i); ret = (unsigned char *)bi_alloc( *length * 2); if( ret == NULL) return NULL; BN_bn2bin( i, ret); return ret; } /* return a BYTE * - in network byte order - and update the length */ /* different from bi_2_nbin: you should reserve enough memory for the storage */ INLINE_DECL void bi_2_nbin1( int *length, unsigned char *buffer, const bi_ptr i) { *length = BN_num_bytes( i); BN_bn2bin( i, buffer); } /* return a bi_ptr that correspond to the big endian encoded BYTE array of length */ INLINE_DECL bi_ptr bi_set_as_nbin( const unsigned long length, const unsigned char *buffer) { bi_ptr ret_bi = bi_new_ptr(); if( ret_bi == NULL) return NULL; if( BN_bin2bn( buffer, length, ret_bi) == NULL) { bi_free( ret_bi); return NULL; } return ret_bi; } /* convert a bi to a openssl BIGNUM struct */ INLINE_DECL BIGNUM *bi_2_BIGNUM( const bi_ptr i) { return i; } /* set with the value represented by the given openssl BIGNUM struct */ INLINE_DECL bi_ptr bi_set_as_BIGNUM( bi_ptr i, BIGNUM *bn) { return bi_set( i, bn); } /*********************************************************************************** BITS OPERATION *************************************************************************************/ /* set the bit to 1 */ INLINE_DECL bi_ptr bi_setbit(bi_ptr result, const int bit) { BN_set_bit( result, bit); return result; } /* := << */ INLINE_DECL bi_ptr bi_shift_left( bi_ptr result, const bi_ptr i, const int n) { BN_lshift( result, i, n); return result; } /* := >> */ INLINE_DECL bi_ptr bi_shift_right( bi_ptr result, const bi_ptr i, const int n) { BN_rshift( result, i, n); return result; } /* create a random of length bits */ /* res := random( length) */ INLINE_DECL bi_ptr bi_urandom( bi_ptr result, const long length) { /* * will be a generated cryptographically strong pseudo-random number of length * */ BN_rand( result, length, -1, 0); return result; } /* res := mod */ INLINE_DECL bi_ptr bi_mod_si( bi_ptr result, const bi_ptr n, const long m) { BIGNUM *mod = BN_new(); BN_set_word( mod, m); BN_mod( result, n, mod, context); BN_free( mod); return result; } /* res := mod */ INLINE_DECL bi_ptr bi_mod( bi_ptr result, const bi_ptr n, const bi_ptr m) { BN_mod( result, n, m, context); if( result->neg == 1) { result->neg=0; BN_sub( result, m, result); } return result; } /* result := (inverse of ) mod */ /* if the inverse exist, return >0, otherwise 0 */ INLINE_DECL int bi_invert_mod( bi_ptr result, const bi_ptr i, const bi_ptr m) { while( ERR_get_error() != 0); BN_mod_inverse( result, i, m, context); return ERR_get_error() == 0 ? 1 : 0; } /* generate a prime number of bits */ INLINE_DECL bi_ptr bi_generate_prime( bi_ptr result, const long bit_length) { BN_generate_prime(result, bit_length, 0, NULL, NULL, NULL, NULL); return result; } /* generate a safe prime number of bits */ /* by safe we mean a prime p so that (p-1)/2 is also prime */ INLINE_DECL bi_ptr bi_generate_safe_prime( bi_ptr result, const long bit_length) { BN_generate_prime(result, bit_length, 1, NULL, NULL, NULL, NULL); return result; } /* return in the greatest common divisor of and */ /* := gcd( , ) */ INLINE_DECL bi_ptr bi_gcd( bi_ptr result, bi_ptr a, bi_ptr b) { BN_gcd( result, a, b, context); return result; } #endif /*BI_OPENSSL_*/