Skip to content

Commit 9c9fce6

Browse files
committed
tx: disallow invalid satoshi amounts for btc signature hash generation
1 parent 3902889 commit 9c9fce6

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

src/tx_io.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "tx_io.h"
77
#include <string.h>
88

9+
#define WALLY_SATOSHI_MAX ((uint64_t)WALLY_BTC_MAX * WALLY_SATOSHI_PER_BTC)
10+
911
#define SIGTYPE_ALL (WALLY_SIGTYPE_PRE_SW | WALLY_SIGTYPE_SW_V0 | WALLY_SIGTYPE_SW_V1)
1012

1113
/* Cache keys for data that is constant while signing a given tx.
@@ -62,6 +64,14 @@ static bool value_len_ok(size_t len)
6264
len == WALLY_TX_ASSET_CT_VALUE_UNBLIND_LEN;
6365
}
6466

67+
static uint64_t satoshi_from_item(const struct wally_map_item *item)
68+
{
69+
uint64_t v;
70+
/* Map values must be in cpu byte order, but may not be aligned */
71+
memcpy(&v, item->value, item->value_len);
72+
return v;
73+
}
74+
6575
/* Ensure 'm' is integer-indexed with num_items valid items */
6676
static bool map_has_all(const struct wally_map *m, size_t num_items,
6777
bool (*len_fn)(size_t))
@@ -87,8 +97,12 @@ static bool map_has_one(const struct wally_map *m, size_t index,
8797
const struct wally_map_item *item = m->items + i;
8898
if (item->key || !item->value || !len_fn(item->value_len))
8999
return false;
90-
if (index == item->key_len)
100+
if (index == item->key_len) {
101+
if (len_fn == satoshi_len_ok &&
102+
satoshi_from_item(item) > WALLY_SATOSHI_MAX)
103+
return false; /* Invalid BTC amount */
91104
return true;
105+
}
92106
}
93107
return false;
94108
}
@@ -111,10 +125,7 @@ static inline void hash_le64(struct sha256_ctx *ctx, uint64_t v)
111125
static void hash_map_le64(struct sha256_ctx *ctx,
112126
const struct wally_map *m, size_t index)
113127
{
114-
const struct wally_map_item *item = wally_map_get_integer(m, index);
115-
uint64_t v;
116-
memcpy(&v, item->value, item->value_len);
117-
hash_le64(ctx, v);
128+
hash_le64(ctx, satoshi_from_item(wally_map_get_integer(m, index)));
118129
}
119130

120131
static inline void hash_bytes(struct sha256_ctx *ctx,
@@ -385,11 +396,8 @@ static void txio_hash_sha_amounts(cursor_io *io, const struct wally_map *values)
385396
if (!txio_hash_cached_item(io, TXIO_SHA_AMOUNTS)) {
386397
struct sha256_ctx ctx;
387398
sha256_init(&ctx);
388-
for (size_t i = 0; i < values->num_items; ++i) {
389-
uint64_t v;
390-
memcpy(&v, values->items[i].value, values->items[i].value_len);
391-
hash_le64(&ctx, v);
392-
}
399+
for (size_t i = 0; i < values->num_items; ++i)
400+
hash_le64(&ctx, satoshi_from_item(values->items + i));
393401
txio_hash_sha256_ctx(io, &ctx, TXIO_SHA_AMOUNTS);
394402
}
395403
}

0 commit comments

Comments
 (0)