* cipher/kem.c (_gcry_kem_genkey): Add input length validation.
(_gcry_kem_encap, _gcry_kem_decap): Likewise.
* src/gcrypt.h.in: Add forgotten constants for X448.
--
Reported-by: Ciwan Ă–ztopal
GnuPG-bug-id: 8259
Signed-off-by: NIIBE Yutaka <[email protected]>
---
cipher/kem.c | 124 ++++++++++++++++++++++++++++++++++++++++--------
src/gcrypt.h.in | 13 +++++
2 files changed, 118 insertions(+), 19 deletions(-)
diff --git a/cipher/kem.c b/cipher/kem.c
index 2a432a0a..e8fb826e 100644
--- a/cipher/kem.c
+++ b/cipher/kem.c
@@ -95,11 +95,18 @@ _gcry_kem_genkey (int algo,
if (seckey_len != GCRY_KEM_SNTRUP761_SECKEY_LEN
|| pubkey_len != GCRY_KEM_SNTRUP761_PUBKEY_LEN)
return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
sntrup761_keypair (pubkey, seckey, NULL, sntrup761_random);
_gcry_burn_stack (SNTRUP761_KEYPAIR_STACK_BURN);
return 0;
case GCRY_KEM_CM6688128F:
+ if (seckey_len != GCRY_KEM_CM6688128F_SECKEY_LEN
+ || pubkey_len != GCRY_KEM_CM6688128F_PUBKEY_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
mceliece6688128f_keypair (pubkey, seckey);
_gcry_burn_stack (MCELIECE6688128F_KEYPAIR_STACK_BURN);
return 0;
@@ -164,29 +171,57 @@ _gcry_kem_encap (int algo,
switch (algo)
{
case GCRY_KEM_SNTRUP761:
- if (optional != NULL || optional_len != 0)
- return GPG_ERR_INV_VALUE;
if (pubkey_len != GCRY_KEM_SNTRUP761_PUBKEY_LEN
|| ciphertext_len != GCRY_KEM_SNTRUP761_ENCAPS_LEN
|| shared_len != GCRY_KEM_SNTRUP761_SHARED_LEN)
- return GPG_ERR_INV_VALUE;
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
sntrup761_enc (ciphertext, shared, pubkey, NULL, sntrup761_random);
_gcry_burn_stack (SNTRUP761_ENC_STACK_BURN);
return 0;
case GCRY_KEM_CM6688128F:
- if (optional != NULL)
- return GPG_ERR_INV_VALUE;
+ if (pubkey_len != GCRY_KEM_CM6688128F_PUBKEY_LEN
+ || ciphertext_len != GCRY_KEM_CM6688128F_ENCAPS_LEN
+ || shared_len != GCRY_KEM_CM6688128F_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
mceliece6688128f_enc (ciphertext, shared, pubkey);
_gcry_burn_stack (MCELIECE6688128F_ENC_STACK_BURN);
return 0;
#if USE_KYBER
case GCRY_KEM_MLKEM512:
+ if (pubkey_len != GCRY_KEM_MLKEM512_PUBKEY_LEN
+ || ciphertext_len != GCRY_KEM_MLKEM512_ENCAPS_LEN
+ || shared_len != GCRY_KEM_MLKEM512_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional && optional_len != GCRY_KEM_MLKEM_RANDOM_LEN)
+ return GPG_ERR_INV_ARG;
+ kyber_encap (algo, ciphertext, shared, pubkey, optional);
+ _gcry_burn_stack (KYBER_ENCAP_STACK_BURN (algo));
+ return 0;
+
case GCRY_KEM_MLKEM768:
+ if (pubkey_len != GCRY_KEM_MLKEM768_PUBKEY_LEN
+ || ciphertext_len != GCRY_KEM_MLKEM768_ENCAPS_LEN
+ || shared_len != GCRY_KEM_MLKEM768_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional && optional_len != GCRY_KEM_MLKEM_RANDOM_LEN)
+ return GPG_ERR_INV_ARG;
+ kyber_encap (algo, ciphertext, shared, pubkey, optional);
+ _gcry_burn_stack (KYBER_ENCAP_STACK_BURN (algo));
+ return 0;
+
case GCRY_KEM_MLKEM1024:
+ if (pubkey_len != GCRY_KEM_MLKEM1024_PUBKEY_LEN
+ || ciphertext_len != GCRY_KEM_MLKEM1024_ENCAPS_LEN
+ || shared_len != GCRY_KEM_MLKEM1024_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
if (optional && optional_len != GCRY_KEM_MLKEM_RANDOM_LEN)
- return GPG_ERR_INV_VALUE;
+ return GPG_ERR_INV_ARG;
kyber_encap (algo, ciphertext, shared, pubkey, optional);
_gcry_burn_stack (KYBER_ENCAP_STACK_BURN (algo));
return 0;
@@ -200,16 +235,28 @@ _gcry_kem_encap (int algo,
case GCRY_KEM_RAW_P256R1:
case GCRY_KEM_RAW_P384R1:
case GCRY_KEM_RAW_P521R1:
- if (optional != NULL)
- return GPG_ERR_INV_VALUE;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
return _gcry_ecc_raw_encap (algo, pubkey, pubkey_len,
ciphertext, ciphertext_len,
shared, shared_len);
case GCRY_KEM_DHKEM25519:
+ if (pubkey_len != GCRY_KEM_DHKEM25519_PUBKEY_LEN
+ || ciphertext_len != GCRY_KEM_DHKEM25519_ENCAPS_LEN
+ || shared_len != GCRY_KEM_DHKEM25519_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
+ return _gcry_ecc_dhkem_encap (algo, pubkey, ciphertext, shared);
+
case GCRY_KEM_DHKEM448:
- if (optional != NULL)
- return GPG_ERR_INV_VALUE;
+ if (pubkey_len != GCRY_KEM_DHKEM448_PUBKEY_LEN
+ || ciphertext_len != GCRY_KEM_DHKEM448_ENCAPS_LEN
+ || shared_len != GCRY_KEM_DHKEM448_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
return _gcry_ecc_dhkem_encap (algo, pubkey, ciphertext, shared);
default:
@@ -229,29 +276,57 @@ _gcry_kem_decap (int algo,
switch (algo)
{
case GCRY_KEM_SNTRUP761:
- if (optional != NULL || optional_len != 0)
- return GPG_ERR_INV_VALUE;
if (seckey_len != GCRY_KEM_SNTRUP761_SECKEY_LEN
|| ciphertext_len != GCRY_KEM_SNTRUP761_ENCAPS_LEN
|| shared_len != GCRY_KEM_SNTRUP761_SHARED_LEN)
- return GPG_ERR_INV_VALUE;
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
sntrup761_dec (shared, ciphertext, seckey);
_gcry_burn_stack (SNTRUP761_DEC_STACK_BURN);
return 0;
case GCRY_KEM_CM6688128F:
- if (optional != NULL)
- return GPG_ERR_INV_VALUE;
+ if (seckey_len != GCRY_KEM_CM6688128F_SECKEY_LEN
+ || ciphertext_len != GCRY_KEM_CM6688128F_ENCAPS_LEN
+ || shared_len != GCRY_KEM_CM6688128F_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
mceliece6688128f_dec (shared, ciphertext, seckey);
_gcry_burn_stack (MCELIECE6688128F_DEC_STACK_BURN);
return 0;
#if USE_KYBER
case GCRY_KEM_MLKEM512:
+ if (seckey_len != GCRY_KEM_MLKEM512_SECKEY_LEN
+ || ciphertext_len != GCRY_KEM_MLKEM512_ENCAPS_LEN
+ || shared_len != GCRY_KEM_MLKEM512_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
+ kyber_decap (algo, shared, ciphertext, seckey);
+ _gcry_burn_stack (KYBER_DECAP_STACK_BURN (algo));
+ return 0;
+
case GCRY_KEM_MLKEM768:
+ if (seckey_len != GCRY_KEM_MLKEM768_SECKEY_LEN
+ || ciphertext_len != GCRY_KEM_MLKEM768_ENCAPS_LEN
+ || shared_len != GCRY_KEM_MLKEM768_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
+ kyber_decap (algo, shared, ciphertext, seckey);
+ _gcry_burn_stack (KYBER_DECAP_STACK_BURN (algo));
+ return 0;
+
case GCRY_KEM_MLKEM1024:
- if (optional != NULL)
- return GPG_ERR_INV_VALUE;
+ if (seckey_len != GCRY_KEM_MLKEM1024_SECKEY_LEN
+ || ciphertext_len != GCRY_KEM_MLKEM1024_ENCAPS_LEN
+ || shared_len != GCRY_KEM_MLKEM1024_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
kyber_decap (algo, shared, ciphertext, seckey);
_gcry_burn_stack (KYBER_DECAP_STACK_BURN (algo));
return 0;
@@ -265,14 +340,25 @@ _gcry_kem_decap (int algo,
case GCRY_KEM_RAW_P256R1:
case GCRY_KEM_RAW_P384R1:
case GCRY_KEM_RAW_P521R1:
- if (optional != NULL)
- return GPG_ERR_INV_VALUE;
+ if (optional != NULL || optional_len != 0)
+ return GPG_ERR_INV_ARG;
return _gcry_ecc_raw_decap (algo, seckey, seckey_len,
ciphertext, ciphertext_len,
shared, shared_len);
case GCRY_KEM_DHKEM25519:
+ if (seckey_len != GCRY_KEM_DHKEM25519_SECKEY_LEN
+ || ciphertext_len != GCRY_KEM_DHKEM25519_ENCAPS_LEN
+ || shared_len != GCRY_KEM_DHKEM25519_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
+ return _gcry_ecc_dhkem_decap (algo, seckey, ciphertext, shared,
+ optional);
+
case GCRY_KEM_DHKEM448:
+ if (seckey_len != GCRY_KEM_DHKEM448_SECKEY_LEN
+ || ciphertext_len != GCRY_KEM_DHKEM448_ENCAPS_LEN
+ || shared_len != GCRY_KEM_DHKEM448_SHARED_LEN)
+ return GPG_ERR_INV_ARG;
return _gcry_ecc_dhkem_decap (algo, seckey, ciphertext, shared,
optional);
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 73e54bf3..562327cb 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -1822,6 +1822,19 @@ enum gcry_kem_algos
#define GCRY_KEM_DHKEM25519_CIPHER_LEN GCRY_KEM_DHKEM25519_ENCAPS_LEN
#define GCRY_KEM_DHKEM25519_SHARED_LEN 32
+#define GCRY_KEM_ECC_X448_SECKEY_LEN 56
+#define GCRY_KEM_ECC_X448_PUBKEY_LEN 56
+#define GCRY_KEM_ECC_X448_ENCAPS_LEN 56
+#define GCRY_KEM_ECC_X448_CIPHER_LEN GCRY_KEM_ECC_X448_ENCAPS_LEN
+/* And shared secret is specific to the protocol. */
+#define GCRY_KEM_RAW_X448_SHARED_LEN 56
+
+#define GCRY_KEM_DHKEM448_SECKEY_LEN GCRY_KEM_ECC_X448_SECKEY_LEN
+#define GCRY_KEM_DHKEM448_PUBKEY_LEN GCRY_KEM_ECC_X448_PUBKEY_LEN
+#define GCRY_KEM_DHKEM448_ENCAPS_LEN GCRY_KEM_ECC_X448_ENCAPS_LEN
+#define GCRY_KEM_DHKEM448_CIPHER_LEN GCRY_KEM_DHKEM448_ENCAPS_LEN
+#define GCRY_KEM_DHKEM448_SHARED_LEN 56
+
#define GCRY_KEM_ECC_BP256_SECKEY_LEN 32
#define GCRY_KEM_ECC_BP256_PUBKEY_LEN (1+32+32)
#define GCRY_KEM_ECC_BP256_ENCAPS_LEN (1+32+32)
_______________________________________________
Gcrypt-devel mailing list
[email protected]
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel