From e4e7a30c9eb5898b7c6953d78e98229760d2d76a Mon Sep 17 00:00:00 2001 From: tb Date: Fri, 31 Mar 2023 19:40:08 +0000 Subject: [PATCH] Add regress coverage for the new behavior of BN_copy() with respect to flags. --- regress/lib/libcrypto/bn/bn_unit.c | 162 ++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 1 deletion(-) diff --git a/regress/lib/libcrypto/bn/bn_unit.c b/regress/lib/libcrypto/bn/bn_unit.c index 6c5b2107395..95764dfce16 100644 --- a/regress/lib/libcrypto/bn/bn_unit.c +++ b/regress/lib/libcrypto/bn/bn_unit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_unit.c,v 1.3 2023/02/14 15:08:15 tb Exp $ */ +/* $OpenBSD: bn_unit.c,v 1.4 2023/03/31 19:40:08 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler @@ -92,6 +92,163 @@ test_bn_num_bits_word(void) return failed; } +#define BN_FLG_ALL_KNOWN \ + (BN_FLG_STATIC_DATA | BN_FLG_CONSTTIME | BN_FLG_MALLOCED) + +static int +bn_check_expected_flags(const BIGNUM *bn, int expected, const char *fn, + const char *descr) +{ + int flags, got; + int ret = 1; + + flags = BN_get_flags(bn, BN_FLG_ALL_KNOWN); + + if ((got = flags & expected) != expected) { + fprintf(stderr, "%s: %s: expected flags: want %x, got %x\n", + fn, descr, expected, got); + ret = 0; + } + + if ((got = flags & ~expected) != 0) { + fprintf(stderr, "%s: %s: unexpected flags: want %x, got %x\n", + fn, descr, 0, got); + ret = 0; + } + + return ret; +} + +static int +test_bn_copy_copies_flags(void) +{ + BIGNUM *dst, *src; + int failed = 0; + + if ((dst = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after BN_new")) + failed |= 1; + + if (BN_copy(dst, BN_value_one()) == NULL) + errx(1, "%s: bn_copy()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after bn_copy")) + failed |= 1; + + if ((src = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + BN_set_flags(src, BN_FLG_CONSTTIME); + + if (!bn_check_expected_flags(src, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "src after BN_set_flags")) + failed |= 1; + + if (!BN_set_word(src, 57)) + errx(1, "%s: BN_set_word(src, 57)", __func__); + + if (BN_copy(dst, src) == NULL) + errx(1, "%s: BN_copy(dst, src)", __func__); + + if (BN_cmp(src, dst) != 0) { + fprintf(stderr, "copy not equal to original\n"); + failed |= 1; + } + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "dst after BN_copy(dst, src)")) + failed |= 1; + + BN_free(dst); + BN_free(src); + + return failed; +} + +static int +test_bn_copy_consttime_is_sticky(void) +{ + BIGNUM *src, *dst; + int failed = 0; + + if ((src = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + if (!bn_check_expected_flags(src, BN_FLG_MALLOCED, + __func__, "src after BN_new")) + failed |= 1; + + if ((dst = BN_new()) == NULL) + errx(1, "%s: dst = BN_new()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after BN_new")) + failed |= 1; + + BN_set_flags(dst, BN_FLG_CONSTTIME); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "src after BN_new")) + failed |= 1; + + if (BN_copy(dst, BN_value_one()) == NULL) + errx(1, "%s: bn_copy()", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "dst after bn_copy")) + failed |= 1; + + BN_free(dst); + BN_free(src); + + return failed; +} + +static int +test_bn_dup_consttime_is_sticky(void) +{ + BIGNUM *src, *dst; + int failed = 0; + + if (!bn_check_expected_flags(BN_value_one(), BN_FLG_STATIC_DATA, + __func__, "flags on BN_value_one()")) + failed |= 1; + + if ((dst = BN_dup(BN_value_one())) == NULL) + errx(1, "%s: dst = BN_dup(BN_value_one())", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED, + __func__, "dst after BN_dup(BN_value_one())")) + failed |= 1; + + BN_free(dst); + + if ((src = BN_new()) == NULL) + errx(1, "%s: src = BN_new()", __func__); + + BN_set_flags(src, BN_FLG_CONSTTIME); + + if (!bn_check_expected_flags(src, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "src after BN_new")) + failed |= 1; + + if ((dst = BN_dup(src)) == NULL) + errx(1, "%s: dst = BN_dup(src)", __func__); + + if (!bn_check_expected_flags(dst, BN_FLG_MALLOCED | BN_FLG_CONSTTIME, + __func__, "dst after bn_copy")) + failed |= 1; + + BN_free(dst); + BN_free(src); + + return failed; +} + int main(void) { @@ -99,6 +256,9 @@ main(void) failed |= test_bn_print_null_derefs(); failed |= test_bn_num_bits_word(); + failed |= test_bn_copy_copies_flags(); + failed |= test_bn_copy_consttime_is_sticky(); + failed |= test_bn_dup_consttime_is_sticky(); return failed; } -- 2.20.1