Subject: Re: [RFC PATCH 03/24] crypto: Add 'krb5enc' hash and cipher AEAD algorithm

From: Simon Horman <[email-masked]>
Date: Mon, 20 Jan 2025 13:57:54 +0000

On Fri, Jan 17, 2025 at 06:35:12PM +0000, David Howells wrote:
> Add an AEAD template that does hash-then-cipher (unlike authenc that does
> cipher-then-hash).  This is required for a number of Kerberos 5 encoding
> types.
> 
> [!] Note that the net/sunrpc/auth_gss/ implementation gets a pair of
> ciphers, one non-CTS and one CTS, using the former to do all the aligned
> blocks and the latter to do the last two blocks if they aren't also
> aligned.  It may be necessary to do this here too for performance reasons -
> but there are considerations both ways:
> 
>  (1) firstly, there is an optimised assembly version of cts(cbc(aes)) on
>      x86_64 that should be used instead of having two ciphers;
> 
>  (2) secondly, none of the hardware offload drivers seem to offer CTS
>      support (Intel QAT does not, for instance).
> 
> However, I don't know if it's possible to query the crypto API to find out
> whether there's an optimised CTS algorithm available.
> 
> Signed-off-by: David Howells <[email-masked]>

...

> diff --git a/crypto/krb5enc.c b/crypto/krb5enc.c

...

> +static int krb5enc_verify_hash(struct aead_request *req, void *hash)
> +{
> +	struct crypto_aead *krb5enc = crypto_aead_reqtfm(req);
> +	struct aead_instance *inst = aead_alg_instance(krb5enc);
> +	struct krb5enc_instance_ctx *ictx = aead_instance_ctx(inst);
> +	struct krb5enc_request_ctx *areq_ctx = aead_request_ctx(req);
> +	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);
> +	unsigned int authsize = crypto_aead_authsize(krb5enc);
> +	u8 *ihash = ahreq->result + authsize;
> +
> +	scatterwalk_map_and_copy(ihash, req->src, ahreq->nbytes, authsize, 0);
> +
> +	if (crypto_memneq(ihash, ahreq->result, authsize))
> +		return -EBADMSG;
> +	return 0;
> +}
> +
> +static void krb5enc_decrypt_hash_done(void *data, int err)
> +{
> +	struct aead_request *req = data;
> +
> +	if (err)
> +		return krb5enc_request_complete(req, err);
> +
> +	err = krb5enc_verify_hash(req, 0);

Hi David,

Sparse complains that the second argument to krb5enc_verify_hash should be
a pointer rather than an integer. So perhaps this would be slightly better
expressed as (completely untested!):

	err = krb5enc_verify_hash(req, NULL);

> +	krb5enc_request_complete(req, err);

...
> +}