GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/bn/bn_mod.c Lines: 55 83 66.3 %
Date: 2017-11-13 Branches: 39 64 60.9 %

Line Branch Exec Source
1
/* $OpenBSD: bn_mod.c,v 1.12 2017/01/29 17:49:22 beck Exp $ */
2
/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3
 * for the OpenSSL project. */
4
/* ====================================================================
5
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 *
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in
16
 *    the documentation and/or other materials provided with the
17
 *    distribution.
18
 *
19
 * 3. All advertising materials mentioning features or use of this
20
 *    software must display the following acknowledgment:
21
 *    "This product includes software developed by the OpenSSL Project
22
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
23
 *
24
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25
 *    endorse or promote products derived from this software without
26
 *    prior written permission. For written permission, please contact
27
 *    openssl-core@openssl.org.
28
 *
29
 * 5. Products derived from this software may not be called "OpenSSL"
30
 *    nor may "OpenSSL" appear in their names without prior written
31
 *    permission of the OpenSSL Project.
32
 *
33
 * 6. Redistributions of any form whatsoever must retain the following
34
 *    acknowledgment:
35
 *    "This product includes software developed by the OpenSSL Project
36
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
37
 *
38
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49
 * OF THE POSSIBILITY OF SUCH DAMAGE.
50
 * ====================================================================
51
 *
52
 * This product includes cryptographic software written by Eric Young
53
 * (eay@cryptsoft.com).  This product includes software written by Tim
54
 * Hudson (tjh@cryptsoft.com).
55
 *
56
 */
57
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
58
 * All rights reserved.
59
 *
60
 * This package is an SSL implementation written
61
 * by Eric Young (eay@cryptsoft.com).
62
 * The implementation was written so as to conform with Netscapes SSL.
63
 *
64
 * This library is free for commercial and non-commercial use as long as
65
 * the following conditions are aheared to.  The following conditions
66
 * apply to all code found in this distribution, be it the RC4, RSA,
67
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
68
 * included with this distribution is covered by the same copyright terms
69
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
70
 *
71
 * Copyright remains Eric Young's, and as such any Copyright notices in
72
 * the code are not to be removed.
73
 * If this package is used in a product, Eric Young should be given attribution
74
 * as the author of the parts of the library used.
75
 * This can be in the form of a textual message at program startup or
76
 * in documentation (online or textual) provided with the package.
77
 *
78
 * Redistribution and use in source and binary forms, with or without
79
 * modification, are permitted provided that the following conditions
80
 * are met:
81
 * 1. Redistributions of source code must retain the copyright
82
 *    notice, this list of conditions and the following disclaimer.
83
 * 2. Redistributions in binary form must reproduce the above copyright
84
 *    notice, this list of conditions and the following disclaimer in the
85
 *    documentation and/or other materials provided with the distribution.
86
 * 3. All advertising materials mentioning features or use of this software
87
 *    must display the following acknowledgement:
88
 *    "This product includes cryptographic software written by
89
 *     Eric Young (eay@cryptsoft.com)"
90
 *    The word 'cryptographic' can be left out if the rouines from the library
91
 *    being used are not cryptographic related :-).
92
 * 4. If you include any Windows specific code (or a derivative thereof) from
93
 *    the apps directory (application code) you must include an acknowledgement:
94
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
95
 *
96
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
97
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
98
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
99
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
100
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
101
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
102
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
103
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
104
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
105
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
106
 * SUCH DAMAGE.
107
 *
108
 * The licence and distribution terms for any publically available version or
109
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
110
 * copied and put under another distribution licence
111
 * [including the GNU Public Licence.]
112
 */
113
114
#include <openssl/err.h>
115
116
#include "bn_lcl.h"
117
118
int
119
BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
120
{
121
	/* like BN_mod, but returns non-negative remainder
122
	 * (i.e.,  0 <= r < |d|  always holds) */
123
124
956746
	if (!(BN_mod_ct(r, m,d, ctx)))
125
15
		return 0;
126
478358
	if (!r->neg)
127
477741
		return 1;
128
	/* now -|d| < r < 0,  so we have to set  r := r + |d| */
129
617
	if (d->neg)
130
		return BN_sub(r, r, d);
131
	else
132
617
		return BN_add(r, r, d);
133
478373
}
134
135
int
136
BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
137
    BN_CTX *ctx)
138
{
139
252
	if (!BN_add(r, a, b))
140
		return 0;
141
126
	return BN_nnmod(r, r, m, ctx);
142
126
}
143
144
/* BN_mod_add variant that may be used if both  a  and  b  are non-negative
145
 * and less than  m */
146
int
147
BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
148
{
149
5922760
	if (!BN_uadd(r, a, b))
150
		return 0;
151
2961380
	if (BN_ucmp(r, m) >= 0)
152
1467215
		return BN_usub(r, r, m);
153
1494165
	return 1;
154
2961380
}
155
156
int
157
BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
158
    BN_CTX *ctx)
159
{
160
	if (!BN_sub(r, a, b))
161
		return 0;
162
	return BN_nnmod(r, r, m, ctx);
163
}
164
165
/* BN_mod_sub variant that may be used if both  a  and  b  are non-negative
166
 * and less than  m */
167
int
168
BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
169
{
170
12003210
	if (!BN_sub(r, a, b))
171
		return 0;
172
6001605
	if (r->neg)
173
3002405
		return BN_add(r, r, m);
174
2999200
	return 1;
175
6001605
}
176
177
/* slow but works */
178
int
179
BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
180
    BN_CTX *ctx)
181
{
182
	BIGNUM *t;
183
	int ret = 0;
184
185
	bn_check_top(a);
186
	bn_check_top(b);
187
	bn_check_top(m);
188
189
740342
	BN_CTX_start(ctx);
190
370171
	if ((t = BN_CTX_get(ctx)) == NULL)
191
		goto err;
192
370171
	if (a == b) {
193
272288
		if (!BN_sqr(t, a, ctx))
194
			goto err;
195
	} else {
196
97883
		if (!BN_mul(t, a,b, ctx))
197
			goto err;
198
	}
199
370171
	if (!BN_nnmod(r, t,m, ctx))
200
		goto err;
201
	bn_check_top(r);
202
370168
	ret = 1;
203
204
err:
205
370171
	BN_CTX_end(ctx);
206
370171
	return (ret);
207
}
208
209
int
210
BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
211
{
212
11928
	if (!BN_sqr(r, a, ctx))
213
		return 0;
214
	/* r->neg == 0,  thus we don't need BN_nnmod */
215
5964
	return BN_mod_ct(r, r, m, ctx);
216
5964
}
217
218
int
219
BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
220
{
221
	if (!BN_lshift1(r, a))
222
		return 0;
223
	bn_check_top(r);
224
	return BN_nnmod(r, r, m, ctx);
225
}
226
227
/* BN_mod_lshift1 variant that may be used if  a  is non-negative
228
 * and less than  m */
229
int
230
BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
231
{
232
7756430
	if (!BN_lshift1(r, a))
233
		return 0;
234
	bn_check_top(r);
235
3878215
	if (BN_cmp(r, m) >= 0)
236
1938426
		return BN_sub(r, r, m);
237
1939789
	return 1;
238
3878215
}
239
240
int
241
BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
242
{
243
	BIGNUM *abs_m = NULL;
244
	int ret;
245
246
	if (!BN_nnmod(r, a, m, ctx))
247
		return 0;
248
249
	if (m->neg) {
250
		abs_m = BN_dup(m);
251
		if (abs_m == NULL)
252
			return 0;
253
		abs_m->neg = 0;
254
	}
255
256
	ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
257
	bn_check_top(r);
258
259
	BN_free(abs_m);
260
	return ret;
261
}
262
263
/* BN_mod_lshift variant that may be used if  a  is non-negative
264
 * and less than  m */
265
int
266
BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
267
{
268
4798764
	if (r != a) {
269
1199691
		if (BN_copy(r, a) == NULL)
270
			return 0;
271
	}
272
273
14782506
	while (n > 0) {
274
		int max_shift;
275
276
		/* 0 < r < m */
277
4991871
		max_shift = BN_num_bits(m) - BN_num_bits(r);
278
		/* max_shift >= 0 */
279
280
4991871
		if (max_shift < 0) {
281
			BNerror(BN_R_INPUT_NOT_REDUCED);
282
			return 0;
283
		}
284
285
4991871
		if (max_shift > n)
286
675561
			max_shift = n;
287
288
4991871
		if (max_shift) {
289
2359642
			if (!BN_lshift(r, r, max_shift))
290
				return 0;
291
2359642
			n -= max_shift;
292
2359642
		} else {
293
2632229
			if (!BN_lshift1(r, r))
294
				return 0;
295
2632229
			--n;
296
		}
297
298
		/* BN_num_bits(r) <= BN_num_bits(m) */
299
300
4991871
		if (BN_cmp(r, m) >= 0) {
301
3001323
			if (!BN_sub(r, r, m))
302
				return 0;
303
		}
304
4991871
	}
305
	bn_check_top(r);
306
307
2399382
	return 1;
308
2399382
}