to_sbin/to_ubin/pack: don't write anything in case of buffer overflow
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
diff --git a/bn_mp_pack.c b/bn_mp_pack.c
index 48da1b2..6e00b6f 100644
--- a/bn_mp_pack.c
+++ b/bn_mp_pack.c
@@ -6,16 +6,18 @@
/* based on gmp's mpz_export.
* see http://gmplib.org/manual/Integer-Import-and-Export.html
*/
-mp_err mp_pack(void *rop, size_t maxcount, size_t *writtencount, mp_order order, size_t size,
+mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order, size_t size,
mp_endian endian, size_t nails, const mp_int *op)
{
mp_err err;
- size_t odd_nails, nail_bytes, i, j, count, written = 0;
+ size_t odd_nails, nail_bytes, i, j, count;
unsigned char odd_nail_mask;
mp_int t;
- if (maxcount == 0u) {
+ count = mp_pack_count(op, nails, size);
+
+ if (count > maxcount) {
return MP_BUF;
}
@@ -34,13 +36,7 @@ mp_err mp_pack(void *rop, size_t maxcount, size_t *writtencount, mp_order order,
}
nail_bytes = nails / 8u;
- count = mp_pack_count(&t, nails, size);
-
for (i = 0u; i < count; ++i) {
- if (i >= maxcount) {
- err = MP_BUF;
- break;
- }
for (j = 0u; j < size; ++j) {
unsigned char *byte = (unsigned char *)rop +
(((order == MP_LSB_FIRST) ? i : ((count - 1u) - i)) * size) +
@@ -58,11 +54,10 @@ mp_err mp_pack(void *rop, size_t maxcount, size_t *writtencount, mp_order order,
}
}
- written++;
}
- if (writtencount != NULL) {
- *writtencount = written;
+ if (written != NULL) {
+ *written = count;
}
err = MP_OKAY;
diff --git a/bn_mp_pack_count.c b/bn_mp_pack_count.c
index 0199d04..dfecdf9 100644
--- a/bn_mp_pack_count.c
+++ b/bn_mp_pack_count.c
@@ -3,7 +3,7 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
-size_t mp_pack_count(mp_int *a, size_t nails, size_t size)
+size_t mp_pack_count(const mp_int *a, size_t nails, size_t size)
{
size_t bits = (size_t)mp_count_bits(a);
return ((bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u));
diff --git a/bn_mp_to_radix.c b/bn_mp_to_radix.c
index e0613b4..7fa86ca 100644
--- a/bn_mp_to_radix.c
+++ b/bn_mp_to_radix.c
@@ -55,7 +55,7 @@ mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, i
if (--maxlen < 1u) {
/* no more room */
err = MP_BUF;
- break;
+ goto LBL_ERR;
}
if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
goto LBL_ERR;
@@ -71,6 +71,7 @@ mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, i
/* append a NULL so the string is properly terminated */
*str = '\0';
digs++;
+
if (written != NULL) {
*written = (a->sign == MP_NEG) ? (digs + 1u): digs;
}
diff --git a/bn_mp_to_sbin.c b/bn_mp_to_sbin.c
index 3e194ca..dbaf53e 100644
--- a/bn_mp_to_sbin.c
+++ b/bn_mp_to_sbin.c
@@ -10,7 +10,6 @@ mp_err mp_to_sbin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *wr
if (maxlen == 0u) {
return MP_BUF;
}
-
if ((err = mp_to_ubin(a, buf + 1, maxlen - 1u, written)) != MP_OKAY) {
return err;
}
diff --git a/bn_mp_to_ubin.c b/bn_mp_to_ubin.c
index cfa391a..5e4a5da 100644
--- a/bn_mp_to_ubin.c
+++ b/bn_mp_to_ubin.c
@@ -6,11 +6,12 @@
/* store in unsigned [big endian] format */
mp_err mp_to_ubin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *written)
{
- size_t x;
+ size_t x, count;
mp_err err;
mp_int t;
- if (maxlen == 0u) {
+ count = mp_ubin_size(a);
+ if (count > maxlen) {
return MP_BUF;
}
@@ -18,27 +19,21 @@ mp_err mp_to_ubin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *wr
return err;
}
- x = 0u;
- while (!MP_IS_ZERO(&t)) {
- if (maxlen == 0u) {
- err = MP_BUF;
- goto LBL_ERR;
- }
- maxlen--;
+ for (x = count; x --> 0;) {
#ifndef MP_8BIT
- buf[x++] = (unsigned char)(t.dp[0] & 255u);
+ buf[x] = (unsigned char)(t.dp[0] & 255u);
#else
- buf[x++] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7));
+ buf[x] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7));
#endif
if ((err = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
}
- s_mp_reverse(buf, x);
if (written != NULL) {
- *written = x;
+ *written = count;
}
+
LBL_ERR:
mp_clear(&t);
return err;
diff --git a/tommath.h b/tommath.h
index deb042a..1e0192b 100644
--- a/tommath.h
+++ b/tommath.h
@@ -384,7 +384,7 @@ mp_err mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size, mp_endi
size_t nails, const void *op) MP_WUR;
/* pack binary data */
-size_t mp_pack_count(mp_int *a, size_t nails, size_t size) MP_WUR;
+size_t mp_pack_count(const mp_int *a, size_t nails, size_t size) MP_WUR;
mp_err mp_pack(void *rop, size_t maxcount, size_t *writtencount, mp_order order, size_t size, mp_endian endian,
size_t nails, const mp_int *op) MP_WUR;
diff --git a/tommath_class.h b/tommath_class.h
index ee30b29..3abb55a 100644
--- a/tommath_class.h
+++ b/tommath_class.h
@@ -1080,7 +1080,7 @@
# define BN_MP_CLEAR_C
# define BN_MP_DIV_2D_C
# define BN_MP_INIT_COPY_C
-# define BN_S_MP_REVERSE_C
+# define BN_MP_UBIN_SIZE_C
#endif
#if defined(BN_MP_UBIN_SIZE_C)