GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/bn/bn_mod.c Lines: 54 87 62.1 %
Date: 2016-12-06 Branches: 36 64 56.3 %

Line Branch Exec Source
1
/* $OpenBSD: bn_mod.c,v 1.9 2014/07/12 16:03:36 miod 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
109788
{
121
	/* like BN_mod, but returns non-negative remainder
122
	 * (i.e.,  0 <= r < |d|  always holds) */
123
124
109788
	if (!(BN_mod(r, m,d, ctx)))
125
		return 0;
126
109788
	if (!r->neg)
127
107804
		return 1;
128
	/* now   -|d| < r < 0,  so we have to set  r := r + |d| */
129
1984
	return (d->neg ? BN_sub : BN_add)(r, r, d);
130
}
131
132
int
133
BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
134
    BN_CTX *ctx)
135
42
{
136
42
	if (!BN_add(r, a, b))
137
		return 0;
138
42
	return BN_nnmod(r, r, m, ctx);
139
}
140
141
/* BN_mod_add variant that may be used if both  a  and  b  are non-negative
142
 * and less than  m */
143
int
144
BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
145
365768
{
146
365768
	if (!BN_uadd(r, a, b))
147
		return 0;
148
365768
	if (BN_ucmp(r, m) >= 0)
149
176959
		return BN_usub(r, r, m);
150
188809
	return 1;
151
}
152
153
int
154
BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
155
    BN_CTX *ctx)
156
{
157
	if (!BN_sub(r, a, b))
158
		return 0;
159
	return BN_nnmod(r, r, m, ctx);
160
}
161
162
/* BN_mod_sub variant that may be used if both  a  and  b  are non-negative
163
 * and less than  m */
164
int
165
BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
166
729511
{
167
729511
	if (!BN_sub(r, a, b))
168
		return 0;
169
729511
	if (r->neg)
170
364792
		return BN_add(r, r, m);
171
364719
	return 1;
172
}
173
174
/* slow but works */
175
int
176
BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
177
    BN_CTX *ctx)
178
85090
{
179
	BIGNUM *t;
180
85090
	int ret = 0;
181
182
	bn_check_top(a);
183
	bn_check_top(b);
184
	bn_check_top(m);
185
186
85090
	BN_CTX_start(ctx);
187
85090
	if ((t = BN_CTX_get(ctx)) == NULL)
188
		goto err;
189
85090
	if (a == b) {
190
69581
		if (!BN_sqr(t, a, ctx))
191
			goto err;
192
	} else {
193
15509
		if (!BN_mul(t, a,b, ctx))
194
			goto err;
195
	}
196
85090
	if (!BN_nnmod(r, t,m, ctx))
197
		goto err;
198
	bn_check_top(r);
199
85090
	ret = 1;
200
201
85090
err:
202
85090
	BN_CTX_end(ctx);
203
85090
	return (ret);
204
}
205
206
int
207
BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
208
846
{
209
846
	if (!BN_sqr(r, a, ctx))
210
		return 0;
211
	/* r->neg == 0,  thus we don't need BN_nnmod */
212
846
	return BN_mod(r, r, m, ctx);
213
}
214
215
int
216
BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
217
{
218
	if (!BN_lshift1(r, a))
219
		return 0;
220
	bn_check_top(r);
221
	return BN_nnmod(r, r, m, ctx);
222
}
223
224
/* BN_mod_lshift1 variant that may be used if  a  is non-negative
225
 * and less than  m */
226
int
227
BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
228
468140
{
229
468140
	if (!BN_lshift1(r, a))
230
		return 0;
231
	bn_check_top(r);
232
468140
	if (BN_cmp(r, m) >= 0)
233
233909
		return BN_sub(r, r, m);
234
234231
	return 1;
235
}
236
237
int
238
BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
239
{
240
	BIGNUM *abs_m = NULL;
241
	int ret;
242
243
	if (!BN_nnmod(r, a, m, ctx))
244
		return 0;
245
246
	if (m->neg) {
247
		abs_m = BN_dup(m);
248
		if (abs_m == NULL)
249
			return 0;
250
		abs_m->neg = 0;
251
	}
252
253
	ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
254
	bn_check_top(r);
255
256
	BN_free(abs_m);
257
	return ret;
258
}
259
260
/* BN_mod_lshift variant that may be used if  a  is non-negative
261
 * and less than  m */
262
int
263
BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
264
285352
{
265
285352
	if (r != a) {
266
142676
		if (BN_copy(r, a) == NULL)
267
			return 0;
268
	}
269
270
863927
	while (n > 0) {
271
		int max_shift;
272
273
		/* 0 < r < m */
274
578575
		max_shift = BN_num_bits(m) - BN_num_bits(r);
275
		/* max_shift >= 0 */
276
277
578575
		if (max_shift < 0) {
278
			BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
279
			return 0;
280
		}
281
282
578575
		if (max_shift > n)
283
90115
			max_shift = n;
284
285
578575
		if (max_shift) {
286
314517
			if (!BN_lshift(r, r, max_shift))
287
				return 0;
288
314517
			n -= max_shift;
289
		} else {
290
264058
			if (!BN_lshift1(r, r))
291
				return 0;
292
264058
			--n;
293
		}
294
295
		/* BN_num_bits(r) <= BN_num_bits(m) */
296
297
578575
		if (BN_cmp(r, m) >= 0) {
298
356413
			if (!BN_sub(r, r, m))
299
				return 0;
300
		}
301
	}
302
	bn_check_top(r);
303
304
285352
	return 1;
305
}