[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250117183538.881618-12-dhowells@redhat.com>
Date: Fri, 17 Jan 2025 18:35:20 +0000
From: David Howells <dhowells@...hat.com>
To: Herbert Xu <herbert@...dor.apana.org.au>,
Chuck Lever <chuck.lever@...cle.com>
Cc: David Howells <dhowells@...hat.com>,
Trond Myklebust <trond.myklebust@...merspace.com>,
"David S. Miller" <davem@...emloft.net>,
Marc Dionne <marc.dionne@...istor.com>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Simon Horman <horms@...nel.org>,
Eric Biggers <ebiggers@...nel.org>,
Ard Biesheuvel <ardb@...nel.org>,
linux-crypto@...r.kernel.org,
linux-afs@...ts.infradead.org,
linux-nfs@...r.kernel.org,
linux-fsdevel@...r.kernel.org,
netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [RFC PATCH 11/24] crypto/krb5: Provide RFC3961 setkey packaging functions
Provide functions to derive keys according to RFC3961 (or load the derived
keys for the selftester where only derived keys are available) and to
package them up appropriately for passing to a krb5enc AEAD setkey or a
hash setkey function.
Signed-off-by: David Howells <dhowells@...hat.com>
cc: Herbert Xu <herbert@...dor.apana.org.au>
cc: "David S. Miller" <davem@...emloft.net>
cc: Chuck Lever <chuck.lever@...cle.com>
cc: Marc Dionne <marc.dionne@...istor.com>
cc: Eric Dumazet <edumazet@...gle.com>
cc: Jakub Kicinski <kuba@...nel.org>
cc: Paolo Abeni <pabeni@...hat.com>
cc: Simon Horman <horms@...nel.org>
cc: linux-afs@...ts.infradead.org
cc: linux-nfs@...r.kernel.org
cc: linux-crypto@...r.kernel.org
cc: netdev@...r.kernel.org
---
crypto/krb5/internal.h | 20 ++++++
crypto/krb5/rfc3961_simplified.c | 116 +++++++++++++++++++++++++++++--
2 files changed, 132 insertions(+), 4 deletions(-)
diff --git a/crypto/krb5/internal.h b/crypto/krb5/internal.h
index 7d60977dc0c5..8418c23d5018 100644
--- a/crypto/krb5/internal.h
+++ b/crypto/krb5/internal.h
@@ -136,3 +136,23 @@ int krb5_derive_Ki(const struct krb5_enctype *krb5, const struct krb5_buffer *TK
* rfc3961_simplified.c
*/
extern const struct krb5_crypto_profile rfc3961_simplified_profile;
+
+int krb5enc_derive_encrypt_keys(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *TK,
+ unsigned int usage,
+ struct krb5_buffer *setkey,
+ gfp_t gfp);
+int krb5enc_load_encrypt_keys(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *Ke,
+ const struct krb5_buffer *Ki,
+ struct krb5_buffer *setkey,
+ gfp_t gfp);
+int rfc3961_derive_checksum_key(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *TK,
+ unsigned int usage,
+ struct krb5_buffer *setkey,
+ gfp_t gfp);
+int rfc3961_load_checksum_key(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *Kc,
+ struct krb5_buffer *setkey,
+ gfp_t gfp);
diff --git a/crypto/krb5/rfc3961_simplified.c b/crypto/krb5/rfc3961_simplified.c
index 492ad85cdd56..d25fbd574dde 100644
--- a/crypto/krb5/rfc3961_simplified.c
+++ b/crypto/krb5/rfc3961_simplified.c
@@ -399,9 +399,117 @@ static int rfc3961_calc_PRF(const struct krb5_enctype *krb5,
return ret;
}
+/*
+ * Derive the Ke and Ki keys and package them into a key parameter that can be
+ * given to the setkey of a krb5enc AEAD crypto object.
+ */
+int krb5enc_derive_encrypt_keys(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *TK,
+ unsigned int usage,
+ struct krb5_buffer *setkey,
+ gfp_t gfp)
+{
+ struct krb5_buffer Ke, Ki;
+ __be32 *khdr = NULL;
+ int ret;
+
+ Ke.len = krb5->Ke_len;
+ Ki.len = krb5->Ki_len;
+ setkey->len = sizeof(__be32) * 3 + krb5->Ke_len + krb5->Ki_len;
+ setkey->data = kzalloc(setkey->len, GFP_KERNEL);
+ if (!setkey->data)
+ return -ENOMEM;
+
+ khdr = setkey->data;
+ Ke.data = setkey->data + 12;
+ Ki.data = setkey->data + 12 + Ke.len;
+
+ khdr[0] = htonl(1); /* Format 1 */
+ khdr[1] = htonl(Ke.len);
+ khdr[2] = htonl(Ki.len);
+
+ ret = krb5_derive_Ke(krb5, TK, usage, &Ke, gfp);
+ if (ret < 0) {
+ pr_err("get_Ke failed %d\n", ret);
+ return ret;
+ }
+ ret = krb5_derive_Ki(krb5, TK, usage, &Ki, gfp);
+ if (ret < 0)
+ pr_err("get_Ki failed %d\n", ret);
+ return ret;
+}
+
+/*
+ * Package predefined Ke and Ki keys and into a key parameter that can be given
+ * to the setkey of a krb5enc AEAD crypto object.
+ */
+int krb5enc_load_encrypt_keys(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *Ke,
+ const struct krb5_buffer *Ki,
+ struct krb5_buffer *setkey,
+ gfp_t gfp)
+{
+ __be32 *khdr = NULL;
+
+ setkey->len = sizeof(__be32) * 3 + Ke->len + Ki->len;
+ setkey->data = kzalloc(setkey->len, GFP_KERNEL);
+ if (!setkey->data)
+ return -ENOMEM;
+
+ khdr = setkey->data;
+ khdr[0] = htonl(1); /* Format 1 */
+ khdr[1] = htonl(Ke->len);
+ khdr[2] = htonl(Ki->len);
+ memcpy(setkey->data + 12, Ke->data, Ke->len);
+ memcpy(setkey->data + 12 + Ke->len, Ki->data, Ki->len);
+ return 0;
+}
+
+/*
+ * Derive the Kc key for checksum-only mode and package it into a key parameter
+ * that can be given to the setkey of a hash crypto object.
+ */
+int rfc3961_derive_checksum_key(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *TK,
+ unsigned int usage,
+ struct krb5_buffer *setkey,
+ gfp_t gfp)
+{
+ int ret;
+
+ setkey->len = krb5->Kc_len;
+ setkey->data = kzalloc(setkey->len, GFP_KERNEL);
+ if (!setkey->data)
+ return -ENOMEM;
+
+ ret = krb5_derive_Kc(krb5, TK, usage, setkey, gfp);
+ if (ret < 0)
+ pr_err("get_Kc failed %d\n", ret);
+ return ret;
+}
+
+/*
+ * Package a predefined Kc key for checksum-only mode into a key parameter that
+ * can be given to the setkey of a hash crypto object.
+ */
+int rfc3961_load_checksum_key(const struct krb5_enctype *krb5,
+ const struct krb5_buffer *Kc,
+ struct krb5_buffer *setkey,
+ gfp_t gfp)
+{
+ setkey->len = krb5->Kc_len;
+ setkey->data = kmemdup(Kc->data, Kc->len, GFP_KERNEL);
+ if (!setkey->data)
+ return -ENOMEM;
+ return 0;
+}
const struct krb5_crypto_profile rfc3961_simplified_profile = {
- .calc_PRF = rfc3961_calc_PRF,
- .calc_Kc = rfc3961_calc_DK,
- .calc_Ke = rfc3961_calc_DK,
- .calc_Ki = rfc3961_calc_DK,
+ .calc_PRF = rfc3961_calc_PRF,
+ .calc_Kc = rfc3961_calc_DK,
+ .calc_Ke = rfc3961_calc_DK,
+ .calc_Ki = rfc3961_calc_DK,
+ .derive_encrypt_keys = krb5enc_derive_encrypt_keys,
+ .load_encrypt_keys = krb5enc_load_encrypt_keys,
+ .derive_checksum_key = rfc3961_derive_checksum_key,
+ .load_checksum_key = rfc3961_load_checksum_key,
};
Powered by blists - more mailing lists