mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
_ecc_import_x963_ex2() took the ordinate width from the input length and never compared it with the curve, so a SubjectPublicKeyInfo naming one curve but carrying wider ordinates became a key on that curve holding oversized ordinates. wc_ecc_set_curve() bounds the size only by ECC_MAXSIZE and, when given a curve id, selects the curve by id without comparing sizes. The untrusted-import validation did not catch it in SP builds: sp_ecc_is_point_256/384/521() copy only the low limbs out of the mp_int, so the truncated point is on the curve and the import succeeds, where the generic wc_ecc_is_point() returns ECC_OUT_OF_RANGE_E. Every caller of the importer is affected, including wc_EccPublicKeyDecode(), the TLS 1.2 and TLS 1.3 key exchange, PKCS#7 KARI, HPKE and the compat d2i_* functions; none of them compares the wire length with the curve size first. wolfSSL_EC_POINT_point2hex() then placed the x-ordinate at an offset derived from the curve size minus the ordinate size, which goes negative once an ordinate is wider than the curve. The compressed form and the y ordinate degenerate the same way. _ecc_import_x963_ex2() now requires the ordinate size to equal key->dp->size, returning ECC_BAD_ARG_E otherwise. This is the check wc_ecc_import_point_der_ex() already has, placed in the shared importer so it covers every caller and every math back end. wolfSSL_EC_POINT_point2hex() refuses ordinates larger than the curve before computing any offset, mirroring wc_ecc_export_point_der(), whose guard wolfSSL_EC_POINT_point2oct() already inherits, and picks up the NULL ordinate check that its new bound would otherwise be the first to dereference past. sp_ecc_is_point_256/384/521/1024() in all eight SP back ends gain the mp_count_bits() and modulus comparison that the neighbouring sp_ecc_check_key_*() already carries, so SP builds no longer accept a same-length non-canonical encoding that every other back end rejects. Both functions also gain the mp_isneg() test the generic implementation has: sp_<n>_from_mp() ignores the sign, so a negative ordinate was read as its magnitude. sp_ecc_check_key_*() lacked that check before this change as well. The sp_*.c files are generator output; the change was made in wolfSSL/scripts sp/ecc.rb and the files regenerated, and the result is byte for byte what the modified generator produces. Behaviour change: X9.63 encodings shorter than the curve size are rejected as well. They are non-canonical under SEC 1 section 2.3.4 and RFC 5480 and OpenSSL rejects them too. With ECC_CURVE_DEF the size-based curve lookup still resolves exact-size encodings as before. Tests: test_wc_ecc_import_x963_oversized and test_wc_ecc_import_x963_non_canonical cover the importer, test_wolfSSL_EC_POINT_point2hex_oversized covers the sink, and all three fail on the unfixed tree. The SP MC/DC drivers gain the new bit-length and sign branches and an operand exactly the field's width but not below the modulus, without which the new range compare was only ever reached with the bit-length guard already true. Those rows now assert ECC_OUT_OF_RANGE_E rather than discarding the result, and report a failure separately from a skipped row; removing either guard from a back end makes them fail.
77 lines
3.3 KiB
C
77 lines
3.3 KiB
C
/* test_ossl_ec.h
|
|
*
|
|
* Copyright (C) 2006-2026 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
#ifndef WOLFCRYPT_TEST_OSSL_EC_H
|
|
#define WOLFCRYPT_TEST_OSSL_EC_H
|
|
|
|
#include <tests/api/api_decl.h>
|
|
|
|
#if defined(HAVE_ECC) && !defined(OPENSSL_NO_PK)
|
|
|
|
int test_wolfSSL_EC_GROUP(void);
|
|
int test_wolfSSL_PEM_read_bio_ECPKParameters(void);
|
|
int test_wolfSSL_i2d_ECPKParameters(void);
|
|
int test_wolfSSL_EC_POINT(void);
|
|
int test_wolfSSL_SPAKE(void);
|
|
int test_wolfSSL_EC_KEY_generate(void);
|
|
int test_EC_i2d(void);
|
|
int test_wolfSSL_EC_curve(void);
|
|
int test_wolfSSL_EC_KEY_dup(void);
|
|
int test_wolfSSL_EC_KEY_set_group(void);
|
|
int test_wolfSSL_EC_KEY_set_conv_form(void);
|
|
int test_wolfSSL_EC_KEY_private_key(void);
|
|
int test_wolfSSL_EC_KEY_public_key(void);
|
|
int test_wolfSSL_EC_KEY_print_fp(void);
|
|
int test_wolfSSL_EC_get_builtin_curves(void);
|
|
int test_wolfSSL_ECDSA_SIG(void);
|
|
int test_ECDSA_size_sign(void);
|
|
int test_ECDH_compute_key(void);
|
|
int test_d2i_ECPrivateKey_no_pubkey(void);
|
|
int test_wolfSSL_EC_POINT_point2hex_oversized(void);
|
|
|
|
|
|
#define TEST_OSSL_EC_DECLS \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_GROUP), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_PEM_read_bio_ECPKParameters), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_i2d_ECPKParameters), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_POINT), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_SPAKE), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_KEY_generate), \
|
|
TEST_DECL_GROUP("ossl_ec", test_EC_i2d), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_curve), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_KEY_dup), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_KEY_set_group), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_KEY_set_conv_form), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_KEY_private_key), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_KEY_public_key), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_KEY_print_fp), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_get_builtin_curves), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_ECDSA_SIG), \
|
|
TEST_DECL_GROUP("ossl_ec", test_ECDSA_size_sign), \
|
|
TEST_DECL_GROUP("ossl_ec", test_ECDH_compute_key), \
|
|
TEST_DECL_GROUP("ossl_ec", test_d2i_ECPrivateKey_no_pubkey), \
|
|
TEST_DECL_GROUP("ossl_ec", test_wolfSSL_EC_POINT_point2hex_oversized)
|
|
|
|
#endif
|
|
|
|
#endif /* WOLFCRYPT_TEST_OSSL_EC_H */
|
|
|