diff mbox series

[v2,21/41] SUNRPC: Add new subkey length fields

Message ID 167380335043.10651.4539540903593677032.stgit@bazille.1015granger.net (mailing list archive)
State Accepted
Commit af664fc9023e69d1a90800c0f815c296bf727e18
Headers show
Series RPCSEC GSS krb5 enhancements | expand

Commit Message

Chuck Lever Jan. 15, 2023, 5:22 p.m. UTC
From: Chuck Lever <chuck.lever@oracle.com>

The aes256-cts-hmac-sha384-192 enctype specifies the length of its
checksum and integrity subkeys as 192 bits, but the length of its
encryption subkey (Ke) as 256 bits. Add new fields to struct
gss_krb5_enctype that specify the key lengths individually, and
where needed, use the correct new field instead of ->keylength.

Tested-by: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 include/linux/sunrpc/gss_krb5.h     |   14 ++++++++++++--
 net/sunrpc/auth_gss/gss_krb5_mech.c |   20 ++++++++++++++------
 2 files changed, 26 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
index 04addef79177..3e97d2a7c87d 100644
--- a/include/linux/sunrpc/gss_krb5.h
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -42,10 +42,16 @@ 
 #include <linux/sunrpc/gss_err.h>
 #include <linux/sunrpc/gss_asn1.h>
 
+/*
+ * The RFCs often specify payload lengths in bits. This helper
+ * converts a specified bit-length to the number of octets/bytes.
+ */
+#define BITS2OCTETS(x)	((x) / 8)
+
 /* Length of constant used in key derivation */
 #define GSS_KRB5_K5CLENGTH (5)
 
-/* Maximum key length (in bytes) for the supported crypto algorithms*/
+/* Maximum key length (in bytes) for the supported crypto algorithms */
 #define GSS_KRB5_MAX_KEYLEN (32)
 
 /* Maximum checksum function output for the supported crypto algorithms */
@@ -68,7 +74,11 @@  struct gss_krb5_enctype {
 	const u32		cksumlength;	/* checksum length */
 	const u32		keyed_cksum;	/* is it a keyed cksum? */
 	const u32		keybytes;	/* raw key len, in bytes */
-	const u32		keylength;	/* final key len, in bytes */
+	const u32		keylength;	/* protocol key length, in octets */
+	const u32		Kc_length;	/* checksum subkey length, in octets */
+	const u32		Ke_length;	/* encryption subkey length, in octets */
+	const u32		Ki_length;	/* integrity subkey length, in octets */
+
 	int (*import_ctx)(struct krb5_ctx *ctx, gfp_t gfp_mask);
 	int (*derive_key)(const struct gss_krb5_enctype *gk5e,
 			  const struct xdr_netobj *in,
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 45f461f9b5ba..ec3cca8fadc5 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -108,8 +108,11 @@  static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = {
 	  .signalg = -1,
 	  .sealalg = -1,
 	  .keybytes = 16,
-	  .keylength = 16,
-	  .cksumlength = 12,
+	  .keylength = BITS2OCTETS(128),
+	  .Kc_length = BITS2OCTETS(128),
+	  .Ke_length = BITS2OCTETS(128),
+	  .Ki_length = BITS2OCTETS(128),
+	  .cksumlength = BITS2OCTETS(96),
 	  .keyed_cksum = 1,
 	},
 	/*
@@ -135,8 +138,11 @@  static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = {
 	  .signalg = -1,
 	  .sealalg = -1,
 	  .keybytes = 32,
-	  .keylength = 32,
-	  .cksumlength = 12,
+	  .keylength = BITS2OCTETS(256),
+	  .Kc_length = BITS2OCTETS(256),
+	  .Ke_length = BITS2OCTETS(256),
+	  .Ki_length = BITS2OCTETS(256),
+	  .cksumlength = BITS2OCTETS(96),
 	  .keyed_cksum = 1,
 	},
 #endif
@@ -423,12 +429,12 @@  gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask)
 	struct xdr_netobj keyout;
 	int ret = -EINVAL;
 
-	keyout.data = kmalloc(ctx->gk5e->keylength, gfp_mask);
+	keyout.data = kmalloc(GSS_KRB5_MAX_KEYLEN, gfp_mask);
 	if (!keyout.data)
 		return -ENOMEM;
-	keyout.len = ctx->gk5e->keylength;
 
 	/* initiator seal encryption */
+	keyout.len = ctx->gk5e->Ke_length;
 	if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL,
 			    KEY_USAGE_SEED_ENCRYPTION, gfp_mask))
 		goto out;
@@ -461,6 +467,7 @@  gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask)
 	}
 
 	/* initiator sign checksum */
+	keyout.len = ctx->gk5e->Kc_length;
 	if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SIGN,
 			    KEY_USAGE_SEED_CHECKSUM, gfp_mask))
 		goto out_free;
@@ -477,6 +484,7 @@  gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask)
 		goto out_free;
 
 	/* initiator seal integrity */
+	keyout.len = ctx->gk5e->Ki_length;
 	if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL,
 			    KEY_USAGE_SEED_INTEGRITY, gfp_mask))
 		goto out_free;