summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2023-02-02 18:39:26 +0000
committerjsing <>2023-02-02 18:39:26 +0000
commitcea09ef9db2c57982c7c7d5eb3808c823c8e16ba (patch)
tree1674698c28777afc06c9e776cbb2058197484d33
parent9a98d1b0a691d9784ff03bc4640dc297775687f0 (diff)
downloadopenbsd-cea09ef9db2c57982c7c7d5eb3808c823c8e16ba.tar.gz
openbsd-cea09ef9db2c57982c7c7d5eb3808c823c8e16ba.tar.bz2
openbsd-cea09ef9db2c57982c7c7d5eb3808c823c8e16ba.zip
Refactor BN_uadd() and BN_usub().
Unlike bn_add_words()/bn_sub_words(), the s2n-bignum bignum_add() and bignum_sub() functions correctly handle inputs with differing word lengths. This means that they can be called directly, without needing to fix up any remaining words manually. Split BN_uadd() in two - the default bn_add() implementation calls bn_add_words(), before handling the carry for any remaining words. Likewise split BN_usub() in two - the default bn_sub() implementation calls bn_sub_words(), before handling the borrow for any remaining words. On amd64, provide an implementation of bn_add() that calls s2n-bignum's bignum_add() directly, similarly with an implementation of bn_sub() that calls s2n-bignum's bignum_sub() directly. ok tb@
-rw-r--r--src/lib/libcrypto/bn/arch/amd64/bn_arch.c20
-rw-r--r--src/lib/libcrypto/bn/arch/amd64/bn_arch.h4
-rw-r--r--src/lib/libcrypto/bn/bn_add.c114
3 files changed, 99 insertions, 39 deletions
diff --git a/src/lib/libcrypto/bn/arch/amd64/bn_arch.c b/src/lib/libcrypto/bn/arch/amd64/bn_arch.c
index aedefc76e2..dc3000fe8b 100644
--- a/src/lib/libcrypto/bn/arch/amd64/bn_arch.c
+++ b/src/lib/libcrypto/bn/arch/amd64/bn_arch.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_arch.c,v 1.2 2023/01/29 14:00:41 jsing Exp $ */ 1/* $OpenBSD: bn_arch.c,v 1.3 2023/02/02 18:39:26 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -21,6 +21,15 @@
21#include "bn_local.h" 21#include "bn_local.h"
22#include "s2n_bignum.h" 22#include "s2n_bignum.h"
23 23
24#ifdef HAVE_BN_ADD
25BN_ULONG
26bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b)
27{
28 return bignum_add(rn, (uint64_t *)r->d, a->top, (uint64_t *)a->d,
29 b->top, (uint64_t *)b->d);
30}
31#endif
32
24#ifdef HAVE_BN_ADD_WORDS 33#ifdef HAVE_BN_ADD_WORDS
25BN_ULONG 34BN_ULONG
26bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) 35bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n)
@@ -30,6 +39,15 @@ bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n)
30} 39}
31#endif 40#endif
32 41
42#ifdef HAVE_BN_SUB
43BN_ULONG
44bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b)
45{
46 return bignum_sub(rn, (uint64_t *)r->d, a->top, (uint64_t *)a->d,
47 b->top, (uint64_t *)b->d);
48}
49#endif
50
33#ifdef HAVE_BN_SUB_WORDS 51#ifdef HAVE_BN_SUB_WORDS
34BN_ULONG 52BN_ULONG
35bn_sub_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) 53bn_sub_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n)
diff --git a/src/lib/libcrypto/bn/arch/amd64/bn_arch.h b/src/lib/libcrypto/bn/arch/amd64/bn_arch.h
index 9e4b6b9442..c41a84409b 100644
--- a/src/lib/libcrypto/bn/arch/amd64/bn_arch.h
+++ b/src/lib/libcrypto/bn/arch/amd64/bn_arch.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_arch.h,v 1.9 2023/01/31 05:53:49 jsing Exp $ */ 1/* $OpenBSD: bn_arch.h,v 1.10 2023/02/02 18:39:26 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -22,6 +22,7 @@
22 22
23#ifndef OPENSSL_NO_ASM 23#ifndef OPENSSL_NO_ASM
24 24
25#define HAVE_BN_ADD
25#define HAVE_BN_ADD_WORDS 26#define HAVE_BN_ADD_WORDS
26 27
27#define HAVE_BN_DIV_WORDS 28#define HAVE_BN_DIV_WORDS
@@ -36,6 +37,7 @@
36#define HAVE_BN_SQR_COMBA8 37#define HAVE_BN_SQR_COMBA8
37#define HAVE_BN_SQR_WORDS 38#define HAVE_BN_SQR_WORDS
38 39
40#define HAVE_BN_SUB
39#define HAVE_BN_SUB_WORDS 41#define HAVE_BN_SUB_WORDS
40 42
41#if defined(__GNUC__) 43#if defined(__GNUC__)
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c
index cfc04fd032..dc525db084 100644
--- a/src/lib/libcrypto/bn/bn_add.c
+++ b/src/lib/libcrypto/bn/bn_add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_add.c,v 1.20 2023/01/31 05:16:52 jsing Exp $ */ 1/* $OpenBSD: bn_add.c,v 1.21 2023/02/02 18:39:26 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -57,6 +57,7 @@
57 */ 57 */
58 58
59#include <assert.h> 59#include <assert.h>
60#include <limits.h>
60#include <stdio.h> 61#include <stdio.h>
61 62
62#include <openssl/err.h> 63#include <openssl/err.h>
@@ -64,6 +65,9 @@
64#include "bn_arch.h" 65#include "bn_arch.h"
65#include "bn_local.h" 66#include "bn_local.h"
66 67
68BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b);
69BN_ULONG bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b);
70
67#ifndef HAVE_BN_ADD_WORDS 71#ifndef HAVE_BN_ADD_WORDS
68#ifdef BN_LLONG 72#ifdef BN_LLONG
69BN_ULONG 73BN_ULONG
@@ -220,13 +224,18 @@ bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
220} 224}
221#endif 225#endif
222 226
223int 227#ifndef HAVE_BN_ADD
224BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 228/*
229 * bn_add() computes a + b, storing the result in r (which may be the same as a
230 * or b). The caller must ensure that r has been expanded to max(a->top, b->top)
231 * words. Any carry resulting from the addition is returned.
232 */
233BN_ULONG
234bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b)
225{ 235{
226 int max, min, dif;
227 const BN_ULONG *ap, *bp;
228 BN_ULONG *rp, carry, t1, t2; 236 BN_ULONG *rp, carry, t1, t2;
229 237 const BN_ULONG *ap, *bp;
238 int max, min, dif;
230 239
231 if (a->top < b->top) { 240 if (a->top < b->top) {
232 const BIGNUM *tmp; 241 const BIGNUM *tmp;
@@ -239,11 +248,6 @@ BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
239 min = b->top; 248 min = b->top;
240 dif = max - min; 249 dif = max - min;
241 250
242 if (!bn_wexpand(r, max + 1))
243 return 0;
244
245 r->top = max;
246
247 ap = a->d; 251 ap = a->d;
248 bp = b->d; 252 bp = b->d;
249 rp = r->d; 253 rp = r->d;
@@ -259,42 +263,34 @@ BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
259 *(rp++) = t2; 263 *(rp++) = t2;
260 carry &= (t2 == 0); 264 carry &= (t2 == 0);
261 } 265 }
262 *rp = carry;
263 r->top += carry;
264 266
265 r->neg = 0; 267 return carry;
266 return 1;
267} 268}
269#endif
268 270
269int 271#ifndef HAVE_BN_SUB
270BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 272/*
273 * bn_sub() computes a - b, storing the result in r (which may be the same as a
274 * or b). The caller must ensure that the number of words in a is greater than
275 * or equal to the number of words in b and that r has been expanded to
276 * a->top words. Any borrow resulting from the subtraction is returned.
277 */
278BN_ULONG
279bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b)
271{ 280{
272 int max, min, dif;
273 const BN_ULONG *ap, *bp;
274 BN_ULONG t1, t2, borrow, *rp; 281 BN_ULONG t1, t2, borrow, *rp;
275 282 const BN_ULONG *ap, *bp;
283 int max, min, dif;
276 284
277 max = a->top; 285 max = a->top;
278 min = b->top; 286 min = b->top;
279 dif = max - min; 287 dif = max - min;
280 288
281 if (dif < 0) {
282 BNerror(BN_R_ARG2_LT_ARG3);
283 return 0;
284 }
285
286 if (!bn_wexpand(r, max))
287 return 0;
288
289 ap = a->d; 289 ap = a->d;
290 bp = b->d; 290 bp = b->d;
291 rp = r->d; 291 rp = r->d;
292 292
293 borrow = bn_sub_words(rp, ap, bp, min); 293 borrow = bn_sub_words(rp, ap, bp, min);
294 if (dif == 0 && borrow > 0) {
295 BNerror(BN_R_ARG2_LT_ARG3);
296 return 0;
297 }
298 ap += min; 294 ap += min;
299 rp += min; 295 rp += min;
300 296
@@ -306,12 +302,58 @@ BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
306 borrow &= (t1 == 0); 302 borrow &= (t1 == 0);
307 } 303 }
308 304
309 while (max > 0 && *--rp == 0) 305 return borrow;
310 max--; 306}
307#endif
308
309int
310BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
311{
312 BN_ULONG carry;
313 int rn;
314
315 if ((rn = a->top) < b->top)
316 rn = b->top;
317 if (rn == INT_MAX)
318 return 0;
319 if (!bn_wexpand(r, rn + 1))
320 return 0;
321
322 carry = bn_add(r, rn, a, b);
323 r->d[rn] = carry;
324
325 r->top = rn + (carry & 1);
326 r->neg = 0;
327
328 return 1;
329}
330
331int
332BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
333{
334 BN_ULONG borrow;
335 int rn;
336
337 if (a->top < b->top) {
338 BNerror(BN_R_ARG2_LT_ARG3);
339 return 0;
340 }
341 rn = a->top;
342
343 if (!bn_wexpand(r, rn))
344 return 0;
311 345
312 r->top = max; 346 borrow = bn_sub(r, rn, a, b);
347 if (borrow > 0) {
348 BNerror(BN_R_ARG2_LT_ARG3);
349 return 0;
350 }
351
352 r->top = rn;
313 r->neg = 0; 353 r->neg = 0;
354
314 bn_correct_top(r); 355 bn_correct_top(r);
356
315 return 1; 357 return 1;
316} 358}
317 359
@@ -320,7 +362,6 @@ BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
320{ 362{
321 int ret, r_neg; 363 int ret, r_neg;
322 364
323
324 if (a->neg == b->neg) { 365 if (a->neg == b->neg) {
325 r_neg = a->neg; 366 r_neg = a->neg;
326 ret = BN_uadd(r, a, b); 367 ret = BN_uadd(r, a, b);
@@ -349,7 +390,6 @@ BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
349{ 390{
350 int ret, r_neg; 391 int ret, r_neg;
351 392
352
353 if (a->neg != b->neg) { 393 if (a->neg != b->neg) {
354 r_neg = a->neg; 394 r_neg = a->neg;
355 ret = BN_uadd(r, a, b); 395 ret = BN_uadd(r, a, b);