summaryrefslogtreecommitdiffstats
path: root/src/crypto/bn/convert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/bn/convert.c')
-rw-r--r--src/crypto/bn/convert.c178
1 files changed, 41 insertions, 137 deletions
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 0122709..531b661 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -56,9 +56,7 @@
#include <openssl/bn.h>
-#include <assert.h>
#include <ctype.h>
-#include <limits.h>
#include <stdio.h>
#include <string.h>
@@ -69,8 +67,7 @@
#include "internal.h"
BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
- size_t num_words;
- unsigned m;
+ unsigned num_words, m;
BN_ULONG word = 0;
BIGNUM *bn = NULL;
@@ -96,10 +93,7 @@ BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
return NULL;
}
- /* |bn_wexpand| must check bounds on |num_words| to write it into
- * |ret->dmax|. */
- assert(num_words <= INT_MAX);
- ret->top = (int)num_words;
+ ret->top = num_words;
ret->neg = 0;
while (len--) {
@@ -204,7 +198,7 @@ char *BN_bn2hex(const BIGNUM *bn) {
buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, BN_bn2hex, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -233,59 +227,47 @@ char *BN_bn2hex(const BIGNUM *bn) {
return buf;
}
-/* decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. */
-static int decode_hex(BIGNUM *bn, const char *in, int in_len) {
- if (in_len > INT_MAX/4) {
- OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
- return 0;
- }
- /* |in_len| is the number of hex digits. */
- if (bn_expand(bn, in_len * 4) == NULL) {
- return 0;
- }
+/* decode_hex decodes |i| bytes of hex data from |in| and updates |bn|. */
+static void decode_hex(BIGNUM *bn, const char *in, int i) {
+ int h, m, j, k, c;
+ BN_ULONG l=0;
+
+ j = i; /* least significant 'hex' */
+ h = 0;
+ while (j > 0) {
+ m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
+ l = 0;
+ for (;;) {
+ c = in[j - m];
+ if ((c >= '0') && (c <= '9')) {
+ k = c - '0';
+ } else if ((c >= 'a') && (c <= 'f')) {
+ k = c - 'a' + 10;
+ } else if ((c >= 'A') && (c <= 'F')) {
+ k = c - 'A' + 10;
+ } else {
+ k = 0; /* paranoia */
+ }
- int i = 0;
- while (in_len > 0) {
- /* Decode one |BN_ULONG| at a time. */
- int todo = BN_BYTES * 2;
- if (todo > in_len) {
- todo = in_len;
- }
+ l = (l << 4) | k;
- BN_ULONG word = 0;
- int j;
- for (j = todo; j > 0; j--) {
- char c = in[in_len - j];
-
- BN_ULONG hex;
- if (c >= '0' && c <= '9') {
- hex = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- hex = c - 'a' + 10;
- } else if (c >= 'A' && c <= 'F') {
- hex = c - 'A' + 10;
- } else {
- hex = 0;
- /* This shouldn't happen. The caller checks |isxdigit|. */
- assert(0);
+ if (--m <= 0) {
+ bn->d[h++] = l;
+ break;
}
- word = (word << 4) | hex;
}
- bn->d[i++] = word;
- in_len -= todo;
+ j -= (BN_BYTES * 2);
}
- assert(i <= bn->dmax);
- bn->top = i;
- return 1;
+
+ bn->top = h;
}
/* decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. */
-static int decode_dec(BIGNUM *bn, const char *in, int in_len) {
+static void decode_dec(BIGNUM *bn, const char *in, int in_len) {
int i, j;
BN_ULONG l = 0;
- /* Decode |BN_DEC_NUM| digits at a time. */
j = BN_DEC_NUM - (in_len % BN_DEC_NUM);
if (j == BN_DEC_NUM) {
j = 0;
@@ -295,18 +277,15 @@ static int decode_dec(BIGNUM *bn, const char *in, int in_len) {
l *= 10;
l += in[i] - '0';
if (++j == BN_DEC_NUM) {
- if (!BN_mul_word(bn, BN_DEC_CONV) ||
- !BN_add_word(bn, l)) {
- return 0;
- }
+ BN_mul_word(bn, BN_DEC_CONV);
+ BN_add_word(bn, l);
l = 0;
j = 0;
}
}
- return 1;
}
-typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len);
+typedef void (*decode_func) (BIGNUM *bn, const char *in, int i);
typedef int (*char_test_func) (int c);
static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) {
@@ -323,7 +302,7 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
in++;
}
- for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {}
+ for (i = 0; want_char((unsigned char)in[i]); i++) {}
num = i + neg;
if (outp == NULL) {
@@ -341,10 +320,13 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
BN_zero(ret);
}
- if (!decode(ret, in, i)) {
+ /* i is the number of hex digests; */
+ if (bn_expand(ret, i * 4) == NULL) {
goto err;
}
+ decode(ret, in, i);
+
bn_correct_top(ret);
if (!BN_is_zero(ret)) {
ret->neg = neg;
@@ -383,7 +365,7 @@ char *BN_bn2dec(const BIGNUM *a) {
(BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
buf = (char *)OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
- OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, BN_bn2dec, ERR_R_MALLOC_FAILURE);
goto err;
}
t = BN_dup(a);
@@ -517,81 +499,3 @@ BN_ULONG BN_get_word(const BIGNUM *bn) {
return BN_MASK2;
}
}
-
-size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) {
- const size_t bits = BN_num_bits(in);
- const size_t bytes = (bits + 7) / 8;
- /* If the number of bits is a multiple of 8, i.e. if the MSB is set,
- * prefix with a zero byte. */
- int extend = 0;
- if (bytes != 0 && (bits & 0x07) == 0) {
- extend = 1;
- }
-
- const size_t len = bytes + extend;
- if (len < bytes ||
- 4 + len < len ||
- (len & 0xffffffff) != len) {
- /* If we cannot represent the number then we emit zero as the interface
- * doesn't allow an error to be signalled. */
- if (out) {
- memset(out, 0, 4);
- }
- return 4;
- }
-
- if (out == NULL) {
- return 4 + len;
- }
-
- out[0] = len >> 24;
- out[1] = len >> 16;
- out[2] = len >> 8;
- out[3] = len;
- if (extend) {
- out[4] = 0;
- }
- BN_bn2bin(in, out + 4 + extend);
- if (in->neg && len > 0) {
- out[4] |= 0x80;
- }
- return len + 4;
-}
-
-BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
- if (len < 4) {
- OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
- return NULL;
- }
- const size_t in_len = ((size_t)in[0] << 24) |
- ((size_t)in[1] << 16) |
- ((size_t)in[2] << 8) |
- ((size_t)in[3]);
- if (in_len != len - 4) {
- OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
- return NULL;
- }
-
- if (out == NULL) {
- out = BN_new();
- }
- if (out == NULL) {
- OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- if (in_len == 0) {
- BN_zero(out);
- return out;
- }
-
- in += 4;
- if (BN_bin2bn(in, in_len, out) == NULL) {
- return NULL;
- }
- out->neg = ((*in) & 0x80) != 0;
- if (out->neg) {
- BN_clear_bit(out, BN_num_bits(out) - 1);
- }
- return out;
-}