Skip to content

Commit c8bedcf

Browse files
committed
Add bounds checks on OSSL_PARAMS for EC, DH and RSA
1 parent f3632b7 commit c8bedcf

5 files changed

Lines changed: 156 additions & 0 deletions

File tree

test/test_dh.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,4 +718,53 @@ int test_dh_krb5_keygen(void *data)
718718
return err;
719719
}
720720

721+
/* Pass an oversize OSSL_PARAM (>1024 bytes) for the FFC P component to
722+
* EVP_PKEY_fromdata so wp_mp_read_unsigned_bin_le (wp_params.c) hits its
723+
* size-guard branch via wp_dh_import_group. Expect failure rather than the
724+
* stack buffer overflow that would happen without the guard. */
725+
int test_dh_fromdata_oversize(void *data)
726+
{
727+
int err = 0;
728+
EVP_PKEY_CTX *ctx_wolf = NULL;
729+
EVP_PKEY *pkey_wolf = NULL;
730+
unsigned char p_oversize[2048];
731+
unsigned char g_buf[1] = { 0x02 };
732+
OSSL_PARAM params[3];
733+
int status;
734+
735+
(void)data;
736+
memset(p_oversize, 0xAA, sizeof(p_oversize));
737+
738+
PRINT_MSG("Testing EVP_PKEY_fromdata with oversize DH FFC_P component");
739+
740+
ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "DH", NULL);
741+
if (ctx_wolf == NULL) {
742+
err = 1;
743+
}
744+
745+
if (err == 0) {
746+
err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1;
747+
}
748+
749+
if (err == 0) {
750+
params[0] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P,
751+
p_oversize, sizeof(p_oversize));
752+
params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G,
753+
g_buf, sizeof(g_buf));
754+
params[2] = OSSL_PARAM_construct_end();
755+
756+
status = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf,
757+
EVP_PKEY_KEY_PARAMETERS, params);
758+
if (status == 1) {
759+
PRINT_MSG("EVP_PKEY_fromdata unexpectedly succeeded with 2048-byte"
760+
" FFC_P");
761+
err = 1;
762+
}
763+
EVP_PKEY_free(pkey_wolf);
764+
}
765+
766+
EVP_PKEY_CTX_free(ctx_wolf);
767+
return err;
768+
}
769+
721770
#endif /* WP_HAVE_DH */

test/test_ecc.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,6 +2618,58 @@ int test_ec_print_public(void* data)
26182618

26192619
return err;
26202620
}
2621+
2622+
/* Pass an oversize OSSL_PARAM (>1024 bytes) for the EC private key component
2623+
* to EVP_PKEY_fromdata so wp_mp_read_unsigned_bin_le (wp_params.c) hits its
2624+
* size-guard branch via wp_params_get_mp in wp_ecc_import_keypair. Expect
2625+
* failure rather than the stack buffer overflow that would happen without
2626+
* the guard. This path also covers ECDH, whose key import shares
2627+
* wp_ecc_kmgmt. */
2628+
int test_ec_fromdata_oversize(void *data)
2629+
{
2630+
int err = 0;
2631+
EVP_PKEY_CTX *ctx_wolf = NULL;
2632+
EVP_PKEY *pkey_wolf = NULL;
2633+
unsigned char priv_oversize[2048];
2634+
char group_name[] = "prime256v1";
2635+
OSSL_PARAM params[3];
2636+
int status;
2637+
2638+
(void)data;
2639+
memset(priv_oversize, 0xAA, sizeof(priv_oversize));
2640+
2641+
PRINT_MSG("Testing EVP_PKEY_fromdata with oversize EC PRIV_KEY component");
2642+
2643+
ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "EC", NULL);
2644+
if (ctx_wolf == NULL) {
2645+
err = 1;
2646+
}
2647+
2648+
if (err == 0) {
2649+
err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1;
2650+
}
2651+
2652+
if (err == 0) {
2653+
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
2654+
group_name, 0);
2655+
params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PRIV_KEY,
2656+
priv_oversize,
2657+
sizeof(priv_oversize));
2658+
params[2] = OSSL_PARAM_construct_end();
2659+
2660+
status = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf, EVP_PKEY_KEYPAIR,
2661+
params);
2662+
if (status == 1) {
2663+
PRINT_MSG("EVP_PKEY_fromdata unexpectedly succeeded with 2048-byte"
2664+
" EC PRIV_KEY");
2665+
err = 1;
2666+
}
2667+
EVP_PKEY_free(pkey_wolf);
2668+
}
2669+
2670+
EVP_PKEY_CTX_free(ctx_wolf);
2671+
return err;
2672+
}
26212673
#endif /* WP_HAVE_EC_P256 */
26222674

26232675
#endif /* WP_HAVE_ECC */

test/test_rsa.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,55 @@ int test_rsa_fromdata(void* data)
16191619
return err;
16201620
}
16211621

1622+
/* Pass an oversize OSSL_PARAM (>1024 bytes) for the N component to
1623+
* EVP_PKEY_fromdata so wp_mp_read_unsigned_bin_le (wp_params.c) hits its
1624+
* size-guard branch. Expect failure rather than the stack buffer overflow
1625+
* that would happen without the guard. */
1626+
int test_rsa_fromdata_oversize(void* data)
1627+
{
1628+
int err = 0;
1629+
EVP_PKEY_CTX *ctx_wolf = NULL;
1630+
EVP_PKEY *pkey_wolf = NULL;
1631+
unsigned char n_oversize[2048];
1632+
unsigned char e_buf[3] = { 0x01, 0x00, 0x01 };
1633+
OSSL_PARAM params[3];
1634+
int status;
1635+
1636+
(void)data;
1637+
memset(n_oversize, 0xAA, sizeof(n_oversize));
1638+
1639+
PRINT_MSG("Testing EVP_PKEY_fromdata with oversize RSA n component");
1640+
1641+
ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "RSA", NULL);
1642+
if (ctx_wolf == NULL) {
1643+
err = 1;
1644+
}
1645+
1646+
if (err == 0) {
1647+
err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1;
1648+
}
1649+
1650+
if (err == 0) {
1651+
params[0] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N,
1652+
n_oversize, sizeof(n_oversize));
1653+
params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E,
1654+
e_buf, sizeof(e_buf));
1655+
params[2] = OSSL_PARAM_construct_end();
1656+
1657+
status = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf, EVP_PKEY_PUBLIC_KEY,
1658+
params);
1659+
if (status == 1) {
1660+
PRINT_MSG("EVP_PKEY_fromdata unexpectedly succeeded with 2048-byte"
1661+
" n");
1662+
err = 1;
1663+
}
1664+
EVP_PKEY_free(pkey_wolf);
1665+
}
1666+
1667+
EVP_PKEY_CTX_free(ctx_wolf);
1668+
return err;
1669+
}
1670+
16221671
static int test_rsa_decode_pkcs8_old(void)
16231672
{
16241673
int err = 0;

test/unit.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ TEST_CASE test_case[] = {
304304
TEST_DECL(test_dh_invalid_kdf_strings, NULL),
305305
TEST_DECL(test_dh_decode, NULL),
306306
TEST_DECL(test_dh_krb5_keygen, NULL),
307+
TEST_DECL(test_dh_fromdata_oversize, NULL),
307308
#ifndef WOLFPROV_QUICKTEST
308309
TEST_DECL(test_dh_get_params, NULL),
309310
#endif
@@ -327,6 +328,7 @@ TEST_CASE test_case[] = {
327328
TEST_DECL(test_rsa_load_key, NULL),
328329
TEST_DECL(test_rsa_load_cert, NULL),
329330
TEST_DECL(test_rsa_fromdata, NULL),
331+
TEST_DECL(test_rsa_fromdata_oversize, NULL),
330332
TEST_DECL(test_rsa_decode_pkcs8, NULL),
331333
TEST_DECL(test_rsa_encode_pkcs8, NULL),
332334
TEST_DECL(test_rsa_null_init, NULL),
@@ -385,6 +387,7 @@ TEST_CASE test_case[] = {
385387
TEST_DECL(test_ec_auto_derive_pubkey, NULL),
386388
TEST_DECL(test_ec_null_init, NULL),
387389
TEST_DECL(test_ec_print_public, NULL),
390+
TEST_DECL(test_ec_fromdata_oversize, NULL),
388391
#endif
389392
#ifdef WP_HAVE_EC_P384
390393
#ifdef WP_HAVE_ECKEYGEN

test/unit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ int test_rsa_pss_restrictions(void *data);
294294
int test_rsa_load_key(void* data);
295295
int test_rsa_load_cert(void* data);
296296
int test_rsa_fromdata(void* data);
297+
int test_rsa_fromdata_oversize(void* data);
297298
int test_rsa_decode_pkcs8(void* data);
298299
int test_rsa_encode_pkcs8(void* data);
299300
int test_rsa_null_init(void* data);
@@ -308,6 +309,7 @@ int test_dh_invalid_kdf_strings(void *data);
308309
int test_dh_decode(void *data);
309310
int test_dh_get_params(void *data);
310311
int test_dh_krb5_keygen(void *data);
312+
int test_dh_fromdata_oversize(void *data);
311313
#endif /* WP_HAVE_DH */
312314

313315
#ifdef WP_HAVE_ECC
@@ -442,6 +444,7 @@ int test_ec_auto_derive_pubkey(void* data);
442444
int test_ec_null_init(void* data);
443445
#ifdef WP_HAVE_EC_P256
444446
int test_ec_print_public(void* data);
447+
int test_ec_fromdata_oversize(void* data);
445448
#endif
446449

447450
#endif /* WP_HAVE_ECC */

0 commit comments

Comments
 (0)