diff --git a/test/test_dh.c b/test/test_dh.c index 8cb5889c..11ee1896 100644 --- a/test/test_dh.c +++ b/test/test_dh.c @@ -1282,4 +1282,53 @@ int test_dh_x963_kdf(void *data) } #endif /* HAVE_X963_KDF && WP_HAVE_SHA256 */ +/* Pass an oversize OSSL_PARAM (>1024 bytes) for the FFC P component to + * EVP_PKEY_fromdata so wp_mp_read_unsigned_bin_le (wp_params.c) hits its + * size-guard branch via wp_dh_import_group. Expect failure rather than the + * stack buffer overflow that would happen without the guard. */ +int test_dh_fromdata_oversize(void *data) +{ + int err = 0; + EVP_PKEY_CTX *ctx_wolf = NULL; + EVP_PKEY *pkey_wolf = NULL; + unsigned char p_oversize[2048]; + unsigned char g_buf[1] = { 0x02 }; + OSSL_PARAM params[3]; + int status; + + (void)data; + memset(p_oversize, 0xAA, sizeof(p_oversize)); + + PRINT_MSG("Testing EVP_PKEY_fromdata with oversize DH FFC_P component"); + + ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "DH", NULL); + if (ctx_wolf == NULL) { + err = 1; + } + + if (err == 0) { + err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1; + } + + if (err == 0) { + params[0] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P, + p_oversize, sizeof(p_oversize)); + params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G, + g_buf, sizeof(g_buf)); + params[2] = OSSL_PARAM_construct_end(); + + status = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf, + EVP_PKEY_KEY_PARAMETERS, params); + if (status == 1) { + PRINT_MSG("EVP_PKEY_fromdata unexpectedly succeeded with 2048-byte" + " FFC_P"); + err = 1; + } + EVP_PKEY_free(pkey_wolf); + } + + EVP_PKEY_CTX_free(ctx_wolf); + return err; +} + #endif /* WP_HAVE_DH */ diff --git a/test/test_ecc.c b/test/test_ecc.c index 800c6a17..2783963b 100644 --- a/test/test_ecc.c +++ b/test/test_ecc.c @@ -2791,6 +2791,58 @@ int test_ec_print_public(void* data) return err; } + +/* Pass an oversize OSSL_PARAM (>1024 bytes) for the EC private key component + * to EVP_PKEY_fromdata so wp_mp_read_unsigned_bin_le (wp_params.c) hits its + * size-guard branch via wp_params_get_mp in wp_ecc_import_keypair. Expect + * failure rather than the stack buffer overflow that would happen without + * the guard. This path also covers ECDH, whose key import shares + * wp_ecc_kmgmt. */ +int test_ec_fromdata_oversize(void *data) +{ + int err = 0; + EVP_PKEY_CTX *ctx_wolf = NULL; + EVP_PKEY *pkey_wolf = NULL; + unsigned char priv_oversize[2048]; + char group_name[] = "prime256v1"; + OSSL_PARAM params[3]; + int status; + + (void)data; + memset(priv_oversize, 0xAA, sizeof(priv_oversize)); + + PRINT_MSG("Testing EVP_PKEY_fromdata with oversize EC PRIV_KEY component"); + + ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "EC", NULL); + if (ctx_wolf == NULL) { + err = 1; + } + + if (err == 0) { + err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1; + } + + if (err == 0) { + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + group_name, 0); + params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PRIV_KEY, + priv_oversize, + sizeof(priv_oversize)); + params[2] = OSSL_PARAM_construct_end(); + + status = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf, EVP_PKEY_KEYPAIR, + params); + if (status == 1) { + PRINT_MSG("EVP_PKEY_fromdata unexpectedly succeeded with 2048-byte" + " EC PRIV_KEY"); + err = 1; + } + EVP_PKEY_free(pkey_wolf); + } + + EVP_PKEY_CTX_free(ctx_wolf); + return err; +} #endif /* WP_HAVE_EC_P256 */ #endif /* WP_HAVE_ECC */ diff --git a/test/test_rsa.c b/test/test_rsa.c index 59fd8421..ae7eb59a 100644 --- a/test/test_rsa.c +++ b/test/test_rsa.c @@ -1619,6 +1619,55 @@ int test_rsa_fromdata(void* data) return err; } +/* Pass an oversize OSSL_PARAM (>1024 bytes) for the N component to + * EVP_PKEY_fromdata so wp_mp_read_unsigned_bin_le (wp_params.c) hits its + * size-guard branch. Expect failure rather than the stack buffer overflow + * that would happen without the guard. */ +int test_rsa_fromdata_oversize(void* data) +{ + int err = 0; + EVP_PKEY_CTX *ctx_wolf = NULL; + EVP_PKEY *pkey_wolf = NULL; + unsigned char n_oversize[2048]; + unsigned char e_buf[3] = { 0x01, 0x00, 0x01 }; + OSSL_PARAM params[3]; + int status; + + (void)data; + memset(n_oversize, 0xAA, sizeof(n_oversize)); + + PRINT_MSG("Testing EVP_PKEY_fromdata with oversize RSA n component"); + + ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "RSA", NULL); + if (ctx_wolf == NULL) { + err = 1; + } + + if (err == 0) { + err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1; + } + + if (err == 0) { + params[0] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, + n_oversize, sizeof(n_oversize)); + params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, + e_buf, sizeof(e_buf)); + params[2] = OSSL_PARAM_construct_end(); + + status = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf, EVP_PKEY_PUBLIC_KEY, + params); + if (status == 1) { + PRINT_MSG("EVP_PKEY_fromdata unexpectedly succeeded with 2048-byte" + " n"); + err = 1; + } + EVP_PKEY_free(pkey_wolf); + } + + EVP_PKEY_CTX_free(ctx_wolf); + return err; +} + static int test_rsa_decode_pkcs8_old(void) { int err = 0; diff --git a/test/unit.c b/test/unit.c index 750e3707..3b684d0d 100644 --- a/test/unit.c +++ b/test/unit.c @@ -314,6 +314,7 @@ TEST_CASE test_case[] = { #if defined(HAVE_X963_KDF) && defined(WP_HAVE_SHA256) TEST_DECL(test_dh_x963_kdf, NULL), #endif + TEST_DECL(test_dh_fromdata_oversize, NULL), #ifndef WOLFPROV_QUICKTEST TEST_DECL(test_dh_get_params, NULL), #endif @@ -337,6 +338,7 @@ TEST_CASE test_case[] = { TEST_DECL(test_rsa_load_key, NULL), TEST_DECL(test_rsa_load_cert, NULL), TEST_DECL(test_rsa_fromdata, NULL), + TEST_DECL(test_rsa_fromdata_oversize, NULL), TEST_DECL(test_rsa_decode_pkcs8, NULL), TEST_DECL(test_rsa_encode_pkcs8, NULL), TEST_DECL(test_rsa_null_init, NULL), @@ -400,6 +402,7 @@ TEST_CASE test_case[] = { TEST_DECL(test_ec_auto_derive_pubkey, NULL), TEST_DECL(test_ec_null_init, NULL), TEST_DECL(test_ec_print_public, NULL), + TEST_DECL(test_ec_fromdata_oversize, NULL), #endif #ifdef WP_HAVE_EC_P384 #ifdef WP_HAVE_ECKEYGEN diff --git a/test/unit.h b/test/unit.h index b45fcddc..0fd44d04 100644 --- a/test/unit.h +++ b/test/unit.h @@ -300,6 +300,7 @@ int test_rsa_pss_restrictions(void *data); int test_rsa_load_key(void* data); int test_rsa_load_cert(void* data); int test_rsa_fromdata(void* data); +int test_rsa_fromdata_oversize(void* data); int test_rsa_decode_pkcs8(void* data); int test_rsa_encode_pkcs8(void* data); int test_rsa_null_init(void* data); @@ -320,6 +321,7 @@ int test_dh_pad(void *data); #if defined(HAVE_X963_KDF) && defined(WP_HAVE_SHA256) int test_dh_x963_kdf(void *data); #endif +int test_dh_fromdata_oversize(void *data); #endif /* WP_HAVE_DH */ #ifdef WP_HAVE_ECC @@ -457,6 +459,7 @@ int test_ec_auto_derive_pubkey(void* data); int test_ec_null_init(void* data); #ifdef WP_HAVE_EC_P256 int test_ec_print_public(void* data); +int test_ec_fromdata_oversize(void* data); #endif #endif /* WP_HAVE_ECC */