diff options
author | Theo Buehler <tb@cvs.openbsd.org> | 2018-07-10 21:52:08 +0000 |
---|---|---|
committer | Theo Buehler <tb@cvs.openbsd.org> | 2018-07-10 21:52:08 +0000 |
commit | b52efea46b328d84915ce938d3b5a32e6faf12f5 (patch) | |
tree | 6b701d426eba7c53e3d2da7916c36c390a3334a3 /lib | |
parent | 80ef079bd01ba902e27fcdafeaf74a348041de24 (diff) |
Provide BN_swap_ct(), a constant time function that conditionally swaps
two bignums. It's saner and substantially less ugly than the existing
public BN_constantime_swap() function and will be used in forthcoming work
on constant time ECC code.
From Billy Brumley and his team. Thanks!
ok jsing
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libcrypto/bn/bn_lcl.h | 5 | ||||
-rw-r--r-- | lib/libcrypto/bn/bn_lib.c | 50 |
2 files changed, 53 insertions, 2 deletions
diff --git a/lib/libcrypto/bn/bn_lcl.h b/lib/libcrypto/bn/bn_lcl.h index c010410cd15..ad9427fddc2 100644 --- a/lib/libcrypto/bn/bn_lcl.h +++ b/lib/libcrypto/bn/bn_lcl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_lcl.h,v 1.27 2017/01/25 06:15:44 beck Exp $ */ +/* $OpenBSD: bn_lcl.h,v 1.28 2018/07/10 21:52:07 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -605,5 +605,8 @@ BIGNUM *BN_mod_inverse_nonct(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); int BN_gcd_ct(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); int BN_gcd_nonct(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +int BN_swap_ct(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + __END_HIDDEN_DECLS #endif diff --git a/lib/libcrypto/bn/bn_lib.c b/lib/libcrypto/bn/bn_lib.c index c480ae8b9db..610e2447d30 100644 --- a/lib/libcrypto/bn/bn_lib.c +++ b/lib/libcrypto/bn/bn_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_lib.c,v 1.40 2018/05/12 17:31:41 jsing Exp $ */ +/* $OpenBSD: bn_lib.c,v 1.41 2018/07/10 21:52:07 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -889,6 +889,54 @@ BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) #undef BN_CONSTTIME_SWAP } +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. + * The code assumes that at most one bit of condition is set. XXX add check! + * nwords is the number of words to swap. + */ +int +BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) +{ + BN_ULONG t; + int i; + + if (a == b) + return 1; + if (bn_wexpand(a, nwords) == NULL || bn_wexpand(b, nwords) == NULL) + return 0; + if (a->top > nwords || b->top > nwords) { + BNerror(BN_R_INVALID_LENGTH); + return 0; + } + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + /* swap top field */ + t = (a->top ^ b->top) & condition; + a->top ^= t; + b->top ^= t; + + /* swap neg field */ + t = (a->neg ^ b->neg) & condition; + a->neg ^= t; + b->neg ^= t; + + /* swap BN_FLG_CONSTTIME from flag field */ + t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition; + a->flags ^= t; + b->flags ^= t; + + /* swap the data */ + for (i = 0; i < nwords; i++) { + t = (a->d[i] ^ b->d[i]) & condition; + a->d[i] ^= t; + b->d[i] ^= t; + } + + return 1; +} + BN_GENCB * BN_GENCB_new(void) { |