GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: bn_lib.c,v 1.38 2017/05/02 03:59:44 deraadt 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 |
void |
||
96 |
BN_set_params(int mult, int high, int low, int mont) |
||
97 |
{ |
||
98 |
if (mult >= 0) { |
||
99 |
if (mult > (int)(sizeof(int) * 8) - 1) |
||
100 |
mult = sizeof(int) * 8 - 1; |
||
101 |
bn_limit_bits = mult; |
||
102 |
bn_limit_num = 1 << mult; |
||
103 |
} |
||
104 |
if (high >= 0) { |
||
105 |
if (high > (int)(sizeof(int) * 8) - 1) |
||
106 |
high = sizeof(int) * 8 - 1; |
||
107 |
bn_limit_bits_high = high; |
||
108 |
bn_limit_num_high = 1 << high; |
||
109 |
} |
||
110 |
if (low >= 0) { |
||
111 |
if (low > (int)(sizeof(int) * 8) - 1) |
||
112 |
low = sizeof(int) * 8 - 1; |
||
113 |
bn_limit_bits_low = low; |
||
114 |
bn_limit_num_low = 1 << low; |
||
115 |
} |
||
116 |
if (mont >= 0) { |
||
117 |
if (mont > (int)(sizeof(int) * 8) - 1) |
||
118 |
mont = sizeof(int) * 8 - 1; |
||
119 |
bn_limit_bits_mont = mont; |
||
120 |
bn_limit_num_mont = 1 << mont; |
||
121 |
} |
||
122 |
} |
||
123 |
|||
124 |
int |
||
125 |
BN_get_params(int which) |
||
126 |
{ |
||
127 |
if (which == 0) |
||
128 |
return (bn_limit_bits); |
||
129 |
else if (which == 1) |
||
130 |
return (bn_limit_bits_high); |
||
131 |
else if (which == 2) |
||
132 |
return (bn_limit_bits_low); |
||
133 |
else if (which == 3) |
||
134 |
return (bn_limit_bits_mont); |
||
135 |
else |
||
136 |
return (0); |
||
137 |
} |
||
138 |
#endif |
||
139 |
|||
140 |
const BIGNUM * |
||
141 |
BN_value_one(void) |
||
142 |
{ |
||
143 |
static const BN_ULONG data_one = 1L; |
||
144 |
static const BIGNUM const_one = { |
||
145 |
(BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA |
||
146 |
}; |
||
147 |
|||
148 |
1157388 |
return (&const_one); |
|
149 |
} |
||
150 |
|||
151 |
int |
||
152 |
BN_num_bits_word(BN_ULONG l) |
||
153 |
{ |
||
154 |
static const unsigned char bits[256] = { |
||
155 |
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, |
||
156 |
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
||
157 |
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, |
||
158 |
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, |
||
159 |
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, |
||
160 |
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, |
||
161 |
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, |
||
162 |
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, |
||
163 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
164 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
165 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
166 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
167 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
168 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
169 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
170 |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
||
171 |
}; |
||
172 |
|||
173 |
#ifdef _LP64 |
||
174 |
✓✓ | 69565428 |
if (l & 0xffffffff00000000L) { |
175 |
✓✓ | 25368986 |
if (l & 0xffff000000000000L) { |
176 |
✓✓ | 21926744 |
if (l & 0xff00000000000000L) { |
177 |
20030510 |
return (bits[(int)(l >> 56)] + 56); |
|
178 |
} else |
||
179 |
1896234 |
return (bits[(int)(l >> 48)] + 48); |
|
180 |
} else { |
||
181 |
✓✓ | 3442242 |
if (l & 0x0000ff0000000000L) { |
182 |
1924155 |
return (bits[(int)(l >> 40)] + 40); |
|
183 |
} else |
||
184 |
1518087 |
return (bits[(int)(l >> 32)] + 32); |
|
185 |
} |
||
186 |
} else |
||
187 |
#endif |
||
188 |
{ |
||
189 |
✓✓ | 9413728 |
if (l & 0xffff0000L) { |
190 |
✓✓ | 5178201 |
if (l & 0xff000000L) |
191 |
3237731 |
return (bits[(int)(l >> 24L)] + 24); |
|
192 |
else |
||
193 |
1940470 |
return (bits[(int)(l >> 16L)] + 16); |
|
194 |
} else { |
||
195 |
✓✓ | 4235527 |
if (l & 0xff00L) |
196 |
2212200 |
return (bits[(int)(l >> 8)] + 8); |
|
197 |
else |
||
198 |
2023327 |
return (bits[(int)(l)]); |
|
199 |
} |
||
200 |
} |
||
201 |
34782714 |
} |
|
202 |
|||
203 |
int |
||
204 |
BN_num_bits(const BIGNUM *a) |
||
205 |
{ |
||
206 |
58937554 |
int i = a->top - 1; |
|
207 |
|||
208 |
bn_check_top(a); |
||
209 |
|||
210 |
✓✓ | 29468777 |
if (BN_is_zero(a)) |
211 |
654 |
return 0; |
|
212 |
29468123 |
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); |
|
213 |
29468777 |
} |
|
214 |
|||
215 |
void |
||
216 |
BN_clear_free(BIGNUM *a) |
||
217 |
{ |
||
218 |
int i; |
||
219 |
|||
220 |
✓✓ | 4790972 |
if (a == NULL) |
221 |
31795 |
return; |
|
222 |
bn_check_top(a); |
||
223 |
✓✓✓✗ |
4669485 |
if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) |
224 |
2305794 |
freezero(a->d, a->dmax * sizeof(a->d[0])); |
|
225 |
2363691 |
i = BN_get_flags(a, BN_FLG_MALLOCED); |
|
226 |
2363691 |
explicit_bzero(a, sizeof(BIGNUM)); |
|
227 |
✓✓ | 2363691 |
if (i) |
228 |
304095 |
free(a); |
|
229 |
4759177 |
} |
|
230 |
|||
231 |
void |
||
232 |
BN_free(BIGNUM *a) |
||
233 |
{ |
||
234 |
965850 |
BN_clear_free(a); |
|
235 |
482925 |
} |
|
236 |
|||
237 |
void |
||
238 |
BN_init(BIGNUM *a) |
||
239 |
{ |
||
240 |
14907472 |
memset(a, 0, sizeof(BIGNUM)); |
|
241 |
bn_check_top(a); |
||
242 |
7453736 |
} |
|
243 |
|||
244 |
BIGNUM * |
||
245 |
BN_new(void) |
||
246 |
{ |
||
247 |
BIGNUM *ret; |
||
248 |
|||
249 |
✗✓ | 615192 |
if ((ret = malloc(sizeof(BIGNUM))) == NULL) { |
250 |
BNerror(ERR_R_MALLOC_FAILURE); |
||
251 |
return (NULL); |
||
252 |
} |
||
253 |
307596 |
ret->flags = BN_FLG_MALLOCED; |
|
254 |
307596 |
ret->top = 0; |
|
255 |
307596 |
ret->neg = 0; |
|
256 |
307596 |
ret->dmax = 0; |
|
257 |
307596 |
ret->d = NULL; |
|
258 |
bn_check_top(ret); |
||
259 |
307596 |
return (ret); |
|
260 |
307596 |
} |
|
261 |
|||
262 |
/* This is used both by bn_expand2() and bn_dup_expand() */ |
||
263 |
/* The caller MUST check that words > b->dmax before calling this */ |
||
264 |
static BN_ULONG * |
||
265 |
bn_expand_internal(const BIGNUM *b, int words) |
||
266 |
{ |
||
267 |
BN_ULONG *A, *a = NULL; |
||
268 |
const BN_ULONG *B; |
||
269 |
int i; |
||
270 |
|||
271 |
bn_check_top(b); |
||
272 |
|||
273 |
✓✓ | 9442920 |
if (words > (INT_MAX/(4*BN_BITS2))) { |
274 |
36 |
BNerror(BN_R_BIGNUM_TOO_LONG); |
|
275 |
36 |
return NULL; |
|
276 |
} |
||
277 |
✗✓ | 4721424 |
if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { |
278 |
BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); |
||
279 |
return (NULL); |
||
280 |
} |
||
281 |
4721424 |
a = A = reallocarray(NULL, words, sizeof(BN_ULONG)); |
|
282 |
✗✓ | 4721424 |
if (A == NULL) { |
283 |
BNerror(ERR_R_MALLOC_FAILURE); |
||
284 |
return (NULL); |
||
285 |
} |
||
286 |
#if 1 |
||
287 |
4721424 |
B = b->d; |
|
288 |
/* Check if the previous number needs to be copied */ |
||
289 |
✓✓ | 4721424 |
if (B != NULL) { |
290 |
✓✓ | 10869158 |
for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { |
291 |
/* |
||
292 |
* The fact that the loop is unrolled |
||
293 |
* 4-wise is a tribute to Intel. It's |
||
294 |
* the one that doesn't have enough |
||
295 |
* registers to accommodate more data. |
||
296 |
* I'd unroll it 8-wise otherwise:-) |
||
297 |
* |
||
298 |
* <appro@fy.chalmers.se> |
||
299 |
*/ |
||
300 |
BN_ULONG a0, a1, a2, a3; |
||
301 |
3022507 |
a0 = B[0]; |
|
302 |
3022507 |
a1 = B[1]; |
|
303 |
3022507 |
a2 = B[2]; |
|
304 |
3022507 |
a3 = B[3]; |
|
305 |
3022507 |
A[0] = a0; |
|
306 |
3022507 |
A[1] = a1; |
|
307 |
3022507 |
A[2] = a2; |
|
308 |
3022507 |
A[3] = a3; |
|
309 |
} |
||
310 |
✓✓✓✓ |
4961233 |
switch (b->top & 3) { |
311 |
case 3: |
||
312 |
32192 |
A[2] = B[2]; |
|
313 |
case 2: |
||
314 |
58932 |
A[1] = B[1]; |
|
315 |
case 1: |
||
316 |
178994 |
A[0] = B[0]; |
|
317 |
178994 |
} |
|
318 |
} |
||
319 |
|||
320 |
#else |
||
321 |
memset(A, 0, sizeof(BN_ULONG) * words); |
||
322 |
memcpy(A, b->d, sizeof(b->d[0]) * b->top); |
||
323 |
#endif |
||
324 |
|||
325 |
4721424 |
return (a); |
|
326 |
4721460 |
} |
|
327 |
|||
328 |
/* This is an internal function that can be used instead of bn_expand2() |
||
329 |
* when there is a need to copy BIGNUMs instead of only expanding the |
||
330 |
* data part, while still expanding them. |
||
331 |
* Especially useful when needing to expand BIGNUMs that are declared |
||
332 |
* 'const' and should therefore not be changed. |
||
333 |
* The reason to use this instead of a BN_dup() followed by a bn_expand2() |
||
334 |
* is memory allocation overhead. A BN_dup() followed by a bn_expand2() |
||
335 |
* will allocate new memory for the BIGNUM data twice, and free it once, |
||
336 |
* while bn_dup_expand() makes sure allocation is made only once. |
||
337 |
*/ |
||
338 |
|||
339 |
#ifndef OPENSSL_NO_DEPRECATED |
||
340 |
BIGNUM * |
||
341 |
bn_dup_expand(const BIGNUM *b, int words) |
||
342 |
{ |
||
343 |
BIGNUM *r = NULL; |
||
344 |
|||
345 |
bn_check_top(b); |
||
346 |
|||
347 |
/* This function does not work if |
||
348 |
* words <= b->dmax && top < words |
||
349 |
* because BN_dup() does not preserve 'dmax'! |
||
350 |
* (But bn_dup_expand() is not used anywhere yet.) |
||
351 |
*/ |
||
352 |
|||
353 |
if (words > b->dmax) { |
||
354 |
BN_ULONG *a = bn_expand_internal(b, words); |
||
355 |
|||
356 |
if (a) { |
||
357 |
r = BN_new(); |
||
358 |
if (r) { |
||
359 |
r->top = b->top; |
||
360 |
r->dmax = words; |
||
361 |
r->neg = b->neg; |
||
362 |
r->d = a; |
||
363 |
} else { |
||
364 |
/* r == NULL, BN_new failure */ |
||
365 |
free(a); |
||
366 |
} |
||
367 |
} |
||
368 |
/* If a == NULL, there was an error in allocation in |
||
369 |
bn_expand_internal(), and NULL should be returned */ |
||
370 |
} else { |
||
371 |
r = BN_dup(b); |
||
372 |
} |
||
373 |
|||
374 |
bn_check_top(r); |
||
375 |
return r; |
||
376 |
} |
||
377 |
#endif |
||
378 |
|||
379 |
/* This is an internal function that should not be used in applications. |
||
380 |
* It ensures that 'b' has enough room for a 'words' word number |
||
381 |
* and initialises any unused part of b->d with leading zeros. |
||
382 |
* It is mostly used by the various BIGNUM routines. If there is an error, |
||
383 |
* NULL is returned. If not, 'b' is returned. */ |
||
384 |
|||
385 |
BIGNUM * |
||
386 |
bn_expand2(BIGNUM *b, int words) |
||
387 |
{ |
||
388 |
bn_check_top(b); |
||
389 |
|||
390 |
✓✗ | 9442920 |
if (words > b->dmax) { |
391 |
4721460 |
BN_ULONG *a = bn_expand_internal(b, words); |
|
392 |
✓✓ | 4721460 |
if (!a) |
393 |
36 |
return NULL; |
|
394 |
✓✓ | 4721424 |
if (b->d) |
395 |
2412072 |
freezero(b->d, b->dmax * sizeof(b->d[0])); |
|
396 |
4721424 |
b->d = a; |
|
397 |
4721424 |
b->dmax = words; |
|
398 |
✓✓ | 4721424 |
} |
399 |
|||
400 |
/* None of this should be necessary because of what b->top means! */ |
||
401 |
#if 0 |
||
402 |
/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */ |
||
403 |
if (b->top < b->dmax) { |
||
404 |
int i; |
||
405 |
BN_ULONG *A = &(b->d[b->top]); |
||
406 |
for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) { |
||
407 |
A[0] = 0; |
||
408 |
A[1] = 0; |
||
409 |
A[2] = 0; |
||
410 |
A[3] = 0; |
||
411 |
A[4] = 0; |
||
412 |
A[5] = 0; |
||
413 |
A[6] = 0; |
||
414 |
A[7] = 0; |
||
415 |
} |
||
416 |
for (i = (b->dmax - b->top)&7; i > 0; i--, A++) |
||
417 |
A[0] = 0; |
||
418 |
assert(A == &(b->d[b->dmax])); |
||
419 |
} |
||
420 |
#endif |
||
421 |
bn_check_top(b); |
||
422 |
4721424 |
return b; |
|
423 |
4721460 |
} |
|
424 |
|||
425 |
BIGNUM * |
||
426 |
BN_dup(const BIGNUM *a) |
||
427 |
{ |
||
428 |
BIGNUM *t; |
||
429 |
|||
430 |
✗✓ | 124390 |
if (a == NULL) |
431 |
return NULL; |
||
432 |
bn_check_top(a); |
||
433 |
|||
434 |
62195 |
t = BN_new(); |
|
435 |
✗✓ | 62195 |
if (t == NULL) |
436 |
return NULL; |
||
437 |
✗✓ | 62195 |
if (!BN_copy(t, a)) { |
438 |
BN_free(t); |
||
439 |
return NULL; |
||
440 |
} |
||
441 |
bn_check_top(t); |
||
442 |
62195 |
return t; |
|
443 |
62195 |
} |
|
444 |
|||
445 |
BIGNUM * |
||
446 |
BN_copy(BIGNUM *a, const BIGNUM *b) |
||
447 |
{ |
||
448 |
int i; |
||
449 |
BN_ULONG *A; |
||
450 |
const BN_ULONG *B; |
||
451 |
|||
452 |
bn_check_top(b); |
||
453 |
|||
454 |
✓✓ | 10997242 |
if (a == b) |
455 |
1171 |
return (a); |
|
456 |
✓✓✗✓ |
11406400 |
if (bn_wexpand(a, b->top) == NULL) |
457 |
return (NULL); |
||
458 |
|||
459 |
#if 1 |
||
460 |
5497450 |
A = a->d; |
|
461 |
5497450 |
B = b->d; |
|
462 |
✓✓ | 28175300 |
for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { |
463 |
BN_ULONG a0, a1, a2, a3; |
||
464 |
8590200 |
a0 = B[0]; |
|
465 |
8590200 |
a1 = B[1]; |
|
466 |
8590200 |
a2 = B[2]; |
|
467 |
8590200 |
a3 = B[3]; |
|
468 |
8590200 |
A[0] = a0; |
|
469 |
8590200 |
A[1] = a1; |
|
470 |
8590200 |
A[2] = a2; |
|
471 |
8590200 |
A[3] = a3; |
|
472 |
} |
||
473 |
✓✓✓✓ |
10431220 |
switch (b->top & 3) { |
474 |
case 3: |
||
475 |
958936 |
A[2] = B[2]; |
|
476 |
case 2: |
||
477 |
1376470 |
A[1] = B[1]; |
|
478 |
case 1: |
||
479 |
2598364 |
A[0] = B[0]; |
|
480 |
2598364 |
} |
|
481 |
#else |
||
482 |
memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); |
||
483 |
#endif |
||
484 |
|||
485 |
5497450 |
a->top = b->top; |
|
486 |
5497450 |
a->neg = b->neg; |
|
487 |
bn_check_top(a); |
||
488 |
5497450 |
return (a); |
|
489 |
5498621 |
} |
|
490 |
|||
491 |
void |
||
492 |
BN_swap(BIGNUM *a, BIGNUM *b) |
||
493 |
{ |
||
494 |
int flags_old_a, flags_old_b; |
||
495 |
BN_ULONG *tmp_d; |
||
496 |
int tmp_top, tmp_dmax, tmp_neg; |
||
497 |
|||
498 |
bn_check_top(a); |
||
499 |
bn_check_top(b); |
||
500 |
|||
501 |
flags_old_a = a->flags; |
||
502 |
flags_old_b = b->flags; |
||
503 |
|||
504 |
tmp_d = a->d; |
||
505 |
tmp_top = a->top; |
||
506 |
tmp_dmax = a->dmax; |
||
507 |
tmp_neg = a->neg; |
||
508 |
|||
509 |
a->d = b->d; |
||
510 |
a->top = b->top; |
||
511 |
a->dmax = b->dmax; |
||
512 |
a->neg = b->neg; |
||
513 |
|||
514 |
b->d = tmp_d; |
||
515 |
b->top = tmp_top; |
||
516 |
b->dmax = tmp_dmax; |
||
517 |
b->neg = tmp_neg; |
||
518 |
|||
519 |
a->flags = (flags_old_a & BN_FLG_MALLOCED) | |
||
520 |
(flags_old_b & BN_FLG_STATIC_DATA); |
||
521 |
b->flags = (flags_old_b & BN_FLG_MALLOCED) | |
||
522 |
(flags_old_a & BN_FLG_STATIC_DATA); |
||
523 |
bn_check_top(a); |
||
524 |
bn_check_top(b); |
||
525 |
} |
||
526 |
|||
527 |
void |
||
528 |
BN_clear(BIGNUM *a) |
||
529 |
{ |
||
530 |
bn_check_top(a); |
||
531 |
✓✗ | 1320 |
if (a->d != NULL) |
532 |
660 |
memset(a->d, 0, a->dmax * sizeof(a->d[0])); |
|
533 |
660 |
a->top = 0; |
|
534 |
660 |
a->neg = 0; |
|
535 |
660 |
} |
|
536 |
|||
537 |
BN_ULONG |
||
538 |
BN_get_word(const BIGNUM *a) |
||
539 |
{ |
||
540 |
✗✓ | 29208 |
if (a->top > 1) |
541 |
return BN_MASK2; |
||
542 |
✓✓ | 14604 |
else if (a->top == 1) |
543 |
12752 |
return a->d[0]; |
|
544 |
/* a->top == 0 */ |
||
545 |
1852 |
return 0; |
|
546 |
14604 |
} |
|
547 |
|||
548 |
BIGNUM * |
||
549 |
bn_expand(BIGNUM *a, int bits) |
||
550 |
{ |
||
551 |
✗✓ | 112268742 |
if (bits > (INT_MAX - BN_BITS2 + 1)) |
552 |
return (NULL); |
||
553 |
|||
554 |
✓✓ | 56134371 |
if (((bits + BN_BITS2 - 1) / BN_BITS2) <= a->dmax) |
555 |
54420747 |
return (a); |
|
556 |
|||
557 |
1713624 |
return bn_expand2(a, (bits + BN_BITS2 - 1) / BN_BITS2); |
|
558 |
56134371 |
} |
|
559 |
|||
560 |
int |
||
561 |
BN_set_word(BIGNUM *a, BN_ULONG w) |
||
562 |
{ |
||
563 |
bn_check_top(a); |
||
564 |
✗✓ | 112266934 |
if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL) |
565 |
return (0); |
||
566 |
56133467 |
a->neg = 0; |
|
567 |
56133467 |
a->d[0] = w; |
|
568 |
56133467 |
a->top = (w ? 1 : 0); |
|
569 |
bn_check_top(a); |
||
570 |
56133467 |
return (1); |
|
571 |
56133467 |
} |
|
572 |
|||
573 |
BIGNUM * |
||
574 |
BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) |
||
575 |
{ |
||
576 |
unsigned int i, m; |
||
577 |
unsigned int n; |
||
578 |
BN_ULONG l; |
||
579 |
BIGNUM *bn = NULL; |
||
580 |
|||
581 |
✓✓ | 1049402 |
if (ret == NULL) |
582 |
22866 |
ret = bn = BN_new(); |
|
583 |
✗✓ | 524701 |
if (ret == NULL) |
584 |
return (NULL); |
||
585 |
bn_check_top(ret); |
||
586 |
l = 0; |
||
587 |
n = len; |
||
588 |
✓✓ | 524701 |
if (n == 0) { |
589 |
36 |
ret->top = 0; |
|
590 |
36 |
return (ret); |
|
591 |
} |
||
592 |
524665 |
i = ((n - 1) / BN_BYTES) + 1; |
|
593 |
524665 |
m = ((n - 1) % (BN_BYTES)); |
|
594 |
✓✓✓✓ |
1470473 |
if (bn_wexpand(ret, (int)i) == NULL) { |
595 |
36 |
BN_free(bn); |
|
596 |
36 |
return NULL; |
|
597 |
} |
||
598 |
524629 |
ret->top = i; |
|
599 |
524629 |
ret->neg = 0; |
|
600 |
✓✓ | 108367534 |
while (n--) { |
601 |
107318276 |
l = (l << 8L) | *(s++); |
|
602 |
✓✓ | 107318276 |
if (m-- == 0) { |
603 |
13457781 |
ret->d[--i] = l; |
|
604 |
l = 0; |
||
605 |
m = BN_BYTES - 1; |
||
606 |
13457781 |
} |
|
607 |
} |
||
608 |
/* need to call this due to clear byte at top if avoiding |
||
609 |
* having the top bit set (-ve number) */ |
||
610 |
✓✗✓✓ ✓✓ |
2670389 |
bn_correct_top(ret); |
611 |
524629 |
return (ret); |
|
612 |
524701 |
} |
|
613 |
|||
614 |
/* ignore negative */ |
||
615 |
int |
||
616 |
BN_bn2bin(const BIGNUM *a, unsigned char *to) |
||
617 |
{ |
||
618 |
int n, i; |
||
619 |
BN_ULONG l; |
||
620 |
|||
621 |
bn_check_top(a); |
||
622 |
795608 |
n = i=BN_num_bytes(a); |
|
623 |
✓✓ | 190242382 |
while (i--) { |
624 |
94723387 |
l = a->d[i / BN_BYTES]; |
|
625 |
94723387 |
*(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; |
|
626 |
} |
||
627 |
397804 |
return (n); |
|
628 |
} |
||
629 |
|||
630 |
int |
||
631 |
BN_ucmp(const BIGNUM *a, const BIGNUM *b) |
||
632 |
{ |
||
633 |
int i; |
||
634 |
BN_ULONG t1, t2, *ap, *bp; |
||
635 |
|||
636 |
bn_check_top(a); |
||
637 |
bn_check_top(b); |
||
638 |
|||
639 |
52120310 |
i = a->top - b->top; |
|
640 |
✓✓ | 26060155 |
if (i != 0) |
641 |
6609393 |
return (i); |
|
642 |
19450762 |
ap = a->d; |
|
643 |
19450762 |
bp = b->d; |
|
644 |
✓✓ | 41841334 |
for (i = a->top - 1; i >= 0; i--) { |
645 |
20775870 |
t1 = ap[i]; |
|
646 |
20775870 |
t2 = bp[i]; |
|
647 |
✓✓ | 20775870 |
if (t1 != t2) |
648 |
19305965 |
return ((t1 > t2) ? 1 : -1); |
|
649 |
} |
||
650 |
144797 |
return (0); |
|
651 |
26060155 |
} |
|
652 |
|||
653 |
int |
||
654 |
BN_cmp(const BIGNUM *a, const BIGNUM *b) |
||
655 |
{ |
||
656 |
int i; |
||
657 |
int gt, lt; |
||
658 |
BN_ULONG t1, t2; |
||
659 |
|||
660 |
✗✓ | 23364018 |
if ((a == NULL) || (b == NULL)) { |
661 |
if (a != NULL) |
||
662 |
return (-1); |
||
663 |
else if (b != NULL) |
||
664 |
return (1); |
||
665 |
else |
||
666 |
return (0); |
||
667 |
} |
||
668 |
|||
669 |
bn_check_top(a); |
||
670 |
bn_check_top(b); |
||
671 |
|||
672 |
✓✓ | 11682009 |
if (a->neg != b->neg) { |
673 |
✓✓ | 27 |
if (a->neg) |
674 |
2 |
return (-1); |
|
675 |
else |
||
676 |
25 |
return (1); |
|
677 |
} |
||
678 |
✓✗ | 11681982 |
if (a->neg == 0) { |
679 |
gt = 1; |
||
680 |
lt = -1; |
||
681 |
11681982 |
} else { |
|
682 |
gt = -1; |
||
683 |
lt = 1; |
||
684 |
} |
||
685 |
|||
686 |
✓✓ | 11681982 |
if (a->top > b->top) |
687 |
4049227 |
return (gt); |
|
688 |
✓✓ | 7632755 |
if (a->top < b->top) |
689 |
9036 |
return (lt); |
|
690 |
✓✓ | 15463176 |
for (i = a->top - 1; i >= 0; i--) { |
691 |
7705768 |
t1 = a->d[i]; |
|
692 |
7705768 |
t2 = b->d[i]; |
|
693 |
✓✓ | 7705768 |
if (t1 > t2) |
694 |
2442103 |
return (gt); |
|
695 |
✓✓ | 5263665 |
if (t1 < t2) |
696 |
5155796 |
return (lt); |
|
697 |
} |
||
698 |
25820 |
return (0); |
|
699 |
11682009 |
} |
|
700 |
|||
701 |
int |
||
702 |
BN_set_bit(BIGNUM *a, int n) |
||
703 |
{ |
||
704 |
int i, j, k; |
||
705 |
|||
706 |
✗✓ | 174392 |
if (n < 0) |
707 |
return 0; |
||
708 |
|||
709 |
87196 |
i = n / BN_BITS2; |
|
710 |
87196 |
j = n % BN_BITS2; |
|
711 |
✓✓ | 87196 |
if (a->top <= i) { |
712 |
✓✓✗✓ |
255141 |
if (bn_wexpand(a, i + 1) == NULL) |
713 |
return (0); |
||
714 |
✓✓ | 2929628 |
for (k = a->top; k < i + 1; k++) |
715 |
1378450 |
a->d[k] = 0; |
|
716 |
86364 |
a->top = i + 1; |
|
717 |
86364 |
} |
|
718 |
|||
719 |
87196 |
a->d[i] |= (((BN_ULONG)1) << j); |
|
720 |
bn_check_top(a); |
||
721 |
87196 |
return (1); |
|
722 |
87196 |
} |
|
723 |
|||
724 |
int |
||
725 |
BN_clear_bit(BIGNUM *a, int n) |
||
726 |
{ |
||
727 |
int i, j; |
||
728 |
|||
729 |
bn_check_top(a); |
||
730 |
if (n < 0) |
||
731 |
return 0; |
||
732 |
|||
733 |
i = n / BN_BITS2; |
||
734 |
j = n % BN_BITS2; |
||
735 |
if (a->top <= i) |
||
736 |
return (0); |
||
737 |
|||
738 |
a->d[i] &= (~(((BN_ULONG)1) << j)); |
||
739 |
bn_correct_top(a); |
||
740 |
return (1); |
||
741 |
} |
||
742 |
|||
743 |
int |
||
744 |
BN_is_bit_set(const BIGNUM *a, int n) |
||
745 |
{ |
||
746 |
int i, j; |
||
747 |
|||
748 |
bn_check_top(a); |
||
749 |
✓✓ | 182955570 |
if (n < 0) |
750 |
39 |
return 0; |
|
751 |
91477746 |
i = n / BN_BITS2; |
|
752 |
91477746 |
j = n % BN_BITS2; |
|
753 |
✓✓ | 91477746 |
if (a->top <= i) |
754 |
14304 |
return 0; |
|
755 |
91463442 |
return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); |
|
756 |
91477785 |
} |
|
757 |
|||
758 |
int |
||
759 |
BN_mask_bits(BIGNUM *a, int n) |
||
760 |
{ |
||
761 |
int b, w; |
||
762 |
|||
763 |
bn_check_top(a); |
||
764 |
✗✓ | 5422 |
if (n < 0) |
765 |
return 0; |
||
766 |
|||
767 |
2711 |
w = n / BN_BITS2; |
|
768 |
2711 |
b = n % BN_BITS2; |
|
769 |
✗✓ | 2711 |
if (w >= a->top) |
770 |
return 0; |
||
771 |
✗✓ | 2711 |
if (b == 0) |
772 |
a->top = w; |
||
773 |
else { |
||
774 |
2711 |
a->top = w + 1; |
|
775 |
2711 |
a->d[w] &= ~(BN_MASK2 << b); |
|
776 |
} |
||
777 |
✓✗✓✗ ✗✓ |
13555 |
bn_correct_top(a); |
778 |
2711 |
return (1); |
|
779 |
2711 |
} |
|
780 |
|||
781 |
void |
||
782 |
BN_set_negative(BIGNUM *a, int b) |
||
783 |
{ |
||
784 |
✓✓✓✗ |
455207 |
if (b && !BN_is_zero(a)) |
785 |
99 |
a->neg = 1; |
|
786 |
else |
||
787 |
a->neg = 0; |
||
788 |
227554 |
} |
|
789 |
|||
790 |
int |
||
791 |
bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) |
||
792 |
{ |
||
793 |
int i; |
||
794 |
BN_ULONG aa, bb; |
||
795 |
|||
796 |
1677788 |
aa = a[n - 1]; |
|
797 |
838894 |
bb = b[n - 1]; |
|
798 |
✓✓ | 838894 |
if (aa != bb) |
799 |
818518 |
return ((aa > bb) ? 1 : -1); |
|
800 |
✓✓ | 127272 |
for (i = n - 2; i >= 0; i--) { |
801 |
63420 |
aa = a[i]; |
|
802 |
63420 |
bb = b[i]; |
|
803 |
✓✓ | 63420 |
if (aa != bb) |
804 |
20160 |
return ((aa > bb) ? 1 : -1); |
|
805 |
} |
||
806 |
216 |
return (0); |
|
807 |
838894 |
} |
|
808 |
|||
809 |
/* Here follows a specialised variants of bn_cmp_words(). It has the |
||
810 |
property of performing the operation on arrays of different sizes. |
||
811 |
The sizes of those arrays is expressed through cl, which is the |
||
812 |
common length ( basicall, min(len(a),len(b)) ), and dl, which is the |
||
813 |
delta between the two lengths, calculated as len(a)-len(b). |
||
814 |
All lengths are the number of BN_ULONGs... */ |
||
815 |
|||
816 |
int |
||
817 |
bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl) |
||
818 |
{ |
||
819 |
int n, i; |
||
820 |
|||
821 |
1374012 |
n = cl - 1; |
|
822 |
|||
823 |
✓✓ | 687006 |
if (dl < 0) { |
824 |
✓✓ | 25250 |
for (i = dl; i < 0; i++) { |
825 |
✓✓ | 12613 |
if (b[n - i] != 0) |
826 |
12145 |
return -1; /* a < b */ |
|
827 |
} |
||
828 |
} |
||
829 |
✓✓ | 674861 |
if (dl > 0) { |
830 |
✓✓ | 27448 |
for (i = dl; i > 0; i--) { |
831 |
✓✓ | 13712 |
if (a[n + i] != 0) |
832 |
13254 |
return 1; /* a > b */ |
|
833 |
} |
||
834 |
} |
||
835 |
661607 |
return bn_cmp_words(a, b, cl); |
|
836 |
687006 |
} |
|
837 |
|||
838 |
/* |
||
839 |
* Constant-time conditional swap of a and b. |
||
840 |
* a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. |
||
841 |
* nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, |
||
842 |
* and that no more than nwords are used by either a or b. |
||
843 |
* a and b cannot be the same number |
||
844 |
*/ |
||
845 |
void |
||
846 |
BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) |
||
847 |
{ |
||
848 |
BN_ULONG t; |
||
849 |
int i; |
||
850 |
|||
851 |
bn_wcheck_size(a, nwords); |
||
852 |
bn_wcheck_size(b, nwords); |
||
853 |
|||
854 |
assert(a != b); |
||
855 |
assert((condition & (condition - 1)) == 0); |
||
856 |
assert(sizeof(BN_ULONG) >= sizeof(int)); |
||
857 |
|||
858 |
23966396 |
condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; |
|
859 |
|||
860 |
20134160 |
t = (a->top^b->top) & condition; |
|
861 |
20134160 |
a->top ^= t; |
|
862 |
20134160 |
b->top ^= t; |
|
863 |
|||
864 |
#define BN_CONSTTIME_SWAP(ind) \ |
||
865 |
do { \ |
||
866 |
t = (a->d[ind] ^ b->d[ind]) & condition; \ |
||
867 |
a->d[ind] ^= t; \ |
||
868 |
b->d[ind] ^= t; \ |
||
869 |
} while (0) |
||
870 |
|||
871 |
|||
872 |
✗✗✓✓ ✓✓✓✓ ✓✓✓ |
20134160 |
switch (nwords) { |
873 |
default: |
||
874 |
for (i = 10; i < nwords; i++) |
||
875 |
BN_CONSTTIME_SWAP(i); |
||
876 |
/* Fallthrough */ |
||
877 |
case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ |
||
878 |
608936 |
case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ |
|
879 |
608936 |
case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ |
|
880 |
1161456 |
case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ |
|
881 |
1436416 |
case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ |
|
882 |
1921180 |
case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ |
|
883 |
2914776 |
case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ |
|
884 |
3817988 |
case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ |
|
885 |
3832236 |
case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ |
|
886 |
case 1: |
||
887 |
3832236 |
BN_CONSTTIME_SWAP(0); |
|
888 |
} |
||
889 |
#undef BN_CONSTTIME_SWAP |
||
890 |
3832236 |
} |
Generated by: GCOVR (Version 3.3) |