From 999d7180b2dfccd1848b289b215d2e5847bf93d0 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 14 Aug 2026 19:50:21 +0200 Subject: [PATCH] Validate algorithm attributes before key creation Signed-off-by: Pol Henarejos --- src/openpgp/cmd_import_data.c | 3 +++ src/openpgp/cmd_keypair_gen.c | 3 +++ src/openpgp/openpgp.c | 18 ++++++++++++++++++ src/openpgp/openpgp.h | 1 + 4 files changed, 25 insertions(+) diff --git a/src/openpgp/cmd_import_data.c b/src/openpgp/cmd_import_data.c index 08a0442..e21bd44 100644 --- a/src/openpgp/cmd_import_data.c +++ b/src/openpgp/cmd_import_data.c @@ -141,6 +141,9 @@ int cmd_import_data(void) { if (algo_len == 0 || algo_len > OPENPGP_MAX_ALGORITHM_ATTR_SIZE) { return SW_WRONG_DATA(); } + if (!openpgp_algorithm_attr_supported(algo, algo_len)) { + return SW_WRONG_DATA(); + } int r = 0; if (algo[0] == ALGO_RSA) { if (algo_len < 3) { diff --git a/src/openpgp/cmd_keypair_gen.c b/src/openpgp/cmd_keypair_gen.c index d0457be..5518ab1 100644 --- a/src/openpgp/cmd_keypair_gen.c +++ b/src/openpgp/cmd_keypair_gen.c @@ -60,6 +60,9 @@ int cmd_keypair_gen(void) { if (algo_len == 0 || algo_len > OPENPGP_MAX_ALGORITHM_ATTR_SIZE) { return SW_WRONG_DATA(); } + if (!openpgp_algorithm_attr_supported(algo, algo_len)) { + return SW_WRONG_DATA(); + } if (P1(apdu) == 0x80) { //generate if (algo[0] == ALGO_RSA) { if (algo_len < 3) { diff --git a/src/openpgp/openpgp.c b/src/openpgp/openpgp.c index 03ef9ff..c0de7cf 100644 --- a/src/openpgp/openpgp.c +++ b/src/openpgp/openpgp.c @@ -1441,6 +1441,24 @@ mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_ return MBEDTLS_ECP_DP_NONE; } +bool openpgp_algorithm_attr_supported(const uint8_t *algo, size_t algo_len) { + if (!algo || algo_len < 2 || algo_len > OPENPGP_MAX_ALGORITHM_ATTR_SIZE) { + return false; + } + if (algo[0] == ALGO_RSA) { + uint16_t modulus_bits; + if (algo_len != 6 || algo[3] != 0 || algo[4] != 0x20 || algo[5] != 0) { + return false; + } + modulus_bits = ((uint16_t)algo[1] << 8) | algo[2]; + return modulus_bits == 1024 || modulus_bits == 2048 || modulus_bits == 3072 || modulus_bits == 4096; + } + if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA || algo[0] == ALGO_EDDSA) { + return get_ec_group_id_from_attr(algo + 1, algo_len - 1) != MBEDTLS_ECP_DP_NONE; + } + return false; +} + void make_rsa_response(mbedtls_rsa_context *rsa) { memcpy(res_APDU, "\x7f\x49\x82\x00\x00", 5); res_APDU_size = 5; diff --git a/src/openpgp/openpgp.h b/src/openpgp/openpgp.h index 83471da..02f19a4 100644 --- a/src/openpgp/openpgp.h +++ b/src/openpgp/openpgp.h @@ -76,6 +76,7 @@ extern int openpgp_adminless_disable(void); extern int openpgp_adminless_reset(void); #endif extern mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_len); +extern bool openpgp_algorithm_attr_supported(const uint8_t *algo, size_t algo_len); extern int reset_sig_count(void); extern uint16_t algo_dec, algo_aut, pk_dec, pk_aut; extern bool wait_button_pressed_fid(uint16_t fid);