From patchwork Fri Jan 13 15:21:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100942 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9F2EAC678D4 for ; Fri, 13 Jan 2023 15:28:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229748AbjAMP2e (ORCPT ); Fri, 13 Jan 2023 10:28:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230181AbjAMP2R (ORCPT ); Fri, 13 Jan 2023 10:28:17 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E2087EC86 for ; Fri, 13 Jan 2023 07:21:36 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AEA2362171 for ; Fri, 13 Jan 2023 15:21:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DAAEFC433EF; Fri, 13 Jan 2023 15:21:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623295; bh=BafomN1WImkk2tnPEHLusmFBeE7srAMZgK56SVJzrng=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=SJ61s10MmDxvvQ6gMlCr/3vGD6btzdIuXh9GmKervwJqP5g3WfqHwdSvDnCHvHHny SzizGMFe5gZpjKsm5C4fy/ufo0VVBRBWsX1ybenJaqvb5uNllsQ8KtTfRjtsHszIY+ XcS9yYOXllK05DMnpYSRE6vu/RGym/Dc7YIoFrLuXo9iSNkcjV8sJzQibqFKFC5Z5M XQkw13p4fdzFdyoRWWYyd5UqAzlk+CVeZxcRwJNFVAPGx/Wv7ia2LqqAVro15PpURf Hg137mg5XAhV9UhRyidwFAGU7sV87aWTx6tSU8eUn4cG2ACYUl1y0zBw+k9FMv5y/W ynbnX1XJG9n9g== Subject: [PATCH v1 01/41] SUNRPC: Add header ifdefs to linux/sunrpc/gss_krb5.h From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:21:33 -0500 Message-ID: <167362329391.8960.2728300899554595366.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Standard convention: Ensure the contents of the header are included only once per source file. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 91f43d86879d..0135139ddf20 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -1,6 +1,4 @@ /* - * linux/include/linux/sunrpc/gss_krb5_types.h - * * Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h, * lib/gssapi/krb5/gssapiP_krb5.h, and others * @@ -36,6 +34,9 @@ * */ +#ifndef _LINUX_SUNRPC_GSS_KRB5_H +#define _LINUX_SUNRPC_GSS_KRB5_H + #include #include #include @@ -316,3 +317,5 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, void gss_krb5_make_confounder(char *p, u32 conflen); + +#endif /* _LINUX_SUNRPC_GSS_KRB5_H */ From patchwork Fri Jan 13 15:21:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100944 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39B19C678D8 for ; Fri, 13 Jan 2023 15:28:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229502AbjAMP2g (ORCPT ); Fri, 13 Jan 2023 10:28:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229937AbjAMP2R (ORCPT ); Fri, 13 Jan 2023 10:28:17 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D0168143D for ; Fri, 13 Jan 2023 07:21:42 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0ED7F620D6 for ; Fri, 13 Jan 2023 15:21:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3D767C433F0; Fri, 13 Jan 2023 15:21:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623301; bh=QaJGYjsXTHDcxun8svP1bv6moYjQCPBWR2JSPH/tTRE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=lhV6+kpmJhBypQQ+bVTnauchTdTqV+5CTNiB4HMwLrmTSURBNhFCCvvG5vYWm3KrX reTrV8laAjQd/vqnUhOUQ8bASwvEe1CDwNHD4tI6YQiPoL0S4trM8vVGrPhHObdv+3 sirLJZFE1N5whd0h6/pTz0qe3sWE3Z7ygbkEpFDIVnUdTqfeIC9rOnHP7uX1pJgK4S R0KL8eI269A45zMJArcYFs+6g+CpfyjcI4oeRCFdBtV/Jta/JN9RGN2+wvHJFrPXE5 g3BMazwaWj59AJWgHh0x3l7BAtCivrPvpmpe1fWxf/9IVmB2N/dBhCh8bhnI3bIhUR cYtRXfSru9q6Q== Subject: [PATCH v1 02/41] SUNRPC: Remove .blocksize field from struct gss_krb5_enctype From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:21:40 -0500 Message-ID: <167362330030.8960.6672671046687912325.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever It is not clear from documenting comments, specifications, or code usage what value the gss_krb5_enctype.blocksize field is supposed to store. The "encryption blocksize" depends only on the cipher being used, so that value can be derived where it's needed instead of stored as a constant. RFC 3961 Section 5.2 says: > cipher block size, c > This is the block size of the block cipher underlying the > encryption and decryption functions indicated above, used for key > derivation and for the size of the message confounder and initial > vector. (If a block cipher is not in use, some comparable > parameter should be determined.) It must be at least 5 octets. > > This is not actually an independent parameter; rather, it is a > property of the functions E and D. It is listed here to clarify > the distinction between it and the message block size, m. In the Linux kernel's implemenation of the SunRPC RPCSEC GSS Kerberos 5 mechanism, the cipher block size, which is dependent on the encryption and decryption transforms, is used only in krb5_derive_key(), so it is straightforward to replace it. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 1 - net/sunrpc/auth_gss/gss_krb5_keys.c | 4 +--- net/sunrpc/auth_gss/gss_krb5_mech.c | 4 ---- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 0135139ddf20..9a833825b55b 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -64,7 +64,6 @@ struct gss_krb5_enctype { const char *cksum_name; /* crypto checksum name */ const u16 signalg; /* signing algorithm */ const u16 sealalg; /* sealing algorithm */ - const u32 blocksize; /* encryption blocksize */ const u32 conflen; /* confounder length (normally the same as the blocksize) */ diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index 726c076950c0..554cfd23f288 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c @@ -150,7 +150,6 @@ u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, struct crypto_sync_skcipher *cipher; u32 ret = EINVAL; - blocksize = gk5e->blocksize; keybytes = gk5e->keybytes; keylength = gk5e->keylength; @@ -160,11 +159,10 @@ u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, cipher = crypto_alloc_sync_skcipher(gk5e->encrypt_name, 0, 0); if (IS_ERR(cipher)) goto err_return; + blocksize = crypto_sync_skcipher_blocksize(cipher); if (crypto_sync_skcipher_setkey(cipher, inkey->data, inkey->len)) goto err_return; - /* allocate and set up buffers */ - ret = ENOMEM; inblockdata = kmalloc(blocksize, gfp_mask); if (inblockdata == NULL) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 1c092b05c2bb..dd85fc9ca80b 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -47,7 +47,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = SEAL_ALG_DES, .keybytes = 7, .keylength = 8, - .blocksize = 8, .conflen = 8, .cksumlength = 8, .keyed_cksum = 0, @@ -69,7 +68,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = SEAL_ALG_DES3KD, .keybytes = 21, .keylength = 24, - .blocksize = 8, .conflen = 8, .cksumlength = 20, .keyed_cksum = 1, @@ -92,7 +90,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = -1, .keybytes = 16, .keylength = 16, - .blocksize = 16, .conflen = 16, .cksumlength = 12, .keyed_cksum = 1, @@ -115,7 +112,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = -1, .keybytes = 32, .keylength = 32, - .blocksize = 16, .conflen = 16, .cksumlength = 12, .keyed_cksum = 1, From patchwork Fri Jan 13 15:21:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100943 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 488C0C678DA for ; Fri, 13 Jan 2023 15:28:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229937AbjAMP2g (ORCPT ); Fri, 13 Jan 2023 10:28:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230182AbjAMP2S (ORCPT ); Fri, 13 Jan 2023 10:28:18 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBBEF8143B for ; Fri, 13 Jan 2023 07:21:48 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6693B6217B for ; Fri, 13 Jan 2023 15:21:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 95AF9C433F0; Fri, 13 Jan 2023 15:21:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623307; bh=KldhuGSYRC2SS9/MNT62J+Rs6IstRysPw1wIfoosjFA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=lpbDi1JnPG91iJOIbrp/44d2JKtdF2JfFuR9hfoPkvc8Nn2gEQfRTetJDjkzTb5DS c/32ON5XmFITDOWBKn9f+2h+DMU8t5Xum8Qd47YH8YFtFkES2DWqJYuFeTBGomlNEl uYAaECJfQr4KYbml1NJKb5xzdS1dorMgQVpX3s7VnrdAEEk7LyDvOjb0GegLeaAxwF vytimGQHxBQ0heS1+3qjSt4neWTEUAJvL65sKAnMucGk1oW6vxSsYXaQA+OiBQil95 RmBZLG6odmN6W41TtCGUBJmGDBOBjFsr7fw/WxeSiJK5o4i7d3mbzlt96ZbKcegPGf kGIkpRkHSXCNQ== Subject: [PATCH v1 03/41] SUNRPC: Remove .conflen field from struct gss_krb5_enctype From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:21:46 -0500 Message-ID: <167362330668.8960.18353493146040000804.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Now that arcfour-hmac is gone, the confounder length is again the same as the cipher blocksize for every implemented enctype. The gss_krb5_enctype::conflen field is no longer necessary. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 3 --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 9 +++++---- net/sunrpc/auth_gss/gss_krb5_mech.c | 4 ---- net/sunrpc/auth_gss/gss_krb5_wrap.c | 4 ++-- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 9a833825b55b..51860e3a0216 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -64,9 +64,6 @@ struct gss_krb5_enctype { const char *cksum_name; /* crypto checksum name */ const u16 signalg; /* signing algorithm */ const u16 sealalg; /* sealing algorithm */ - const u32 conflen; /* confounder length - (normally the same as - the blocksize) */ const u32 cksumlength; /* checksum length */ const u32 keyed_cksum; /* is it a keyed cksum? */ const u32 keybytes; /* raw key len, in bytes */ diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 3ea58175e159..8aa5610ef660 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -610,6 +610,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, struct encryptor_desc desc; u32 cbcbytes; unsigned int usage; + unsigned int conflen; if (kctx->initiate) { cipher = kctx->initiator_enc; @@ -623,12 +624,13 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, usage = KG_USAGE_ACCEPTOR_SEAL; } blocksize = crypto_sync_skcipher_blocksize(cipher); + conflen = crypto_sync_skcipher_blocksize(cipher); /* hide the gss token header and insert the confounder */ offset += GSS_KRB5_TOK_HDR_LEN; - if (xdr_extend_head(buf, offset, kctx->gk5e->conflen)) + if (xdr_extend_head(buf, offset, conflen)) return GSS_S_FAILURE; - gss_krb5_make_confounder(buf->head[0].iov_base + offset, kctx->gk5e->conflen); + gss_krb5_make_confounder(buf->head[0].iov_base + offset, conflen); offset -= GSS_KRB5_TOK_HDR_LEN; if (buf->tail[0].iov_base != NULL) { @@ -744,7 +746,6 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, } blocksize = crypto_sync_skcipher_blocksize(cipher); - /* create a segment skipping the header and leaving out the checksum */ xdr_buf_subsegment(buf, &subbuf, offset + GSS_KRB5_TOK_HDR_LEN, (len - offset - GSS_KRB5_TOK_HDR_LEN - @@ -801,7 +802,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, ret = GSS_S_BAD_SIG; goto out_err; } - *headskip = kctx->gk5e->conflen; + *headskip = blocksize; *tailskip = kctx->gk5e->cksumlength; out_err: if (ret && ret != GSS_S_BAD_SIG) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index dd85fc9ca80b..08a86ece665e 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -47,7 +47,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = SEAL_ALG_DES, .keybytes = 7, .keylength = 8, - .conflen = 8, .cksumlength = 8, .keyed_cksum = 0, }, @@ -68,7 +67,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = SEAL_ALG_DES3KD, .keybytes = 21, .keylength = 24, - .conflen = 8, .cksumlength = 20, .keyed_cksum = 1, }, @@ -90,7 +88,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = -1, .keybytes = 16, .keylength = 16, - .conflen = 16, .cksumlength = 12, .keyed_cksum = 1, }, @@ -112,7 +109,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .sealalg = -1, .keybytes = 32, .keylength = 32, - .conflen = 16, .cksumlength = 12, .keyed_cksum = 1, }, diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 48337687848c..bd068e936947 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -168,7 +168,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct page **tmp_pages; u32 seq_send; u8 *cksumkey; - u32 conflen = kctx->gk5e->conflen; + u32 conflen = crypto_sync_skcipher_blocksize(kctx->enc); dprintk("RPC: %s\n", __func__); @@ -261,7 +261,7 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, int len, void *data_start, *orig_start; int data_len; int blocksize; - u32 conflen = kctx->gk5e->conflen; + u32 conflen = crypto_sync_skcipher_blocksize(kctx->enc); int crypt_offset; u8 *cksumkey; unsigned int saved_len = buf->len; From patchwork Fri Jan 13 15:21:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100945 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF3FFC54EBD for ; Fri, 13 Jan 2023 15:29:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229635AbjAMP3A (ORCPT ); Fri, 13 Jan 2023 10:29:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229499AbjAMP2V (ORCPT ); Fri, 13 Jan 2023 10:28:21 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 19B94876CA for ; Fri, 13 Jan 2023 07:21:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A2573B820D2 for ; Fri, 13 Jan 2023 15:21:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05675C4339B; Fri, 13 Jan 2023 15:21:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623314; bh=0Oum7s/rQWA/1mTmpbrwZOv7bnMHiykn/XyBuVDv5k4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=o6STalZXAPVrXfhuKtE4dwG/Ctr+RUWNAvcw/U2Y3OwXMyd08Yo0bq4kjmHSGaDWp bZM9Ql3mAluSkICNuHg/sRLy3xCyXqhlQW1VrUtcFit1/7NpuVyUukANMOJkWMcssr VZ+XA1bKYNDTLVcLaDf0hRftJ1P+QEAJX4fm+jF+b7UAkJeDF9ZQXcfCJWeh1UDzrx SAe+I7Jb85FcxYdi4jy992NcIyvFac6QaPGViSvFkOwqTydYLEMuKzRSdKs7l9m+op PNPIDgFdHtxMala0F3CsdlDdvj8JCj4yxpFEB21lR18eUq0GWanMER5HJOJDOkoXfd 82mp/+pqM0Fmw== Subject: [PATCH v1 04/41] SUNRPC: Improve Kerberos confounder generation From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:21:53 -0500 Message-ID: <167362331302.8960.7194615871100298109.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Other common Kerberos implementations use a fully random confounder for encryption. For a Kerberos implementation that is part of an O/S I/O stack, this is impractical. However, using a fast PRG that does not deplete the system entropy pool is possible and desirable. Use an atomic type to ensure that confounder generation deterministically generates a unique and pseudo-random result in the face of concurrent execution, and make the confounder generation materials unique to each Keberos context. The latter has several benefits: - the internal counter will wrap less often - no way to guess confounders based on other Kerberos-encrypted traffic - better scalability Since confounder generation is part of Kerberos itself rather than the GSS-API Kerberos mechanism, the function is renamed and moved. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 7 +++--- net/sunrpc/auth_gss/gss_krb5_crypto.c | 28 ++++++++++++++++++++++- net/sunrpc/auth_gss/gss_krb5_internal.h | 13 +++++++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 17 +++++++------- net/sunrpc/auth_gss/gss_krb5_wrap.c | 38 ++----------------------------- 5 files changed, 56 insertions(+), 47 deletions(-) create mode 100644 net/sunrpc/auth_gss/gss_krb5_internal.h diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 51860e3a0216..192f5b37763f 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -38,6 +38,8 @@ #define _LINUX_SUNRPC_GSS_KRB5_H #include +#include + #include #include #include @@ -106,6 +108,8 @@ struct krb5_ctx { atomic_t seq_send; atomic64_t seq_send64; time64_t endtime; + atomic64_t confounder; + siphash_key_t confkey; struct xdr_netobj mech_used; u8 initiator_sign[GSS_KRB5_MAX_KEYLEN]; u8 acceptor_sign[GSS_KRB5_MAX_KEYLEN]; @@ -311,7 +315,4 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, struct xdr_buf *buf, u32 *plainoffset, u32 *plainlen); -void -gss_krb5_make_confounder(char *p, u32 conflen); - #endif /* _LINUX_SUNRPC_GSS_KRB5_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 8aa5610ef660..6d962079aa95 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -47,10 +47,36 @@ #include #include +#include "gss_krb5_internal.h" + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif +/** + * krb5_make_confounder - Generate a unique pseudorandom string + * @kctx: Kerberos context + * @p: memory location into which to write the string + * @conflen: string length to write, in octets + * + * To avoid draining the system's entropy pool when under heavy + * encrypted I/O loads, the @kctx has a small amount of random seed + * data that is then hashed to generate each pseudorandom confounder + * string. + */ +void +krb5_make_confounder(struct krb5_ctx *kctx, u8 *p, int conflen) +{ + u64 *q = (u64 *)p; + + WARN_ON_ONCE(conflen < sizeof(*q)); + while (conflen > 0) { + *q++ = siphash_1u64(atomic64_inc_return(&kctx->confounder), + &kctx->confkey); + conflen -= sizeof(*q); + } +} + u32 krb5_encrypt( struct crypto_sync_skcipher *tfm, @@ -630,7 +656,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, offset += GSS_KRB5_TOK_HDR_LEN; if (xdr_extend_head(buf, offset, conflen)) return GSS_S_FAILURE; - gss_krb5_make_confounder(buf->head[0].iov_base + offset, conflen); + krb5_make_confounder(kctx, buf->head[0].iov_base + offset, conflen); offset -= GSS_KRB5_TOK_HDR_LEN; if (buf->tail[0].iov_base != NULL) { diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h new file mode 100644 index 000000000000..6249124aba1d --- /dev/null +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ +/* + * SunRPC GSS Kerberos 5 mechanism internal definitions + * + * Copyright (c) 2022 Oracle and/or its affiliates. + */ + +#ifndef _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H +#define _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H + +void krb5_make_confounder(struct krb5_ctx *kctx, u8 *p, int conflen); + +#endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 08a86ece665e..6d59794c9b69 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -550,16 +550,17 @@ gss_import_sec_context_kerberos(const void *p, size_t len, ret = gss_import_v1_context(p, end, ctx); else ret = gss_import_v2_context(p, end, ctx, gfp_mask); - - if (ret == 0) { - ctx_id->internal_ctx_id = ctx; - if (endtime) - *endtime = ctx->endtime; - } else + if (ret) { kfree(ctx); + return ret; + } - dprintk("RPC: %s: returning %d\n", __func__, ret); - return ret; + ctx_id->internal_ctx_id = ctx; + if (endtime) + *endtime = ctx->endtime; + atomic64_set(&ctx->confounder, get_random_u64()); + get_random_bytes(&ctx->confkey, sizeof(ctx->confkey)); + return 0; } static void diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index bd068e936947..374214f3c463 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -32,9 +32,10 @@ #include #include #include -#include #include +#include "gss_krb5_internal.h" + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif @@ -113,39 +114,6 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize) return 0; } -void -gss_krb5_make_confounder(char *p, u32 conflen) -{ - static u64 i = 0; - u64 *q = (u64 *)p; - - /* rfc1964 claims this should be "random". But all that's really - * necessary is that it be unique. And not even that is necessary in - * our case since our "gssapi" implementation exists only to support - * rpcsec_gss, so we know that the only buffers we will ever encrypt - * already begin with a unique sequence number. Just to hedge my bets - * I'll make a half-hearted attempt at something unique, but ensuring - * uniqueness would mean worrying about atomicity and rollover, and I - * don't care enough. */ - - /* initialize to random value */ - if (i == 0) { - i = get_random_u32(); - i = (i << 32) | get_random_u32(); - } - - switch (conflen) { - case 16: - *q++ = i++; - fallthrough; - case 8: - *q++ = i++; - break; - default: - BUG(); - } -} - /* Assumptions: the head and tail of inbuf are ours to play with. * The pages, however, may be real pages in the page cache and we replace * them with scratch pages from **pages before writing to them. */ @@ -211,7 +179,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset, ptr[6] = 0xff; ptr[7] = 0xff; - gss_krb5_make_confounder(msg_start, conflen); + krb5_make_confounder(kctx, msg_start, conflen); if (kctx->gk5e->keyed_cksum) cksumkey = kctx->cksum; From patchwork Fri Jan 13 15:21:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100946 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 051F5C61DB3 for ; Fri, 13 Jan 2023 15:29:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230036AbjAMP3B (ORCPT ); Fri, 13 Jan 2023 10:29:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229505AbjAMP2V (ORCPT ); Fri, 13 Jan 2023 10:28:21 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 982F744C43 for ; Fri, 13 Jan 2023 07:22:01 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 372886216C for ; Fri, 13 Jan 2023 15:22:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 65985C433D2; Fri, 13 Jan 2023 15:22:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623320; bh=kpUGvzOW39hlMmxADthx96vNAWACrjND/YOYiOTSHks=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=sZkK4DpHe6+3z+O4e0qj13/IOvpwcaWzUT7Tc4GxQ4KFiLEpWs+sO0NzQv2xou1ZK hBBK9QDX6ENWKyS76KEsGLwoHr81xB1RtVC9r6xmboESqv+qTGz/kn+IPic04javOL 4VXUhu8fmLS6fY7r1Gf4s8j1Js/jtpigtp9pSo8G+euo0IyjUqbT3ooRZ7MWvlKknT Hy1J3RxPxxI7daqlV8dizGVs8fKa2OghivSzJ9znkHKdoNT7xIj51nt5omvYorPM5S KvT8CSY1oNV5GacPXLLERxJsxh/JmwsocBuAexQOwyHg8FQseELd/5Iym0vcC3Cjl+ 3uCYcXOI0mGFQ== Subject: [PATCH v1 05/41] SUNRPC: Obscure Kerberos session key From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:21:59 -0500 Message-ID: <167362331943.8960.1546242627205639130.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever ctx->Ksess is never used after import has completed. Obscure it immediately so it cannot be re-used or copied. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_mech.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 6d59794c9b69..9b489f7f2720 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -550,6 +550,7 @@ gss_import_sec_context_kerberos(const void *p, size_t len, ret = gss_import_v1_context(p, end, ctx); else ret = gss_import_v2_context(p, end, ctx, gfp_mask); + memzero_explicit(&ctx->Ksess, sizeof(ctx->Ksess)); if (ret) { kfree(ctx); return ret; From patchwork Fri Jan 13 15:22:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100947 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6236C54EBE for ; Fri, 13 Jan 2023 15:29:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229912AbjAMP3I (ORCPT ); Fri, 13 Jan 2023 10:29:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230125AbjAMP2Y (ORCPT ); Fri, 13 Jan 2023 10:28:24 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3382477AD6 for ; Fri, 13 Jan 2023 07:22:10 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id A69ABCE20E5 for ; Fri, 13 Jan 2023 15:22:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AF4E6C433F0; Fri, 13 Jan 2023 15:22:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623326; bh=PoOrxR1gudKQCxvesHKR5Bl7Gnm3yY4ayGL3PBHzDXE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=KR8U2XDu07zm7cqjknyjlDXLB+LwxEYE4gcZdForCWCzgOh1bVKyMB4iS/H78WKdw 1qde8Crk5Li+BoU2cRRQ7QJzk0Qjx4go49OWgGH6eI31OEcdO1mhprj2tWPRHbAzGS 64R+usqeJqIZzj5iJ8oiYiJ051PhIyjTjFzuPM09zMPC2oMlo0TcoRnMhPTwZ28xoX UCrw/0w3i8l4CbhyI8VqnJaxQAAzMg7pwo8cwi/bT7KsKyJOlUR/dW4WFVpRsj0yOH mej9f8It4aku6VKbiKaIg0Z45ekOGopw1w3jhzOIwtCpISDZlgnDzPGXndm1DdpwEG d2UX7yhM/CQvg== Subject: [PATCH v1 06/41] SUNRPC: Refactor set-up for aux_cipher From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:05 -0500 Message-ID: <167362332582.8960.13295643540048029311.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Hoist the name of the aux_cipher into struct gss_krb5_enctype to prepare for obscuring the encryption keys just after they are derived. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 1 + net/sunrpc/auth_gss/gss_krb5_mech.c | 50 ++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 192f5b37763f..77f6adf20f7f 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -63,6 +63,7 @@ struct gss_krb5_enctype { const u32 ctype; /* checksum type */ const char *name; /* "friendly" name */ const char *encrypt_name; /* crypto encrypt name */ + const char *aux_cipher; /* aux encrypt cipher name */ const char *cksum_name; /* crypto checksum name */ const u16 signalg; /* signing algorithm */ const u16 sealalg; /* sealing algorithm */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 9b489f7f2720..3a464cb3f6e9 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -78,6 +78,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .ctype = CKSUMTYPE_HMAC_SHA1_96_AES128, .name = "aes128-cts", .encrypt_name = "cts(cbc(aes))", + .aux_cipher = "cbc(aes)", .cksum_name = "hmac(sha1)", .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, @@ -99,6 +100,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .ctype = CKSUMTYPE_HMAC_SHA1_96_AES256, .name = "aes256-cts", .encrypt_name = "cts(cbc(aes))", + .aux_cipher = "cbc(aes)", .cksum_name = "hmac(sha1)", .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, @@ -373,6 +375,13 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) ctx->initiator_seal); if (ctx->initiator_enc == NULL) goto out_err; + if (ctx->gk5e->aux_cipher) { + ctx->initiator_enc_aux = + context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher, + ctx->initiator_seal); + if (ctx->initiator_enc_aux == NULL) + goto out_free; + } /* acceptor seal encryption */ set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); @@ -381,13 +390,20 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) if (err) { dprintk("%s: Error %d deriving acceptor_seal key\n", __func__, err); - goto out_free_initiator_enc; + goto out_free; } ctx->acceptor_enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, ctx->acceptor_seal); if (ctx->acceptor_enc == NULL) - goto out_free_initiator_enc; + goto out_free; + if (ctx->gk5e->aux_cipher) { + ctx->acceptor_enc_aux = + context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher, + ctx->acceptor_seal); + if (ctx->acceptor_enc_aux == NULL) + goto out_free; + } /* initiator sign checksum */ set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); @@ -396,7 +412,7 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) if (err) { dprintk("%s: Error %d deriving initiator_sign key\n", __func__, err); - goto out_free_acceptor_enc; + goto out_free; } /* acceptor sign checksum */ @@ -406,7 +422,7 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) if (err) { dprintk("%s: Error %d deriving acceptor_sign key\n", __func__, err); - goto out_free_acceptor_enc; + goto out_free; } /* initiator seal integrity */ @@ -416,7 +432,7 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) if (err) { dprintk("%s: Error %d deriving initiator_integ key\n", __func__, err); - goto out_free_acceptor_enc; + goto out_free; } /* acceptor seal integrity */ @@ -426,31 +442,15 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) if (err) { dprintk("%s: Error %d deriving acceptor_integ key\n", __func__, err); - goto out_free_acceptor_enc; - } - - switch (ctx->enctype) { - case ENCTYPE_AES128_CTS_HMAC_SHA1_96: - case ENCTYPE_AES256_CTS_HMAC_SHA1_96: - ctx->initiator_enc_aux = - context_v2_alloc_cipher(ctx, "cbc(aes)", - ctx->initiator_seal); - if (ctx->initiator_enc_aux == NULL) - goto out_free_acceptor_enc; - ctx->acceptor_enc_aux = - context_v2_alloc_cipher(ctx, "cbc(aes)", - ctx->acceptor_seal); - if (ctx->acceptor_enc_aux == NULL) { - crypto_free_sync_skcipher(ctx->initiator_enc_aux); - goto out_free_acceptor_enc; - } + goto out_free; } return 0; -out_free_acceptor_enc: +out_free: + crypto_free_sync_skcipher(ctx->acceptor_enc_aux); crypto_free_sync_skcipher(ctx->acceptor_enc); -out_free_initiator_enc: + crypto_free_sync_skcipher(ctx->initiator_enc_aux); crypto_free_sync_skcipher(ctx->initiator_enc); out_err: return -EINVAL; From patchwork Fri Jan 13 15:22:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100948 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CDBBC54EBD for ; Fri, 13 Jan 2023 15:29:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229551AbjAMP3h (ORCPT ); Fri, 13 Jan 2023 10:29:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230193AbjAMP2Z (ORCPT ); Fri, 13 Jan 2023 10:28:25 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F57277D1B for ; Fri, 13 Jan 2023 07:22:14 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id DE60E6216C for ; Fri, 13 Jan 2023 15:22:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 19046C433D2; Fri, 13 Jan 2023 15:22:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623333; bh=LFjemD4TUP+Zd2j4WiYOgkDVgJttBm9I86HZmcTSXTw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=qqF9OeTtxv+K64krBjv9g6cF2lNtZqfNlRRxW3rotnvfOuA7/L/sbtdSHGH71tSyN qw4L+9JgnH+w/3PdS1IFfZml1MTeUQexZMACrQoDKHfWD8W51JIcmc/mzsf0CxJX0m q/6k8q6+YbXkcdSwu8GwooAsamM8WEqfY2UWtW4hB7DgPZ9JEvj7qIptrAAFLEJupI Tmq7akCfm3pmqlpuizJNPPa/IdwxOLMiUicDQgrPHDWmrItfBQCw6cuRK2BdUjBcxT zL+tsBE9F8f9x1KK/XhrqaLYscV3FL4rQkp+/WB+Mu6UIE1GcAa4vbgOQSkmcZE796 7l1771/8ik0YQ== Subject: [PATCH v1 07/41] SUNRPC: Obscure Kerberos encryption keys From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:12 -0500 Message-ID: <167362333213.8960.4251999590261954481.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever The encryption subkeys are not used after the cipher transforms have been allocated and keyed. There is no need to retain them in struct krb5_ctx. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 2 -- net/sunrpc/auth_gss/gss_krb5_mech.c | 43 +++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 77f6adf20f7f..806df140feae 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -114,8 +114,6 @@ struct krb5_ctx { struct xdr_netobj mech_used; u8 initiator_sign[GSS_KRB5_MAX_KEYLEN]; u8 acceptor_sign[GSS_KRB5_MAX_KEYLEN]; - u8 initiator_seal[GSS_KRB5_MAX_KEYLEN]; - u8 acceptor_seal[GSS_KRB5_MAX_KEYLEN]; u8 initiator_integ[GSS_KRB5_MAX_KEYLEN]; u8 acceptor_integ[GSS_KRB5_MAX_KEYLEN]; }; diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 3a464cb3f6e9..ba3cfcb2c7c5 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -350,42 +350,49 @@ context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask) static int context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) { - struct xdr_netobj c, keyin, keyout; u8 cdata[GSS_KRB5_K5CLENGTH]; + struct xdr_netobj c = { + .len = sizeof(cdata), + .data = cdata, + }; + struct xdr_netobj keyin = { + .len = ctx->gk5e->keylength, + .data = ctx->Ksess, + }; + struct xdr_netobj keyout; + int ret = -EINVAL; + void *subkey; u32 err; - c.len = GSS_KRB5_K5CLENGTH; - c.data = cdata; - - keyin.data = ctx->Ksess; - keyin.len = ctx->gk5e->keylength; + subkey = kmalloc(ctx->gk5e->keylength, gfp_mask); + if (!subkey) + return -ENOMEM; keyout.len = ctx->gk5e->keylength; + keyout.data = subkey; /* initiator seal encryption */ set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); - keyout.data = ctx->initiator_seal; err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); if (err) { dprintk("%s: Error %d deriving initiator_seal key\n", __func__, err); - goto out_err; + goto out; } ctx->initiator_enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, - ctx->initiator_seal); + subkey); if (ctx->initiator_enc == NULL) - goto out_err; + goto out; if (ctx->gk5e->aux_cipher) { ctx->initiator_enc_aux = context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher, - ctx->initiator_seal); + subkey); if (ctx->initiator_enc_aux == NULL) goto out_free; } /* acceptor seal encryption */ set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); - keyout.data = ctx->acceptor_seal; err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); if (err) { dprintk("%s: Error %d deriving acceptor_seal key\n", @@ -394,13 +401,13 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) } ctx->acceptor_enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, - ctx->acceptor_seal); + subkey); if (ctx->acceptor_enc == NULL) goto out_free; if (ctx->gk5e->aux_cipher) { ctx->acceptor_enc_aux = context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher, - ctx->acceptor_seal); + subkey); if (ctx->acceptor_enc_aux == NULL) goto out_free; } @@ -445,15 +452,17 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) goto out_free; } - return 0; + ret = 0; +out: + kfree_sensitive(subkey); + return ret; out_free: crypto_free_sync_skcipher(ctx->acceptor_enc_aux); crypto_free_sync_skcipher(ctx->acceptor_enc); crypto_free_sync_skcipher(ctx->initiator_enc_aux); crypto_free_sync_skcipher(ctx->initiator_enc); -out_err: - return -EINVAL; + goto out; } static int From patchwork Fri Jan 13 15:22:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100949 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EEEDDC54EBE for ; Fri, 13 Jan 2023 15:29:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230046AbjAMP3r (ORCPT ); Fri, 13 Jan 2023 10:29:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230070AbjAMP21 (ORCPT ); Fri, 13 Jan 2023 10:28:27 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A76F343DA2 for ; Fri, 13 Jan 2023 07:22:20 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2AADE620D6 for ; Fri, 13 Jan 2023 15:22:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5D158C433EF; Fri, 13 Jan 2023 15:22:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623339; bh=wKycOl5c2QV5M/yjvRkD6rUWHsDQ0F2ilyVauonUKPo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=JDW3j3+QpEkFSKYAZUKFUVEP0LnbqreCAZtMoHE7wqo97Jn7HXRpncEP0EJe4ObkW 6mCzYIN8PShEE05Bx9hUtI25eyVpmuB150ay821yLYvM0Z9dWfR+t/6rkgJkVW8m7C Ugc06z8TdqAC82qn6YwwNZIrhbeZgiDulz1kHf48j0cbNHXTGpw+RoxvJ4dc5Lzvq3 mQ8TNN5qEt9kHTmXlkPflqoT0cjPF77tFXFJITEjKiX9wURkrNgrNxFGYfZY5aKwSq Nh4gsLBhsTKCaEx/MAHm8QJcoO92MAWp+I4WGLNCr8TOlX5Ouo/0+WUhtcqSCj6sMy pXmb5lhuQQ9aA== Subject: [PATCH v1 08/41] SUNRPC: Obscure Kerberos signing keys From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:18 -0500 Message-ID: <167362333850.8960.15009112905314133774.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever There's no need to keep the signing keys around if we instead allocate and key an ahash and keep that. This not only enables the subkeys to be destroyed immediately after deriving them, but it makes the Kerberos signing code path more efficient. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 5 +- net/sunrpc/auth_gss/gss_krb5_crypto.c | 70 +++++++++++++++++++++++++++++++ net/sunrpc/auth_gss/gss_krb5_internal.h | 4 ++ net/sunrpc/auth_gss/gss_krb5_mech.c | 37 ++++++++++++---- net/sunrpc/auth_gss/gss_krb5_seal.c | 30 +++++-------- net/sunrpc/auth_gss/gss_krb5_unseal.c | 29 ++++++------- 6 files changed, 127 insertions(+), 48 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 806df140feae..a9b29401d6d1 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -104,6 +104,8 @@ struct krb5_ctx { struct crypto_sync_skcipher *initiator_enc; struct crypto_sync_skcipher *acceptor_enc_aux; struct crypto_sync_skcipher *initiator_enc_aux; + struct crypto_ahash *acceptor_sign; + struct crypto_ahash *initiator_sign; u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */ u8 cksum[GSS_KRB5_MAX_KEYLEN]; atomic_t seq_send; @@ -112,8 +114,6 @@ struct krb5_ctx { atomic64_t confounder; siphash_key_t confkey; struct xdr_netobj mech_used; - u8 initiator_sign[GSS_KRB5_MAX_KEYLEN]; - u8 acceptor_sign[GSS_KRB5_MAX_KEYLEN]; u8 initiator_integ[GSS_KRB5_MAX_KEYLEN]; u8 acceptor_integ[GSS_KRB5_MAX_KEYLEN]; }; @@ -256,7 +256,6 @@ u32 gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset, int len, struct xdr_buf *buf); - u32 krb5_encrypt(struct crypto_sync_skcipher *key, void *iv, void *in, void *out, int length); diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 6d962079aa95..3fe16852ccd8 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -341,6 +341,76 @@ make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen, return err ? GSS_S_FAILURE : 0; } +/** + * gss_krb5_checksum - Compute the MAC for a GSS Wrap or MIC token + * @tfm: an initialized hash transform + * @header: pointer to a buffer containing the token header, or NULL + * @hdrlen: number of octets in @header + * @body: xdr_buf containing an RPC message (body.len is the message length) + * @body_offset: byte offset into @body to start checksumming + * @cksumout: OUT: a buffer to be filled in with the computed HMAC + * + * Usually expressed as H = HMAC(K, message)[1..h] . + * + * Caller provides the truncation length of the output token (h) in + * cksumout.len. + * + * Return values: + * %GSS_S_COMPLETE: Digest computed, @cksumout filled in + * %GSS_S_FAILURE: Call failed + */ +u32 +gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, + const struct xdr_buf *body, int body_offset, + struct xdr_netobj *cksumout) +{ + struct ahash_request *req; + int err = -ENOMEM; + u8 *checksumdata; + + checksumdata = kmalloc(crypto_ahash_digestsize(tfm), GFP_KERNEL); + if (!checksumdata) + return GSS_S_FAILURE; + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) + goto out_free_cksum; + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); + err = crypto_ahash_init(req); + if (err) + goto out_free_ahash; + + /* + * Per RFC 4121 Section 4.2.4, the checksum is performed over the + * data body first, then over the octets in "header". + */ + err = xdr_process_buf(body, body_offset, body->len - body_offset, + checksummer, req); + if (err) + goto out_free_ahash; + if (header) { + struct scatterlist sg[1]; + + sg_init_one(sg, header, hdrlen); + ahash_request_set_crypt(req, sg, NULL, hdrlen); + err = crypto_ahash_update(req); + if (err) + goto out_free_ahash; + } + + ahash_request_set_crypt(req, NULL, checksumdata, 0); + err = crypto_ahash_final(req); + if (err) + goto out_free_ahash; + memcpy(cksumout->data, checksumdata, cksumout->len); + +out_free_ahash: + ahash_request_free(req); +out_free_cksum: + kfree_sensitive(checksumdata); + return err ? GSS_S_FAILURE : GSS_S_COMPLETE; +} + struct encryptor_desc { u8 iv[GSS_KRB5_MAX_BLOCKSIZE]; struct skcipher_request *req; diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index 6249124aba1d..c7ebaf964483 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -10,4 +10,8 @@ void krb5_make_confounder(struct krb5_ctx *kctx, u8 *p, int conflen); +u32 gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, + const struct xdr_buf *body, int body_offset, + struct xdr_netobj *cksumout); + #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index ba3cfcb2c7c5..0b8ed365a7cb 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -347,6 +347,21 @@ context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask) return -EINVAL; } +static struct crypto_ahash * +gss_krb5_alloc_hash_v2(struct krb5_ctx *kctx, const struct xdr_netobj *key) +{ + struct crypto_ahash *tfm; + + tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm)) + return NULL; + if (crypto_ahash_setkey(tfm, key->data, key->len)) { + crypto_free_ahash(tfm); + return NULL; + } + return tfm; +} + static int context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) { @@ -414,23 +429,21 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) /* initiator sign checksum */ set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); - keyout.data = ctx->initiator_sign; err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) { - dprintk("%s: Error %d deriving initiator_sign key\n", - __func__, err); + if (err) + goto out_free; + ctx->initiator_sign = gss_krb5_alloc_hash_v2(ctx, &keyout); + if (ctx->initiator_sign == NULL) goto out_free; - } /* acceptor sign checksum */ set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM); - keyout.data = ctx->acceptor_sign; err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) { - dprintk("%s: Error %d deriving acceptor_sign key\n", - __func__, err); + if (err) + goto out_free; + ctx->acceptor_sign = gss_krb5_alloc_hash_v2(ctx, &keyout); + if (ctx->acceptor_sign == NULL) goto out_free; - } /* initiator seal integrity */ set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); @@ -458,6 +471,8 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) return ret; out_free: + crypto_free_ahash(ctx->acceptor_sign); + crypto_free_ahash(ctx->initiator_sign); crypto_free_sync_skcipher(ctx->acceptor_enc_aux); crypto_free_sync_skcipher(ctx->acceptor_enc); crypto_free_sync_skcipher(ctx->initiator_enc_aux); @@ -583,6 +598,8 @@ gss_delete_sec_context_kerberos(void *internal_ctx) { crypto_free_sync_skcipher(kctx->initiator_enc); crypto_free_sync_skcipher(kctx->acceptor_enc_aux); crypto_free_sync_skcipher(kctx->initiator_enc_aux); + crypto_free_ahash(kctx->acceptor_sign); + crypto_free_ahash(kctx->initiator_sign); kfree(kctx->mech_used.data); kfree(kctx); } diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index 33061417ec97..1d6f8a345354 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c @@ -65,6 +65,8 @@ #include #include +#include "gss_krb5_internal.h" + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif @@ -166,14 +168,14 @@ static u32 gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, struct xdr_netobj *token) { - char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; - struct xdr_netobj cksumobj = { .len = sizeof(cksumdata), - .data = cksumdata}; + struct crypto_ahash *tfm = ctx->initiate ? + ctx->initiator_sign : ctx->acceptor_sign; + struct xdr_netobj cksumobj = { + .len = ctx->gk5e->cksumlength, + }; + __be64 seq_send_be64; void *krb5_hdr; time64_t now; - u8 *cksumkey; - unsigned int cksum_usage; - __be64 seq_send_be64; dprintk("RPC: %s\n", __func__); @@ -184,22 +186,12 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, seq_send_be64 = cpu_to_be64(atomic64_fetch_inc(&ctx->seq_send64)); memcpy(krb5_hdr + 8, (char *) &seq_send_be64, 8); - if (ctx->initiate) { - cksumkey = ctx->initiator_sign; - cksum_usage = KG_USAGE_INITIATOR_SIGN; - } else { - cksumkey = ctx->acceptor_sign; - cksum_usage = KG_USAGE_ACCEPTOR_SIGN; - } - - if (make_checksum_v2(ctx, krb5_hdr, GSS_KRB5_TOK_HDR_LEN, - text, 0, cksumkey, cksum_usage, &cksumobj)) + cksumobj.data = krb5_hdr + GSS_KRB5_TOK_HDR_LEN; + if (gss_krb5_checksum(tfm, krb5_hdr, GSS_KRB5_TOK_HDR_LEN, + text, 0, &cksumobj)) return GSS_S_FAILURE; - memcpy(krb5_hdr + GSS_KRB5_TOK_HDR_LEN, cksumobj.data, cksumobj.len); - now = ktime_get_real_seconds(); - return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; } diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c index ba04e3ec970a..d52103f1203b 100644 --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c @@ -57,11 +57,14 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#include #include #include #include #include +#include "gss_krb5_internal.h" + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif @@ -146,16 +149,18 @@ static u32 gss_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, struct xdr_netobj *read_token) { + struct crypto_ahash *tfm = ctx->initiate ? + ctx->acceptor_sign : ctx->initiator_sign; char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; - struct xdr_netobj cksumobj = {.len = sizeof(cksumdata), - .data = cksumdata}; - time64_t now; + struct xdr_netobj cksumobj = { + .len = ctx->gk5e->cksumlength, + .data = cksumdata, + }; u8 *ptr = read_token->data; - u8 *cksumkey; + __be16 be16_ptr; + time64_t now; u8 flags; int i; - unsigned int cksum_usage; - __be16 be16_ptr; dprintk("RPC: %s\n", __func__); @@ -177,16 +182,8 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, if (ptr[i] != 0xff) return GSS_S_DEFECTIVE_TOKEN; - if (ctx->initiate) { - cksumkey = ctx->acceptor_sign; - cksum_usage = KG_USAGE_ACCEPTOR_SIGN; - } else { - cksumkey = ctx->initiator_sign; - cksum_usage = KG_USAGE_INITIATOR_SIGN; - } - - if (make_checksum_v2(ctx, ptr, GSS_KRB5_TOK_HDR_LEN, message_buffer, 0, - cksumkey, cksum_usage, &cksumobj)) + if (gss_krb5_checksum(tfm, ptr, GSS_KRB5_TOK_HDR_LEN, + message_buffer, 0, &cksumobj)) return GSS_S_FAILURE; if (memcmp(cksumobj.data, ptr + GSS_KRB5_TOK_HDR_LEN, From patchwork Fri Jan 13 15:22:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100950 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5CB5C54EBD for ; Fri, 13 Jan 2023 15:30:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230251AbjAMPaI (ORCPT ); Fri, 13 Jan 2023 10:30:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229503AbjAMP2d (ORCPT ); Fri, 13 Jan 2023 10:28:33 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 770B889BEA for ; Fri, 13 Jan 2023 07:22:26 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7F3AA621D2 for ; Fri, 13 Jan 2023 15:22:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA9D9C433F0; Fri, 13 Jan 2023 15:22:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623345; bh=WnjailKbHeCriGgFbZFIF8sEthneuOzxIxbGBmKQOQQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=f50iDGA51r9pg+SI5xb3hJ28sCrgiAhl9xtP7CnED+pQmU8lAIXYmFTF/2s9extp/ wF/gqOqNApBElAvuqUHdgd7m6xJedPIlaJTHpwG3IMbdrnm5FYZHkDaQAKwxZ/ikuz hZ/gOMOUc4HuPPnlcKvHrFwFRT+lheluN4q3OrGiav2HStEgRAELWclVuJwm2tdJ62 cBv3O5icXz08Dq2s35YAptNscbtBWJ6kwqesW9zlyhJyx2TAMrrD+62k27nWZyV10K HOMFsEWIiWgbGuUmNRu392Dl5OIDCGyszeKOEODGMA+zeEDv1JRBrWDwZNgv6A5knn S+W5xkSJUdp9A== Subject: [PATCH v1 09/41] SUNRPC: Obscure Kerberos integrity keys From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:24 -0500 Message-ID: <167362334479.8960.14337520339947064030.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever There's no need to keep the integrity keys around if we instead allocate and key a pair of ahashes and keep those. This not only enables the subkeys to be destroyed immediately after deriving them, but it makes the Kerberos integrity code path more efficient. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 9 +-- net/sunrpc/auth_gss/gss_krb5_crypto.c | 116 +++------------------------------ net/sunrpc/auth_gss/gss_krb5_mech.c | 22 +++--- 3 files changed, 23 insertions(+), 124 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index a9b29401d6d1..65e3c0853a0b 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -106,6 +106,8 @@ struct krb5_ctx { struct crypto_sync_skcipher *initiator_enc_aux; struct crypto_ahash *acceptor_sign; struct crypto_ahash *initiator_sign; + struct crypto_ahash *initiator_integ; + struct crypto_ahash *acceptor_integ; u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */ u8 cksum[GSS_KRB5_MAX_KEYLEN]; atomic_t seq_send; @@ -114,8 +116,6 @@ struct krb5_ctx { atomic64_t confounder; siphash_key_t confkey; struct xdr_netobj mech_used; - u8 initiator_integ[GSS_KRB5_MAX_KEYLEN]; - u8 acceptor_integ[GSS_KRB5_MAX_KEYLEN]; }; /* The length of the Kerberos GSS token header */ @@ -237,11 +237,6 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, struct xdr_buf *body, int body_offset, u8 *cksumkey, unsigned int usage, struct xdr_netobj *cksumout); -u32 -make_checksum_v2(struct krb5_ctx *, char *header, int hdrlen, - struct xdr_buf *body, int body_offset, u8 *key, - unsigned int usage, struct xdr_netobj *cksum); - u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *, struct xdr_netobj *); diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 3fe16852ccd8..3ffe66779fb7 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -254,93 +254,6 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, return err ? GSS_S_FAILURE : 0; } -/* - * checksum the plaintext data and hdrlen bytes of the token header - * Per rfc4121, sec. 4.2.4, the checksum is performed over the data - * body then over the first 16 octets of the MIC token - * Inclusion of the header data in the calculation of the - * checksum is optional. - */ -u32 -make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen, - struct xdr_buf *body, int body_offset, u8 *cksumkey, - unsigned int usage, struct xdr_netobj *cksumout) -{ - struct crypto_ahash *tfm; - struct ahash_request *req; - struct scatterlist sg[1]; - int err = -1; - u8 *checksumdata; - - if (kctx->gk5e->keyed_cksum == 0) { - dprintk("%s: expected keyed hash for %s\n", - __func__, kctx->gk5e->name); - return GSS_S_FAILURE; - } - if (cksumkey == NULL) { - dprintk("%s: no key supplied for %s\n", - __func__, kctx->gk5e->name); - return GSS_S_FAILURE; - } - - checksumdata = kmalloc(GSS_KRB5_MAX_CKSUM_LEN, GFP_KERNEL); - if (!checksumdata) - return GSS_S_FAILURE; - - tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - goto out_free_cksum; - - req = ahash_request_alloc(tfm, GFP_KERNEL); - if (!req) - goto out_free_ahash; - - ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); - - err = crypto_ahash_setkey(tfm, cksumkey, kctx->gk5e->keylength); - if (err) - goto out; - - err = crypto_ahash_init(req); - if (err) - goto out; - err = xdr_process_buf(body, body_offset, body->len - body_offset, - checksummer, req); - if (err) - goto out; - if (header != NULL) { - sg_init_one(sg, header, hdrlen); - ahash_request_set_crypt(req, sg, NULL, hdrlen); - err = crypto_ahash_update(req); - if (err) - goto out; - } - ahash_request_set_crypt(req, NULL, checksumdata, 0); - err = crypto_ahash_final(req); - if (err) - goto out; - - cksumout->len = kctx->gk5e->cksumlength; - - switch (kctx->gk5e->ctype) { - case CKSUMTYPE_HMAC_SHA1_96_AES128: - case CKSUMTYPE_HMAC_SHA1_96_AES256: - /* note that this truncates the hash */ - memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength); - break; - default: - BUG(); - break; - } -out: - ahash_request_free(req); -out_free_ahash: - crypto_free_ahash(tfm); -out_free_cksum: - kfree(checksumdata); - return err ? GSS_S_FAILURE : 0; -} - /** * gss_krb5_checksum - Compute the MAC for a GSS Wrap or MIC token * @tfm: an initialized hash transform @@ -697,27 +610,24 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, { u32 err; struct xdr_netobj hmac; - u8 *cksumkey; u8 *ecptr; struct crypto_sync_skcipher *cipher, *aux_cipher; + struct crypto_ahash *ahash; int blocksize; struct page **save_pages; int nblocks, nbytes; struct encryptor_desc desc; u32 cbcbytes; - unsigned int usage; unsigned int conflen; if (kctx->initiate) { cipher = kctx->initiator_enc; aux_cipher = kctx->initiator_enc_aux; - cksumkey = kctx->initiator_integ; - usage = KG_USAGE_INITIATOR_SEAL; + ahash = kctx->initiator_integ; } else { cipher = kctx->acceptor_enc; aux_cipher = kctx->acceptor_enc_aux; - cksumkey = kctx->acceptor_integ; - usage = KG_USAGE_ACCEPTOR_SEAL; + ahash = kctx->acceptor_integ; } blocksize = crypto_sync_skcipher_blocksize(cipher); conflen = crypto_sync_skcipher_blocksize(cipher); @@ -757,9 +667,8 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, save_pages = buf->pages; buf->pages = pages; - err = make_checksum_v2(kctx, NULL, 0, buf, - offset + GSS_KRB5_TOK_HDR_LEN, - cksumkey, usage, &hmac); + err = gss_krb5_checksum(ahash, NULL, 0, buf, + offset + GSS_KRB5_TOK_HDR_LEN, &hmac); buf->pages = save_pages; if (err) return GSS_S_FAILURE; @@ -820,25 +729,22 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, { struct xdr_buf subbuf; u32 ret = 0; - u8 *cksum_key; struct crypto_sync_skcipher *cipher, *aux_cipher; + struct crypto_ahash *ahash; struct xdr_netobj our_hmac_obj; u8 our_hmac[GSS_KRB5_MAX_CKSUM_LEN]; u8 pkt_hmac[GSS_KRB5_MAX_CKSUM_LEN]; int nblocks, blocksize, cbcbytes; struct decryptor_desc desc; - unsigned int usage; if (kctx->initiate) { cipher = kctx->acceptor_enc; aux_cipher = kctx->acceptor_enc_aux; - cksum_key = kctx->acceptor_integ; - usage = KG_USAGE_ACCEPTOR_SEAL; + ahash = kctx->acceptor_integ; } else { cipher = kctx->initiator_enc; aux_cipher = kctx->initiator_enc_aux; - cksum_key = kctx->initiator_integ; - usage = KG_USAGE_INITIATOR_SEAL; + ahash = kctx->initiator_integ; } blocksize = crypto_sync_skcipher_blocksize(cipher); @@ -878,13 +784,9 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, if (ret) goto out_err; - - /* Calculate our hmac over the plaintext data */ our_hmac_obj.len = sizeof(our_hmac); our_hmac_obj.data = our_hmac; - - ret = make_checksum_v2(kctx, NULL, 0, &subbuf, 0, - cksum_key, usage, &our_hmac_obj); + ret = gss_krb5_checksum(ahash, NULL, 0, &subbuf, 0, &our_hmac_obj); if (ret) goto out_err; diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 0b8ed365a7cb..d7307a267b20 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -447,23 +447,21 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) /* initiator seal integrity */ set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); - keyout.data = ctx->initiator_integ; err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) { - dprintk("%s: Error %d deriving initiator_integ key\n", - __func__, err); + if (err) + goto out_free; + ctx->initiator_integ = gss_krb5_alloc_hash_v2(ctx, &keyout); + if (ctx->initiator_integ == NULL) goto out_free; - } /* acceptor seal integrity */ set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY); - keyout.data = ctx->acceptor_integ; err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) { - dprintk("%s: Error %d deriving acceptor_integ key\n", - __func__, err); + if (err) + goto out_free; + ctx->acceptor_integ = gss_krb5_alloc_hash_v2(ctx, &keyout); + if (ctx->acceptor_integ == NULL) goto out_free; - } ret = 0; out: @@ -471,6 +469,8 @@ context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) return ret; out_free: + crypto_free_ahash(ctx->acceptor_integ); + crypto_free_ahash(ctx->initiator_integ); crypto_free_ahash(ctx->acceptor_sign); crypto_free_ahash(ctx->initiator_sign); crypto_free_sync_skcipher(ctx->acceptor_enc_aux); @@ -600,6 +600,8 @@ gss_delete_sec_context_kerberos(void *internal_ctx) { crypto_free_sync_skcipher(kctx->initiator_enc_aux); crypto_free_ahash(kctx->acceptor_sign); crypto_free_ahash(kctx->initiator_sign); + crypto_free_ahash(kctx->acceptor_integ); + crypto_free_ahash(kctx->initiator_integ); kfree(kctx->mech_used.data); kfree(kctx); } From patchwork Fri Jan 13 15:22:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100951 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5CC9DC54EBE for ; Fri, 13 Jan 2023 15:30:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229986AbjAMPaa (ORCPT ); Fri, 13 Jan 2023 10:30:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230200AbjAMP3f (ORCPT ); Fri, 13 Jan 2023 10:29:35 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F3EDBE11 for ; Fri, 13 Jan 2023 07:22:33 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id EDF076216C for ; Fri, 13 Jan 2023 15:22:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0F1A7C433EF; Fri, 13 Jan 2023 15:22:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623352; bh=BKBUbvBy0hg1A87MH3KoJWhcoCG9WF1wn0Lchy3qO90=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=t2ZbRxxvN7WAto6TPY9KLVIcEecrH6ZdYx6TldkzuPmQc9y3zPVaeZojq/eWU8ohQ Rkc2628l+55uWC2s2iVnYkXIFrvuIy8t9peyonA6bhjTVxFk5LuzBD7xhJogpd6+/H IM8EZXu3UjjXUJmnul/rBkyu1zDn+W7uJN+bGhLfG/lnouOSDy6Q9ldzH59koW+8PZ xqje0LiVtcaTqQkb61/RCSeEFyaQRqQbG6092RzoXc7cu0ZbIaHhPLu17PloluS0Ex D3XMSj9oQuK2UBPuZAmaHcJSBd4DSBjekkKPYXY7yCPCMFDXa3VDvK9Aw91fysSHSL TH3mbpU0898BQ== Subject: [PATCH v1 10/41] SUNRPC: Refactor the GSS-API Per Message calls in the Kerberos mechanism From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:31 -0500 Message-ID: <167362335112.8960.4943467133115111378.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Replace a number of switches on encryption type so that all of them don't have to be modified when adding or removing support for an enctype. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 23 ++---- net/sunrpc/auth_gss/gss_krb5_internal.h | 30 +++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 126 ++++++++++++++++++++++++++++--- net/sunrpc/auth_gss/gss_krb5_seal.c | 30 +------ net/sunrpc/auth_gss/gss_krb5_unseal.c | 31 +------- net/sunrpc/auth_gss/gss_krb5_wrap.c | 66 +++------------- 6 files changed, 180 insertions(+), 126 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 65e3c0853a0b..81f4bea7888a 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -86,6 +86,15 @@ struct gss_krb5_enctype { u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset, u32 len, struct xdr_buf *buf, u32 *headskip, u32 *tailskip); /* v2 decryption function */ + u32 (*get_mic)(struct krb5_ctx *kctx, struct xdr_buf *text, + struct xdr_netobj *token); + u32 (*verify_mic)(struct krb5_ctx *kctx, struct xdr_buf *message_buffer, + struct xdr_netobj *read_token); + u32 (*wrap)(struct krb5_ctx *kctx, int offset, + struct xdr_buf *buf, struct page **pages); + u32 (*unwrap)(struct krb5_ctx *kctx, int offset, int len, + struct xdr_buf *buf, unsigned int *slack, + unsigned int *align); }; /* krb5_ctx flags definitions */ @@ -237,20 +246,6 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, struct xdr_buf *body, int body_offset, u8 *cksumkey, unsigned int usage, struct xdr_netobj *cksumout); -u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *, - struct xdr_netobj *); - -u32 gss_verify_mic_kerberos(struct gss_ctx *, struct xdr_buf *, - struct xdr_netobj *); - -u32 -gss_wrap_kerberos(struct gss_ctx *ctx_id, int offset, - struct xdr_buf *outbuf, struct page **pages); - -u32 -gss_unwrap_kerberos(struct gss_ctx *ctx_id, int offset, int len, - struct xdr_buf *buf); - u32 krb5_encrypt(struct crypto_sync_skcipher *key, void *iv, void *in, void *out, int length); diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index c7ebaf964483..c6420f9a6c4e 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -8,6 +8,36 @@ #ifndef _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H #define _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H +/* + * GSS Kerberos 5 mechanism Per-Message calls. + */ + +u32 gss_krb5_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, + struct xdr_netobj *token); +u32 gss_krb5_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, + struct xdr_netobj *token); + +u32 gss_krb5_verify_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, + struct xdr_netobj *read_token); +u32 gss_krb5_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, + struct xdr_netobj *read_token); + +u32 gss_krb5_wrap_v1(struct krb5_ctx *kctx, int offset, + struct xdr_buf *buf, struct page **pages); +u32 gss_krb5_wrap_v2(struct krb5_ctx *kctx, int offset, + struct xdr_buf *buf, struct page **pages); + +u32 gss_krb5_unwrap_v1(struct krb5_ctx *kctx, int offset, int len, + struct xdr_buf *buf, unsigned int *slack, + unsigned int *align); +u32 gss_krb5_unwrap_v2(struct krb5_ctx *kctx, int offset, int len, + struct xdr_buf *buf, unsigned int *slack, + unsigned int *align); + +/* + * Implementation internal functions + */ + void krb5_make_confounder(struct krb5_ctx *kctx, u8 *p, int conflen); u32 gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index d7307a267b20..921f1a00fc9d 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -22,6 +22,7 @@ #include #include "auth_gss_internal.h" +#include "gss_krb5_internal.h" #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH @@ -43,6 +44,10 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, .mk_key = NULL, + .get_mic = gss_krb5_get_mic_v1, + .verify_mic = gss_krb5_verify_mic_v1, + .wrap = gss_krb5_wrap_v1, + .unwrap = gss_krb5_unwrap_v1, .signalg = SGN_ALG_DES_MAC_MD5, .sealalg = SEAL_ALG_DES, .keybytes = 7, @@ -63,6 +68,10 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, .mk_key = gss_krb5_des3_make_key, + .get_mic = gss_krb5_get_mic_v1, + .verify_mic = gss_krb5_verify_mic_v1, + .wrap = gss_krb5_wrap_v1, + .unwrap = gss_krb5_unwrap_v1, .signalg = SGN_ALG_HMAC_SHA1_DES3_KD, .sealalg = SEAL_ALG_DES3KD, .keybytes = 21, @@ -85,6 +94,12 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .mk_key = gss_krb5_aes_make_key, .encrypt_v2 = gss_krb5_aes_encrypt, .decrypt_v2 = gss_krb5_aes_decrypt, + + .get_mic = gss_krb5_get_mic_v2, + .verify_mic = gss_krb5_verify_mic_v2, + .wrap = gss_krb5_wrap_v2, + .unwrap = gss_krb5_unwrap_v2, + .signalg = -1, .sealalg = -1, .keybytes = 16, @@ -107,6 +122,12 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .mk_key = gss_krb5_aes_make_key, .encrypt_v2 = gss_krb5_aes_encrypt, .decrypt_v2 = gss_krb5_aes_decrypt, + + .get_mic = gss_krb5_get_mic_v2, + .verify_mic = gss_krb5_verify_mic_v2, + .wrap = gss_krb5_wrap_v2, + .unwrap = gss_krb5_unwrap_v2, + .signalg = -1, .sealalg = -1, .keybytes = 32, @@ -557,10 +578,8 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, } static int -gss_import_sec_context_kerberos(const void *p, size_t len, - struct gss_ctx *ctx_id, - time64_t *endtime, - gfp_t gfp_mask) +gss_krb5_import_sec_context(const void *p, size_t len, struct gss_ctx *ctx_id, + time64_t *endtime, gfp_t gfp_mask) { const void *end = (const void *)((const char *)p + len); struct krb5_ctx *ctx; @@ -589,7 +608,8 @@ gss_import_sec_context_kerberos(const void *p, size_t len, } static void -gss_delete_sec_context_kerberos(void *internal_ctx) { +gss_krb5_delete_sec_context(void *internal_ctx) +{ struct krb5_ctx *kctx = internal_ctx; crypto_free_sync_skcipher(kctx->seq); @@ -606,13 +626,97 @@ gss_delete_sec_context_kerberos(void *internal_ctx) { kfree(kctx); } +/** + * gss_krb5_get_mic - get_mic for the Kerberos GSS mechanism + * @gctx: GSS context + * @text: plaintext to checksum + * @token: buffer into which to write the computed checksum + * + * Return values: + * %GSS_S_COMPLETE - success, and @token is filled in + * %GSS_S_FAILURE - checksum could not be generated + * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid + */ +static u32 gss_krb5_get_mic(struct gss_ctx *gctx, struct xdr_buf *text, + struct xdr_netobj *token) +{ + struct krb5_ctx *kctx = gctx->internal_ctx_id; + + return kctx->gk5e->get_mic(kctx, text, token); +} + +/** + * gss_krb5_verify_mic - verify_mic for the Kerberos GSS mechanism + * @gctx: GSS context + * @message_buffer: plaintext to check + * @read_token: received checksum to check + * + * Return values: + * %GSS_S_COMPLETE - computed and received checksums match + * %GSS_S_DEFECTIVE_TOKEN - received checksum is not valid + * %GSS_S_BAD_SIG - computed and received checksums do not match + * %GSS_S_FAILURE - received checksum could not be checked + * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid + */ +static u32 gss_krb5_verify_mic(struct gss_ctx *gctx, + struct xdr_buf *message_buffer, + struct xdr_netobj *read_token) +{ + struct krb5_ctx *kctx = gctx->internal_ctx_id; + + return kctx->gk5e->verify_mic(kctx, message_buffer, read_token); +} + +/** + * gss_krb5_wrap - gss_wrap for the Kerberos GSS mechanism + * @gctx: initialized GSS context + * @offset: byte offset in @buf to start writing the cipher text + * @buf: OUT: send buffer + * @pages: plaintext to wrap + * + * Return values: + * %GSS_S_COMPLETE - success, @buf has been updated + * %GSS_S_FAILURE - @buf could not be wrapped + * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid + */ +static u32 gss_krb5_wrap(struct gss_ctx *gctx, int offset, + struct xdr_buf *buf, struct page **pages) +{ + struct krb5_ctx *kctx = gctx->internal_ctx_id; + + return kctx->gk5e->wrap(kctx, offset, buf, pages); +} + +/** + * gss_krb5_unwrap - gss_unwrap for the Kerberos GSS mechanism + * @gctx: initialized GSS context + * @offset: starting byte offset into @buf + * @len: size of ciphertext to unwrap + * @buf: ciphertext to unwrap + * + * Return values: + * %GSS_S_COMPLETE - success, @buf has been updated + * %GSS_S_DEFECTIVE_TOKEN - received blob is not valid + * %GSS_S_BAD_SIG - computed and received checksums do not match + * %GSS_S_FAILURE - @buf could not be unwrapped + * %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid + */ +static u32 gss_krb5_unwrap(struct gss_ctx *gctx, int offset, + int len, struct xdr_buf *buf) +{ + struct krb5_ctx *kctx = gctx->internal_ctx_id; + + return kctx->gk5e->unwrap(kctx, offset, len, buf, + &gctx->slack, &gctx->align); +} + static const struct gss_api_ops gss_kerberos_ops = { - .gss_import_sec_context = gss_import_sec_context_kerberos, - .gss_get_mic = gss_get_mic_kerberos, - .gss_verify_mic = gss_verify_mic_kerberos, - .gss_wrap = gss_wrap_kerberos, - .gss_unwrap = gss_unwrap_kerberos, - .gss_delete_sec_context = gss_delete_sec_context_kerberos, + .gss_import_sec_context = gss_krb5_import_sec_context, + .gss_get_mic = gss_krb5_get_mic, + .gss_verify_mic = gss_krb5_verify_mic, + .gss_wrap = gss_krb5_wrap, + .gss_unwrap = gss_krb5_unwrap, + .gss_delete_sec_context = gss_krb5_delete_sec_context, }; static struct pf_desc gss_kerberos_pfs[] = { diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index 1d6f8a345354..f74125407588 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c @@ -125,9 +125,9 @@ setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token) return krb5_hdr; } -static u32 -gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, - struct xdr_netobj *token) +u32 +gss_krb5_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, + struct xdr_netobj *token) { char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; struct xdr_netobj md5cksum = {.len = sizeof(cksumdata), @@ -164,9 +164,9 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; } -static u32 -gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, - struct xdr_netobj *token) +u32 +gss_krb5_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, + struct xdr_netobj *token) { struct crypto_ahash *tfm = ctx->initiate ? ctx->initiator_sign : ctx->acceptor_sign; @@ -194,21 +194,3 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, now = ktime_get_real_seconds(); return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; } - -u32 -gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text, - struct xdr_netobj *token) -{ - struct krb5_ctx *ctx = gss_ctx->internal_ctx_id; - - switch (ctx->enctype) { - default: - BUG(); - case ENCTYPE_DES_CBC_RAW: - case ENCTYPE_DES3_CBC_RAW: - return gss_get_mic_v1(ctx, text, token); - case ENCTYPE_AES128_CTS_HMAC_SHA1_96: - case ENCTYPE_AES256_CTS_HMAC_SHA1_96: - return gss_get_mic_v2(ctx, text, token); - } -} diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c index d52103f1203b..939d199eb7b7 100644 --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c @@ -73,9 +73,9 @@ /* read_token is a mic token, and message_buffer is the data that the mic was * supposedly taken over. */ -static u32 -gss_verify_mic_v1(struct krb5_ctx *ctx, - struct xdr_buf *message_buffer, struct xdr_netobj *read_token) +u32 +gss_krb5_verify_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, + struct xdr_netobj *read_token) { int signalg; int sealalg; @@ -145,9 +145,9 @@ gss_verify_mic_v1(struct krb5_ctx *ctx, return GSS_S_COMPLETE; } -static u32 -gss_verify_mic_v2(struct krb5_ctx *ctx, - struct xdr_buf *message_buffer, struct xdr_netobj *read_token) +u32 +gss_krb5_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, + struct xdr_netobj *read_token) { struct crypto_ahash *tfm = ctx->initiate ? ctx->acceptor_sign : ctx->initiator_sign; @@ -202,22 +202,3 @@ gss_verify_mic_v2(struct krb5_ctx *ctx, return GSS_S_COMPLETE; } - -u32 -gss_verify_mic_kerberos(struct gss_ctx *gss_ctx, - struct xdr_buf *message_buffer, - struct xdr_netobj *read_token) -{ - struct krb5_ctx *ctx = gss_ctx->internal_ctx_id; - - switch (ctx->enctype) { - default: - BUG(); - case ENCTYPE_DES_CBC_RAW: - case ENCTYPE_DES3_CBC_RAW: - return gss_verify_mic_v1(ctx, message_buffer, read_token); - case ENCTYPE_AES128_CTS_HMAC_SHA1_96: - case ENCTYPE_AES256_CTS_HMAC_SHA1_96: - return gss_verify_mic_v2(ctx, message_buffer, read_token); - } -} diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 374214f3c463..57085bdec053 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -122,9 +122,9 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize) /* XXX factor out common code with seal/unseal. */ -static u32 -gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset, - struct xdr_buf *buf, struct page **pages) +u32 +gss_krb5_wrap_v1(struct krb5_ctx *kctx, int offset, + struct xdr_buf *buf, struct page **pages) { char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; struct xdr_netobj md5cksum = {.len = sizeof(cksumdata), @@ -211,10 +211,10 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset, return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; } -static u32 -gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, int len, - struct xdr_buf *buf, unsigned int *slack, - unsigned int *align) +u32 +gss_krb5_unwrap_v1(struct krb5_ctx *kctx, int offset, int len, + struct xdr_buf *buf, unsigned int *slack, + unsigned int *align) { int signalg; int sealalg; @@ -373,9 +373,9 @@ static void rotate_left(u32 base, struct xdr_buf *buf, unsigned int shift) _rotate_left(&subbuf, shift); } -static u32 -gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset, - struct xdr_buf *buf, struct page **pages) +u32 +gss_krb5_wrap_v2(struct krb5_ctx *kctx, int offset, + struct xdr_buf *buf, struct page **pages) { u8 *ptr; time64_t now; @@ -424,10 +424,10 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset, return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; } -static u32 -gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len, - struct xdr_buf *buf, unsigned int *slack, - unsigned int *align) +u32 +gss_krb5_unwrap_v2(struct krb5_ctx *kctx, int offset, int len, + struct xdr_buf *buf, unsigned int *slack, + unsigned int *align) { time64_t now; u8 *ptr; @@ -524,41 +524,3 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len, *slack = *align + XDR_QUADLEN(ec + GSS_KRB5_TOK_HDR_LEN + tailskip); return GSS_S_COMPLETE; } - -u32 -gss_wrap_kerberos(struct gss_ctx *gctx, int offset, - struct xdr_buf *buf, struct page **pages) -{ - struct krb5_ctx *kctx = gctx->internal_ctx_id; - - switch (kctx->enctype) { - default: - BUG(); - case ENCTYPE_DES_CBC_RAW: - case ENCTYPE_DES3_CBC_RAW: - return gss_wrap_kerberos_v1(kctx, offset, buf, pages); - case ENCTYPE_AES128_CTS_HMAC_SHA1_96: - case ENCTYPE_AES256_CTS_HMAC_SHA1_96: - return gss_wrap_kerberos_v2(kctx, offset, buf, pages); - } -} - -u32 -gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, - int len, struct xdr_buf *buf) -{ - struct krb5_ctx *kctx = gctx->internal_ctx_id; - - switch (kctx->enctype) { - default: - BUG(); - case ENCTYPE_DES_CBC_RAW: - case ENCTYPE_DES3_CBC_RAW: - return gss_unwrap_kerberos_v1(kctx, offset, len, buf, - &gctx->slack, &gctx->align); - case ENCTYPE_AES128_CTS_HMAC_SHA1_96: - case ENCTYPE_AES256_CTS_HMAC_SHA1_96: - return gss_unwrap_kerberos_v2(kctx, offset, len, buf, - &gctx->slack, &gctx->align); - } -} From patchwork Fri Jan 13 15:22:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100952 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FE92C54EBE for ; Fri, 13 Jan 2023 15:30:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229618AbjAMPam (ORCPT ); Fri, 13 Jan 2023 10:30:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230253AbjAMPaE (ORCPT ); Fri, 13 Jan 2023 10:30:04 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9F37B7A90B for ; Fri, 13 Jan 2023 07:22:39 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3B505620D6 for ; Fri, 13 Jan 2023 15:22:39 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6323AC433EF; Fri, 13 Jan 2023 15:22:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623358; bh=wOiKBrpJB3aPxP5V8CaNiybN7RFPAaTEoDSvVSkFKaA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=m2jcA6nlCuLA0PAQwseB9UXUY/amdjrI8W9MyTPbahqkmT8gJG8UUoYQ5fwuCqPvn DhKPPhkxadvoqSzD5zW73JfC3pFNYVmOWvbAXrFAtTOQjyHEwJmwA1XDpYzAi0eq5z EjqvT96TxySpuYW+4PYAKHkLN6kTAK6/fnYQrQ+fATZcwqbq+CJ498jGPN2EZBapt4 DVCx+Xz0fam3RNU3n7Nn4H3Kr0Rgi+bakzSUoQkqiqqe/kRzMKqEEud1gE6moaVPeS O1jG0YWinUbkakF+fdMz1sUSnzWkRXbFK3J5ZK9REyg3gwcMbTTicP0kmiUDBbj8Ya XfLvJxJFW5Diw== Subject: [PATCH v1 11/41] SUNRPC: Remove another switch on ctx->enctype From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:37 -0500 Message-ID: <167362335753.8960.11613211961341629098.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Replace another switch on encryption type so that it does not have to be modified when adding or removing support for an enctype. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 1 + net/sunrpc/auth_gss/gss_krb5_mech.c | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 81f4bea7888a..00305a967dee 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -77,6 +77,7 @@ struct gss_krb5_enctype { u32 (*decrypt) (struct crypto_sync_skcipher *tfm, void *iv, void *in, void *out, int length); /* decryption function */ + int (*import_ctx)(struct krb5_ctx *ctx, gfp_t gfp_mask); u32 (*mk_key) (const struct gss_krb5_enctype *gk5e, struct xdr_netobj *in, struct xdr_netobj *out); /* complete key generation */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 921f1a00fc9d..4986435e9b92 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -28,7 +28,11 @@ # define RPCDBG_FACILITY RPCDBG_AUTH #endif -static struct gss_api_mech gss_kerberos_mech; /* forward declaration */ +static struct gss_api_mech gss_kerberos_mech; + +static int gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask); +static int gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask); +static int gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask); static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { #ifndef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES @@ -43,6 +47,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksum_name = "md5", .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, + .import_ctx = gss_krb5_import_ctx_des, .mk_key = NULL, .get_mic = gss_krb5_get_mic_v1, .verify_mic = gss_krb5_verify_mic_v1, @@ -67,6 +72,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksum_name = "hmac(sha1)", .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, + .import_ctx = gss_krb5_import_ctx_v1, .mk_key = gss_krb5_des3_make_key, .get_mic = gss_krb5_get_mic_v1, .verify_mic = gss_krb5_verify_mic_v1, @@ -91,6 +97,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksum_name = "hmac(sha1)", .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, + .import_ctx = gss_krb5_import_ctx_v2, .mk_key = gss_krb5_aes_make_key, .encrypt_v2 = gss_krb5_aes_encrypt, .decrypt_v2 = gss_krb5_aes_decrypt, @@ -119,6 +126,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksum_name = "hmac(sha1)", .encrypt = krb5_encrypt, .decrypt = krb5_decrypt, + .import_ctx = gss_krb5_import_ctx_v2, .mk_key = gss_krb5_aes_make_key, .encrypt_v2 = gss_krb5_aes_encrypt, .decrypt_v2 = gss_krb5_aes_decrypt, @@ -324,7 +332,13 @@ set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed) } static int -context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask) +gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask) +{ + return -EINVAL; +} + +static int +gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask) { struct xdr_netobj c, keyin, keyout; u8 cdata[GSS_KRB5_K5CLENGTH]; @@ -384,7 +398,7 @@ gss_krb5_alloc_hash_v2(struct krb5_ctx *kctx, const struct xdr_netobj *key) } static int -context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) +gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) { u8 cdata[GSS_KRB5_K5CLENGTH]; struct xdr_netobj c = { @@ -563,15 +577,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, } ctx->mech_used.len = gss_kerberos_mech.gm_oid.len; - switch (ctx->enctype) { - case ENCTYPE_DES3_CBC_RAW: - return context_derive_keys_des3(ctx, gfp_mask); - case ENCTYPE_AES128_CTS_HMAC_SHA1_96: - case ENCTYPE_AES256_CTS_HMAC_SHA1_96: - return context_derive_keys_new(ctx, gfp_mask); - default: - return -EINVAL; - } + return ctx->gk5e->import_ctx(ctx, gfp_mask); out_err: return PTR_ERR(p); From patchwork Fri Jan 13 15:22:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100953 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6563C54EBD for ; Fri, 13 Jan 2023 15:30:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230262AbjAMPar (ORCPT ); Fri, 13 Jan 2023 10:30:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230260AbjAMPaJ (ORCPT ); Fri, 13 Jan 2023 10:30:09 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 081C510EA for ; Fri, 13 Jan 2023 07:22:47 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 55BC6B8217A for ; Fri, 13 Jan 2023 15:22:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8A65C433F0; Fri, 13 Jan 2023 15:22:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623364; bh=AAKF2h49CkAzEC5hAJhxvkm51RZupkaiVZQfgHEyap8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=mkeHwQAEijJeXFhDpsMyFuEQzNYt1ULvCBepzXJ5fbDUp7qDPIfA5kdEoBFlxCO/L Y6YGm9Yfthy5u9D4b/74YsFtG45ujpX0YnspPfM2MpWahu9Po+0E1MRnEiGFlcO0j3 2XSBH5DUCufP1uD5dnRW7lKo5pi0xTaoRphIg03tczhwxmpwey+sLEhRud0VBfmcse mxTnoSWjXim6t2UT2ew0O6PDJZl/VzvuNn8K67lMUSUd5j2/zYvqkqnpa17Ts3tFLf HcA5LRKD3n6W5bOB+S2pEK2Eg8X0ntoEflJSXWFeuxEwd2AGBbPSPUJL03xABM+6sy 7JgW3vbqA7THw== Subject: [PATCH v1 12/41] SUNRPC: Add /proc/net/rpc/gss_krb5_enctypes file From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:43 -0500 Message-ID: <167362336382.8960.2076097967542181718.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever I would like to replace the KRB5_SUPPORTED_ENCTYPES macro so that there is finer granularity about what enctype support is built in to the kernel and then advertised by it. The /proc/fs/nfsd/supported_krb5_enctypes file is a legacy API that advertises supported enctypes to rpc.svcgssd (I think?). It simply prints the value of the KRB5_SUPPORTED_ENCTYPES macro, so it will need to be replaced with something that can instead display exactly which enctypes are configured and built into the SunRPC layer. Completely decommissioning such APIs is hard. Instead, add a file that is managed by SunRPC's GSS Kerberos mechanism, which is authoritative about enctype support status. A subsequent patch will replace /proc/fs/nfsd/supported_krb5_enctypes with a symlink to this new file. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/svcauth_gss.c | 65 +++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 28e977c89a5a..19f0190a0b97 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1494,6 +1494,55 @@ static void destroy_use_gss_proxy_proc_entry(struct net *net) clear_gssp_clnt(sn); } } + +static ssize_t read_gss_krb5_enctypes(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct rpcsec_gss_oid oid = { + .len = 9, + .data = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", + }; + struct gss_api_mech *mech; + ssize_t ret; + + mech = gss_mech_get_by_OID(&oid); + if (!mech) + return 0; + if (!mech->gm_upcall_enctypes) { + gss_mech_put(mech); + return 0; + } + + ret = simple_read_from_buffer(buf, count, ppos, + mech->gm_upcall_enctypes, + strlen(mech->gm_upcall_enctypes)); + gss_mech_put(mech); + return ret; +} + +static const struct proc_ops gss_krb5_enctypes_proc_ops = { + .proc_open = nonseekable_open, + .proc_read = read_gss_krb5_enctypes, +}; + +static int create_krb5_enctypes_proc_entry(struct net *net) +{ + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); + + if (!proc_create_data("gss_krb5_enctypes", S_IFREG | 0444, + sn->proc_net_rpc, + &gss_krb5_enctypes_proc_ops, net)) + return -ENOMEM; + return 0; +} + +static void destroy_krb5_enctypes_proc_entry(struct net *net) +{ + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); + + remove_proc_entry("gss_krb5_enctypes", sn->proc_net_rpc); +} + #else /* CONFIG_PROC_FS */ static int create_use_gss_proxy_proc_entry(struct net *net) @@ -1503,6 +1552,13 @@ static int create_use_gss_proxy_proc_entry(struct net *net) static void destroy_use_gss_proxy_proc_entry(struct net *net) {} +static int create_krb5_enctypes_proc_entry(struct net *net) +{ + return 0; +} + +static void destroy_krb5_enctypes_proc_entry(struct net *net) {} + #endif /* CONFIG_PROC_FS */ /* @@ -2042,7 +2098,15 @@ gss_svc_init_net(struct net *net) rv = create_use_gss_proxy_proc_entry(net); if (rv) goto out2; + + rv = create_krb5_enctypes_proc_entry(net); + if (rv) + goto out3; + return 0; + +out3: + destroy_use_gss_proxy_proc_entry(net); out2: rsi_cache_destroy_net(net); out1: @@ -2053,6 +2117,7 @@ gss_svc_init_net(struct net *net) void gss_svc_shutdown_net(struct net *net) { + destroy_krb5_enctypes_proc_entry(net); destroy_use_gss_proxy_proc_entry(net); rsi_cache_destroy_net(net); rsc_cache_destroy_net(net); From patchwork Fri Jan 13 15:22:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100954 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C33D8C54EBE for ; Fri, 13 Jan 2023 15:30:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229902AbjAMPat (ORCPT ); Fri, 13 Jan 2023 10:30:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229881AbjAMPaK (ORCPT ); Fri, 13 Jan 2023 10:30:10 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0401477AC8 for ; Fri, 13 Jan 2023 07:22:54 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id ADF2CB82121 for ; Fri, 13 Jan 2023 15:22:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 09A6DC433EF; Fri, 13 Jan 2023 15:22:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623371; bh=xLxVGWdwSbYolStnuWIQa4D7zd8awG8REU3pYzPYYzU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=cgH7yEw5tE3z2ffkG3jE8z4B3I8296wQo9oIZqX9iixG+UATMVOqjS8exA+N0HhIH PlkvgDJ4Q5seFk24zxXzY44oyFGi3FeRFu+aB/nCA0vEgHGu3Naw9QU+/vBPDk07d7 H79E0kLUWeEs+Eh7tazppWKEl7EbG5H2XeiNtNcnpzsItDEf02adTzEGUfFVlkINh6 QTcvft4jfQYzbbGObDvvIuDU8cjfdJEe6Ksc2vNeJKxV8bLkosHWJwl1XF2/cuhTmS DHYwjnRrUYWq5ne9txkrXXMJFZSSr0QNJTG51NEIX5xpyA9b/RkQ9hU/niqVWRkSaS +35QiQ8Eab+8Q== Subject: [PATCH v1 13/41] NFSD: Replace /proc/fs/nfsd/supported_krb5_enctypes with a symlink From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:50 -0500 Message-ID: <167362337010.8960.16891515356995944886.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Now that I've added a file under /proc/net/rpc that is managed by the SunRPC's Kerberos mechanism, replace NFSD's supported_krb5_enctypes file with a symlink to the new SunRPC proc file, which contains exactly the same content. Remarkably, commit b0b0c0a26e84 ("nfsd: add proc file listing kernel's gss_krb5 enctypes") added the nfsd_supported_krb5_enctypes file in 2011, but this file has never been documented in nfsd(7). Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- fs/nfsd/nfsctl.c | 74 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index f2a0d6ac88df..04474b8ccf0a 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -47,7 +46,6 @@ enum { NFSD_MaxBlkSize, NFSD_MaxConnections, NFSD_Filecache, - NFSD_SupportedEnctypes, /* * The below MUST come last. Otherwise we leave a hole in nfsd_files[] * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops @@ -187,16 +185,6 @@ static int export_features_show(struct seq_file *m, void *v) DEFINE_SHOW_ATTRIBUTE(export_features); -#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) -static int supported_enctypes_show(struct seq_file *m, void *v) -{ - seq_printf(m, KRB5_SUPPORTED_ENCTYPES); - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(supported_enctypes); -#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ - static const struct file_operations pool_stats_operations = { .open = nfsd_pool_stats_open, .read = seq_read, @@ -1150,6 +1138,9 @@ static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode) inode->i_op = &simple_dir_inode_operations; inc_nlink(inode); break; + case S_IFLNK: + inode->i_op = &simple_symlink_inode_operations; + break; default: break; } @@ -1195,6 +1186,59 @@ static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *nc goto out; } +#if IS_ENABLED(CONFIG_SUNRPC_GSS) +static int __nfsd_symlink(struct inode *dir, struct dentry *dentry, + umode_t mode, const char *content) +{ + struct inode *inode; + + inode = nfsd_get_inode(dir->i_sb, mode); + if (!inode) + return -ENOMEM; + + inode->i_link = (char *)content; + inode->i_size = strlen(content); + + d_add(dentry, inode); + inc_nlink(dir); + fsnotify_create(dir, dentry); + return 0; +} + +/* + * @content is assumed to be a NUL-terminated string that lives + * longer than the symlink itself. + */ +static void nfsd_symlink(struct dentry *parent, const char *name, + const char *content) +{ + struct inode *dir = parent->d_inode; + struct dentry *dentry; + int ret = -ENOMEM; + + inode_lock(dir); + dentry = d_alloc_name(parent, name); + if (!dentry) + goto out_err; + ret = __nfsd_symlink(d_inode(parent), dentry, S_IFLNK | 0777, content); + if (ret) + goto out_err; +out: + inode_unlock(dir); + return; +out_err: + dput(dentry); + dentry = ERR_PTR(ret); + goto out; +} +#else +static inline void nfsd_symlink(struct dentry *parent, const char *name, + const char *content) +{ +} + +#endif + static void clear_ncl(struct inode *inode) { struct nfsdfs_client *ncl = inode->i_private; @@ -1355,10 +1399,6 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc) [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, [NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO}, [NFSD_Filecache] = {"filecache", &nfsd_file_cache_stats_fops, S_IRUGO}, -#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) - [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", - &supported_enctypes_fops, S_IRUGO}, -#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ #ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, @@ -1371,6 +1411,8 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc) ret = simple_fill_super(sb, 0x6e667364, nfsd_files); if (ret) return ret; + nfsd_symlink(sb->s_root, "supported_krb5_enctypes", + "/proc/net/rpc/gss_krb5_enctypes"); dentry = nfsd_mkdir(sb->s_root, NULL, "clients"); if (IS_ERR(dentry)) return PTR_ERR(dentry); From patchwork Fri Jan 13 15:22:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100955 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50960C54EBD for ; Fri, 13 Jan 2023 15:30:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230023AbjAMPau (ORCPT ); Fri, 13 Jan 2023 10:30:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229669AbjAMPaK (ORCPT ); Fri, 13 Jan 2023 10:30:10 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4FDDB7EC93 for ; Fri, 13 Jan 2023 07:23:00 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id F36C4B82121 for ; Fri, 13 Jan 2023 15:22:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 57832C433D2; Fri, 13 Jan 2023 15:22:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623377; bh=v4JgldVMqv+TdODbHkrf0+pe07F9Njga7uDvxHurm+I=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=PtRSS/fkyRPxh7gUPWf2pWIIpqUPV8pG/VVTvX4N1rtlX2kHGyJBQFz7XhGeXSJNh rHAsNmmIqOuMU7Yrat8LfCwPH1uZ/WolBEojVBqGj/1rn0V9cN8SToOGfc1Ggmz6q/ bZQEek2goAZIQ03Vvcl9pCV74sRzQhX3RvxNJ8jpib0ESUaS0y5rJKRj7WZcS2a1Bw o7f53iXI3nb1NzeWo7OLdUBWpt/n7UIlvwOTjpwsM1NK8E/nLOxdDIOmLt2qPlSFKV 6gTw50BQAA+nYJIeafg207bG/qv3WZCXcG+kQUgFd8tEdKmEPT1KRxzeeBnoMicqqL JECATMrJc092w== Subject: [PATCH v1 14/41] SUNRPC: Replace KRB5_SUPPORTED_ENCTYPES macro From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:22:56 -0500 Message-ID: <167362337645.8960.2534116685918772760.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Now that all consumers of the KRB5_SUPPORTED_ENCTYPES macro are within the SunRPC layer, the macro can be replaced with something private and more flexible. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5_enctypes.h | 41 ------------------------------ net/sunrpc/auth_gss/gss_krb5_mech.c | 41 +++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 43 deletions(-) delete mode 100644 include/linux/sunrpc/gss_krb5_enctypes.h diff --git a/include/linux/sunrpc/gss_krb5_enctypes.h b/include/linux/sunrpc/gss_krb5_enctypes.h deleted file mode 100644 index 87eea679d750..000000000000 --- a/include/linux/sunrpc/gss_krb5_enctypes.h +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Define the string that exports the set of kernel-supported - * Kerberos enctypes. This list is sent via upcall to gssd, and - * is also exposed via the nfsd /proc API. The consumers generally - * treat this as an ordered list, where the first item in the list - * is the most preferred. - */ - -#ifndef _LINUX_SUNRPC_GSS_KRB5_ENCTYPES_H -#define _LINUX_SUNRPC_GSS_KRB5_ENCTYPES_H - -#ifdef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES - -/* - * NB: This list includes DES3_CBC_SHA1, which was deprecated by RFC 8429. - * - * ENCTYPE_AES256_CTS_HMAC_SHA1_96 - * ENCTYPE_AES128_CTS_HMAC_SHA1_96 - * ENCTYPE_DES3_CBC_SHA1 - */ -#define KRB5_SUPPORTED_ENCTYPES "18,17,16" - -#else /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */ - -/* - * NB: This list includes encryption types that were deprecated - * by RFC 8429 and RFC 6649. - * - * ENCTYPE_AES256_CTS_HMAC_SHA1_96 - * ENCTYPE_AES128_CTS_HMAC_SHA1_96 - * ENCTYPE_DES3_CBC_SHA1 - * ENCTYPE_DES_CBC_MD5 - * ENCTYPE_DES_CBC_CRC - * ENCTYPE_DES_CBC_MD4 - */ -#define KRB5_SUPPORTED_ENCTYPES "18,17,16,3,1,2" - -#endif /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */ - -#endif /* _LINUX_SUNRPC_GSS_KRB5_ENCTYPES_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 4986435e9b92..a0c4e45888a4 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "auth_gss_internal.h" #include "gss_krb5_internal.h" @@ -145,6 +144,43 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { }, }; +/* + * The list of advertised enctypes is specified in order of most + * preferred to least. + */ +static char gss_krb5_enctype_priority_list[64]; + +static void gss_krb5_prepare_enctype_priority_list(void) +{ + static const u32 gss_krb5_enctypes[] = { + ENCTYPE_AES256_CTS_HMAC_SHA1_96, + ENCTYPE_AES128_CTS_HMAC_SHA1_96, + ENCTYPE_DES3_CBC_SHA1, +#ifndef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD4, +#endif + }; + size_t total, i; + char buf[16]; + char *sep; + int n; + + sep = ""; + gss_krb5_enctype_priority_list[0] = '\0'; + for (total = 0, i = 0; i < ARRAY_SIZE(gss_krb5_enctypes); i++) { + n = sprintf(buf, "%s%u", sep, gss_krb5_enctypes[i]); + if (n < 0) + break; + if (total + n >= sizeof(gss_krb5_enctype_priority_list)) + break; + strcat(gss_krb5_enctype_priority_list, buf); + sep = ","; + total += n; + } +} + static const int num_supported_enctypes = ARRAY_SIZE(supported_gss_krb5_enctypes); @@ -763,13 +799,14 @@ static struct gss_api_mech gss_kerberos_mech = { .gm_ops = &gss_kerberos_ops, .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), .gm_pfs = gss_kerberos_pfs, - .gm_upcall_enctypes = KRB5_SUPPORTED_ENCTYPES, + .gm_upcall_enctypes = gss_krb5_enctype_priority_list, }; static int __init init_kerberos_module(void) { int status; + gss_krb5_prepare_enctype_priority_list(); status = gss_mech_register(&gss_kerberos_mech); if (status) printk("Failed to register kerberos gss mechanism!\n"); From patchwork Fri Jan 13 15:23:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100956 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9D5DC54EBD for ; Fri, 13 Jan 2023 15:30:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230034AbjAMPay (ORCPT ); Fri, 13 Jan 2023 10:30:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230090AbjAMPaN (ORCPT ); Fri, 13 Jan 2023 10:30:13 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF8AA7EC8F for ; Fri, 13 Jan 2023 07:23:06 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 453E3B820D3 for ; Fri, 13 Jan 2023 15:23:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5D44C433F0; Fri, 13 Jan 2023 15:23:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623383; bh=h8MSvlsAUnXP4u//askTJxUYSO6ysdaCANr7rOo5uSM=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=OzFesgZeR+9Bg4OPgYi74T59GcRbF4sIGJT5UmEY9/cVmREObgvs/WSv2R+nGWEuM xs3B6Vh+490sZtnP77Ox0v1Zp5FHSD1RJkmg58bDleYhZBXIplJOyqoNTO/HhTCGbU pDW7fbPDRqtLdTL0YjzTifAd+Jgk3HlgJor3QoiD1mp4MZk9jqibHYtDARTe+flMbp nv2ZiqRX0xEW7qHoK3PkjaFqyO9Bm1nceFf8pvRUMmAxBevy0aHGmqU9f/XiAIuZ4a 1YHNw/SVimh0qsdTMapIbu5B48DethfWOug9ekU3Hn+cK1jkmKfbVCWN+YXyaRDXCC 2xUsJZi8fRzdg== Subject: [PATCH v1 15/41] SUNRPC: Enable rpcsec_gss_krb5.ko to be built without CRYPTO_DES From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:02 -0500 Message-ID: <167362338278.8960.6221901521513665682.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Because the DES block cipher has been deprecated by Internet standard, highly secure configurations might require that DES support be blacklisted or not installed. NFS Kerberos should still be able to work correctly with only the AES-based enctypes in that situation. Also note that MIT Kerberos has begun a deprecation process for DES encryption types. Their README for 1.19.3 states: > Beginning with the krb5-1.19 release, a warning will be issued > if initial credentials are acquired using the des3-cbc-sha1 > encryption type. In future releases, this encryption type will > be disabled by default and eventually removed. > > Beginning with the krb5-1.18 release, single-DES encryption > types have been removed. Aside from the CONFIG option name change, there are two important policy changes: 1. The 'insecure enctype' group is now disabled by default. Distributors have to take action to enable support for deprecated enctypes. Implementation of these enctypes will be removed in a future kernel release. 2. des3-cbc-sha1 is now considered part of the 'insecure enctype' group, having been deprecated by RFC 8429, and is thus disabled by default After this patch is applied, SunRPC support can be built with Kerberos 5 support but without CRYPTO_DES enabled in the kernel. And, when these enctypes are disabled, the Linux kernel's SunRPC RPCSEC GSS implementation fully complies with BCP 179 / RFC 6649 and BCP 218 / RFC 8429. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/Kconfig | 54 +++++++++++++++++++++-------- net/sunrpc/auth_gss/gss_krb5_mech.c | 27 +++++++++++--- net/sunrpc/auth_gss/gss_krb5_seal.c | 62 ++++++++++++++++++--------------- net/sunrpc/auth_gss/gss_krb5_unseal.c | 3 +- net/sunrpc/auth_gss/gss_krb5_wrap.c | 4 ++ 5 files changed, 101 insertions(+), 49 deletions(-) diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig index bbbb5af0af13..1135ff362132 100644 --- a/net/sunrpc/Kconfig +++ b/net/sunrpc/Kconfig @@ -19,10 +19,10 @@ config SUNRPC_SWAP config RPCSEC_GSS_KRB5 tristate "Secure RPC: Kerberos V mechanism" depends on SUNRPC && CRYPTO - depends on CRYPTO_MD5 && CRYPTO_DES && CRYPTO_CBC && CRYPTO_CTS - depends on CRYPTO_ECB && CRYPTO_HMAC && CRYPTO_SHA1 && CRYPTO_AES default y select SUNRPC_GSS + select CRYPTO_SKCIPHER + select CRYPTO_HASH help Choose Y here to enable Secure RPC using the Kerberos version 5 GSS-API mechanism (RFC 1964). @@ -34,21 +34,47 @@ config RPCSEC_GSS_KRB5 If unsure, say Y. -config SUNRPC_DISABLE_INSECURE_ENCTYPES - bool "Secure RPC: Disable insecure Kerberos encryption types" +config RPCSEC_GSS_KRB5_SIMPLIFIED + bool + depends on RPCSEC_GSS_KRB5 + +config RPCSEC_GSS_KRB5_CRYPTOSYSTEM + bool + depends on RPCSEC_GSS_KRB5 + +config RPCSEC_GSS_KRB5_ENCTYPES_DES + bool "Enable Kerberos enctypes based on DES (deprecated)" depends on RPCSEC_GSS_KRB5 + depends on CRYPTO_CBC && CRYPTO_CTS && CRYPTO_ECB + depends on CRYPTO_HMAC && CRYPTO_MD5 && CRYPTO_SHA1 + depends on CRYPTO_DES default n + select RPCSEC_GSS_KRB5_SIMPLIFIED + help + Choose Y to enable the use of deprecated Kerberos 5 + encryption types that utilize Data Encryption Standard + (DES) based ciphers. These include des-cbc-md5, + des-cbc-crc, and des-cbc-md4, which were deprecated by + RFC 6649, and des3-cbc-sha1, which was deprecated by RFC + 8429. + + Support for these encryption types is available for + compatibility with legacy NFS client and server + implementations. The default is N which is more secure. + +config RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1 + bool "Enable Kerberos enctypes based on AES and SHA-1" + depends on RPCSEC_GSS_KRB5 + depends on CRYPTO_CBC && CRYPTO_CTS + depends on CRYPTO_HMAC && CRYPTO_SHA1 + depends on CRYPTO_AES + default y + select RPCSEC_GSS_KRB5_CRYPTOSYSTEM help - Choose Y here to disable the use of deprecated encryption types - with the Kerberos version 5 GSS-API mechanism (RFC 1964). The - deprecated encryption types include DES-CBC-MD5, DES-CBC-CRC, - and DES-CBC-MD4. These types were deprecated by RFC 6649 because - they were found to be insecure. - - N is the default because many sites have deployed KDCs and - keytabs that contain only these deprecated encryption types. - Choosing Y prevents the use of known-insecure encryption types - but might result in compatibility problems. + Choose Y to enable the use of Kerberos 5 encryption types + that utilize Advanced Encryption Standard (AES) ciphers and + SHA-1 digests. These include aes128-cts-hmac-sha1-96 and + aes256-cts-hmac-sha1-96. config SUNRPC_DEBUG bool "RPC: Enable dprintk debugging" diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index a0c4e45888a4..a6f1904fc799 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -29,12 +29,16 @@ static struct gss_api_mech gss_kerberos_mech; +#if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED) static int gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask); static int gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask); +#endif +#if defined(CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM) static int gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask); +#endif static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { -#ifndef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES) /* * DES (All DES enctypes are mapped to the same gss functionality) */ @@ -59,7 +63,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksumlength = 8, .keyed_cksum = 0, }, -#endif /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */ /* * 3DES */ @@ -84,8 +87,11 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksumlength = 20, .keyed_cksum = 1, }, +#endif + +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1) /* - * AES128 + * AES-128 with SHA-1 (RFC 3962) */ { .etype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, @@ -114,7 +120,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .keyed_cksum = 1, }, /* - * AES256 + * AES-256 with SHA-1 (RFC 3962) */ { .etype = ENCTYPE_AES256_CTS_HMAC_SHA1_96, @@ -142,6 +148,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksumlength = 12, .keyed_cksum = 1, }, +#endif }; /* @@ -153,10 +160,12 @@ static char gss_krb5_enctype_priority_list[64]; static void gss_krb5_prepare_enctype_priority_list(void) { static const u32 gss_krb5_enctypes[] = { +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1) ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, +#endif +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES) ENCTYPE_DES3_CBC_SHA1, -#ifndef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD4, @@ -337,7 +346,7 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) return PTR_ERR(p); } -static struct crypto_sync_skcipher * +static inline struct crypto_sync_skcipher * context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) { struct crypto_sync_skcipher *cp; @@ -367,6 +376,7 @@ set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed) cdata[4] = seed; } +#if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED) static int gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask) { @@ -417,6 +427,9 @@ gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask) out_err: return -EINVAL; } +#endif + +#if defined(CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM) static struct crypto_ahash * gss_krb5_alloc_hash_v2(struct krb5_ctx *kctx, const struct xdr_netobj *key) @@ -551,6 +564,8 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) goto out; } +#endif + static int gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, gfp_t gfp_mask) diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index f74125407588..146aa755f07d 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c @@ -71,6 +71,8 @@ # define RPCDBG_FACILITY RPCDBG_AUTH #endif +#if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED) + static void * setup_token(struct krb5_ctx *ctx, struct xdr_netobj *token) { @@ -97,34 +99,6 @@ setup_token(struct krb5_ctx *ctx, struct xdr_netobj *token) return krb5_hdr; } -static void * -setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token) -{ - u16 *ptr; - void *krb5_hdr; - u8 *p, flags = 0x00; - - if ((ctx->flags & KRB5_CTX_FLAG_INITIATOR) == 0) - flags |= 0x01; - if (ctx->flags & KRB5_CTX_FLAG_ACCEPTOR_SUBKEY) - flags |= 0x04; - - /* Per rfc 4121, sec 4.2.6.1, there is no header, - * just start the token */ - krb5_hdr = ptr = (u16 *)token->data; - - *ptr++ = KG2_TOK_MIC; - p = (u8 *)ptr; - *p++ = flags; - *p++ = 0xff; - ptr = (u16 *)p; - *ptr++ = 0xffff; - *ptr = 0xffff; - - token->len = GSS_KRB5_TOK_HDR_LEN + ctx->gk5e->cksumlength; - return krb5_hdr; -} - u32 gss_krb5_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, struct xdr_netobj *token) @@ -164,6 +138,38 @@ gss_krb5_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; } +#endif + +static void * +setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token) +{ + u16 *ptr; + void *krb5_hdr; + u8 *p, flags = 0x00; + + if ((ctx->flags & KRB5_CTX_FLAG_INITIATOR) == 0) + flags |= 0x01; + if (ctx->flags & KRB5_CTX_FLAG_ACCEPTOR_SUBKEY) + flags |= 0x04; + + /* Per rfc 4121, sec 4.2.6.1, there is no header, + * just start the token. + */ + krb5_hdr = (u16 *)token->data; + ptr = krb5_hdr; + + *ptr++ = KG2_TOK_MIC; + p = (u8 *)ptr; + *p++ = flags; + *p++ = 0xff; + ptr = (u16 *)p; + *ptr++ = 0xffff; + *ptr = 0xffff; + + token->len = GSS_KRB5_TOK_HDR_LEN + ctx->gk5e->cksumlength; + return krb5_hdr; +} + u32 gss_krb5_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, struct xdr_netobj *token) diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c index 939d199eb7b7..7d6d4ae4a3c9 100644 --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c @@ -70,9 +70,9 @@ #endif +#if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED) /* read_token is a mic token, and message_buffer is the data that the mic was * supposedly taken over. */ - u32 gss_krb5_verify_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, struct xdr_netobj *read_token) @@ -144,6 +144,7 @@ gss_krb5_verify_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, return GSS_S_COMPLETE; } +#endif u32 gss_krb5_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 57085bdec053..13e633bcbc2d 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -40,6 +40,8 @@ # define RPCDBG_FACILITY RPCDBG_AUTH #endif +#if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED) + static inline int gss_krb5_padding(int blocksize, int length) { @@ -323,6 +325,8 @@ gss_krb5_unwrap_v1(struct krb5_ctx *kctx, int offset, int len, return GSS_S_COMPLETE; } +#endif + /* * We can shift data by up to LOCAL_BUF_LEN bytes in a pass. If we need * to do more than that, we shift repeatedly. Kevin Coffman reports From patchwork Fri Jan 13 15:23:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100957 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC614C54EBE for ; Fri, 13 Jan 2023 15:30:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230250AbjAMPa4 (ORCPT ); Fri, 13 Jan 2023 10:30:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230259AbjAMPaN (ORCPT ); Fri, 13 Jan 2023 10:30:13 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A2BC2675 for ; Fri, 13 Jan 2023 07:23:13 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id B8FF8B8212E for ; Fri, 13 Jan 2023 15:23:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0AF68C433EF; Fri, 13 Jan 2023 15:23:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623390; bh=36vWIPJNnj+B9Dnq6gsR92VyfA0kahWEm014Wut8HTk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=tkxyYTwz4ufCEmtsgBp1ZWPjyQIP1nI+/rPHcMsNZarZq5mV78lnb+Y4SVjAlvOSR oa8x47qVo/RF2zlvOksNZ0/ZvrZwS+bNuwMb3TIVGZkMbILrSHE6zwT50c6II/j4FM DC+2DJaYGj+USuCaAmIUTTX64Y7IJtz8ol3vGgj+VerM2Owjg6KUd6OLJUWc6IEcsH 3buNfMTqtlZKcxHIsDPoeWpkT3HwQV2dAplpARNw5G01RZUePZx2W2JkAdZKRN1lk1 5KukQCzThxCV+ae+uAFwWSB204YRcR4oSEu/+S++FLE79bOQAokNVdYMgcXjzlSd8S YrpDv2oZA4eDg== Subject: [PATCH v1 16/41] SUNRPC: Remove ->encrypt and ->decrypt methods from struct gss_krb5_enctype From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:09 -0500 Message-ID: <167362338910.8960.8731253086521215072.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Clean up: ->encrypt is set to only one value. Replace the two remaining call sites with direct calls to krb5_encrypt(). There have never been any call sites for the ->decrypt() method. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 14 ------------ net/sunrpc/auth_gss/gss_krb5_crypto.c | 36 +++++++++++++++++++++++++++++-- net/sunrpc/auth_gss/gss_krb5_internal.h | 6 +++++ net/sunrpc/auth_gss/gss_krb5_keys.c | 6 +++-- net/sunrpc/auth_gss/gss_krb5_mech.c | 8 ------- net/sunrpc/auth_gss/gss_krb5_seqnum.c | 2 ++ 6 files changed, 46 insertions(+), 26 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 00305a967dee..3fb0e72fa656 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -71,12 +71,6 @@ struct gss_krb5_enctype { 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 */ - u32 (*encrypt) (struct crypto_sync_skcipher *tfm, - void *iv, void *in, void *out, - int length); /* encryption function */ - u32 (*decrypt) (struct crypto_sync_skcipher *tfm, - void *iv, void *in, void *out, - int length); /* decryption function */ int (*import_ctx)(struct krb5_ctx *ctx, gfp_t gfp_mask); u32 (*mk_key) (const struct gss_krb5_enctype *gk5e, struct xdr_netobj *in, @@ -247,14 +241,6 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, struct xdr_buf *body, int body_offset, u8 *cksumkey, unsigned int usage, struct xdr_netobj *cksumout); -u32 -krb5_encrypt(struct crypto_sync_skcipher *key, - void *iv, void *in, void *out, int length); - -u32 -krb5_decrypt(struct crypto_sync_skcipher *key, - void *iv, void *in, void *out, int length); - int gss_encrypt_xdr_buf(struct crypto_sync_skcipher *tfm, struct xdr_buf *outbuf, int offset, struct page **pages); diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 3ffe66779fb7..9703881fbd1d 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -77,6 +77,22 @@ krb5_make_confounder(struct krb5_ctx *kctx, u8 *p, int conflen) } } +/** + * krb5_encrypt - simple encryption of an RPCSEC GSS payload + * @tfm: initialized cipher transform + * @iv: pointer to an IV + * @in: plaintext to encrypt + * @out: OUT: ciphertext + * @length: length of input and output buffers, in bytes + * + * @iv may be NULL to force the use of an all-zero IV. + * The buffer containing the IV must be as large as the + * cipher's ivsize. + * + * Return values: + * %0: @in successfully encrypted into @out + * negative errno: @in not encrypted + */ u32 krb5_encrypt( struct crypto_sync_skcipher *tfm, @@ -116,6 +132,22 @@ krb5_encrypt( return ret; } +/** + * krb5_decrypt - simple decryption of an RPCSEC GSS payload + * @tfm: initialized cipher transform + * @iv: pointer to an IV + * @in: ciphertext to decrypt + * @out: OUT: plaintext + * @length: length of input and output buffers, in bytes + * + * @iv may be NULL to force the use of an all-zero IV. + * The buffer containing the IV must be as large as the + * cipher's ivsize. + * + * Return values: + * %0: @in successfully decrypted into @out + * negative errno: @in not decrypted + */ u32 krb5_decrypt( struct crypto_sync_skcipher *tfm, @@ -229,8 +261,8 @@ make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, switch (kctx->gk5e->ctype) { case CKSUMTYPE_RSA_MD5: - err = kctx->gk5e->encrypt(kctx->seq, NULL, checksumdata, - checksumdata, checksumlen); + err = krb5_encrypt(kctx->seq, NULL, checksumdata, + checksumdata, checksumlen); if (err) goto out; memcpy(cksumout->data, diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index c6420f9a6c4e..f4dc0f075144 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -44,4 +44,10 @@ u32 gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, const struct xdr_buf *body, int body_offset, struct xdr_netobj *cksumout); +u32 krb5_encrypt(struct crypto_sync_skcipher *key, void *iv, void *in, + void *out, int length); + +u32 krb5_decrypt(struct crypto_sync_skcipher *key, void *iv, void *in, + void *out, int length); + #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index 554cfd23f288..a7c6866dad96 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c @@ -61,6 +61,8 @@ #include #include +#include "gss_krb5_internal.h" + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif @@ -195,8 +197,8 @@ u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, n = 0; while (n < keybytes) { - (*(gk5e->encrypt))(cipher, NULL, inblock.data, - outblock.data, inblock.len); + krb5_encrypt(cipher, NULL, inblock.data, outblock.data, + inblock.len); if ((keybytes - n) <= outblock.len) { memcpy(rawkey + n, outblock.data, (keybytes - n)); diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index a6f1904fc799..8780f80b5f66 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -48,8 +48,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .name = "des-cbc-crc", .encrypt_name = "cbc(des)", .cksum_name = "md5", - .encrypt = krb5_encrypt, - .decrypt = krb5_decrypt, .import_ctx = gss_krb5_import_ctx_des, .mk_key = NULL, .get_mic = gss_krb5_get_mic_v1, @@ -72,8 +70,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .name = "des3-hmac-sha1", .encrypt_name = "cbc(des3_ede)", .cksum_name = "hmac(sha1)", - .encrypt = krb5_encrypt, - .decrypt = krb5_decrypt, .import_ctx = gss_krb5_import_ctx_v1, .mk_key = gss_krb5_des3_make_key, .get_mic = gss_krb5_get_mic_v1, @@ -100,8 +96,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .encrypt_name = "cts(cbc(aes))", .aux_cipher = "cbc(aes)", .cksum_name = "hmac(sha1)", - .encrypt = krb5_encrypt, - .decrypt = krb5_decrypt, .import_ctx = gss_krb5_import_ctx_v2, .mk_key = gss_krb5_aes_make_key, .encrypt_v2 = gss_krb5_aes_encrypt, @@ -129,8 +123,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .encrypt_name = "cts(cbc(aes))", .aux_cipher = "cbc(aes)", .cksum_name = "hmac(sha1)", - .encrypt = krb5_encrypt, - .decrypt = krb5_decrypt, .import_ctx = gss_krb5_import_ctx_v2, .mk_key = gss_krb5_aes_make_key, .encrypt_v2 = gss_krb5_aes_encrypt, diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c index 3200b971a814..1babc3474e10 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c +++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c @@ -35,6 +35,8 @@ #include #include +#include "gss_krb5_internal.h" + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) # define RPCDBG_FACILITY RPCDBG_AUTH #endif From patchwork Fri Jan 13 15:23:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100958 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8F44C54EBD for ; Fri, 13 Jan 2023 15:30:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229702AbjAMPa5 (ORCPT ); Fri, 13 Jan 2023 10:30:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229599AbjAMPaR (ORCPT ); Fri, 13 Jan 2023 10:30:17 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8ED477EC99 for ; Fri, 13 Jan 2023 07:23:17 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2C0916216C for ; Fri, 13 Jan 2023 15:23:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 53B62C433EF; Fri, 13 Jan 2023 15:23:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623396; bh=uVCOo0BKMwJB7HoR9Fj6fBsT/1Ukc4fKdT2dha23QFU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=eNX1TrgkhawCMvrzHT5aLg7pItGwy54OLPh93HsHjtwPHdOPid3O98RKAHvCPabyQ sFi6rs6RegIKrHdRbJ8ibsXqOhCArgQHKA+cpilxaer+nH/yyuyLdhtvQC1fknoxzC fDXL6j8R6pZPKMAQZp1xC6mBJ2m8Uyk+7cH3jiTRWQ5yXu7PqHuDQTnYELdTqvPhJ/ Xdpj6eUO6PKiW5k0FsjIeeuxO/m4Uo1jhP1fNXDSdXICcl/DMMw0A5SoSSuZxxyUJ5 z0x1voDfeH74z4By4JH0Z64mn2eAQfHR5BMCu7YkNNDnjKL73cNI8yFwkhR6y6IWRZ nuzsjo+i4ByMw== Subject: [PATCH v1 17/41] SUNRPC: Rename .encrypt_v2 and .decrypt_v2 methods From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:15 -0500 Message-ID: <167362339545.8960.4642624913840080009.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Clean up: there is now only one encrypt and only one decrypt method, thus there is no longer a need for the v2-suffixed method names. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 20 ++++---------------- net/sunrpc/auth_gss/gss_krb5_internal.h | 6 ++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 8 ++++---- net/sunrpc/auth_gss/gss_krb5_wrap.c | 12 +++--------- 4 files changed, 17 insertions(+), 29 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 3fb0e72fa656..9c9caa5712b3 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -75,12 +75,10 @@ struct gss_krb5_enctype { u32 (*mk_key) (const struct gss_krb5_enctype *gk5e, struct xdr_netobj *in, struct xdr_netobj *out); /* complete key generation */ - u32 (*encrypt_v2) (struct krb5_ctx *kctx, u32 offset, - struct xdr_buf *buf, - struct page **pages); /* v2 encryption function */ - u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset, u32 len, - struct xdr_buf *buf, u32 *headskip, - u32 *tailskip); /* v2 decryption function */ + u32 (*encrypt)(struct krb5_ctx *kctx, u32 offset, + struct xdr_buf *buf, struct page **pages); + u32 (*decrypt)(struct krb5_ctx *kctx, u32 offset, u32 len, + struct xdr_buf *buf, u32 *headskip, u32 *tailskip); u32 (*get_mic)(struct krb5_ctx *kctx, struct xdr_buf *text, struct xdr_netobj *token); u32 (*verify_mic)(struct krb5_ctx *kctx, struct xdr_buf *message_buffer, @@ -280,14 +278,4 @@ gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e, struct xdr_netobj *randombits, struct xdr_netobj *key); -u32 -gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, - struct xdr_buf *buf, - struct page **pages); - -u32 -gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, - struct xdr_buf *buf, u32 *plainoffset, - u32 *plainlen); - #endif /* _LINUX_SUNRPC_GSS_KRB5_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index f4dc0f075144..0003128e05e8 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -50,4 +50,10 @@ u32 krb5_encrypt(struct crypto_sync_skcipher *key, void *iv, void *in, u32 krb5_decrypt(struct crypto_sync_skcipher *key, void *iv, void *in, void *out, int length); +u32 gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, + struct xdr_buf *buf, struct page **pages); + +u32 gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, + struct xdr_buf *buf, u32 *plainoffset, u32 *plainlen); + #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 8780f80b5f66..794bb6826dce 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -98,8 +98,8 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksum_name = "hmac(sha1)", .import_ctx = gss_krb5_import_ctx_v2, .mk_key = gss_krb5_aes_make_key, - .encrypt_v2 = gss_krb5_aes_encrypt, - .decrypt_v2 = gss_krb5_aes_decrypt, + .encrypt = gss_krb5_aes_encrypt, + .decrypt = gss_krb5_aes_decrypt, .get_mic = gss_krb5_get_mic_v2, .verify_mic = gss_krb5_verify_mic_v2, @@ -125,8 +125,8 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .cksum_name = "hmac(sha1)", .import_ctx = gss_krb5_import_ctx_v2, .mk_key = gss_krb5_aes_make_key, - .encrypt_v2 = gss_krb5_aes_encrypt, - .decrypt_v2 = gss_krb5_aes_decrypt, + .encrypt = gss_krb5_aes_encrypt, + .decrypt = gss_krb5_aes_decrypt, .get_mic = gss_krb5_get_mic_v2, .verify_mic = gss_krb5_verify_mic_v2, diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 13e633bcbc2d..5491e083ee98 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -390,9 +390,6 @@ gss_krb5_wrap_v2(struct krb5_ctx *kctx, int offset, dprintk("RPC: %s\n", __func__); - if (kctx->gk5e->encrypt_v2 == NULL) - return GSS_S_FAILURE; - /* make room for gss token header */ if (xdr_extend_head(buf, offset, GSS_KRB5_TOK_HDR_LEN)) return GSS_S_FAILURE; @@ -420,7 +417,7 @@ gss_krb5_wrap_v2(struct krb5_ctx *kctx, int offset, be64ptr = (__be64 *)be16ptr; *be64ptr = cpu_to_be64(atomic64_fetch_inc(&kctx->seq_send64)); - err = (*kctx->gk5e->encrypt_v2)(kctx, offset, buf, pages); + err = (*kctx->gk5e->encrypt)(kctx, offset, buf, pages); if (err) return err; @@ -445,9 +442,6 @@ gss_krb5_unwrap_v2(struct krb5_ctx *kctx, int offset, int len, dprintk("RPC: %s\n", __func__); - if (kctx->gk5e->decrypt_v2 == NULL) - return GSS_S_FAILURE; - ptr = buf->head[0].iov_base + offset; if (be16_to_cpu(*((__be16 *)ptr)) != KG2_TOK_WRAP) @@ -477,8 +471,8 @@ gss_krb5_unwrap_v2(struct krb5_ctx *kctx, int offset, int len, if (rrc != 0) rotate_left(offset + 16, buf, rrc); - err = (*kctx->gk5e->decrypt_v2)(kctx, offset, len, buf, - &headskip, &tailskip); + err = (*kctx->gk5e->decrypt)(kctx, offset, len, buf, + &headskip, &tailskip); if (err) return GSS_S_FAILURE; From patchwork Fri Jan 13 15:23:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100959 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8079BC54EBE for ; Fri, 13 Jan 2023 15:31:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229721AbjAMPa7 (ORCPT ); Fri, 13 Jan 2023 10:30:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229676AbjAMPa2 (ORCPT ); Fri, 13 Jan 2023 10:30:28 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 094CF5B48F for ; Fri, 13 Jan 2023 07:23:24 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8C0CC6216C for ; Fri, 13 Jan 2023 15:23:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9FAC6C433EF; Fri, 13 Jan 2023 15:23:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623403; bh=WNC59MpX1U79QzJ/M7gXc1A4YGaOU2recCCVwy5qHR4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=vL6DVdCjY9Hr2B8kfh9LQjIHmDinYMhy5LO4sYd+Mynqqmh/mieimEXZJ4kt8Ma/D NIcaWos8mJbfRbWjDyJ3CBiGebYK14KG4HT6J5aoA9kRnU+VVHF6u34YlVhchM/k9c 7IySrQ5jWd9bdz5fbe30xyUOAu3QjfQFvdd1ulhjJPbP2/VnvN/A1+4E3vcC7szQZh jhQYUIYgFHTd9jPV6ZgaxZp30qzXu9VhWH2UDxGb02AklVUhtiC7eC2UobaZ023ZXX uFAXXwQ14id/DrrkMm4eXQlxYgKyinYf/3cIHsQWEtuPgZ4bsOcAswLlJiyL4j5KMk jqMAer0WnNRMQ== Subject: [PATCH v1 18/41] SUNRPC: Hoist KDF into struct gss_krb5_enctype From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:21 -0500 Message-ID: <167362340176.8960.9876417707472902857.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Each Kerberos enctype can have a different KDF. Refactor the key derivation path to support different KDFs for the enctypes introduced in subsequent patches. In particular, expose the key derivation function in struct gss_krb5_enctype instead of the enctype's preferred random-to-key function. The latter is usually the identity function and is only ever called during key derivation, so have each KDF call it directly. A couple of extra clean-ups: - Deduplicate the set_cdata() helper - Have ->derive_key return negative errnos, in accordance with usual kernel coding conventions This patch is a little bigger than I'd like, but these are all mechanical changes and they are all to the same areas of code. No behavior change is intended. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 25 +----- net/sunrpc/auth_gss/gss_krb5_internal.h | 46 +++++++++++ net/sunrpc/auth_gss/gss_krb5_keys.c | 131 ++++++++++++++++++++----------- net/sunrpc/auth_gss/gss_krb5_mech.c | 76 ++++-------------- 4 files changed, 156 insertions(+), 122 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 9c9caa5712b3..0c08f4f75b43 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -72,9 +72,11 @@ struct gss_krb5_enctype { const u32 keybytes; /* raw key len, in bytes */ const u32 keylength; /* final key len, in bytes */ int (*import_ctx)(struct krb5_ctx *ctx, gfp_t gfp_mask); - u32 (*mk_key) (const struct gss_krb5_enctype *gk5e, - struct xdr_netobj *in, - struct xdr_netobj *out); /* complete key generation */ + int (*derive_key)(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *in, + struct xdr_netobj *out, + const struct xdr_netobj *label, + gfp_t gfp_mask); u32 (*encrypt)(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, struct page **pages); u32 (*decrypt)(struct krb5_ctx *kctx, u32 offset, u32 len, @@ -261,21 +263,4 @@ krb5_get_seq_num(struct krb5_ctx *kctx, int xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen); -u32 -krb5_derive_key(const struct gss_krb5_enctype *gk5e, - const struct xdr_netobj *inkey, - struct xdr_netobj *outkey, - const struct xdr_netobj *in_constant, - gfp_t gfp_mask); - -u32 -gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e, - struct xdr_netobj *randombits, - struct xdr_netobj *key); - -u32 -gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e, - struct xdr_netobj *randombits, - struct xdr_netobj *key); - #endif /* _LINUX_SUNRPC_GSS_KRB5_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index 0003128e05e8..e1c61c267dad 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -38,6 +38,52 @@ u32 gss_krb5_unwrap_v2(struct krb5_ctx *kctx, int offset, int len, * Implementation internal functions */ +/* Key Derivation Functions */ + +int krb5_derive_key_v1(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *label, + gfp_t gfp_mask); + +int krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *label, + gfp_t gfp_mask); + +/** + * krb5_derive_key - Derive a subkey from a protocol key + * @kctx: Kerberos 5 context + * @inkey: base protocol key + * @outkey: OUT: derived key + * @usage: key usage value + * @seed: key usage seed (one octet) + * @gfp_mask: memory allocation control flags + * + * Caller sets @outkey->len to the desired length of the derived key. + * + * On success, returns 0 and fills in @outkey. A negative errno value + * is returned on failure. + */ +static inline int krb5_derive_key(struct krb5_ctx *kctx, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + u32 usage, u8 seed, gfp_t gfp_mask) +{ + const struct gss_krb5_enctype *gk5e = kctx->gk5e; + u8 label_data[GSS_KRB5_K5CLENGTH]; + struct xdr_netobj label = { + .len = sizeof(label_data), + .data = label_data, + }; + __be32 *p = (__be32 *)label_data; + + *p = cpu_to_be32(usage); + label_data[4] = seed; + return gk5e->derive_key(gk5e, inkey, outkey, &label, gfp_mask); +} + void krb5_make_confounder(struct krb5_ctx *kctx, u8 *p, int conflen); u32 gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index a7c6866dad96..f6de4fdd63ae 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c @@ -139,23 +139,20 @@ static void krb5_nfold(u32 inbits, const u8 *in, * This is the DK (derive_key) function as described in rfc3961, sec 5.1 * Taken from MIT Kerberos and modified. */ - -u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, - const struct xdr_netobj *inkey, - struct xdr_netobj *outkey, - const struct xdr_netobj *in_constant, - gfp_t gfp_mask) +static int krb5_DK(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, u8 *rawkey, + const struct xdr_netobj *in_constant, gfp_t gfp_mask) { size_t blocksize, keybytes, keylength, n; - unsigned char *inblockdata, *outblockdata, *rawkey; + unsigned char *inblockdata, *outblockdata; struct xdr_netobj inblock, outblock; struct crypto_sync_skcipher *cipher; - u32 ret = EINVAL; + int ret = -EINVAL; keybytes = gk5e->keybytes; keylength = gk5e->keylength; - if ((inkey->len != keylength) || (outkey->len != keylength)) + if (inkey->len != keylength) goto err_return; cipher = crypto_alloc_sync_skcipher(gk5e->encrypt_name, 0, 0); @@ -165,7 +162,7 @@ u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, if (crypto_sync_skcipher_setkey(cipher, inkey->data, inkey->len)) goto err_return; - ret = ENOMEM; + ret = -ENOMEM; inblockdata = kmalloc(blocksize, gfp_mask); if (inblockdata == NULL) goto err_free_cipher; @@ -174,10 +171,6 @@ u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, if (outblockdata == NULL) goto err_free_in; - rawkey = kmalloc(keybytes, gfp_mask); - if (rawkey == NULL) - goto err_free_out; - inblock.data = (char *) inblockdata; inblock.len = blocksize; @@ -210,26 +203,8 @@ u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e, n += outblock.len; } - /* postprocess the key */ - - inblock.data = (char *) rawkey; - inblock.len = keybytes; - - BUG_ON(gk5e->mk_key == NULL); - ret = (*(gk5e->mk_key))(gk5e, &inblock, outkey); - if (ret) { - dprintk("%s: got %d from mk_key function for '%s'\n", - __func__, ret, gk5e->encrypt_name); - goto err_free_raw; - } - - /* clean memory, free resources and exit */ - ret = 0; -err_free_raw: - kfree_sensitive(rawkey); -err_free_out: kfree_sensitive(outblockdata); err_free_in: kfree_sensitive(inblockdata); @@ -252,15 +227,11 @@ static void mit_des_fixup_key_parity(u8 key[8]) } } -/* - * This is the des3 key derivation postprocess function - */ -u32 gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e, - struct xdr_netobj *randombits, - struct xdr_netobj *key) +static int krb5_random_to_key_v1(const struct gss_krb5_enctype *gk5e, + struct xdr_netobj *randombits, + struct xdr_netobj *key) { - int i; - u32 ret = EINVAL; + int i, ret = -EINVAL; if (key->len != 24) { dprintk("%s: key->len is %d\n", __func__, key->len); @@ -292,14 +263,49 @@ u32 gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e, return ret; } +/** + * krb5_derive_key_v1 - Derive a subkey for an RFC 3961 enctype + * @gk5e: Kerberos 5 enctype profile + * @inkey: base protocol key + * @outkey: OUT: derived key + * @label: subkey usage label + * @gfp_mask: memory allocation control flags + * + * Caller sets @outkey->len to the desired length of the derived key. + * + * On success, returns 0 and fills in @outkey. A negative errno value + * is returned on failure. + */ +int krb5_derive_key_v1(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *label, + gfp_t gfp_mask) +{ + struct xdr_netobj inblock; + int ret; + + inblock.len = gk5e->keybytes; + inblock.data = kmalloc(inblock.len, gfp_mask); + if (!inblock.data) + return -ENOMEM; + + ret = krb5_DK(gk5e, inkey, inblock.data, label, gfp_mask); + if (!ret) + ret = krb5_random_to_key_v1(gk5e, &inblock, outkey); + + kfree_sensitive(inblock.data); + return ret; +} + /* - * This is the aes key derivation postprocess function + * This is the identity function, with some sanity checking. */ -u32 gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e, - struct xdr_netobj *randombits, - struct xdr_netobj *key) +static int krb5_random_to_key_v2(const struct gss_krb5_enctype *gk5e, + struct xdr_netobj *randombits, + struct xdr_netobj *key) { - u32 ret = EINVAL; + int ret = -EINVAL; if (key->len != 16 && key->len != 32) { dprintk("%s: key->len is %d\n", __func__, key->len); @@ -320,3 +326,38 @@ u32 gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e, err_out: return ret; } + +/** + * krb5_derive_key_v2 - Derive a subkey for an RFC 3962 enctype + * @gk5e: Kerberos 5 enctype profile + * @inkey: base protocol key + * @outkey: OUT: derived key + * @label: subkey usage label + * @gfp_mask: memory allocation control flags + * + * Caller sets @outkey->len to the desired length of the derived key. + * + * On success, returns 0 and fills in @outkey. A negative errno value + * is returned on failure. + */ +int krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *label, + gfp_t gfp_mask) +{ + struct xdr_netobj inblock; + int ret; + + inblock.len = gk5e->keybytes; + inblock.data = kmalloc(inblock.len, gfp_mask); + if (!inblock.data) + return -ENOMEM; + + ret = krb5_DK(gk5e, inkey, inblock.data, label, gfp_mask); + if (!ret) + ret = krb5_random_to_key_v2(gk5e, &inblock, outkey); + + kfree_sensitive(inblock.data); + return ret; +} diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 794bb6826dce..33fa09fa3d21 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -49,7 +49,6 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .encrypt_name = "cbc(des)", .cksum_name = "md5", .import_ctx = gss_krb5_import_ctx_des, - .mk_key = NULL, .get_mic = gss_krb5_get_mic_v1, .verify_mic = gss_krb5_verify_mic_v1, .wrap = gss_krb5_wrap_v1, @@ -71,7 +70,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .encrypt_name = "cbc(des3_ede)", .cksum_name = "hmac(sha1)", .import_ctx = gss_krb5_import_ctx_v1, - .mk_key = gss_krb5_des3_make_key, + .derive_key = krb5_derive_key_v1, .get_mic = gss_krb5_get_mic_v1, .verify_mic = gss_krb5_verify_mic_v1, .wrap = gss_krb5_wrap_v1, @@ -97,7 +96,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .aux_cipher = "cbc(aes)", .cksum_name = "hmac(sha1)", .import_ctx = gss_krb5_import_ctx_v2, - .mk_key = gss_krb5_aes_make_key, + .derive_key = krb5_derive_key_v2, .encrypt = gss_krb5_aes_encrypt, .decrypt = gss_krb5_aes_decrypt, @@ -124,7 +123,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .aux_cipher = "cbc(aes)", .cksum_name = "hmac(sha1)", .import_ctx = gss_krb5_import_ctx_v2, - .mk_key = gss_krb5_aes_make_key, + .derive_key = krb5_derive_key_v2, .encrypt = gss_krb5_aes_encrypt, .decrypt = gss_krb5_aes_decrypt, @@ -358,16 +357,6 @@ context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) return cp; } -static inline void -set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed) -{ - cdata[0] = (usage>>24)&0xff; - cdata[1] = (usage>>16)&0xff; - cdata[2] = (usage>>8)&0xff; - cdata[3] = usage&0xff; - cdata[4] = seed; -} - #if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED) static int gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask) @@ -378,16 +367,10 @@ gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask) static int gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask) { - struct xdr_netobj c, keyin, keyout; - u8 cdata[GSS_KRB5_K5CLENGTH]; - u32 err; - - c.len = GSS_KRB5_K5CLENGTH; - c.data = cdata; + struct xdr_netobj keyin, keyout; keyin.data = ctx->Ksess; keyin.len = ctx->gk5e->keylength; - keyout.len = ctx->gk5e->keylength; /* seq uses the raw key */ ctx->seq = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, @@ -401,14 +384,11 @@ gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask) goto out_free_seq; /* derive cksum */ - set_cdata(cdata, KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM); keyout.data = ctx->cksum; - err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) { - dprintk("%s: Error %d deriving cksum key\n", - __func__, err); + keyout.len = ctx->gk5e->keylength; + if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_SIGN, + KEY_USAGE_SEED_CHECKSUM, gfp_mask)) goto out_free_enc; - } return 0; @@ -441,11 +421,6 @@ gss_krb5_alloc_hash_v2(struct krb5_ctx *kctx, const struct xdr_netobj *key) static int gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) { - u8 cdata[GSS_KRB5_K5CLENGTH]; - struct xdr_netobj c = { - .len = sizeof(cdata), - .data = cdata, - }; struct xdr_netobj keyin = { .len = ctx->gk5e->keylength, .data = ctx->Ksess, @@ -453,7 +428,6 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) struct xdr_netobj keyout; int ret = -EINVAL; void *subkey; - u32 err; subkey = kmalloc(ctx->gk5e->keylength, gfp_mask); if (!subkey) @@ -462,13 +436,9 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) keyout.data = subkey; /* initiator seal encryption */ - set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); - err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) { - dprintk("%s: Error %d deriving initiator_seal key\n", - __func__, err); + if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL, + KEY_USAGE_SEED_ENCRYPTION, gfp_mask)) goto out; - } ctx->initiator_enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, subkey); @@ -483,13 +453,9 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) } /* acceptor seal encryption */ - set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); - err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) { - dprintk("%s: Error %d deriving acceptor_seal key\n", - __func__, err); + if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SEAL, + KEY_USAGE_SEED_ENCRYPTION, gfp_mask)) goto out_free; - } ctx->acceptor_enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, subkey); @@ -504,36 +470,32 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) } /* initiator sign checksum */ - set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); - err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) + if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SIGN, + KEY_USAGE_SEED_CHECKSUM, gfp_mask)) goto out_free; ctx->initiator_sign = gss_krb5_alloc_hash_v2(ctx, &keyout); if (ctx->initiator_sign == NULL) goto out_free; /* acceptor sign checksum */ - set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM); - err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) + if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SIGN, + KEY_USAGE_SEED_CHECKSUM, gfp_mask)) goto out_free; ctx->acceptor_sign = gss_krb5_alloc_hash_v2(ctx, &keyout); if (ctx->acceptor_sign == NULL) goto out_free; /* initiator seal integrity */ - set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); - err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) + if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL, + KEY_USAGE_SEED_INTEGRITY, gfp_mask)) goto out_free; ctx->initiator_integ = gss_krb5_alloc_hash_v2(ctx, &keyout); if (ctx->initiator_integ == NULL) goto out_free; /* acceptor seal integrity */ - set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY); - err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); - if (err) + if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SEAL, + KEY_USAGE_SEED_INTEGRITY, gfp_mask)) goto out_free; ctx->acceptor_integ = gss_krb5_alloc_hash_v2(ctx, &keyout); if (ctx->acceptor_integ == NULL) From patchwork Fri Jan 13 15:23:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100960 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7BCA4C67871 for ; Fri, 13 Jan 2023 15:31:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229906AbjAMPbA (ORCPT ); Fri, 13 Jan 2023 10:31:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230033AbjAMPaa (ORCPT ); Fri, 13 Jan 2023 10:30:30 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99F7725E2 for ; Fri, 13 Jan 2023 07:23:32 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id 11A08CE20E4 for ; Fri, 13 Jan 2023 15:23:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08D52C433F2; Fri, 13 Jan 2023 15:23:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623409; bh=Iic1LRBOerxdEticEl5FwsjAIN/fSkrT8nfnxkjwkhc=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=aVJCFRM/B+Pj3depQnf3ZOa3l8A0l6RKJIPqVx9PiYtmD4CvtMFdFzMnCuBr9hAIA cs3FkKQ2RwdU9zzq2SlNCy0sDbjRJB2BAeLQ5/ST0OOLrTi5qc6oqOWg+G5D9yE42z 1E7VAczMWRexFn7uTL8UbzcQepsDTg9C0dtWCqCcmomQ10ryZQXbh1qdjp/ORZ9RT6 pJAJKiTGmv/o/fufmNAP92Z/YG4jZg0jfEacLos827CksuRqOkeBtLzshT7vQeJzY2 mc71SSiYhAOON8iDJUFRSdXc/v6oxg6vE7ZoZJeAw/PUWa21imFy/CYVzRqVh76ViI GoznxsvR8uFqw== Subject: [PATCH v1 19/41] SUNRPC: Clean up cipher set up for v1 encryption types From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:28 -0500 Message-ID: <167362340814.8960.5512279594588055531.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever De-duplicate some common code. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_mech.c | 58 ++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 33fa09fa3d21..579ff755d535 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -204,17 +204,32 @@ get_gss_krb5_enctype(int etype) return NULL; } +static struct crypto_sync_skcipher * +gss_krb5_alloc_cipher_v1(struct krb5_ctx *ctx, struct xdr_netobj *key) +{ + struct crypto_sync_skcipher *tfm; + + tfm = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); + if (IS_ERR(tfm)) + return NULL; + if (crypto_sync_skcipher_setkey(tfm, key->data, key->len)) { + crypto_free_sync_skcipher(tfm); + return NULL; + } + return tfm; +} + static inline const void * get_key(const void *p, const void *end, struct krb5_ctx *ctx, struct crypto_sync_skcipher **res) { + struct crypto_sync_skcipher *tfm; struct xdr_netobj key; int alg; p = simple_get_bytes(p, end, &alg, sizeof(alg)); if (IS_ERR(p)) goto out_err; - switch (alg) { case ENCTYPE_DES_CBC_CRC: case ENCTYPE_DES_CBC_MD4: @@ -223,37 +238,26 @@ get_key(const void *p, const void *end, alg = ENCTYPE_DES_CBC_RAW; break; } - if (!supported_gss_krb5_enctype(alg)) { - printk(KERN_WARNING "gss_kerberos_mech: unsupported " - "encryption key algorithm %d\n", alg); - p = ERR_PTR(-EINVAL); - goto out_err; + pr_warn("gss_krb5: unsupported enctype: %d\n", alg); + goto out_err_inval; } + p = simple_get_netobj(p, end, &key); if (IS_ERR(p)) goto out_err; - - *res = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); - if (IS_ERR(*res)) { - printk(KERN_WARNING "gss_kerberos_mech: unable to initialize " - "crypto algorithm %s\n", ctx->gk5e->encrypt_name); - *res = NULL; - goto out_err_free_key; - } - if (crypto_sync_skcipher_setkey(*res, key.data, key.len)) { - printk(KERN_WARNING "gss_kerberos_mech: error setting key for " - "crypto algorithm %s\n", ctx->gk5e->encrypt_name); - goto out_err_free_tfm; + tfm = gss_krb5_alloc_cipher_v1(ctx, &key); + kfree(key.data); + if (!tfm) { + pr_warn("gss_krb5: failed to initialize cipher '%s'\n", + ctx->gk5e->encrypt_name); + goto out_err_inval; } + *res = tfm; - kfree(key.data); return p; -out_err_free_tfm: - crypto_free_sync_skcipher(*res); -out_err_free_key: - kfree(key.data); +out_err_inval: p = ERR_PTR(-EINVAL); out_err: return p; @@ -372,14 +376,10 @@ gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask) keyin.data = ctx->Ksess; keyin.len = ctx->gk5e->keylength; - /* seq uses the raw key */ - ctx->seq = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, - ctx->Ksess); + ctx->seq = gss_krb5_alloc_cipher_v1(ctx, &keyin); if (ctx->seq == NULL) goto out_err; - - ctx->enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, - ctx->Ksess); + ctx->enc = gss_krb5_alloc_cipher_v1(ctx, &keyin); if (ctx->enc == NULL) goto out_free_seq; From patchwork Fri Jan 13 15:23:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100961 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BBED7C678D4 for ; Fri, 13 Jan 2023 15:31:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230132AbjAMPbB (ORCPT ); Fri, 13 Jan 2023 10:31:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46242 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230181AbjAMPab (ORCPT ); Fri, 13 Jan 2023 10:30:31 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 849A86167 for ; Fri, 13 Jan 2023 07:23:36 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 21229621BE for ; Fri, 13 Jan 2023 15:23:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 52DDAC433D2; Fri, 13 Jan 2023 15:23:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623415; bh=WipbJzCZIuJ5tqj4ebNKZl0nLcE07pSg4gXCfiaV+LE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=iWBQYt1zqJDMvaOb8lfDsAyEANnOn8rhzEyuy9Sb2kcNseuUUlGDFw8oZmucmqyvQ rR+Njc4TS4oEntQkz4Tpqb6bxgyYKQ3w7wzOZz9jFTiqGOzNNF6+uYUyYDVF3CAXKt BG25iSwkSPxIULRrvaKuyz6T3w25s4NM2InyLcSNMWW9bMNARESA/XVRnOby72Sfbo SEWTGoOkXy8Y9dEeRAjK6T4LiZ0H4iNTUsQ7PaJ6NTfp92FH8PXvqFb4bo5D7MtJu4 6WBUkxgQNCppCGHNSoyLfD4D5U1DpPZiYqtCKxabTy90ur7IUVMXE3IGgXlBOpHUyS rZ6lQhd9YHH/g== Subject: [PATCH v1 20/41] SUNRPC: Parametrize the key length passed to context_v2_alloc_cipher() From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:34 -0500 Message-ID: <167362341444.8960.13636393192226517391.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Although the Kerberos specs have always listed separate subkey lengths, the Linux kernel's SunRPC GSS Kerberos enctype profiles assume the base key and the derived keys have identical lengths. 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. To support that enctype, parametrize context_v2_alloc_cipher() so that each of its call sites can pass in its desired key length. For now it will be the same length as before (gk5e->keylength), but a subsequent patch will change this. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_mech.c | 61 +++++++++++++++-------------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 579ff755d535..b48a06769891 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -341,26 +341,6 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) return PTR_ERR(p); } -static inline struct crypto_sync_skcipher * -context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) -{ - struct crypto_sync_skcipher *cp; - - cp = crypto_alloc_sync_skcipher(cname, 0, 0); - if (IS_ERR(cp)) { - dprintk("gss_kerberos_mech: unable to initialize " - "crypto algorithm %s\n", cname); - return NULL; - } - if (crypto_sync_skcipher_setkey(cp, key, ctx->gk5e->keylength)) { - dprintk("gss_kerberos_mech: error setting key for " - "crypto algorithm %s\n", cname); - crypto_free_sync_skcipher(cp); - return NULL; - } - return cp; -} - #if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED) static int gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask) @@ -403,6 +383,21 @@ gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask) #if defined(CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM) +static struct crypto_sync_skcipher * +gss_krb5_alloc_cipher_v2(const char *cname, const struct xdr_netobj *key) +{ + struct crypto_sync_skcipher *tfm; + + tfm = crypto_alloc_sync_skcipher(cname, 0, 0); + if (IS_ERR(tfm)) + return NULL; + if (crypto_sync_skcipher_setkey(tfm, key->data, key->len)) { + crypto_free_sync_skcipher(tfm); + return NULL; + } + return tfm; +} + static struct crypto_ahash * gss_krb5_alloc_hash_v2(struct krb5_ctx *kctx, const struct xdr_netobj *key) { @@ -427,27 +422,24 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) }; struct xdr_netobj keyout; int ret = -EINVAL; - void *subkey; - subkey = kmalloc(ctx->gk5e->keylength, gfp_mask); - if (!subkey) + keyout.data = kmalloc(ctx->gk5e->keylength, gfp_mask); + if (!keyout.data) return -ENOMEM; keyout.len = ctx->gk5e->keylength; - keyout.data = subkey; /* initiator seal encryption */ if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION, gfp_mask)) goto out; - ctx->initiator_enc = context_v2_alloc_cipher(ctx, - ctx->gk5e->encrypt_name, - subkey); + ctx->initiator_enc = gss_krb5_alloc_cipher_v2(ctx->gk5e->encrypt_name, + &keyout); if (ctx->initiator_enc == NULL) goto out; if (ctx->gk5e->aux_cipher) { ctx->initiator_enc_aux = - context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher, - subkey); + gss_krb5_alloc_cipher_v2(ctx->gk5e->aux_cipher, + &keyout); if (ctx->initiator_enc_aux == NULL) goto out_free; } @@ -456,15 +448,14 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION, gfp_mask)) goto out_free; - ctx->acceptor_enc = context_v2_alloc_cipher(ctx, - ctx->gk5e->encrypt_name, - subkey); + ctx->acceptor_enc = gss_krb5_alloc_cipher_v2(ctx->gk5e->encrypt_name, + &keyout); if (ctx->acceptor_enc == NULL) goto out_free; if (ctx->gk5e->aux_cipher) { ctx->acceptor_enc_aux = - context_v2_alloc_cipher(ctx, ctx->gk5e->aux_cipher, - subkey); + gss_krb5_alloc_cipher_v2(ctx->gk5e->aux_cipher, + &keyout); if (ctx->acceptor_enc_aux == NULL) goto out_free; } @@ -503,7 +494,7 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask) ret = 0; out: - kfree_sensitive(subkey); + kfree_sensitive(keyout.data); return ret; out_free: From patchwork Fri Jan 13 15:23:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100962 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD0E7C67871 for ; Fri, 13 Jan 2023 15:31:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230187AbjAMPbC (ORCPT ); Fri, 13 Jan 2023 10:31:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229868AbjAMPac (ORCPT ); Fri, 13 Jan 2023 10:30:32 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C54385F49C for ; Fri, 13 Jan 2023 07:23:42 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 614636212C for ; Fri, 13 Jan 2023 15:23:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 952E9C433F0; Fri, 13 Jan 2023 15:23:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623421; bh=EflpkU3JaHApkZEMJNADvDghLV7Vh/jHmqORPqgORvw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=gFO9b2P6rKIa+cdbrT5Vc8qafJRM21qiAvzxZezxLMfBto0+C+rc/wSNz7VpcrIW4 8BiZSV02tnTQBeJWRKZ1aw3Ta6j4Nx4A0gwq76MSyyKs00g0PoZlJOtPlwa/rf44iz /70gFI2VBgltfkxLo1y6v8JqpRUWV8s/QNkL/g2VPChg8EVeK1rH1MJmcvZ4cdLy1b 1AtqImsD3rcQ454wsyADUBMkN2dE/L0FJAvyngRtbEEbCpzLZn6yACdoX5O+TsHtNG O45ekTC6cJZQnCmoReccu8mBiggziau5sGLHYC3gwY6D/x/obvFlZTKDPLCe8OXNMb TyeX8MX2gysAw== Subject: [PATCH v1 21/41] SUNRPC: Add new subkey length fields From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:40 -0500 Message-ID: <167362342075.8960.8739690579435009216.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever 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 Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 14 ++++++++++++-- net/sunrpc/auth_gss/gss_krb5_mech.c | 20 ++++++++++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 0c08f4f75b43..48e82397132b 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -44,10 +44,16 @@ #include #include +/* + * 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 */ @@ -70,7 +76,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 b48a06769891..03725f2dd28f 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; From patchwork Fri Jan 13 15:23:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100963 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FA8AC678D4 for ; Fri, 13 Jan 2023 15:31:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229649AbjAMPbE (ORCPT ); Fri, 13 Jan 2023 10:31:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230214AbjAMPae (ORCPT ); Fri, 13 Jan 2023 10:30:34 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B63740875 for ; Fri, 13 Jan 2023 07:23:51 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 907C6B820D4 for ; Fri, 13 Jan 2023 15:23:49 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E372AC433F1; Fri, 13 Jan 2023 15:23:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623428; bh=EnzPB2IMzJhFxI/rUn6PYARmyT9JCmF++Ni+6I4uGT4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=J1CPGOOKWA3sqCOatStRBB6c/RpLsvffWaSxCTrkvGjbQvD/Mdt3C2GR1Zz+lqYTN Eo048zjj2B0mq8oeBu11uf4GKbBYRtEp4PK7O4wOnjNUxcYGnHqKbs1+xK5W+aQPjG Bn8dN5Pzkz9In0KeWItRjOy3hQdpfaPfJXNMTbiroJWLsrvCC8CrFszBeAQtseLTwU BOjjp9sVfxS3OsL42TFCeQmj2Xe/RU0l2Qt47WJkQnnjsp7ee3Fqp9Yq0XmBpOZqsH q6DstIGfs5qKw4cU9AyENiLkIpodPWv6LcAilv/K597+687Hf7QjOqzEhyLcpEWaa0 0EI5nq1R5rTow== Subject: [PATCH v1 22/41] SUNRPC: Refactor CBC with CTS into helpers From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:47 -0500 Message-ID: <167362342701.8960.11272037650804118930.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Cryptosystem profile enctypes all use cipher block chaining with ciphertext steal (CBC-with-CTS). However enctypes that are currently supported in the Linux kernel SunRPC implementation use only the encrypt-&-MAC approach. The RFC 8009 enctypes use encrypt-then-MAC, which performs encryption and checksumming in a different order. Refactor to make it possible to share the CBC with CTS encryption and decryption mechanisms between e&M and etM enctypes. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 187 +++++++++++++++++++-------------- 1 file changed, 105 insertions(+), 82 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 9703881fbd1d..27bfb8c6b931 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -636,6 +636,100 @@ gss_krb5_cts_crypt(struct crypto_sync_skcipher *cipher, struct xdr_buf *buf, return ret; } +/* + * To provide confidentiality, encrypt using cipher block chaining + * with ciphertext stealing. Message integrity is handled separately. + */ +static int +krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, + struct crypto_sync_skcipher *cbc_tfm, + u32 offset, struct xdr_buf *buf, struct page **pages) +{ + u32 blocksize, nbytes, nblocks, cbcbytes; + struct encryptor_desc desc; + int err; + + blocksize = crypto_sync_skcipher_blocksize(cts_tfm); + nbytes = buf->len - offset; + nblocks = (nbytes + blocksize - 1) / blocksize; + cbcbytes = 0; + if (nblocks > 2) + cbcbytes = (nblocks - 2) * blocksize; + + memset(desc.iv, 0, sizeof(desc.iv)); + + /* Handle block-sized chunks of plaintext with CBC. */ + if (cbcbytes) { + SYNC_SKCIPHER_REQUEST_ON_STACK(req, cbc_tfm); + + desc.pos = offset; + desc.fragno = 0; + desc.fraglen = 0; + desc.pages = pages; + desc.outbuf = buf; + desc.req = req; + + skcipher_request_set_sync_tfm(req, cbc_tfm); + skcipher_request_set_callback(req, 0, NULL, NULL); + + sg_init_table(desc.infrags, 4); + sg_init_table(desc.outfrags, 4); + + err = xdr_process_buf(buf, offset, cbcbytes, encryptor, &desc); + skcipher_request_zero(req); + if (err) + return err; + } + + /* Remaining plaintext is handled with CBC-CTS. */ + err = gss_krb5_cts_crypt(cts_tfm, buf, offset + cbcbytes, + desc.iv, pages, 1); + if (err) + return err; + + return 0; +} + +static int +krb5_cbc_cts_decrypt(struct crypto_sync_skcipher *cts_tfm, + struct crypto_sync_skcipher *cbc_tfm, + u32 offset, struct xdr_buf *buf) +{ + u32 blocksize, nblocks, cbcbytes; + struct decryptor_desc desc; + int err; + + blocksize = crypto_sync_skcipher_blocksize(cts_tfm); + nblocks = (buf->len + blocksize - 1) / blocksize; + cbcbytes = 0; + if (nblocks > 2) + cbcbytes = (nblocks - 2) * blocksize; + + memset(desc.iv, 0, sizeof(desc.iv)); + + /* Handle block-sized chunks of plaintext with CBC. */ + if (cbcbytes) { + SYNC_SKCIPHER_REQUEST_ON_STACK(req, cbc_tfm); + + desc.fragno = 0; + desc.fraglen = 0; + desc.req = req; + + skcipher_request_set_sync_tfm(req, cbc_tfm); + skcipher_request_set_callback(req, 0, NULL, NULL); + + sg_init_table(desc.frags, 4); + + err = xdr_process_buf(buf, 0, cbcbytes, decryptor, &desc); + skcipher_request_zero(req); + if (err) + return err; + } + + /* Remaining plaintext is handled with CBC-CTS. */ + return gss_krb5_cts_crypt(cts_tfm, buf, cbcbytes, desc.iv, NULL, 0); +} + u32 gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, struct page **pages) @@ -645,11 +739,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, u8 *ecptr; struct crypto_sync_skcipher *cipher, *aux_cipher; struct crypto_ahash *ahash; - int blocksize; struct page **save_pages; - int nblocks, nbytes; - struct encryptor_desc desc; - u32 cbcbytes; unsigned int conflen; if (kctx->initiate) { @@ -661,7 +751,6 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, aux_cipher = kctx->acceptor_enc_aux; ahash = kctx->acceptor_integ; } - blocksize = crypto_sync_skcipher_blocksize(cipher); conflen = crypto_sync_skcipher_blocksize(cipher); /* hide the gss token header and insert the confounder */ @@ -705,69 +794,30 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, if (err) return GSS_S_FAILURE; - nbytes = buf->len - offset - GSS_KRB5_TOK_HDR_LEN; - nblocks = (nbytes + blocksize - 1) / blocksize; - cbcbytes = 0; - if (nblocks > 2) - cbcbytes = (nblocks - 2) * blocksize; - - memset(desc.iv, 0, sizeof(desc.iv)); - - if (cbcbytes) { - SYNC_SKCIPHER_REQUEST_ON_STACK(req, aux_cipher); - - desc.pos = offset + GSS_KRB5_TOK_HDR_LEN; - desc.fragno = 0; - desc.fraglen = 0; - desc.pages = pages; - desc.outbuf = buf; - desc.req = req; - - skcipher_request_set_sync_tfm(req, aux_cipher); - skcipher_request_set_callback(req, 0, NULL, NULL); - - sg_init_table(desc.infrags, 4); - sg_init_table(desc.outfrags, 4); - - err = xdr_process_buf(buf, offset + GSS_KRB5_TOK_HDR_LEN, - cbcbytes, encryptor, &desc); - skcipher_request_zero(req); - if (err) - goto out_err; - } - - /* Make sure IV carries forward from any CBC results. */ - err = gss_krb5_cts_crypt(cipher, buf, - offset + GSS_KRB5_TOK_HDR_LEN + cbcbytes, - desc.iv, pages, 1); - if (err) { - err = GSS_S_FAILURE; - goto out_err; - } + err = krb5_cbc_cts_encrypt(cipher, aux_cipher, + offset + GSS_KRB5_TOK_HDR_LEN, + buf, pages); + if (err) + return GSS_S_FAILURE; /* Now update buf to account for HMAC */ buf->tail[0].iov_len += kctx->gk5e->cksumlength; buf->len += kctx->gk5e->cksumlength; -out_err: - if (err) - err = GSS_S_FAILURE; - return err; + return GSS_S_COMPLETE; } u32 gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, struct xdr_buf *buf, u32 *headskip, u32 *tailskip) { - struct xdr_buf subbuf; - u32 ret = 0; struct crypto_sync_skcipher *cipher, *aux_cipher; struct crypto_ahash *ahash; struct xdr_netobj our_hmac_obj; u8 our_hmac[GSS_KRB5_MAX_CKSUM_LEN]; u8 pkt_hmac[GSS_KRB5_MAX_CKSUM_LEN]; - int nblocks, blocksize, cbcbytes; - struct decryptor_desc desc; + struct xdr_buf subbuf; + u32 ret = 0; if (kctx->initiate) { cipher = kctx->acceptor_enc; @@ -778,44 +828,17 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, aux_cipher = kctx->initiator_enc_aux; ahash = kctx->initiator_integ; } - blocksize = crypto_sync_skcipher_blocksize(cipher); /* create a segment skipping the header and leaving out the checksum */ xdr_buf_subsegment(buf, &subbuf, offset + GSS_KRB5_TOK_HDR_LEN, (len - offset - GSS_KRB5_TOK_HDR_LEN - kctx->gk5e->cksumlength)); - nblocks = (subbuf.len + blocksize - 1) / blocksize; - - cbcbytes = 0; - if (nblocks > 2) - cbcbytes = (nblocks - 2) * blocksize; - - memset(desc.iv, 0, sizeof(desc.iv)); - - if (cbcbytes) { - SYNC_SKCIPHER_REQUEST_ON_STACK(req, aux_cipher); - - desc.fragno = 0; - desc.fraglen = 0; - desc.req = req; - - skcipher_request_set_sync_tfm(req, aux_cipher); - skcipher_request_set_callback(req, 0, NULL, NULL); - - sg_init_table(desc.frags, 4); - - ret = xdr_process_buf(&subbuf, 0, cbcbytes, decryptor, &desc); - skcipher_request_zero(req); - if (ret) - goto out_err; - } - - /* Make sure IV carries forward from any CBC results. */ - ret = gss_krb5_cts_crypt(cipher, &subbuf, cbcbytes, desc.iv, NULL, 0); + ret = krb5_cbc_cts_decrypt(cipher, aux_cipher, 0, &subbuf); if (ret) goto out_err; + /* Calculate our hmac over the plaintext data */ our_hmac_obj.len = sizeof(our_hmac); our_hmac_obj.data = our_hmac; ret = gss_krb5_checksum(ahash, NULL, 0, &subbuf, 0, &our_hmac_obj); @@ -832,7 +855,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, ret = GSS_S_BAD_SIG; goto out_err; } - *headskip = blocksize; + *headskip = crypto_sync_skcipher_blocksize(cipher); *tailskip = kctx->gk5e->cksumlength; out_err: if (ret && ret != GSS_S_BAD_SIG) From patchwork Fri Jan 13 15:23:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100964 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE747C678D7 for ; Fri, 13 Jan 2023 15:31:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230029AbjAMPbF (ORCPT ); Fri, 13 Jan 2023 10:31:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46470 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229946AbjAMPaf (ORCPT ); Fri, 13 Jan 2023 10:30:35 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7426C40872 for ; Fri, 13 Jan 2023 07:23:55 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 1076F6216C for ; Fri, 13 Jan 2023 15:23:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 410D4C433D2; Fri, 13 Jan 2023 15:23:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623434; bh=SPE4OES7E53PZuWloxl19HAGVSW5b4YeUxi9yH1dpgk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=AiCFSDODvmYTP9yO3fm7LAhwx2etSKKC9U9iUagDs4Kp87DRIskImqAHnjt5/6n59 1mJFNHiF0/UQgf+/uv7T1QLZvEmZYIILGEu9gyDz07zuqaIfXbJMCqOcUU507QefwF L9BbtKQvyEPnxrgKlEOA7AEgtIIlhuml6aR5knhBRa5w+s+Vh5UHI7si3X56E1DvNl GCpkN2phQLYYOJv3eJheHJtQPM+LXFK4cufCfn3zPwopCVeQdzdC9YTcw5gXYwUd0G D+un2lYhXZuwEz/RdsSDklIw7bUvQbccdUAZ8w9jRCpkXFHzAQbLgUraKlFPJaSogz fdefm0IBS6pOw== Subject: [PATCH v1 23/41] SUNRPC: Add gk5e definitions for RFC 8009 encryption types From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:53 -0500 Message-ID: <167362343334.8960.5026720275533111412.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Fill in entries in the supported_gss_krb5_enctypes array for the encryption types defined in RFC 8009. These new enctypes use the SHA-256 and SHA-384 message digest algorithms (as defined in FIPS-180) instead of the deprecated SHA-1 algorithm, and are thus more secure. Note that NIST has scheduled SHA-1 for deprecation: https://www.nist.gov/news-events/news/2022/12/nist-retires-sha-1-cryptographic-algorithm Thus these new encryption types are placed under a separate CONFIG option to enable distributors to separately introduce support for the AES-SHA2 enctypes and deprecate support for the current set of AES-SHA1 encryption types as their user space allows. As this implementation is still a "beta", the default is to not build it automatically. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 19 ++++++++++++- net/sunrpc/Kconfig | 14 ++++++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 51 +++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index 48e82397132b..be2fa13ef0f8 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -56,8 +56,8 @@ /* 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 */ -#define GSS_KRB5_MAX_CKSUM_LEN (20) +/* Maximum checksum function output for the supported enctypes */ +#define GSS_KRB5_MAX_CKSUM_LEN (24) /* Maximum blocksize for the supported crypto algorithms */ #define GSS_KRB5_MAX_BLOCKSIZE (16) @@ -164,6 +164,12 @@ enum seal_alg { SEAL_ALG_DES3KD = 0x0002 }; +/* + * These values are assigned by IANA and published via the + * subregistry at the link below: + * + * https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-2 + */ #define CKSUMTYPE_CRC32 0x0001 #define CKSUMTYPE_RSA_MD4 0x0002 #define CKSUMTYPE_RSA_MD4_DES 0x0003 @@ -174,6 +180,8 @@ enum seal_alg { #define CKSUMTYPE_HMAC_SHA1_DES3 0x000c #define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f #define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010 +#define CKSUMTYPE_HMAC_SHA256_128_AES128 0x0013 +#define CKSUMTYPE_HMAC_SHA384_192_AES256 0x0014 #define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /* Microsoft md5 hmac cksumtype */ /* from gssapi_err_krb5.h */ @@ -194,6 +202,11 @@ enum seal_alg { /* per Kerberos v5 protocol spec crypto types from the wire. * these get mapped to linux kernel crypto routines. + * + * These values are assigned by IANA and published via the + * subregistry at the link below: + * + * https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml#kerberos-parameters-1 */ #define ENCTYPE_NULL 0x0000 #define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */ @@ -207,6 +220,8 @@ enum seal_alg { #define ENCTYPE_DES3_CBC_SHA1 0x0010 #define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011 #define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012 +#define ENCTYPE_AES128_CTS_HMAC_SHA256_128 0x0013 +#define ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014 #define ENCTYPE_ARCFOUR_HMAC 0x0017 #define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018 #define ENCTYPE_UNKNOWN 0x01ff diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig index 1135ff362132..b1aa2318e1dc 100644 --- a/net/sunrpc/Kconfig +++ b/net/sunrpc/Kconfig @@ -76,6 +76,20 @@ config RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1 SHA-1 digests. These include aes128-cts-hmac-sha1-96 and aes256-cts-hmac-sha1-96. +config RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2 + bool "Enable Kerberos enctypes based on AES and SHA-2" + depends on RPCSEC_GSS_KRB5 + depends on CRYPTO_CBC && CRYPTO_CTS + depends on CRYPTO_HMAC && CRYPTO_SHA256 && CRYPTO_SHA512 + depends on CRYPTO_AES + default n + select RPCSEC_GSS_KRB5_CRYPTOSYSTEM + help + Choose Y to enable the use of Kerberos 5 encryption types + that utilize Advanced Encryption Standard (AES) ciphers and + SHA-2 digests. These include aes128-cts-hmac-sha256-128 and + aes256-cts-hmac-sha384-192. + config SUNRPC_DEBUG bool "RPC: Enable dprintk debugging" depends on SUNRPC && SYSCTL diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 03725f2dd28f..bfcd13e6eb18 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -146,6 +146,57 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .keyed_cksum = 1, }, #endif + +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2) + /* + * AES-128 with SHA-256 (RFC 8009) + */ + { + .etype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .ctype = CKSUMTYPE_HMAC_SHA256_128_AES128, + .name = "aes128-cts-hmac-sha256-128", + .encrypt_name = "cts(cbc(aes))", + .aux_cipher = "cbc(aes)", + .cksum_name = "hmac(sha256)", + .cksumlength = BITS2OCTETS(128), + .keyed_cksum = 1, + .keylength = BITS2OCTETS(128), + .Kc_length = BITS2OCTETS(128), + .Ke_length = BITS2OCTETS(128), + .Ki_length = BITS2OCTETS(128), + + .import_ctx = gss_krb5_import_ctx_v2, + + .get_mic = gss_krb5_get_mic_v2, + .verify_mic = gss_krb5_verify_mic_v2, + .wrap = gss_krb5_wrap_v2, + .unwrap = gss_krb5_unwrap_v2, + }, + /* + * AES-256 with SHA-384 (RFC 8009) + */ + { + .etype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .ctype = CKSUMTYPE_HMAC_SHA384_192_AES256, + .name = "aes256-cts-hmac-sha384-192", + .encrypt_name = "cts(cbc(aes))", + .aux_cipher = "cbc(aes)", + .cksum_name = "hmac(sha384)", + .cksumlength = BITS2OCTETS(192), + .keyed_cksum = 1, + .keylength = BITS2OCTETS(256), + .Kc_length = BITS2OCTETS(192), + .Ke_length = BITS2OCTETS(256), + .Ki_length = BITS2OCTETS(192), + + .import_ctx = gss_krb5_import_ctx_v2, + + .get_mic = gss_krb5_get_mic_v2, + .verify_mic = gss_krb5_verify_mic_v2, + .wrap = gss_krb5_wrap_v2, + .unwrap = gss_krb5_unwrap_v2, + }, +#endif }; /* From patchwork Fri Jan 13 15:23:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100965 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25E3CC54EBE for ; Fri, 13 Jan 2023 15:31:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230193AbjAMPbS (ORCPT ); Fri, 13 Jan 2023 10:31:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230003AbjAMPaj (ORCPT ); Fri, 13 Jan 2023 10:30:39 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE87E7ECAE for ; Fri, 13 Jan 2023 07:24:03 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 33A6BB820D4 for ; Fri, 13 Jan 2023 15:24:02 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 873BEC433D2; Fri, 13 Jan 2023 15:24:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623440; bh=7Kj8AQXfW1wRp279GQLla/GlVkbmwX1X193sBM3n3zM=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=BWZ34QMmeEyOd7NOVc9l3AKNaUTrht4lDN8kDmaY9B4J7cbK6jYaagHKBsCiTYVSl Lrr2r04Acz/JW/YO7uCgAHvqc/Hqeu/N6HUMA+LzMZOYQXQFeHnJHgG/NAu0J0RzJT ArvudPoYNR27o6XeeUlLmqjPwSgwH9dzCfoQhTYnzE0c5y76hLUbkUynEofLLHmrfR G2KNyK06+TAxqNptbUN48OtHvn96Hvjyw4BRQh0NkpGBSq8kgUPRL4eYYynRYkGDW1 ScGeaOEaDOzi+s7olOwQiJccpQqzMXhjHA+DWmkq0fG68G2j4GXcGOB74xmptSsorh n9QzJ+yEGUdNA== Subject: [PATCH v1 24/41] SUNRPC: Add KDF-HMAC-SHA2 From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:23:59 -0500 Message-ID: <167362343968.8960.15888057547200220750.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever The RFC 8009 encryption types use a different key derivation function than the RFC 3962 encryption types. The new key derivation function is defined in Section 3 of RFC 8009. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_internal.h | 6 ++ net/sunrpc/auth_gss/gss_krb5_keys.c | 117 +++++++++++++++++++++++++++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 2 + 3 files changed, 125 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index e1c61c267dad..818a5fd89a8f 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -52,6 +52,12 @@ int krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, const struct xdr_netobj *label, gfp_t gfp_mask); +int krb5_kdf_hmac_sha2(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *in_constant, + gfp_t gfp_mask); + /** * krb5_derive_key - Derive a subkey from a protocol key * @kctx: Kerberos 5 context diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index f6de4fdd63ae..724be20f5417 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c @@ -60,6 +60,7 @@ #include #include #include +#include #include "gss_krb5_internal.h" @@ -361,3 +362,119 @@ int krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, kfree_sensitive(inblock.data); return ret; } + +/* + * K1 = HMAC-SHA(key, 0x00000001 | label | 0x00 | k) + * + * key: The source of entropy from which subsequent keys are derived. + * + * label: An octet string describing the intended usage of the + * derived key. + * + * k: Length in bits of the key to be outputted, expressed in + * big-endian binary representation in 4 bytes. + */ +static int +krb5_hmac_K1(struct crypto_shash *tfm, const struct xdr_netobj *label, + u32 outlen, struct xdr_netobj *K1) +{ + __be32 k = cpu_to_be32(outlen * 8); + SHASH_DESC_ON_STACK(desc, tfm); + __be32 one = cpu_to_be32(1); + u8 zero = 0; + int ret; + + desc->tfm = tfm; + ret = crypto_shash_init(desc); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, (u8 *)&one, sizeof(one)); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, label->data, label->len); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, &zero, sizeof(zero)); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, (u8 *)&k, sizeof(k)); + if (ret) + goto out_err; + ret = crypto_shash_final(desc, K1->data); + if (ret) + goto out_err; + +out_err: + shash_desc_zero(desc); + return ret; +} + +/** + * krb5_kdf_hmac_sha2 - Derive a subkey for an AES/SHA2-based enctype + * @gk5e: Kerberos 5 enctype policy parameters + * @inkey: base protocol key + * @outkey: OUT: derived key + * @label: subkey usage label + * @gfp_mask: memory allocation control flags + * + * RFC 8009 Section 3: + * + * "We use a key derivation function from Section 5.1 of [SP800-108], + * which uses the HMAC algorithm as the PRF." + * + * function KDF-HMAC-SHA2(key, label, [context,] k): + * k-truncate(K1) + * + * Caller sets @outkey->len to the desired length of the derived key. + * + * On success, returns 0 and fills in @outkey. A negative errno value + * is returned on failure. + */ +int +krb5_kdf_hmac_sha2(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *label, + gfp_t gfp_mask) +{ + struct crypto_shash *tfm; + struct xdr_netobj K1 = { + .data = NULL, + }; + int ret; + + /* + * This implementation assumes the HMAC used for an enctype's + * key derivation is the same as the HMAC used for its + * checksumming. This happens to be true for enctypes that + * are currently supported by this implementation. + */ + tfm = crypto_alloc_shash(gk5e->cksum_name, 0, 0); + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + goto out; + } + ret = crypto_shash_setkey(tfm, inkey->data, inkey->len); + if (ret) + goto out_free_tfm; + + K1.len = crypto_shash_digestsize(tfm); + K1.data = kmalloc(K1.len, gfp_mask); + if (!K1.data) { + ret = -ENOMEM; + goto out_free_tfm; + } + + ret = krb5_hmac_K1(tfm, label, outkey->len, &K1); + if (ret) + goto out_free_tfm; + + /* k-truncate and random-to-key */ + memcpy(outkey->data, K1.data, outkey->len); + +out_free_tfm: + kfree_sensitive(K1.data); + crypto_free_shash(tfm); +out: + return ret; +} diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index bfcd13e6eb18..95a041a80e21 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -166,6 +166,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .Ki_length = BITS2OCTETS(128), .import_ctx = gss_krb5_import_ctx_v2, + .derive_key = krb5_kdf_hmac_sha2, .get_mic = gss_krb5_get_mic_v2, .verify_mic = gss_krb5_verify_mic_v2, @@ -190,6 +191,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .Ki_length = BITS2OCTETS(192), .import_ctx = gss_krb5_import_ctx_v2, + .derive_key = krb5_kdf_hmac_sha2, .get_mic = gss_krb5_get_mic_v2, .verify_mic = gss_krb5_verify_mic_v2, From patchwork Fri Jan 13 15:24:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100966 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A135CC54EBD for ; Fri, 13 Jan 2023 15:31:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229585AbjAMPb0 (ORCPT ); Fri, 13 Jan 2023 10:31:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229669AbjAMPax (ORCPT ); Fri, 13 Jan 2023 10:30:53 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29E73727AE for ; Fri, 13 Jan 2023 07:24:10 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id DE02BCE20EA for ; Fri, 13 Jan 2023 15:24:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D6D41C433F0; Fri, 13 Jan 2023 15:24:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623447; bh=0LPtWDYopNVHoUKc6pVsLieucuZ7BDcBrs7Av4pM8OE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=FvyG942YYoAqaeiac5OQ7O8yeazU2ivOAnFsz1ZOQfz1yZ7NpWWtvy5fHITdsJq0r pLUoVPQjOIxXFuNzd+9Ou88xQ1GIYH+UxlB02xieC35BSC+t7OBWP+aThVqE/3bUKA Dt3Jh40ihPRTnWsfVUviMiXF/PDomZy6yF1qDlwvyRn432noxowTj4WvZegSbUeFv9 tjQDea2N4gNKPZIn09rhK5H9C7+p4CKc6I+rBwEWbYdwjJ/LIZ6tgGRauOiBnWr32n o9MwBoM0rFDqcTt7MbHxn9Km0upKAQ08241nYypRkIVVYi97Fr3cUBqQE2/JpnktWG sSqwDpvK/5WoA== Subject: [PATCH v1 25/41] SUNRPC: Add RFC 8009 encryption and decryption functions From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:05 -0500 Message-ID: <167362344597.8960.11361135105165588212.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever RFC 8009 enctypes use different crypt formulae than previous Kerberos 5 encryption types. Section 1 of RFC 8009 explains the reason for this change: > The new types conform to the framework specified in [RFC3961], > but do not use the simplified profile, as the simplified profile > is not compliant with modern cryptographic best practices such as > calculating Message Authentication Codes (MACs) over ciphertext > rather than plaintext. Add new .encrypt and .decrypt functions to handle this variation. The new approach described above is referred to as Encrypt-then-MAC (or EtM). Hence the names of the new functions added here are prefixed with "krb5_etm_". A critical second difference with previous crypt formulae is that the cipher state is included in the computed HMAC. Note however that for RPCSEC, the initial cipher state is easy to compute on both initiator and acceptor because it is always all zeroes. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 227 +++++++++++++++++++++++++++++++ net/sunrpc/auth_gss/gss_krb5_internal.h | 6 + net/sunrpc/auth_gss/gss_krb5_mech.c | 4 + 3 files changed, 237 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 27bfb8c6b931..9112b3f87e72 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -862,3 +862,230 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, ret = GSS_S_FAILURE; return ret; } + +static u32 +krb5_etm_checksum(struct crypto_sync_skcipher *cipher, + struct crypto_ahash *tfm, const struct xdr_buf *body, + int body_offset, struct xdr_netobj *cksumout) +{ + unsigned int ivsize = crypto_sync_skcipher_ivsize(cipher); + struct ahash_request *req; + struct scatterlist sg[1]; + u8 *iv, *checksumdata; + int err = -ENOMEM; + + checksumdata = kmalloc(crypto_ahash_digestsize(tfm), GFP_KERNEL); + if (!checksumdata) + return GSS_S_FAILURE; + /* For RPCSEC, the "initial cipher state" is always all zeroes. */ + iv = kzalloc(ivsize, GFP_KERNEL); + if (!iv) + goto out_free_mem; + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) + goto out_free_mem; + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); + err = crypto_ahash_init(req); + if (err) + goto out_free_ahash; + + sg_init_one(sg, iv, ivsize); + ahash_request_set_crypt(req, sg, NULL, ivsize); + err = crypto_ahash_update(req); + if (err) + goto out_free_ahash; + err = xdr_process_buf(body, body_offset, body->len - body_offset, + checksummer, req); + if (err) + goto out_free_ahash; + + ahash_request_set_crypt(req, NULL, checksumdata, 0); + err = crypto_ahash_final(req); + if (err) + goto out_free_ahash; + memcpy(cksumout->data, checksumdata, cksumout->len); + +out_free_ahash: + ahash_request_free(req); +out_free_mem: + kfree(iv); + kfree_sensitive(checksumdata); + return err ? GSS_S_FAILURE : GSS_S_COMPLETE; +} + +/** + * krb5_etm_encrypt - Encrypt using the RFC 8009 rules + * @kctx: Kerberos context + * @offset: starting offset of the payload, in bytes + * @buf: OUT: send buffer to contain the encrypted payload + * @pages: plaintext payload + * + * The main difference with aes_encrypt is that "The HMAC is + * calculated over the cipher state concatenated with the AES + * output, instead of being calculated over the confounder and + * plaintext. This allows the message receiver to verify the + * integrity of the message before decrypting the message." + * + * RFC 8009 Section 5: + * + * encryption function: as follows, where E() is AES encryption in + * CBC-CS3 mode, and h is the size of truncated HMAC (128 bits or + * 192 bits as described above). + * + * N = random value of length 128 bits (the AES block size) + * IV = cipher state + * C = E(Ke, N | plaintext, IV) + * H = HMAC(Ki, IV | C) + * ciphertext = C | H[1..h] + * + * This encryption formula provides AEAD EtM with key separation. + * + * Return values: + * %GSS_S_COMPLETE: Encryption successful + * %GSS_S_FAILURE: Encryption failed + */ +u32 +krb5_etm_encrypt(struct krb5_ctx *kctx, u32 offset, + struct xdr_buf *buf, struct page **pages) +{ + struct crypto_sync_skcipher *cipher, *aux_cipher; + struct crypto_ahash *ahash; + struct xdr_netobj hmac; + unsigned int conflen; + u8 *ecptr; + u32 err; + + if (kctx->initiate) { + cipher = kctx->initiator_enc; + aux_cipher = kctx->initiator_enc_aux; + ahash = kctx->initiator_integ; + } else { + cipher = kctx->acceptor_enc; + aux_cipher = kctx->acceptor_enc_aux; + ahash = kctx->acceptor_integ; + } + conflen = crypto_sync_skcipher_blocksize(cipher); + + offset += GSS_KRB5_TOK_HDR_LEN; + if (xdr_extend_head(buf, offset, conflen)) + return GSS_S_FAILURE; + krb5_make_confounder(kctx, buf->head[0].iov_base + offset, conflen); + offset -= GSS_KRB5_TOK_HDR_LEN; + + if (buf->tail[0].iov_base) { + ecptr = buf->tail[0].iov_base + buf->tail[0].iov_len; + } else { + buf->tail[0].iov_base = buf->head[0].iov_base + + buf->head[0].iov_len; + buf->tail[0].iov_len = 0; + ecptr = buf->tail[0].iov_base; + } + + memcpy(ecptr, buf->head[0].iov_base + offset, GSS_KRB5_TOK_HDR_LEN); + buf->tail[0].iov_len += GSS_KRB5_TOK_HDR_LEN; + buf->len += GSS_KRB5_TOK_HDR_LEN; + + err = krb5_cbc_cts_encrypt(cipher, aux_cipher, + offset + GSS_KRB5_TOK_HDR_LEN, + buf, pages); + if (err) + return GSS_S_FAILURE; + + hmac.data = buf->tail[0].iov_base + buf->tail[0].iov_len; + hmac.len = kctx->gk5e->cksumlength; + err = krb5_etm_checksum(cipher, ahash, + buf, offset + GSS_KRB5_TOK_HDR_LEN, &hmac); + if (err) + goto out_err; + buf->tail[0].iov_len += kctx->gk5e->cksumlength; + buf->len += kctx->gk5e->cksumlength; + + return GSS_S_COMPLETE; + +out_err: + return GSS_S_FAILURE; +} + +/** + * krb5_etm_decrypt - Decrypt using the RFC 8009 rules + * @kctx: Kerberos context + * @offset: starting offset of the ciphertext, in bytes + * @len: + * @buf: + * @headskip: OUT: the enctype's confounder length, in octets + * @tailskip: OUT: the enctype's HMAC length, in octets + * + * RFC 8009 Section 5: + * + * decryption function: as follows, where D() is AES decryption in + * CBC-CS3 mode, and h is the size of truncated HMAC. + * + * (C, H) = ciphertext + * (Note: H is the last h bits of the ciphertext.) + * IV = cipher state + * if H != HMAC(Ki, IV | C)[1..h] + * stop, report error + * (N, P) = D(Ke, C, IV) + * + * Return values: + * %GSS_S_COMPLETE: Decryption successful + * %GSS_S_BAD_SIG: computed HMAC != received HMAC + * %GSS_S_FAILURE: Decryption failed + */ +u32 +krb5_etm_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, + struct xdr_buf *buf, u32 *headskip, u32 *tailskip) +{ + struct crypto_sync_skcipher *cipher, *aux_cipher; + u8 our_hmac[GSS_KRB5_MAX_CKSUM_LEN]; + u8 pkt_hmac[GSS_KRB5_MAX_CKSUM_LEN]; + struct xdr_netobj our_hmac_obj; + struct crypto_ahash *ahash; + struct xdr_buf subbuf; + u32 ret = 0; + + if (kctx->initiate) { + cipher = kctx->acceptor_enc; + aux_cipher = kctx->acceptor_enc_aux; + ahash = kctx->acceptor_integ; + } else { + cipher = kctx->initiator_enc; + aux_cipher = kctx->initiator_enc_aux; + ahash = kctx->initiator_integ; + } + + /* Extract the ciphertext into @subbuf. */ + xdr_buf_subsegment(buf, &subbuf, offset + GSS_KRB5_TOK_HDR_LEN, + (len - offset - GSS_KRB5_TOK_HDR_LEN - + kctx->gk5e->cksumlength)); + + our_hmac_obj.data = our_hmac; + our_hmac_obj.len = kctx->gk5e->cksumlength; + ret = krb5_etm_checksum(cipher, ahash, &subbuf, 0, &our_hmac_obj); + if (ret) + goto out_err; + ret = read_bytes_from_xdr_buf(buf, len - kctx->gk5e->cksumlength, + pkt_hmac, kctx->gk5e->cksumlength); + if (ret) + goto out_err; + if (crypto_memneq(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) != 0) { + ret = GSS_S_BAD_SIG; + goto out_err; + } + + ret = krb5_cbc_cts_decrypt(cipher, aux_cipher, 0, &subbuf); + if (ret) { + ret = GSS_S_FAILURE; + goto out_err; + } + + *headskip = crypto_sync_skcipher_blocksize(cipher); + *tailskip = kctx->gk5e->cksumlength; + return GSS_S_COMPLETE; + +out_err: + if (ret != GSS_S_BAD_SIG) + ret = GSS_S_FAILURE; + return ret; +} diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index 818a5fd89a8f..d16563afaeae 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -108,4 +108,10 @@ u32 gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, u32 gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, struct xdr_buf *buf, u32 *plainoffset, u32 *plainlen); +u32 krb5_etm_encrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, + struct page **pages); + +u32 krb5_etm_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, + struct xdr_buf *buf, u32 *headskip, u32 *tailskip); + #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 95a041a80e21..fa0b5197fe32 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -167,6 +167,8 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .import_ctx = gss_krb5_import_ctx_v2, .derive_key = krb5_kdf_hmac_sha2, + .encrypt = krb5_etm_encrypt, + .decrypt = krb5_etm_decrypt, .get_mic = gss_krb5_get_mic_v2, .verify_mic = gss_krb5_verify_mic_v2, @@ -192,6 +194,8 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .import_ctx = gss_krb5_import_ctx_v2, .derive_key = krb5_kdf_hmac_sha2, + .encrypt = krb5_etm_encrypt, + .decrypt = krb5_etm_decrypt, .get_mic = gss_krb5_get_mic_v2, .verify_mic = gss_krb5_verify_mic_v2, From patchwork Fri Jan 13 15:24:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100967 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EBA22C61DB3 for ; Fri, 13 Jan 2023 15:31:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229499AbjAMPb2 (ORCPT ); Fri, 13 Jan 2023 10:31:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229626AbjAMPa5 (ORCPT ); Fri, 13 Jan 2023 10:30:57 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 292FC81415 for ; Fri, 13 Jan 2023 07:24:16 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id D0416B820D4 for ; Fri, 13 Jan 2023 15:24:14 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 335DCC433D2; Fri, 13 Jan 2023 15:24:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623453; bh=/1wdiSxGD1EpIWl77hZrX3dtHUMY3lKRAFpNBcpkmPI=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=SiuKfW+3H/dbjDU5OoPqrDiIqeTP7tuc5z3lRFPU1KW6UmW/OezmWozpveOdQRuxr 81iOrdeHPPS7eaemGCtviSvRrfoX8DDcZowGH7SMlxAvMRbpqzBBZVmRfwOMQprJxi 5bo6pgj8zuZoCMxQuHr7Sy3YALCV236RnBEsAl+QErcq8Y0w5fP5Xc9EukzluaeQaB XasjjhtjeYJBrIZPuxRCydKjxc6mCe9rcC42qy7rykHL8ehCyJ9KnHCFJAhM2Rat7s Jc8s02FAibyU/XLeWq/7o/nEb+yWYGOfIqvizHEWXUeLzHhxfQCLGwQt/EOUoB3pFy mIXghzKqqHuUQ== Subject: [PATCH v1 26/41] SUNRPC: Advertise support for RFC 8009 encryption types From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:12 -0500 Message-ID: <167362345228.8960.10652140004514370977.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Add the RFC 8009 encryption types to the string of integers that is reported to gssd during upcalls. This enables gssd to utilize keys with these encryption types when support for them is built into the kernel. Link: https://bugzilla.linux-nfs.org/show_bug.cgi?id=400 Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_mech.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index fa0b5197fe32..6ef0c7247692 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -214,6 +214,10 @@ static char gss_krb5_enctype_priority_list[64]; static void gss_krb5_prepare_enctype_priority_list(void) { static const u32 gss_krb5_enctypes[] = { +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2) + ENCTYPE_AES256_CTS_HMAC_SHA384_192, + ENCTYPE_AES128_CTS_HMAC_SHA256_128, +#endif #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1) ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, From patchwork Fri Jan 13 15:24:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100968 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0AB7C54EBD for ; Fri, 13 Jan 2023 15:31:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230181AbjAMPbd (ORCPT ); Fri, 13 Jan 2023 10:31:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52902 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230285AbjAMPbC (ORCPT ); Fri, 13 Jan 2023 10:31:02 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7CB287F44E for ; Fri, 13 Jan 2023 07:24:22 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 36E2DB8217C for ; Fri, 13 Jan 2023 15:24:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8C939C433D2; Fri, 13 Jan 2023 15:24:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623459; bh=wLNFQ62gO3qvVph+feQ3fR5k/xvC31rL2hskLqvcCsQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=mrWry2aC96Mfzsq3rNQAkT61ioPc8pheu9RTapq3DH0ENmnoP2Y2dy6FpEdUGNIiL 4DcMdnx5eoe9wI6e7VjUV2FBkC+jUby39Ex00PyJBpLydSAgwiGptMcKwH4TqewFwI APFt62acqWjSZvVUUG/ax6I+qCQ8UGwMG8O2K0cSYAh0cDSuSFlB7i2e00OyD8Vfrs qWgfK6tUhgu/i2vLVxuNaHIz5UxWfDnWsC4h0N//066mjB0QG3HxdxiY+s5hiSn5f3 b8sz2XQaXjcuxM2KZ66MXswvHBGytEKvFv6hsCr9DTlM+DkVsWFotVzf9VxrZx3uXA t6u8V/k4ClQhg== Subject: [PATCH v1 27/41] SUNRPC: Support the Camellia enctypes From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:18 -0500 Message-ID: <167362345862.8960.15211879325024928060.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever RFC 6803 defines two encryption types that use Camellia ciphers (RFC 3713) and CMAC digests. Implement support for those in SunRPC's GSS Kerberos 5 mechanism. There has not been an explicit request to support these enctypes. However, this new set of enctypes provides a good alternative to the AES-SHA1 enctypes that are to be deprecated at some point. As this implementation is still a "beta", the default is to not build it automatically. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 4 +++ net/sunrpc/Kconfig | 13 ++++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 55 +++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index be2fa13ef0f8..e5d9a94cf394 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -180,6 +180,8 @@ enum seal_alg { #define CKSUMTYPE_HMAC_SHA1_DES3 0x000c #define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f #define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010 +#define CKSUMTYPE_CMAC_CAMELLIA128 0x0011 +#define CKSUMTYPE_CMAC_CAMELLIA256 0x0012 #define CKSUMTYPE_HMAC_SHA256_128_AES128 0x0013 #define CKSUMTYPE_HMAC_SHA384_192_AES256 0x0014 #define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /* Microsoft md5 hmac cksumtype */ @@ -224,6 +226,8 @@ enum seal_alg { #define ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014 #define ENCTYPE_ARCFOUR_HMAC 0x0017 #define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018 +#define ENCTYPE_CAMELLIA128_CTS_CMAC 0x0019 +#define ENCTYPE_CAMELLIA256_CTS_CMAC 0x001A #define ENCTYPE_UNKNOWN 0x01ff /* diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig index b1aa2318e1dc..def7e1ce348b 100644 --- a/net/sunrpc/Kconfig +++ b/net/sunrpc/Kconfig @@ -76,6 +76,19 @@ config RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1 SHA-1 digests. These include aes128-cts-hmac-sha1-96 and aes256-cts-hmac-sha1-96. +config RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA + bool "Enable Kerberos encryption types based on Camellia and CMAC" + depends on RPCSEC_GSS_KRB5 + depends on CRYPTO_CBC && CRYPTO_CTS && CRYPTO_CAMELLIA + depends on CRYPTO_CMAC + default n + select RPCSEC_GSS_KRB5_CRYPTOSYSTEM + help + Choose Y to enable the use of Kerberos 5 encryption types + that utilize Camellia ciphers (RFC 3713) and CMAC digests + (NIST Special Publication 800-38B). These include + camellia128-cts-cmac and camellia256-cts-cmac. + config RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2 bool "Enable Kerberos enctypes based on AES and SHA-2" depends on RPCSEC_GSS_KRB5 diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 6ef0c7247692..5f9c79e404f4 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -147,6 +147,61 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { }, #endif +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA) + /* + * Camellia-128 with CMAC (RFC 6803) + */ + { + .etype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .ctype = CKSUMTYPE_CMAC_CAMELLIA128, + .name = "camellia128-cts-cmac", + .encrypt_name = "cts(cbc(camellia))", + .aux_cipher = "cbc(camellia)", + .cksum_name = "cmac(camellia)", + .cksumlength = BITS2OCTETS(128), + .keyed_cksum = 1, + .keylength = BITS2OCTETS(128), + .Kc_length = BITS2OCTETS(128), + .Ke_length = BITS2OCTETS(128), + .Ki_length = BITS2OCTETS(128), + + .import_ctx = gss_krb5_import_ctx_v2, + .encrypt = gss_krb5_aes_encrypt, + .decrypt = gss_krb5_aes_decrypt, + + .get_mic = gss_krb5_get_mic_v2, + .verify_mic = gss_krb5_verify_mic_v2, + .wrap = gss_krb5_wrap_v2, + .unwrap = gss_krb5_unwrap_v2, + }, + /* + * Camellia-256 with CMAC (RFC 6803) + */ + { + .etype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .ctype = CKSUMTYPE_CMAC_CAMELLIA256, + .name = "camellia256-cts-cmac", + .encrypt_name = "cts(cbc(camellia))", + .aux_cipher = "cbc(camellia)", + .cksum_name = "cmac(camellia)", + .cksumlength = BITS2OCTETS(128), + .keyed_cksum = 1, + .keylength = BITS2OCTETS(256), + .Kc_length = BITS2OCTETS(256), + .Ke_length = BITS2OCTETS(256), + .Ki_length = BITS2OCTETS(256), + + .import_ctx = gss_krb5_import_ctx_v2, + .encrypt = gss_krb5_aes_encrypt, + .decrypt = gss_krb5_aes_decrypt, + + .get_mic = gss_krb5_get_mic_v2, + .verify_mic = gss_krb5_verify_mic_v2, + .wrap = gss_krb5_wrap_v2, + .unwrap = gss_krb5_unwrap_v2, + }, +#endif + #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2) /* * AES-128 with SHA-256 (RFC 8009) From patchwork Fri Jan 13 15:24:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100969 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0A14C61DB3 for ; Fri, 13 Jan 2023 15:31:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230268AbjAMPbe (ORCPT ); Fri, 13 Jan 2023 10:31:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229762AbjAMPbD (ORCPT ); Fri, 13 Jan 2023 10:31:03 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D41CB92356 for ; Fri, 13 Jan 2023 07:24:28 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 86E0AB8217A for ; Fri, 13 Jan 2023 15:24:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D4D28C433F0; Fri, 13 Jan 2023 15:24:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623466; bh=7VCbesUwm2oJkjkxA9BkaISBMa0P5PxUZ2+lsJJoWVA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=E47baRFhIZAkEUJ1AvV4itbrz4Ti+h/SfMSLI4s7J3dNS7+fxPOOYcnkdX0lUyqHl 2aXUWXV8rz1Tkxar8+X/ly7z3kUmVtzKm044yElVy6zZ0UPEN3+uUgRaKCRDW9Ntl+ 1w6At8b+jfkUaLbolynpF3sg3KmQ8n9Pv5AGVhD8XcS5qxQaMmbt0B0dypptIMl9js loNoRl+9zhwPhPI8C+9ye3os7tbbLZOh+tocB7pbiCOwC9USzXe0OI+gEO+qH6HqT8 QRCTsMbZjeP6kSVThYJctkjWnTG1CrvFFQ2mwLgWTd0HaAk3ver+Cjks8QXh51P5Fr 6idmyDVDulgvA== Subject: [PATCH v1 28/41] SUNRPC: Add KDF_FEEDBACK_CMAC From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:24 -0500 Message-ID: <167362346499.8960.1910934713524280944.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever The Camellia enctypes use the KDF_FEEDBACK_CMAC Key Derivation Function defined in RFC 6803 Section 3. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_internal.h | 6 + net/sunrpc/auth_gss/gss_krb5_keys.c | 143 +++++++++++++++++++++++++++++++ net/sunrpc/auth_gss/gss_krb5_mech.c | 2 3 files changed, 151 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index d16563afaeae..c6d1bf876fe4 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -58,6 +58,12 @@ int krb5_kdf_hmac_sha2(const struct gss_krb5_enctype *gk5e, const struct xdr_netobj *in_constant, gfp_t gfp_mask); +int krb5_kdf_feedback_cmac(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *in_constant, + gfp_t gfp_mask); + /** * krb5_derive_key - Derive a subkey from a protocol key * @kctx: Kerberos 5 context diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index 724be20f5417..99251f15723a 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c @@ -363,6 +363,149 @@ int krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, return ret; } +/* + * K(i) = CMAC(key, K(i-1) | i | constant | 0x00 | k) + * + * i: A block counter is used with a length of 4 bytes, represented + * in big-endian order. + * + * constant: The label input to the KDF is the usage constant supplied + * to the key derivation function + * + * k: The length of the output key in bits, represented as a 4-byte + * string in big-endian order. + * + * Caller fills in K(i-1) in @step, and receives the result K(i) + * in the same buffer. + */ +static int +krb5_cmac_Ki(struct crypto_shash *tfm, const struct xdr_netobj *constant, + u32 outlen, u32 count, struct xdr_netobj *step) +{ + __be32 k = cpu_to_be32(outlen * 8); + SHASH_DESC_ON_STACK(desc, tfm); + __be32 i = cpu_to_be32(count); + u8 zero = 0; + int ret; + + desc->tfm = tfm; + ret = crypto_shash_init(desc); + if (ret) + goto out_err; + + ret = crypto_shash_update(desc, step->data, step->len); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, (u8 *)&i, sizeof(i)); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, constant->data, constant->len); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, &zero, sizeof(zero)); + if (ret) + goto out_err; + ret = crypto_shash_update(desc, (u8 *)&k, sizeof(k)); + if (ret) + goto out_err; + ret = crypto_shash_final(desc, step->data); + if (ret) + goto out_err; + +out_err: + shash_desc_zero(desc); + return ret; +} + +/** + * krb5_kdf_feedback_cmac - Derive a subkey for a Camellia/CMAC-based enctype + * @gk5e: Kerberos 5 enctype parameters + * @inkey: base protocol key + * @outkey: OUT: derived key + * @constant: subkey usage label + * @gfp_mask: memory allocation control flags + * + * RFC 6803 Section 3: + * + * "We use a key derivation function from the family specified in + * [SP800-108], Section 5.2, 'KDF in Feedback Mode'." + * + * n = ceiling(k / 128) + * K(0) = zeros + * K(i) = CMAC(key, K(i-1) | i | constant | 0x00 | k) + * DR(key, constant) = k-truncate(K(1) | K(2) | ... | K(n)) + * KDF-FEEDBACK-CMAC(key, constant) = random-to-key(DR(key, constant)) + * + * Caller sets @outkey->len to the desired length of the derived key (k). + * + * On success, returns 0 and fills in @outkey. A negative errno value + * is returned on failure. + */ +int +krb5_kdf_feedback_cmac(const struct gss_krb5_enctype *gk5e, + const struct xdr_netobj *inkey, + struct xdr_netobj *outkey, + const struct xdr_netobj *constant, + gfp_t gfp_mask) +{ + struct xdr_netobj step = { .data = NULL }; + struct xdr_netobj DR = { .data = NULL }; + unsigned int blocksize, offset; + struct crypto_shash *tfm; + int n, count, ret; + + /* + * This implementation assumes the CMAC used for an enctype's + * key derivation is the same as the CMAC used for its + * checksumming. This happens to be true for enctypes that + * are currently supported by this implementation. + */ + tfm = crypto_alloc_shash(gk5e->cksum_name, 0, 0); + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + goto out; + } + ret = crypto_shash_setkey(tfm, inkey->data, inkey->len); + if (ret) + goto out_free_tfm; + + blocksize = crypto_shash_digestsize(tfm); + n = (outkey->len + blocksize - 1) / blocksize; + + /* K(0) is all zeroes */ + ret = -ENOMEM; + step.len = blocksize; + step.data = kzalloc(step.len, gfp_mask); + if (!step.data) + goto out_free_tfm; + + DR.len = blocksize * n; + DR.data = kmalloc(DR.len, gfp_mask); + if (!DR.data) + goto out_free_tfm; + + /* XXX: Does not handle partial-block key sizes */ + for (offset = 0, count = 1; count <= n; count++) { + ret = krb5_cmac_Ki(tfm, constant, outkey->len, count, &step); + if (ret) + goto out_free_tfm; + + memcpy(DR.data + offset, step.data, blocksize); + offset += blocksize; + } + + /* k-truncate and random-to-key */ + memcpy(outkey->data, DR.data, outkey->len); + ret = 0; + +out_free_tfm: + crypto_free_shash(tfm); +out: + kfree_sensitive(step.data); + kfree_sensitive(DR.data); + return ret; +} + /* * K1 = HMAC-SHA(key, 0x00000001 | label | 0x00 | k) * diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 5f9c79e404f4..157d90a5aef6 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -166,6 +166,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .Ki_length = BITS2OCTETS(128), .import_ctx = gss_krb5_import_ctx_v2, + .derive_key = krb5_kdf_feedback_cmac, .encrypt = gss_krb5_aes_encrypt, .decrypt = gss_krb5_aes_decrypt, @@ -192,6 +193,7 @@ static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { .Ki_length = BITS2OCTETS(256), .import_ctx = gss_krb5_import_ctx_v2, + .derive_key = krb5_kdf_feedback_cmac, .encrypt = gss_krb5_aes_encrypt, .decrypt = gss_krb5_aes_decrypt, From patchwork Fri Jan 13 15:24:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92091C678D4 for ; Fri, 13 Jan 2023 15:31:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229560AbjAMPbg (ORCPT ); Fri, 13 Jan 2023 10:31:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229675AbjAMPbR (ORCPT ); Fri, 13 Jan 2023 10:31:17 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 694A192354 for ; Fri, 13 Jan 2023 07:24:33 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 048A56216C for ; Fri, 13 Jan 2023 15:24:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34EA3C433EF; Fri, 13 Jan 2023 15:24:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623472; bh=fCH2Sn4QSEsq6g/JOJk0bTB1nfM+mb/p1UFXdrmBYk4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=hj+KhsaK0arQJCQPioLu+V1/9qak8zT0IZmGBXI/eiIXNCG0aoOR+3NoNvSZjoRv9 wmqgwz7gj6NNKzUleAGqSidILfhK/3BJBwXMsu1lriqGRog1ut/KeDkkbnCKEcuKBF fij6SjOHKj+RUfe6KChJOmyHqdfhUNWams/yBpo//yJNG5bucjk+RL/DrveZPh5MU3 zsnMuPpQ47Wws8N7T5qxkh4mxzKJvbEIdg1kZ9DLq2jXPJ3WrD1tGqsWc6IBe0nhgR LvkfkW1zBXJ6RvB6zFiA4MIJQvRp1hwk5zO4/euXf/QxX7iJq2Lp0/jYMbjIlfH7Gh IBk/ilnPHhLKQ== Subject: [PATCH v1 29/41] SUNRPC: Advertise support for the Camellia encryption types From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:31 -0500 Message-ID: <167362347130.8960.16694201789326175105.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Add the RFC 6803 encryption types to the string of integers that is reported to gssd during upcalls. This enables gssd to utilize keys with these encryption types when support for them is built into the kernel. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_mech.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 157d90a5aef6..6e728a8a3a37 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -275,6 +275,10 @@ static void gss_krb5_prepare_enctype_priority_list(void) ENCTYPE_AES256_CTS_HMAC_SHA384_192, ENCTYPE_AES128_CTS_HMAC_SHA256_128, #endif +#if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA) + ENCTYPE_CAMELLIA256_CTS_CMAC, + ENCTYPE_CAMELLIA128_CTS_CMAC, +#endif #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1) ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, From patchwork Fri Jan 13 15:24:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100971 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9EA0AC54EBE for ; Fri, 13 Jan 2023 15:31:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229892AbjAMPbj (ORCPT ); Fri, 13 Jan 2023 10:31:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230184AbjAMPbU (ORCPT ); Fri, 13 Jan 2023 10:31:20 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A882E80AF7 for ; Fri, 13 Jan 2023 07:24:41 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 1E62AB8216D for ; Fri, 13 Jan 2023 15:24:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6EC59C433D2; Fri, 13 Jan 2023 15:24:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623478; bh=hVWiOllP3jcynmTOLjTVN1U9Cu8q8Pes0o0P9LjTfQQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=uDeBnU6Hq9RBTKY7CS9R29Kn0O/VUX3gCeWahSFzkrcECvBbeVWfIIbnLVvpr1ebQ tmp7Xwa+RvPyOj2VvllKfjozfXDXpw2xKMfbeKG7tPH9hNG6O5pzFBJ9ZQxAQnTLfW jug2aH7ODnGWbEUxtsozO279gURpybbG3BPLBDlG/x3/V7HY1QhAPW7psECAbMpAkP FfvwPfdURYXoS81oS78UK9scUV/KRcFo+RP/iLvgBYqW3N7ZqetossZyfzjHZe1Idh TSr9fPH/NEqA1yft/SWdmblehLYPLos2jCnRbdcrS/mmnrRdUbpeWeTpLztcuS3IGp VZKIMeVCGwPDg== Subject: [PATCH v1 30/41] SUNRPC: Move remaining internal definitions to gss_krb5_internal.h From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:37 -0500 Message-ID: <167362347762.8960.9068522489996929477.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever The goal is to leave only protocol-defined items in gss_krb5.h so that it can be easily replaced by a generic header. Implementation specific items are moved to the new internal header. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- include/linux/sunrpc/gss_krb5.h | 119 ------------------------------- net/sunrpc/auth_gss/auth_gss.c | 17 ++++ net/sunrpc/auth_gss/gss_krb5_crypto.c | 1 net/sunrpc/auth_gss/gss_krb5_internal.h | 97 +++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 120 deletions(-) diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h index e5d9a94cf394..2fb2dee08ec6 100644 --- a/include/linux/sunrpc/gss_krb5.h +++ b/include/linux/sunrpc/gss_krb5.h @@ -44,12 +44,6 @@ #include #include -/* - * 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) @@ -62,76 +56,6 @@ /* Maximum blocksize for the supported crypto algorithms */ #define GSS_KRB5_MAX_BLOCKSIZE (16) -struct krb5_ctx; - -struct gss_krb5_enctype { - const u32 etype; /* encryption (key) type */ - const u32 ctype; /* checksum type */ - const char *name; /* "friendly" name */ - const char *encrypt_name; /* crypto encrypt name */ - const char *aux_cipher; /* aux encrypt cipher name */ - const char *cksum_name; /* crypto checksum name */ - const u16 signalg; /* signing algorithm */ - const u16 sealalg; /* sealing algorithm */ - 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; /* 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, - struct xdr_netobj *out, - const struct xdr_netobj *label, - gfp_t gfp_mask); - u32 (*encrypt)(struct krb5_ctx *kctx, u32 offset, - struct xdr_buf *buf, struct page **pages); - u32 (*decrypt)(struct krb5_ctx *kctx, u32 offset, u32 len, - struct xdr_buf *buf, u32 *headskip, u32 *tailskip); - u32 (*get_mic)(struct krb5_ctx *kctx, struct xdr_buf *text, - struct xdr_netobj *token); - u32 (*verify_mic)(struct krb5_ctx *kctx, struct xdr_buf *message_buffer, - struct xdr_netobj *read_token); - u32 (*wrap)(struct krb5_ctx *kctx, int offset, - struct xdr_buf *buf, struct page **pages); - u32 (*unwrap)(struct krb5_ctx *kctx, int offset, int len, - struct xdr_buf *buf, unsigned int *slack, - unsigned int *align); -}; - -/* krb5_ctx flags definitions */ -#define KRB5_CTX_FLAG_INITIATOR 0x00000001 -#define KRB5_CTX_FLAG_CFX 0x00000002 -#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004 - -struct krb5_ctx { - int initiate; /* 1 = initiating, 0 = accepting */ - u32 enctype; - u32 flags; - const struct gss_krb5_enctype *gk5e; /* enctype-specific info */ - struct crypto_sync_skcipher *enc; - struct crypto_sync_skcipher *seq; - struct crypto_sync_skcipher *acceptor_enc; - struct crypto_sync_skcipher *initiator_enc; - struct crypto_sync_skcipher *acceptor_enc_aux; - struct crypto_sync_skcipher *initiator_enc_aux; - struct crypto_ahash *acceptor_sign; - struct crypto_ahash *initiator_sign; - struct crypto_ahash *initiator_integ; - struct crypto_ahash *acceptor_integ; - u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */ - u8 cksum[GSS_KRB5_MAX_KEYLEN]; - atomic_t seq_send; - atomic64_t seq_send64; - time64_t endtime; - atomic64_t confounder; - siphash_key_t confkey; - struct xdr_netobj mech_used; -}; - /* The length of the Kerberos GSS token header */ #define GSS_KRB5_TOK_HDR_LEN (16) @@ -249,47 +173,4 @@ enum seal_alg { #define KG_USAGE_INITIATOR_SEAL (24) #define KG_USAGE_INITIATOR_SIGN (25) -/* - * This compile-time check verifies that we will not exceed the - * slack space allotted by the client and server auth_gss code - * before they call gss_wrap(). - */ -#define GSS_KRB5_MAX_SLACK_NEEDED \ - (GSS_KRB5_TOK_HDR_LEN /* gss token header */ \ - + GSS_KRB5_MAX_CKSUM_LEN /* gss token checksum */ \ - + GSS_KRB5_MAX_BLOCKSIZE /* confounder */ \ - + GSS_KRB5_MAX_BLOCKSIZE /* possible padding */ \ - + GSS_KRB5_TOK_HDR_LEN /* encrypted hdr in v2 token */\ - + GSS_KRB5_MAX_CKSUM_LEN /* encryption hmac */ \ - + 4 + 4 /* RPC verifier */ \ - + GSS_KRB5_TOK_HDR_LEN \ - + GSS_KRB5_MAX_CKSUM_LEN) - -u32 -make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, - struct xdr_buf *body, int body_offset, u8 *cksumkey, - unsigned int usage, struct xdr_netobj *cksumout); - -int -gss_encrypt_xdr_buf(struct crypto_sync_skcipher *tfm, struct xdr_buf *outbuf, - int offset, struct page **pages); - -int -gss_decrypt_xdr_buf(struct crypto_sync_skcipher *tfm, struct xdr_buf *inbuf, - int offset); - -s32 -krb5_make_seq_num(struct krb5_ctx *kctx, - struct crypto_sync_skcipher *key, - int direction, - u32 seqnum, unsigned char *cksum, unsigned char *buf); - -s32 -krb5_get_seq_num(struct krb5_ctx *kctx, - unsigned char *cksum, - unsigned char *buf, int *direction, u32 *seqnum); - -int -xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen); - #endif /* _LINUX_SUNRPC_GSS_KRB5_H */ diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 2d7b1e03110a..1af71fbb0d80 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -49,6 +49,22 @@ static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO; # define RPCDBG_FACILITY RPCDBG_AUTH #endif +/* + * This compile-time check verifies that we will not exceed the + * slack space allotted by the client and server auth_gss code + * before they call gss_wrap(). + */ +#define GSS_KRB5_MAX_SLACK_NEEDED \ + (GSS_KRB5_TOK_HDR_LEN /* gss token header */ \ + + GSS_KRB5_MAX_CKSUM_LEN /* gss token checksum */ \ + + GSS_KRB5_MAX_BLOCKSIZE /* confounder */ \ + + GSS_KRB5_MAX_BLOCKSIZE /* possible padding */ \ + + GSS_KRB5_TOK_HDR_LEN /* encrypted hdr in v2 token */ \ + + GSS_KRB5_MAX_CKSUM_LEN /* encryption hmac */ \ + + XDR_UNIT * 2 /* RPC verifier */ \ + + GSS_KRB5_TOK_HDR_LEN \ + + GSS_KRB5_MAX_CKSUM_LEN) + #define GSS_CRED_SLACK (RPC_MAX_AUTH_SIZE * 2) /* length of a krb5 verifier (48), plus data added before arguments when * using integrity (two 4-byte integers): */ @@ -1042,6 +1058,7 @@ gss_create_new(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt) goto err_put_mech; auth = &gss_auth->rpc_auth; auth->au_cslack = GSS_CRED_SLACK >> 2; + BUILD_BUG_ON(GSS_KRB5_MAX_SLACK_NEEDED > RPC_MAX_AUTH_SIZE); auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2; auth->au_verfsize = GSS_VERF_SLACK >> 2; auth->au_ralign = GSS_VERF_SLACK >> 2; diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 9112b3f87e72..986d8908d172 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -567,7 +567,6 @@ xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen) if (shiftlen == 0) return 0; - BUILD_BUG_ON(GSS_KRB5_MAX_SLACK_NEEDED > RPC_MAX_AUTH_SIZE); BUG_ON(shiftlen > RPC_MAX_AUTH_SIZE); p = buf->head[0].iov_base + base; diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index c6d1bf876fe4..4bfb58a162a1 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -8,6 +8,82 @@ #ifndef _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H #define _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_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) + +struct krb5_ctx; + +struct gss_krb5_enctype { + const u32 etype; /* encryption (key) type */ + const u32 ctype; /* checksum type */ + const char *name; /* "friendly" name */ + const char *encrypt_name; /* crypto encrypt name */ + const char *aux_cipher; /* aux encrypt cipher name */ + const char *cksum_name; /* crypto checksum name */ + const u16 signalg; /* signing algorithm */ + const u16 sealalg; /* sealing algorithm */ + 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; /* 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, + struct xdr_netobj *out, + const struct xdr_netobj *label, + gfp_t gfp_mask); + u32 (*encrypt)(struct krb5_ctx *kctx, u32 offset, + struct xdr_buf *buf, struct page **pages); + u32 (*decrypt)(struct krb5_ctx *kctx, u32 offset, u32 len, + struct xdr_buf *buf, u32 *headskip, u32 *tailskip); + u32 (*get_mic)(struct krb5_ctx *kctx, struct xdr_buf *text, + struct xdr_netobj *token); + u32 (*verify_mic)(struct krb5_ctx *kctx, struct xdr_buf *message_buffer, + struct xdr_netobj *read_token); + u32 (*wrap)(struct krb5_ctx *kctx, int offset, + struct xdr_buf *buf, struct page **pages); + u32 (*unwrap)(struct krb5_ctx *kctx, int offset, int len, + struct xdr_buf *buf, unsigned int *slack, + unsigned int *align); +}; + +/* krb5_ctx flags definitions */ +#define KRB5_CTX_FLAG_INITIATOR 0x00000001 +#define KRB5_CTX_FLAG_CFX 0x00000002 +#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004 + +struct krb5_ctx { + int initiate; /* 1 = initiating, 0 = accepting */ + u32 enctype; + u32 flags; + const struct gss_krb5_enctype *gk5e; /* enctype-specific info */ + struct crypto_sync_skcipher *enc; + struct crypto_sync_skcipher *seq; + struct crypto_sync_skcipher *acceptor_enc; + struct crypto_sync_skcipher *initiator_enc; + struct crypto_sync_skcipher *acceptor_enc_aux; + struct crypto_sync_skcipher *initiator_enc_aux; + struct crypto_ahash *acceptor_sign; + struct crypto_ahash *initiator_sign; + struct crypto_ahash *initiator_integ; + struct crypto_ahash *acceptor_integ; + u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */ + u8 cksum[GSS_KRB5_MAX_KEYLEN]; + atomic_t seq_send; + atomic64_t seq_send64; + time64_t endtime; + atomic64_t confounder; + siphash_key_t confkey; + struct xdr_netobj mech_used; +}; + /* * GSS Kerberos 5 mechanism Per-Message calls. */ @@ -96,8 +172,19 @@ static inline int krb5_derive_key(struct krb5_ctx *kctx, return gk5e->derive_key(gk5e, inkey, outkey, &label, gfp_mask); } +s32 krb5_make_seq_num(struct krb5_ctx *kctx, struct crypto_sync_skcipher *key, + int direction, u32 seqnum, unsigned char *cksum, + unsigned char *buf); + +s32 krb5_get_seq_num(struct krb5_ctx *kctx, unsigned char *cksum, + unsigned char *buf, int *direction, u32 *seqnum); + void krb5_make_confounder(struct krb5_ctx *kctx, u8 *p, int conflen); +u32 make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, + struct xdr_buf *body, int body_offset, u8 *cksumkey, + unsigned int usage, struct xdr_netobj *cksumout); + u32 gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, const struct xdr_buf *body, int body_offset, struct xdr_netobj *cksumout); @@ -108,6 +195,16 @@ u32 krb5_encrypt(struct crypto_sync_skcipher *key, void *iv, void *in, u32 krb5_decrypt(struct crypto_sync_skcipher *key, void *iv, void *in, void *out, int length); +int xdr_extend_head(struct xdr_buf *buf, unsigned int base, + unsigned int shiftlen); + +int gss_encrypt_xdr_buf(struct crypto_sync_skcipher *tfm, + struct xdr_buf *outbuf, int offset, + struct page **pages); + +int gss_decrypt_xdr_buf(struct crypto_sync_skcipher *tfm, + struct xdr_buf *inbuf, int offset); + u32 gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, struct page **pages); From patchwork Fri Jan 13 15:24:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100972 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 244E1C67871 for ; Fri, 13 Jan 2023 15:31:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230184AbjAMPbk (ORCPT ); Fri, 13 Jan 2023 10:31:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230218AbjAMPbU (ORCPT ); Fri, 13 Jan 2023 10:31:20 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FEDD7EA5E for ; Fri, 13 Jan 2023 07:24:46 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A05C56216C for ; Fri, 13 Jan 2023 15:24:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CAB0EC433F1; Fri, 13 Jan 2023 15:24:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623485; bh=WbJER1AmZlDMd8v64CvQbUofLtbBaj2V0p0t1lsGlZY=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=tpaheU7RQnkCxY9WKLXBUR3L7Nj7HQh4h44v/GvcH1BHEAjW6miwwSCogEMGCLpP7 NlhabMN/GethooZD0iHVTH14ssBEP4jFq+vf7s1vwwzgCwsuiMjCod2XyqaoYNVjZd uh0H4NCfjQhFaFLOoa6EEqjgfstNmu9u2x6DzvmXCBfIL9r8ziBGrDb246fsZHhLrH Y7G9Ens6Hs/iyi5pMt3AiLg3vMBVI8KMG+TzE3GBvcSwUMTUaYO9qKfYiRfTjpFHwo y7HlXkK9OWM+FPNRfPRP0qITOdwBHC7a+tA/XTeNWDKp6r19mAEhVZa2oc5gmXIoOt EwCK6nDUXF7Yg== Subject: [PATCH v1 31/41] SUNRPC: Add KUnit tests for rpcsec_krb5.ko From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:43 -0500 Message-ID: <167362348387.8960.8220126169909827.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever The Kerberos RFCs provide test vectors to verify the operation of an implementation. Introduce a KUnit test framework to exercise the Linux kernel's implementation of Kerberos. Start with test cases for the RFC 3961-defined n-fold function. The sample vectors for that are found in RFC 3961 Section 10. Run the GSS Kerberos 5 mechanism's unit tests with this command: $ ./tools/testing/kunit/kunit.py run \ --kunitconfig ./net/sunrpc/.kunitconfig Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/.kunitconfig | 22 +++ net/sunrpc/Kconfig | 15 ++ net/sunrpc/auth_gss/Makefile | 2 net/sunrpc/auth_gss/gss_krb5_internal.h | 4 + net/sunrpc/auth_gss/gss_krb5_keys.c | 15 +- net/sunrpc/auth_gss/gss_krb5_test.c | 244 +++++++++++++++++++++++++++++++ 6 files changed, 298 insertions(+), 4 deletions(-) create mode 100644 net/sunrpc/.kunitconfig create mode 100644 net/sunrpc/auth_gss/gss_krb5_test.c diff --git a/net/sunrpc/.kunitconfig b/net/sunrpc/.kunitconfig new file mode 100644 index 000000000000..dc9abe4faa4f --- /dev/null +++ b/net/sunrpc/.kunitconfig @@ -0,0 +1,22 @@ +CONFIG_KUNIT=y +CONFIG_UBSAN=y +CONFIG_STACKTRACE=y +CONFIG_NET=y +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_INET=y +CONFIG_FILE_LOCKING=y +CONFIG_MULTIUSER=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTS=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_DES=y +CONFIG_NFS_FS=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES=y +CONFIG_RPCSEC_GSS_KRB5_KUNIT_TEST=y diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig index def7e1ce348b..214e07e39f7b 100644 --- a/net/sunrpc/Kconfig +++ b/net/sunrpc/Kconfig @@ -103,6 +103,21 @@ config RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2 SHA-2 digests. These include aes128-cts-hmac-sha256-128 and aes256-cts-hmac-sha384-192. +config RPCSEC_GSS_KRB5_KUNIT_TEST + tristate "KUnit tests for RPCSEC GSS Kerberos" if !KUNIT_ALL_TESTS + depends on RPCSEC_GSS_KRB5 && KUNIT + default KUNIT_ALL_TESTS + help + This builds the KUnit tests for RPCSEC GSS Kerberos 5. + + KUnit tests run during boot and output the results to the debug + log in TAP format (https://testanything.org/). Only useful for + kernel devs running KUnit test harness and are not for inclusion + into a production build. + + For more information on KUnit and unit tests in general, refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + config SUNRPC_DEBUG bool "RPC: Enable dprintk debugging" depends on SUNRPC && SYSCTL diff --git a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile index 4a29f4c5dac4..012ae1720689 100644 --- a/net/sunrpc/auth_gss/Makefile +++ b/net/sunrpc/auth_gss/Makefile @@ -13,3 +13,5 @@ obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o rpcsec_gss_krb5-y := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \ gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o gss_krb5_keys.o + +obj-$(CONFIG_RPCSEC_GSS_KRB5_KUNIT_TEST) += gss_krb5_test.o diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index 4bfb58a162a1..b2cf975a42d4 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -217,4 +217,8 @@ u32 krb5_etm_encrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, u32 krb5_etm_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, struct xdr_buf *buf, u32 *headskip, u32 *tailskip); +#if IS_ENABLED(CONFIG_KUNIT) +void krb5_nfold(u32 inbits, const u8 *in, u32 outbits, u8 *out); +#endif + #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c index 99251f15723a..5347fe1cc93f 100644 --- a/net/sunrpc/auth_gss/gss_krb5_keys.c +++ b/net/sunrpc/auth_gss/gss_krb5_keys.c @@ -61,6 +61,7 @@ #include #include #include +#include #include "gss_krb5_internal.h" @@ -68,13 +69,18 @@ # define RPCDBG_FACILITY RPCDBG_AUTH #endif -/* +/** + * krb5_nfold - n-fold function + * @inbits: number of bits in @in + * @in: buffer containing input to fold + * @outbits: number of bits in the output buffer + * @out: buffer to hold the result + * * This is the n-fold function as described in rfc3961, sec 5.1 * Taken from MIT Kerberos and modified. */ - -static void krb5_nfold(u32 inbits, const u8 *in, - u32 outbits, u8 *out) +VISIBLE_IF_KUNIT +void krb5_nfold(u32 inbits, const u8 *in, u32 outbits, u8 *out) { unsigned long ulcm; int byte, i, msbit; @@ -135,6 +141,7 @@ static void krb5_nfold(u32 inbits, const u8 *in, } } } +EXPORT_SYMBOL_IF_KUNIT(krb5_nfold); /* * This is the DK (derive_key) function as described in rfc3961, sec 5.1 diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c new file mode 100644 index 000000000000..f67dbf7c8af4 --- /dev/null +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Oracle and/or its affiliates. + * + * KUnit test of SunRPC's GSS Kerberos mechanism. Subsystem + * name is "rpcsec_gss_krb5". + */ + +#include +#include + +#include + +#include +#include + +#include "gss_krb5_internal.h" + +MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); + +struct gss_krb5_test_param { + const char *desc; + u32 nfold; + const struct xdr_netobj *plaintext; + const struct xdr_netobj *expected_result; +}; + +static inline void gss_krb5_get_desc(const struct gss_krb5_test_param *param, + char *desc) +{ + strscpy(desc, param->desc, KUNIT_PARAM_DESC_SIZE); +} + +#define DEFINE_HEX_XDR_NETOBJ(name, hex_array...) \ + static const u8 name ## _data[] = { hex_array }; \ + static const struct xdr_netobj name = { \ + .data = (u8 *)name##_data, \ + .len = sizeof(name##_data), \ + } + +/* + * RFC 3961 Appendix A.1. n-fold + * + * The n-fold function is defined in section 5.1 of RFC 3961. + * + * This test material is copyright (C) The Internet Society (2005). + */ + +DEFINE_HEX_XDR_NETOBJ(nfold_test1_plaintext, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test1_expected_result, + 0xbe, 0x07, 0x26, 0x31, 0x27, 0x6b, 0x19, 0x55 +); + +DEFINE_HEX_XDR_NETOBJ(nfold_test2_plaintext, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test2_expected_result, + 0x78, 0xa0, 0x7b, 0x6c, 0xaf, 0x85, 0xfa +); + +DEFINE_HEX_XDR_NETOBJ(nfold_test3_plaintext, + 0x52, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x43, 0x6f, + 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2c, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x52, 0x75, 0x6e, + 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x6f, 0x64, + 0x65 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test3_expected_result, + 0xbb, 0x6e, 0xd3, 0x08, 0x70, 0xb7, 0xf0, 0xe0 +); + +DEFINE_HEX_XDR_NETOBJ(nfold_test4_plaintext, + 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test4_expected_result, + 0x59, 0xe4, 0xa8, 0xca, 0x7c, 0x03, 0x85, 0xc3, + 0xc3, 0x7b, 0x3f, 0x6d, 0x20, 0x00, 0x24, 0x7c, + 0xb6, 0xe6, 0xbd, 0x5b, 0x3e +); + +DEFINE_HEX_XDR_NETOBJ(nfold_test5_plaintext, + 0x4d, 0x41, 0x53, 0x53, 0x41, 0x43, 0x48, 0x56, + 0x53, 0x45, 0x54, 0x54, 0x53, 0x20, 0x49, 0x4e, + 0x53, 0x54, 0x49, 0x54, 0x56, 0x54, 0x45, 0x20, + 0x4f, 0x46, 0x20, 0x54, 0x45, 0x43, 0x48, 0x4e, + 0x4f, 0x4c, 0x4f, 0x47, 0x59 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test5_expected_result, + 0xdb, 0x3b, 0x0d, 0x8f, 0x0b, 0x06, 0x1e, 0x60, + 0x32, 0x82, 0xb3, 0x08, 0xa5, 0x08, 0x41, 0x22, + 0x9a, 0xd7, 0x98, 0xfa, 0xb9, 0x54, 0x0c, 0x1b +); + +DEFINE_HEX_XDR_NETOBJ(nfold_test6_plaintext, + 0x51 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test6_expected_result, + 0x51, 0x8a, 0x54, 0xa2, 0x15, 0xa8, 0x45, 0x2a, + 0x51, 0x8a, 0x54, 0xa2, 0x15, 0xa8, 0x45, 0x2a, + 0x51, 0x8a, 0x54, 0xa2, 0x15 +); + +DEFINE_HEX_XDR_NETOBJ(nfold_test7_plaintext, + 0x62, 0x61 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test7_expected_result, + 0xfb, 0x25, 0xd5, 0x31, 0xae, 0x89, 0x74, 0x49, + 0x9f, 0x52, 0xfd, 0x92, 0xea, 0x98, 0x57, 0xc4, + 0xba, 0x24, 0xcf, 0x29, 0x7e +); + +DEFINE_HEX_XDR_NETOBJ(nfold_test_kerberos, + 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test8_expected_result, + 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test9_expected_result, + 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, + 0x7b, 0x9b, 0x5b, 0x2b, 0x93, 0x13, 0x2b, 0x93 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test10_expected_result, + 0x83, 0x72, 0xc2, 0x36, 0x34, 0x4e, 0x5f, 0x15, + 0x50, 0xcd, 0x07, 0x47, 0xe1, 0x5d, 0x62, 0xca, + 0x7a, 0x5a, 0x3b, 0xce, 0xa4 +); +DEFINE_HEX_XDR_NETOBJ(nfold_test11_expected_result, + 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73, + 0x7b, 0x9b, 0x5b, 0x2b, 0x93, 0x13, 0x2b, 0x93, + 0x5c, 0x9b, 0xdc, 0xda, 0xd9, 0x5c, 0x98, 0x99, + 0xc4, 0xca, 0xe4, 0xde, 0xe6, 0xd6, 0xca, 0xe4 +); + +static const struct gss_krb5_test_param rfc3961_nfold_test_params[] = { + { + .desc = "64-fold(\"012345\")", + .nfold = 64, + .plaintext = &nfold_test1_plaintext, + .expected_result = &nfold_test1_expected_result, + }, + { + .desc = "56-fold(\"password\")", + .nfold = 56, + .plaintext = &nfold_test2_plaintext, + .expected_result = &nfold_test2_expected_result, + }, + { + .desc = "64-fold(\"Rough Consensus, and Running Code\")", + .nfold = 64, + .plaintext = &nfold_test3_plaintext, + .expected_result = &nfold_test3_expected_result, + }, + { + .desc = "168-fold(\"password\")", + .nfold = 168, + .plaintext = &nfold_test4_plaintext, + .expected_result = &nfold_test4_expected_result, + }, + { + .desc = "192-fold(\"MASSACHVSETTS INSTITVTE OF TECHNOLOGY\")", + .nfold = 192, + .plaintext = &nfold_test5_plaintext, + .expected_result = &nfold_test5_expected_result, + }, + { + .desc = "168-fold(\"Q\")", + .nfold = 168, + .plaintext = &nfold_test6_plaintext, + .expected_result = &nfold_test6_expected_result, + }, + { + .desc = "168-fold(\"ba\")", + .nfold = 168, + .plaintext = &nfold_test7_plaintext, + .expected_result = &nfold_test7_expected_result, + }, + { + .desc = "64-fold(\"kerberos\")", + .nfold = 64, + .plaintext = &nfold_test_kerberos, + .expected_result = &nfold_test8_expected_result, + }, + { + .desc = "128-fold(\"kerberos\")", + .nfold = 128, + .plaintext = &nfold_test_kerberos, + .expected_result = &nfold_test9_expected_result, + }, + { + .desc = "168-fold(\"kerberos\")", + .nfold = 168, + .plaintext = &nfold_test_kerberos, + .expected_result = &nfold_test10_expected_result, + }, + { + .desc = "256-fold(\"kerberos\")", + .nfold = 256, + .plaintext = &nfold_test_kerberos, + .expected_result = &nfold_test11_expected_result, + }, +}; + +/* Creates the function rfc3961_nfold_gen_params */ +KUNIT_ARRAY_PARAM(rfc3961_nfold, rfc3961_nfold_test_params, gss_krb5_get_desc); + +static void rfc3961_nfold_case(struct kunit *test) +{ + const struct gss_krb5_test_param *param = test->param_value; + u8 *result; + + /* Arrange */ + result = kunit_kzalloc(test, 4096, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, result); + + /* Act */ + krb5_nfold(param->plaintext->len * 8, param->plaintext->data, + param->expected_result->len * 8, result); + + /* Assert */ + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->expected_result->data, + result, param->expected_result->len), 0, + "result mismatch"); +} + +static struct kunit_case rfc3961_test_cases[] = { + { + .name = "RFC 3961 n-fold", + .run_case = rfc3961_nfold_case, + .generate_params = rfc3961_nfold_gen_params, + }, +}; + +static struct kunit_suite rfc3961_suite = { + .name = "RFC 3961 tests", + .test_cases = rfc3961_test_cases, +}; + +kunit_test_suites(&rfc3961_suite); + +MODULE_DESCRIPTION("Test RPCSEC GSS Kerberos 5 functions"); +MODULE_LICENSE("GPL"); From patchwork Fri Jan 13 15:24:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100973 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7836C54EBE for ; Fri, 13 Jan 2023 15:31:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229877AbjAMPbr (ORCPT ); Fri, 13 Jan 2023 10:31:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230219AbjAMPbX (ORCPT ); Fri, 13 Jan 2023 10:31:23 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BA8893C20 for ; Fri, 13 Jan 2023 07:24:52 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 013BD620DB for ; Fri, 13 Jan 2023 15:24:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2C424C433F1; Fri, 13 Jan 2023 15:24:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623491; bh=95bsxLo4a4ZblD9HrvKC0Rtul43dyBzsmW308CcxgXk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=aQ62g9iPaQb3woDu/k94mfv5eO9zHYDteg2NljlM51w3zc0F13mjbryZLde1b68UO h4wdNNgIe47g0zHMl/kJrWOhX+AWzjAk3GoGjun1R3pt7TcGC+3wk3O+1r+/ydCzaX wiQvsrNSSU2holvYutrMMl4AuGpn0YVL2Pk/RtRbxnOE8agmmteoXoXF+q2iv4GA/W umZnvT8x6XD7xwxb9a6atJnwf+s6Y1CF0jOcyN5W9SslYmiaDi457UDWa1HgYBq+XO My4/sPiJZv2LcHySD0JZAA0595yIWvN+8DBvRBjAnKdMI1+S5C45uuFaE15GvJj4YI NIVM7ghvYUTdA== Subject: [PATCH v1 32/41] SUNRPC: Export get_gss_krb5_enctype() From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:50 -0500 Message-ID: <167362349024.8960.17925315944330916382.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever I plan to add KUnit tests that will need enctype profile information. Export the enctype profile lookup function. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_internal.h | 1 + net/sunrpc/auth_gss/gss_krb5_mech.c | 35 ++++++++++++++----------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index b2cf975a42d4..a24e67938c80 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -219,6 +219,7 @@ u32 krb5_etm_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, #if IS_ENABLED(CONFIG_KUNIT) void krb5_nfold(u32 inbits, const u8 *in, u32 outbits, u8 *out); +const struct gss_krb5_enctype *gss_krb5_lookup_enctype(u32 etype); #endif #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 6e728a8a3a37..7af651daf814 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "auth_gss_internal.h" #include "gss_krb5_internal.h" @@ -309,28 +310,24 @@ static void gss_krb5_prepare_enctype_priority_list(void) } } -static const int num_supported_enctypes = - ARRAY_SIZE(supported_gss_krb5_enctypes); - -static int -supported_gss_krb5_enctype(int etype) +/** + * gss_krb5_lookup_enctype - Retrieve profile information for a given enctype + * @etype: ENCTYPE value + * + * Returns a pointer to a gss_krb5_enctype structure, or NULL if no + * matching etype is found. + */ +VISIBLE_IF_KUNIT +const struct gss_krb5_enctype *gss_krb5_lookup_enctype(u32 etype) { - int i; - for (i = 0; i < num_supported_enctypes; i++) - if (supported_gss_krb5_enctypes[i].etype == etype) - return 1; - return 0; -} + size_t i; -static const struct gss_krb5_enctype * -get_gss_krb5_enctype(int etype) -{ - int i; - for (i = 0; i < num_supported_enctypes; i++) + for (i = 0; i < ARRAY_SIZE(supported_gss_krb5_enctypes); i++) if (supported_gss_krb5_enctypes[i].etype == etype) return &supported_gss_krb5_enctypes[i]; return NULL; } +EXPORT_SYMBOL_IF_KUNIT(gss_krb5_lookup_enctype); static struct crypto_sync_skcipher * gss_krb5_alloc_cipher_v1(struct krb5_ctx *ctx, struct xdr_netobj *key) @@ -366,7 +363,7 @@ get_key(const void *p, const void *end, alg = ENCTYPE_DES_CBC_RAW; break; } - if (!supported_gss_krb5_enctype(alg)) { + if (!gss_krb5_lookup_enctype(alg)) { pr_warn("gss_krb5: unsupported enctype: %d\n", alg); goto out_err_inval; } @@ -405,7 +402,7 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) /* Old format supports only DES! Any other enctype uses new format */ ctx->enctype = ENCTYPE_DES_CBC_RAW; - ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); + ctx->gk5e = gss_krb5_lookup_enctype(ctx->enctype); if (ctx->gk5e == NULL) { p = ERR_PTR(-EINVAL); goto out_err; @@ -677,7 +674,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */ if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1) ctx->enctype = ENCTYPE_DES3_CBC_RAW; - ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); + ctx->gk5e = gss_krb5_lookup_enctype(ctx->enctype); if (ctx->gk5e == NULL) { dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n", ctx->enctype); From patchwork Fri Jan 13 15:24:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100974 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35B72C54EBE for ; Fri, 13 Jan 2023 15:32:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229626AbjAMPb7 (ORCPT ); Fri, 13 Jan 2023 10:31:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230137AbjAMPbf (ORCPT ); Fri, 13 Jan 2023 10:31:35 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBF3A93C01 for ; Fri, 13 Jan 2023 07:24:58 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 59DAC621BE for ; Fri, 13 Jan 2023 15:24:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7C3F8C433D2; Fri, 13 Jan 2023 15:24:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623497; bh=rBUK4J0JUMICEBphNBz7FZlmL19SsGygiIYzbQSwQug=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=hkoz07gCeMaF71Hzo7dcD0QwSCdbeKnLVnaS+gHOLeavF5v7sxK2sR53rKcy0CU0s zuQMHVJf1jmn5//vdyZzEI+ygIl7yxEMQCHLYCh/vfeM8A/EmQBYsj6XBfdnAfqkoq 2VPUVGKMIqScrqOIdylsRA5yyiV9mH5t2EyLa01LuGvRsi20GkSVAo0GdSUAtqoPI5 MLGaf8IPCiN80Gh5R8xaT9bdtZAK5a3KK0al5QSM/KgszDvN11rdST8khmFQwVYNJu MWfT2IFo+PWvYFxgzgLSkPx+/kQdAqr4LLbqm7e5UO97acIGxzmwwpNDpulQfupyRW K0JVL/bk8MHqA== Subject: [PATCH v1 33/41] SUNRPC: Add KUnit tests RFC 3961 Key Derivation From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:24:56 -0500 Message-ID: <167362349660.8960.5483184673213091422.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever RFC 3961 Appendix A provides tests for the KDF specified in that document as well as other parts of Kerberos. The other three usage scenarios in Section 10 are not implemented by the Linux kernel's RPCSEC GSS Kerberos 5 mechanism, so tests are not added for those. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_test.c | 227 +++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index f67dbf7c8af4..550f1b3a11a3 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -20,7 +20,10 @@ MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); struct gss_krb5_test_param { const char *desc; + u32 enctype; u32 nfold; + const struct xdr_netobj *base_key; + const struct xdr_netobj *usage; const struct xdr_netobj *plaintext; const struct xdr_netobj *expected_result; }; @@ -31,6 +34,34 @@ static inline void gss_krb5_get_desc(const struct gss_krb5_test_param *param, strscpy(desc, param->desc, KUNIT_PARAM_DESC_SIZE); } +static void kdf_case(struct kunit *test) +{ + const struct gss_krb5_test_param *param = test->param_value; + const struct gss_krb5_enctype *gk5e; + struct xdr_netobj derivedkey; + int err; + + /* Arrange */ + gk5e = gss_krb5_lookup_enctype(param->enctype); + KUNIT_ASSERT_NOT_NULL(test, gk5e); + + derivedkey.data = kunit_kzalloc(test, param->expected_result->len, + GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, derivedkey.data); + derivedkey.len = param->expected_result->len; + + /* Act */ + err = gk5e->derive_key(gk5e, param->base_key, &derivedkey, + param->usage, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Assert */ + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->expected_result->data, + derivedkey.data, derivedkey.len), 0, + "key mismatch"); +} + #define DEFINE_HEX_XDR_NETOBJ(name, hex_array...) \ static const u8 name ## _data[] = { hex_array }; \ static const struct xdr_netobj name = { \ @@ -225,12 +256,208 @@ static void rfc3961_nfold_case(struct kunit *test) "result mismatch"); } +/* + * RFC 3961 Appendix A.3. DES3 DR and DK + * + * These tests show the derived-random and derived-key values for the + * des3-hmac-sha1-kd encryption scheme, using the DR and DK functions + * defined in section 6.3.1. The input keys were randomly generated; + * the usage values are from this specification. + * + * This test material is copyright (C) The Internet Society (2005). + */ + +DEFINE_HEX_XDR_NETOBJ(des3_dk_usage_155, + 0x00, 0x00, 0x00, 0x01, 0x55 +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_usage_1aa, + 0x00, 0x00, 0x00, 0x01, 0xaa +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_usage_kerberos, + 0x6b, 0x65, 0x72, 0x62, 0x65, 0x72, 0x6f, 0x73 +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test1_base_key, + 0xdc, 0xe0, 0x6b, 0x1f, 0x64, 0xc8, 0x57, 0xa1, + 0x1c, 0x3d, 0xb5, 0x7c, 0x51, 0x89, 0x9b, 0x2c, + 0xc1, 0x79, 0x10, 0x08, 0xce, 0x97, 0x3b, 0x92 +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test1_derived_key, + 0x92, 0x51, 0x79, 0xd0, 0x45, 0x91, 0xa7, 0x9b, + 0x5d, 0x31, 0x92, 0xc4, 0xa7, 0xe9, 0xc2, 0x89, + 0xb0, 0x49, 0xc7, 0x1f, 0x6e, 0xe6, 0x04, 0xcd +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test2_base_key, + 0x5e, 0x13, 0xd3, 0x1c, 0x70, 0xef, 0x76, 0x57, + 0x46, 0x57, 0x85, 0x31, 0xcb, 0x51, 0xc1, 0x5b, + 0xf1, 0x1c, 0xa8, 0x2c, 0x97, 0xce, 0xe9, 0xf2 +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test2_derived_key, + 0x9e, 0x58, 0xe5, 0xa1, 0x46, 0xd9, 0x94, 0x2a, + 0x10, 0x1c, 0x46, 0x98, 0x45, 0xd6, 0x7a, 0x20, + 0xe3, 0xc4, 0x25, 0x9e, 0xd9, 0x13, 0xf2, 0x07 +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test3_base_key, + 0x98, 0xe6, 0xfd, 0x8a, 0x04, 0xa4, 0xb6, 0x85, + 0x9b, 0x75, 0xa1, 0x76, 0x54, 0x0b, 0x97, 0x52, + 0xba, 0xd3, 0xec, 0xd6, 0x10, 0xa2, 0x52, 0xbc +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test3_derived_key, + 0x13, 0xfe, 0xf8, 0x0d, 0x76, 0x3e, 0x94, 0xec, + 0x6d, 0x13, 0xfd, 0x2c, 0xa1, 0xd0, 0x85, 0x07, + 0x02, 0x49, 0xda, 0xd3, 0x98, 0x08, 0xea, 0xbf +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test4_base_key, + 0x62, 0x2a, 0xec, 0x25, 0xa2, 0xfe, 0x2c, 0xad, + 0x70, 0x94, 0x68, 0x0b, 0x7c, 0x64, 0x94, 0x02, + 0x80, 0x08, 0x4c, 0x1a, 0x7c, 0xec, 0x92, 0xb5 +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test4_derived_key, + 0xf8, 0xdf, 0xbf, 0x04, 0xb0, 0x97, 0xe6, 0xd9, + 0xdc, 0x07, 0x02, 0x68, 0x6b, 0xcb, 0x34, 0x89, + 0xd9, 0x1f, 0xd9, 0xa4, 0x51, 0x6b, 0x70, 0x3e +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test5_base_key, + 0xd3, 0xf8, 0x29, 0x8c, 0xcb, 0x16, 0x64, 0x38, + 0xdc, 0xb9, 0xb9, 0x3e, 0xe5, 0xa7, 0x62, 0x92, + 0x86, 0xa4, 0x91, 0xf8, 0x38, 0xf8, 0x02, 0xfb +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test5_derived_key, + 0x23, 0x70, 0xda, 0x57, 0x5d, 0x2a, 0x3d, 0xa8, + 0x64, 0xce, 0xbf, 0xdc, 0x52, 0x04, 0xd5, 0x6d, + 0xf7, 0x79, 0xa7, 0xdf, 0x43, 0xd9, 0xda, 0x43 +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test6_base_key, + 0xc1, 0x08, 0x16, 0x49, 0xad, 0xa7, 0x43, 0x62, + 0xe6, 0xa1, 0x45, 0x9d, 0x01, 0xdf, 0xd3, 0x0d, + 0x67, 0xc2, 0x23, 0x4c, 0x94, 0x07, 0x04, 0xda +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test6_derived_key, + 0x34, 0x80, 0x57, 0xec, 0x98, 0xfd, 0xc4, 0x80, + 0x16, 0x16, 0x1c, 0x2a, 0x4c, 0x7a, 0x94, 0x3e, + 0x92, 0xae, 0x49, 0x2c, 0x98, 0x91, 0x75, 0xf7 +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test7_base_key, + 0x5d, 0x15, 0x4a, 0xf2, 0x38, 0xf4, 0x67, 0x13, + 0x15, 0x57, 0x19, 0xd5, 0x5e, 0x2f, 0x1f, 0x79, + 0x0d, 0xd6, 0x61, 0xf2, 0x79, 0xa7, 0x91, 0x7c +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test7_derived_key, + 0xa8, 0x80, 0x8a, 0xc2, 0x67, 0xda, 0xda, 0x3d, + 0xcb, 0xe9, 0xa7, 0xc8, 0x46, 0x26, 0xfb, 0xc7, + 0x61, 0xc2, 0x94, 0xb0, 0x13, 0x15, 0xe5, 0xc1 +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test8_base_key, + 0x79, 0x85, 0x62, 0xe0, 0x49, 0x85, 0x2f, 0x57, + 0xdc, 0x8c, 0x34, 0x3b, 0xa1, 0x7f, 0x2c, 0xa1, + 0xd9, 0x73, 0x94, 0xef, 0xc8, 0xad, 0xc4, 0x43 +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test8_derived_key, + 0xc8, 0x13, 0xf8, 0x8a, 0x3b, 0xe3, 0xb3, 0x34, + 0xf7, 0x54, 0x25, 0xce, 0x91, 0x75, 0xfb, 0xe3, + 0xc8, 0x49, 0x3b, 0x89, 0xc8, 0x70, 0x3b, 0x49 +); + +DEFINE_HEX_XDR_NETOBJ(des3_dk_test9_base_key, + 0x26, 0xdc, 0xe3, 0x34, 0xb5, 0x45, 0x29, 0x2f, + 0x2f, 0xea, 0xb9, 0xa8, 0x70, 0x1a, 0x89, 0xa4, + 0xb9, 0x9e, 0xb9, 0x94, 0x2c, 0xec, 0xd0, 0x16 +); +DEFINE_HEX_XDR_NETOBJ(des3_dk_test9_derived_key, + 0xf4, 0x8f, 0xfd, 0x6e, 0x83, 0xf8, 0x3e, 0x73, + 0x54, 0xe6, 0x94, 0xfd, 0x25, 0x2c, 0xf8, 0x3b, + 0xfe, 0x58, 0xf7, 0xd5, 0xba, 0x37, 0xec, 0x5d +); + +static const struct gss_krb5_test_param rfc3961_kdf_test_params[] = { + { + .desc = "des3-hmac-sha1 key derivation case 1", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test1_base_key, + .usage = &des3_dk_usage_155, + .expected_result = &des3_dk_test1_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 2", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test2_base_key, + .usage = &des3_dk_usage_1aa, + .expected_result = &des3_dk_test2_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 3", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test3_base_key, + .usage = &des3_dk_usage_155, + .expected_result = &des3_dk_test3_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 4", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test4_base_key, + .usage = &des3_dk_usage_1aa, + .expected_result = &des3_dk_test4_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 5", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test5_base_key, + .usage = &des3_dk_usage_kerberos, + .expected_result = &des3_dk_test5_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 6", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test6_base_key, + .usage = &des3_dk_usage_155, + .expected_result = &des3_dk_test6_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 7", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test7_base_key, + .usage = &des3_dk_usage_1aa, + .expected_result = &des3_dk_test7_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 8", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test8_base_key, + .usage = &des3_dk_usage_155, + .expected_result = &des3_dk_test8_derived_key, + }, + { + .desc = "des3-hmac-sha1 key derivation case 9", + .enctype = ENCTYPE_DES3_CBC_RAW, + .base_key = &des3_dk_test9_base_key, + .usage = &des3_dk_usage_1aa, + .expected_result = &des3_dk_test9_derived_key, + }, +}; + +/* Creates the function rfc3961_kdf_gen_params */ +KUNIT_ARRAY_PARAM(rfc3961_kdf, rfc3961_kdf_test_params, gss_krb5_get_desc); + static struct kunit_case rfc3961_test_cases[] = { { .name = "RFC 3961 n-fold", .run_case = rfc3961_nfold_case, .generate_params = rfc3961_nfold_gen_params, }, + { + .name = "RFC 3961 key derivation", + .run_case = kdf_case, + .generate_params = rfc3961_kdf_gen_params, + }, }; static struct kunit_suite rfc3961_suite = { From patchwork Fri Jan 13 15:25:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100975 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26F76C54EBD for ; Fri, 13 Jan 2023 15:32:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230253AbjAMPcE (ORCPT ); Fri, 13 Jan 2023 10:32:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229613AbjAMPbl (ORCPT ); Fri, 13 Jan 2023 10:31:41 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F19B880AEF for ; Fri, 13 Jan 2023 07:25:06 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 834DAB820D4 for ; Fri, 13 Jan 2023 15:25:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CBBD6C433D2; Fri, 13 Jan 2023 15:25:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623504; bh=u1Yy99ELqzK+qnBzL8AAL1+SOxlQYoUwkUWR5pRzdx4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=dCH9Va4abPHx1sBzyOHn7RFQgJhXj0b17ONNVvUYZqgRdurU453/znx8TZUbadQnK u+CCRP+dZNc49aqfWrfH0pBD0WXcVWO3EvT2JyDo9qndtbJ5o5F6ZYQUhWXlwW7DIW E4KdvAjvkeq/H6XYenL0DEiv0X6xeUFZp5CTdVrOim9qUEOyhHsSOtwBtk4cS4q4GQ b8d59tWL8SWeU7osIy0XfBZJjCsEQJlaXLRaDGi91amtQAu59fDNQ4Y0fRixm+P+4z IyA2BZ2pbFuvylh0/9BDEdDUpJVgDIYmbwbmXAWU11bVf3D0uFIW6ea8IJRHPFae9b NzROsJMaSpAXA== Subject: [PATCH v1 34/41] SUNRPC: Add Kunit tests for RFC 3962-defined encryption/decryption From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:02 -0500 Message-ID: <167362350292.8960.8697643253733066455.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Add Kunit tests for ENCTYPE_AES128_CTS_HMAC_SHA1_96. The test vectors come from RFC 3962 Appendix B. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/.kunitconfig | 2 net/sunrpc/auth_gss/gss_krb5_crypto.c | 32 +++- net/sunrpc/auth_gss/gss_krb5_internal.h | 4 net/sunrpc/auth_gss/gss_krb5_test.c | 267 +++++++++++++++++++++++++++++++ 4 files changed, 296 insertions(+), 9 deletions(-) diff --git a/net/sunrpc/.kunitconfig b/net/sunrpc/.kunitconfig index dc9abe4faa4f..01e12729f465 100644 --- a/net/sunrpc/.kunitconfig +++ b/net/sunrpc/.kunitconfig @@ -14,9 +14,11 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_AES=y CONFIG_NFS_FS=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES=y +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1=y CONFIG_RPCSEC_GSS_KRB5_KUNIT_TEST=y diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 986d8908d172..f5c086471881 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "gss_krb5_internal.h" @@ -635,14 +636,28 @@ gss_krb5_cts_crypt(struct crypto_sync_skcipher *cipher, struct xdr_buf *buf, return ret; } -/* +/** + * krb5_cbc_cts_encrypt - encrypt in CBC mode with CTS + * @cts_tfm: CBC cipher with CTS + * @cbc_tfm: base CBC cipher + * @offset: starting byte offset for plaintext + * @buf: OUT: output buffer + * @pages: plaintext + * @iv: output CBC initialization vector, or NULL + * @ivsize: size of @iv, in octets + * * To provide confidentiality, encrypt using cipher block chaining * with ciphertext stealing. Message integrity is handled separately. + * + * Return values: + * %0: encryption successful + * negative errno: encryption could not be completed */ -static int -krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, - struct crypto_sync_skcipher *cbc_tfm, - u32 offset, struct xdr_buf *buf, struct page **pages) +VISIBLE_IF_KUNIT +int krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, + struct crypto_sync_skcipher *cbc_tfm, + u32 offset, struct xdr_buf *buf, struct page **pages, + u8 *iv, unsigned int ivsize) { u32 blocksize, nbytes, nblocks, cbcbytes; struct encryptor_desc desc; @@ -686,8 +701,11 @@ krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, if (err) return err; + if (unlikely(iv)) + memcpy(iv, desc.iv, ivsize); return 0; } +EXPORT_SYMBOL_IF_KUNIT(krb5_cbc_cts_encrypt); static int krb5_cbc_cts_decrypt(struct crypto_sync_skcipher *cts_tfm, @@ -795,7 +813,7 @@ gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, err = krb5_cbc_cts_encrypt(cipher, aux_cipher, offset + GSS_KRB5_TOK_HDR_LEN, - buf, pages); + buf, pages, NULL, 0); if (err) return GSS_S_FAILURE; @@ -987,7 +1005,7 @@ krb5_etm_encrypt(struct krb5_ctx *kctx, u32 offset, err = krb5_cbc_cts_encrypt(cipher, aux_cipher, offset + GSS_KRB5_TOK_HDR_LEN, - buf, pages); + buf, pages, NULL, 0); if (err) return GSS_S_FAILURE; diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index a24e67938c80..3d4d1208ba19 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -220,6 +220,10 @@ u32 krb5_etm_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, #if IS_ENABLED(CONFIG_KUNIT) void krb5_nfold(u32 inbits, const u8 *in, u32 outbits, u8 *out); const struct gss_krb5_enctype *gss_krb5_lookup_enctype(u32 etype); +int krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, + struct crypto_sync_skcipher *cbc_tfm, u32 offset, + struct xdr_buf *buf, struct page **pages, + u8 *iv, unsigned int ivsize); #endif #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index 550f1b3a11a3..2f7e31b8004e 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -23,9 +23,11 @@ struct gss_krb5_test_param { u32 enctype; u32 nfold; const struct xdr_netobj *base_key; + const struct xdr_netobj *Ke; const struct xdr_netobj *usage; - const struct xdr_netobj *plaintext; + const struct xdr_netobj *plaintext; const struct xdr_netobj *expected_result; + const struct xdr_netobj *next_iv; }; static inline void gss_krb5_get_desc(const struct gss_krb5_test_param *param, @@ -465,7 +467,268 @@ static struct kunit_suite rfc3961_suite = { .test_cases = rfc3961_test_cases, }; -kunit_test_suites(&rfc3961_suite); +/* + * From RFC 3962 Appendix B: Sample Test Vectors + * + * Some test vectors for CBC with ciphertext stealing, using an + * initial vector of all-zero. + * + * This test material is copyright (C) The Internet Society (2005). + */ + +DEFINE_HEX_XDR_NETOBJ(rfc3962_encryption_key, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 +); + +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test1_plaintext, + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test1_expected_result, + 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4, + 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f, + 0x97 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test1_next_iv, + 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4, + 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f +); + +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test2_plaintext, + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test2_expected_result, + 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1, + 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test2_next_iv, + 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1, + 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22 +); + +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test3_plaintext, + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test3_expected_result, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test3_next_iv, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8 +); + +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test4_plaintext, + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43, + 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20, + 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test4_expected_result, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, + 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test4_next_iv, + 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, + 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e +); + +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test5_plaintext, + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43, + 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20, + 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test5_expected_result, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test5_next_iv, + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8 +); + +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test6_plaintext, + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43, + 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20, + 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x6e, 0x74, + 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x70, 0x2e +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test6_expected_result, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, + 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, + 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40, + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8 +); +DEFINE_HEX_XDR_NETOBJ(rfc3962_enc_test6_next_iv, + 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, + 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40 +); + +static const struct gss_krb5_test_param rfc3962_encrypt_test_params[] = { + { + .desc = "Encrypt with aes128-cts-hmac-sha1-96 case 1", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &rfc3962_enc_test1_plaintext, + .expected_result = &rfc3962_enc_test1_expected_result, + .next_iv = &rfc3962_enc_test1_next_iv, + }, + { + .desc = "Encrypt with aes128-cts-hmac-sha1-96 case 2", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &rfc3962_enc_test2_plaintext, + .expected_result = &rfc3962_enc_test2_expected_result, + .next_iv = &rfc3962_enc_test2_next_iv, + }, + { + .desc = "Encrypt with aes128-cts-hmac-sha1-96 case 3", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &rfc3962_enc_test3_plaintext, + .expected_result = &rfc3962_enc_test3_expected_result, + .next_iv = &rfc3962_enc_test3_next_iv, + }, + { + .desc = "Encrypt with aes128-cts-hmac-sha1-96 case 4", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &rfc3962_enc_test4_plaintext, + .expected_result = &rfc3962_enc_test4_expected_result, + .next_iv = &rfc3962_enc_test4_next_iv, + }, + { + .desc = "Encrypt with aes128-cts-hmac-sha1-96 case 5", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &rfc3962_enc_test5_plaintext, + .expected_result = &rfc3962_enc_test5_expected_result, + .next_iv = &rfc3962_enc_test5_next_iv, + }, + { + .desc = "Encrypt with aes128-cts-hmac-sha1-96 case 6", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &rfc3962_enc_test6_plaintext, + .expected_result = &rfc3962_enc_test6_expected_result, + .next_iv = &rfc3962_enc_test6_next_iv, + }, +}; + +/* Creates the function rfc3962_encrypt_gen_params */ +KUNIT_ARRAY_PARAM(rfc3962_encrypt, rfc3962_encrypt_test_params, + gss_krb5_get_desc); + +/* + * This tests the implementation of the encryption part of the mechanism. + * It does not apply a confounder or test the result of HMAC over the + * plaintext. + */ +static void rfc3962_encrypt_case(struct kunit *test) +{ + const struct gss_krb5_test_param *param = test->param_value; + struct crypto_sync_skcipher *cts_tfm, *cbc_tfm; + const struct gss_krb5_enctype *gk5e; + struct xdr_buf buf; + void *iv, *text; + u32 err; + + /* Arrange */ + gk5e = gss_krb5_lookup_enctype(param->enctype); + KUNIT_ASSERT_NOT_NULL(test, gk5e); + + cbc_tfm = crypto_alloc_sync_skcipher(gk5e->aux_cipher, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cbc_tfm); + err = crypto_sync_skcipher_setkey(cbc_tfm, param->Ke->data, param->Ke->len); + KUNIT_ASSERT_EQ(test, err, 0); + + cts_tfm = crypto_alloc_sync_skcipher(gk5e->encrypt_name, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cts_tfm); + err = crypto_sync_skcipher_setkey(cts_tfm, param->Ke->data, param->Ke->len); + KUNIT_ASSERT_EQ(test, err, 0); + + iv = kunit_kzalloc(test, crypto_sync_skcipher_ivsize(cts_tfm), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, iv); + + text = kunit_kzalloc(test, param->plaintext->len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, text); + + memcpy(text, param->plaintext->data, param->plaintext->len); + memset(&buf, 0, sizeof(buf)); + buf.head[0].iov_base = text; + buf.head[0].iov_len = param->plaintext->len; + buf.len = buf.head[0].iov_len; + + /* Act */ + err = krb5_cbc_cts_encrypt(cts_tfm, cbc_tfm, 0, &buf, NULL, + iv, crypto_sync_skcipher_ivsize(cts_tfm)); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Assert */ + KUNIT_EXPECT_EQ_MSG(test, + param->expected_result->len, buf.len, + "ciphertext length mismatch"); + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->expected_result->data, + text, param->expected_result->len), 0, + "ciphertext mismatch"); + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->next_iv->data, iv, + param->next_iv->len), 0, + "IV mismatch"); + + crypto_free_sync_skcipher(cts_tfm); + crypto_free_sync_skcipher(cbc_tfm); +} + +static struct kunit_case rfc3962_test_cases[] = { + { + .name = "RFC 3962 encryption", + .run_case = rfc3962_encrypt_case, + .generate_params = rfc3962_encrypt_gen_params, + }, +}; + +static struct kunit_suite rfc3962_suite = { + .name = "RFC 3962 suite", + .test_cases = rfc3962_test_cases, +}; + +kunit_test_suites(&rfc3961_suite, + &rfc3962_suite); MODULE_DESCRIPTION("Test RPCSEC GSS Kerberos 5 functions"); MODULE_LICENSE("GPL"); From patchwork Fri Jan 13 15:25:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100978 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4783DC54EBD for ; Fri, 13 Jan 2023 15:32:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229698AbjAMPcT (ORCPT ); Fri, 13 Jan 2023 10:32:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230255AbjAMPbu (ORCPT ); Fri, 13 Jan 2023 10:31:50 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3235C63D1 for ; Fri, 13 Jan 2023 07:25:13 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id D36A3B8216D for ; Fri, 13 Jan 2023 15:25:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 319F7C433EF; Fri, 13 Jan 2023 15:25:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623510; bh=H89GNPbBgVD2Kdw9S2vRAbQpCE7nUW0D6NftAWIV6+s=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=KY+Y1uqYFGg6ayMH/ajnAy1Aeq0080g6j2xSC2ZwXCZadnCV1OAZGbDjhylAhkvXT SMIEOdeoj/Pc7Xz8gX8Vq8Uvt29K+AJnP7mcMmzLPyRq1UI/EBUGbdqrb62D6yThyv P3Ns5XvlZTIYqCXpTuhUC/ox9WvgxjSXLv/eWns+QogEcHhPhUMJnstlm9MJgUA42O Tg3sDbaX2EUS6GWEPuvYpgnwhTn1Xg/J53RfLtB26zks4PordukU+wIdIGeXnGzJSK joXHs9Oke2Xz5R1k2TAhYn87A7Sdldh80YL/3eimOAGx/094zc6SqvjSQ2wtFNJU3a NwD3jwieP/dfw== Subject: [PATCH v1 35/41] SUNRPC: Add KDF KUnit tests for the RFC 6803 encryption types From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:09 -0500 Message-ID: <167362350931.8960.15055012746732398275.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever The Camellia enctypes use a new KDF, so add some tests to ensure it is working properly. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/.kunitconfig | 3 + net/sunrpc/auth_gss/gss_krb5_test.c | 125 +++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/.kunitconfig b/net/sunrpc/.kunitconfig index 01e12729f465..90d0ad430e7e 100644 --- a/net/sunrpc/.kunitconfig +++ b/net/sunrpc/.kunitconfig @@ -11,14 +11,17 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_CAMELLIA=y CONFIG_NFS_FS=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES=y CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1=y +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA=y CONFIG_RPCSEC_GSS_KRB5_KUNIT_TEST=y diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index 2f7e31b8004e..c80a8f6588c0 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -727,8 +727,131 @@ static struct kunit_suite rfc3962_suite = { .test_cases = rfc3962_test_cases, }; +/* + * From RFC 6803 Section 10. Test vectors + * + * Sample results for key derivation + * + * Copyright (c) 2012 IETF Trust and the persons identified as the + * document authors. All rights reserved. + */ + +DEFINE_HEX_XDR_NETOBJ(camellia128_cts_cmac_basekey, + 0x57, 0xd0, 0x29, 0x72, 0x98, 0xff, 0xd9, 0xd3, + 0x5d, 0xe5, 0xa4, 0x7f, 0xb4, 0xbd, 0xe2, 0x4b +); +DEFINE_HEX_XDR_NETOBJ(camellia128_cts_cmac_Kc, + 0xd1, 0x55, 0x77, 0x5a, 0x20, 0x9d, 0x05, 0xf0, + 0x2b, 0x38, 0xd4, 0x2a, 0x38, 0x9e, 0x5a, 0x56 +); +DEFINE_HEX_XDR_NETOBJ(camellia128_cts_cmac_Ke, + 0x64, 0xdf, 0x83, 0xf8, 0x5a, 0x53, 0x2f, 0x17, + 0x57, 0x7d, 0x8c, 0x37, 0x03, 0x57, 0x96, 0xab +); +DEFINE_HEX_XDR_NETOBJ(camellia128_cts_cmac_Ki, + 0x3e, 0x4f, 0xbd, 0xf3, 0x0f, 0xb8, 0x25, 0x9c, + 0x42, 0x5c, 0xb6, 0xc9, 0x6f, 0x1f, 0x46, 0x35 +); + +DEFINE_HEX_XDR_NETOBJ(camellia256_cts_cmac_basekey, + 0xb9, 0xd6, 0x82, 0x8b, 0x20, 0x56, 0xb7, 0xbe, + 0x65, 0x6d, 0x88, 0xa1, 0x23, 0xb1, 0xfa, 0xc6, + 0x82, 0x14, 0xac, 0x2b, 0x72, 0x7e, 0xcf, 0x5f, + 0x69, 0xaf, 0xe0, 0xc4, 0xdf, 0x2a, 0x6d, 0x2c +); +DEFINE_HEX_XDR_NETOBJ(camellia256_cts_cmac_Kc, + 0xe4, 0x67, 0xf9, 0xa9, 0x55, 0x2b, 0xc7, 0xd3, + 0x15, 0x5a, 0x62, 0x20, 0xaf, 0x9c, 0x19, 0x22, + 0x0e, 0xee, 0xd4, 0xff, 0x78, 0xb0, 0xd1, 0xe6, + 0xa1, 0x54, 0x49, 0x91, 0x46, 0x1a, 0x9e, 0x50 +); +DEFINE_HEX_XDR_NETOBJ(camellia256_cts_cmac_Ke, + 0x41, 0x2a, 0xef, 0xc3, 0x62, 0xa7, 0x28, 0x5f, + 0xc3, 0x96, 0x6c, 0x6a, 0x51, 0x81, 0xe7, 0x60, + 0x5a, 0xe6, 0x75, 0x23, 0x5b, 0x6d, 0x54, 0x9f, + 0xbf, 0xc9, 0xab, 0x66, 0x30, 0xa4, 0xc6, 0x04 +); +DEFINE_HEX_XDR_NETOBJ(camellia256_cts_cmac_Ki, + 0xfa, 0x62, 0x4f, 0xa0, 0xe5, 0x23, 0x99, 0x3f, + 0xa3, 0x88, 0xae, 0xfd, 0xc6, 0x7e, 0x67, 0xeb, + 0xcd, 0x8c, 0x08, 0xe8, 0xa0, 0x24, 0x6b, 0x1d, + 0x73, 0xb0, 0xd1, 0xdd, 0x9f, 0xc5, 0x82, 0xb0 +); + +DEFINE_HEX_XDR_NETOBJ(usage_checksum, + 0x00, 0x00, 0x00, 0x02, KEY_USAGE_SEED_CHECKSUM +); +DEFINE_HEX_XDR_NETOBJ(usage_encryption, + 0x00, 0x00, 0x00, 0x02, KEY_USAGE_SEED_ENCRYPTION +); +DEFINE_HEX_XDR_NETOBJ(usage_integrity, + 0x00, 0x00, 0x00, 0x02, KEY_USAGE_SEED_INTEGRITY +); + +static const struct gss_krb5_test_param rfc6803_kdf_test_params[] = { + { + .desc = "Derive Kc subkey for camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .base_key = &camellia128_cts_cmac_basekey, + .usage = &usage_checksum, + .expected_result = &camellia128_cts_cmac_Kc, + }, + { + .desc = "Derive Ke subkey for camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .base_key = &camellia128_cts_cmac_basekey, + .usage = &usage_encryption, + .expected_result = &camellia128_cts_cmac_Ke, + }, + { + .desc = "Derive Ki subkey for camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .base_key = &camellia128_cts_cmac_basekey, + .usage = &usage_integrity, + .expected_result = &camellia128_cts_cmac_Ki, + }, + { + .desc = "Derive Kc subkey for camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .base_key = &camellia256_cts_cmac_basekey, + .usage = &usage_checksum, + .expected_result = &camellia256_cts_cmac_Kc, + }, + { + .desc = "Derive Ke subkey for camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .base_key = &camellia256_cts_cmac_basekey, + .usage = &usage_encryption, + .expected_result = &camellia256_cts_cmac_Ke, + }, + { + .desc = "Derive Ki subkey for camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .base_key = &camellia256_cts_cmac_basekey, + .usage = &usage_integrity, + .expected_result = &camellia256_cts_cmac_Ki, + }, +}; + +/* Creates the function rfc6803_kdf_gen_params */ +KUNIT_ARRAY_PARAM(rfc6803_kdf, rfc6803_kdf_test_params, gss_krb5_get_desc); + +static struct kunit_case rfc6803_test_cases[] = { + { + .name = "RFC 6803 key derivation", + .run_case = kdf_case, + .generate_params = rfc6803_kdf_gen_params, + }, +}; + +static struct kunit_suite rfc6803_suite = { + .name = "RFC 6803 suite", + .test_cases = rfc6803_test_cases, +}; + kunit_test_suites(&rfc3961_suite, - &rfc3962_suite); + &rfc3962_suite, + &rfc6803_suite); MODULE_DESCRIPTION("Test RPCSEC GSS Kerberos 5 functions"); MODULE_LICENSE("GPL"); From patchwork Fri Jan 13 15:25:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100977 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D1A8C61DB3 for ; Fri, 13 Jan 2023 15:32:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229947AbjAMPcQ (ORCPT ); Fri, 13 Jan 2023 10:32:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53646 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230264AbjAMPbu (ORCPT ); Fri, 13 Jan 2023 10:31:50 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD0E9CDA for ; Fri, 13 Jan 2023 07:25:17 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 488F26216C for ; Fri, 13 Jan 2023 15:25:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7A745C433EF; Fri, 13 Jan 2023 15:25:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623516; bh=Y7I3lqcAdVFhm6H8KBTMsXsQ5elpYkLqFWxEPhmBp4s=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=XEyvtyk0n2btU+XF3KObfWl+vt8tVheFkBdRl22oM5N29B2xphQFk8k4F09LYRwf/ XDslSXca9nySKVgjNiO9a1nLPdQNIJ9r0JWkRAN3sH4jNXSE/qubDZ2K9s4sSpDk+e uRHERvD+X1cTPF8rw5GfXtEK573sVRsS6k1Fc6c8sSkKGiNdTA1jbTCiBsgovDonXN fIK90Oq7lgYYVe0h7GYO0CDmKdt4DiaGAwUgV804w9XdAvdLZW8OH+tlm1zL8RR0rn m6VNskHSoZe54Poa/KMPyIaJJ8BJFvcXepaHT4RorS2V+j+hCB8YJJvdJXmTuJNehH SQIh5AhECmqaw== Subject: [PATCH v1 36/41] SUNRPC: Add checksum KUnit tests for the RFC 6803 encryption types From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:15 -0500 Message-ID: <167362351563.8960.7123282096118809453.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Test the new-to-RPCSEC CMAC digest algorithm. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 1 net/sunrpc/auth_gss/gss_krb5_test.c | 168 +++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index f5c086471881..f2b84a07d1a1 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -356,6 +356,7 @@ gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, kfree_sensitive(checksumdata); return err ? GSS_S_FAILURE : GSS_S_COMPLETE; } +EXPORT_SYMBOL_IF_KUNIT(gss_krb5_checksum); struct encryptor_desc { u8 iv[GSS_KRB5_MAX_BLOCKSIZE]; diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index c80a8f6588c0..ea8cba8c3eb3 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -64,6 +65,52 @@ static void kdf_case(struct kunit *test) "key mismatch"); } +static void checksum_case(struct kunit *test) +{ + const struct gss_krb5_test_param *param = test->param_value; + struct xdr_buf buf = { + .head[0].iov_base = param->plaintext->data, + .head[0].iov_len = param->plaintext->len, + .len = param->plaintext->len, + }; + const struct gss_krb5_enctype *gk5e; + struct xdr_netobj Kc, checksum; + struct crypto_ahash *tfm; + int err; + + /* Arrange */ + gk5e = gss_krb5_lookup_enctype(param->enctype); + KUNIT_ASSERT_NOT_NULL(test, gk5e); + + Kc.len = gk5e->Kc_length; + Kc.data = kunit_kzalloc(test, Kc.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, Kc.data); + err = gk5e->derive_key(gk5e, param->base_key, &Kc, + param->usage, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, err, 0); + + tfm = crypto_alloc_ahash(gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, tfm); + err = crypto_ahash_setkey(tfm, Kc.data, Kc.len); + KUNIT_ASSERT_EQ(test, err, 0); + + checksum.len = gk5e->cksumlength; + checksum.data = kunit_kzalloc(test, checksum.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, checksum.data); + + /* Act */ + err = gss_krb5_checksum(tfm, NULL, 0, &buf, 0, &checksum); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Assert */ + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->expected_result->data, + checksum.data, checksum.len), 0, + "checksum mismatch"); + + crypto_free_ahash(tfm); +} + #define DEFINE_HEX_XDR_NETOBJ(name, hex_array...) \ static const u8 name ## _data[] = { hex_array }; \ static const struct xdr_netobj name = { \ @@ -71,6 +118,13 @@ static void kdf_case(struct kunit *test) .len = sizeof(name##_data), \ } +#define DEFINE_STR_XDR_NETOBJ(name, string) \ + static const u8 name ## _str[] = string; \ + static const struct xdr_netobj name = { \ + .data = (u8 *)name##_str, \ + .len = sizeof(name##_str) - 1, \ + } + /* * RFC 3961 Appendix A.1. n-fold * @@ -836,12 +890,126 @@ static const struct gss_krb5_test_param rfc6803_kdf_test_params[] = { /* Creates the function rfc6803_kdf_gen_params */ KUNIT_ARRAY_PARAM(rfc6803_kdf, rfc6803_kdf_test_params, gss_krb5_get_desc); +/* + * From RFC 6803 Section 10. Test vectors + * + * Sample checksums. + * + * Copyright (c) 2012 IETF Trust and the persons identified as the + * document authors. All rights reserved. + * + * XXX: These tests are likely to fail on EBCDIC or Unicode platforms. + */ +DEFINE_STR_XDR_NETOBJ(rfc6803_checksum_test1_plaintext, + "abcdefghijk"); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test1_basekey, + 0x1d, 0xc4, 0x6a, 0x8d, 0x76, 0x3f, 0x4f, 0x93, + 0x74, 0x2b, 0xcb, 0xa3, 0x38, 0x75, 0x76, 0xc3 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test1_usage, + 0x00, 0x00, 0x00, 0x07, KEY_USAGE_SEED_CHECKSUM +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test1_expected_result, + 0x11, 0x78, 0xe6, 0xc5, 0xc4, 0x7a, 0x8c, 0x1a, + 0xe0, 0xc4, 0xb9, 0xc7, 0xd4, 0xeb, 0x7b, 0x6b +); + +DEFINE_STR_XDR_NETOBJ(rfc6803_checksum_test2_plaintext, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test2_basekey, + 0x50, 0x27, 0xbc, 0x23, 0x1d, 0x0f, 0x3a, 0x9d, + 0x23, 0x33, 0x3f, 0x1c, 0xa6, 0xfd, 0xbe, 0x7c +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test2_usage, + 0x00, 0x00, 0x00, 0x08, KEY_USAGE_SEED_CHECKSUM +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test2_expected_result, + 0xd1, 0xb3, 0x4f, 0x70, 0x04, 0xa7, 0x31, 0xf2, + 0x3a, 0x0c, 0x00, 0xbf, 0x6c, 0x3f, 0x75, 0x3a +); + +DEFINE_STR_XDR_NETOBJ(rfc6803_checksum_test3_plaintext, + "123456789"); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test3_basekey, + 0xb6, 0x1c, 0x86, 0xcc, 0x4e, 0x5d, 0x27, 0x57, + 0x54, 0x5a, 0xd4, 0x23, 0x39, 0x9f, 0xb7, 0x03, + 0x1e, 0xca, 0xb9, 0x13, 0xcb, 0xb9, 0x00, 0xbd, + 0x7a, 0x3c, 0x6d, 0xd8, 0xbf, 0x92, 0x01, 0x5b +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test3_usage, + 0x00, 0x00, 0x00, 0x09, KEY_USAGE_SEED_CHECKSUM +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test3_expected_result, + 0x87, 0xa1, 0x2c, 0xfd, 0x2b, 0x96, 0x21, 0x48, + 0x10, 0xf0, 0x1c, 0x82, 0x6e, 0x77, 0x44, 0xb1 +); + +DEFINE_STR_XDR_NETOBJ(rfc6803_checksum_test4_plaintext, + "!@#$%^&*()!@#$%^&*()!@#$%^&*()"); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test4_basekey, + 0x32, 0x16, 0x4c, 0x5b, 0x43, 0x4d, 0x1d, 0x15, + 0x38, 0xe4, 0xcf, 0xd9, 0xbe, 0x80, 0x40, 0xfe, + 0x8c, 0x4a, 0xc7, 0xac, 0xc4, 0xb9, 0x3d, 0x33, + 0x14, 0xd2, 0x13, 0x36, 0x68, 0x14, 0x7a, 0x05 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test4_usage, + 0x00, 0x00, 0x00, 0x0a, KEY_USAGE_SEED_CHECKSUM +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_checksum_test4_expected_result, + 0x3f, 0xa0, 0xb4, 0x23, 0x55, 0xe5, 0x2b, 0x18, + 0x91, 0x87, 0x29, 0x4a, 0xa2, 0x52, 0xab, 0x64 +); + +static const struct gss_krb5_test_param rfc6803_checksum_test_params[] = { + { + .desc = "camellia128-cts-cmac checksum test 1", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .base_key = &rfc6803_checksum_test1_basekey, + .usage = &rfc6803_checksum_test1_usage, + .plaintext = &rfc6803_checksum_test1_plaintext, + .expected_result = &rfc6803_checksum_test1_expected_result, + }, + { + .desc = "camellia128-cts-cmac checksum test 2", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .base_key = &rfc6803_checksum_test2_basekey, + .usage = &rfc6803_checksum_test2_usage, + .plaintext = &rfc6803_checksum_test2_plaintext, + .expected_result = &rfc6803_checksum_test2_expected_result, + }, + { + .desc = "camellia256-cts-cmac checksum test 3", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .base_key = &rfc6803_checksum_test3_basekey, + .usage = &rfc6803_checksum_test3_usage, + .plaintext = &rfc6803_checksum_test3_plaintext, + .expected_result = &rfc6803_checksum_test3_expected_result, + }, + { + .desc = "camellia256-cts-cmac checksum test 4", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .base_key = &rfc6803_checksum_test4_basekey, + .usage = &rfc6803_checksum_test4_usage, + .plaintext = &rfc6803_checksum_test4_plaintext, + .expected_result = &rfc6803_checksum_test4_expected_result, + }, +}; + +/* Creates the function rfc6803_checksum_gen_params */ +KUNIT_ARRAY_PARAM(rfc6803_checksum, rfc6803_checksum_test_params, + gss_krb5_get_desc); + static struct kunit_case rfc6803_test_cases[] = { { .name = "RFC 6803 key derivation", .run_case = kdf_case, .generate_params = rfc6803_kdf_gen_params, }, + { + .name = "RFC 6803 checksum", + .run_case = checksum_case, + .generate_params = rfc6803_checksum_gen_params, + }, }; static struct kunit_suite rfc6803_suite = { From patchwork Fri Jan 13 15:25:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100976 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11A3BC54EBE for ; Fri, 13 Jan 2023 15:32:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229669AbjAMPcM (ORCPT ); Fri, 13 Jan 2023 10:32:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229947AbjAMPbv (ORCPT ); Fri, 13 Jan 2023 10:31:51 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2352140C32 for ; Fri, 13 Jan 2023 07:25:24 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A7050621BE for ; Fri, 13 Jan 2023 15:25:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C6ABAC433F0; Fri, 13 Jan 2023 15:25:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623523; bh=B9Grsp+KSucs7jDEeyZT6+CPUp3aLVDeWFEEnhXEoWw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=osrvY0eOsqSBsP2BshYYrAgs6CboSTw247141LewH5ShTLDr7PRwDWnrERbzT3ipx D6Prn7BSN0T43CBhn2j6r11FV8qSPHA0Hbc/GuuTWk2c17+Hms+DrSGVxe1JQsim48 x1Hun6ujANnZd2LAyw3kQn15Ukq7LLJAHUxsPrj7t+efOtZ2gFJLBrTgokyDWNSPuk /4/CoyB1zyz5cERXcDLPEXiikqrzzmZOrgMFURu+dNoG6xVyeND2K6W0FNdQ0Li3yK 4o5mxsN6vxL6fQOxiYlyiWdjjUPS8hSGvEKJsImUIkjOtPMk618fhutEH3pzdf90TZ gqCzMKnFySS1Q== Subject: [PATCH v1 37/41] SUNRPC: Add encryption KUnit tests for the RFC 6803 encryption types From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:21 -0500 Message-ID: <167362352191.8960.4363697488372595984.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Add tests for the new-to-RPCSEC Camellia cipher. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_test.c | 400 +++++++++++++++++++++++++++++++++++ 1 file changed, 400 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index ea8cba8c3eb3..3d8d41aab5fe 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -23,10 +23,12 @@ struct gss_krb5_test_param { const char *desc; u32 enctype; u32 nfold; + u32 constant; const struct xdr_netobj *base_key; const struct xdr_netobj *Ke; const struct xdr_netobj *usage; const struct xdr_netobj *plaintext; + const struct xdr_netobj *confounder; const struct xdr_netobj *expected_result; const struct xdr_netobj *next_iv; }; @@ -999,6 +1001,399 @@ static const struct gss_krb5_test_param rfc6803_checksum_test_params[] = { KUNIT_ARRAY_PARAM(rfc6803_checksum, rfc6803_checksum_test_params, gss_krb5_get_desc); +/* + * From RFC 6803 Section 10. Test vectors + * + * Sample encryptions (all using the default cipher state) + * + * Copyright (c) 2012 IETF Trust and the persons identified as the + * document authors. All rights reserved. + * + * Key usage values are from errata 4326 against RFC 6803. + */ + +static const struct xdr_netobj rfc6803_enc_empty_plaintext = { + .len = 0, +}; + +DEFINE_STR_XDR_NETOBJ(rfc6803_enc_1byte_plaintext, "1"); +DEFINE_STR_XDR_NETOBJ(rfc6803_enc_9byte_plaintext, "9 bytesss"); +DEFINE_STR_XDR_NETOBJ(rfc6803_enc_13byte_plaintext, "13 bytes byte"); +DEFINE_STR_XDR_NETOBJ(rfc6803_enc_30byte_plaintext, + "30 bytes bytes bytes bytes byt" +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test1_confounder, + 0xb6, 0x98, 0x22, 0xa1, 0x9a, 0x6b, 0x09, 0xc0, + 0xeb, 0xc8, 0x55, 0x7d, 0x1f, 0x1b, 0x6c, 0x0a +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test1_basekey, + 0x1d, 0xc4, 0x6a, 0x8d, 0x76, 0x3f, 0x4f, 0x93, + 0x74, 0x2b, 0xcb, 0xa3, 0x38, 0x75, 0x76, 0xc3 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test1_expected_result, + 0xc4, 0x66, 0xf1, 0x87, 0x10, 0x69, 0x92, 0x1e, + 0xdb, 0x7c, 0x6f, 0xde, 0x24, 0x4a, 0x52, 0xdb, + 0x0b, 0xa1, 0x0e, 0xdc, 0x19, 0x7b, 0xdb, 0x80, + 0x06, 0x65, 0x8c, 0xa3, 0xcc, 0xce, 0x6e, 0xb8 +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test2_confounder, + 0x6f, 0x2f, 0xc3, 0xc2, 0xa1, 0x66, 0xfd, 0x88, + 0x98, 0x96, 0x7a, 0x83, 0xde, 0x95, 0x96, 0xd9 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test2_basekey, + 0x50, 0x27, 0xbc, 0x23, 0x1d, 0x0f, 0x3a, 0x9d, + 0x23, 0x33, 0x3f, 0x1c, 0xa6, 0xfd, 0xbe, 0x7c +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test2_expected_result, + 0x84, 0x2d, 0x21, 0xfd, 0x95, 0x03, 0x11, 0xc0, + 0xdd, 0x46, 0x4a, 0x3f, 0x4b, 0xe8, 0xd6, 0xda, + 0x88, 0xa5, 0x6d, 0x55, 0x9c, 0x9b, 0x47, 0xd3, + 0xf9, 0xa8, 0x50, 0x67, 0xaf, 0x66, 0x15, 0x59, + 0xb8 +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test3_confounder, + 0xa5, 0xb4, 0xa7, 0x1e, 0x07, 0x7a, 0xee, 0xf9, + 0x3c, 0x87, 0x63, 0xc1, 0x8f, 0xdb, 0x1f, 0x10 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test3_basekey, + 0xa1, 0xbb, 0x61, 0xe8, 0x05, 0xf9, 0xba, 0x6d, + 0xde, 0x8f, 0xdb, 0xdd, 0xc0, 0x5c, 0xde, 0xa0 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test3_expected_result, + 0x61, 0x9f, 0xf0, 0x72, 0xe3, 0x62, 0x86, 0xff, + 0x0a, 0x28, 0xde, 0xb3, 0xa3, 0x52, 0xec, 0x0d, + 0x0e, 0xdf, 0x5c, 0x51, 0x60, 0xd6, 0x63, 0xc9, + 0x01, 0x75, 0x8c, 0xcf, 0x9d, 0x1e, 0xd3, 0x3d, + 0x71, 0xdb, 0x8f, 0x23, 0xaa, 0xbf, 0x83, 0x48, + 0xa0 +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test4_confounder, + 0x19, 0xfe, 0xe4, 0x0d, 0x81, 0x0c, 0x52, 0x4b, + 0x5b, 0x22, 0xf0, 0x18, 0x74, 0xc6, 0x93, 0xda +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test4_basekey, + 0x2c, 0xa2, 0x7a, 0x5f, 0xaf, 0x55, 0x32, 0x24, + 0x45, 0x06, 0x43, 0x4e, 0x1c, 0xef, 0x66, 0x76 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test4_expected_result, + 0xb8, 0xec, 0xa3, 0x16, 0x7a, 0xe6, 0x31, 0x55, + 0x12, 0xe5, 0x9f, 0x98, 0xa7, 0xc5, 0x00, 0x20, + 0x5e, 0x5f, 0x63, 0xff, 0x3b, 0xb3, 0x89, 0xaf, + 0x1c, 0x41, 0xa2, 0x1d, 0x64, 0x0d, 0x86, 0x15, + 0xc9, 0xed, 0x3f, 0xbe, 0xb0, 0x5a, 0xb6, 0xac, + 0xb6, 0x76, 0x89, 0xb5, 0xea +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test5_confounder, + 0xca, 0x7a, 0x7a, 0xb4, 0xbe, 0x19, 0x2d, 0xab, + 0xd6, 0x03, 0x50, 0x6d, 0xb1, 0x9c, 0x39, 0xe2 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test5_basekey, + 0x78, 0x24, 0xf8, 0xc1, 0x6f, 0x83, 0xff, 0x35, + 0x4c, 0x6b, 0xf7, 0x51, 0x5b, 0x97, 0x3f, 0x43 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test5_expected_result, + 0xa2, 0x6a, 0x39, 0x05, 0xa4, 0xff, 0xd5, 0x81, + 0x6b, 0x7b, 0x1e, 0x27, 0x38, 0x0d, 0x08, 0x09, + 0x0c, 0x8e, 0xc1, 0xf3, 0x04, 0x49, 0x6e, 0x1a, + 0xbd, 0xcd, 0x2b, 0xdc, 0xd1, 0xdf, 0xfc, 0x66, + 0x09, 0x89, 0xe1, 0x17, 0xa7, 0x13, 0xdd, 0xbb, + 0x57, 0xa4, 0x14, 0x6c, 0x15, 0x87, 0xcb, 0xa4, + 0x35, 0x66, 0x65, 0x59, 0x1d, 0x22, 0x40, 0x28, + 0x2f, 0x58, 0x42, 0xb1, 0x05, 0xa5 +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test6_confounder, + 0x3c, 0xbb, 0xd2, 0xb4, 0x59, 0x17, 0x94, 0x10, + 0x67, 0xf9, 0x65, 0x99, 0xbb, 0x98, 0x92, 0x6c +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test6_basekey, + 0xb6, 0x1c, 0x86, 0xcc, 0x4e, 0x5d, 0x27, 0x57, + 0x54, 0x5a, 0xd4, 0x23, 0x39, 0x9f, 0xb7, 0x03, + 0x1e, 0xca, 0xb9, 0x13, 0xcb, 0xb9, 0x00, 0xbd, + 0x7a, 0x3c, 0x6d, 0xd8, 0xbf, 0x92, 0x01, 0x5b +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test6_expected_result, + 0x03, 0x88, 0x6d, 0x03, 0x31, 0x0b, 0x47, 0xa6, + 0xd8, 0xf0, 0x6d, 0x7b, 0x94, 0xd1, 0xdd, 0x83, + 0x7e, 0xcc, 0xe3, 0x15, 0xef, 0x65, 0x2a, 0xff, + 0x62, 0x08, 0x59, 0xd9, 0x4a, 0x25, 0x92, 0x66 +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test7_confounder, + 0xde, 0xf4, 0x87, 0xfc, 0xeb, 0xe6, 0xde, 0x63, + 0x46, 0xd4, 0xda, 0x45, 0x21, 0xbb, 0xa2, 0xd2 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test7_basekey, + 0x1b, 0x97, 0xfe, 0x0a, 0x19, 0x0e, 0x20, 0x21, + 0xeb, 0x30, 0x75, 0x3e, 0x1b, 0x6e, 0x1e, 0x77, + 0xb0, 0x75, 0x4b, 0x1d, 0x68, 0x46, 0x10, 0x35, + 0x58, 0x64, 0x10, 0x49, 0x63, 0x46, 0x38, 0x33 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test7_expected_result, + 0x2c, 0x9c, 0x15, 0x70, 0x13, 0x3c, 0x99, 0xbf, + 0x6a, 0x34, 0xbc, 0x1b, 0x02, 0x12, 0x00, 0x2f, + 0xd1, 0x94, 0x33, 0x87, 0x49, 0xdb, 0x41, 0x35, + 0x49, 0x7a, 0x34, 0x7c, 0xfc, 0xd9, 0xd1, 0x8a, + 0x12 +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test8_confounder, + 0xad, 0x4f, 0xf9, 0x04, 0xd3, 0x4e, 0x55, 0x53, + 0x84, 0xb1, 0x41, 0x00, 0xfc, 0x46, 0x5f, 0x88 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test8_basekey, + 0x32, 0x16, 0x4c, 0x5b, 0x43, 0x4d, 0x1d, 0x15, + 0x38, 0xe4, 0xcf, 0xd9, 0xbe, 0x80, 0x40, 0xfe, + 0x8c, 0x4a, 0xc7, 0xac, 0xc4, 0xb9, 0x3d, 0x33, + 0x14, 0xd2, 0x13, 0x36, 0x68, 0x14, 0x7a, 0x05 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test8_expected_result, + 0x9c, 0x6d, 0xe7, 0x5f, 0x81, 0x2d, 0xe7, 0xed, + 0x0d, 0x28, 0xb2, 0x96, 0x35, 0x57, 0xa1, 0x15, + 0x64, 0x09, 0x98, 0x27, 0x5b, 0x0a, 0xf5, 0x15, + 0x27, 0x09, 0x91, 0x3f, 0xf5, 0x2a, 0x2a, 0x9c, + 0x8e, 0x63, 0xb8, 0x72, 0xf9, 0x2e, 0x64, 0xc8, + 0x39 +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test9_confounder, + 0xcf, 0x9b, 0xca, 0x6d, 0xf1, 0x14, 0x4e, 0x0c, + 0x0a, 0xf9, 0xb8, 0xf3, 0x4c, 0x90, 0xd5, 0x14 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test9_basekey, + 0xb0, 0x38, 0xb1, 0x32, 0xcd, 0x8e, 0x06, 0x61, + 0x22, 0x67, 0xfa, 0xb7, 0x17, 0x00, 0x66, 0xd8, + 0x8a, 0xec, 0xcb, 0xa0, 0xb7, 0x44, 0xbf, 0xc6, + 0x0d, 0xc8, 0x9b, 0xca, 0x18, 0x2d, 0x07, 0x15 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test9_expected_result, + 0xee, 0xec, 0x85, 0xa9, 0x81, 0x3c, 0xdc, 0x53, + 0x67, 0x72, 0xab, 0x9b, 0x42, 0xde, 0xfc, 0x57, + 0x06, 0xf7, 0x26, 0xe9, 0x75, 0xdd, 0xe0, 0x5a, + 0x87, 0xeb, 0x54, 0x06, 0xea, 0x32, 0x4c, 0xa1, + 0x85, 0xc9, 0x98, 0x6b, 0x42, 0xaa, 0xbe, 0x79, + 0x4b, 0x84, 0x82, 0x1b, 0xee +); + +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test10_confounder, + 0x64, 0x4d, 0xef, 0x38, 0xda, 0x35, 0x00, 0x72, + 0x75, 0x87, 0x8d, 0x21, 0x68, 0x55, 0xe2, 0x28 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test10_basekey, + 0xcc, 0xfc, 0xd3, 0x49, 0xbf, 0x4c, 0x66, 0x77, + 0xe8, 0x6e, 0x4b, 0x02, 0xb8, 0xea, 0xb9, 0x24, + 0xa5, 0x46, 0xac, 0x73, 0x1c, 0xf9, 0xbf, 0x69, + 0x89, 0xb9, 0x96, 0xe7, 0xd6, 0xbf, 0xbb, 0xa7 +); +DEFINE_HEX_XDR_NETOBJ(rfc6803_enc_test10_expected_result, + 0x0e, 0x44, 0x68, 0x09, 0x85, 0x85, 0x5f, 0x2d, + 0x1f, 0x18, 0x12, 0x52, 0x9c, 0xa8, 0x3b, 0xfd, + 0x8e, 0x34, 0x9d, 0xe6, 0xfd, 0x9a, 0xda, 0x0b, + 0xaa, 0xa0, 0x48, 0xd6, 0x8e, 0x26, 0x5f, 0xeb, + 0xf3, 0x4a, 0xd1, 0x25, 0x5a, 0x34, 0x49, 0x99, + 0xad, 0x37, 0x14, 0x68, 0x87, 0xa6, 0xc6, 0x84, + 0x57, 0x31, 0xac, 0x7f, 0x46, 0x37, 0x6a, 0x05, + 0x04, 0xcd, 0x06, 0x57, 0x14, 0x74 +); + +static const struct gss_krb5_test_param rfc6803_encrypt_test_params[] = { + { + .desc = "Encrypt empty plaintext with camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .constant = 0, + .base_key = &rfc6803_enc_test1_basekey, + .plaintext = &rfc6803_enc_empty_plaintext, + .confounder = &rfc6803_enc_test1_confounder, + .expected_result = &rfc6803_enc_test1_expected_result, + }, + { + .desc = "Encrypt 1 byte with camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .constant = 1, + .base_key = &rfc6803_enc_test2_basekey, + .plaintext = &rfc6803_enc_1byte_plaintext, + .confounder = &rfc6803_enc_test2_confounder, + .expected_result = &rfc6803_enc_test2_expected_result, + }, + { + .desc = "Encrypt 9 bytes with camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .constant = 2, + .base_key = &rfc6803_enc_test3_basekey, + .plaintext = &rfc6803_enc_9byte_plaintext, + .confounder = &rfc6803_enc_test3_confounder, + .expected_result = &rfc6803_enc_test3_expected_result, + }, + { + .desc = "Encrypt 13 bytes with camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .constant = 3, + .base_key = &rfc6803_enc_test4_basekey, + .plaintext = &rfc6803_enc_13byte_plaintext, + .confounder = &rfc6803_enc_test4_confounder, + .expected_result = &rfc6803_enc_test4_expected_result, + }, + { + .desc = "Encrypt 30 bytes with camellia128-cts-cmac", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .constant = 4, + .base_key = &rfc6803_enc_test5_basekey, + .plaintext = &rfc6803_enc_30byte_plaintext, + .confounder = &rfc6803_enc_test5_confounder, + .expected_result = &rfc6803_enc_test5_expected_result, + }, + { + .desc = "Encrypt empty plaintext with camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .constant = 0, + .base_key = &rfc6803_enc_test6_basekey, + .plaintext = &rfc6803_enc_empty_plaintext, + .confounder = &rfc6803_enc_test6_confounder, + .expected_result = &rfc6803_enc_test6_expected_result, + }, + { + .desc = "Encrypt 1 byte with camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .constant = 1, + .base_key = &rfc6803_enc_test7_basekey, + .plaintext = &rfc6803_enc_1byte_plaintext, + .confounder = &rfc6803_enc_test7_confounder, + .expected_result = &rfc6803_enc_test7_expected_result, + }, + { + .desc = "Encrypt 9 bytes with camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .constant = 2, + .base_key = &rfc6803_enc_test8_basekey, + .plaintext = &rfc6803_enc_9byte_plaintext, + .confounder = &rfc6803_enc_test8_confounder, + .expected_result = &rfc6803_enc_test8_expected_result, + }, + { + .desc = "Encrypt 13 bytes with camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .constant = 3, + .base_key = &rfc6803_enc_test9_basekey, + .plaintext = &rfc6803_enc_13byte_plaintext, + .confounder = &rfc6803_enc_test9_confounder, + .expected_result = &rfc6803_enc_test9_expected_result, + }, + { + .desc = "Encrypt 30 bytes with camellia256-cts-cmac", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .constant = 4, + .base_key = &rfc6803_enc_test10_basekey, + .plaintext = &rfc6803_enc_30byte_plaintext, + .confounder = &rfc6803_enc_test10_confounder, + .expected_result = &rfc6803_enc_test10_expected_result, + }, +}; + +/* Creates the function rfc6803_encrypt_gen_params */ +KUNIT_ARRAY_PARAM(rfc6803_encrypt, rfc6803_encrypt_test_params, + gss_krb5_get_desc); + +static void rfc6803_encrypt_case(struct kunit *test) +{ + const struct gss_krb5_test_param *param = test->param_value; + struct crypto_sync_skcipher *cts_tfm, *cbc_tfm; + const struct gss_krb5_enctype *gk5e; + struct xdr_netobj Ke, Ki, checksum; + u8 usage_data[GSS_KRB5_K5CLENGTH]; + struct xdr_netobj usage = { + .data = usage_data, + .len = sizeof(usage_data), + }; + struct crypto_ahash *ahash_tfm; + unsigned int blocksize; + struct xdr_buf buf; + void *text; + size_t len; + u32 err; + + /* Arrange */ + gk5e = gss_krb5_lookup_enctype(param->enctype); + KUNIT_ASSERT_NOT_NULL(test, gk5e); + + usage.data[3] = param->constant; + + Ke.len = gk5e->Ke_length; + Ke.data = kunit_kzalloc(test, Ke.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, Ke.data); + usage.data[4] = KEY_USAGE_SEED_ENCRYPTION; + err = gk5e->derive_key(gk5e, param->base_key, &Ke, &usage, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, err, 0); + + cbc_tfm = crypto_alloc_sync_skcipher(gk5e->aux_cipher, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cbc_tfm); + err = crypto_sync_skcipher_setkey(cbc_tfm, Ke.data, Ke.len); + KUNIT_ASSERT_EQ(test, err, 0); + + cts_tfm = crypto_alloc_sync_skcipher(gk5e->encrypt_name, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cts_tfm); + err = crypto_sync_skcipher_setkey(cts_tfm, Ke.data, Ke.len); + KUNIT_ASSERT_EQ(test, err, 0); + blocksize = crypto_sync_skcipher_blocksize(cts_tfm); + + len = param->confounder->len + param->plaintext->len + blocksize; + text = kunit_kzalloc(test, len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, text); + memcpy(text, param->confounder->data, param->confounder->len); + memcpy(text + param->confounder->len, param->plaintext->data, + param->plaintext->len); + + memset(&buf, 0, sizeof(buf)); + buf.head[0].iov_base = text; + buf.head[0].iov_len = param->confounder->len + param->plaintext->len; + buf.len = buf.head[0].iov_len; + + checksum.len = gk5e->cksumlength; + checksum.data = kunit_kzalloc(test, checksum.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, checksum.data); + + Ki.len = gk5e->Ki_length; + Ki.data = kunit_kzalloc(test, Ki.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, Ki.data); + usage.data[4] = KEY_USAGE_SEED_INTEGRITY; + err = gk5e->derive_key(gk5e, param->base_key, &Ki, + &usage, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, err, 0); + ahash_tfm = crypto_alloc_ahash(gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ahash_tfm); + err = crypto_ahash_setkey(ahash_tfm, Ki.data, Ki.len); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Act */ + err = gss_krb5_checksum(ahash_tfm, NULL, 0, &buf, 0, &checksum); + KUNIT_ASSERT_EQ(test, err, 0); + + err = krb5_cbc_cts_encrypt(cts_tfm, cbc_tfm, 0, &buf, NULL, NULL, 0); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Assert */ + KUNIT_EXPECT_EQ_MSG(test, param->expected_result->len, + buf.len + checksum.len, + "ciphertext length mismatch"); + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->expected_result->data, + buf.head[0].iov_base, buf.len), 0, + "encrypted result mismatch"); + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->expected_result->data + + (param->expected_result->len - checksum.len), + checksum.data, checksum.len), 0, + "HMAC mismatch"); + + crypto_free_ahash(ahash_tfm); + crypto_free_sync_skcipher(cts_tfm); + crypto_free_sync_skcipher(cbc_tfm); +} + static struct kunit_case rfc6803_test_cases[] = { { .name = "RFC 6803 key derivation", @@ -1010,6 +1405,11 @@ static struct kunit_case rfc6803_test_cases[] = { .run_case = checksum_case, .generate_params = rfc6803_checksum_gen_params, }, + { + .name = "RFC 6803 encryption", + .run_case = rfc6803_encrypt_case, + .generate_params = rfc6803_encrypt_gen_params, + }, }; static struct kunit_suite rfc6803_suite = { From patchwork Fri Jan 13 15:25:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100979 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 214BAC61DB3 for ; Fri, 13 Jan 2023 15:32:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230246AbjAMPcb (ORCPT ); Fri, 13 Jan 2023 10:32:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230235AbjAMPbz (ORCPT ); Fri, 13 Jan 2023 10:31:55 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E7CF68C84 for ; Fri, 13 Jan 2023 07:25:30 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id EDBBC621E3 for ; Fri, 13 Jan 2023 15:25:29 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2BBB1C433F2; Fri, 13 Jan 2023 15:25:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623529; bh=Ji+xFET7VBoHvSkc5p2kDI9yqVAW6IUXD5IEaE75c6Y=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=SXa96z7NlsoYBDMIxS1QVDEA2jhesUVrTg11fJ9LOxV8YDpko1vUgqaXlGi2g9ogr toi/TwOwhGd+TURedWrbHJl1lgP1fDjavuModUAhggxdXXG1Tc/dDA557NHPXgkvi9 d7sT3JZvEP7axGwcLH3cGdGmBfPszifnJFsGHjcl0gzHf2sHuIs9KA7NvFd8+C8BEd RoMjg8bIN3W4QzHd3xer/kQIhE1xhoLK3PY3MI1fbmP6egTf6zfaZPtE8RY9QFUE5X nbICYpf4xf4ELNKDR6gpKqegqTMxOEyIk7DLxGZ5B2y8+gWDBZn82/96JABw89eEBa bRH50jDNAxEnA== Subject: [PATCH v1 38/41] SUNRPC: Add KDF-HMAC-SHA2 Kunit tests From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:28 -0500 Message-ID: <167362352830.8960.2255925977517994313.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever RFC 8009 provides sample key derivation results, so Kunit tests are added to ensure our implementation derives the expected keys for the provided sample input. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/.kunitconfig | 3 + net/sunrpc/auth_gss/gss_krb5_test.c | 113 +++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/.kunitconfig b/net/sunrpc/.kunitconfig index 90d0ad430e7e..a55a00fa649b 100644 --- a/net/sunrpc/.kunitconfig +++ b/net/sunrpc/.kunitconfig @@ -14,6 +14,8 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_CAMELLIA=y @@ -24,4 +26,5 @@ CONFIG_RPCSEC_GSS_KRB5=y CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES=y CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1=y CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA=y +CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2=y CONFIG_RPCSEC_GSS_KRB5_KUNIT_TEST=y diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index 3d8d41aab5fe..ad4737b60b56 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -1417,9 +1417,120 @@ static struct kunit_suite rfc6803_suite = { .test_cases = rfc6803_test_cases, }; +/* + * From RFC 8009 Appendix A. Test Vectors + * + * Sample results for SHA-2 enctype key derivation + * + * This test material is copyright (c) 2016 IETF Trust and the + * persons identified as the document authors. All rights reserved. + */ + +DEFINE_HEX_XDR_NETOBJ(aes128_cts_hmac_sha256_128_basekey, + 0x37, 0x05, 0xd9, 0x60, 0x80, 0xc1, 0x77, 0x28, + 0xa0, 0xe8, 0x00, 0xea, 0xb6, 0xe0, 0xd2, 0x3c +); +DEFINE_HEX_XDR_NETOBJ(aes128_cts_hmac_sha256_128_Kc, + 0xb3, 0x1a, 0x01, 0x8a, 0x48, 0xf5, 0x47, 0x76, + 0xf4, 0x03, 0xe9, 0xa3, 0x96, 0x32, 0x5d, 0xc3 +); +DEFINE_HEX_XDR_NETOBJ(aes128_cts_hmac_sha256_128_Ke, + 0x9b, 0x19, 0x7d, 0xd1, 0xe8, 0xc5, 0x60, 0x9d, + 0x6e, 0x67, 0xc3, 0xe3, 0x7c, 0x62, 0xc7, 0x2e +); +DEFINE_HEX_XDR_NETOBJ(aes128_cts_hmac_sha256_128_Ki, + 0x9f, 0xda, 0x0e, 0x56, 0xab, 0x2d, 0x85, 0xe1, + 0x56, 0x9a, 0x68, 0x86, 0x96, 0xc2, 0x6a, 0x6c +); + +DEFINE_HEX_XDR_NETOBJ(aes256_cts_hmac_sha384_192_basekey, + 0x6d, 0x40, 0x4d, 0x37, 0xfa, 0xf7, 0x9f, 0x9d, + 0xf0, 0xd3, 0x35, 0x68, 0xd3, 0x20, 0x66, 0x98, + 0x00, 0xeb, 0x48, 0x36, 0x47, 0x2e, 0xa8, 0xa0, + 0x26, 0xd1, 0x6b, 0x71, 0x82, 0x46, 0x0c, 0x52 +); +DEFINE_HEX_XDR_NETOBJ(aes256_cts_hmac_sha384_192_Kc, + 0xef, 0x57, 0x18, 0xbe, 0x86, 0xcc, 0x84, 0x96, + 0x3d, 0x8b, 0xbb, 0x50, 0x31, 0xe9, 0xf5, 0xc4, + 0xba, 0x41, 0xf2, 0x8f, 0xaf, 0x69, 0xe7, 0x3d +); +DEFINE_HEX_XDR_NETOBJ(aes256_cts_hmac_sha384_192_Ke, + 0x56, 0xab, 0x22, 0xbe, 0xe6, 0x3d, 0x82, 0xd7, + 0xbc, 0x52, 0x27, 0xf6, 0x77, 0x3f, 0x8e, 0xa7, + 0xa5, 0xeb, 0x1c, 0x82, 0x51, 0x60, 0xc3, 0x83, + 0x12, 0x98, 0x0c, 0x44, 0x2e, 0x5c, 0x7e, 0x49 +); +DEFINE_HEX_XDR_NETOBJ(aes256_cts_hmac_sha384_192_Ki, + 0x69, 0xb1, 0x65, 0x14, 0xe3, 0xcd, 0x8e, 0x56, + 0xb8, 0x20, 0x10, 0xd5, 0xc7, 0x30, 0x12, 0xb6, + 0x22, 0xc4, 0xd0, 0x0f, 0xfc, 0x23, 0xed, 0x1f +); + +static const struct gss_krb5_test_param rfc8009_kdf_test_params[] = { + { + .desc = "Derive Kc subkey for aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .usage = &usage_checksum, + .expected_result = &aes128_cts_hmac_sha256_128_Kc, + }, + { + .desc = "Derive Ke subkey for aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .usage = &usage_encryption, + .expected_result = &aes128_cts_hmac_sha256_128_Ke, + }, + { + .desc = "Derive Ki subkey for aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .usage = &usage_integrity, + .expected_result = &aes128_cts_hmac_sha256_128_Ki, + }, + { + .desc = "Derive Kc subkey for aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .usage = &usage_checksum, + .expected_result = &aes256_cts_hmac_sha384_192_Kc, + }, + { + .desc = "Derive Ke subkey for aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .usage = &usage_encryption, + .expected_result = &aes256_cts_hmac_sha384_192_Ke, + }, + { + .desc = "Derive Ki subkey for aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .usage = &usage_integrity, + .expected_result = &aes256_cts_hmac_sha384_192_Ki, + }, +}; + +/* Creates the function rfc8009_kdf_gen_params */ +KUNIT_ARRAY_PARAM(rfc8009_kdf, rfc8009_kdf_test_params, gss_krb5_get_desc); + +static struct kunit_case rfc8009_test_cases[] = { + { + .name = "RFC 8009 key derivation", + .run_case = kdf_case, + .generate_params = rfc8009_kdf_gen_params, + }, +}; + +static struct kunit_suite rfc8009_suite = { + .name = "RFC 8009 suite", + .test_cases = rfc8009_test_cases, +}; + kunit_test_suites(&rfc3961_suite, &rfc3962_suite, - &rfc6803_suite); + &rfc6803_suite, + &rfc8009_suite); MODULE_DESCRIPTION("Test RPCSEC GSS Kerberos 5 functions"); MODULE_LICENSE("GPL"); From patchwork Fri Jan 13 15:25:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100980 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7EDEEC54EBD for ; Fri, 13 Jan 2023 15:32:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229599AbjAMPc4 (ORCPT ); Fri, 13 Jan 2023 10:32:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230259AbjAMPb7 (ORCPT ); Fri, 13 Jan 2023 10:31:59 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4378A7BCF7 for ; Fri, 13 Jan 2023 07:25:38 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id F01ABB8217A for ; Fri, 13 Jan 2023 15:25:36 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5A651C433EF; Fri, 13 Jan 2023 15:25:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623535; bh=g8WJ6fhL8jNraM89KSl6j4lzOWM+L9xF2xxiCmeUPR4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=NTtlIJvCg03sqNQ6CDLDvvMOYPx6RgBxyPR10n6006gzvVMuMgSpDhQ3qj+RQDsNz tBHe9h8Em0hWtSXFfC3qhnQ7cH+8NSCilt5QGW8Blfq6YJp3XTovXTrHveajw65rnG tv8whQ7FFeCWR1/U9YfFaXmB65/Kp/wFDznABuJHQyXm8UMb0Lv2A9fA9YCHBdm3IU MVTaHJnAs2lpaF2hIZ7Kd4Ska6TujQLXWp3LAIu2Fzij6lcVO5Ft/IvInxVceftk5A zmo9EfY80yTASq8KE8M+lzeFWe1kmsoyRQ5vciMq8isNjkEWbFK46E2KIf0Qtp+Gd8 g4M+Nu889UXnw== Subject: [PATCH v1 39/41] SUNRPC: Add RFC 8009 checksum KUnit tests From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:34 -0500 Message-ID: <167362353459.8960.14610209769312450607.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever RFC 8009 provides sample checksum results. Add KUnit tests to ensure our implementation derives the expected results for the provided sample input. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_test.c | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index ad4737b60b56..0399f8338066 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -1514,12 +1514,65 @@ static const struct gss_krb5_test_param rfc8009_kdf_test_params[] = { /* Creates the function rfc8009_kdf_gen_params */ KUNIT_ARRAY_PARAM(rfc8009_kdf, rfc8009_kdf_test_params, gss_krb5_get_desc); +/* + * From RFC 8009 Appendix A. Test Vectors + * + * These sample checksums use the above sample key derivation results, + * including use of the same base-key and key usage values. + * + * This test material is copyright (c) 2016 IETF Trust and the + * persons identified as the document authors. All rights reserved. + */ + +DEFINE_HEX_XDR_NETOBJ(rfc8009_checksum_plaintext, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_checksum_test1_expected_result, + 0xd7, 0x83, 0x67, 0x18, 0x66, 0x43, 0xd6, 0x7b, + 0x41, 0x1c, 0xba, 0x91, 0x39, 0xfc, 0x1d, 0xee +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_checksum_test2_expected_result, + 0x45, 0xee, 0x79, 0x15, 0x67, 0xee, 0xfc, 0xa3, + 0x7f, 0x4a, 0xc1, 0xe0, 0x22, 0x2d, 0xe8, 0x0d, + 0x43, 0xc3, 0xbf, 0xa0, 0x66, 0x99, 0x67, 0x2a +); + +static const struct gss_krb5_test_param rfc8009_checksum_test_params[] = { + { + .desc = "Checksum with aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .usage = &usage_checksum, + .plaintext = &rfc8009_checksum_plaintext, + .expected_result = &rfc8009_checksum_test1_expected_result, + }, + { + .desc = "Checksum with aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .usage = &usage_checksum, + .plaintext = &rfc8009_checksum_plaintext, + .expected_result = &rfc8009_checksum_test2_expected_result, + }, +}; + +/* Creates the function rfc8009_checksum_gen_params */ +KUNIT_ARRAY_PARAM(rfc8009_checksum, rfc8009_checksum_test_params, + gss_krb5_get_desc); + static struct kunit_case rfc8009_test_cases[] = { { .name = "RFC 8009 key derivation", .run_case = kdf_case, .generate_params = rfc8009_kdf_gen_params, }, + { + .name = "RFC 8009 checksum", + .run_case = checksum_case, + .generate_params = rfc8009_checksum_gen_params, + }, }; static struct kunit_suite rfc8009_suite = { From patchwork Fri Jan 13 15:25:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100981 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A78FC54EBE for ; Fri, 13 Jan 2023 15:32:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230257AbjAMPc6 (ORCPT ); Fri, 13 Jan 2023 10:32:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230200AbjAMPcC (ORCPT ); Fri, 13 Jan 2023 10:32:02 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F04DD7BCFB for ; Fri, 13 Jan 2023 07:25:42 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7E5366212C for ; Fri, 13 Jan 2023 15:25:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9DD6CC433D2; Fri, 13 Jan 2023 15:25:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623541; bh=i4hr3CoKaerZ+7qSXP2PF47E+GyOLN2XoMm8jU7Raeo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=B7y1AUdSAdgTXERdehu6crlMKWNFXLcwRqNN9YBUqSkqSvVN+N//eKQ4cOj/dDm7l qTp6areDys1fAzmtCO/x82dK5jPtmyx9hlNnmDZOrYrWhInQl0m9tv9rwAxUlJ6BF1 DI5omoFcl0EYLR3Gx/pgXuIE21CTKtlvx4eNNZDqZeFMHGFvkkotTCOr4sd2yDqkML q+RG+jeeZTl9COiAjks6K20iBjwapplBkZ9dkI1J4liurdd1C9Fe1kLnARgXFx5+JI RfxzLbtWgMZ+9S2hO+1BNapnGcXUfpaMAyaFgcdI+m4ubDCPjn6Ml0xYSMNLS063sv xggwuPIoD5vqw== Subject: [PATCH v1 40/41] SUNRPC: Add RFC 8009 encryption KUnit tests From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:40 -0500 Message-ID: <167362354078.8960.9453466829845461400.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever RFC 8009 provides sample encryption results. Add KUnit tests to ensure our implementation derives the expected results for the provided sample input. I hate how large this test is, but using non-standard key usage values means rfc8009_encrypt_case() can't simply reuse ->import_ctx to allocate and key its ciphers; and the test provides its own confounders, which means krb5_etm_encrypt() can't be used directly. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 26 ++ net/sunrpc/auth_gss/gss_krb5_internal.h | 3 net/sunrpc/auth_gss/gss_krb5_test.c | 329 +++++++++++++++++++++++++++++++ 3 files changed, 354 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index f2b84a07d1a1..e37d341a761b 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -881,10 +881,27 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, return ret; } -static u32 -krb5_etm_checksum(struct crypto_sync_skcipher *cipher, - struct crypto_ahash *tfm, const struct xdr_buf *body, - int body_offset, struct xdr_netobj *cksumout) +/** + * krb5_etm_checksum - Compute a MAC for a GSS Wrap token + * @cipher: an initialized cipher transform + * @tfm: an initialized hash transform + * @body: xdr_buf containing an RPC message (body.len is the message length) + * @body_offset: byte offset into @body to start checksumming + * @cksumout: OUT: a buffer to be filled in with the computed HMAC + * + * Usually expressed as H = HMAC(K, IV | ciphertext)[1..h] . + * + * Caller provides the truncation length of the output token (h) in + * cksumout.len. + * + * Return values: + * %GSS_S_COMPLETE: Digest computed, @cksumout filled in + * %GSS_S_FAILURE: Call failed + */ +VISIBLE_IF_KUNIT +u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher, + struct crypto_ahash *tfm, const struct xdr_buf *body, + int body_offset, struct xdr_netobj *cksumout) { unsigned int ivsize = crypto_sync_skcipher_ivsize(cipher); struct ahash_request *req; @@ -931,6 +948,7 @@ krb5_etm_checksum(struct crypto_sync_skcipher *cipher, kfree_sensitive(checksumdata); return err ? GSS_S_FAILURE : GSS_S_COMPLETE; } +EXPORT_SYMBOL_IF_KUNIT(krb5_etm_checksum); /** * krb5_etm_encrypt - Encrypt using the RFC 8009 rules diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index 3d4d1208ba19..bcc8992e274a 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -224,6 +224,9 @@ int krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, struct crypto_sync_skcipher *cbc_tfm, u32 offset, struct xdr_buf *buf, struct page **pages, u8 *iv, unsigned int ivsize); +u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher, + struct crypto_ahash *tfm, const struct xdr_buf *body, + int body_offset, struct xdr_netobj *cksumout); #endif #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index 0399f8338066..fe3e4b81221a 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -30,6 +30,7 @@ struct gss_krb5_test_param { const struct xdr_netobj *plaintext; const struct xdr_netobj *confounder; const struct xdr_netobj *expected_result; + const struct xdr_netobj *expected_hmac; const struct xdr_netobj *next_iv; }; @@ -1562,6 +1563,329 @@ static const struct gss_krb5_test_param rfc8009_checksum_test_params[] = { KUNIT_ARRAY_PARAM(rfc8009_checksum, rfc8009_checksum_test_params, gss_krb5_get_desc); +/* + * From RFC 8009 Appendix A. Test Vectors + * + * Sample encryptions (all using the default cipher state): + * -------------------------------------------------------- + * + * These sample encryptions use the above sample key derivation results, + * including use of the same base-key and key usage values. + * + * This test material is copyright (c) 2016 IETF Trust and the + * persons identified as the document authors. All rights reserved. + */ + +static const struct xdr_netobj rfc8009_enc_empty_plaintext = { + .len = 0, +}; +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_short_plaintext, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_block_plaintext, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_long_plaintext, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14 +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test1_confounder, + 0x7e, 0x58, 0x95, 0xea, 0xf2, 0x67, 0x24, 0x35, + 0xba, 0xd8, 0x17, 0xf5, 0x45, 0xa3, 0x71, 0x48 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test1_expected_result, + 0xef, 0x85, 0xfb, 0x89, 0x0b, 0xb8, 0x47, 0x2f, + 0x4d, 0xab, 0x20, 0x39, 0x4d, 0xca, 0x78, 0x1d +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test1_expected_hmac, + 0xad, 0x87, 0x7e, 0xda, 0x39, 0xd5, 0x0c, 0x87, + 0x0c, 0x0d, 0x5a, 0x0a, 0x8e, 0x48, 0xc7, 0x18 +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test2_confounder, + 0x7b, 0xca, 0x28, 0x5e, 0x2f, 0xd4, 0x13, 0x0f, + 0xb5, 0x5b, 0x1a, 0x5c, 0x83, 0xbc, 0x5b, 0x24 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test2_expected_result, + 0x84, 0xd7, 0xf3, 0x07, 0x54, 0xed, 0x98, 0x7b, + 0xab, 0x0b, 0xf3, 0x50, 0x6b, 0xeb, 0x09, 0xcf, + 0xb5, 0x54, 0x02, 0xce, 0xf7, 0xe6 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test2_expected_hmac, + 0x87, 0x7c, 0xe9, 0x9e, 0x24, 0x7e, 0x52, 0xd1, + 0x6e, 0xd4, 0x42, 0x1d, 0xfd, 0xf8, 0x97, 0x6c +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test3_confounder, + 0x56, 0xab, 0x21, 0x71, 0x3f, 0xf6, 0x2c, 0x0a, + 0x14, 0x57, 0x20, 0x0f, 0x6f, 0xa9, 0x94, 0x8f +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test3_expected_result, + 0x35, 0x17, 0xd6, 0x40, 0xf5, 0x0d, 0xdc, 0x8a, + 0xd3, 0x62, 0x87, 0x22, 0xb3, 0x56, 0x9d, 0x2a, + 0xe0, 0x74, 0x93, 0xfa, 0x82, 0x63, 0x25, 0x40, + 0x80, 0xea, 0x65, 0xc1, 0x00, 0x8e, 0x8f, 0xc2 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test3_expected_hmac, + 0x95, 0xfb, 0x48, 0x52, 0xe7, 0xd8, 0x3e, 0x1e, + 0x7c, 0x48, 0xc3, 0x7e, 0xeb, 0xe6, 0xb0, 0xd3 +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test4_confounder, + 0xa7, 0xa4, 0xe2, 0x9a, 0x47, 0x28, 0xce, 0x10, + 0x66, 0x4f, 0xb6, 0x4e, 0x49, 0xad, 0x3f, 0xac +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test4_expected_result, + 0x72, 0x0f, 0x73, 0xb1, 0x8d, 0x98, 0x59, 0xcd, + 0x6c, 0xcb, 0x43, 0x46, 0x11, 0x5c, 0xd3, 0x36, + 0xc7, 0x0f, 0x58, 0xed, 0xc0, 0xc4, 0x43, 0x7c, + 0x55, 0x73, 0x54, 0x4c, 0x31, 0xc8, 0x13, 0xbc, + 0xe1, 0xe6, 0xd0, 0x72, 0xc1 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test4_expected_hmac, + 0x86, 0xb3, 0x9a, 0x41, 0x3c, 0x2f, 0x92, 0xca, + 0x9b, 0x83, 0x34, 0xa2, 0x87, 0xff, 0xcb, 0xfc +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test5_confounder, + 0xf7, 0x64, 0xe9, 0xfa, 0x15, 0xc2, 0x76, 0x47, + 0x8b, 0x2c, 0x7d, 0x0c, 0x4e, 0x5f, 0x58, 0xe4 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test5_expected_result, + 0x41, 0xf5, 0x3f, 0xa5, 0xbf, 0xe7, 0x02, 0x6d, + 0x91, 0xfa, 0xf9, 0xbe, 0x95, 0x91, 0x95, 0xa0 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test5_expected_hmac, + 0x58, 0x70, 0x72, 0x73, 0xa9, 0x6a, 0x40, 0xf0, + 0xa0, 0x19, 0x60, 0x62, 0x1a, 0xc6, 0x12, 0x74, + 0x8b, 0x9b, 0xbf, 0xbe, 0x7e, 0xb4, 0xce, 0x3c +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test6_confounder, + 0xb8, 0x0d, 0x32, 0x51, 0xc1, 0xf6, 0x47, 0x14, + 0x94, 0x25, 0x6f, 0xfe, 0x71, 0x2d, 0x0b, 0x9a +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test6_expected_result, + 0x4e, 0xd7, 0xb3, 0x7c, 0x2b, 0xca, 0xc8, 0xf7, + 0x4f, 0x23, 0xc1, 0xcf, 0x07, 0xe6, 0x2b, 0xc7, + 0xb7, 0x5f, 0xb3, 0xf6, 0x37, 0xb9 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test6_expected_hmac, + 0xf5, 0x59, 0xc7, 0xf6, 0x64, 0xf6, 0x9e, 0xab, + 0x7b, 0x60, 0x92, 0x23, 0x75, 0x26, 0xea, 0x0d, + 0x1f, 0x61, 0xcb, 0x20, 0xd6, 0x9d, 0x10, 0xf2 +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test7_confounder, + 0x53, 0xbf, 0x8a, 0x0d, 0x10, 0x52, 0x65, 0xd4, + 0xe2, 0x76, 0x42, 0x86, 0x24, 0xce, 0x5e, 0x63 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test7_expected_result, + 0xbc, 0x47, 0xff, 0xec, 0x79, 0x98, 0xeb, 0x91, + 0xe8, 0x11, 0x5c, 0xf8, 0xd1, 0x9d, 0xac, 0x4b, + 0xbb, 0xe2, 0xe1, 0x63, 0xe8, 0x7d, 0xd3, 0x7f, + 0x49, 0xbe, 0xca, 0x92, 0x02, 0x77, 0x64, 0xf6 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test7_expected_hmac, + 0x8c, 0xf5, 0x1f, 0x14, 0xd7, 0x98, 0xc2, 0x27, + 0x3f, 0x35, 0xdf, 0x57, 0x4d, 0x1f, 0x93, 0x2e, + 0x40, 0xc4, 0xff, 0x25, 0x5b, 0x36, 0xa2, 0x66 +); + +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test8_confounder, + 0x76, 0x3e, 0x65, 0x36, 0x7e, 0x86, 0x4f, 0x02, + 0xf5, 0x51, 0x53, 0xc7, 0xe3, 0xb5, 0x8a, 0xf1 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test8_expected_result, + 0x40, 0x01, 0x3e, 0x2d, 0xf5, 0x8e, 0x87, 0x51, + 0x95, 0x7d, 0x28, 0x78, 0xbc, 0xd2, 0xd6, 0xfe, + 0x10, 0x1c, 0xcf, 0xd5, 0x56, 0xcb, 0x1e, 0xae, + 0x79, 0xdb, 0x3c, 0x3e, 0xe8, 0x64, 0x29, 0xf2, + 0xb2, 0xa6, 0x02, 0xac, 0x86 +); +DEFINE_HEX_XDR_NETOBJ(rfc8009_enc_test8_expected_hmac, + 0xfe, 0xf6, 0xec, 0xb6, 0x47, 0xd6, 0x29, 0x5f, + 0xae, 0x07, 0x7a, 0x1f, 0xeb, 0x51, 0x75, 0x08, + 0xd2, 0xc1, 0x6b, 0x41, 0x92, 0xe0, 0x1f, 0x62 +); + +static const struct gss_krb5_test_param rfc8009_encrypt_test_params[] = { + { + .desc = "Encrypt empty plaintext with aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .plaintext = &rfc8009_enc_empty_plaintext, + .confounder = &rfc8009_enc_test1_confounder, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .expected_result = &rfc8009_enc_test1_expected_result, + .expected_hmac = &rfc8009_enc_test1_expected_hmac, + }, + { + .desc = "Encrypt short plaintext with aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .plaintext = &rfc8009_enc_short_plaintext, + .confounder = &rfc8009_enc_test2_confounder, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .expected_result = &rfc8009_enc_test2_expected_result, + .expected_hmac = &rfc8009_enc_test2_expected_hmac, + }, + { + .desc = "Encrypt block plaintext with aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .plaintext = &rfc8009_enc_block_plaintext, + .confounder = &rfc8009_enc_test3_confounder, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .expected_result = &rfc8009_enc_test3_expected_result, + .expected_hmac = &rfc8009_enc_test3_expected_hmac, + }, + { + .desc = "Encrypt long plaintext with aes128-cts-hmac-sha256-128", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .plaintext = &rfc8009_enc_long_plaintext, + .confounder = &rfc8009_enc_test4_confounder, + .base_key = &aes128_cts_hmac_sha256_128_basekey, + .expected_result = &rfc8009_enc_test4_expected_result, + .expected_hmac = &rfc8009_enc_test4_expected_hmac, + }, + { + .desc = "Encrypt empty plaintext with aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .plaintext = &rfc8009_enc_empty_plaintext, + .confounder = &rfc8009_enc_test5_confounder, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .expected_result = &rfc8009_enc_test5_expected_result, + .expected_hmac = &rfc8009_enc_test5_expected_hmac, + }, + { + .desc = "Encrypt short plaintext with aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .plaintext = &rfc8009_enc_short_plaintext, + .confounder = &rfc8009_enc_test6_confounder, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .expected_result = &rfc8009_enc_test6_expected_result, + .expected_hmac = &rfc8009_enc_test6_expected_hmac, + }, + { + .desc = "Encrypt block plaintext with aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .plaintext = &rfc8009_enc_block_plaintext, + .confounder = &rfc8009_enc_test7_confounder, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .expected_result = &rfc8009_enc_test7_expected_result, + .expected_hmac = &rfc8009_enc_test7_expected_hmac, + }, + { + .desc = "Encrypt long plaintext with aes256-cts-hmac-sha384-192", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .plaintext = &rfc8009_enc_long_plaintext, + .confounder = &rfc8009_enc_test8_confounder, + .base_key = &aes256_cts_hmac_sha384_192_basekey, + .expected_result = &rfc8009_enc_test8_expected_result, + .expected_hmac = &rfc8009_enc_test8_expected_hmac, + }, +}; + +/* Creates the function rfc8009_encrypt_gen_params */ +KUNIT_ARRAY_PARAM(rfc8009_encrypt, rfc8009_encrypt_test_params, + gss_krb5_get_desc); + +static void rfc8009_encrypt_case(struct kunit *test) +{ + const struct gss_krb5_test_param *param = test->param_value; + struct crypto_sync_skcipher *cts_tfm, *cbc_tfm; + const struct gss_krb5_enctype *gk5e; + struct xdr_netobj Ke, Ki, checksum; + u8 usage_data[GSS_KRB5_K5CLENGTH]; + struct xdr_netobj usage = { + .data = usage_data, + .len = sizeof(usage_data), + }; + struct crypto_ahash *ahash_tfm; + struct xdr_buf buf; + void *text; + size_t len; + u32 err; + + /* Arrange */ + gk5e = gss_krb5_lookup_enctype(param->enctype); + KUNIT_ASSERT_NOT_NULL(test, gk5e); + + *(__be32 *)usage.data = cpu_to_be32(2); + + Ke.len = gk5e->Ke_length; + Ke.data = kunit_kzalloc(test, Ke.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, Ke.data); + usage.data[4] = KEY_USAGE_SEED_ENCRYPTION; + err = gk5e->derive_key(gk5e, param->base_key, &Ke, + &usage, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, err, 0); + + cbc_tfm = crypto_alloc_sync_skcipher(gk5e->aux_cipher, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cbc_tfm); + err = crypto_sync_skcipher_setkey(cbc_tfm, Ke.data, Ke.len); + KUNIT_ASSERT_EQ(test, err, 0); + + cts_tfm = crypto_alloc_sync_skcipher(gk5e->encrypt_name, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cts_tfm); + err = crypto_sync_skcipher_setkey(cts_tfm, Ke.data, Ke.len); + KUNIT_ASSERT_EQ(test, err, 0); + + len = param->confounder->len + param->plaintext->len; + text = kunit_kzalloc(test, len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, text); + memcpy(text, param->confounder->data, param->confounder->len); + memcpy(text + param->confounder->len, param->plaintext->data, + param->plaintext->len); + + memset(&buf, 0, sizeof(buf)); + buf.head[0].iov_base = text; + buf.head[0].iov_len = param->confounder->len + param->plaintext->len; + buf.len = buf.head[0].iov_len; + + checksum.len = gk5e->cksumlength; + checksum.data = kunit_kzalloc(test, checksum.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, checksum.data); + + Ki.len = gk5e->Ki_length; + Ki.data = kunit_kzalloc(test, Ki.len, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, Ki.data); + usage.data[4] = KEY_USAGE_SEED_INTEGRITY; + err = gk5e->derive_key(gk5e, param->base_key, &Ki, + &usage, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, err, 0); + + ahash_tfm = crypto_alloc_ahash(gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ahash_tfm); + err = crypto_ahash_setkey(ahash_tfm, Ki.data, Ki.len); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Act */ + err = krb5_cbc_cts_encrypt(cts_tfm, cbc_tfm, 0, &buf, NULL, NULL, 0); + KUNIT_ASSERT_EQ(test, err, 0); + err = krb5_etm_checksum(cts_tfm, ahash_tfm, &buf, 0, &checksum); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Assert */ + KUNIT_EXPECT_EQ_MSG(test, + param->expected_result->len, buf.len, + "ciphertext length mismatch"); + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->expected_result->data, + buf.head[0].iov_base, + param->expected_result->len), 0, + "ciphertext mismatch"); + KUNIT_EXPECT_EQ_MSG(test, memcmp(param->expected_hmac->data, + checksum.data, + checksum.len), 0, + "HMAC mismatch"); + + crypto_free_ahash(ahash_tfm); + crypto_free_sync_skcipher(cts_tfm); + crypto_free_sync_skcipher(cbc_tfm); +} + static struct kunit_case rfc8009_test_cases[] = { { .name = "RFC 8009 key derivation", @@ -1573,6 +1897,11 @@ static struct kunit_case rfc8009_test_cases[] = { .run_case = checksum_case, .generate_params = rfc8009_checksum_gen_params, }, + { + .name = "RFC 8009 encryption", + .run_case = rfc8009_encrypt_case, + .generate_params = rfc8009_encrypt_gen_params, + }, }; static struct kunit_suite rfc8009_suite = { From patchwork Fri Jan 13 15:25:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13100982 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E38DC54EBD for ; Fri, 13 Jan 2023 15:33:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230249AbjAMPc6 (ORCPT ); Fri, 13 Jan 2023 10:32:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229765AbjAMPcD (ORCPT ); Fri, 13 Jan 2023 10:32:03 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D67D945651 for ; Fri, 13 Jan 2023 07:25:50 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 9238BB8216D for ; Fri, 13 Jan 2023 15:25:49 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E989EC433EF; Fri, 13 Jan 2023 15:25:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673623548; bh=Vz7osluOoqw2PtIy3RIFBBdeK2uRRu1sbRSKlXj5Zj0=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=MjM1twkirVZlmpCZ3yoImFWN5P7zZDCG+ahJNXjnn7QVaNSLCWNzKOYXWQ5+NnKx6 8mnZ+cV9jh/Y9DWxQuzG1rWnylFLK287zK8hTKN/R1OxqdxV8CDbLxGhnlUL8fcLTl akTlryCTK4h2CstQjL3r/gsCFoULwkb3hGksmgTLGEa4vCSwM+hgqCCTeaQucaLUgA 7zC+qI149gP1qkGMtSKQ/+11eGQwWINfQtQKFBnyMo3u0MsL1F8S/N/zlKu7EZvvBw rz93wREoZEMFh/jcqQhUYNmNPqbQfTmB3QoHlmcxPFwLqBCtnObaLuYIM5m6+G50Wd MODbf8R0cCamw== Subject: [PATCH v1 41/41] SUNRPC: Add encryption self-tests From: Chuck Lever To: linux-nfs@vger.kernel.org Cc: dhowells@redhat.com, simo@redhat.com Date: Fri, 13 Jan 2023 10:25:47 -0500 Message-ID: <167362354712.8960.13059050669153981213.stgit@bazille.1015granger.net> In-Reply-To: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> References: <167362164696.8960.16701168753472560115.stgit@bazille.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever With the KUnit infrastructure recently added, we are free to define other unit tests particular to our implementation. As an example, I've added a self-test that encrypts then decrypts a string, and checks the result. Tested-by: Scott Mayhew Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 20 ++++- net/sunrpc/auth_gss/gss_krb5_internal.h | 3 + net/sunrpc/auth_gss/gss_krb5_test.c | 124 +++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 5 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index e37d341a761b..14c21c2e03dc 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -708,10 +708,21 @@ int krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, } EXPORT_SYMBOL_IF_KUNIT(krb5_cbc_cts_encrypt); -static int -krb5_cbc_cts_decrypt(struct crypto_sync_skcipher *cts_tfm, - struct crypto_sync_skcipher *cbc_tfm, - u32 offset, struct xdr_buf *buf) +/** + * krb5_cbc_cts_decrypt - decrypt in CBC mode with CTS + * @cts_tfm: CBC cipher with CTS + * @cbc_tfm: base CBC cipher + * @offset: starting byte offset for plaintext + * @buf: OUT: output buffer + * + * Return values: + * %0: decryption successful + * negative errno: decryption could not be completed + */ +VISIBLE_IF_KUNIT +int krb5_cbc_cts_decrypt(struct crypto_sync_skcipher *cts_tfm, + struct crypto_sync_skcipher *cbc_tfm, + u32 offset, struct xdr_buf *buf) { u32 blocksize, nblocks, cbcbytes; struct decryptor_desc desc; @@ -747,6 +758,7 @@ krb5_cbc_cts_decrypt(struct crypto_sync_skcipher *cts_tfm, /* Remaining plaintext is handled with CBC-CTS. */ return gss_krb5_cts_crypt(cts_tfm, buf, cbcbytes, desc.iv, NULL, 0); } +EXPORT_SYMBOL_IF_KUNIT(krb5_cbc_cts_decrypt); u32 gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h index bcc8992e274a..957aa4e38e9a 100644 --- a/net/sunrpc/auth_gss/gss_krb5_internal.h +++ b/net/sunrpc/auth_gss/gss_krb5_internal.h @@ -224,6 +224,9 @@ int krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, struct crypto_sync_skcipher *cbc_tfm, u32 offset, struct xdr_buf *buf, struct page **pages, u8 *iv, unsigned int ivsize); +int krb5_cbc_cts_decrypt(struct crypto_sync_skcipher *cts_tfm, + struct crypto_sync_skcipher *cbc_tfm, + u32 offset, struct xdr_buf *buf); u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher, struct crypto_ahash *tfm, const struct xdr_buf *body, int body_offset, struct xdr_netobj *cksumout); diff --git a/net/sunrpc/auth_gss/gss_krb5_test.c b/net/sunrpc/auth_gss/gss_krb5_test.c index fe3e4b81221a..c287ce15c419 100644 --- a/net/sunrpc/auth_gss/gss_krb5_test.c +++ b/net/sunrpc/auth_gss/gss_krb5_test.c @@ -1909,10 +1909,132 @@ static struct kunit_suite rfc8009_suite = { .test_cases = rfc8009_test_cases, }; +/* + * Encryption self-tests + */ + +DEFINE_STR_XDR_NETOBJ(encrypt_selftest_plaintext, + "This is the plaintext for the encryption self-test."); + +static const struct gss_krb5_test_param encrypt_selftest_params[] = { + { + .desc = "aes128-cts-hmac-sha1-96 encryption self-test", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &encrypt_selftest_plaintext, + }, + { + .desc = "aes256-cts-hmac-sha1-96 encryption self-test", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA1_96, + .Ke = &rfc3962_encryption_key, + .plaintext = &encrypt_selftest_plaintext, + }, + { + .desc = "camellia128-cts-cmac encryption self-test", + .enctype = ENCTYPE_CAMELLIA128_CTS_CMAC, + .Ke = &camellia128_cts_cmac_Ke, + .plaintext = &encrypt_selftest_plaintext, + }, + { + .desc = "camellia256-cts-cmac encryption self-test", + .enctype = ENCTYPE_CAMELLIA256_CTS_CMAC, + .Ke = &camellia256_cts_cmac_Ke, + .plaintext = &encrypt_selftest_plaintext, + }, + { + .desc = "aes128-cts-hmac-sha256-128 encryption self-test", + .enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128, + .Ke = &aes128_cts_hmac_sha256_128_Ke, + .plaintext = &encrypt_selftest_plaintext, + }, + { + .desc = "aes256-cts-hmac-sha384-192 encryption self-test", + .enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192, + .Ke = &aes256_cts_hmac_sha384_192_Ke, + .plaintext = &encrypt_selftest_plaintext, + }, +}; + +/* Creates the function encrypt_selftest_gen_params */ +KUNIT_ARRAY_PARAM(encrypt_selftest, encrypt_selftest_params, + gss_krb5_get_desc); + +/* + * Encrypt and decrypt plaintext, and ensure the input plaintext + * matches the output plaintext. A confounder is not added in this + * case. + */ +static void encrypt_selftest_case(struct kunit *test) +{ + const struct gss_krb5_test_param *param = test->param_value; + struct crypto_sync_skcipher *cts_tfm, *cbc_tfm; + const struct gss_krb5_enctype *gk5e; + struct xdr_buf buf; + void *text; + int err; + + /* Arrange */ + gk5e = gss_krb5_lookup_enctype(param->enctype); + KUNIT_ASSERT_NOT_NULL(test, gk5e); + + cbc_tfm = crypto_alloc_sync_skcipher(gk5e->aux_cipher, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cbc_tfm); + err = crypto_sync_skcipher_setkey(cbc_tfm, param->Ke->data, param->Ke->len); + KUNIT_ASSERT_EQ(test, err, 0); + + cts_tfm = crypto_alloc_sync_skcipher(gk5e->encrypt_name, 0, 0); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cts_tfm); + err = crypto_sync_skcipher_setkey(cts_tfm, param->Ke->data, param->Ke->len); + KUNIT_ASSERT_EQ(test, err, 0); + + text = kunit_kzalloc(test, roundup(param->plaintext->len, + crypto_sync_skcipher_blocksize(cbc_tfm)), + GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, text); + + memcpy(text, param->plaintext->data, param->plaintext->len); + memset(&buf, 0, sizeof(buf)); + buf.head[0].iov_base = text; + buf.head[0].iov_len = param->plaintext->len; + buf.len = buf.head[0].iov_len; + + /* Act */ + err = krb5_cbc_cts_encrypt(cts_tfm, cbc_tfm, 0, &buf, NULL, NULL, 0); + KUNIT_ASSERT_EQ(test, err, 0); + err = krb5_cbc_cts_decrypt(cts_tfm, cbc_tfm, 0, &buf); + KUNIT_ASSERT_EQ(test, err, 0); + + /* Assert */ + KUNIT_EXPECT_EQ_MSG(test, + param->plaintext->len, buf.len, + "length mismatch"); + KUNIT_EXPECT_EQ_MSG(test, + memcmp(param->plaintext->data, + buf.head[0].iov_base, buf.len), 0, + "plaintext mismatch"); + + crypto_free_sync_skcipher(cts_tfm); + crypto_free_sync_skcipher(cbc_tfm); +} + +static struct kunit_case encryption_test_cases[] = { + { + .name = "Encryption self-tests", + .run_case = encrypt_selftest_case, + .generate_params = encrypt_selftest_gen_params, + }, +}; + +static struct kunit_suite encryption_test_suite = { + .name = "Encryption test suite", + .test_cases = encryption_test_cases, +}; + kunit_test_suites(&rfc3961_suite, &rfc3962_suite, &rfc6803_suite, - &rfc8009_suite); + &rfc8009_suite, + &encryption_test_suite); MODULE_DESCRIPTION("Test RPCSEC GSS Kerberos 5 functions"); MODULE_LICENSE("GPL");