From 9ad69b994ae7c73ba06d9f75efd2625102de814c Mon Sep 17 00:00:00 2001 From: Ken Zalewski Date: Mon, 21 Oct 2024 16:24:47 -0400 Subject: [PATCH] Patch to openssl-1.1.1zb. This version addresses one vulnerability: CVE-2024-9143 --- openssl-1.1.1w/crypto/bn/bn_gf2m.c.old 2024-10-23 11:54:58.908107893 -0400 +++ openssl-1.1.1w/crypto/bn/bn_gf2m.c 2024-10-23 11:56:23.395006355 -0400 @@ -15,6 +15,7 @@ #include "bn_local.h" #ifndef OPENSSL_NO_EC2M +#include /* * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should @@ -1109,16 +1110,26 @@ /* * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i * * x^i) into an array of integers corresponding to the bits with non-zero - * coefficient. Array is terminated with -1. Up to max elements of the array - * will be filled. Return value is total number of array elements that would - * be filled if array was large enough. + * coefficient. The array is intended to be suitable for use with + * `BN_GF2m_mod_arr()`, and so the constant term of the polynomial must not be + * zero. This translates to a requirement that the input BIGNUM `a` is odd. + * + * Given sufficient room, the array is terminated with -1. Up to max elements + * of the array will be filled. + * + * The return value is total number of array elements that would be filled if + * array was large enough, including the terminating `-1`. It is `0` when `a` + * is not odd or the constant term is zero contrary to requirement. + * + * The return value is also `0` when the leading exponent exceeds + * `OPENSSL_ECC_MAX_FIELD_BITS`, this guards against CPU exhaustion attacks, */ int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) { int i, j, k = 0; BN_ULONG mask; - if (BN_is_zero(a)) + if (!BN_is_odd(a)) return 0; for (i = a->top - 1; i >= 0; i--) { @@ -1136,12 +1147,13 @@ } } - if (k < max) { + if (k > 0 && p[0] > OPENSSL_ECC_MAX_FIELD_BITS) + return 0; + + if (k < max) p[k] = -1; - k++; - } - return k; + return k + 1; } /* --- openssl-1.1.1w/test/ec_internal_test.c.old 2024-10-23 11:58:29.956123911 -0400 +++ openssl-1.1.1w/test/ec_internal_test.c 2024-10-23 11:59:07.717605282 -0400 @@ -150,6 +150,56 @@ } #ifndef OPENSSL_NO_EC2M +/* Test that decoding of invalid GF2m field parameters fails. */ +static int ec2m_field_sanity(void) +{ + int ret = 0; + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *p, *a, *b; + EC_GROUP *group1 = NULL, *group2 = NULL, *group3 = NULL; + + TEST_info("Testing GF2m hardening\n"); + + BN_CTX_start(ctx); + p = BN_CTX_get(ctx); + a = BN_CTX_get(ctx); + if (!TEST_ptr(b = BN_CTX_get(ctx)) + || !TEST_true(BN_one(a)) + || !TEST_true(BN_one(b))) + goto out; + + /* Even pentanomial value should be rejected */ + if (!TEST_true(BN_set_word(p, 0xf2))) + goto out; + if (!TEST_ptr_null(group1 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) + TEST_error("Zero constant term accepted in GF2m polynomial"); + + /* Odd hexanomial should also be rejected */ + if (!TEST_true(BN_set_word(p, 0xf3))) + goto out; + if (!TEST_ptr_null(group2 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) + TEST_error("Hexanomial accepted as GF2m polynomial"); + + /* Excessive polynomial degree should also be rejected */ + if (!TEST_true(BN_set_word(p, 0x71)) + || !TEST_true(BN_set_bit(p, OPENSSL_ECC_MAX_FIELD_BITS + 1))) + goto out; + if (!TEST_ptr_null(group3 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) + TEST_error("GF2m polynomial degree > %d accepted", + OPENSSL_ECC_MAX_FIELD_BITS); + + ret = group1 == NULL && group2 == NULL && group3 == NULL; + + out: + EC_GROUP_free(group1); + EC_GROUP_free(group2); + EC_GROUP_free(group3); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ret; +} + /* test EC_GF2m_simple_method directly */ static int field_tests_ec2_simple(void) { @@ -367,6 +417,7 @@ ADD_TEST(field_tests_ecp_simple); ADD_TEST(field_tests_ecp_mont); #ifndef OPENSSL_NO_EC2M + ADD_TEST(ec2m_field_sanity); ADD_TEST(field_tests_ec2_simple); #endif ADD_ALL_TESTS(field_tests_default, crv_len);