TEST: Add a test of the new BN_signed set of functions in test/bntest.c
authorRichard Levitte <levitte@openssl.org>
Thu, 25 Nov 2021 17:00:16 +0000 (18:00 +0100)
committerRichard Levitte <levitte@openssl.org>
Thu, 20 Jan 2022 16:58:08 +0000 (17:58 +0100)
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17139)

test/bntest.c

index 69506a0e35acb7e71e83692d635cb8b556422ca4..efdb3ef963eb1d9e694d5ef2176cf77e5b443d20 100644 (file)
@@ -1834,6 +1834,137 @@ static int test_bn2padded(void)
     return st;
 }
 
+static const MPITEST kSignedTests_BE[] = {
+    {"-1", "\xff", 1},
+    {"0", "", 0},
+    {"1", "\x01", 1},
+    /*
+     * The above cover the basics, now let's go for possible bignum
+     * chunk edges and other word edges (for a broad definition of
+     * "word", i.e. 1 byte included).
+     */
+    /* 1 byte edge */
+    {"127", "\x7f", 1},
+    {"-127", "\x81", 1},
+    {"128", "\x00\x80", 2},
+    {"-128", "\x80", 1},
+    {"129", "\x00\x81", 2},
+    {"-129", "\xff\x7f", 2},
+    {"255", "\x00\xff", 2},
+    {"-255", "\xff\x01", 2},
+    {"256", "\x01\x00", 2},
+    {"-256", "\xff\x00", 2},
+    /* 2 byte edge */
+    {"32767", "\x7f\xff", 2},
+    {"-32767", "\x80\x01", 2},
+    {"32768", "\x00\x80\x00", 3},
+    {"-32768", "\x80\x00", 2},
+    {"32769", "\x00\x80\x01", 3},
+    {"-32769", "\xff\x7f\xff", 3},
+    {"65535", "\x00\xff\xff", 3},
+    {"-65535", "\xff\x00\x01", 3},
+    {"65536", "\x01\x00\x00", 3},
+    {"-65536", "\xff\x00\x00", 3},
+    /* 4 byte edge */
+    {"2147483647", "\x7f\xff\xff\xff", 4},
+    {"-2147483647", "\x80\x00\x00\x01", 4},
+    {"2147483648", "\x00\x80\x00\x00\x00", 5},
+    {"-2147483648", "\x80\x00\x00\x00", 4},
+    {"2147483649", "\x00\x80\x00\x00\x01", 5},
+    {"-2147483649", "\xff\x7f\xff\xff\xff", 5},
+    {"4294967295", "\x00\xff\xff\xff\xff", 5},
+    {"-4294967295", "\xff\x00\x00\x00\x01", 5},
+    {"4294967296", "\x01\x00\x00\x00\x00", 5},
+    {"-4294967296", "\xff\x00\x00\x00\x00", 5},
+    /* 8 byte edge */
+    {"9223372036854775807", "\x7f\xff\xff\xff\xff\xff\xff\xff", 8},
+    {"-9223372036854775807", "\x80\x00\x00\x00\x00\x00\x00\x01", 8},
+    {"9223372036854775808", "\x00\x80\x00\x00\x00\x00\x00\x00\x00", 9},
+    {"-9223372036854775808", "\x80\x00\x00\x00\x00\x00\x00\x00", 8},
+    {"9223372036854775809", "\x00\x80\x00\x00\x00\x00\x00\x00\x01", 9},
+    {"-9223372036854775809", "\xff\x7f\xff\xff\xff\xff\xff\xff\xff", 9},
+    {"18446744073709551615", "\x00\xff\xff\xff\xff\xff\xff\xff\xff", 9},
+    {"-18446744073709551615", "\xff\x00\x00\x00\x00\x00\x00\x00\x01", 9},
+    {"18446744073709551616", "\x01\x00\x00\x00\x00\x00\x00\x00\x00", 9},
+    {"-18446744073709551616", "\xff\x00\x00\x00\x00\x00\x00\x00\x00", 9},
+};
+
+static int copy_reversed(uint8_t *dst, uint8_t *src, size_t len)
+{
+    for (dst += len - 1; len > 0; src++, dst--, len--)
+        *dst = *src;
+    return 1;
+}
+
+static int test_bn2signed(int i)
+{
+    uint8_t scratch[10], reversed[10];
+    const MPITEST *test = &kSignedTests_BE[i];
+    BIGNUM *bn = NULL, *bn2 = NULL;
+    int st = 0;
+
+    if (!TEST_ptr(bn = BN_new())
+        || !TEST_true(BN_asc2bn(&bn, test->base10)))
+        goto err;
+
+    /*
+     * Check BN_signed_bn2bin() / BN_signed_bin2bn()
+     * The interesting stuff happens in the last bytes of the buffers,
+     * the beginning is just padding (i.e. sign extension).
+     */
+    i = sizeof(scratch) - test->mpi_len;
+    if (!TEST_int_eq(BN_signed_bn2bin(bn, scratch, sizeof(scratch)),
+                     sizeof(scratch))
+        || !TEST_true(copy_reversed(reversed, scratch, sizeof(scratch)))
+        || !TEST_mem_eq(test->mpi, test->mpi_len, scratch + i, test->mpi_len))
+        goto err;
+
+    if (!TEST_ptr(bn2 = BN_signed_bin2bn(scratch, sizeof(scratch), NULL))
+        || !TEST_BN_eq(bn, bn2))
+        goto err;
+
+    BN_free(bn2);
+    bn2 = NULL;
+
+    /* Check that a parse of the reversed buffer works too */
+    if (!TEST_ptr(bn2 = BN_signed_lebin2bn(reversed, sizeof(reversed), NULL))
+        || !TEST_BN_eq(bn, bn2))
+        goto err;
+
+    BN_free(bn2);
+    bn2 = NULL;
+
+    /*
+     * Check BN_signed_bn2lebin() / BN_signed_lebin2bn()
+     * The interesting stuff happens in the first bytes of the buffers,
+     * the end is just padding (i.e. sign extension).
+     */
+    i = sizeof(reversed) - test->mpi_len;
+    if (!TEST_int_eq(BN_signed_bn2lebin(bn, scratch, sizeof(scratch)),
+                     sizeof(scratch))
+        || !TEST_true(copy_reversed(reversed, scratch, sizeof(scratch)))
+        || !TEST_mem_eq(test->mpi, test->mpi_len, reversed + i, test->mpi_len))
+        goto err;
+
+    if (!TEST_ptr(bn2 = BN_signed_lebin2bn(scratch, sizeof(scratch), NULL))
+        || !TEST_BN_eq(bn, bn2))
+        goto err;
+
+    BN_free(bn2);
+    bn2 = NULL;
+
+    /* Check that a parse of the reversed buffer works too */
+    if (!TEST_ptr(bn2 = BN_signed_bin2bn(reversed, sizeof(reversed), NULL))
+        || !TEST_BN_eq(bn, bn2))
+        goto err;
+
+    st = 1;
+ err:
+    BN_free(bn2);
+    BN_free(bn);
+    return st;
+}
+
 static int test_dec2bn(void)
 {
     BIGNUM *bn = NULL;
@@ -2998,6 +3129,7 @@ int setup_tests(void)
         ADD_TEST(test_hex2bn);
         ADD_TEST(test_asc2bn);
         ADD_ALL_TESTS(test_mpi, (int)OSSL_NELEM(kMPITests));
+        ADD_ALL_TESTS(test_bn2signed, (int)OSSL_NELEM(kSignedTests_BE));
         ADD_TEST(test_negzero);
         ADD_TEST(test_badmod);
         ADD_TEST(test_expmodzero);