GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/bn/bn_add.c Lines: 122 133 91.7 %
Date: 2016-12-06 Branches: 70 82 85.4 %

Line Branch Exec Source
1
/* $OpenBSD: bn_add.c,v 1.10 2014/10/28 07:35:58 jsg 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
#include <stdio.h>
60
61
#include <openssl/err.h>
62
63
#include "bn_lcl.h"
64
65
/* r can == a or b */
66
int
67
BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
68
411662
{
69
	const BIGNUM *tmp;
70
411662
	int a_neg = a->neg, ret;
71
72
	bn_check_top(a);
73
	bn_check_top(b);
74
75
	/*  a +  b	a+b
76
	 *  a + -b	a-b
77
	 * -a +  b	b-a
78
	 * -a + -b	-(a+b)
79
	 */
80
411662
	if (a_neg ^ b->neg) {
81
		/* only one is negative */
82
367071
		if (a_neg)
83
366936
				{ tmp = a;
84
366936
			a = b;
85
366936
			b = tmp;
86
		}
87
88
		/* we are now a - b */
89
90
367071
		if (BN_ucmp(a, b) < 0) {
91
85
			if (!BN_usub(r, b, a))
92
				return (0);
93
85
			r->neg = 1;
94
		} else {
95
366986
			if (!BN_usub(r, a, b))
96
				return (0);
97
366986
			r->neg = 0;
98
		}
99
367071
		return (1);
100
	}
101
102
44591
	ret = BN_uadd(r, a, b);
103
44591
	r->neg = a_neg;
104
	bn_check_top(r);
105
44591
	return ret;
106
}
107
108
/* unsigned add of b to a */
109
int
110
BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
111
1013299
{
112
	int max, min, dif;
113
	BN_ULONG *ap, *bp, *rp, carry, t1, t2;
114
	const BIGNUM *tmp;
115
116
	bn_check_top(a);
117
	bn_check_top(b);
118
119
1013299
	if (a->top < b->top) {
120
28985
		tmp = a;
121
28985
		a = b;
122
28985
		b = tmp;
123
	}
124
1013299
	max = a->top;
125
1013299
	min = b->top;
126
1013299
	dif = max - min;
127
128

1013299
	if (bn_wexpand(r, max + 1) == NULL)
129
		return 0;
130
131
1013299
	r->top = max;
132
133
1013299
	ap = a->d;
134
1013299
	bp = b->d;
135
1013299
	rp = r->d;
136
137
1013299
	carry = bn_add_words(rp, ap, bp, min);
138
1013299
	rp += min;
139
1013299
	ap += min;
140
1013299
	bp += min;
141
142
1013299
	if (carry) {
143
265002
		while (dif) {
144
64754
			dif--;
145
64754
			t1 = *(ap++);
146
64754
			t2 = (t1 + 1) & BN_MASK2;
147
64754
			*(rp++) = t2;
148
64754
			if (t2) {
149
64277
				carry = 0;
150
64277
				break;
151
			}
152
		}
153
264525
		if (carry) {
154
			/* carry != 0 => dif == 0 */
155
200248
			*rp = 1;
156
200248
			r->top++;
157
		}
158
	}
159
1013299
	if (dif && rp != ap)
160
87816
		while (dif--)
161
			/* copy remaining words if ap != rp */
162
62402
			*(rp++) = *(ap++);
163
1013299
	r->neg = 0;
164
	bn_check_top(r);
165
1013299
	return 1;
166
}
167
168
/* unsigned subtraction of b from a, a must be larger than b. */
169
int
170
BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
171
2457444
{
172
	int max, min, dif;
173
	BN_ULONG t1, t2, *ap, *bp, *rp;
174
	int i, carry;
175
176
	bn_check_top(a);
177
	bn_check_top(b);
178
179
2457444
	max = a->top;
180
2457444
	min = b->top;
181
2457444
	dif = max - min;
182
183
2457444
	if (dif < 0)	/* hmm... should not be happening */
184
	{
185
		BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3);
186
		return (0);
187
	}
188
189

2457444
	if (bn_wexpand(r, max) == NULL)
190
		return (0);
191
192
2457444
	ap = a->d;
193
2457444
	bp = b->d;
194
2457444
	rp = r->d;
195
196
#if 1
197
2457444
	carry = 0;
198
15728772
	for (i = min; i != 0; i--) {
199
13271328
		t1= *(ap++);
200
13271328
		t2= *(bp++);
201
13271328
		if (carry) {
202
5167360
			carry = (t1 <= t2);
203
5167360
			t1 = (t1 - t2 - 1)&BN_MASK2;
204
		} else {
205
8103968
			carry = (t1 < t2);
206
8103968
			t1 = (t1 - t2)&BN_MASK2;
207
		}
208
13271328
		*(rp++) = t1&BN_MASK2;
209
	}
210
#else
211
	carry = bn_sub_words(rp, ap, bp, min);
212
	ap += min;
213
	bp += min;
214
	rp += min;
215
#endif
216
2457444
	if (carry) /* subtracted */
217
	{
218
370804
		if (!dif)
219
			/* error: a < b */
220
			return 0;
221
370812
		while (dif) {
222
370812
			dif--;
223
370812
			t1 = *(ap++);
224
370812
			t2 = (t1 - 1)&BN_MASK2;
225
370812
			*(rp++) = t2;
226
370812
			if (t1)
227
370804
				break;
228
		}
229
	}
230
#if 0
231
	memcpy(rp, ap, sizeof(*rp)*(max - i));
232
#else
233
2457444
	if (rp != ap) {
234
		for (;;) {
235
1145785
			if (!dif--)
236
1143953
				break;
237
1832
			rp[0] = ap[0];
238
1832
			if (!dif--)
239
671
				break;
240
1161
			rp[1] = ap[1];
241
1161
			if (!dif--)
242
302
				break;
243
859
			rp[2] = ap[2];
244
859
			if (!dif--)
245
248
				break;
246
611
			rp[3] = ap[3];
247
611
			rp += 4;
248
611
			ap += 4;
249
611
		}
250
	}
251
#endif
252
253
2457444
	r->top = max;
254
2457444
	r->neg = 0;
255

2457444
	bn_correct_top(r);
256
2457444
	return (1);
257
}
258
259
int
260
BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
261
1326470
{
262
	int max;
263
1326470
	int add = 0, neg = 0;
264
	const BIGNUM *tmp;
265
266
	bn_check_top(a);
267
	bn_check_top(b);
268
269
	/*  a -  b	a-b
270
	 *  a - -b	a+b
271
	 * -a -  b	-(a+b)
272
	 * -a - -b	b-a
273
	 */
274
1326470
	if (a->neg) {
275
676
		if (b->neg) {
276
501
			tmp = a;
277
501
			a = b;
278
501
			b = tmp;
279
		} else {
280
175
			add = 1;
281
175
			neg = 1;
282
		}
283
	} else {
284
1325794
		if (b->neg) {
285
50
			add = 1;
286
50
			neg = 0;
287
		}
288
	}
289
290
1326470
	if (add) {
291
225
		if (!BN_uadd(r, a, b))
292
			return (0);
293
225
		r->neg = neg;
294
225
		return (1);
295
	}
296
297
	/* We are actually doing a - b :-) */
298
299
1326245
	max = (a->top > b->top) ? a->top : b->top;
300

1326245
	if (bn_wexpand(r, max) == NULL)
301
		return (0);
302
1326245
	if (BN_ucmp(a, b) < 0) {
303
366641
		if (!BN_usub(r, b, a))
304
			return (0);
305
366641
		r->neg = 1;
306
	} else {
307
959604
		if (!BN_usub(r, a, b))
308
			return (0);
309
959604
		r->neg = 0;
310
	}
311
	bn_check_top(r);
312
1326245
	return (1);
313
}