File: | src/lib/libcrypto/bn/bn_lib.c |
Warning: | line 483, column 8 Array access (from variable 'A') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: bn_lib.c,v 1.53 2021/12/27 15:12:22 jsing Exp $ */ | |||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | |||
3 | * All rights reserved. | |||
4 | * | |||
5 | * This package is an SSL implementation written | |||
6 | * by Eric Young (eay@cryptsoft.com). | |||
7 | * The implementation was written so as to conform with Netscapes SSL. | |||
8 | * | |||
9 | * This library is free for commercial and non-commercial use as long as | |||
10 | * the following conditions are aheared to. The following conditions | |||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | |||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |||
13 | * included with this distribution is covered by the same copyright terms | |||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |||
15 | * | |||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | |||
17 | * the code are not to be removed. | |||
18 | * If this package is used in a product, Eric Young should be given attribution | |||
19 | * as the author of the parts of the library used. | |||
20 | * This can be in the form of a textual message at program startup or | |||
21 | * in documentation (online or textual) provided with the package. | |||
22 | * | |||
23 | * Redistribution and use in source and binary forms, with or without | |||
24 | * modification, are permitted provided that the following conditions | |||
25 | * are met: | |||
26 | * 1. Redistributions of source code must retain the copyright | |||
27 | * notice, this list of conditions and the following disclaimer. | |||
28 | * 2. Redistributions in binary form must reproduce the above copyright | |||
29 | * notice, this list of conditions and the following disclaimer in the | |||
30 | * documentation and/or other materials provided with the distribution. | |||
31 | * 3. All advertising materials mentioning features or use of this software | |||
32 | * must display the following acknowledgement: | |||
33 | * "This product includes cryptographic software written by | |||
34 | * Eric Young (eay@cryptsoft.com)" | |||
35 | * The word 'cryptographic' can be left out if the rouines from the library | |||
36 | * being used are not cryptographic related :-). | |||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | |||
38 | * the apps directory (application code) you must include an acknowledgement: | |||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |||
40 | * | |||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | |||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
51 | * SUCH DAMAGE. | |||
52 | * | |||
53 | * The licence and distribution terms for any publically available version or | |||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | |||
55 | * copied and put under another distribution licence | |||
56 | * [including the GNU Public Licence.] | |||
57 | */ | |||
58 | ||||
59 | #ifndef BN_DEBUG | |||
60 | # undef NDEBUG /* avoid conflicting definitions */ | |||
61 | # define NDEBUG | |||
62 | #endif | |||
63 | ||||
64 | #include <assert.h> | |||
65 | #include <limits.h> | |||
66 | #include <stdio.h> | |||
67 | #include <string.h> | |||
68 | ||||
69 | #include <openssl/opensslconf.h> | |||
70 | ||||
71 | #include <openssl/err.h> | |||
72 | ||||
73 | #include "bn_lcl.h" | |||
74 | ||||
75 | /* This stuff appears to be completely unused, so is deprecated */ | |||
76 | #ifndef OPENSSL_NO_DEPRECATED | |||
77 | /* For a 32 bit machine | |||
78 | * 2 - 4 == 128 | |||
79 | * 3 - 8 == 256 | |||
80 | * 4 - 16 == 512 | |||
81 | * 5 - 32 == 1024 | |||
82 | * 6 - 64 == 2048 | |||
83 | * 7 - 128 == 4096 | |||
84 | * 8 - 256 == 8192 | |||
85 | */ | |||
86 | static int bn_limit_bits = 0; | |||
87 | static int bn_limit_num = 8; /* (1<<bn_limit_bits) */ | |||
88 | static int bn_limit_bits_low = 0; | |||
89 | static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */ | |||
90 | static int bn_limit_bits_high = 0; | |||
91 | static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */ | |||
92 | static int bn_limit_bits_mont = 0; | |||
93 | static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */ | |||
94 | ||||
95 | BIGNUM * | |||
96 | BN_new(void) | |||
97 | { | |||
98 | BIGNUM *ret; | |||
99 | ||||
100 | if ((ret = malloc(sizeof(BIGNUM))) == NULL((void *)0)) { | |||
101 | BNerror(ERR_R_MALLOC_FAILURE)ERR_put_error(3,(0xfff),((1|64)),"/usr/src/lib/libcrypto/bn/bn_lib.c" ,101); | |||
102 | return (NULL((void *)0)); | |||
103 | } | |||
104 | ret->flags = BN_FLG_MALLOCED0x01; | |||
105 | ret->top = 0; | |||
106 | ret->neg = 0; | |||
107 | ret->dmax = 0; | |||
108 | ret->d = NULL((void *)0); | |||
109 | bn_check_top(ret); | |||
110 | return (ret); | |||
111 | } | |||
112 | ||||
113 | void | |||
114 | BN_init(BIGNUM *a) | |||
115 | { | |||
116 | memset(a, 0, sizeof(BIGNUM)); | |||
117 | bn_check_top(a); | |||
118 | } | |||
119 | ||||
120 | void | |||
121 | BN_clear(BIGNUM *a) | |||
122 | { | |||
123 | bn_check_top(a); | |||
124 | if (a->d != NULL((void *)0)) | |||
125 | explicit_bzero(a->d, a->dmax * sizeof(a->d[0])); | |||
126 | a->top = 0; | |||
127 | a->neg = 0; | |||
128 | } | |||
129 | ||||
130 | void | |||
131 | BN_clear_free(BIGNUM *a) | |||
132 | { | |||
133 | int i; | |||
134 | ||||
135 | if (a == NULL((void *)0)) | |||
136 | return; | |||
137 | bn_check_top(a); | |||
138 | if (a->d != NULL((void *)0) && !(BN_get_flags(a, BN_FLG_STATIC_DATA0x02))) | |||
139 | freezero(a->d, a->dmax * sizeof(a->d[0])); | |||
140 | i = BN_get_flags(a, BN_FLG_MALLOCED0x01); | |||
141 | explicit_bzero(a, sizeof(BIGNUM)); | |||
142 | if (i) | |||
143 | free(a); | |||
144 | } | |||
145 | ||||
146 | void | |||
147 | BN_free(BIGNUM *a) | |||
148 | { | |||
149 | BN_clear_free(a); | |||
150 | } | |||
151 | ||||
152 | void | |||
153 | BN_set_params(int mult, int high, int low, int mont) | |||
154 | { | |||
155 | if (mult >= 0) { | |||
156 | if (mult > (int)(sizeof(int) * 8) - 1) | |||
157 | mult = sizeof(int) * 8 - 1; | |||
158 | bn_limit_bits = mult; | |||
159 | bn_limit_num = 1 << mult; | |||
160 | } | |||
161 | if (high >= 0) { | |||
162 | if (high > (int)(sizeof(int) * 8) - 1) | |||
163 | high = sizeof(int) * 8 - 1; | |||
164 | bn_limit_bits_high = high; | |||
165 | bn_limit_num_high = 1 << high; | |||
166 | } | |||
167 | if (low >= 0) { | |||
168 | if (low > (int)(sizeof(int) * 8) - 1) | |||
169 | low = sizeof(int) * 8 - 1; | |||
170 | bn_limit_bits_low = low; | |||
171 | bn_limit_num_low = 1 << low; | |||
172 | } | |||
173 | if (mont >= 0) { | |||
174 | if (mont > (int)(sizeof(int) * 8) - 1) | |||
175 | mont = sizeof(int) * 8 - 1; | |||
176 | bn_limit_bits_mont = mont; | |||
177 | bn_limit_num_mont = 1 << mont; | |||
178 | } | |||
179 | } | |||
180 | ||||
181 | int | |||
182 | BN_get_params(int which) | |||
183 | { | |||
184 | if (which == 0) | |||
185 | return (bn_limit_bits); | |||
186 | else if (which == 1) | |||
187 | return (bn_limit_bits_high); | |||
188 | else if (which == 2) | |||
189 | return (bn_limit_bits_low); | |||
190 | else if (which == 3) | |||
191 | return (bn_limit_bits_mont); | |||
192 | else | |||
193 | return (0); | |||
194 | } | |||
195 | #endif | |||
196 | ||||
197 | void | |||
198 | BN_set_flags(BIGNUM *b, int n) | |||
199 | { | |||
200 | b->flags |= n; | |||
201 | } | |||
202 | ||||
203 | int | |||
204 | BN_get_flags(const BIGNUM *b, int n) | |||
205 | { | |||
206 | return b->flags & n; | |||
207 | } | |||
208 | ||||
209 | void | |||
210 | BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags) | |||
211 | { | |||
212 | int dest_flags; | |||
213 | ||||
214 | dest_flags = (dest->flags & BN_FLG_MALLOCED0x01) | | |||
215 | (b->flags & ~BN_FLG_MALLOCED0x01) | BN_FLG_STATIC_DATA0x02 | flags; | |||
216 | ||||
217 | *dest = *b; | |||
218 | dest->flags = dest_flags; | |||
219 | } | |||
220 | ||||
221 | const BIGNUM * | |||
222 | BN_value_one(void) | |||
223 | { | |||
224 | static const BN_ULONGunsigned long data_one = 1L; | |||
225 | static const BIGNUM const_one = { | |||
226 | (BN_ULONGunsigned long *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA0x02 | |||
227 | }; | |||
228 | ||||
229 | return (&const_one); | |||
230 | } | |||
231 | ||||
232 | int | |||
233 | BN_num_bits_word(BN_ULONGunsigned long l) | |||
234 | { | |||
235 | BN_ULONGunsigned long x, mask; | |||
236 | int bits; | |||
237 | unsigned int shift; | |||
238 | ||||
239 | /* Constant time calculation of floor(log2(l)) + 1. */ | |||
240 | bits = (l != 0); | |||
241 | shift = BN_BITS432; /* On _LP64 this is 32, otherwise 16. */ | |||
242 | do { | |||
243 | x = l >> shift; | |||
244 | /* If x is 0, set mask to 0, otherwise set it to all 1s. */ | |||
245 | mask = ((~x & (x - 1)) >> (BN_BITS264 - 1)) - 1; | |||
246 | bits += shift & mask; | |||
247 | /* If x is 0, leave l alone, otherwise set l = x. */ | |||
248 | l ^= (x ^ l) & mask; | |||
249 | } while ((shift /= 2) != 0); | |||
250 | ||||
251 | return bits; | |||
252 | } | |||
253 | ||||
254 | int | |||
255 | BN_num_bits(const BIGNUM *a) | |||
256 | { | |||
257 | int i = a->top - 1; | |||
258 | ||||
259 | bn_check_top(a); | |||
260 | ||||
261 | if (BN_is_zero(a)) | |||
262 | return 0; | |||
263 | return ((i * BN_BITS264) + BN_num_bits_word(a->d[i])); | |||
264 | } | |||
265 | ||||
266 | /* This is used both by bn_expand2() and bn_dup_expand() */ | |||
267 | /* The caller MUST check that words > b->dmax before calling this */ | |||
268 | static BN_ULONGunsigned long * | |||
269 | bn_expand_internal(const BIGNUM *b, int words) | |||
270 | { | |||
271 | BN_ULONGunsigned long *A, *a = NULL((void *)0); | |||
272 | const BN_ULONGunsigned long *B; | |||
273 | int i; | |||
274 | ||||
275 | bn_check_top(b); | |||
276 | ||||
277 | if (words > (INT_MAX2147483647/(4*BN_BITS264))) { | |||
278 | BNerror(BN_R_BIGNUM_TOO_LONG)ERR_put_error(3,(0xfff),(114),"/usr/src/lib/libcrypto/bn/bn_lib.c" ,278); | |||
279 | return NULL((void *)0); | |||
280 | } | |||
281 | if (BN_get_flags(b, BN_FLG_STATIC_DATA0x02)) { | |||
282 | BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA)ERR_put_error(3,(0xfff),(105),"/usr/src/lib/libcrypto/bn/bn_lib.c" ,282); | |||
283 | return (NULL((void *)0)); | |||
284 | } | |||
285 | a = A = reallocarray(NULL((void *)0), words, sizeof(BN_ULONGunsigned long)); | |||
286 | if (A == NULL((void *)0)) { | |||
287 | BNerror(ERR_R_MALLOC_FAILURE)ERR_put_error(3,(0xfff),((1|64)),"/usr/src/lib/libcrypto/bn/bn_lib.c" ,287); | |||
288 | return (NULL((void *)0)); | |||
289 | } | |||
290 | #if 1 | |||
291 | B = b->d; | |||
292 | /* Check if the previous number needs to be copied */ | |||
293 | if (B != NULL((void *)0)) { | |||
294 | for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { | |||
295 | /* | |||
296 | * The fact that the loop is unrolled | |||
297 | * 4-wise is a tribute to Intel. It's | |||
298 | * the one that doesn't have enough | |||
299 | * registers to accommodate more data. | |||
300 | * I'd unroll it 8-wise otherwise:-) | |||
301 | * | |||
302 | * <appro@fy.chalmers.se> | |||
303 | */ | |||
304 | BN_ULONGunsigned long a0, a1, a2, a3; | |||
305 | a0 = B[0]; | |||
306 | a1 = B[1]; | |||
307 | a2 = B[2]; | |||
308 | a3 = B[3]; | |||
309 | A[0] = a0; | |||
310 | A[1] = a1; | |||
311 | A[2] = a2; | |||
312 | A[3] = a3; | |||
313 | } | |||
314 | switch (b->top & 3) { | |||
315 | case 3: | |||
316 | A[2] = B[2]; | |||
317 | case 2: | |||
318 | A[1] = B[1]; | |||
319 | case 1: | |||
320 | A[0] = B[0]; | |||
321 | } | |||
322 | } | |||
323 | ||||
324 | #else | |||
325 | memset(A, 0, sizeof(BN_ULONGunsigned long) * words); | |||
326 | memcpy(A, b->d, sizeof(b->d[0]) * b->top); | |||
327 | #endif | |||
328 | ||||
329 | return (a); | |||
330 | } | |||
331 | ||||
332 | /* This is an internal function that can be used instead of bn_expand2() | |||
333 | * when there is a need to copy BIGNUMs instead of only expanding the | |||
334 | * data part, while still expanding them. | |||
335 | * Especially useful when needing to expand BIGNUMs that are declared | |||
336 | * 'const' and should therefore not be changed. | |||
337 | * The reason to use this instead of a BN_dup() followed by a bn_expand2() | |||
338 | * is memory allocation overhead. A BN_dup() followed by a bn_expand2() | |||
339 | * will allocate new memory for the BIGNUM data twice, and free it once, | |||
340 | * while bn_dup_expand() makes sure allocation is made only once. | |||
341 | */ | |||
342 | ||||
343 | #ifndef OPENSSL_NO_DEPRECATED | |||
344 | BIGNUM * | |||
345 | bn_dup_expand(const BIGNUM *b, int words) | |||
346 | { | |||
347 | BIGNUM *r = NULL((void *)0); | |||
348 | ||||
349 | bn_check_top(b); | |||
350 | ||||
351 | /* This function does not work if | |||
352 | * words <= b->dmax && top < words | |||
353 | * because BN_dup() does not preserve 'dmax'! | |||
354 | * (But bn_dup_expand() is not used anywhere yet.) | |||
355 | */ | |||
356 | ||||
357 | if (words > b->dmax) { | |||
| ||||
358 | BN_ULONGunsigned long *a = bn_expand_internal(b, words); | |||
359 | ||||
360 | if (a) { | |||
361 | r = BN_new(); | |||
362 | if (r) { | |||
363 | r->top = b->top; | |||
364 | r->dmax = words; | |||
365 | r->neg = b->neg; | |||
366 | r->d = a; | |||
367 | } else { | |||
368 | /* r == NULL, BN_new failure */ | |||
369 | free(a); | |||
370 | } | |||
371 | } | |||
372 | /* If a == NULL, there was an error in allocation in | |||
373 | bn_expand_internal(), and NULL should be returned */ | |||
374 | } else { | |||
375 | r = BN_dup(b); | |||
376 | } | |||
377 | ||||
378 | bn_check_top(r); | |||
379 | return r; | |||
380 | } | |||
381 | #endif | |||
382 | ||||
383 | /* This is an internal function that should not be used in applications. | |||
384 | * It ensures that 'b' has enough room for a 'words' word number | |||
385 | * and initialises any unused part of b->d with leading zeros. | |||
386 | * It is mostly used by the various BIGNUM routines. If there is an error, | |||
387 | * NULL is returned. If not, 'b' is returned. */ | |||
388 | ||||
389 | BIGNUM * | |||
390 | bn_expand2(BIGNUM *b, int words) | |||
391 | { | |||
392 | bn_check_top(b); | |||
393 | ||||
394 | if (words > b->dmax) { | |||
395 | BN_ULONGunsigned long *a = bn_expand_internal(b, words); | |||
396 | if (!a) | |||
397 | return NULL((void *)0); | |||
398 | if (b->d) | |||
399 | freezero(b->d, b->dmax * sizeof(b->d[0])); | |||
400 | b->d = a; | |||
401 | b->dmax = words; | |||
402 | } | |||
403 | ||||
404 | /* None of this should be necessary because of what b->top means! */ | |||
405 | #if 0 | |||
406 | /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */ | |||
407 | if (b->top < b->dmax) { | |||
408 | int i; | |||
409 | BN_ULONGunsigned long *A = &(b->d[b->top]); | |||
410 | for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) { | |||
411 | A[0] = 0; | |||
412 | A[1] = 0; | |||
413 | A[2] = 0; | |||
414 | A[3] = 0; | |||
415 | A[4] = 0; | |||
416 | A[5] = 0; | |||
417 | A[6] = 0; | |||
418 | A[7] = 0; | |||
419 | } | |||
420 | for (i = (b->dmax - b->top)&7; i > 0; i--, A++) | |||
421 | A[0] = 0; | |||
422 | assert(A == &(b->d[b->dmax]))((void)0); | |||
423 | } | |||
424 | #endif | |||
425 | bn_check_top(b); | |||
426 | return b; | |||
427 | } | |||
428 | ||||
429 | BIGNUM * | |||
430 | BN_dup(const BIGNUM *a) | |||
431 | { | |||
432 | BIGNUM *t; | |||
433 | ||||
434 | if (a
| |||
435 | return NULL((void *)0); | |||
436 | bn_check_top(a); | |||
437 | ||||
438 | t = BN_new(); | |||
439 | if (t
| |||
440 | return NULL((void *)0); | |||
441 | if (!BN_copy(t, a)) { | |||
442 | BN_free(t); | |||
443 | return NULL((void *)0); | |||
444 | } | |||
445 | bn_check_top(t); | |||
446 | return t; | |||
447 | } | |||
448 | ||||
449 | BIGNUM * | |||
450 | BN_copy(BIGNUM *a, const BIGNUM *b) | |||
451 | { | |||
452 | int i; | |||
453 | BN_ULONGunsigned long *A; | |||
454 | const BN_ULONGunsigned long *B; | |||
455 | ||||
456 | bn_check_top(b); | |||
457 | ||||
458 | if (a
| |||
459 | return (a); | |||
460 | if (bn_wexpand(a, b->top)(((b->top) <= (a)->dmax)?(a):bn_expand2((a),(b->top ))) == NULL((void *)0)) | |||
461 | return (NULL((void *)0)); | |||
462 | ||||
463 | #if 1 | |||
464 | A = a->d; | |||
465 | B = b->d; | |||
466 | for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { | |||
467 | BN_ULONGunsigned long a0, a1, a2, a3; | |||
468 | a0 = B[0]; | |||
469 | a1 = B[1]; | |||
470 | a2 = B[2]; | |||
471 | a3 = B[3]; | |||
472 | A[0] = a0; | |||
473 | A[1] = a1; | |||
474 | A[2] = a2; | |||
475 | A[3] = a3; | |||
476 | } | |||
477 | switch (b->top & 3) { | |||
478 | case 3: | |||
479 | A[2] = B[2]; | |||
480 | case 2: | |||
481 | A[1] = B[1]; | |||
482 | case 1: | |||
483 | A[0] = B[0]; | |||
| ||||
484 | } | |||
485 | #else | |||
486 | memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); | |||
487 | #endif | |||
488 | ||||
489 | a->top = b->top; | |||
490 | a->neg = b->neg; | |||
491 | bn_check_top(a); | |||
492 | return (a); | |||
493 | } | |||
494 | ||||
495 | void | |||
496 | BN_swap(BIGNUM *a, BIGNUM *b) | |||
497 | { | |||
498 | int flags_old_a, flags_old_b; | |||
499 | BN_ULONGunsigned long *tmp_d; | |||
500 | int tmp_top, tmp_dmax, tmp_neg; | |||
501 | ||||
502 | bn_check_top(a); | |||
503 | bn_check_top(b); | |||
504 | ||||
505 | flags_old_a = a->flags; | |||
506 | flags_old_b = b->flags; | |||
507 | ||||
508 | tmp_d = a->d; | |||
509 | tmp_top = a->top; | |||
510 | tmp_dmax = a->dmax; | |||
511 | tmp_neg = a->neg; | |||
512 | ||||
513 | a->d = b->d; | |||
514 | a->top = b->top; | |||
515 | a->dmax = b->dmax; | |||
516 | a->neg = b->neg; | |||
517 | ||||
518 | b->d = tmp_d; | |||
519 | b->top = tmp_top; | |||
520 | b->dmax = tmp_dmax; | |||
521 | b->neg = tmp_neg; | |||
522 | ||||
523 | a->flags = (flags_old_a & BN_FLG_MALLOCED0x01) | | |||
524 | (flags_old_b & BN_FLG_STATIC_DATA0x02); | |||
525 | b->flags = (flags_old_b & BN_FLG_MALLOCED0x01) | | |||
526 | (flags_old_a & BN_FLG_STATIC_DATA0x02); | |||
527 | bn_check_top(a); | |||
528 | bn_check_top(b); | |||
529 | } | |||
530 | ||||
531 | BN_ULONGunsigned long | |||
532 | BN_get_word(const BIGNUM *a) | |||
533 | { | |||
534 | if (a->top > 1) | |||
535 | return BN_MASK2(0xffffffffffffffffL); | |||
536 | else if (a->top == 1) | |||
537 | return a->d[0]; | |||
538 | /* a->top == 0 */ | |||
539 | return 0; | |||
540 | } | |||
541 | ||||
542 | BIGNUM * | |||
543 | bn_expand(BIGNUM *a, int bits) | |||
544 | { | |||
545 | if (bits > (INT_MAX2147483647 - BN_BITS264 + 1)) | |||
546 | return (NULL((void *)0)); | |||
547 | ||||
548 | if (((bits + BN_BITS264 - 1) / BN_BITS264) <= a->dmax) | |||
549 | return (a); | |||
550 | ||||
551 | return bn_expand2(a, (bits + BN_BITS264 - 1) / BN_BITS264); | |||
552 | } | |||
553 | ||||
554 | int | |||
555 | BN_set_word(BIGNUM *a, BN_ULONGunsigned long w) | |||
556 | { | |||
557 | bn_check_top(a); | |||
558 | if (bn_expand(a, (int)sizeof(BN_ULONGunsigned long) * 8) == NULL((void *)0)) | |||
559 | return (0); | |||
560 | a->neg = 0; | |||
561 | a->d[0] = w; | |||
562 | a->top = (w ? 1 : 0); | |||
563 | bn_check_top(a); | |||
564 | return (1); | |||
565 | } | |||
566 | ||||
567 | BIGNUM * | |||
568 | BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) | |||
569 | { | |||
570 | unsigned int i, m; | |||
571 | unsigned int n; | |||
572 | BN_ULONGunsigned long l; | |||
573 | BIGNUM *bn = NULL((void *)0); | |||
574 | ||||
575 | if (len < 0) | |||
576 | return (NULL((void *)0)); | |||
577 | if (ret == NULL((void *)0)) | |||
578 | ret = bn = BN_new(); | |||
579 | if (ret == NULL((void *)0)) | |||
580 | return (NULL((void *)0)); | |||
581 | bn_check_top(ret); | |||
582 | l = 0; | |||
583 | n = len; | |||
584 | if (n == 0) { | |||
585 | ret->top = 0; | |||
586 | return (ret); | |||
587 | } | |||
588 | i = ((n - 1) / BN_BYTES8) + 1; | |||
589 | m = ((n - 1) % (BN_BYTES8)); | |||
590 | if (bn_wexpand(ret, (int)i)((((int)i) <= (ret)->dmax)?(ret):bn_expand2((ret),((int )i))) == NULL((void *)0)) { | |||
591 | BN_free(bn); | |||
592 | return NULL((void *)0); | |||
593 | } | |||
594 | ret->top = i; | |||
595 | ret->neg = 0; | |||
596 | while (n--) { | |||
597 | l = (l << 8L) | *(s++); | |||
598 | if (m-- == 0) { | |||
599 | ret->d[--i] = l; | |||
600 | l = 0; | |||
601 | m = BN_BYTES8 - 1; | |||
602 | } | |||
603 | } | |||
604 | /* need to call this due to clear byte at top if avoiding | |||
605 | * having the top bit set (-ve number) */ | |||
606 | bn_correct_top(ret){ unsigned long *ftl; int tmp_top = (ret)->top; if (tmp_top > 0) { for (ftl= &((ret)->d[tmp_top-1]); tmp_top > 0; tmp_top--) if (*(ftl--)) break; (ret)->top = tmp_top; } ; }; | |||
607 | return (ret); | |||
608 | } | |||
609 | ||||
610 | typedef enum { | |||
611 | big, | |||
612 | little, | |||
613 | } endianness_t; | |||
614 | ||||
615 | /* ignore negative */ | |||
616 | static int | |||
617 | bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness) | |||
618 | { | |||
619 | int n; | |||
620 | size_t i, lasti, j, atop, mask; | |||
621 | BN_ULONGunsigned long l; | |||
622 | ||||
623 | /* | |||
624 | * In case |a| is fixed-top, BN_num_bytes can return bogus length, | |||
625 | * but it's assumed that fixed-top inputs ought to be "nominated" | |||
626 | * even for padded output, so it works out... | |||
627 | */ | |||
628 | n = BN_num_bytes(a)((BN_num_bits(a)+7)/8); | |||
629 | if (tolen == -1) | |||
630 | tolen = n; | |||
631 | else if (tolen < n) { /* uncommon/unlike case */ | |||
632 | BIGNUM temp = *a; | |||
633 | ||||
634 | bn_correct_top(&temp){ unsigned long *ftl; int tmp_top = (&temp)->top; if ( tmp_top > 0) { for (ftl= &((&temp)->d[tmp_top-1 ]); tmp_top > 0; tmp_top--) if (*(ftl--)) break; (&temp )->top = tmp_top; } ; }; | |||
635 | ||||
636 | n = BN_num_bytes(&temp)((BN_num_bits(&temp)+7)/8); | |||
637 | if (tolen < n) | |||
638 | return -1; | |||
639 | } | |||
640 | ||||
641 | /* Swipe through whole available data and don't give away padded zero. */ | |||
642 | atop = a->dmax * BN_BYTES8; | |||
643 | if (atop == 0) { | |||
644 | explicit_bzero(to, tolen); | |||
645 | return tolen; | |||
646 | } | |||
647 | ||||
648 | lasti = atop - 1; | |||
649 | atop = a->top * BN_BYTES8; | |||
650 | ||||
651 | if (endianness == big) | |||
652 | to += tolen; /* start from the end of the buffer */ | |||
653 | ||||
654 | for (i = 0, j = 0; j < (size_t)tolen; j++) { | |||
655 | unsigned char val; | |||
656 | ||||
657 | l = a->d[i / BN_BYTES8]; | |||
658 | mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); | |||
659 | val = (unsigned char)(l >> (8 * (i % BN_BYTES8)) & mask); | |||
660 | ||||
661 | if (endianness == big) | |||
662 | *--to = val; | |||
663 | else | |||
664 | *to++ = val; | |||
665 | ||||
666 | i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ | |||
667 | } | |||
668 | ||||
669 | return tolen; | |||
670 | } | |||
671 | ||||
672 | int | |||
673 | BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) | |||
674 | { | |||
675 | if (tolen < 0) | |||
676 | return -1; | |||
677 | return bn2binpad(a, to, tolen, big); | |||
678 | } | |||
679 | ||||
680 | int | |||
681 | BN_bn2bin(const BIGNUM *a, unsigned char *to) | |||
682 | { | |||
683 | return bn2binpad(a, to, -1, big); | |||
684 | } | |||
685 | ||||
686 | BIGNUM * | |||
687 | BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) | |||
688 | { | |||
689 | unsigned int i, m, n; | |||
690 | BN_ULONGunsigned long l; | |||
691 | BIGNUM *bn = NULL((void *)0); | |||
692 | ||||
693 | if (ret == NULL((void *)0)) | |||
694 | ret = bn = BN_new(); | |||
695 | if (ret == NULL((void *)0)) | |||
696 | return NULL((void *)0); | |||
697 | ||||
698 | bn_check_top(ret); | |||
699 | ||||
700 | s += len; | |||
701 | /* Skip trailing zeroes. */ | |||
702 | for (; len > 0 && s[-1] == 0; s--, len--) | |||
703 | continue; | |||
704 | ||||
705 | n = len; | |||
706 | if (n == 0) { | |||
707 | ret->top = 0; | |||
708 | return ret; | |||
709 | } | |||
710 | ||||
711 | i = ((n - 1) / BN_BYTES8) + 1; | |||
712 | m = (n - 1) % BN_BYTES8; | |||
713 | if (bn_wexpand(ret, (int)i)((((int)i) <= (ret)->dmax)?(ret):bn_expand2((ret),((int )i))) == NULL((void *)0)) { | |||
714 | BN_free(bn); | |||
715 | return NULL((void *)0); | |||
716 | } | |||
717 | ||||
718 | ret->top = i; | |||
719 | ret->neg = 0; | |||
720 | l = 0; | |||
721 | while (n-- > 0) { | |||
722 | s--; | |||
723 | l = (l << 8L) | *s; | |||
724 | if (m-- == 0) { | |||
725 | ret->d[--i] = l; | |||
726 | l = 0; | |||
727 | m = BN_BYTES8 - 1; | |||
728 | } | |||
729 | } | |||
730 | ||||
731 | /* | |||
732 | * need to call this due to clear byte at top if avoiding having the | |||
733 | * top bit set (-ve number) | |||
734 | */ | |||
735 | bn_correct_top(ret){ unsigned long *ftl; int tmp_top = (ret)->top; if (tmp_top > 0) { for (ftl= &((ret)->d[tmp_top-1]); tmp_top > 0; tmp_top--) if (*(ftl--)) break; (ret)->top = tmp_top; } ; }; | |||
736 | ||||
737 | return ret; | |||
738 | } | |||
739 | ||||
740 | int | |||
741 | BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) | |||
742 | { | |||
743 | if (tolen < 0) | |||
744 | return -1; | |||
745 | ||||
746 | return bn2binpad(a, to, tolen, little); | |||
747 | } | |||
748 | ||||
749 | int | |||
750 | BN_ucmp(const BIGNUM *a, const BIGNUM *b) | |||
751 | { | |||
752 | int i; | |||
753 | BN_ULONGunsigned long t1, t2, *ap, *bp; | |||
754 | ||||
755 | bn_check_top(a); | |||
756 | bn_check_top(b); | |||
757 | ||||
758 | i = a->top - b->top; | |||
759 | if (i != 0) | |||
760 | return (i); | |||
761 | ap = a->d; | |||
762 | bp = b->d; | |||
763 | for (i = a->top - 1; i >= 0; i--) { | |||
764 | t1 = ap[i]; | |||
765 | t2 = bp[i]; | |||
766 | if (t1 != t2) | |||
767 | return ((t1 > t2) ? 1 : -1); | |||
768 | } | |||
769 | return (0); | |||
770 | } | |||
771 | ||||
772 | int | |||
773 | BN_cmp(const BIGNUM *a, const BIGNUM *b) | |||
774 | { | |||
775 | int i; | |||
776 | int gt, lt; | |||
777 | BN_ULONGunsigned long t1, t2; | |||
778 | ||||
779 | if ((a == NULL((void *)0)) || (b == NULL((void *)0))) { | |||
780 | if (a != NULL((void *)0)) | |||
781 | return (-1); | |||
782 | else if (b != NULL((void *)0)) | |||
783 | return (1); | |||
784 | else | |||
785 | return (0); | |||
786 | } | |||
787 | ||||
788 | bn_check_top(a); | |||
789 | bn_check_top(b); | |||
790 | ||||
791 | if (a->neg != b->neg) { | |||
792 | if (a->neg) | |||
793 | return (-1); | |||
794 | else | |||
795 | return (1); | |||
796 | } | |||
797 | if (a->neg == 0) { | |||
798 | gt = 1; | |||
799 | lt = -1; | |||
800 | } else { | |||
801 | gt = -1; | |||
802 | lt = 1; | |||
803 | } | |||
804 | ||||
805 | if (a->top > b->top) | |||
806 | return (gt); | |||
807 | if (a->top < b->top) | |||
808 | return (lt); | |||
809 | for (i = a->top - 1; i >= 0; i--) { | |||
810 | t1 = a->d[i]; | |||
811 | t2 = b->d[i]; | |||
812 | if (t1 > t2) | |||
813 | return (gt); | |||
814 | if (t1 < t2) | |||
815 | return (lt); | |||
816 | } | |||
817 | return (0); | |||
818 | } | |||
819 | ||||
820 | int | |||
821 | BN_set_bit(BIGNUM *a, int n) | |||
822 | { | |||
823 | int i, j, k; | |||
824 | ||||
825 | if (n < 0) | |||
826 | return 0; | |||
827 | ||||
828 | i = n / BN_BITS264; | |||
829 | j = n % BN_BITS264; | |||
830 | if (a->top <= i) { | |||
831 | if (bn_wexpand(a, i + 1)(((i + 1) <= (a)->dmax)?(a):bn_expand2((a),(i + 1))) == NULL((void *)0)) | |||
832 | return (0); | |||
833 | for (k = a->top; k < i + 1; k++) | |||
834 | a->d[k] = 0; | |||
835 | a->top = i + 1; | |||
836 | } | |||
837 | ||||
838 | a->d[i] |= (((BN_ULONGunsigned long)1) << j); | |||
839 | bn_check_top(a); | |||
840 | return (1); | |||
841 | } | |||
842 | ||||
843 | int | |||
844 | BN_clear_bit(BIGNUM *a, int n) | |||
845 | { | |||
846 | int i, j; | |||
847 | ||||
848 | bn_check_top(a); | |||
849 | if (n < 0) | |||
850 | return 0; | |||
851 | ||||
852 | i = n / BN_BITS264; | |||
853 | j = n % BN_BITS264; | |||
854 | if (a->top <= i) | |||
855 | return (0); | |||
856 | ||||
857 | a->d[i] &= (~(((BN_ULONGunsigned long)1) << j)); | |||
858 | bn_correct_top(a){ unsigned long *ftl; int tmp_top = (a)->top; if (tmp_top > 0) { for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top --) if (*(ftl--)) break; (a)->top = tmp_top; } ; }; | |||
859 | return (1); | |||
860 | } | |||
861 | ||||
862 | int | |||
863 | BN_is_bit_set(const BIGNUM *a, int n) | |||
864 | { | |||
865 | int i, j; | |||
866 | ||||
867 | bn_check_top(a); | |||
868 | if (n < 0) | |||
869 | return 0; | |||
870 | i = n / BN_BITS264; | |||
871 | j = n % BN_BITS264; | |||
872 | if (a->top <= i) | |||
873 | return 0; | |||
874 | return (int)(((a->d[i]) >> j) & ((BN_ULONGunsigned long)1)); | |||
875 | } | |||
876 | ||||
877 | int | |||
878 | BN_mask_bits(BIGNUM *a, int n) | |||
879 | { | |||
880 | int b, w; | |||
881 | ||||
882 | bn_check_top(a); | |||
883 | if (n < 0) | |||
884 | return 0; | |||
885 | ||||
886 | w = n / BN_BITS264; | |||
887 | b = n % BN_BITS264; | |||
888 | if (w >= a->top) | |||
889 | return 0; | |||
890 | if (b == 0) | |||
891 | a->top = w; | |||
892 | else { | |||
893 | a->top = w + 1; | |||
894 | a->d[w] &= ~(BN_MASK2(0xffffffffffffffffL) << b); | |||
895 | } | |||
896 | bn_correct_top(a){ unsigned long *ftl; int tmp_top = (a)->top; if (tmp_top > 0) { for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top --) if (*(ftl--)) break; (a)->top = tmp_top; } ; }; | |||
897 | return (1); | |||
898 | } | |||
899 | ||||
900 | void | |||
901 | BN_set_negative(BIGNUM *a, int b) | |||
902 | { | |||
903 | if (b && !BN_is_zero(a)) | |||
904 | a->neg = 1; | |||
905 | else | |||
906 | a->neg = 0; | |||
907 | } | |||
908 | ||||
909 | int | |||
910 | bn_cmp_words(const BN_ULONGunsigned long *a, const BN_ULONGunsigned long *b, int n) | |||
911 | { | |||
912 | int i; | |||
913 | BN_ULONGunsigned long aa, bb; | |||
914 | ||||
915 | aa = a[n - 1]; | |||
916 | bb = b[n - 1]; | |||
917 | if (aa != bb) | |||
918 | return ((aa > bb) ? 1 : -1); | |||
919 | for (i = n - 2; i >= 0; i--) { | |||
920 | aa = a[i]; | |||
921 | bb = b[i]; | |||
922 | if (aa != bb) | |||
923 | return ((aa > bb) ? 1 : -1); | |||
924 | } | |||
925 | return (0); | |||
926 | } | |||
927 | ||||
928 | /* Here follows a specialised variants of bn_cmp_words(). It has the | |||
929 | property of performing the operation on arrays of different sizes. | |||
930 | The sizes of those arrays is expressed through cl, which is the | |||
931 | common length ( basicall, min(len(a),len(b)) ), and dl, which is the | |||
932 | delta between the two lengths, calculated as len(a)-len(b). | |||
933 | All lengths are the number of BN_ULONGs... */ | |||
934 | ||||
935 | int | |||
936 | bn_cmp_part_words(const BN_ULONGunsigned long *a, const BN_ULONGunsigned long *b, int cl, int dl) | |||
937 | { | |||
938 | int n, i; | |||
939 | ||||
940 | n = cl - 1; | |||
941 | ||||
942 | if (dl < 0) { | |||
943 | for (i = dl; i < 0; i++) { | |||
944 | if (b[n - i] != 0) | |||
945 | return -1; /* a < b */ | |||
946 | } | |||
947 | } | |||
948 | if (dl > 0) { | |||
949 | for (i = dl; i > 0; i--) { | |||
950 | if (a[n + i] != 0) | |||
951 | return 1; /* a > b */ | |||
952 | } | |||
953 | } | |||
954 | return bn_cmp_words(a, b, cl); | |||
955 | } | |||
956 | ||||
957 | /* | |||
958 | * Constant-time conditional swap of a and b. | |||
959 | * a and b are swapped if condition is not 0. | |||
960 | * The code assumes that at most one bit of condition is set. | |||
961 | * nwords is the number of words to swap. | |||
962 | * The code assumes that at least nwords are allocated in both a and b, | |||
963 | * and that no more than nwords are used by either a or b. | |||
964 | * a and b cannot be the same number | |||
965 | */ | |||
966 | void | |||
967 | BN_consttime_swap(BN_ULONGunsigned long condition, BIGNUM *a, BIGNUM *b, int nwords) | |||
968 | { | |||
969 | BN_ULONGunsigned long t; | |||
970 | int i; | |||
971 | ||||
972 | bn_wcheck_size(a, nwords); | |||
973 | bn_wcheck_size(b, nwords); | |||
974 | ||||
975 | assert(a != b)((void)0); | |||
976 | assert((condition & (condition - 1)) == 0)((void)0); | |||
977 | assert(sizeof(BN_ULONG) >= sizeof(int))((void)0); | |||
978 | ||||
979 | condition = ((condition - 1) >> (BN_BITS264 - 1)) - 1; | |||
980 | ||||
981 | t = (a->top^b->top) & condition; | |||
982 | a->top ^= t; | |||
983 | b->top ^= t; | |||
984 | ||||
985 | #define BN_CONSTTIME_SWAP(ind) \ | |||
986 | do { \ | |||
987 | t = (a->d[ind] ^ b->d[ind]) & condition; \ | |||
988 | a->d[ind] ^= t; \ | |||
989 | b->d[ind] ^= t; \ | |||
990 | } while (0) | |||
991 | ||||
992 | ||||
993 | switch (nwords) { | |||
994 | default: | |||
995 | for (i = 10; i < nwords; i++) | |||
996 | BN_CONSTTIME_SWAP(i); | |||
997 | /* Fallthrough */ | |||
998 | case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ | |||
999 | case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ | |||
1000 | case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ | |||
1001 | case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ | |||
1002 | case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ | |||
1003 | case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ | |||
1004 | case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ | |||
1005 | case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ | |||
1006 | case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ | |||
1007 | case 1: | |||
1008 | BN_CONSTTIME_SWAP(0); | |||
1009 | } | |||
1010 | #undef BN_CONSTTIME_SWAP | |||
1011 | } | |||
1012 | ||||
1013 | /* | |||
1014 | * Constant-time conditional swap of a and b. | |||
1015 | * a and b are swapped if condition is not 0. | |||
1016 | * nwords is the number of words to swap. | |||
1017 | */ | |||
1018 | int | |||
1019 | BN_swap_ct(BN_ULONGunsigned long condition, BIGNUM *a, BIGNUM *b, size_t nwords) | |||
1020 | { | |||
1021 | BN_ULONGunsigned long t; | |||
1022 | int i, words; | |||
1023 | ||||
1024 | if (a == b) | |||
1025 | return 1; | |||
1026 | if (nwords > INT_MAX2147483647) | |||
1027 | return 0; | |||
1028 | words = (int)nwords; | |||
1029 | if (bn_wexpand(a, words)(((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) == NULL((void *)0) || bn_wexpand(b, words)(((words) <= (b)->dmax)?(b):bn_expand2((b),(words))) == NULL((void *)0)) | |||
1030 | return 0; | |||
1031 | if (a->top > words || b->top > words) { | |||
1032 | BNerror(BN_R_INVALID_LENGTH)ERR_put_error(3,(0xfff),(106),"/usr/src/lib/libcrypto/bn/bn_lib.c" ,1032); | |||
1033 | return 0; | |||
1034 | } | |||
1035 | ||||
1036 | /* Set condition to 0 (if it was zero) or all 1s otherwise. */ | |||
1037 | condition = ((~condition & (condition - 1)) >> (BN_BITS264 - 1)) - 1; | |||
1038 | ||||
1039 | /* swap top field */ | |||
1040 | t = (a->top ^ b->top) & condition; | |||
1041 | a->top ^= t; | |||
1042 | b->top ^= t; | |||
1043 | ||||
1044 | /* swap neg field */ | |||
1045 | t = (a->neg ^ b->neg) & condition; | |||
1046 | a->neg ^= t; | |||
1047 | b->neg ^= t; | |||
1048 | ||||
1049 | /* swap BN_FLG_CONSTTIME from flag field */ | |||
1050 | t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME0x04) & condition; | |||
1051 | a->flags ^= t; | |||
1052 | b->flags ^= t; | |||
1053 | ||||
1054 | /* swap the data */ | |||
1055 | for (i = 0; i < words; i++) { | |||
1056 | t = (a->d[i] ^ b->d[i]) & condition; | |||
1057 | a->d[i] ^= t; | |||
1058 | b->d[i] ^= t; | |||
1059 | } | |||
1060 | ||||
1061 | return 1; | |||
1062 | } | |||
1063 | ||||
1064 | void | |||
1065 | BN_zero_ex(BIGNUM *a) | |||
1066 | { | |||
1067 | a->neg = 0; | |||
1068 | a->top = 0; | |||
1069 | /* XXX: a->flags &= ~BN_FIXED_TOP */ | |||
1070 | } | |||
1071 | ||||
1072 | int | |||
1073 | BN_abs_is_word(const BIGNUM *a, const BN_ULONGunsigned long w) | |||
1074 | { | |||
1075 | return (a->top == 1 && a->d[0] == w) || (w == 0 && a->top == 0); | |||
1076 | } | |||
1077 | ||||
1078 | int | |||
1079 | BN_is_zero(const BIGNUM *a) | |||
1080 | { | |||
1081 | return a->top == 0; | |||
1082 | } | |||
1083 | ||||
1084 | int | |||
1085 | BN_is_one(const BIGNUM *a) | |||
1086 | { | |||
1087 | return BN_abs_is_word(a, 1) && !a->neg; | |||
1088 | } | |||
1089 | ||||
1090 | int | |||
1091 | BN_is_word(const BIGNUM *a, const BN_ULONGunsigned long w) | |||
1092 | { | |||
1093 | return BN_abs_is_word(a, w) && (w == 0 || !a->neg); | |||
1094 | } | |||
1095 | ||||
1096 | int | |||
1097 | BN_is_odd(const BIGNUM *a) | |||
1098 | { | |||
1099 | return a->top > 0 && (a->d[0] & 1); | |||
1100 | } | |||
1101 | ||||
1102 | int | |||
1103 | BN_is_negative(const BIGNUM *a) | |||
1104 | { | |||
1105 | return a->neg != 0; | |||
1106 | } | |||
1107 | ||||
1108 | BN_GENCB * | |||
1109 | BN_GENCB_new(void) | |||
1110 | { | |||
1111 | BN_GENCB *cb; | |||
1112 | ||||
1113 | if ((cb = calloc(1, sizeof(*cb))) == NULL((void *)0)) | |||
1114 | return NULL((void *)0); | |||
1115 | ||||
1116 | return cb; | |||
1117 | } | |||
1118 | ||||
1119 | void | |||
1120 | BN_GENCB_free(BN_GENCB *cb) | |||
1121 | { | |||
1122 | if (cb == NULL((void *)0)) | |||
1123 | return; | |||
1124 | free(cb); | |||
1125 | } | |||
1126 | ||||
1127 | /* Populate a BN_GENCB structure with an "old"-style callback */ | |||
1128 | void | |||
1129 | BN_GENCB_set_old(BN_GENCB *gencb, void (*cb)(int, int, void *), void *cb_arg) | |||
1130 | { | |||
1131 | gencb->ver = 1; | |||
1132 | gencb->cb.cb_1 = cb; | |||
1133 | gencb->arg = cb_arg; | |||
1134 | } | |||
1135 | ||||
1136 | /* Populate a BN_GENCB structure with a "new"-style callback */ | |||
1137 | void | |||
1138 | BN_GENCB_set(BN_GENCB *gencb, int (*cb)(int, int, BN_GENCB *), void *cb_arg) | |||
1139 | { | |||
1140 | gencb->ver = 2; | |||
1141 | gencb->cb.cb_2 = cb; | |||
1142 | gencb->arg = cb_arg; | |||
1143 | } | |||
1144 | ||||
1145 | void * | |||
1146 | BN_GENCB_get_arg(BN_GENCB *cb) | |||
1147 | { | |||
1148 | return cb->arg; | |||
1149 | } |