GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: bn_exp.c,v 1.23 2015/09/10 15:56:25 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 |
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. |
||
60 |
* |
||
61 |
* Redistribution and use in source and binary forms, with or without |
||
62 |
* modification, are permitted provided that the following conditions |
||
63 |
* are met: |
||
64 |
* |
||
65 |
* 1. Redistributions of source code must retain the above copyright |
||
66 |
* notice, this list of conditions and the following disclaimer. |
||
67 |
* |
||
68 |
* 2. Redistributions in binary form must reproduce the above copyright |
||
69 |
* notice, this list of conditions and the following disclaimer in |
||
70 |
* the documentation and/or other materials provided with the |
||
71 |
* distribution. |
||
72 |
* |
||
73 |
* 3. All advertising materials mentioning features or use of this |
||
74 |
* software must display the following acknowledgment: |
||
75 |
* "This product includes software developed by the OpenSSL Project |
||
76 |
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
||
77 |
* |
||
78 |
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
||
79 |
* endorse or promote products derived from this software without |
||
80 |
* prior written permission. For written permission, please contact |
||
81 |
* openssl-core@openssl.org. |
||
82 |
* |
||
83 |
* 5. Products derived from this software may not be called "OpenSSL" |
||
84 |
* nor may "OpenSSL" appear in their names without prior written |
||
85 |
* permission of the OpenSSL Project. |
||
86 |
* |
||
87 |
* 6. Redistributions of any form whatsoever must retain the following |
||
88 |
* acknowledgment: |
||
89 |
* "This product includes software developed by the OpenSSL Project |
||
90 |
* for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
||
91 |
* |
||
92 |
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
||
93 |
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
94 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||
95 |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
||
96 |
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||
97 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||
98 |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
99 |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||
100 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||
101 |
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
102 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
||
103 |
* OF THE POSSIBILITY OF SUCH DAMAGE. |
||
104 |
* ==================================================================== |
||
105 |
* |
||
106 |
* This product includes cryptographic software written by Eric Young |
||
107 |
* (eay@cryptsoft.com). This product includes software written by Tim |
||
108 |
* Hudson (tjh@cryptsoft.com). |
||
109 |
* |
||
110 |
*/ |
||
111 |
|||
112 |
#include <stdlib.h> |
||
113 |
#include <string.h> |
||
114 |
|||
115 |
#include <openssl/err.h> |
||
116 |
|||
117 |
#include "bn_lcl.h" |
||
118 |
|||
119 |
/* maximum precomputation table size for *variable* sliding windows */ |
||
120 |
#define TABLE_SIZE 32 |
||
121 |
|||
122 |
/* this one works - simple but works */ |
||
123 |
int |
||
124 |
BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) |
||
125 |
15 |
{ |
|
126 |
15 |
int i, bits, ret = 0; |
|
127 |
BIGNUM *v, *rr; |
||
128 |
|||
129 |
✗✓ | 15 |
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { |
130 |
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ |
||
131 |
BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
||
132 |
return -1; |
||
133 |
} |
||
134 |
|||
135 |
15 |
BN_CTX_start(ctx); |
|
136 |
✗✓ | 15 |
if ((r == a) || (r == p)) |
137 |
rr = BN_CTX_get(ctx); |
||
138 |
else |
||
139 |
15 |
rr = r; |
|
140 |
15 |
v = BN_CTX_get(ctx); |
|
141 |
✗✓ | 15 |
if (rr == NULL || v == NULL) |
142 |
goto err; |
||
143 |
|||
144 |
✗✓ | 15 |
if (BN_copy(v, a) == NULL) |
145 |
goto err; |
||
146 |
15 |
bits = BN_num_bits(p); |
|
147 |
|||
148 |
✓✗✓✓ |
15 |
if (BN_is_odd(p)) { |
149 |
✗✓ | 7 |
if (BN_copy(rr, a) == NULL) |
150 |
goto err; |
||
151 |
} else { |
||
152 |
✗✓ | 8 |
if (!BN_one(rr)) |
153 |
goto err; |
||
154 |
} |
||
155 |
|||
156 |
✓✓ | 60 |
for (i = 1; i < bits; i++) { |
157 |
✗✓ | 45 |
if (!BN_sqr(v, v, ctx)) |
158 |
goto err; |
||
159 |
✓✓ | 45 |
if (BN_is_bit_set(p, i)) { |
160 |
✗✓ | 34 |
if (!BN_mul(rr, rr, v, ctx)) |
161 |
goto err; |
||
162 |
} |
||
163 |
} |
||
164 |
15 |
ret = 1; |
|
165 |
|||
166 |
15 |
err: |
|
167 |
✗✓ | 15 |
if (r != rr && rr != NULL) |
168 |
BN_copy(r, rr); |
||
169 |
15 |
BN_CTX_end(ctx); |
|
170 |
bn_check_top(r); |
||
171 |
15 |
return (ret); |
|
172 |
} |
||
173 |
|||
174 |
int |
||
175 |
BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, |
||
176 |
BN_CTX *ctx) |
||
177 |
220 |
{ |
|
178 |
int ret; |
||
179 |
|||
180 |
bn_check_top(a); |
||
181 |
bn_check_top(p); |
||
182 |
bn_check_top(m); |
||
183 |
|||
184 |
/* For even modulus m = 2^k*m_odd, it might make sense to compute |
||
185 |
* a^p mod m_odd and a^p mod 2^k separately (with Montgomery |
||
186 |
* exponentiation for the odd part), using appropriate exponent |
||
187 |
* reductions, and combine the results using the CRT. |
||
188 |
* |
||
189 |
* For now, we use Montgomery only if the modulus is odd; otherwise, |
||
190 |
* exponentiation using the reciprocal-based quick remaindering |
||
191 |
* algorithm is used. |
||
192 |
* |
||
193 |
* (Timing obtained with expspeed.c [computations a^p mod m |
||
194 |
* where a, p, m are of the same length: 256, 512, 1024, 2048, |
||
195 |
* 4096, 8192 bits], compared to the running time of the |
||
196 |
* standard algorithm: |
||
197 |
* |
||
198 |
* BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration] |
||
199 |
* 55 .. 77 % [UltraSparc processor, but |
||
200 |
* debug-solaris-sparcv8-gcc conf.] |
||
201 |
* |
||
202 |
* BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration] |
||
203 |
* 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc] |
||
204 |
* |
||
205 |
* On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont |
||
206 |
* at 2048 and more bits, but at 512 and 1024 bits, it was |
||
207 |
* slower even than the standard algorithm! |
||
208 |
* |
||
209 |
* "Real" timings [linux-elf, solaris-sparcv9-gcc configurations] |
||
210 |
* should be obtained when the new Montgomery reduction code |
||
211 |
* has been integrated into OpenSSL.) |
||
212 |
*/ |
||
213 |
|||
214 |
#define MONT_MUL_MOD |
||
215 |
#define MONT_EXP_WORD |
||
216 |
#define RECP_MUL_MOD |
||
217 |
|||
218 |
#ifdef MONT_MUL_MOD |
||
219 |
/* I have finally been able to take out this pre-condition of |
||
220 |
* the top bit being set. It was caused by an error in BN_div |
||
221 |
* with negatives. There was also another problem when for a^b%m |
||
222 |
* a >= m. eay 07-May-97 */ |
||
223 |
/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ |
||
224 |
|||
225 |
✓✗✓✗ |
220 |
if (BN_is_odd(m)) { |
226 |
# ifdef MONT_EXP_WORD |
||
227 |
✓✓✓✗ ✓✗ |
270 |
if (a->top == 1 && !a->neg && |
228 |
(BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) { |
||
229 |
50 |
BN_ULONG A = a->d[0]; |
|
230 |
50 |
ret = BN_mod_exp_mont_word(r, A,p, m,ctx, NULL); |
|
231 |
} else |
||
232 |
# endif |
||
233 |
170 |
ret = BN_mod_exp_mont(r, a,p, m,ctx, NULL); |
|
234 |
} else |
||
235 |
#endif |
||
236 |
#ifdef RECP_MUL_MOD |
||
237 |
{ |
||
238 |
ret = BN_mod_exp_recp(r, a,p, m, ctx); |
||
239 |
} |
||
240 |
#else |
||
241 |
{ |
||
242 |
ret = BN_mod_exp_simple(r, a,p, m, ctx); |
||
243 |
} |
||
244 |
#endif |
||
245 |
|||
246 |
bn_check_top(r); |
||
247 |
220 |
return (ret); |
|
248 |
} |
||
249 |
|||
250 |
int |
||
251 |
BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, |
||
252 |
BN_CTX *ctx) |
||
253 |
300 |
{ |
|
254 |
300 |
int i, j, bits, ret = 0, wstart, wend, window, wvalue; |
|
255 |
300 |
int start = 1; |
|
256 |
BIGNUM *aa; |
||
257 |
/* Table of variables obtained from 'ctx' */ |
||
258 |
BIGNUM *val[TABLE_SIZE]; |
||
259 |
BN_RECP_CTX recp; |
||
260 |
|||
261 |
✗✓ | 300 |
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { |
262 |
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ |
||
263 |
BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
||
264 |
return -1; |
||
265 |
} |
||
266 |
|||
267 |
300 |
bits = BN_num_bits(p); |
|
268 |
|||
269 |
✗✓ | 300 |
if (bits == 0) { |
270 |
ret = BN_one(r); |
||
271 |
return ret; |
||
272 |
} |
||
273 |
|||
274 |
300 |
BN_CTX_start(ctx); |
|
275 |
✗✓ | 300 |
if ((aa = BN_CTX_get(ctx)) == NULL) |
276 |
goto err; |
||
277 |
✗✓ | 300 |
if ((val[0] = BN_CTX_get(ctx)) == NULL) |
278 |
goto err; |
||
279 |
|||
280 |
300 |
BN_RECP_CTX_init(&recp); |
|
281 |
✗✓ | 300 |
if (m->neg) { |
282 |
/* ignore sign of 'm' */ |
||
283 |
if (!BN_copy(aa, m)) |
||
284 |
goto err; |
||
285 |
aa->neg = 0; |
||
286 |
if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0) |
||
287 |
goto err; |
||
288 |
} else { |
||
289 |
✗✓ | 300 |
if (BN_RECP_CTX_set(&recp, m, ctx) <= 0) |
290 |
goto err; |
||
291 |
} |
||
292 |
|||
293 |
✗✓ | 300 |
if (!BN_nnmod(val[0], a, m, ctx)) |
294 |
goto err; /* 1 */ |
||
295 |
✗✓ | 300 |
if (BN_is_zero(val[0])) { |
296 |
BN_zero(r); |
||
297 |
ret = 1; |
||
298 |
goto err; |
||
299 |
} |
||
300 |
|||
301 |
✓✗✗✓ ✗✗✗✗ |
300 |
window = BN_window_bits_for_exponent_size(bits); |
302 |
✓✗ | 300 |
if (window > 1) { |
303 |
✗✓ | 300 |
if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) |
304 |
goto err; /* 2 */ |
||
305 |
300 |
j = 1 << (window - 1); |
|
306 |
✓✓ | 4800 |
for (i = 1; i < j; i++) { |
307 |
✓✗✓✗ |
4500 |
if (((val[i] = BN_CTX_get(ctx)) == NULL) || |
308 |
!BN_mod_mul_reciprocal(val[i], val[i - 1], |
||
309 |
aa, &recp, ctx)) |
||
310 |
goto err; |
||
311 |
} |
||
312 |
} |
||
313 |
|||
314 |
300 |
start = 1; /* This is used to avoid multiplication etc |
|
315 |
* when there is only the value '1' in the |
||
316 |
* buffer. */ |
||
317 |
300 |
wvalue = 0; /* The 'value' of the window */ |
|
318 |
300 |
wstart = bits - 1; /* The top bit of the window */ |
|
319 |
300 |
wend = 0; /* The bottom bit of the window */ |
|
320 |
|||
321 |
✗✓ | 300 |
if (!BN_one(r)) |
322 |
goto err; |
||
323 |
|||
324 |
for (;;) { |
||
325 |
✓✓ | 57447 |
if (BN_is_bit_set(p, wstart) == 0) { |
326 |
✓✗ | 37844 |
if (!start) |
327 |
✗✓ | 37844 |
if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx)) |
328 |
goto err; |
||
329 |
✓✓ | 37844 |
if (wstart == 0) |
330 |
216 |
break; |
|
331 |
37628 |
wstart--; |
|
332 |
37628 |
continue; |
|
333 |
} |
||
334 |
/* We now have wstart on a 'set' bit, we now need to work out |
||
335 |
* how bit a window to do. To do this we need to scan |
||
336 |
* forward until the last set bit before the end of the |
||
337 |
* window */ |
||
338 |
19603 |
j = wstart; |
|
339 |
19603 |
wvalue = 1; |
|
340 |
19603 |
wend = 0; |
|
341 |
✓✓ | 97698 |
for (i = 1; i < window; i++) { |
342 |
✓✓ | 78222 |
if (wstart - i < 0) |
343 |
127 |
break; |
|
344 |
✓✓ | 78095 |
if (BN_is_bit_set(p, wstart - i)) { |
345 |
38915 |
wvalue <<= (i - wend); |
|
346 |
38915 |
wvalue |= 1; |
|
347 |
38915 |
wend = i; |
|
348 |
} |
||
349 |
} |
||
350 |
|||
351 |
/* wend is the size of the current window */ |
||
352 |
19603 |
j = wend + 1; |
|
353 |
/* add the 'bytes above' */ |
||
354 |
✓✓ | 19603 |
if (!start) |
355 |
✓✓ | 96940 |
for (i = 0; i < j; i++) { |
356 |
✗✓ | 77637 |
if (!BN_mod_mul_reciprocal(r, r,r, &recp, ctx)) |
357 |
goto err; |
||
358 |
} |
||
359 |
|||
360 |
/* wvalue will be an odd number < 2^window */ |
||
361 |
✗✓ | 19603 |
if (!BN_mod_mul_reciprocal(r, r,val[wvalue >> 1], &recp, ctx)) |
362 |
goto err; |
||
363 |
|||
364 |
/* move the 'window' down further */ |
||
365 |
19603 |
wstart -= wend + 1; |
|
366 |
19603 |
wvalue = 0; |
|
367 |
19603 |
start = 0; |
|
368 |
✓✓ | 19603 |
if (wstart < 0) |
369 |
84 |
break; |
|
370 |
} |
||
371 |
300 |
ret = 1; |
|
372 |
|||
373 |
300 |
err: |
|
374 |
300 |
BN_CTX_end(ctx); |
|
375 |
300 |
BN_RECP_CTX_free(&recp); |
|
376 |
bn_check_top(r); |
||
377 |
300 |
return (ret); |
|
378 |
} |
||
379 |
|||
380 |
int |
||
381 |
BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, |
||
382 |
BN_CTX *ctx, BN_MONT_CTX *in_mont) |
||
383 |
2060 |
{ |
|
384 |
2060 |
int i, j, bits, ret = 0, wstart, wend, window, wvalue; |
|
385 |
2060 |
int start = 1; |
|
386 |
BIGNUM *d, *r; |
||
387 |
const BIGNUM *aa; |
||
388 |
/* Table of variables obtained from 'ctx' */ |
||
389 |
BIGNUM *val[TABLE_SIZE]; |
||
390 |
2060 |
BN_MONT_CTX *mont = NULL; |
|
391 |
|||
392 |
✓✓ | 2060 |
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { |
393 |
46 |
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); |
|
394 |
} |
||
395 |
|||
396 |
bn_check_top(a); |
||
397 |
bn_check_top(p); |
||
398 |
bn_check_top(m); |
||
399 |
|||
400 |
✓✗✗✓ |
2014 |
if (!BN_is_odd(m)) { |
401 |
BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); |
||
402 |
return (0); |
||
403 |
} |
||
404 |
2014 |
bits = BN_num_bits(p); |
|
405 |
✗✓ | 2014 |
if (bits == 0) { |
406 |
ret = BN_one(rr); |
||
407 |
return ret; |
||
408 |
} |
||
409 |
|||
410 |
2014 |
BN_CTX_start(ctx); |
|
411 |
✗✓ | 2014 |
if ((d = BN_CTX_get(ctx)) == NULL) |
412 |
goto err; |
||
413 |
✗✓ | 2014 |
if ((r = BN_CTX_get(ctx)) == NULL) |
414 |
goto err; |
||
415 |
✗✓ | 2014 |
if ((val[0] = BN_CTX_get(ctx)) == NULL) |
416 |
goto err; |
||
417 |
|||
418 |
/* If this is not done, things will break in the montgomery |
||
419 |
* part */ |
||
420 |
|||
421 |
✓✓ | 2014 |
if (in_mont != NULL) |
422 |
1646 |
mont = in_mont; |
|
423 |
else { |
||
424 |
✗✓ | 368 |
if ((mont = BN_MONT_CTX_new()) == NULL) |
425 |
goto err; |
||
426 |
✗✓ | 368 |
if (!BN_MONT_CTX_set(mont, m, ctx)) |
427 |
goto err; |
||
428 |
} |
||
429 |
|||
430 |
✓✗✓✓ |
2133 |
if (a->neg || BN_ucmp(a, m) >= 0) { |
431 |
✗✓ | 119 |
if (!BN_nnmod(val[0], a,m, ctx)) |
432 |
goto err; |
||
433 |
119 |
aa = val[0]; |
|
434 |
} else |
||
435 |
1895 |
aa = a; |
|
436 |
✓✓ | 2014 |
if (BN_is_zero(aa)) { |
437 |
3 |
BN_zero(rr); |
|
438 |
3 |
ret = 1; |
|
439 |
3 |
goto err; |
|
440 |
} |
||
441 |
✗✓ | 2011 |
if (!BN_to_montgomery(val[0], aa, mont, ctx)) |
442 |
goto err; /* 1 */ |
||
443 |
|||
444 |
✓✓✓✓ ✓✓✓✓ |
2011 |
window = BN_window_bits_for_exponent_size(bits); |
445 |
✓✓ | 2011 |
if (window > 1) { |
446 |
✗✓ | 1971 |
if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) |
447 |
goto err; /* 2 */ |
||
448 |
1971 |
j = 1 << (window - 1); |
|
449 |
✓✓ | 18228 |
for (i = 1; i < j; i++) { |
450 |
✓✗✓✗ |
16257 |
if (((val[i] = BN_CTX_get(ctx)) == NULL) || |
451 |
!BN_mod_mul_montgomery(val[i], val[i - 1], |
||
452 |
d, mont, ctx)) |
||
453 |
goto err; |
||
454 |
} |
||
455 |
} |
||
456 |
|||
457 |
2011 |
start = 1; /* This is used to avoid multiplication etc |
|
458 |
* when there is only the value '1' in the |
||
459 |
* buffer. */ |
||
460 |
2011 |
wvalue = 0; /* The 'value' of the window */ |
|
461 |
2011 |
wstart = bits - 1; /* The top bit of the window */ |
|
462 |
2011 |
wend = 0; /* The bottom bit of the window */ |
|
463 |
|||
464 |
✗✓ | 2011 |
if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) |
465 |
goto err; |
||
466 |
for (;;) { |
||
467 |
✓✓ | 172078 |
if (BN_is_bit_set(p, wstart) == 0) { |
468 |
✓✗ | 109670 |
if (!start) { |
469 |
✗✓ | 109670 |
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) |
470 |
goto err; |
||
471 |
} |
||
472 |
✓✓ | 109670 |
if (wstart == 0) |
473 |
198 |
break; |
|
474 |
109472 |
wstart--; |
|
475 |
109472 |
continue; |
|
476 |
} |
||
477 |
/* We now have wstart on a 'set' bit, we now need to work out |
||
478 |
* how bit a window to do. To do this we need to scan |
||
479 |
* forward until the last set bit before the end of the |
||
480 |
* window */ |
||
481 |
62408 |
j = wstart; |
|
482 |
62408 |
wvalue = 1; |
|
483 |
62408 |
wend = 0; |
|
484 |
✓✓ | 287528 |
for (i = 1; i < window; i++) { |
485 |
✓✓ | 226562 |
if (wstart - i < 0) |
486 |
1442 |
break; |
|
487 |
✓✓ | 225120 |
if (BN_is_bit_set(p, wstart - i)) { |
488 |
119624 |
wvalue <<= (i - wend); |
|
489 |
119624 |
wvalue |= 1; |
|
490 |
119624 |
wend = i; |
|
491 |
} |
||
492 |
} |
||
493 |
|||
494 |
/* wend is the size of the current window */ |
||
495 |
62408 |
j = wend + 1; |
|
496 |
/* add the 'bytes above' */ |
||
497 |
✓✓ | 62408 |
if (!start) |
498 |
✓✓ | 289331 |
for (i = 0; i < j; i++) { |
499 |
✗✓ | 228934 |
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) |
500 |
goto err; |
||
501 |
} |
||
502 |
|||
503 |
/* wvalue will be an odd number < 2^window */ |
||
504 |
✗✓ | 62408 |
if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) |
505 |
goto err; |
||
506 |
|||
507 |
/* move the 'window' down further */ |
||
508 |
62408 |
wstart -= wend + 1; |
|
509 |
62408 |
wvalue = 0; |
|
510 |
62408 |
start = 0; |
|
511 |
✓✓ | 62408 |
if (wstart < 0) |
512 |
1813 |
break; |
|
513 |
} |
||
514 |
✗✓ | 2011 |
if (!BN_from_montgomery(rr, r,mont, ctx)) |
515 |
goto err; |
||
516 |
2011 |
ret = 1; |
|
517 |
|||
518 |
2014 |
err: |
|
519 |
✓✓ | 2014 |
if ((in_mont == NULL) && (mont != NULL)) |
520 |
368 |
BN_MONT_CTX_free(mont); |
|
521 |
2014 |
BN_CTX_end(ctx); |
|
522 |
bn_check_top(rr); |
||
523 |
2014 |
return (ret); |
|
524 |
} |
||
525 |
|||
526 |
|||
527 |
/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout |
||
528 |
* so that accessing any of these table values shows the same access pattern as far |
||
529 |
* as cache lines are concerned. The following functions are used to transfer a BIGNUM |
||
530 |
* from/to that table. */ |
||
531 |
|||
532 |
static int |
||
533 |
MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, |
||
534 |
int idx, int width) |
||
535 |
6858 |
{ |
|
536 |
size_t i, j; |
||
537 |
|||
538 |
✓✓ | 6858 |
if (top > b->top) |
539 |
24 |
top = b->top; /* this works because 'buf' is explicitly zeroed */ |
|
540 |
✓✓ | 149466 |
for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) { |
541 |
142608 |
buf[j] = ((unsigned char*)b->d)[i]; |
|
542 |
} |
||
543 |
|||
544 |
6858 |
return 1; |
|
545 |
} |
||
546 |
|||
547 |
static int |
||
548 |
MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, |
||
549 |
int width) |
||
550 |
27742 |
{ |
|
551 |
size_t i, j; |
||
552 |
|||
553 |
✗✓✗✓ |
27742 |
if (bn_wexpand(b, top) == NULL) |
554 |
return 0; |
||
555 |
|||
556 |
✓✓ | 628174 |
for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) { |
557 |
600432 |
((unsigned char*)b->d)[i] = buf[j]; |
|
558 |
} |
||
559 |
|||
560 |
27742 |
b->top = top; |
|
561 |
✓✗✓✓ ✓✗ |
27742 |
bn_correct_top(b); |
562 |
27742 |
return 1; |
|
563 |
} |
||
564 |
|||
565 |
/* Given a pointer value, compute the next address that is a cache line multiple. */ |
||
566 |
#define MOD_EXP_CTIME_ALIGN(x_) \ |
||
567 |
((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) |
||
568 |
|||
569 |
/* This variant of BN_mod_exp_mont() uses fixed windows and the special |
||
570 |
* precomputation memory layout to limit data-dependency to a minimum |
||
571 |
* to protect secret exponents (cf. the hyper-threading timing attacks |
||
572 |
* pointed out by Colin Percival, |
||
573 |
* http://www.daemonology.net/hyperthreading-considered-harmful/) |
||
574 |
*/ |
||
575 |
int |
||
576 |
BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, |
||
577 |
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) |
||
578 |
375 |
{ |
|
579 |
375 |
int i, bits, ret = 0, window, wvalue; |
|
580 |
int top; |
||
581 |
375 |
BN_MONT_CTX *mont = NULL; |
|
582 |
int numPowers; |
||
583 |
375 |
unsigned char *powerbufFree = NULL; |
|
584 |
375 |
int powerbufLen = 0; |
|
585 |
375 |
unsigned char *powerbuf = NULL; |
|
586 |
BIGNUM tmp, am; |
||
587 |
|||
588 |
bn_check_top(a); |
||
589 |
bn_check_top(p); |
||
590 |
bn_check_top(m); |
||
591 |
|||
592 |
375 |
top = m->top; |
|
593 |
|||
594 |
✗✓ | 375 |
if (!(m->d[0] & 1)) { |
595 |
BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, |
||
596 |
BN_R_CALLED_WITH_EVEN_MODULUS); |
||
597 |
return (0); |
||
598 |
} |
||
599 |
375 |
bits = BN_num_bits(p); |
|
600 |
✗✓ | 375 |
if (bits == 0) { |
601 |
ret = BN_one(rr); |
||
602 |
return ret; |
||
603 |
} |
||
604 |
|||
605 |
375 |
BN_CTX_start(ctx); |
|
606 |
|||
607 |
/* Allocate a montgomery context if it was not supplied by the caller. |
||
608 |
* If this is not done, things will break in the montgomery part. |
||
609 |
*/ |
||
610 |
✓✓ | 375 |
if (in_mont != NULL) |
611 |
168 |
mont = in_mont; |
|
612 |
else { |
||
613 |
✗✓ | 207 |
if ((mont = BN_MONT_CTX_new()) == NULL) |
614 |
goto err; |
||
615 |
✗✓ | 207 |
if (!BN_MONT_CTX_set(mont, m, ctx)) |
616 |
goto err; |
||
617 |
} |
||
618 |
|||
619 |
/* Get the window size to use with size of p. */ |
||
620 |
✓✓✓✓ ✓✓✓✓ |
375 |
window = BN_window_bits_for_ctime_exponent_size(bits); |
621 |
#if defined(OPENSSL_BN_ASM_MONT5) |
||
622 |
✓✓ | 375 |
if (window == 6 && bits <= 1024) |
623 |
20 |
window = 5; /* ~5% improvement of 2048-bit RSA sign */ |
|
624 |
#endif |
||
625 |
|||
626 |
/* Allocate a buffer large enough to hold all of the pre-computed |
||
627 |
* powers of am, am itself and tmp. |
||
628 |
*/ |
||
629 |
375 |
numPowers = 1 << window; |
|
630 |
375 |
powerbufLen = sizeof(m->d[0]) * (top * numPowers + |
|
631 |
((2*top) > numPowers ? (2*top) : numPowers)); |
||
632 |
✗✓ | 375 |
if ((powerbufFree = malloc(powerbufLen + |
633 |
MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) |
||
634 |
goto err; |
||
635 |
|||
636 |
375 |
powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); |
|
637 |
375 |
memset(powerbuf, 0, powerbufLen); |
|
638 |
|||
639 |
/* lay down tmp and am right after powers table */ |
||
640 |
375 |
tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers); |
|
641 |
375 |
am.d = tmp.d + top; |
|
642 |
375 |
tmp.top = am.top = 0; |
|
643 |
375 |
tmp.dmax = am.dmax = top; |
|
644 |
375 |
tmp.neg = am.neg = 0; |
|
645 |
375 |
tmp.flags = am.flags = BN_FLG_STATIC_DATA; |
|
646 |
|||
647 |
/* prepare a^0 in Montgomery domain */ |
||
648 |
#if 1 |
||
649 |
✗✓ | 375 |
if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx)) |
650 |
goto err; |
||
651 |
#else |
||
652 |
tmp.d[0] = (0 - m - >d[0]) & BN_MASK2; /* 2^(top*BN_BITS2) - m */ |
||
653 |
for (i = 1; i < top; i++) |
||
654 |
tmp.d[i] = (~m->d[i]) & BN_MASK2; |
||
655 |
tmp.top = top; |
||
656 |
#endif |
||
657 |
|||
658 |
/* prepare a^1 in Montgomery domain */ |
||
659 |
✓✗✓✓ |
375 |
if (a->neg || BN_ucmp(a, m) >= 0) { |
660 |
✗✓ | 125 |
if (!BN_mod(&am, a,m, ctx)) |
661 |
goto err; |
||
662 |
✗✓ | 125 |
if (!BN_to_montgomery(&am, &am, mont, ctx)) |
663 |
goto err; |
||
664 |
✗✓ | 250 |
} else if (!BN_to_montgomery(&am, a,mont, ctx)) |
665 |
goto err; |
||
666 |
|||
667 |
#if defined(OPENSSL_BN_ASM_MONT5) |
||
668 |
/* This optimization uses ideas from http://eprint.iacr.org/2011/239, |
||
669 |
* specifically optimization of cache-timing attack countermeasures |
||
670 |
* and pre-computation optimization. */ |
||
671 |
|||
672 |
/* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as |
||
673 |
* 512-bit RSA is hardly relevant, we omit it to spare size... */ |
||
674 |
✓✓ | 375 |
if (window == 5 && top > 1) { |
675 |
void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, |
||
676 |
const void *table, const BN_ULONG *np, |
||
677 |
const BN_ULONG *n0, int num, int power); |
||
678 |
void bn_scatter5(const BN_ULONG *inp, size_t num, |
||
679 |
void *table, size_t power); |
||
680 |
void bn_gather5(BN_ULONG *out, size_t num, |
||
681 |
void *table, size_t power); |
||
682 |
|||
683 |
74 |
BN_ULONG *np = mont->N.d, *n0 = mont->n0; |
|
684 |
|||
685 |
/* BN_to_montgomery can contaminate words above .top |
||
686 |
* [in BN_DEBUG[_DEBUG] build]... */ |
||
687 |
✓✓ | 76 |
for (i = am.top; i < top; i++) |
688 |
2 |
am.d[i] = 0; |
|
689 |
✓✓ | 78 |
for (i = tmp.top; i < top; i++) |
690 |
4 |
tmp.d[i] = 0; |
|
691 |
|||
692 |
74 |
bn_scatter5(tmp.d, top, powerbuf, 0); |
|
693 |
74 |
bn_scatter5(am.d, am.top, powerbuf, 1); |
|
694 |
74 |
bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); |
|
695 |
74 |
bn_scatter5(tmp.d, top, powerbuf, 2); |
|
696 |
|||
697 |
#if 0 |
||
698 |
for (i = 3; i < 32; i++) { |
||
699 |
/* Calculate a^i = a^(i-1) * a */ |
||
700 |
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, |
||
701 |
n0, top, i - 1); |
||
702 |
bn_scatter5(tmp.d, top, powerbuf, i); |
||
703 |
} |
||
704 |
#else |
||
705 |
/* same as above, but uses squaring for 1/2 of operations */ |
||
706 |
✓✓ | 296 |
for (i = 4; i < 32; i*=2) { |
707 |
222 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
708 |
222 |
bn_scatter5(tmp.d, top, powerbuf, i); |
|
709 |
} |
||
710 |
✓✓ | 296 |
for (i = 3; i < 8; i += 2) { |
711 |
int j; |
||
712 |
222 |
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, |
|
713 |
n0, top, i - 1); |
||
714 |
222 |
bn_scatter5(tmp.d, top, powerbuf, i); |
|
715 |
✓✓ | 740 |
for (j = 2 * i; j < 32; j *= 2) { |
716 |
518 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
717 |
518 |
bn_scatter5(tmp.d, top, powerbuf, j); |
|
718 |
} |
||
719 |
} |
||
720 |
✓✓ | 296 |
for (; i < 16; i += 2) { |
721 |
296 |
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, |
|
722 |
n0, top, i - 1); |
||
723 |
296 |
bn_scatter5(tmp.d, top, powerbuf, i); |
|
724 |
296 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
725 |
296 |
bn_scatter5(tmp.d, top, powerbuf, 2*i); |
|
726 |
} |
||
727 |
✓✓ | 592 |
for (; i < 32; i += 2) { |
728 |
592 |
bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, |
|
729 |
n0, top, i - 1); |
||
730 |
592 |
bn_scatter5(tmp.d, top, powerbuf, i); |
|
731 |
} |
||
732 |
#endif |
||
733 |
74 |
bits--; |
|
734 |
✓✓ | 315 |
for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) |
735 |
241 |
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); |
|
736 |
74 |
bn_gather5(tmp.d, top, powerbuf, wvalue); |
|
737 |
|||
738 |
/* Scan the exponent one window at a time starting from the most |
||
739 |
* significant bits. |
||
740 |
*/ |
||
741 |
✓✓ | 7126 |
while (bits >= 0) { |
742 |
✓✓ | 41868 |
for (wvalue = 0, i = 0; i < 5; i++, bits--) |
743 |
34890 |
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); |
|
744 |
|||
745 |
6978 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
746 |
6978 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
747 |
6978 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
748 |
6978 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
749 |
6978 |
bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); |
|
750 |
6978 |
bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); |
|
751 |
} |
||
752 |
|||
753 |
74 |
tmp.top = top; |
|
754 |
✓✗✓✓ ✓✗ |
74 |
bn_correct_top(&tmp); |
755 |
} else |
||
756 |
#endif |
||
757 |
{ |
||
758 |
✗✓ | 301 |
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, |
759 |
numPowers)) |
||
760 |
goto err; |
||
761 |
✗✓ | 301 |
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, |
762 |
numPowers)) |
||
763 |
goto err; |
||
764 |
|||
765 |
/* If the window size is greater than 1, then calculate |
||
766 |
* val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) |
||
767 |
* (even powers could instead be computed as (a^(i/2))^2 |
||
768 |
* to use the slight performance advantage of sqr over mul). |
||
769 |
*/ |
||
770 |
✓✓ | 301 |
if (window > 1) { |
771 |
✗✓ | 296 |
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) |
772 |
goto err; |
||
773 |
✗✓ | 296 |
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, |
774 |
2, numPowers)) |
||
775 |
goto err; |
||
776 |
✓✓ | 6256 |
for (i = 3; i < numPowers; i++) { |
777 |
/* Calculate a^i = a^(i-1) * a */ |
||
778 |
✗✓ | 5960 |
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, |
779 |
mont, ctx)) |
||
780 |
goto err; |
||
781 |
✗✓ | 5960 |
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, |
782 |
powerbuf, i, numPowers)) |
||
783 |
goto err; |
||
784 |
} |
||
785 |
} |
||
786 |
|||
787 |
301 |
bits--; |
|
788 |
✓✓ | 1098 |
for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) |
789 |
797 |
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); |
|
790 |
✗✓ | 301 |
if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, |
791 |
wvalue, numPowers)) |
||
792 |
goto err; |
||
793 |
|||
794 |
/* Scan the exponent one window at a time starting from the most |
||
795 |
* significant bits. |
||
796 |
*/ |
||
797 |
✓✓ | 27742 |
while (bits >= 0) { |
798 |
27441 |
wvalue = 0; /* The 'value' of the window */ |
|
799 |
|||
800 |
/* Scan the window, squaring the result as we go */ |
||
801 |
✓✓ | 155079 |
for (i = 0; i < window; i++, bits--) { |
802 |
✗✓ | 127638 |
if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, |
803 |
mont, ctx)) |
||
804 |
goto err; |
||
805 |
127638 |
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); |
|
806 |
} |
||
807 |
|||
808 |
/* Fetch the appropriate pre-computed value from the pre-buf */ |
||
809 |
✗✓ | 27441 |
if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, |
810 |
wvalue, numPowers)) |
||
811 |
goto err; |
||
812 |
|||
813 |
/* Multiply the result into the intermediate result */ |
||
814 |
✗✓ | 27441 |
if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) |
815 |
goto err; |
||
816 |
} |
||
817 |
} |
||
818 |
|||
819 |
/* Convert the final result from montgomery to standard format */ |
||
820 |
✗✓ | 375 |
if (!BN_from_montgomery(rr, &tmp, mont, ctx)) |
821 |
goto err; |
||
822 |
375 |
ret = 1; |
|
823 |
|||
824 |
375 |
err: |
|
825 |
✓✓ | 375 |
if ((in_mont == NULL) && (mont != NULL)) |
826 |
207 |
BN_MONT_CTX_free(mont); |
|
827 |
✓✗ | 375 |
if (powerbuf != NULL) { |
828 |
375 |
explicit_bzero(powerbuf, powerbufLen); |
|
829 |
375 |
free(powerbufFree); |
|
830 |
} |
||
831 |
375 |
BN_CTX_end(ctx); |
|
832 |
375 |
return (ret); |
|
833 |
} |
||
834 |
|||
835 |
int |
||
836 |
BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, const BIGNUM *m, |
||
837 |
BN_CTX *ctx, BN_MONT_CTX *in_mont) |
||
838 |
50 |
{ |
|
839 |
50 |
BN_MONT_CTX *mont = NULL; |
|
840 |
50 |
int b, bits, ret = 0; |
|
841 |
int r_is_one; |
||
842 |
BN_ULONG w, next_w; |
||
843 |
BIGNUM *d, *r, *t; |
||
844 |
BIGNUM *swap_tmp; |
||
845 |
|||
846 |
#define BN_MOD_MUL_WORD(r, w, m) \ |
||
847 |
(BN_mul_word(r, (w)) && \ |
||
848 |
(/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \ |
||
849 |
(BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1)))) |
||
850 |
/* BN_MOD_MUL_WORD is only used with 'w' large, |
||
851 |
* so the BN_ucmp test is probably more overhead |
||
852 |
* than always using BN_mod (which uses BN_copy if |
||
853 |
* a similar test returns true). */ |
||
854 |
/* We can use BN_mod and do not need BN_nnmod because our |
||
855 |
* accumulator is never negative (the result of BN_mod does |
||
856 |
* not depend on the sign of the modulus). |
||
857 |
*/ |
||
858 |
#define BN_TO_MONTGOMERY_WORD(r, w, mont) \ |
||
859 |
(BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) |
||
860 |
|||
861 |
✗✓ | 50 |
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { |
862 |
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ |
||
863 |
BNerr(BN_F_BN_MOD_EXP_MONT_WORD, |
||
864 |
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
||
865 |
return -1; |
||
866 |
} |
||
867 |
|||
868 |
bn_check_top(p); |
||
869 |
bn_check_top(m); |
||
870 |
|||
871 |
✓✗✗✓ |
50 |
if (!BN_is_odd(m)) { |
872 |
BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS); |
||
873 |
return (0); |
||
874 |
} |
||
875 |
✓✓ | 50 |
if (m->top == 1) |
876 |
39 |
a %= m->d[0]; /* make sure that 'a' is reduced */ |
|
877 |
|||
878 |
50 |
bits = BN_num_bits(p); |
|
879 |
✓✓ | 50 |
if (bits == 0) { |
880 |
4 |
ret = BN_one(rr); |
|
881 |
4 |
return ret; |
|
882 |
} |
||
883 |
✗✓ | 46 |
if (a == 0) { |
884 |
BN_zero(rr); |
||
885 |
ret = 1; |
||
886 |
return ret; |
||
887 |
} |
||
888 |
|||
889 |
46 |
BN_CTX_start(ctx); |
|
890 |
✗✓ | 46 |
if ((d = BN_CTX_get(ctx)) == NULL) |
891 |
goto err; |
||
892 |
✗✓ | 46 |
if ((r = BN_CTX_get(ctx)) == NULL) |
893 |
goto err; |
||
894 |
✗✓ | 46 |
if ((t = BN_CTX_get(ctx)) == NULL) |
895 |
goto err; |
||
896 |
|||
897 |
✗✓ | 46 |
if (in_mont != NULL) |
898 |
mont = in_mont; |
||
899 |
else { |
||
900 |
✗✓ | 46 |
if ((mont = BN_MONT_CTX_new()) == NULL) |
901 |
goto err; |
||
902 |
✗✓ | 46 |
if (!BN_MONT_CTX_set(mont, m, ctx)) |
903 |
goto err; |
||
904 |
} |
||
905 |
|||
906 |
46 |
r_is_one = 1; /* except for Montgomery factor */ |
|
907 |
|||
908 |
/* bits-1 >= 0 */ |
||
909 |
|||
910 |
/* The result is accumulated in the product r*w. */ |
||
911 |
46 |
w = a; /* bit 'bits-1' of 'p' is always set */ |
|
912 |
✓✓ | 2954 |
for (b = bits - 2; b >= 0; b--) { |
913 |
/* First, square r*w. */ |
||
914 |
2908 |
next_w = w * w; |
|
915 |
✓✓ | 2908 |
if ((next_w / w) != w) /* overflow */ |
916 |
{ |
||
917 |
✓✓ | 470 |
if (r_is_one) { |
918 |
✓✗✓✗ |
15 |
if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) |
919 |
goto err; |
||
920 |
15 |
r_is_one = 0; |
|
921 |
} else { |
||
922 |
✓✗✓✗ |
455 |
if (!BN_MOD_MUL_WORD(r, w, m)) |
923 |
goto err; |
||
924 |
} |
||
925 |
470 |
next_w = 1; |
|
926 |
} |
||
927 |
2908 |
w = next_w; |
|
928 |
✓✓ | 2908 |
if (!r_is_one) { |
929 |
✗✓ | 2832 |
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) |
930 |
goto err; |
||
931 |
} |
||
932 |
|||
933 |
/* Second, multiply r*w by 'a' if exponent bit is set. */ |
||
934 |
✓✓ | 2908 |
if (BN_is_bit_set(p, b)) { |
935 |
1515 |
next_w = w * a; |
|
936 |
✓✓ | 1515 |
if ((next_w / a) != w) /* overflow */ |
937 |
{ |
||
938 |
✓✓ | 71 |
if (r_is_one) { |
939 |
✓✗✓✗ |
5 |
if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) |
940 |
goto err; |
||
941 |
5 |
r_is_one = 0; |
|
942 |
} else { |
||
943 |
✓✗✓✗ |
66 |
if (!BN_MOD_MUL_WORD(r, w, m)) |
944 |
goto err; |
||
945 |
} |
||
946 |
71 |
next_w = a; |
|
947 |
} |
||
948 |
1515 |
w = next_w; |
|
949 |
} |
||
950 |
} |
||
951 |
|||
952 |
/* Finally, set r:=r*w. */ |
||
953 |
✓✓ | 46 |
if (w != 1) { |
954 |
✓✓ | 39 |
if (r_is_one) { |
955 |
✓✗✓✗ |
22 |
if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) |
956 |
goto err; |
||
957 |
22 |
r_is_one = 0; |
|
958 |
} else { |
||
959 |
✓✗✓✗ |
17 |
if (!BN_MOD_MUL_WORD(r, w, m)) |
960 |
goto err; |
||
961 |
} |
||
962 |
} |
||
963 |
|||
964 |
✓✓ | 46 |
if (r_is_one) /* can happen only if a == 1*/ |
965 |
{ |
||
966 |
✗✓ | 4 |
if (!BN_one(rr)) |
967 |
goto err; |
||
968 |
} else { |
||
969 |
✗✓ | 42 |
if (!BN_from_montgomery(rr, r, mont, ctx)) |
970 |
goto err; |
||
971 |
} |
||
972 |
46 |
ret = 1; |
|
973 |
|||
974 |
46 |
err: |
|
975 |
✓✗ | 46 |
if ((in_mont == NULL) && (mont != NULL)) |
976 |
46 |
BN_MONT_CTX_free(mont); |
|
977 |
46 |
BN_CTX_end(ctx); |
|
978 |
bn_check_top(rr); |
||
979 |
46 |
return (ret); |
|
980 |
} |
||
981 |
|||
982 |
|||
983 |
/* The old fallback, simple version :-) */ |
||
984 |
int |
||
985 |
BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, |
||
986 |
BN_CTX *ctx) |
||
987 |
200 |
{ |
|
988 |
200 |
int i, j,bits, ret = 0, wstart, wend, window, wvalue; |
|
989 |
200 |
int start = 1; |
|
990 |
BIGNUM *d; |
||
991 |
/* Table of variables obtained from 'ctx' */ |
||
992 |
BIGNUM *val[TABLE_SIZE]; |
||
993 |
|||
994 |
✗✓ | 200 |
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { |
995 |
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ |
||
996 |
BNerr(BN_F_BN_MOD_EXP_SIMPLE, |
||
997 |
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
||
998 |
return -1; |
||
999 |
} |
||
1000 |
|||
1001 |
200 |
bits = BN_num_bits(p); |
|
1002 |
|||
1003 |
✗✓ | 200 |
if (bits == 0) { |
1004 |
ret = BN_one(r); |
||
1005 |
return ret; |
||
1006 |
} |
||
1007 |
|||
1008 |
200 |
BN_CTX_start(ctx); |
|
1009 |
✗✓ | 200 |
if ((d = BN_CTX_get(ctx)) == NULL) |
1010 |
goto err; |
||
1011 |
✗✓ | 200 |
if ((val[0] = BN_CTX_get(ctx)) == NULL) |
1012 |
goto err; |
||
1013 |
|||
1014 |
✗✓ | 200 |
if (!BN_nnmod(val[0],a,m,ctx)) |
1015 |
goto err; /* 1 */ |
||
1016 |
✗✓ | 200 |
if (BN_is_zero(val[0])) { |
1017 |
BN_zero(r); |
||
1018 |
ret = 1; |
||
1019 |
goto err; |
||
1020 |
} |
||
1021 |
|||
1022 |
✓✗✗✓ ✗✗✗✗ |
200 |
window = BN_window_bits_for_exponent_size(bits); |
1023 |
✓✗ | 200 |
if (window > 1) { |
1024 |
✗✓ | 200 |
if (!BN_mod_mul(d, val[0], val[0], m, ctx)) |
1025 |
goto err; /* 2 */ |
||
1026 |
200 |
j = 1 << (window - 1); |
|
1027 |
✓✓ | 3200 |
for (i = 1; i < j; i++) { |
1028 |
✓✗✓✗ |
3000 |
if (((val[i] = BN_CTX_get(ctx)) == NULL) || |
1029 |
!BN_mod_mul(val[i], val[i - 1], d,m, ctx)) |
||
1030 |
goto err; |
||
1031 |
} |
||
1032 |
} |
||
1033 |
|||
1034 |
200 |
start = 1; /* This is used to avoid multiplication etc |
|
1035 |
* when there is only the value '1' in the |
||
1036 |
* buffer. */ |
||
1037 |
200 |
wvalue = 0; /* The 'value' of the window */ |
|
1038 |
200 |
wstart = bits - 1; /* The top bit of the window */ |
|
1039 |
200 |
wend = 0; /* The bottom bit of the window */ |
|
1040 |
|||
1041 |
✗✓ | 200 |
if (!BN_one(r)) |
1042 |
goto err; |
||
1043 |
|||
1044 |
for (;;) { |
||
1045 |
✓✓ | 32547 |
if (BN_is_bit_set(p, wstart) == 0) { |
1046 |
✓✗ | 21544 |
if (!start) |
1047 |
✗✓ | 21544 |
if (!BN_mod_mul(r, r, r, m, ctx)) |
1048 |
goto err; |
||
1049 |
✓✓ | 21544 |
if (wstart == 0) |
1050 |
116 |
break; |
|
1051 |
21428 |
wstart--; |
|
1052 |
21428 |
continue; |
|
1053 |
} |
||
1054 |
/* We now have wstart on a 'set' bit, we now need to work out |
||
1055 |
* how bit a window to do. To do this we need to scan |
||
1056 |
* forward until the last set bit before the end of the |
||
1057 |
* window */ |
||
1058 |
11003 |
j = wstart; |
|
1059 |
11003 |
wvalue = 1; |
|
1060 |
11003 |
wend = 0; |
|
1061 |
✓✓ | 54698 |
for (i = 1; i < window; i++) { |
1062 |
✓✓ | 43822 |
if (wstart - i < 0) |
1063 |
127 |
break; |
|
1064 |
✓✓ | 43695 |
if (BN_is_bit_set(p, wstart - i)) { |
1065 |
21815 |
wvalue <<= (i - wend); |
|
1066 |
21815 |
wvalue |= 1; |
|
1067 |
21815 |
wend = i; |
|
1068 |
} |
||
1069 |
} |
||
1070 |
|||
1071 |
/* wend is the size of the current window */ |
||
1072 |
11003 |
j = wend + 1; |
|
1073 |
/* add the 'bytes above' */ |
||
1074 |
✓✓ | 11003 |
if (!start) |
1075 |
✓✓ | 54140 |
for (i = 0; i < j; i++) { |
1076 |
✗✓ | 43337 |
if (!BN_mod_mul(r, r, r, m, ctx)) |
1077 |
goto err; |
||
1078 |
} |
||
1079 |
|||
1080 |
/* wvalue will be an odd number < 2^window */ |
||
1081 |
✗✓ | 11003 |
if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx)) |
1082 |
goto err; |
||
1083 |
|||
1084 |
/* move the 'window' down further */ |
||
1085 |
11003 |
wstart -= wend + 1; |
|
1086 |
11003 |
wvalue = 0; |
|
1087 |
11003 |
start = 0; |
|
1088 |
✓✓ | 11003 |
if (wstart < 0) |
1089 |
84 |
break; |
|
1090 |
} |
||
1091 |
200 |
ret = 1; |
|
1092 |
|||
1093 |
200 |
err: |
|
1094 |
200 |
BN_CTX_end(ctx); |
|
1095 |
bn_check_top(r); |
||
1096 |
200 |
return (ret); |
|
1097 |
} |
Generated by: GCOVR (Version 3.3) |