]>
Commit | Line | Data |
---|---|---|
4f22f405 | 1 | /* |
da1c088f | 2 | * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
367ace68 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
4f22f405 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
d02b48c6 RE |
8 | */ |
9 | ||
bbb8de09 | 10 | #include <assert.h> |
addb309a | 11 | #include <limits.h> |
b39fc560 | 12 | #include "internal/cryptlib.h" |
310a0edb | 13 | #include "internal/endian.h" |
706457b7 | 14 | #include "bn_local.h" |
98186eb4 | 15 | #include <openssl/opensslconf.h> |
706457b7 | 16 | #include "internal/constant_time.h" |
d02b48c6 | 17 | |
df11e1e9 | 18 | /* This stuff appears to be completely unused, so is deprecated */ |
00db8c60 | 19 | #ifndef OPENSSL_NO_DEPRECATED_0_9_8 |
1d97c843 TH |
20 | /*- |
21 | * For a 32 bit machine | |
dfeab068 RE |
22 | * 2 - 4 == 128 |
23 | * 3 - 8 == 256 | |
24 | * 4 - 16 == 512 | |
25 | * 5 - 32 == 1024 | |
26 | * 6 - 64 == 2048 | |
27 | * 7 - 128 == 4096 | |
28 | * 8 - 256 == 8192 | |
29 | */ | |
0f113f3e MC |
30 | static int bn_limit_bits = 0; |
31 | static int bn_limit_num = 8; /* (1<<bn_limit_bits) */ | |
32 | static int bn_limit_bits_low = 0; | |
33 | static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */ | |
34 | static int bn_limit_bits_high = 0; | |
35 | static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */ | |
36 | static int bn_limit_bits_mont = 0; | |
37 | static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */ | |
dfeab068 | 38 | |
6b691a5c | 39 | void BN_set_params(int mult, int high, int low, int mont) |
0f113f3e MC |
40 | { |
41 | if (mult >= 0) { | |
42 | if (mult > (int)(sizeof(int) * 8) - 1) | |
43 | mult = sizeof(int) * 8 - 1; | |
44 | bn_limit_bits = mult; | |
45 | bn_limit_num = 1 << mult; | |
46 | } | |
47 | if (high >= 0) { | |
48 | if (high > (int)(sizeof(int) * 8) - 1) | |
49 | high = sizeof(int) * 8 - 1; | |
50 | bn_limit_bits_high = high; | |
51 | bn_limit_num_high = 1 << high; | |
52 | } | |
53 | if (low >= 0) { | |
54 | if (low > (int)(sizeof(int) * 8) - 1) | |
55 | low = sizeof(int) * 8 - 1; | |
56 | bn_limit_bits_low = low; | |
57 | bn_limit_num_low = 1 << low; | |
58 | } | |
59 | if (mont >= 0) { | |
60 | if (mont > (int)(sizeof(int) * 8) - 1) | |
61 | mont = sizeof(int) * 8 - 1; | |
62 | bn_limit_bits_mont = mont; | |
63 | bn_limit_num_mont = 1 << mont; | |
64 | } | |
65 | } | |
dfeab068 | 66 | |
6b691a5c | 67 | int BN_get_params(int which) |
0f113f3e MC |
68 | { |
69 | if (which == 0) | |
26a7d938 | 70 | return bn_limit_bits; |
0f113f3e | 71 | else if (which == 1) |
26a7d938 | 72 | return bn_limit_bits_high; |
0f113f3e | 73 | else if (which == 2) |
26a7d938 | 74 | return bn_limit_bits_low; |
0f113f3e | 75 | else if (which == 3) |
26a7d938 | 76 | return bn_limit_bits_mont; |
0f113f3e | 77 | else |
26a7d938 | 78 | return 0; |
0f113f3e | 79 | } |
df11e1e9 | 80 | #endif |
d02b48c6 | 81 | |
98499135 | 82 | const BIGNUM *BN_value_one(void) |
0f113f3e MC |
83 | { |
84 | static const BN_ULONG data_one = 1L; | |
85 | static const BIGNUM const_one = | |
86 | { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA }; | |
d02b48c6 | 87 | |
26a7d938 | 88 | return &const_one; |
0f113f3e | 89 | } |
d02b48c6 | 90 | |
7a09fab2 | 91 | /* |
92 | * Old Visual Studio ARM compiler miscompiles BN_num_bits_word() | |
93 | * https://mta.openssl.org/pipermail/openssl-users/2018-August/008465.html | |
94 | */ | |
95 | #if defined(_MSC_VER) && defined(_ARM_) && defined(_WIN32_WCE) \ | |
96 | && _MSC_VER>=1400 && _MSC_VER<1501 | |
97 | # define MS_BROKEN_BN_num_bits_word | |
98 | # pragma optimize("", off) | |
99 | #endif | |
6b691a5c | 100 | int BN_num_bits_word(BN_ULONG l) |
0f113f3e | 101 | { |
972c87df DB |
102 | BN_ULONG x, mask; |
103 | int bits = (l != 0); | |
104 | ||
105 | #if BN_BITS2 > 32 | |
106 | x = l >> 32; | |
107 | mask = (0 - x) & BN_MASK2; | |
108 | mask = (0 - (mask >> (BN_BITS2 - 1))); | |
109 | bits += 32 & mask; | |
110 | l ^= (x ^ l) & mask; | |
d02b48c6 | 111 | #endif |
972c87df DB |
112 | |
113 | x = l >> 16; | |
114 | mask = (0 - x) & BN_MASK2; | |
115 | mask = (0 - (mask >> (BN_BITS2 - 1))); | |
116 | bits += 16 & mask; | |
117 | l ^= (x ^ l) & mask; | |
118 | ||
119 | x = l >> 8; | |
120 | mask = (0 - x) & BN_MASK2; | |
121 | mask = (0 - (mask >> (BN_BITS2 - 1))); | |
122 | bits += 8 & mask; | |
123 | l ^= (x ^ l) & mask; | |
124 | ||
125 | x = l >> 4; | |
126 | mask = (0 - x) & BN_MASK2; | |
127 | mask = (0 - (mask >> (BN_BITS2 - 1))); | |
128 | bits += 4 & mask; | |
129 | l ^= (x ^ l) & mask; | |
130 | ||
131 | x = l >> 2; | |
132 | mask = (0 - x) & BN_MASK2; | |
133 | mask = (0 - (mask >> (BN_BITS2 - 1))); | |
134 | bits += 2 & mask; | |
135 | l ^= (x ^ l) & mask; | |
136 | ||
137 | x = l >> 1; | |
138 | mask = (0 - x) & BN_MASK2; | |
139 | mask = (0 - (mask >> (BN_BITS2 - 1))); | |
140 | bits += 1 & mask; | |
141 | ||
142 | return bits; | |
0f113f3e | 143 | } |
7a09fab2 | 144 | #ifdef MS_BROKEN_BN_num_bits_word |
145 | # pragma optimize("", on) | |
146 | #endif | |
d02b48c6 | 147 | |
8b44198b NT |
148 | /* |
149 | * This function still leaks `a->dmax`: it's caller's responsibility to | |
150 | * expand the input `a` in advance to a public length. | |
151 | */ | |
152 | static ossl_inline | |
153 | int bn_num_bits_consttime(const BIGNUM *a) | |
154 | { | |
155 | int j, ret; | |
156 | unsigned int mask, past_i; | |
157 | int i = a->top - 1; | |
158 | bn_check_top(a); | |
159 | ||
160 | for (j = 0, past_i = 0, ret = 0; j < a->dmax; j++) { | |
161 | mask = constant_time_eq_int(i, j); /* 0xff..ff if i==j, 0x0 otherwise */ | |
162 | ||
163 | ret += BN_BITS2 & (~mask & ~past_i); | |
164 | ret += BN_num_bits_word(a->d[j]) & mask; | |
165 | ||
166 | past_i |= mask; /* past_i will become 0xff..ff after i==j */ | |
167 | } | |
168 | ||
169 | /* | |
170 | * if BN_is_zero(a) => i is -1 and ret contains garbage, so we mask the | |
171 | * final result. | |
172 | */ | |
173 | mask = ~(constant_time_eq_int(i, ((int)-1))); | |
174 | ||
175 | return ret & mask; | |
176 | } | |
177 | ||
84c15db5 | 178 | int BN_num_bits(const BIGNUM *a) |
0f113f3e MC |
179 | { |
180 | int i = a->top - 1; | |
181 | bn_check_top(a); | |
dfeab068 | 182 | |
8b44198b NT |
183 | if (a->flags & BN_FLG_CONSTTIME) { |
184 | /* | |
185 | * We assume that BIGNUMs flagged as CONSTTIME have also been expanded | |
186 | * so that a->dmax is not leaking secret information. | |
187 | * | |
188 | * In other words, it's the caller's responsibility to ensure `a` has | |
189 | * been preallocated in advance to a public length if we hit this | |
190 | * branch. | |
191 | * | |
192 | */ | |
193 | return bn_num_bits_consttime(a); | |
194 | } | |
195 | ||
0f113f3e MC |
196 | if (BN_is_zero(a)) |
197 | return 0; | |
8b44198b | 198 | |
0f113f3e MC |
199 | return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); |
200 | } | |
d02b48c6 | 201 | |
82925f9d | 202 | static void bn_free_d(BIGNUM *a, int clear) |
9f040d6d | 203 | { |
700b8145 | 204 | if (BN_get_flags(a, BN_FLG_SECURE)) |
82925f9d P |
205 | OPENSSL_secure_clear_free(a->d, a->dmax * sizeof(a->d[0])); |
206 | else if (clear != 0) | |
207 | OPENSSL_clear_free(a->d, a->dmax * sizeof(a->d[0])); | |
9f040d6d RS |
208 | else |
209 | OPENSSL_free(a->d); | |
210 | } | |
211 | ||
212 | ||
6b691a5c | 213 | void BN_clear_free(BIGNUM *a) |
0f113f3e | 214 | { |
0f113f3e MC |
215 | if (a == NULL) |
216 | return; | |
82925f9d P |
217 | if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA)) |
218 | bn_free_d(a, 1); | |
5f2d9c4d DSH |
219 | if (BN_get_flags(a, BN_FLG_MALLOCED)) { |
220 | OPENSSL_cleanse(a, sizeof(*a)); | |
0f113f3e | 221 | OPENSSL_free(a); |
5f2d9c4d | 222 | } |
0f113f3e | 223 | } |
d02b48c6 | 224 | |
6b691a5c | 225 | void BN_free(BIGNUM *a) |
0f113f3e MC |
226 | { |
227 | if (a == NULL) | |
228 | return; | |
b548a1f1 | 229 | if (!BN_get_flags(a, BN_FLG_STATIC_DATA)) |
82925f9d | 230 | bn_free_d(a, 0); |
0f113f3e MC |
231 | if (a->flags & BN_FLG_MALLOCED) |
232 | OPENSSL_free(a); | |
0f113f3e | 233 | } |
dfeab068 | 234 | |
d59c7c81 | 235 | void bn_init(BIGNUM *a) |
0f113f3e | 236 | { |
d59c7c81 RS |
237 | static BIGNUM nilbn; |
238 | ||
239 | *a = nilbn; | |
0f113f3e MC |
240 | bn_check_top(a); |
241 | } | |
d02b48c6 | 242 | |
6b691a5c | 243 | BIGNUM *BN_new(void) |
0f113f3e MC |
244 | { |
245 | BIGNUM *ret; | |
246 | ||
e077455e | 247 | if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) |
26a7d938 | 248 | return NULL; |
0f113f3e | 249 | ret->flags = BN_FLG_MALLOCED; |
0f113f3e | 250 | bn_check_top(ret); |
26a7d938 | 251 | return ret; |
0f113f3e | 252 | } |
d02b48c6 | 253 | |
74924dcb RS |
254 | BIGNUM *BN_secure_new(void) |
255 | { | |
256 | BIGNUM *ret = BN_new(); | |
90945fa3 | 257 | if (ret != NULL) |
74924dcb | 258 | ret->flags |= BN_FLG_SECURE; |
26a7d938 | 259 | return ret; |
74924dcb RS |
260 | } |
261 | ||
8707e3be | 262 | /* This is used by bn_expand2() */ |
020fc820 | 263 | /* The caller MUST check that words > b->dmax before calling this */ |
6343829a | 264 | static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) |
0f113f3e | 265 | { |
d5aa14dd | 266 | BN_ULONG *a = NULL; |
0f113f3e | 267 | |
0f113f3e | 268 | if (words > (INT_MAX / (4 * BN_BITS2))) { |
9311d0c4 | 269 | ERR_raise(ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG); |
0f113f3e MC |
270 | return NULL; |
271 | } | |
272 | if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { | |
9311d0c4 | 273 | ERR_raise(ERR_LIB_BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); |
26a7d938 | 274 | return NULL; |
0f113f3e | 275 | } |
700b8145 | 276 | if (BN_get_flags(b, BN_FLG_SECURE)) |
d5aa14dd | 277 | a = OPENSSL_secure_zalloc(words * sizeof(*a)); |
74924dcb | 278 | else |
d5aa14dd | 279 | a = OPENSSL_zalloc(words * sizeof(*a)); |
e077455e | 280 | if (a == NULL) |
26a7d938 | 281 | return NULL; |
f8571ce8 | 282 | |
d5aa14dd | 283 | assert(b->top <= words); |
d0808664 MC |
284 | if (b->top > 0) |
285 | memcpy(a, b->d, sizeof(*a) * b->top); | |
dfeab068 | 286 | |
d5aa14dd | 287 | return a; |
0f113f3e MC |
288 | } |
289 | ||
290 | /* | |
291 | * This is an internal function that should not be used in applications. It | |
292 | * ensures that 'b' has enough room for a 'words' word number and initialises | |
293 | * any unused part of b->d with leading zeros. It is mostly used by the | |
294 | * various BIGNUM routines. If there is an error, NULL is returned. If not, | |
295 | * 'b' is returned. | |
296 | */ | |
020fc820 | 297 | |
6343829a | 298 | BIGNUM *bn_expand2(BIGNUM *b, int words) |
0f113f3e | 299 | { |
0f113f3e MC |
300 | if (words > b->dmax) { |
301 | BN_ULONG *a = bn_expand_internal(b, words); | |
302 | if (!a) | |
303 | return NULL; | |
82925f9d P |
304 | if (b->d != NULL) |
305 | bn_free_d(b, 1); | |
0f113f3e MC |
306 | b->d = a; |
307 | b->dmax = words; | |
308 | } | |
2bfd2c74 | 309 | |
0f113f3e MC |
310 | return b; |
311 | } | |
d02b48c6 | 312 | |
84c15db5 | 313 | BIGNUM *BN_dup(const BIGNUM *a) |
0f113f3e MC |
314 | { |
315 | BIGNUM *t; | |
316 | ||
317 | if (a == NULL) | |
318 | return NULL; | |
319 | bn_check_top(a); | |
320 | ||
74924dcb | 321 | t = BN_get_flags(a, BN_FLG_SECURE) ? BN_secure_new() : BN_new(); |
0f113f3e MC |
322 | if (t == NULL) |
323 | return NULL; | |
324 | if (!BN_copy(t, a)) { | |
325 | BN_free(t); | |
326 | return NULL; | |
327 | } | |
328 | bn_check_top(t); | |
329 | return t; | |
330 | } | |
d02b48c6 | 331 | |
84c15db5 | 332 | BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) |
0f113f3e | 333 | { |
2d9167ed NT |
334 | int bn_words; |
335 | ||
0f113f3e | 336 | bn_check_top(b); |
dfeab068 | 337 | |
2d9167ed NT |
338 | bn_words = BN_get_flags(b, BN_FLG_CONSTTIME) ? b->dmax : b->top; |
339 | ||
0f113f3e | 340 | if (a == b) |
d5aa14dd | 341 | return a; |
2d9167ed | 342 | if (bn_wexpand(a, bn_words) == NULL) |
d5aa14dd | 343 | return NULL; |
58964a49 | 344 | |
d0808664 | 345 | if (b->top > 0) |
2d9167ed | 346 | memcpy(a->d, b->d, sizeof(b->d[0]) * bn_words); |
58964a49 | 347 | |
0f113f3e | 348 | a->neg = b->neg; |
305b68f1 AP |
349 | a->top = b->top; |
350 | a->flags |= b->flags & BN_FLG_FIXED_TOP; | |
0f113f3e | 351 | bn_check_top(a); |
d5aa14dd | 352 | return a; |
0f113f3e | 353 | } |
d02b48c6 | 354 | |
9e5b50b5 BB |
355 | #define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \ |
356 | | BN_FLG_CONSTTIME \ | |
305b68f1 AP |
357 | | BN_FLG_SECURE \ |
358 | | BN_FLG_FIXED_TOP)) | |
9e5b50b5 BB |
359 | #define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED)) |
360 | ||
78a0c1f1 | 361 | void BN_swap(BIGNUM *a, BIGNUM *b) |
0f113f3e MC |
362 | { |
363 | int flags_old_a, flags_old_b; | |
364 | BN_ULONG *tmp_d; | |
365 | int tmp_top, tmp_dmax, tmp_neg; | |
366 | ||
367 | bn_check_top(a); | |
368 | bn_check_top(b); | |
369 | ||
370 | flags_old_a = a->flags; | |
371 | flags_old_b = b->flags; | |
372 | ||
373 | tmp_d = a->d; | |
374 | tmp_top = a->top; | |
375 | tmp_dmax = a->dmax; | |
376 | tmp_neg = a->neg; | |
377 | ||
378 | a->d = b->d; | |
379 | a->top = b->top; | |
380 | a->dmax = b->dmax; | |
381 | a->neg = b->neg; | |
382 | ||
383 | b->d = tmp_d; | |
384 | b->top = tmp_top; | |
385 | b->dmax = tmp_dmax; | |
386 | b->neg = tmp_neg; | |
387 | ||
9e5b50b5 BB |
388 | a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b); |
389 | b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a); | |
0f113f3e MC |
390 | bn_check_top(a); |
391 | bn_check_top(b); | |
392 | } | |
78a0c1f1 | 393 | |
6b691a5c | 394 | void BN_clear(BIGNUM *a) |
0f113f3e | 395 | { |
ce1415ed SL |
396 | if (a == NULL) |
397 | return; | |
0f113f3e MC |
398 | bn_check_top(a); |
399 | if (a->d != NULL) | |
3ce2fdab | 400 | OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax); |
0f113f3e | 401 | a->neg = 0; |
305b68f1 AP |
402 | a->top = 0; |
403 | a->flags &= ~BN_FLG_FIXED_TOP; | |
0f113f3e | 404 | } |
d02b48c6 | 405 | |
020fc820 | 406 | BN_ULONG BN_get_word(const BIGNUM *a) |
0f113f3e MC |
407 | { |
408 | if (a->top > 1) | |
409 | return BN_MASK2; | |
410 | else if (a->top == 1) | |
411 | return a->d[0]; | |
412 | /* a->top == 0 */ | |
413 | return 0; | |
414 | } | |
d02b48c6 | 415 | |
e042540f | 416 | int BN_set_word(BIGNUM *a, BN_ULONG w) |
0f113f3e MC |
417 | { |
418 | bn_check_top(a); | |
419 | if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL) | |
26a7d938 | 420 | return 0; |
0f113f3e MC |
421 | a->neg = 0; |
422 | a->d[0] = w; | |
423 | a->top = (w ? 1 : 0); | |
305b68f1 | 424 | a->flags &= ~BN_FLG_FIXED_TOP; |
0f113f3e | 425 | bn_check_top(a); |
208fb891 | 426 | return 1; |
0f113f3e | 427 | } |
d02b48c6 | 428 | |
060f370e | 429 | typedef enum {BIG, LITTLE} endianness_t; |
f5e8050f | 430 | typedef enum {SIGNED, UNSIGNED} signedness_t; |
c2cab435 RL |
431 | |
432 | static BIGNUM *bin2bn(const unsigned char *s, int len, BIGNUM *ret, | |
060f370e | 433 | endianness_t endianness, signedness_t signedness) |
0f113f3e | 434 | { |
c2cab435 | 435 | int inc; |
c30de601 RL |
436 | const unsigned char *s2; |
437 | int inc2; | |
f5e8050f | 438 | int neg = 0, xor = 0, carry = 0; |
c30de601 | 439 | unsigned int i; |
0f113f3e | 440 | unsigned int n; |
0f113f3e MC |
441 | BIGNUM *bn = NULL; |
442 | ||
c9466f38 RL |
443 | /* Negative length is not acceptable */ |
444 | if (len < 0) | |
445 | return NULL; | |
446 | ||
0f113f3e MC |
447 | if (ret == NULL) |
448 | ret = bn = BN_new(); | |
449 | if (ret == NULL) | |
26a7d938 | 450 | return NULL; |
0f113f3e | 451 | bn_check_top(ret); |
c2cab435 | 452 | |
1b24b5a1 RL |
453 | /* |
454 | * If the input has no bits, the number is considered zero. | |
455 | * This makes calls with s==NULL and len==0 safe. | |
456 | */ | |
457 | if (len == 0) { | |
458 | BN_clear(ret); | |
459 | return ret; | |
460 | } | |
461 | ||
c2cab435 | 462 | /* |
c30de601 | 463 | * The loop that does the work iterates from least to most |
07c5465e | 464 | * significant BIGNUM chunk, so we adapt parameters to transfer |
c2cab435 RL |
465 | * input bytes accordingly. |
466 | */ | |
060f370e | 467 | if (endianness == LITTLE) { |
c30de601 RL |
468 | s2 = s + len - 1; |
469 | inc2 = -1; | |
470 | inc = 1; | |
649999dc | 471 | } else { |
c30de601 RL |
472 | s2 = s; |
473 | inc2 = 1; | |
474 | inc = -1; | |
475 | s += len - 1; | |
c2cab435 RL |
476 | } |
477 | ||
f5e8050f RL |
478 | /* Take note of the signedness of the input bytes*/ |
479 | if (signedness == SIGNED) { | |
480 | neg = !!(*s2 & 0x80); | |
481 | xor = neg ? 0xff : 0x00; | |
482 | carry = neg; | |
483 | } | |
484 | ||
c30de601 | 485 | /* |
f5e8050f | 486 | * Skip leading sign extensions (the value of |xor|). |
c30de601 RL |
487 | * This is the only spot where |s2| and |inc2| are used. |
488 | */ | |
489 | for ( ; len > 0 && *s2 == xor; s2 += inc2, len--) | |
22dc08d0 | 490 | continue; |
c30de601 | 491 | |
f5e8050f RL |
492 | /* |
493 | * If there was a set of 0xff, we backtrack one byte unless the next | |
494 | * one has a sign bit, as the last 0xff is then part of the actual | |
495 | * number, rather then a mere sign extension. | |
496 | */ | |
497 | if (xor == 0xff) { | |
498 | if (len == 0 || !(*s2 & 0x80)) | |
499 | len++; | |
500 | } | |
501 | /* If it was all zeros, we're done */ | |
c30de601 | 502 | if (len == 0) { |
0f113f3e | 503 | ret->top = 0; |
26a7d938 | 504 | return ret; |
0f113f3e | 505 | } |
c30de601 | 506 | n = ((len - 1) / BN_BYTES) + 1; /* Number of resulting bignum chunks */ |
69b9a992 | 507 | if (bn_wexpand(ret, (int)n) == NULL) { |
23a1d5e9 | 508 | BN_free(bn); |
0f113f3e MC |
509 | return NULL; |
510 | } | |
c30de601 | 511 | ret->top = n; |
f5e8050f | 512 | ret->neg = neg; |
c30de601 RL |
513 | for (i = 0; n-- > 0; i++) { |
514 | BN_ULONG l = 0; /* Accumulator */ | |
515 | unsigned int m = 0; /* Offset in a bignum chunk, in bits */ | |
516 | ||
517 | for (; len > 0 && m < BN_BYTES * 8; len--, s += inc, m += 8) { | |
f5e8050f RL |
518 | BN_ULONG byte_xored = *s ^ xor; |
519 | BN_ULONG byte = (byte_xored + carry) & 0xff; | |
c30de601 | 520 | |
f5e8050f | 521 | carry = byte_xored > byte; /* Implicit 1 or 0 */ |
c30de601 | 522 | l |= (byte << m); |
0f113f3e | 523 | } |
c30de601 | 524 | ret->d[i] = l; |
0f113f3e MC |
525 | } |
526 | /* | |
527 | * need to call this due to clear byte at top if avoiding having the top | |
528 | * bit set (-ve number) | |
529 | */ | |
530 | bn_correct_top(ret); | |
26a7d938 | 531 | return ret; |
0f113f3e | 532 | } |
d02b48c6 | 533 | |
c2cab435 RL |
534 | BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) |
535 | { | |
f5e8050f | 536 | return bin2bn(s, len, ret, BIG, UNSIGNED); |
c2cab435 | 537 | } |
1b338abe | 538 | |
f5e8050f RL |
539 | BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret) |
540 | { | |
541 | return bin2bn(s, len, ret, BIG, SIGNED); | |
542 | } | |
543 | ||
544 | static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, | |
060f370e | 545 | endianness_t endianness, signedness_t signedness) |
0f113f3e | 546 | { |
4e26fe50 | 547 | int inc; |
f5e8050f RL |
548 | int n, n8; |
549 | int xor = 0, carry = 0, ext = 0; | |
324b9560 | 550 | size_t i, lasti, j, atop, mask; |
0f113f3e MC |
551 | BN_ULONG l; |
552 | ||
324b9560 | 553 | /* |
f5e8050f | 554 | * In case |a| is fixed-top, BN_num_bits can return bogus length, |
324b9560 AP |
555 | * but it's assumed that fixed-top inputs ought to be "nominated" |
556 | * even for padded output, so it works out... | |
557 | */ | |
f5e8050f RL |
558 | n8 = BN_num_bits(a); |
559 | n = (n8 + 7) / 8; /* This is what BN_num_bytes() does */ | |
560 | ||
561 | /* Take note of the signedness of the bignum */ | |
562 | if (signedness == SIGNED) { | |
563 | xor = a->neg ? 0xff : 0x00; | |
564 | carry = a->neg; | |
565 | ||
566 | /* | |
567 | * if |n * 8 == n|, then the MSbit is set, otherwise unset. | |
568 | * We must compensate with one extra byte if that doesn't | |
569 | * correspond to the signedness of the bignum with regards | |
570 | * to 2's complement. | |
571 | */ | |
572 | ext = (n * 8 == n8) | |
573 | ? !a->neg /* MSbit set on nonnegative bignum */ | |
574 | : a->neg; /* MSbit unset on negative bignum */ | |
575 | } | |
576 | ||
324b9560 | 577 | if (tolen == -1) { |
f5e8050f RL |
578 | tolen = n + ext; |
579 | } else if (tolen < n + ext) { /* uncommon/unlike case */ | |
324b9560 | 580 | BIGNUM temp = *a; |
89d8aade | 581 | |
324b9560 | 582 | bn_correct_top(&temp); |
f5e8050f RL |
583 | n8 = BN_num_bits(&temp); |
584 | n = (n8 + 7) / 8; /* This is what BN_num_bytes() does */ | |
585 | if (tolen < n + ext) | |
324b9560 AP |
586 | return -1; |
587 | } | |
588 | ||
589 | /* Swipe through whole available data and don't give away padded zero. */ | |
590 | atop = a->dmax * BN_BYTES; | |
591 | if (atop == 0) { | |
858d5ac1 TM |
592 | if (tolen != 0) |
593 | memset(to, '\0', tolen); | |
89d8aade | 594 | return tolen; |
85a4807f | 595 | } |
89d8aade | 596 | |
4e26fe50 RL |
597 | /* |
598 | * The loop that does the work iterates from least significant | |
599 | * to most significant BIGNUM limb, so we adapt parameters to | |
07c5465e | 600 | * transfer output bytes accordingly. |
4e26fe50 | 601 | */ |
060f370e | 602 | if (endianness == LITTLE) { |
4e26fe50 | 603 | inc = 1; |
649999dc | 604 | } else { |
4e26fe50 RL |
605 | inc = -1; |
606 | to += tolen - 1; /* Move to the last byte, not beyond */ | |
4e26fe50 RL |
607 | } |
608 | ||
324b9560 AP |
609 | lasti = atop - 1; |
610 | atop = a->top * BN_BYTES; | |
1b338abe | 611 | for (i = 0, j = 0; j < (size_t)tolen; j++) { |
f5e8050f RL |
612 | unsigned char byte, byte_xored; |
613 | ||
0f113f3e | 614 | l = a->d[i / BN_BYTES]; |
324b9560 | 615 | mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); |
f5e8050f RL |
616 | byte = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); |
617 | byte_xored = byte ^ xor; | |
618 | *to = (unsigned char)(byte_xored + carry); | |
619 | carry = byte_xored > *to; /* Implicit 1 or 0 */ | |
4e26fe50 | 620 | to += inc; |
324b9560 | 621 | i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ |
0f113f3e | 622 | } |
89d8aade | 623 | |
85a4807f DSH |
624 | return tolen; |
625 | } | |
626 | ||
627 | int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) | |
628 | { | |
629 | if (tolen < 0) | |
630 | return -1; | |
f5e8050f RL |
631 | return bn2binpad(a, to, tolen, BIG, UNSIGNED); |
632 | } | |
633 | ||
634 | int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen) | |
635 | { | |
636 | if (tolen < 0) | |
637 | return -1; | |
638 | return bn2binpad(a, to, tolen, BIG, SIGNED); | |
85a4807f DSH |
639 | } |
640 | ||
641 | int BN_bn2bin(const BIGNUM *a, unsigned char *to) | |
642 | { | |
f5e8050f | 643 | return bn2binpad(a, to, -1, BIG, UNSIGNED); |
85a4807f DSH |
644 | } |
645 | ||
646 | BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) | |
647 | { | |
f5e8050f RL |
648 | return bin2bn(s, len, ret, LITTLE, UNSIGNED); |
649 | } | |
650 | ||
651 | BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) | |
652 | { | |
653 | return bin2bn(s, len, ret, LITTLE, SIGNED); | |
85a4807f DSH |
654 | } |
655 | ||
656 | int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) | |
657 | { | |
1b338abe | 658 | if (tolen < 0) |
85a4807f | 659 | return -1; |
f5e8050f RL |
660 | return bn2binpad(a, to, tolen, LITTLE, UNSIGNED); |
661 | } | |
662 | ||
663 | int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen) | |
664 | { | |
665 | if (tolen < 0) | |
666 | return -1; | |
667 | return bn2binpad(a, to, tolen, LITTLE, SIGNED); | |
0f113f3e | 668 | } |
d02b48c6 | 669 | |
fa4d419c RL |
670 | BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret) |
671 | { | |
310a0edb RL |
672 | DECLARE_IS_ENDIAN; |
673 | ||
674 | if (IS_LITTLE_ENDIAN) | |
675 | return BN_lebin2bn(s, len, ret); | |
fa4d419c | 676 | return BN_bin2bn(s, len, ret); |
fa4d419c RL |
677 | } |
678 | ||
f5e8050f RL |
679 | BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret) |
680 | { | |
681 | DECLARE_IS_ENDIAN; | |
682 | ||
683 | if (IS_LITTLE_ENDIAN) | |
684 | return BN_signed_lebin2bn(s, len, ret); | |
685 | return BN_signed_bin2bn(s, len, ret); | |
686 | } | |
687 | ||
fa4d419c RL |
688 | int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen) |
689 | { | |
310a0edb RL |
690 | DECLARE_IS_ENDIAN; |
691 | ||
692 | if (IS_LITTLE_ENDIAN) | |
693 | return BN_bn2lebinpad(a, to, tolen); | |
fa4d419c | 694 | return BN_bn2binpad(a, to, tolen); |
fa4d419c RL |
695 | } |
696 | ||
f5e8050f RL |
697 | int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen) |
698 | { | |
699 | DECLARE_IS_ENDIAN; | |
700 | ||
701 | if (IS_LITTLE_ENDIAN) | |
702 | return BN_signed_bn2lebin(a, to, tolen); | |
703 | return BN_signed_bn2bin(a, to, tolen); | |
704 | } | |
705 | ||
84c15db5 | 706 | int BN_ucmp(const BIGNUM *a, const BIGNUM *b) |
0f113f3e MC |
707 | { |
708 | int i; | |
709 | BN_ULONG t1, t2, *ap, *bp; | |
710 | ||
711 | bn_check_top(a); | |
712 | bn_check_top(b); | |
713 | ||
714 | i = a->top - b->top; | |
715 | if (i != 0) | |
26a7d938 | 716 | return i; |
0f113f3e MC |
717 | ap = a->d; |
718 | bp = b->d; | |
719 | for (i = a->top - 1; i >= 0; i--) { | |
720 | t1 = ap[i]; | |
721 | t2 = bp[i]; | |
722 | if (t1 != t2) | |
723 | return ((t1 > t2) ? 1 : -1); | |
724 | } | |
26a7d938 | 725 | return 0; |
0f113f3e | 726 | } |
d02b48c6 | 727 | |
84c15db5 | 728 | int BN_cmp(const BIGNUM *a, const BIGNUM *b) |
0f113f3e MC |
729 | { |
730 | int i; | |
731 | int gt, lt; | |
732 | BN_ULONG t1, t2; | |
733 | ||
734 | if ((a == NULL) || (b == NULL)) { | |
735 | if (a != NULL) | |
26a7d938 | 736 | return -1; |
0f113f3e | 737 | else if (b != NULL) |
208fb891 | 738 | return 1; |
0f113f3e | 739 | else |
26a7d938 | 740 | return 0; |
0f113f3e MC |
741 | } |
742 | ||
743 | bn_check_top(a); | |
744 | bn_check_top(b); | |
745 | ||
746 | if (a->neg != b->neg) { | |
747 | if (a->neg) | |
26a7d938 | 748 | return -1; |
0f113f3e | 749 | else |
208fb891 | 750 | return 1; |
0f113f3e MC |
751 | } |
752 | if (a->neg == 0) { | |
753 | gt = 1; | |
754 | lt = -1; | |
755 | } else { | |
756 | gt = -1; | |
757 | lt = 1; | |
758 | } | |
759 | ||
760 | if (a->top > b->top) | |
26a7d938 | 761 | return gt; |
0f113f3e | 762 | if (a->top < b->top) |
26a7d938 | 763 | return lt; |
0f113f3e MC |
764 | for (i = a->top - 1; i >= 0; i--) { |
765 | t1 = a->d[i]; | |
766 | t2 = b->d[i]; | |
767 | if (t1 > t2) | |
26a7d938 | 768 | return gt; |
0f113f3e | 769 | if (t1 < t2) |
26a7d938 | 770 | return lt; |
0f113f3e | 771 | } |
26a7d938 | 772 | return 0; |
0f113f3e | 773 | } |
d02b48c6 | 774 | |
6b691a5c | 775 | int BN_set_bit(BIGNUM *a, int n) |
0f113f3e MC |
776 | { |
777 | int i, j, k; | |
778 | ||
779 | if (n < 0) | |
780 | return 0; | |
781 | ||
782 | i = n / BN_BITS2; | |
783 | j = n % BN_BITS2; | |
784 | if (a->top <= i) { | |
785 | if (bn_wexpand(a, i + 1) == NULL) | |
26a7d938 | 786 | return 0; |
0f113f3e MC |
787 | for (k = a->top; k < i + 1; k++) |
788 | a->d[k] = 0; | |
789 | a->top = i + 1; | |
305b68f1 | 790 | a->flags &= ~BN_FLG_FIXED_TOP; |
0f113f3e MC |
791 | } |
792 | ||
793 | a->d[i] |= (((BN_ULONG)1) << j); | |
794 | bn_check_top(a); | |
208fb891 | 795 | return 1; |
0f113f3e | 796 | } |
d02b48c6 | 797 | |
6b691a5c | 798 | int BN_clear_bit(BIGNUM *a, int n) |
0f113f3e MC |
799 | { |
800 | int i, j; | |
d02b48c6 | 801 | |
0f113f3e MC |
802 | bn_check_top(a); |
803 | if (n < 0) | |
804 | return 0; | |
1a017330 | 805 | |
0f113f3e MC |
806 | i = n / BN_BITS2; |
807 | j = n % BN_BITS2; | |
808 | if (a->top <= i) | |
26a7d938 | 809 | return 0; |
d02b48c6 | 810 | |
0f113f3e MC |
811 | a->d[i] &= (~(((BN_ULONG)1) << j)); |
812 | bn_correct_top(a); | |
208fb891 | 813 | return 1; |
0f113f3e | 814 | } |
d02b48c6 | 815 | |
84c15db5 | 816 | int BN_is_bit_set(const BIGNUM *a, int n) |
0f113f3e MC |
817 | { |
818 | int i, j; | |
819 | ||
820 | bn_check_top(a); | |
821 | if (n < 0) | |
822 | return 0; | |
823 | i = n / BN_BITS2; | |
824 | j = n % BN_BITS2; | |
825 | if (a->top <= i) | |
826 | return 0; | |
827 | return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); | |
828 | } | |
d02b48c6 | 829 | |
6b691a5c | 830 | int BN_mask_bits(BIGNUM *a, int n) |
0f113f3e MC |
831 | { |
832 | int b, w; | |
833 | ||
834 | bn_check_top(a); | |
835 | if (n < 0) | |
836 | return 0; | |
837 | ||
838 | w = n / BN_BITS2; | |
839 | b = n % BN_BITS2; | |
840 | if (w >= a->top) | |
841 | return 0; | |
842 | if (b == 0) | |
843 | a->top = w; | |
844 | else { | |
845 | a->top = w + 1; | |
846 | a->d[w] &= ~(BN_MASK2 << b); | |
847 | } | |
848 | bn_correct_top(a); | |
208fb891 | 849 | return 1; |
0f113f3e | 850 | } |
dfeab068 | 851 | |
ff22e913 | 852 | void BN_set_negative(BIGNUM *a, int b) |
0f113f3e MC |
853 | { |
854 | if (b && !BN_is_zero(a)) | |
855 | a->neg = 1; | |
856 | else | |
857 | a->neg = 0; | |
858 | } | |
ff22e913 | 859 | |
cbd48ba6 | 860 | int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) |
0f113f3e MC |
861 | { |
862 | int i; | |
863 | BN_ULONG aa, bb; | |
864 | ||
576129cd MC |
865 | if (n == 0) |
866 | return 0; | |
867 | ||
0f113f3e MC |
868 | aa = a[n - 1]; |
869 | bb = b[n - 1]; | |
870 | if (aa != bb) | |
871 | return ((aa > bb) ? 1 : -1); | |
872 | for (i = n - 2; i >= 0; i--) { | |
873 | aa = a[i]; | |
874 | bb = b[i]; | |
875 | if (aa != bb) | |
876 | return ((aa > bb) ? 1 : -1); | |
877 | } | |
26a7d938 | 878 | return 0; |
0f113f3e MC |
879 | } |
880 | ||
881 | /* | |
882 | * Here follows a specialised variants of bn_cmp_words(). It has the | |
399de496 | 883 | * capability of performing the operation on arrays of different sizes. The |
0f113f3e | 884 | * sizes of those arrays is expressed through cl, which is the common length |
399de496 | 885 | * ( basically, min(len(a),len(b)) ), and dl, which is the delta between the |
0f113f3e MC |
886 | * two lengths, calculated as len(a)-len(b). All lengths are the number of |
887 | * BN_ULONGs... | |
888 | */ | |
889 | ||
890 | int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl) | |
891 | { | |
892 | int n, i; | |
893 | n = cl - 1; | |
894 | ||
895 | if (dl < 0) { | |
896 | for (i = dl; i < 0; i++) { | |
897 | if (b[n - i] != 0) | |
898 | return -1; /* a < b */ | |
899 | } | |
900 | } | |
901 | if (dl > 0) { | |
902 | for (i = dl; i > 0; i--) { | |
903 | if (a[n + i] != 0) | |
904 | return 1; /* a > b */ | |
905 | } | |
906 | } | |
907 | return bn_cmp_words(a, b, cl); | |
908 | } | |
909 | ||
900fd8f3 | 910 | /*- |
0f113f3e | 911 | * Constant-time conditional swap of a and b. |
900fd8f3 BB |
912 | * a and b are swapped if condition is not 0. |
913 | * nwords is the number of words to swap. | |
914 | * Assumes that at least nwords are allocated in both a and b. | |
915 | * Assumes that no more than nwords are used by either a or b. | |
f9b6c0ba DSH |
916 | */ |
917 | void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) | |
0f113f3e MC |
918 | { |
919 | BN_ULONG t; | |
920 | int i; | |
f9b6c0ba | 921 | |
0f113f3e MC |
922 | bn_wcheck_size(a, nwords); |
923 | bn_wcheck_size(b, nwords); | |
f9b6c0ba | 924 | |
900fd8f3 | 925 | condition = ((~condition & ((condition - 1))) >> (BN_BITS2 - 1)) - 1; |
f9b6c0ba | 926 | |
0f113f3e MC |
927 | t = (a->top ^ b->top) & condition; |
928 | a->top ^= t; | |
929 | b->top ^= t; | |
f9b6c0ba | 930 | |
40e48e54 BB |
931 | t = (a->neg ^ b->neg) & condition; |
932 | a->neg ^= t; | |
933 | b->neg ^= t; | |
934 | ||
39df5152 | 935 | /*- |
dd41956d BB |
936 | * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention |
937 | * is actually to treat it as it's read-only data, and some (if not most) | |
938 | * of it does reside in read-only segment. In other words observation of | |
939 | * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal | |
940 | * condition. It would either cause SEGV or effectively cause data | |
941 | * corruption. | |
942 | * | |
943 | * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be | |
944 | * preserved. | |
945 | * | |
946 | * BN_FLG_SECURE: must be preserved, because it determines how x->d was | |
947 | * allocated and hence how to free it. | |
948 | * | |
949 | * BN_FLG_CONSTTIME: sufficient to mask and swap | |
950 | * | |
951 | * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on | |
952 | * the data, so the d array may be padded with additional 0 values (i.e. | |
953 | * top could be greater than the minimal value that it could be). We should | |
954 | * be swapping it | |
40e48e54 | 955 | */ |
dd41956d BB |
956 | |
957 | #define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP) | |
958 | ||
959 | t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition; | |
40e48e54 BB |
960 | a->flags ^= t; |
961 | b->flags ^= t; | |
962 | ||
900fd8f3 BB |
963 | /* conditionally swap the data */ |
964 | for (i = 0; i < nwords; i++) { | |
965 | t = (a->d[i] ^ b->d[i]) & condition; | |
966 | a->d[i] ^= t; | |
967 | b->d[i] ^= t; | |
968 | } | |
f9b6c0ba | 969 | } |
2514fa79 | 970 | |
900fd8f3 BB |
971 | #undef BN_CONSTTIME_SWAP_FLAGS |
972 | ||
2514fa79 DSH |
973 | /* Bits of security, see SP800-57 */ |
974 | ||
975 | int BN_security_bits(int L, int N) | |
0f113f3e MC |
976 | { |
977 | int secbits, bits; | |
978 | if (L >= 15360) | |
979 | secbits = 256; | |
c9fe3623 | 980 | else if (L >= 7680) |
0f113f3e MC |
981 | secbits = 192; |
982 | else if (L >= 3072) | |
983 | secbits = 128; | |
984 | else if (L >= 2048) | |
985 | secbits = 112; | |
986 | else if (L >= 1024) | |
987 | secbits = 80; | |
988 | else | |
989 | return 0; | |
990 | if (N == -1) | |
991 | return secbits; | |
992 | bits = N / 2; | |
993 | if (bits < 80) | |
994 | return 0; | |
995 | return bits >= secbits ? secbits : bits; | |
996 | } | |
85bcf27c MC |
997 | |
998 | void BN_zero_ex(BIGNUM *a) | |
0f113f3e | 999 | { |
0f113f3e | 1000 | a->neg = 0; |
305b68f1 AP |
1001 | a->top = 0; |
1002 | a->flags &= ~BN_FLG_FIXED_TOP; | |
0f113f3e | 1003 | } |
85bcf27c MC |
1004 | |
1005 | int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w) | |
0f113f3e MC |
1006 | { |
1007 | return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0)); | |
1008 | } | |
85bcf27c MC |
1009 | |
1010 | int BN_is_zero(const BIGNUM *a) | |
0f113f3e MC |
1011 | { |
1012 | return a->top == 0; | |
1013 | } | |
85bcf27c MC |
1014 | |
1015 | int BN_is_one(const BIGNUM *a) | |
0f113f3e MC |
1016 | { |
1017 | return BN_abs_is_word(a, 1) && !a->neg; | |
1018 | } | |
85bcf27c MC |
1019 | |
1020 | int BN_is_word(const BIGNUM *a, const BN_ULONG w) | |
0f113f3e MC |
1021 | { |
1022 | return BN_abs_is_word(a, w) && (!w || !a->neg); | |
1023 | } | |
85bcf27c MC |
1024 | |
1025 | int BN_is_odd(const BIGNUM *a) | |
0f113f3e MC |
1026 | { |
1027 | return (a->top > 0) && (a->d[0] & 1); | |
1028 | } | |
85bcf27c MC |
1029 | |
1030 | int BN_is_negative(const BIGNUM *a) | |
0f113f3e MC |
1031 | { |
1032 | return (a->neg != 0); | |
1033 | } | |
85bcf27c | 1034 | |
0f113f3e MC |
1035 | int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, |
1036 | BN_CTX *ctx) | |
1037 | { | |
1038 | return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx); | |
1039 | } | |
85bcf27c | 1040 | |
fd7d2520 | 1041 | void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags) |
0f113f3e MC |
1042 | { |
1043 | dest->d = b->d; | |
1044 | dest->top = b->top; | |
1045 | dest->dmax = b->dmax; | |
1046 | dest->neg = b->neg; | |
1047 | dest->flags = ((dest->flags & BN_FLG_MALLOCED) | |
1048 | | (b->flags & ~BN_FLG_MALLOCED) | |
fd7d2520 | 1049 | | BN_FLG_STATIC_DATA | flags); |
0f113f3e | 1050 | } |
85bcf27c MC |
1051 | |
1052 | BN_GENCB *BN_GENCB_new(void) | |
0f113f3e MC |
1053 | { |
1054 | BN_GENCB *ret; | |
85bcf27c | 1055 | |
e077455e | 1056 | if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) |
26a7d938 | 1057 | return NULL; |
85bcf27c | 1058 | |
0f113f3e MC |
1059 | return ret; |
1060 | } | |
85bcf27c MC |
1061 | |
1062 | void BN_GENCB_free(BN_GENCB *cb) | |
0f113f3e MC |
1063 | { |
1064 | if (cb == NULL) | |
1065 | return; | |
1066 | OPENSSL_free(cb); | |
1067 | } | |
85bcf27c MC |
1068 | |
1069 | void BN_set_flags(BIGNUM *b, int n) | |
0f113f3e MC |
1070 | { |
1071 | b->flags |= n; | |
1072 | } | |
85bcf27c MC |
1073 | |
1074 | int BN_get_flags(const BIGNUM *b, int n) | |
0f113f3e MC |
1075 | { |
1076 | return b->flags & n; | |
1077 | } | |
85bcf27c MC |
1078 | |
1079 | /* Populate a BN_GENCB structure with an "old"-style callback */ | |
0f113f3e MC |
1080 | void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *), |
1081 | void *cb_arg) | |
1082 | { | |
1083 | BN_GENCB *tmp_gencb = gencb; | |
1084 | tmp_gencb->ver = 1; | |
1085 | tmp_gencb->arg = cb_arg; | |
1086 | tmp_gencb->cb.cb_1 = callback; | |
1087 | } | |
85bcf27c MC |
1088 | |
1089 | /* Populate a BN_GENCB structure with a "new"-style callback */ | |
0f113f3e MC |
1090 | void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *), |
1091 | void *cb_arg) | |
1092 | { | |
1093 | BN_GENCB *tmp_gencb = gencb; | |
1094 | tmp_gencb->ver = 2; | |
1095 | tmp_gencb->arg = cb_arg; | |
1096 | tmp_gencb->cb.cb_2 = callback; | |
1097 | } | |
85bcf27c MC |
1098 | |
1099 | void *BN_GENCB_get_arg(BN_GENCB *cb) | |
0f113f3e MC |
1100 | { |
1101 | return cb->arg; | |
1102 | } | |
85bcf27c MC |
1103 | |
1104 | BIGNUM *bn_wexpand(BIGNUM *a, int words) | |
0f113f3e MC |
1105 | { |
1106 | return (words <= a->dmax) ? a : bn_expand2(a, words); | |
1107 | } | |
85bcf27c | 1108 | |
f06ef165 BE |
1109 | void bn_correct_top_consttime(BIGNUM *a) |
1110 | { | |
1111 | int j, atop; | |
1112 | BN_ULONG limb; | |
1113 | unsigned int mask; | |
1114 | ||
1115 | for (j = 0, atop = 0; j < a->dmax; j++) { | |
1116 | limb = a->d[j]; | |
1117 | limb |= 0 - limb; | |
1118 | limb >>= BN_BITS2 - 1; | |
1119 | limb = 0 - limb; | |
1120 | mask = (unsigned int)limb; | |
1121 | mask &= constant_time_msb(j - a->top); | |
1122 | atop = constant_time_select_int(mask, j + 1, atop); | |
1123 | } | |
1124 | ||
1125 | mask = constant_time_eq_int(atop, 0); | |
1126 | a->top = atop; | |
1127 | a->neg = constant_time_select_int(mask, 0, a->neg); | |
1128 | a->flags &= ~BN_FLG_FIXED_TOP; | |
1129 | } | |
1130 | ||
85bcf27c | 1131 | void bn_correct_top(BIGNUM *a) |
0f113f3e MC |
1132 | { |
1133 | BN_ULONG *ftl; | |
1134 | int tmp_top = a->top; | |
1135 | ||
1136 | if (tmp_top > 0) { | |
1544583b KR |
1137 | for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) { |
1138 | ftl--; | |
1139 | if (*ftl != 0) | |
0f113f3e | 1140 | break; |
1544583b | 1141 | } |
0f113f3e MC |
1142 | a->top = tmp_top; |
1143 | } | |
01c09f9f RS |
1144 | if (a->top == 0) |
1145 | a->neg = 0; | |
305b68f1 | 1146 | a->flags &= ~BN_FLG_FIXED_TOP; |
0f113f3e MC |
1147 | bn_pollute(a); |
1148 | } |