summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/bn/arch/amd64/bn_arch.h27
-rw-r--r--src/lib/libcrypto/bn/arch/i386/bn_arch.h27
-rw-r--r--src/lib/libcrypto/bn/bn_div.c85
-rw-r--r--src/lib/libcrypto/bn/bn_local.h10
-rw-r--r--src/lib/libcrypto/bn/bn_word.c5
5 files changed, 87 insertions, 67 deletions
diff --git a/src/lib/libcrypto/bn/arch/amd64/bn_arch.h b/src/lib/libcrypto/bn/arch/amd64/bn_arch.h
index 065f6b1c3b..6b7eaf5eee 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.7 2023/01/23 12:17:57 jsing Exp $ */ 1/* $OpenBSD: bn_arch.h,v 1.8 2023/01/28 16:33:34 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -15,6 +15,8 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17 17
18#include <openssl/bn.h>
19
18#ifndef HEADER_BN_ARCH_H 20#ifndef HEADER_BN_ARCH_H
19#define HEADER_BN_ARCH_H 21#define HEADER_BN_ARCH_H
20 22
@@ -36,5 +38,28 @@
36 38
37#define HAVE_BN_SUB_WORDS 39#define HAVE_BN_SUB_WORDS
38 40
41#if defined(__GNUC__)
42#define HAVE_BN_DIV_REM_WORDS_INLINE
43
44static inline void
45bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
46 BN_ULONG *out_r)
47{
48 BN_ULONG q, r;
49
50 /*
51 * Unsigned division of %rdx:%rax by d with quotient being stored in
52 * %rax and remainder in %rdx.
53 */
54 __asm__ volatile ("divq %4"
55 : "=a"(q), "=d"(r)
56 : "d"(h), "a"(l), "rm"(d)
57 : "cc");
58
59 *out_q = q;
60 *out_r = r;
61}
62#endif /* __GNUC__ */
63
39#endif 64#endif
40#endif 65#endif
diff --git a/src/lib/libcrypto/bn/arch/i386/bn_arch.h b/src/lib/libcrypto/bn/arch/i386/bn_arch.h
index 681c2090a7..e2b4957efc 100644
--- a/src/lib/libcrypto/bn/arch/i386/bn_arch.h
+++ b/src/lib/libcrypto/bn/arch/i386/bn_arch.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_arch.h,v 1.6 2023/01/23 12:17:57 jsing Exp $ */ 1/* $OpenBSD: bn_arch.h,v 1.7 2023/01/28 16:33:34 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -15,6 +15,8 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17 17
18#include <openssl/bn.h>
19
18#ifndef HEADER_BN_ARCH_H 20#ifndef HEADER_BN_ARCH_H
19#define HEADER_BN_ARCH_H 21#define HEADER_BN_ARCH_H
20 22
@@ -35,5 +37,28 @@
35 37
36#define HAVE_BN_SUB_WORDS 38#define HAVE_BN_SUB_WORDS
37 39
40#if defined(__GNUC__)
41#define HAVE_BN_DIV_REM_WORDS_INLINE
42
43static inline void
44bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
45 BN_ULONG *out_r)
46{
47 BN_ULONG q, r;
48
49 /*
50 * Unsigned division of %edx:%eax by d with quotient being stored in
51 * %eax and remainder in %edx.
52 */
53 __asm__ volatile ("divl %4"
54 : "=a"(q), "=d"(r)
55 : "a"(l), "d"(h), "rm"(d)
56 : "cc");
57
58 *out_q = q;
59 *out_r = r;
60}
61#endif /* __GNUC__ */
62
38#endif 63#endif
39#endif 64#endif
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c
index 8ec2e01831..e60fb84062 100644
--- a/src/lib/libcrypto/bn/bn_div.c
+++ b/src/lib/libcrypto/bn/bn_div.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_div.c,v 1.33 2023/01/23 12:02:48 jsing Exp $ */ 1/* $OpenBSD: bn_div.c,v 1.34 2023/01/28 16:33:34 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 *
@@ -150,49 +150,30 @@ bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
150#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */ 150#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
151#endif 151#endif
152 152
153#ifndef HAVE_BN_DIV_3_WORDS 153/*
154 * Divide a double word (h:l) by d, returning the quotient q and the remainder
155 * r, such that q * d + r is equal to the numerator.
156 */
157#ifndef HAVE_BN_DIV_REM_WORDS
158#ifndef HAVE_BN_DIV_REM_WORDS_INLINE
159static inline
160bn_div_rem_words_inline(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
161 BN_ULONG *out_r)
162{
163 *q = bn_div_words(h, l, d);
164 *r = (l - q * d) & BN_MASK2;
165}
166#endif
154 167
155#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 168void
156# if defined(__GNUC__) && __GNUC__>=2 169bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
157# if defined(__i386) || defined (__i386__) 170 BN_ULONG *out_r)
158 /* 171{
159 * There were two reasons for implementing this template: 172 bn_div_rem_words_inline(h, l, d, out_q, out_r);
160 * - GNU C generates a call to a function (__udivdi3 to be exact) 173}
161 * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to 174#endif
162 * understand why...); 175
163 * - divl doesn't only calculate quotient, but also leaves 176#ifndef HAVE_BN_DIV_3_WORDS
164 * remainder in %edx which we can definitely use here:-)
165 *
166 * <appro@fy.chalmers.se>
167 */
168#undef bn_div_words
169# define bn_div_words(n0,n1,d0) \
170 ({ asm volatile ( \
171 "divl %4" \
172 : "=a"(q), "=d"(rem) \
173 : "a"(n1), "d"(n0), "g"(d0) \
174 : "cc"); \
175 q; \
176 })
177# define REMAINDER_IS_ALREADY_CALCULATED
178# elif defined(__x86_64)
179 /*
180 * Same story here, but it's 128-bit by 64-bit division. Wow!
181 * <appro@fy.chalmers.se>
182 */
183# undef bn_div_words
184# define bn_div_words(n0,n1,d0) \
185 ({ asm volatile ( \
186 "divq %4" \
187 : "=a"(q), "=d"(rem) \
188 : "a"(n1), "d"(n0), "g"(d0) \
189 : "cc"); \
190 q; \
191 })
192# define REMAINDER_IS_ALREADY_CALCULATED
193# endif /* __<cpu> */
194# endif /* __GNUC__ */
195#endif /* OPENSSL_NO_ASM */
196 177
197/* 178/*
198 * Interface is somewhat quirky, |m| is pointer to most significant limb, 179 * Interface is somewhat quirky, |m| is pointer to most significant limb,
@@ -219,19 +200,8 @@ bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0)
219#ifdef BN_LLONG 200#ifdef BN_LLONG
220 BN_ULLONG t2; 201 BN_ULLONG t2;
221 202
222#if defined(BN_DIV2W) && !defined(bn_div_words) 203 bn_div_rem_words(n0, n1, d0, &q, &rem);
223 q = (BN_ULONG)((((BN_ULLONG)n0 << BN_BITS2) | n1) / d0);
224#else
225 q = bn_div_words(n0, n1, d0);
226#endif
227 204
228#ifndef REMAINDER_IS_ALREADY_CALCULATED
229 /*
230 * rem doesn't have to be BN_ULLONG. The least we
231 * know it's less that d0, isn't it?
232 */
233 rem = (n1 - q * d0) & BN_MASK2;
234#endif
235 t2 = (BN_ULLONG)d1 * q; 205 t2 = (BN_ULLONG)d1 * q;
236 206
237 for (;;) { 207 for (;;) {
@@ -245,10 +215,7 @@ bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0)
245#else /* !BN_LLONG */ 215#else /* !BN_LLONG */
246 BN_ULONG t2l, t2h; 216 BN_ULONG t2l, t2h;
247 217
248 q = bn_div_words(n0, n1, d0); 218 bn_div_rem_words(n0, n1, d0, &q, &rem);
249#ifndef REMAINDER_IS_ALREADY_CALCULATED
250 rem = (n1 - q * d0) & BN_MASK2;
251#endif
252 219
253#if defined(BN_UMULT_LOHI) 220#if defined(BN_UMULT_LOHI)
254 BN_UMULT_LOHI(t2l, t2h, d1, q); 221 BN_UMULT_LOHI(t2l, t2h, d1, q);
diff --git a/src/lib/libcrypto/bn/bn_local.h b/src/lib/libcrypto/bn/bn_local.h
index 74e158d6fd..bcd6fa2732 100644
--- a/src/lib/libcrypto/bn/bn_local.h
+++ b/src/lib/libcrypto/bn/bn_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_local.h,v 1.5 2023/01/20 17:26:03 jsing Exp $ */ 1/* $OpenBSD: bn_local.h,v 1.6 2023/01/28 16:33:34 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 *
@@ -657,12 +657,16 @@ void bn_correct_top(BIGNUM *a);
657int bn_expand(BIGNUM *a, int bits); 657int bn_expand(BIGNUM *a, int bits);
658int bn_wexpand(BIGNUM *a, int words); 658int bn_wexpand(BIGNUM *a, int words);
659 659
660BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
661 int num);
662BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
663 int num);
660BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); 664BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
661BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); 665BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
662void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); 666void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
663BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); 667BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
664BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, int num); 668void bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
665BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, int num); 669 BN_ULONG *out_r);
666 670
667int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); 671int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
668int bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc); 672int bn_rand_interval(BIGNUM *rnd, const BIGNUM *lower_inc, const BIGNUM *upper_exc);
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c
index 4663237b05..7077d3ad7a 100644
--- a/src/lib/libcrypto/bn/bn_word.c
+++ b/src/lib/libcrypto/bn/bn_word.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_word.c,v 1.16 2022/11/26 16:08:51 tb Exp $ */ 1/* $OpenBSD: bn_word.c,v 1.17 2023/01/28 16:33:34 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 *
@@ -125,8 +125,7 @@ BN_div_word(BIGNUM *a, BN_ULONG w)
125 BN_ULONG l, d; 125 BN_ULONG l, d;
126 126
127 l = a->d[i]; 127 l = a->d[i];
128 d = bn_div_words(ret, l, w); 128 bn_div_rem_words(ret, l, w, &d, &ret);
129 ret = (l - ((d*w)&BN_MASK2))&BN_MASK2;
130 a->d[i] = d; 129 a->d[i] = d;
131 } 130 }
132 if ((a->top > 0) && (a->d[a->top - 1] == 0)) 131 if ((a->top > 0) && (a->d[a->top - 1] == 0))