From 0cda1c0e83b0922a5d125165a6793c303052b899 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 15 Jan 2025 22:25:36 +0100 Subject: [PATCH] bignum: Make sure the padding is large enough for the number Signed-off-by: Jakub Jelen Reviewed-by: Andreas Schneider Reviewed-by: Sahana Prasad --- src/bignum.c | 5 ++++- tests/unittests/torture_bignum.c | 22 +++++++++++++++++++++- tests/unittests/torture_buffer.c | 15 ++++++++++++--- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/bignum.c b/src/bignum.c index 00ad0fb9..b18c1162 100644 --- a/src/bignum.c +++ b/src/bignum.c @@ -40,7 +40,10 @@ static ssh_string make_bignum_string(bignum num, size_t pad_to_len) pad++; } } else { - pad = pad_to_len - bignum_num_bytes(num); + if (len > pad_to_len) { + return NULL; + } + pad = pad_to_len - len; } #ifdef DEBUG_CRYPTO diff --git a/tests/unittests/torture_bignum.c b/tests/unittests/torture_bignum.c index 9e67a9c7..6f679946 100644 --- a/tests/unittests/torture_bignum.c +++ b/tests/unittests/torture_bignum.c @@ -54,11 +54,13 @@ static void check_bignum(int n, const char *nstr) bignum num3 = NULL; ssh_string str = NULL; char *dec = NULL; + int rc; num = bignum_new(); assert_non_null(num); - assert_int_equal (1, bignum_set_word (num, n)); + rc = bignum_set_word(num, n); + assert_int_equal(rc, 1); ssh_print_bignum("num", num); @@ -115,6 +117,24 @@ static void check_bignum(int n, const char *nstr) assert_string_equal(nstr, dec); ssh_crypto_free(dec); + /* negative test */ + str = ssh_make_padded_bignum_string(num, 2); + if (n > 65535) { + /* larger values need larger padding! */ + assert_null(str); + } else { + assert_non_null(str); + assert_int_equal(2, ntohl(str->size)); + if (n > 0 && n <= 255) { + assert_int_equal(0, str->data[0]); + assert_int_equal(n, str->data[1]); + } else { + assert_int_equal(n >> 8, str->data[0]); + assert_int_equal(n & 0xFF, str->data[1]); + } + ssh_string_free(str); + } + bignum_safe_free(num); bignum_safe_free(num2); bignum_safe_free(num3); diff --git a/tests/unittests/torture_buffer.c b/tests/unittests/torture_buffer.c index c168036f..7adeb34c 100644 --- a/tests/unittests/torture_buffer.c +++ b/tests/unittests/torture_buffer.c @@ -277,17 +277,26 @@ static void torture_ssh_buffer_bignum(void **state) num = bignum_new(); assert_non_null(num); - assert_int_equal(1, bignum_set_word(num, 255)); + + rc = bignum_set_word(num, 255); + assert_int_equal(rc, 1); rc = ssh_buffer_pack(buffer, "FB", num, (size_t)4, num); assert_int_equal(rc, SSH_OK); - bignum_safe_free(num); - len = ssh_buffer_get_len(buffer); assert_int_equal(len, sizeof(verif) - 1); assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) - 1); + /* negative test -- this number requires 3 bytes */ + rc = bignum_set_word(num, 256 * 256); + assert_int_equal(rc, 1); + + rc = ssh_buffer_pack(buffer, "FB", num, (size_t)2, num); + assert_int_equal(rc, SSH_ERROR); + + bignum_safe_free(num); + SSH_BUFFER_FREE(buffer); }