diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_exp.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_exp.c | 238 |
1 files changed, 219 insertions, 19 deletions
diff --git a/src/lib/libcrypto/bn/bn_exp.c b/src/lib/libcrypto/bn/bn_exp.c index 2df1614ada..0c11601675 100644 --- a/src/lib/libcrypto/bn/bn_exp.c +++ b/src/lib/libcrypto/bn/bn_exp.c | |||
@@ -59,6 +59,12 @@ | |||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
61 | #include "bn_lcl.h" | 61 | #include "bn_lcl.h" |
62 | #ifdef ATALLA | ||
63 | # include <alloca.h> | ||
64 | # include <atasi.h> | ||
65 | # include <assert.h> | ||
66 | # include <dlfcn.h> | ||
67 | #endif | ||
62 | 68 | ||
63 | #define TABLE_SIZE 16 | 69 | #define TABLE_SIZE 16 |
64 | 70 | ||
@@ -72,7 +78,8 @@ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) | |||
72 | bn_check_top(b); | 78 | bn_check_top(b); |
73 | bn_check_top(m); | 79 | bn_check_top(m); |
74 | 80 | ||
75 | t= &(ctx->bn[ctx->tos++]); | 81 | BN_CTX_start(ctx); |
82 | if ((t = BN_CTX_get(ctx)) == NULL) goto err; | ||
76 | if (a == b) | 83 | if (a == b) |
77 | { if (!BN_sqr(t,a,ctx)) goto err; } | 84 | { if (!BN_sqr(t,a,ctx)) goto err; } |
78 | else | 85 | else |
@@ -80,7 +87,7 @@ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) | |||
80 | if (!BN_mod(ret,t,m,ctx)) goto err; | 87 | if (!BN_mod(ret,t,m,ctx)) goto err; |
81 | r=1; | 88 | r=1; |
82 | err: | 89 | err: |
83 | ctx->tos--; | 90 | BN_CTX_end(ctx); |
84 | return(r); | 91 | return(r); |
85 | } | 92 | } |
86 | 93 | ||
@@ -91,8 +98,10 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) | |||
91 | int i,bits,ret=0; | 98 | int i,bits,ret=0; |
92 | BIGNUM *v,*tmp; | 99 | BIGNUM *v,*tmp; |
93 | 100 | ||
94 | v= &(ctx->bn[ctx->tos++]); | 101 | BN_CTX_start(ctx); |
95 | tmp= &(ctx->bn[ctx->tos++]); | 102 | v = BN_CTX_get(ctx); |
103 | tmp = BN_CTX_get(ctx); | ||
104 | if (v == NULL || tmp == NULL) goto err; | ||
96 | 105 | ||
97 | if (BN_copy(v,a) == NULL) goto err; | 106 | if (BN_copy(v,a) == NULL) goto err; |
98 | bits=BN_num_bits(p); | 107 | bits=BN_num_bits(p); |
@@ -113,7 +122,7 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) | |||
113 | } | 122 | } |
114 | ret=1; | 123 | ret=1; |
115 | err: | 124 | err: |
116 | ctx->tos-=2; | 125 | BN_CTX_end(ctx); |
117 | return(ret); | 126 | return(ret); |
118 | } | 127 | } |
119 | 128 | ||
@@ -122,15 +131,15 @@ err: | |||
122 | /* this one works - simple but works */ | 131 | /* this one works - simple but works */ |
123 | int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) | 132 | int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) |
124 | { | 133 | { |
125 | int i,bits,ret=0,tos; | 134 | int i,bits,ret=0; |
126 | BIGNUM *v,*rr; | 135 | BIGNUM *v,*rr; |
127 | 136 | ||
128 | tos=ctx->tos; | 137 | BN_CTX_start(ctx); |
129 | v= &(ctx->bn[ctx->tos++]); | ||
130 | if ((r == a) || (r == p)) | 138 | if ((r == a) || (r == p)) |
131 | rr= &(ctx->bn[ctx->tos++]); | 139 | rr = BN_CTX_get(ctx); |
132 | else | 140 | else |
133 | rr=r; | 141 | rr = r; |
142 | if ((v = BN_CTX_get(ctx)) == NULL) goto err; | ||
134 | 143 | ||
135 | if (BN_copy(v,a) == NULL) goto err; | 144 | if (BN_copy(v,a) == NULL) goto err; |
136 | bits=BN_num_bits(p); | 145 | bits=BN_num_bits(p); |
@@ -149,11 +158,178 @@ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) | |||
149 | } | 158 | } |
150 | ret=1; | 159 | ret=1; |
151 | err: | 160 | err: |
152 | ctx->tos=tos; | ||
153 | if (r != rr) BN_copy(r,rr); | 161 | if (r != rr) BN_copy(r,rr); |
162 | BN_CTX_end(ctx); | ||
154 | return(ret); | 163 | return(ret); |
155 | } | 164 | } |
156 | 165 | ||
166 | #ifdef ATALLA | ||
167 | |||
168 | /* | ||
169 | * This routine will dynamically check for the existance of an Atalla AXL-200 | ||
170 | * SSL accelerator module. If one is found, the variable | ||
171 | * asi_accelerator_present is set to 1 and the function pointers | ||
172 | * ptr_ASI_xxxxxx above will be initialized to corresponding ASI API calls. | ||
173 | */ | ||
174 | typedef int tfnASI_GetPerformanceStatistics(int reset_flag, | ||
175 | unsigned int *ret_buf); | ||
176 | typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf); | ||
177 | typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey, | ||
178 | unsigned char *output, | ||
179 | unsigned char *input, | ||
180 | unsigned int modulus_len); | ||
181 | |||
182 | static tfnASI_GetHardwareConfig *ptr_ASI_GetHardwareConfig; | ||
183 | static tfnASI_RSAPrivateKeyOpFn *ptr_ASI_RSAPrivateKeyOpFn; | ||
184 | static tfnASI_GetPerformanceStatistics *ptr_ASI_GetPerformanceStatistics; | ||
185 | static int asi_accelerator_present; | ||
186 | static int tried_atalla; | ||
187 | |||
188 | void atalla_initialize_accelerator_handle(void) | ||
189 | { | ||
190 | void *dl_handle; | ||
191 | int status; | ||
192 | unsigned int config_buf[1024]; | ||
193 | static int tested; | ||
194 | |||
195 | if(tested) | ||
196 | return; | ||
197 | |||
198 | tested=1; | ||
199 | |||
200 | bzero((void *)config_buf, 1024); | ||
201 | |||
202 | /* | ||
203 | * Check to see if the library is present on the system | ||
204 | */ | ||
205 | dl_handle = dlopen("atasi.so", RTLD_NOW); | ||
206 | if (dl_handle == (void *) NULL) | ||
207 | { | ||
208 | /* printf("atasi.so library is not present on the system\n"); | ||
209 | printf("No HW acceleration available\n");*/ | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * The library is present. Now we'll check to insure that the | ||
215 | * LDM is up and running. First we'll get the address of the | ||
216 | * function in the atasi library that we need to see if the | ||
217 | * LDM is operating. | ||
218 | */ | ||
219 | |||
220 | ptr_ASI_GetHardwareConfig = | ||
221 | (tfnASI_GetHardwareConfig *)dlsym(dl_handle,"ASI_GetHardwareConfig"); | ||
222 | |||
223 | if (ptr_ASI_GetHardwareConfig) | ||
224 | { | ||
225 | /* | ||
226 | * We found the call, now we'll get our config | ||
227 | * status. If we get a non 0 result, the LDM is not | ||
228 | * running and we cannot use the Atalla ASI * | ||
229 | * library. | ||
230 | */ | ||
231 | status = (*ptr_ASI_GetHardwareConfig)(0L, config_buf); | ||
232 | if (status != 0) | ||
233 | { | ||
234 | printf("atasi.so library is present but not initialized\n"); | ||
235 | printf("No HW acceleration available\n"); | ||
236 | return; | ||
237 | } | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | /* printf("We found the library, but not the function. Very Strange!\n");*/ | ||
242 | return ; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * It looks like we have acceleration capabilities. Load up the | ||
247 | * pointers to our ASI API calls. | ||
248 | */ | ||
249 | ptr_ASI_RSAPrivateKeyOpFn= | ||
250 | (tfnASI_RSAPrivateKeyOpFn *)dlsym(dl_handle, "ASI_RSAPrivateKeyOpFn"); | ||
251 | if (ptr_ASI_RSAPrivateKeyOpFn == NULL) | ||
252 | { | ||
253 | /* printf("We found the library, but no RSA function. Very Strange!\n");*/ | ||
254 | return; | ||
255 | } | ||
256 | |||
257 | ptr_ASI_GetPerformanceStatistics = | ||
258 | (tfnASI_GetPerformanceStatistics *)dlsym(dl_handle, "ASI_GetPerformanceStatistics"); | ||
259 | if (ptr_ASI_GetPerformanceStatistics == NULL) | ||
260 | { | ||
261 | /* printf("We found the library, but no stat function. Very Strange!\n");*/ | ||
262 | return; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Indicate that acceleration is available | ||
267 | */ | ||
268 | asi_accelerator_present = 1; | ||
269 | |||
270 | /* printf("This system has acceleration!\n");*/ | ||
271 | |||
272 | return; | ||
273 | } | ||
274 | |||
275 | /* make sure this only gets called once when bn_mod_exp calls bn_mod_exp_mont */ | ||
276 | int BN_mod_exp_atalla(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m) | ||
277 | { | ||
278 | unsigned char *abin; | ||
279 | unsigned char *pbin; | ||
280 | unsigned char *mbin; | ||
281 | unsigned char *rbin; | ||
282 | int an,pn,mn,ret; | ||
283 | RSAPrivateKey keydata; | ||
284 | |||
285 | atalla_initialize_accelerator_handle(); | ||
286 | if(!asi_accelerator_present) | ||
287 | return 0; | ||
288 | |||
289 | |||
290 | /* We should be able to run without size testing */ | ||
291 | # define ASIZE 128 | ||
292 | an=BN_num_bytes(a); | ||
293 | pn=BN_num_bytes(p); | ||
294 | mn=BN_num_bytes(m); | ||
295 | |||
296 | if(an <= ASIZE && pn <= ASIZE && mn <= ASIZE) | ||
297 | { | ||
298 | int size=mn; | ||
299 | |||
300 | assert(an <= mn); | ||
301 | abin=alloca(size); | ||
302 | memset(abin,'\0',mn); | ||
303 | BN_bn2bin(a,abin+size-an); | ||
304 | |||
305 | pbin=alloca(pn); | ||
306 | BN_bn2bin(p,pbin); | ||
307 | |||
308 | mbin=alloca(size); | ||
309 | memset(mbin,'\0',mn); | ||
310 | BN_bn2bin(m,mbin+size-mn); | ||
311 | |||
312 | rbin=alloca(size); | ||
313 | |||
314 | memset(&keydata,'\0',sizeof keydata); | ||
315 | keydata.privateExponent.data=pbin; | ||
316 | keydata.privateExponent.len=pn; | ||
317 | keydata.modulus.data=mbin; | ||
318 | keydata.modulus.len=size; | ||
319 | |||
320 | ret=(*ptr_ASI_RSAPrivateKeyOpFn)(&keydata,rbin,abin,keydata.modulus.len); | ||
321 | /*fprintf(stderr,"!%s\n",BN_bn2hex(a));*/ | ||
322 | if(!ret) | ||
323 | { | ||
324 | BN_bin2bn(rbin,keydata.modulus.len,r); | ||
325 | /*fprintf(stderr,"?%s\n",BN_bn2hex(r));*/ | ||
326 | return 1; | ||
327 | } | ||
328 | } | ||
329 | return 0; | ||
330 | } | ||
331 | #endif /* def ATALLA */ | ||
332 | |||
157 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, | 333 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, |
158 | BN_CTX *ctx) | 334 | BN_CTX *ctx) |
159 | { | 335 | { |
@@ -163,6 +339,13 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, | |||
163 | bn_check_top(p); | 339 | bn_check_top(p); |
164 | bn_check_top(m); | 340 | bn_check_top(m); |
165 | 341 | ||
342 | #ifdef ATALLA | ||
343 | if(BN_mod_exp_atalla(r,a,p,m)) | ||
344 | return 1; | ||
345 | /* If it fails, try the other methods (but don't try atalla again) */ | ||
346 | tried_atalla=1; | ||
347 | #endif | ||
348 | |||
166 | #ifdef MONT_MUL_MOD | 349 | #ifdef MONT_MUL_MOD |
167 | /* I have finally been able to take out this pre-condition of | 350 | /* I have finally been able to take out this pre-condition of |
168 | * the top bit being set. It was caused by an error in BN_div | 351 | * the top bit being set. It was caused by an error in BN_div |
@@ -180,6 +363,10 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, | |||
180 | { ret=BN_mod_exp_simple(r,a,p,m,ctx); } | 363 | { ret=BN_mod_exp_simple(r,a,p,m,ctx); } |
181 | #endif | 364 | #endif |
182 | 365 | ||
366 | #ifdef ATALLA | ||
367 | tried_atalla=0; | ||
368 | #endif | ||
369 | |||
183 | return(ret); | 370 | return(ret); |
184 | } | 371 | } |
185 | 372 | ||
@@ -193,7 +380,6 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |||
193 | BIGNUM val[TABLE_SIZE]; | 380 | BIGNUM val[TABLE_SIZE]; |
194 | BN_RECP_CTX recp; | 381 | BN_RECP_CTX recp; |
195 | 382 | ||
196 | aa= &(ctx->bn[ctx->tos++]); | ||
197 | bits=BN_num_bits(p); | 383 | bits=BN_num_bits(p); |
198 | 384 | ||
199 | if (bits == 0) | 385 | if (bits == 0) |
@@ -201,6 +387,10 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |||
201 | BN_one(r); | 387 | BN_one(r); |
202 | return(1); | 388 | return(1); |
203 | } | 389 | } |
390 | |||
391 | BN_CTX_start(ctx); | ||
392 | if ((aa = BN_CTX_get(ctx)) == NULL) goto err; | ||
393 | |||
204 | BN_RECP_CTX_init(&recp); | 394 | BN_RECP_CTX_init(&recp); |
205 | if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; | 395 | if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; |
206 | 396 | ||
@@ -289,7 +479,7 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |||
289 | } | 479 | } |
290 | ret=1; | 480 | ret=1; |
291 | err: | 481 | err: |
292 | ctx->tos--; | 482 | BN_CTX_end(ctx); |
293 | for (i=0; i<ts; i++) | 483 | for (i=0; i<ts; i++) |
294 | BN_clear_free(&(val[i])); | 484 | BN_clear_free(&(val[i])); |
295 | BN_RECP_CTX_free(&recp); | 485 | BN_RECP_CTX_free(&recp); |
@@ -312,19 +502,27 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p, | |||
312 | bn_check_top(p); | 502 | bn_check_top(p); |
313 | bn_check_top(m); | 503 | bn_check_top(m); |
314 | 504 | ||
505 | #ifdef ATALLA | ||
506 | if(!tried_atalla && BN_mod_exp_atalla(rr,a,p,m)) | ||
507 | return 1; | ||
508 | /* If it fails, try the other methods */ | ||
509 | #endif | ||
510 | |||
315 | if (!(m->d[0] & 1)) | 511 | if (!(m->d[0] & 1)) |
316 | { | 512 | { |
317 | BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); | 513 | BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); |
318 | return(0); | 514 | return(0); |
319 | } | 515 | } |
320 | d= &(ctx->bn[ctx->tos++]); | ||
321 | r= &(ctx->bn[ctx->tos++]); | ||
322 | bits=BN_num_bits(p); | 516 | bits=BN_num_bits(p); |
323 | if (bits == 0) | 517 | if (bits == 0) |
324 | { | 518 | { |
325 | BN_one(r); | 519 | BN_one(rr); |
326 | return(1); | 520 | return(1); |
327 | } | 521 | } |
522 | BN_CTX_start(ctx); | ||
523 | d = BN_CTX_get(ctx); | ||
524 | r = BN_CTX_get(ctx); | ||
525 | if (d == NULL || r == NULL) goto err; | ||
328 | 526 | ||
329 | /* If this is not done, things will break in the montgomery | 527 | /* If this is not done, things will break in the montgomery |
330 | * part */ | 528 | * part */ |
@@ -432,7 +630,7 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p, | |||
432 | ret=1; | 630 | ret=1; |
433 | err: | 631 | err: |
434 | if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); | 632 | if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); |
435 | ctx->tos-=2; | 633 | BN_CTX_end(ctx); |
436 | for (i=0; i<ts; i++) | 634 | for (i=0; i<ts; i++) |
437 | BN_clear_free(&(val[i])); | 635 | BN_clear_free(&(val[i])); |
438 | return(ret); | 636 | return(ret); |
@@ -448,7 +646,6 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, | |||
448 | BIGNUM *d; | 646 | BIGNUM *d; |
449 | BIGNUM val[TABLE_SIZE]; | 647 | BIGNUM val[TABLE_SIZE]; |
450 | 648 | ||
451 | d= &(ctx->bn[ctx->tos++]); | ||
452 | bits=BN_num_bits(p); | 649 | bits=BN_num_bits(p); |
453 | 650 | ||
454 | if (bits == 0) | 651 | if (bits == 0) |
@@ -457,6 +654,9 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, | |||
457 | return(1); | 654 | return(1); |
458 | } | 655 | } |
459 | 656 | ||
657 | BN_CTX_start(ctx); | ||
658 | if ((d = BN_CTX_get(ctx)) == NULL) goto err; | ||
659 | |||
460 | BN_init(&(val[0])); | 660 | BN_init(&(val[0])); |
461 | ts=1; | 661 | ts=1; |
462 | if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ | 662 | if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ |
@@ -541,7 +741,7 @@ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, | |||
541 | } | 741 | } |
542 | ret=1; | 742 | ret=1; |
543 | err: | 743 | err: |
544 | ctx->tos--; | 744 | BN_CTX_end(ctx); |
545 | for (i=0; i<ts; i++) | 745 | for (i=0; i<ts; i++) |
546 | BN_clear_free(&(val[i])); | 746 | BN_clear_free(&(val[i])); |
547 | return(ret); | 747 | return(ret); |