diff mbox series

[17/18] crypto: dh - try to match domain parameters to a known safe-prime group

Message ID 20211201004858.19831-18-nstange@suse.de (mailing list archive)
State New
Headers show
Series crypto: dh - infrastructure for NVM in-band auth and FIPS conformance | expand

Commit Message

Nicolai Stange Dec. 1, 2021, 12:48 a.m. UTC
A subsequent patch will make the DH implementation to reject any input
domain parameter set with ->group_id == dh_group_id_unknown in FIPS mode.
However, as the keyctl(KEYCTL_DH_COMPUTE) implementation simply passes
forward keys from userspace, it does not (and cannot) set ->group_id to
anything else than dh_group_id_unknown.

In order to still allow for keyctl(KEYCTL_DH_COMPUTE) to work on approved
domain parameters passed in from userspace in FIPS mode, make
crypto_dh_decode_key() to compare them against any of the known groups and
set ->group_id upon having found a match, if any.

Signed-off-by: Nicolai Stange <nstange@suse.de>
---
 crypto/dh_helper.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Comments

Hannes Reinecke Dec. 1, 2021, 7:34 a.m. UTC | #1
On 12/1/21 1:48 AM, Nicolai Stange wrote:
> A subsequent patch will make the DH implementation to reject any input
> domain parameter set with ->group_id == dh_group_id_unknown in FIPS mode.
> However, as the keyctl(KEYCTL_DH_COMPUTE) implementation simply passes
> forward keys from userspace, it does not (and cannot) set ->group_id to
> anything else than dh_group_id_unknown.
> 
> In order to still allow for keyctl(KEYCTL_DH_COMPUTE) to work on approved
> domain parameters passed in from userspace in FIPS mode, make
> crypto_dh_decode_key() to compare them against any of the known groups and
> set ->group_id upon having found a match, if any.
> 
> Signed-off-by: Nicolai Stange <nstange@suse.de>
> ---
>   crypto/dh_helper.c | 33 +++++++++++++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
> 
Reviewed-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
diff mbox series

Patch

diff --git a/crypto/dh_helper.c b/crypto/dh_helper.c
index 5a8c9c50297f..cf632beca65e 100644
--- a/crypto/dh_helper.c
+++ b/crypto/dh_helper.c
@@ -471,6 +471,36 @@  get_safe_prime_group(enum dh_group_id group_id)
 	return NULL;
 }
 
+static enum dh_group_id lookup_group_id(const char *g, size_t g_size,
+					const char *p, size_t p_size)
+{
+	int i;
+
+	/* All safe-prime groups use a generator of g == 2. */
+	while (g_size && !*g) {
+		++g;
+		--g_size;
+	}
+
+	if (g_size != 1 || *g != 2)
+		return dh_group_id_unknown;
+
+	while (p_size && !*p) {
+		++p;
+		--p_size;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(safe_prime_groups); ++i) {
+		if (safe_prime_groups[i].p_size != p_size)
+			continue;
+
+		if (!memcmp(safe_prime_groups[i].p, p, p_size))
+			return safe_prime_groups[i].group_id;
+	}
+
+	return dh_group_id_unknown;
+}
+
 static inline u8 *dh_pack_data(u8 *dst, u8 *end, const void *src, size_t size)
 {
 	if (!dst || size > end - dst)
@@ -566,6 +596,9 @@  int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
 		if (memchr_inv(params->p, 0, params->p_size) == NULL)
 			return -EINVAL;
 
+		params->group_id = lookup_group_id(params->g, params->g_size,
+						   params->p, params->p_size);
+
 	} else {
 		const struct safe_prime_group *g;