summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/gpg.texi9
-rw-r--r--g10/getkey.c17
-rw-r--r--g10/gpg.c6
-rw-r--r--g10/mainproc.c4
-rw-r--r--g10/options.h1
5 files changed, 36 insertions, 1 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 10a1937f6..446189b4b 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -3146,6 +3146,15 @@ This option adjusts the compliance mode "de-vs" for stricter key size
requirements. For example, a value of 3000 turns rsa2048 and dsa2048
keys into non-VS-NfD compliant keys.
+@item --require-pqc-encryption
+@opindex require-pqc-encryption
+This option forces the use of quantum-resistant encryption algorithms.
+If not all public keys are quantum-resistant the encryption will fail.
+On decryption a warning is printed for all non-quantum-resistant keys.
+As of now the Kyber (ML-KEM768 and ML-KEM1024) algorithms are
+considered quantum-resistant; Kyber is always used in a composite
+scheme along with a classic ECC algorithm.
+
@item --require-compliance
@opindex require-compliance
To check that data has been encrypted according to the rules of the
diff --git a/g10/getkey.c b/g10/getkey.c
index ce59628a0..f2d1e7d7b 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -3779,6 +3779,16 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
continue;
}
+ if (opt.flags.require_pqc_encryption
+ && (req_usage & PUBKEY_USAGE_ENC)
+ && pk->pubkey_algo != PUBKEY_ALGO_KYBER)
+ {
+ if (DBG_LOOKUP)
+ log_debug ("\tsubkey is not quantum-resistant\n");
+ continue;
+ }
+
+
if (want_secret)
{
int secret_key_avail = agent_probe_secret_key (NULL, pk);
@@ -3857,6 +3867,13 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
if (DBG_LOOKUP)
log_debug ("\tprimary key has expired\n");
}
+ else if (opt.flags.require_pqc_encryption
+ && (req_usage & PUBKEY_USAGE_ENC)
+ && pk->pubkey_algo != PUBKEY_ALGO_KYBER)
+ {
+ if (DBG_LOOKUP)
+ log_debug ("\tprimary key is not quantum-resistant\n");
+ }
else /* Okay. */
{
if (DBG_LOOKUP)
diff --git a/g10/gpg.c b/g10/gpg.c
index 658fb7cf1..82745fa18 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -456,6 +456,7 @@ enum cmd_and_opt_values
oAssertSigner,
oAssertPubkeyAlgo,
oKbxBufferSize,
+ oRequirePQCEncryption,
oNoop
};
@@ -896,7 +897,7 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
-
+ ARGPARSE_s_n (oRequirePQCEncryption, "require-pqc-encryption", "@"),
ARGPARSE_header (NULL, N_("Options for unattended use")),
@@ -3071,6 +3072,9 @@ main (int argc, char **argv)
break;
case oMinRSALength: opt.min_rsa_length = pargs.r.ret_ulong; break;
+ case oRequirePQCEncryption:
+ opt.flags.require_pqc_encryption = 1;
+ break;
case oRFC2440Text: opt.rfc2440_text=1; break;
case oNoRFC2440Text: opt.rfc2440_text=0; break;
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 48bc463c5..91ababbb6 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -578,6 +578,10 @@ print_pkenc_list (ctrl_t ctrl, struct pubkey_enc_list *list)
openpgp_pk_algo_name (list->pubkey_algo),
keystr(list->keyid));
+ if (opt.flags.require_pqc_encryption
+ && pk->pubkey_algo != PUBKEY_ALGO_KYBER)
+ log_info (_("WARNING: key is not quantum-resistant\n"));
+
free_public_key (pk);
}
}
diff --git a/g10/options.h b/g10/options.h
index 2fe4f5bbf..ae429fcc1 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -283,6 +283,7 @@ struct
/* Fail if an operation can't be done in the requested compliance
* mode. */
unsigned int require_compliance:1;
+ unsigned int require_pqc_encryption:1;
} flags;
/* Linked list of ways to find a key if the key isn't on the local