summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/bn/bn_convert.c102
1 files changed, 44 insertions, 58 deletions
diff --git a/src/lib/libcrypto/bn/bn_convert.c b/src/lib/libcrypto/bn/bn_convert.c
index d38747e017..6a6354f44e 100644
--- a/src/lib/libcrypto/bn/bn_convert.c
+++ b/src/lib/libcrypto/bn/bn_convert.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_convert.c,v 1.22 2024/06/22 16:33:00 jsing Exp $ */ 1/* $OpenBSD: bn_convert.c,v 1.23 2024/11/08 14:18:44 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 *
@@ -69,87 +69,73 @@
69 69
70#include "bn_local.h" 70#include "bn_local.h"
71#include "bytestring.h" 71#include "bytestring.h"
72#include "crypto_internal.h"
72 73
73static int bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs); 74static int bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs);
74static int bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs); 75static int bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs);
75 76
76static const char hex_digits[] = "0123456789ABCDEF"; 77static const char hex_digits[] = "0123456789ABCDEF";
77 78
78typedef enum {
79 big,
80 little,
81} endianness_t;
82
83/* ignore negative */
84static int 79static int
85bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness) 80bn_bn2binpad_internal(const BIGNUM *bn, uint8_t *out, int out_len,
81 int little_endian)
86{ 82{
87 int n; 83 uint8_t mask, v;
88 size_t i, lasti, j, atop, mask; 84 BN_ULONG w;
89 BN_ULONG l; 85 int i, j;
90 86 int b, n;
91 /*
92 * In case |a| is fixed-top, BN_num_bytes can return bogus length,
93 * but it's assumed that fixed-top inputs ought to be "nominated"
94 * even for padded output, so it works out...
95 */
96 n = BN_num_bytes(a);
97 if (tolen == -1)
98 tolen = n;
99 else if (tolen < n) { /* uncommon/unlike case */
100 BIGNUM temp = *a;
101 87
102 bn_correct_top(&temp); 88 n = BN_num_bytes(bn);
103 89
104 n = BN_num_bytes(&temp); 90 if (out_len == -1)
105 if (tolen < n) 91 out_len = n;
106 return -1; 92 if (out_len < n)
107 } 93 return -1;
108 94
109 /* Swipe through whole available data and don't give away padded zero. */ 95 if (bn->dmax == 0) {
110 atop = a->dmax * BN_BYTES; 96 explicit_bzero(out, out_len);
111 if (atop == 0) { 97 return out_len;
112 explicit_bzero(to, tolen);
113 return tolen;
114 } 98 }
115 99
116 lasti = atop - 1; 100 mask = 0;
117 atop = a->top * BN_BYTES; 101 b = BN_BITS2;
118 102 j = 0;
119 if (endianness == big)
120 to += tolen; /* start from the end of the buffer */
121 103
122 for (i = 0, j = 0; j < (size_t)tolen; j++) { 104 for (i = out_len - 1; i >= 0; i--) {
123 unsigned char val; 105 if (b == BN_BITS2) {
124 106 mask = crypto_ct_lt_mask(j, bn->top);
125 l = a->d[i / BN_BYTES]; 107 w = bn->d[j++ % bn->dmax];
126 mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); 108 b = 0;
127 val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); 109 }
128 110 out[i] = (w >> b) & mask;
129 if (endianness == big) 111 b += 8;
130 *--to = val; 112 }
131 else
132 *to++ = val;
133 113
134 i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ 114 if (little_endian) {
115 for (i = 0, j = out_len - 1; i < out_len / 2; i++, j--) {
116 v = out[i];
117 out[i] = out[j];
118 out[j] = v;
119 }
135 } 120 }
136 121
137 return tolen; 122 return out_len;
138} 123}
139 124
140int 125int
141BN_bn2bin(const BIGNUM *a, unsigned char *to) 126BN_bn2bin(const BIGNUM *bn, unsigned char *to)
142{ 127{
143 return bn2binpad(a, to, -1, big); 128 return bn_bn2binpad_internal(bn, to, -1, 0);
144} 129}
145LCRYPTO_ALIAS(BN_bn2bin); 130LCRYPTO_ALIAS(BN_bn2bin);
146 131
147int 132int
148BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) 133BN_bn2binpad(const BIGNUM *bn, unsigned char *to, int to_len)
149{ 134{
150 if (tolen < 0) 135 if (to_len < 0)
151 return -1; 136 return -1;
152 return bn2binpad(a, to, tolen, big); 137
138 return bn_bn2binpad_internal(bn, to, to_len, 0);
153} 139}
154LCRYPTO_ALIAS(BN_bn2binpad); 140LCRYPTO_ALIAS(BN_bn2binpad);
155 141
@@ -225,12 +211,12 @@ BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn)
225LCRYPTO_ALIAS(BN_bin2bn); 211LCRYPTO_ALIAS(BN_bin2bn);
226 212
227int 213int
228BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) 214BN_bn2lebinpad(const BIGNUM *bn, unsigned char *to, int to_len)
229{ 215{
230 if (tolen < 0) 216 if (to_len < 0)
231 return -1; 217 return -1;
232 218
233 return bn2binpad(a, to, tolen, little); 219 return bn_bn2binpad_internal(bn, to, to_len, 1);
234} 220}
235LCRYPTO_ALIAS(BN_bn2lebinpad); 221LCRYPTO_ALIAS(BN_bn2lebinpad);
236 222