From ab4668d2ff9c33c66db8a665cd34c2dcaa57e996 Mon Sep 17 00:00:00 2001 From: Stavros Kousidis Date: Sun, 20 Sep 2026 12:43:19 +0200 Subject: [PATCH] Add RFC 9980 post-quantum public-key algorithms * src/gpgme.h.in (gpgme_pubkey_algo_t): Add OpenPGP algorithm identifiers 30 through 36 from RFC 9980. * src/conversion.c (_gpgme_map_pk_algo): Map the new OpenPGP identifiers to GPGME algorithm values. * src/gpgme.c (gpgme_pubkey_algo_name): Return names for the new algorithms. * tests/t-version.c (check_pubkey_algorithms): Check numeric values and names of the new algorithms. (main): Run the new checks. Signed-off-by: Stavros Kousidis --- src/conversion.c | 7 +++++++ src/gpgme.c | 19 ++++++++++++++++++- src/gpgme.h.in | 10 ++++++++++ tests/t-version.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/conversion.c b/src/conversion.c index 11e03e9c..7d6ea068 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -690,6 +690,13 @@ _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol) { case 1: case 2: case 3: case 8: case 16: case 17: break; case 18: algo = GPGME_PK_ECDH; break; + case 30: algo = GPGME_PK_MLDSA65_ED25519; break; + case 31: algo = GPGME_PK_MLDSA87_ED448; break; + case 32: algo = GPGME_PK_SLHDSA_SHAKE_128S; break; + case 33: algo = GPGME_PK_SLHDSA_SHAKE_128F; break; + case 34: algo = GPGME_PK_SLHDSA_SHAKE_256S; break; + case 35: algo = GPGME_PK_MLKEM768_X25519; break; + case 36: algo = GPGME_PK_MLKEM1024_X448; break; case 19: algo = GPGME_PK_ECDSA; break; case 20: break; case 22: algo = GPGME_PK_EDDSA; break; diff --git a/src/gpgme.c b/src/gpgme.c index 7025b20b..b968ed5b 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -1366,7 +1366,24 @@ gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo) case GPGME_PK_ECDSA: return "ECDSA"; case GPGME_PK_ECDH: return "ECDH"; case GPGME_PK_EDDSA: return "EdDSA"; - default: return NULL; + + case GPGME_PK_MLDSA65_ED25519: + return "ML-DSA-65+Ed25519"; + case GPGME_PK_MLDSA87_ED448: + return "ML-DSA-87+Ed448"; + case GPGME_PK_SLHDSA_SHAKE_128S: + return "SLH-DSA-SHAKE-128s"; + case GPGME_PK_SLHDSA_SHAKE_128F: + return "SLH-DSA-SHAKE-128f"; + case GPGME_PK_SLHDSA_SHAKE_256S: + return "SLH-DSA-SHAKE-256s"; + case GPGME_PK_MLKEM768_X25519: + return "ML-KEM-768+X25519"; + case GPGME_PK_MLKEM1024_X448: + return "ML-KEM-1024+X448"; + + default: + return NULL; } } diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 54dba0be..8d8b8337 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -275,6 +275,16 @@ typedef enum GPGME_PK_DSA = 17, GPGME_PK_ECC = 18, GPGME_PK_ELG = 20, + + /* OpenPGP RFC 9980 post-quantum algorithms. */ + GPGME_PK_MLDSA65_ED25519 = 30, + GPGME_PK_MLDSA87_ED448 = 31, + GPGME_PK_SLHDSA_SHAKE_128S = 32, + GPGME_PK_SLHDSA_SHAKE_128F = 33, + GPGME_PK_SLHDSA_SHAKE_256S = 34, + GPGME_PK_MLKEM768_X25519 = 35, + GPGME_PK_MLKEM1024_X448 = 36, + GPGME_PK_ECDSA = 301, GPGME_PK_ECDH = 302, GPGME_PK_EDDSA = 303 diff --git a/tests/t-version.c b/tests/t-version.c index 1958343e..dbce6eb5 100644 --- a/tests/t-version.c +++ b/tests/t-version.c @@ -32,6 +32,52 @@ static int verbose; static int debug; +static int +check_pubkey_algorithms (void) +{ + struct pubkey_algo_test + { + gpgme_pubkey_algo_t algo; + int value; + const char *name; + }; + + static const struct pubkey_algo_test tests[] = + { + { GPGME_PK_MLDSA65_ED25519, 30, "ML-DSA-65+Ed25519" }, + { GPGME_PK_MLDSA87_ED448, 31, "ML-DSA-87+Ed448" }, + { GPGME_PK_SLHDSA_SHAKE_128S, 32, "SLH-DSA-SHAKE-128s" }, + { GPGME_PK_SLHDSA_SHAKE_128F, 33, "SLH-DSA-SHAKE-128f" }, + { GPGME_PK_SLHDSA_SHAKE_256S, 34, "SLH-DSA-SHAKE-256s" }, + { GPGME_PK_MLKEM768_X25519, 35, "ML-KEM-768+X25519" }, + { GPGME_PK_MLKEM1024_X448, 36, "ML-KEM-1024+X448" } + }; + + size_t i; + const char *name; + + for (i = 0; i < sizeof tests / sizeof tests[0]; i++) + { + if ((int) tests[i].algo != tests[i].value) + { + fprintf (stderr, "Unexpected public-key algorithm value: %d\n", + (int) tests[i].algo); + return 1; + } + + name = gpgme_pubkey_algo_name (tests[i].algo); + if (!name || strcmp (name, tests[i].name)) + { + fprintf (stderr, "Unexpected public-key algorithm name for %d\n", + tests[i].value); + return 1; + } + } + + return 0; +} + + int main (int argc, char **argv) { @@ -80,6 +126,8 @@ main (int argc, char **argv) && ! strcmp (current_result, VERSION) && ! future_result); + ret |= check_pubkey_algorithms (); + if (verbose || ret) { printf ("Version from header: %s (0x%06x)\n", -- 2.55.0