diff options
author | tb <> | 2019-06-17 17:11:48 +0000 |
---|---|---|
committer | tb <> | 2019-06-17 17:11:48 +0000 |
commit | a58a6d90c7fa6ece9183c620ed89abddbd00699d (patch) | |
tree | a4ed0e1c301397364b5fd748784feb51f7b6e36c /src | |
parent | c7305ad941e6223f20a1f38219e82ac0fb4f5f77 (diff) | |
download | openbsd-a58a6d90c7fa6ece9183c620ed89abddbd00699d.tar.gz openbsd-a58a6d90c7fa6ece9183c620ed89abddbd00699d.tar.bz2 openbsd-a58a6d90c7fa6ece9183c620ed89abddbd00699d.zip |
Make BN_num_bits_word() constant time.
Previously, this function would leak the most significant word of its
argument due to branching and memory access pattern. This patch is
enough to fix the use of BN_num_bits() on RSA prime factors in the
library.
The diff is a simplified and more readable (but perhaps less efficient)
version of https://github.com/openssl/openssl/commit/972c87df
by Andy Polyakov and David Benjamin (pre license change). Consult that
commit message for details. Subsequent fixes to follow in the near future.
Issue pointed out by David Schrammel and Samuel Weiser as part of
a larger report.
tests & ok inoguchi, ok jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/bn/bn_lib.c | 66 |
1 files changed, 18 insertions, 48 deletions
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c index 0025cf52ef..1a91b9e60c 100644 --- a/src/lib/libcrypto/bn/bn_lib.c +++ b/src/lib/libcrypto/bn/bn_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_lib.c,v 1.46 2019/03/23 18:48:15 beck Exp $ */ | 1 | /* $OpenBSD: bn_lib.c,v 1.47 2019/06/17 17:11:48 tb 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 | * |
@@ -151,53 +151,23 @@ BN_value_one(void) | |||
151 | int | 151 | int |
152 | BN_num_bits_word(BN_ULONG l) | 152 | BN_num_bits_word(BN_ULONG l) |
153 | { | 153 | { |
154 | static const unsigned char bits[256] = { | 154 | BN_ULONG x, mask; |
155 | 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, | 155 | int bits; |
156 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | 156 | unsigned int shift; |
157 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | 157 | |
158 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | 158 | /* Constant time calculation of floor(log2(l)) + 1. */ |
159 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | 159 | bits = (l != 0); |
160 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | 160 | shift = BN_BITS4; /* On _LP64 this is 32, otherwise 16. */ |
161 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | 161 | do { |
162 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | 162 | x = l >> shift; |
163 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 163 | /* If x is 0, set mask to 0, otherwise set it to all 1s. */ |
164 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 164 | mask = ((~x & (x - 1)) >> (BN_BITS2 - 1)) - 1; |
165 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 165 | bits += shift & mask; |
166 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 166 | /* If x is 0, leave l alone, otherwise set l = x. */ |
167 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 167 | l ^= (x ^ l) & mask; |
168 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 168 | } while ((shift /= 2) != 0); |
169 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 169 | |
170 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | 170 | return bits; |
171 | }; | ||
172 | |||
173 | #ifdef _LP64 | ||
174 | if (l & 0xffffffff00000000L) { | ||
175 | if (l & 0xffff000000000000L) { | ||
176 | if (l & 0xff00000000000000L) { | ||
177 | return (bits[(int)(l >> 56)] + 56); | ||
178 | } else | ||
179 | return (bits[(int)(l >> 48)] + 48); | ||
180 | } else { | ||
181 | if (l & 0x0000ff0000000000L) { | ||
182 | return (bits[(int)(l >> 40)] + 40); | ||
183 | } else | ||
184 | return (bits[(int)(l >> 32)] + 32); | ||
185 | } | ||
186 | } else | ||
187 | #endif | ||
188 | { | ||
189 | if (l & 0xffff0000L) { | ||
190 | if (l & 0xff000000L) | ||
191 | return (bits[(int)(l >> 24L)] + 24); | ||
192 | else | ||
193 | return (bits[(int)(l >> 16L)] + 16); | ||
194 | } else { | ||
195 | if (l & 0xff00L) | ||
196 | return (bits[(int)(l >> 8)] + 8); | ||
197 | else | ||
198 | return (bits[(int)(l)]); | ||
199 | } | ||
200 | } | ||
201 | } | 171 | } |
202 | 172 | ||
203 | int | 173 | int |