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 #include <bi.h>
12 
13 #include "tcslog.h"
14 
15 #undef INLINE_DECL
16 #define INLINE_DECL
17 
18 /***********************************************************************************
19           CONSTANT
20 *************************************************************************************/
21 
22 bi_t bi_0;
23 bi_t bi_1;
24 bi_t bi_2;
25 
26 /***********************************************************************************
27           WORK VARIABLE
28 *************************************************************************************/
29 
30 // Buffer to load bi from a file . A static field is used, this should not be
31 // refere in any SPI calls.
32 #define BUFFER_SIZE 10000
33 static char buffer[BUFFER_SIZE]; // used for loading bi
34 
35 #define SAFETY_PARAM 80
36 
37 // keep the list of allocated memory, usually used for the format functions
38 list_ptr allocs = NULL;
39 
40 /***********************************************************************************
41           DUMP LIB
42 *************************************************************************************/
43 
44 // !! to use only for debugging
45 // do not used it in the same call, as a static buffer is used
dump_byte_array(int len,unsigned char * array)46 char *dump_byte_array(int len, unsigned char *array) {
47           int i, j=0;
48           char c, str[3];
49 
50           for( i=0; i<len; i++) {
51                     c = array[i];
52                     sprintf( str, "%02X", (int)(c & 0xFF));
53                     buffer[j] = str[0];
54                     buffer[j+1] = str[1];
55                     j+=2;
56           }
57           buffer[j] = 0;
58           return buffer;
59 }
60 
61 /* convert <strings> and return it into a byte array <result> of length <length> */
retrieve_byte_array(int * len,const char * strings)62 unsigned char *retrieve_byte_array( int *len, const char *strings) {
63           int index_str = 0, index_result = 0;
64           int str_len = strlen( strings);
65           char read_buffer[3];
66           int c;
67           unsigned char *result;
68 
69           read_buffer[2]=0;
70           *len = ( str_len >> 1);
71           #ifdef BI_DEBUG
72           printf("[%s]\n", strings);
73           printf("[retrieve_byte_array] strlen=%d len=%d\n", str_len, *len);
74           #endif
75           result = (unsigned char *)malloc( *len+1);
76           if( result == NULL) {
77                     LogError("malloc of %d bytes failed", *len+1);
78                     return NULL;
79           }
80           if( (str_len & 1) ==1) {
81                     // impair =>   1 12 23 -> 01 12 23
82                     read_buffer[0]='0';
83                     read_buffer[1]=strings[index_str++];
84                     sscanf( read_buffer, "%2X", &c);
85                     #ifdef BI_DEBUG
86                     printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer);
87                     #endif
88                     result[index_result++] = c&0xFF;
89                     (*len)++;
90           }
91           while( index_str < str_len) {
92                     read_buffer[0] = strings[ index_str++];
93                     read_buffer[1] = strings[ index_str++];
94                     sscanf( read_buffer, "%02X", &c);
95                     #ifdef BI_DEBUG
96                     printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer);
97                     #endif
98                     result[index_result++] = c&0xFF;
99           }
100           return result;
101 }
102 
103 /* create a <big integer> array */
bi_new_array(bi_array array,const int length)104 INLINE_DECL void bi_new_array( bi_array array, const int length) {
105           int i=0;
106 
107           bi_new_array2( array, length);
108           if( array->array == NULL) return;
109           for( i = 0; i< length; i++) {
110                     array->array[i] = bi_new_ptr();
111           }
112 }
113 
114 /* create a <big integer> array */
bi_new_array2(bi_array array,const int length)115 INLINE_DECL void bi_new_array2( bi_array array, const int length) {
116           array->length = length;
117           array->array = (bi_ptr *)malloc( sizeof(bi_ptr) * length);
118           if( array->array == NULL) {
119                     LogError("malloc of %d bytes failed", sizeof(bi_ptr)*length);
120                     return;
121           }
122 }
123 
124 /* free resources allocated to the big integer <i> */
bi_free_array(bi_array array)125 INLINE_DECL void bi_free_array(bi_array array) {
126           int length = array->length;
127           int i=0;
128 
129           for( i = 0; i< length; i++) {
130                     bi_free_ptr( array->array[i]);
131           }
132           free( array->array);
133 }
134 
135 /* copy length pointers from the array <src, offset_src> to array <dest, offset_dest> */
bi_copy_array(bi_array_ptr src,int offset_src,bi_array_ptr dest,int offset_dest,int length)136 INLINE_DECL void bi_copy_array(bi_array_ptr src,
137                                         int offset_src,
138                                         bi_array_ptr dest,
139                                         int offset_dest,
140                                         int length) {
141           int i=0;
142 
143           for( i = 0; i< length; i++) {
144                     dest->array[ offset_dest + i] = src->array[ offset_src + i];
145           }
146 }
147 
148 /* debug function -> dump a field of type bi_array */
dump_bi_array(char * field,const bi_array_ptr array)149 void dump_bi_array( char *field, const bi_array_ptr array) {
150           int i;
151 
152           for( i=0; i<array->length; i++) {
153                     printf("%s->array[%d] = %s\n", field, i, bi_2_hex_char(array->array[i]));
154           }
155 }
156 
157 /***********************************************************************************
158           SAFE RANDOM
159 *************************************************************************************/
160 
161 /* Returns a random number in the range of [0,element-1] */
compute_random_number(bi_ptr result,const bi_ptr element)162 bi_ptr compute_random_number( bi_ptr result, const bi_ptr element) {
163           bi_urandom( result, bi_length( element) + SAFETY_PARAM);
164           bi_mod( result, result, element);
165           return result;
166 }
167 
168 /***********************************************************************************
169           SAVE / LOAD
170 *************************************************************************************/
171 
172 /* load an big integer from an open file handler */
bi_load(bi_ptr bi,FILE * file)173 void bi_load( bi_ptr bi, FILE *file) {
174           int i=0;
175           char c;
176 
177           fgets( buffer, BUFFER_SIZE, file);
178           do {
179                     c = buffer[i];
180                     i++;
181           } while( c != 0 && c != ' ');
182           buffer[i-1] = 0;
183           bi_set_as_hex( bi, buffer);
184 }
185 
186 /* load an big integer array from an open file handler */
bi_load_array(bi_array_ptr array,FILE * file)187 void bi_load_array( bi_array_ptr array, FILE *file) {
188           int i, j = 0, length;
189           char c;
190 
191           fgets( buffer, BUFFER_SIZE, file);
192           do {
193                     c = buffer[ j];
194                     j++;
195           } while( c != 0 && c != ' ');
196           buffer[ j -1] = 0;
197           sscanf( buffer, "%d", &length);
198           bi_new_array( array, length);
199           for( i=0; i<array->length; i++) {
200                     bi_load( array->array[i], file);
201           }
202 }
203 
204 /* save an big integer to an open file handler */
bi_save(const bi_ptr bi,const char * name,FILE * file)205 void bi_save( const bi_ptr bi, const char *name, FILE *file) {
206           fprintf( file, "%s # %s [%ld]\n", bi_2_hex_char( bi), name, bi_nbin_size( bi));
207 }
208 
209 /* save an big integer array to an open file handler */
bi_save_array(const bi_array_ptr array,const char * name,FILE * file)210 void bi_save_array( const bi_array_ptr array, const char *name, FILE *file) {
211           int i;
212           char new_name[100];
213 
214           fprintf(file, "%d # %s.length\n", array->length, name);
215           for( i=0; i<array->length; i++) {
216                     sprintf( new_name, "%s[%d]", name, i);
217                     bi_save( array->array[i], new_name, file);
218           }
219 }
220 
221 /* convert <bi> to a byte array of length result, the beginning of */
222 /* this buffer is feel with '0' if needed */
bi_2_byte_array(unsigned char * result,int length,bi_ptr bi)223 void bi_2_byte_array( unsigned char *result, int length, bi_ptr bi) {
224           int i, result_length;
225 
226           bi_2_nbin1( &result_length, buffer, bi);
227           int delta = length - result_length;
228           #ifdef BI_DEBUG
229           fprintf( stderr, "[bi_2_byte_array] result_length=%d length=%d\n", result_length, length);
230           #endif
231           if( delta < 0) {
232                     LogError( "[bi_2_byte_array] asked length:%d  found:%d\n", length, result_length);
233                     return;
234           }
235           for( i=0; i<delta; i++) result[i] = 0;
236           for( ; i<length; i++)         result[ i] = buffer[ i - delta];
237 }
238