// SPDX-License-Identifier: BSD-3-Clause
/* rfc3961 Kerberos 5 simplified crypto profile.
 *
 * Parts borrowed from net/sunrpc/auth_gss/.
 */
/*
 * COPYRIGHT (c) 2008
 * The Regents of the University of Michigan
 * ALL RIGHTS RESERVED
 *
 * Permission is granted to use, copy, create derivative works
 * and redistribute this software and such derivative works
 * for any purpose, so long as the name of The University of
 * Michigan is not used in any advertising or publicity
 * pertaining to the use of distribution of this software
 * without specific, written prior authorization.  If the
 * above copyright notice or any other identification of the
 * University of Michigan is included in any copy of any
 * portion of this software, then the disclaimer below must
 * also be included.
 *
 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGES.
 */

/*
 * Copyright (C) 1998 by the FundsXpress, INC.
 *
 * All rights reserved.
 *
 * Export of this software from the United States of America may require
 * a specific license from the United States Government.  It is the
 * responsibility of any person or organization contemplating export to
 * obtain such a license before exporting.
 *
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
 * distribute this software and its documentation for any purpose and
 * without fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation, and that
 * the name of FundsXpress. not be used in advertising or publicity pertaining
 * to distribution of the software without specific, written prior
 * permission.  FundsXpress makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is" without express
 * or implied warranty.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/*
 * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/random.h>
#include <linux/scatterlist.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/lcm.h>
#include <linux/rtnetlink.h>
#include <crypto/authenc.h>
#include <crypto/skcipher.h>
#include <crypto/hash.h>
#include "internal.h"

/* Maximum blocksize for the supported crypto algorithms */
#define KRB5_MAX_BLOCKSIZE  (16)

int crypto_shash_update_sg(struct shash_desc *desc, struct scatterlist *sg,
			   size_t offset, size_t len)
{
	struct sg_mapping_iter miter;
	size_t i, n;
	int ret = 0;

	sg_miter_start(&miter, sg, sg_nents(sg),
		       SG_MITER_FROM_SG | SG_MITER_LOCAL);
	for (i = 0; i < len; i += n) {
		sg_miter_next(&miter);
		n = min(miter.length, len - i);
		ret = crypto_shash_update(desc, miter.addr, n);
		if (ret < 0)
			break;
	}
	sg_miter_stop(&miter);
	return ret;
}

static int rfc3961_do_encrypt(struct crypto_sync_skcipher *tfm, void *iv,
			      const struct krb5_buffer *in, struct krb5_buffer *out)
{
	struct scatterlist sg[1];
	u8 local_iv[KRB5_MAX_BLOCKSIZE] __aligned(KRB5_MAX_BLOCKSIZE) = {0};
	SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
	int ret;

	if (WARN_ON(in->len != out->len))
		return -EINVAL;
	if (out->len % crypto_sync_skcipher_blocksize(tfm) != 0)
		return -EINVAL;

	if (crypto_sync_skcipher_ivsize(tfm) > KRB5_MAX_BLOCKSIZE)
		return -EINVAL;

	if (iv)
		memcpy(local_iv, iv, crypto_sync_skcipher_ivsize(tfm));

	memcpy(out->data, in->data, out->len);
	sg_init_one(sg, out->data, out->len);

	skcipher_request_set_sync_tfm(req, tfm);
	skcipher_request_set_callback(req, 0, NULL, NULL);
	skcipher_request_set_crypt(req, sg, sg, out->len, local_iv);

	ret = crypto_skcipher_encrypt(req);
	skcipher_request_zero(req);
	return ret;
}

/*
 * Calculate an unkeyed basic hash.
 */
static int rfc3961_calc_H(const struct krb5_enctype *krb5,
			  const struct krb5_buffer *data,
			  struct krb5_buffer *digest,
			  gfp_t gfp)
{
	struct crypto_shash *tfm;
	struct shash_desc *desc;
	size_t desc_size;
	int ret = -ENOMEM;

	tfm = crypto_alloc_shash(krb5->hash_name, 0, 0);
	if (IS_ERR(tfm))
		return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);

	desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);

	desc = kzalloc(desc_size, gfp);
	if (!desc)
		goto error_tfm;

	digest->len = crypto_shash_digestsize(tfm);
	digest->data = kzalloc(digest->len, gfp);
	if (!digest->data)
		goto error_desc;

	desc->tfm = tfm;
	ret = crypto_shash_init(desc);
	if (ret < 0)
		goto error_digest;

	ret = crypto_shash_finup(desc, data->data, data->len, digest->data);
	if (ret < 0)
		goto error_digest;

	goto error_desc;

error_digest:
	kfree_sensitive(digest->data);
error_desc:
	kfree_sensitive(desc);
error_tfm:
	crypto_free_shash(tfm);
	return ret;
}

/*
 * This is the n-fold function as described in rfc3961, sec 5.1
 * Taken from MIT Kerberos and modified.
 */
static void rfc3961_nfold(const struct krb5_buffer *source, struct krb5_buffer *result)
{
	const u8 *in = source->data;
	u8 *out = result->data;
	unsigned long ulcm;
	unsigned int inbits, outbits;
	int byte, i, msbit;

	/* the code below is more readable if I make these bytes instead of bits */
	inbits = source->len;
	outbits = result->len;

	/* first compute lcm(n,k) */
	ulcm = lcm(inbits, outbits);

	/* now do the real work */
	memset(out, 0, outbits);
	byte = 0;

	/* this will end up cycling through k lcm(k,n)/k times, which
	 * is correct.
	 */
	for (i = ulcm-1; i >= 0; i--) {
		/* compute the msbit in k which gets added into this byte */
		msbit = (
			/* first, start with the msbit in the first,
			 * unrotated byte
			 */
			((inbits << 3) - 1) +
			/* then, for each byte, shift to the right
			 * for each repetition
			 */
			(((inbits << 3) + 13) * (i/inbits)) +
			/* last, pick out the correct byte within
			 * that shifted repetition
			 */
			((inbits - (i % inbits)) << 3)
			 ) % (inbits << 3);

		/* pull out the byte value itself */
		byte += (((in[((inbits - 1) - (msbit >> 3)) % inbits] << 8) |
			  (in[((inbits)     - (msbit >> 3)) % inbits]))
			 >> ((msbit & 7) + 1)) & 0xff;

		/* do the addition */
		byte += out[i % outbits];
		out[i % outbits] = byte & 0xff;

		/* keep around the carry bit, if any */
		byte >>= 8;
	}

	/* if there's a carry bit left over, add it back in */
	if (byte) {
		for (i = outbits - 1; i >= 0; i--) {
			/* do the addition */
			byte += out[i];
			out[i] = byte & 0xff;

			/* keep around the carry bit, if any */
			byte >>= 8;
		}
	}
}

/*
 * Calculate a derived key, DK(Base Key, Well-Known Constant)
 *
 * DK(Key, Constant) = random-to-key(DR(Key, Constant))
 * DR(Key, Constant) = k-truncate(E(Key, Constant, initial-cipher-state))
 * K1 = E(Key, n-fold(Constant), initial-cipher-state)
 * K2 = E(Key, K1, initial-cipher-state)
 * K3 = E(Key, K2, initial-cipher-state)
 * K4 = ...
 * DR(Key, Constant) = k-truncate(K1 | K2 | K3 | K4 ...)
 * [rfc3961 sec 5.1]
 */
static int rfc3961_calc_DK(const struct krb5_enctype *krb5,
			   const struct krb5_buffer *inkey,
			   const struct krb5_buffer *in_constant,
			   struct krb5_buffer *result,
			   gfp_t gfp)
{
	unsigned int blocksize, keybytes, keylength, n;
	struct krb5_buffer inblock, outblock, rawkey;
	struct crypto_sync_skcipher *cipher;
	int ret = -EINVAL;

	blocksize = krb5->block_len;
	keybytes = krb5->key_bytes;
	keylength = krb5->key_len;

	if (inkey->len != keylength || result->len != keylength)
		return -EINVAL;
	if (!krb5->random_to_key && result->len != keybytes)
		return -EINVAL;

	cipher = crypto_alloc_sync_skcipher(krb5->derivation_enc, 0, 0);
	if (IS_ERR(cipher)) {
		ret = (PTR_ERR(cipher) == -ENOENT) ? -ENOPKG : PTR_ERR(cipher);
		goto err_return;
	}
	ret = crypto_sync_skcipher_setkey(cipher, inkey->data, inkey->len);
	if (ret < 0)
		goto err_free_cipher;

	ret = -ENOMEM;
	inblock.data = kzalloc(blocksize * 2 + keybytes, gfp);
	if (!inblock.data)
		goto err_free_cipher;

	inblock.len	= blocksize;
	outblock.data	= inblock.data + blocksize;
	outblock.len	= blocksize;
	rawkey.data	= outblock.data + blocksize;
	rawkey.len	= keybytes;

	/* initialize the input block */

	if (in_constant->len == inblock.len)
		memcpy(inblock.data, in_constant->data, inblock.len);
	else
		rfc3961_nfold(in_constant, &inblock);

	/* loop encrypting the blocks until enough key bytes are generated */
	n = 0;
	while (n < rawkey.len) {
		rfc3961_do_encrypt(cipher, NULL, &inblock, &outblock);

		if (keybytes - n <= outblock.len) {
			memcpy(rawkey.data + n, outblock.data, keybytes - n);
			break;
		}

		memcpy(rawkey.data + n, outblock.data, outblock.len);
		memcpy(inblock.data, outblock.data, outblock.len);
		n += outblock.len;
	}

	/* postprocess the key */
	if (!krb5->random_to_key) {
		/* Identity random-to-key function. */
		memcpy(result->data, rawkey.data, rawkey.len);
		ret = 0;
	} else {
		ret = krb5->random_to_key(krb5, &rawkey, result);
	}

	kfree_sensitive(inblock.data);
err_free_cipher:
	crypto_free_sync_skcipher(cipher);
err_return:
	return ret;
}

/*
 * Calculate single encryption, E()
 *
 *	E(Key, octets)
 */
static int rfc3961_calc_E(const struct krb5_enctype *krb5,
			  const struct krb5_buffer *key,
			  const struct krb5_buffer *in_data,
			  struct krb5_buffer *result,
			  gfp_t gfp)
{
	struct crypto_sync_skcipher *cipher;
	int ret;

	cipher = crypto_alloc_sync_skcipher(krb5->derivation_enc, 0, 0);
	if (IS_ERR(cipher)) {
		ret = (PTR_ERR(cipher) == -ENOENT) ? -ENOPKG : PTR_ERR(cipher);
		goto err;
	}

	ret = crypto_sync_skcipher_setkey(cipher, key->data, key->len);
	if (ret < 0)
		goto err_free;

	ret = rfc3961_do_encrypt(cipher, NULL, in_data, result);

err_free:
	crypto_free_sync_skcipher(cipher);
err:
	return ret;
}

/*
 * Calculate the pseudo-random function, PRF().
 *
 *      tmp1 = H(octet-string)
 *      tmp2 = truncate tmp1 to multiple of m
 *      PRF = E(DK(protocol-key, prfconstant), tmp2, initial-cipher-state)
 *
 *      The "prfconstant" used in the PRF operation is the three-octet string
 *      "prf".
 *      [rfc3961 sec 5.3]
 */
static int rfc3961_calc_PRF(const struct krb5_enctype *krb5,
			    const struct krb5_buffer *protocol_key,
			    const struct krb5_buffer *octet_string,
			    struct krb5_buffer *result,
			    gfp_t gfp)
{
	static const struct krb5_buffer prfconstant = { 3, "prf" };
	struct krb5_buffer derived_key;
	struct krb5_buffer tmp1, tmp2;
	unsigned int m = krb5->block_len;
	void *buffer;
	int ret;

	if (result->len != krb5->prf_len)
		return -EINVAL;

	tmp1.len = krb5->hash_len;
	derived_key.len = krb5->key_bytes;
	buffer = kzalloc(round16(tmp1.len) + round16(derived_key.len), gfp);
	if (!buffer)
		return -ENOMEM;

	tmp1.data = buffer;
	derived_key.data = buffer + round16(tmp1.len);

	ret = rfc3961_calc_H(krb5, octet_string, &tmp1, gfp);
	if (ret < 0)
		goto err;

	tmp2.len = tmp1.len & ~(m - 1);
	tmp2.data = tmp1.data;

	ret = rfc3961_calc_DK(krb5, protocol_key, &prfconstant, &derived_key, gfp);
	if (ret < 0)
		goto err;

	ret = rfc3961_calc_E(krb5, &derived_key, &tmp2, result, gfp);

err:
	kfree_sensitive(buffer);
	return ret;
}

/*
 * Derive the Ke and Ki keys and package them into a key parameter that can be
 * given to the setkey of a authenc AEAD crypto object.
 */
int authenc_derive_encrypt_keys(const struct krb5_enctype *krb5,
				const struct krb5_buffer *TK,
				unsigned int usage,
				struct krb5_buffer *setkey,
				gfp_t gfp)
{
	struct crypto_authenc_key_param *param;
	struct krb5_buffer Ke, Ki;
	struct rtattr *rta;
	int ret;

	Ke.len  = krb5->Ke_len;
	Ki.len  = krb5->Ki_len;
	setkey->len = RTA_LENGTH(sizeof(*param)) + Ke.len + Ki.len;
	setkey->data = kzalloc(setkey->len, GFP_KERNEL);
	if (!setkey->data)
		return -ENOMEM;

	rta = setkey->data;
	rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
	rta->rta_len = RTA_LENGTH(sizeof(*param));
	param = RTA_DATA(rta);
	param->enckeylen = htonl(Ke.len);

	Ki.data = (void *)(param + 1);
	Ke.data = Ki.data + Ki.len;

	ret = krb5_derive_Ke(krb5, TK, usage, &Ke, gfp);
	if (ret < 0) {
		pr_err("get_Ke failed %d\n", ret);
		return ret;
	}
	ret = krb5_derive_Ki(krb5, TK, usage, &Ki, gfp);
	if (ret < 0)
		pr_err("get_Ki failed %d\n", ret);
	return ret;
}

/*
 * Package predefined Ke and Ki keys and into a key parameter that can be given
 * to the setkey of an authenc AEAD crypto object.
 */
int authenc_load_encrypt_keys(const struct krb5_enctype *krb5,
			      const struct krb5_buffer *Ke,
			      const struct krb5_buffer *Ki,
			      struct krb5_buffer *setkey,
			      gfp_t gfp)
{
	struct crypto_authenc_key_param *param;
	struct rtattr *rta;

	setkey->len = RTA_LENGTH(sizeof(*param)) + Ke->len + Ki->len;
	setkey->data = kzalloc(setkey->len, GFP_KERNEL);
	if (!setkey->data)
		return -ENOMEM;

	rta = setkey->data;
	rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM;
	rta->rta_len = RTA_LENGTH(sizeof(*param));
	param = RTA_DATA(rta);
	param->enckeylen = htonl(Ke->len);
	memcpy((void *)(param + 1), Ki->data, Ki->len);
	memcpy((void *)(param + 1) + Ki->len, Ke->data, Ke->len);
	return 0;
}

/*
 * Derive the Kc key for checksum-only mode and package it into a key parameter
 * that can be given to the setkey of a hash crypto object.
 */
int rfc3961_derive_checksum_key(const struct krb5_enctype *krb5,
				const struct krb5_buffer *TK,
				unsigned int usage,
				struct krb5_buffer *setkey,
				gfp_t gfp)
{
	int ret;

	setkey->len = krb5->Kc_len;
	setkey->data = kzalloc(setkey->len, GFP_KERNEL);
	if (!setkey->data)
		return -ENOMEM;

	ret = krb5_derive_Kc(krb5, TK, usage, setkey, gfp);
	if (ret < 0)
		pr_err("get_Kc failed %d\n", ret);
	return ret;
}

/*
 * Package a predefined Kc key for checksum-only mode into a key parameter that
 * can be given to the setkey of a hash crypto object.
 */
int rfc3961_load_checksum_key(const struct krb5_enctype *krb5,
			      const struct krb5_buffer *Kc,
			      struct krb5_buffer *setkey,
			      gfp_t gfp)
{
	setkey->len = krb5->Kc_len;
	setkey->data = kmemdup(Kc->data, Kc->len, GFP_KERNEL);
	if (!setkey->data)
		return -ENOMEM;
	return 0;
}

/*
 * Apply encryption and checksumming functions to part of a scatterlist.
 */
ssize_t krb5_aead_encrypt(const struct krb5_enctype *krb5,
			  struct crypto_aead *aead,
			  struct scatterlist *sg, unsigned int nr_sg, size_t sg_len,
			  size_t data_offset, size_t data_len,
			  bool preconfounded)
{
	struct aead_request *req;
	ssize_t ret, done;
	size_t bsize, base_len, secure_offset, secure_len, pad_len, cksum_offset;
	void *buffer;
	u8 *iv;

	if (WARN_ON(data_offset != krb5->conf_len))
		return -EINVAL; /* Data is in wrong place */

	secure_offset	= 0;
	base_len	= krb5->conf_len + data_len;
	pad_len		= 0;
	secure_len	= base_len + pad_len;
	cksum_offset	= secure_len;
	if (WARN_ON(cksum_offset + krb5->cksum_len > sg_len))
		return -EFAULT;

	bsize = krb5_aead_size(aead) +
		krb5_aead_ivsize(aead);
	buffer = kzalloc(bsize, GFP_NOFS);
	if (!buffer)
		return -ENOMEM;

	/* Insert the confounder into the buffer */
	ret = -EFAULT;
	if (!preconfounded) {
		get_random_bytes(buffer, krb5->conf_len);
		done = sg_pcopy_from_buffer(sg, nr_sg, buffer, krb5->conf_len,
					    secure_offset);
		if (done != krb5->conf_len)
			goto error;
	}

	/* We may need to pad out to the crypto blocksize. */
	if (pad_len) {
		done = sg_zero_buffer(sg, nr_sg, pad_len, data_offset + data_len);
		if (done != pad_len)
			goto error;
	}

	/* Hash and encrypt the message. */
	req = buffer;
	iv = buffer + krb5_aead_size(aead);

	aead_request_set_tfm(req, aead);
	aead_request_set_callback(req, 0, NULL, NULL);
	aead_request_set_crypt(req, sg, sg, secure_len, iv);
	ret = crypto_aead_encrypt(req);
	if (ret < 0)
		goto error;

	ret = secure_len + krb5->cksum_len;

error:
	kfree_sensitive(buffer);
	return ret;
}

/*
 * Apply decryption and checksumming functions to a message.  The offset and
 * length are updated to reflect the actual content of the encrypted region.
 */
int krb5_aead_decrypt(const struct krb5_enctype *krb5,
		      struct crypto_aead *aead,
		      struct scatterlist *sg, unsigned int nr_sg,
		      size_t *_offset, size_t *_len)
{
	struct aead_request *req;
	size_t bsize;
	void *buffer;
	int ret;
	u8 *iv;

	if (WARN_ON(*_offset != 0))
		return -EINVAL; /* Can't set offset on aead */

	if (*_len < krb5->conf_len + krb5->cksum_len)
		return -EPROTO;

	bsize = krb5_aead_size(aead) +
		krb5_aead_ivsize(aead);
	buffer = kzalloc(bsize, GFP_NOFS);
	if (!buffer)
		return -ENOMEM;

	/* Decrypt the message and verify its checksum. */
	req = buffer;
	iv = buffer + krb5_aead_size(aead);

	aead_request_set_tfm(req, aead);
	aead_request_set_callback(req, 0, NULL, NULL);
	aead_request_set_crypt(req, sg, sg, *_len, iv);
	ret = crypto_aead_decrypt(req);
	if (ret < 0)
		goto error;

	/* Adjust the boundaries of the data. */
	*_offset += krb5->conf_len;
	*_len -= krb5->conf_len + krb5->cksum_len;
	ret = 0;

error:
	kfree_sensitive(buffer);
	return ret;
}

/*
 * Generate a checksum over some metadata and part of an skbuff and insert the
 * MIC into the skbuff immediately prior to the data.
 */
ssize_t rfc3961_get_mic(const struct krb5_enctype *krb5,
			struct crypto_shash *shash,
			const struct krb5_buffer *metadata,
			struct scatterlist *sg, unsigned int nr_sg, size_t sg_len,
			size_t data_offset, size_t data_len)
{
	struct shash_desc *desc;
	ssize_t ret, done;
	size_t bsize;
	void *buffer, *digest;

	if (WARN_ON(data_offset != krb5->cksum_len))
		return -EMSGSIZE;

	bsize = krb5_shash_size(shash) +
		krb5_digest_size(shash);
	buffer = kzalloc(bsize, GFP_NOFS);
	if (!buffer)
		return -ENOMEM;

	/* Calculate the MIC with key Kc and store it into the skb */
	desc = buffer;
	desc->tfm = shash;
	ret = crypto_shash_init(desc);
	if (ret < 0)
		goto error;

	if (metadata) {
		ret = crypto_shash_update(desc, metadata->data, metadata->len);
		if (ret < 0)
			goto error;
	}

	ret = crypto_shash_update_sg(desc, sg, data_offset, data_len);
	if (ret < 0)
		goto error;

	digest = buffer + krb5_shash_size(shash);
	ret = crypto_shash_final(desc, digest);
	if (ret < 0)
		goto error;

	ret = -EFAULT;
	done = sg_pcopy_from_buffer(sg, nr_sg, digest, krb5->cksum_len,
				    data_offset - krb5->cksum_len);
	if (done != krb5->cksum_len)
		goto error;

	ret = krb5->cksum_len + data_len;

error:
	kfree_sensitive(buffer);
	return ret;
}

/*
 * Check the MIC on a region of an skbuff.  The offset and length are updated
 * to reflect the actual content of the secure region.
 */
int rfc3961_verify_mic(const struct krb5_enctype *krb5,
		       struct crypto_shash *shash,
		       const struct krb5_buffer *metadata,
		       struct scatterlist *sg, unsigned int nr_sg,
		       size_t *_offset, size_t *_len)
{
	struct shash_desc *desc;
	ssize_t done;
	size_t bsize, data_offset, data_len, offset = *_offset, len = *_len;
	void *buffer = NULL;
	int ret;
	u8 *cksum, *cksum2;

	if (len < krb5->cksum_len)
		return -EPROTO;
	data_offset = offset + krb5->cksum_len;
	data_len = len - krb5->cksum_len;

	bsize = krb5_shash_size(shash) +
		krb5_digest_size(shash) * 2;
	buffer = kzalloc(bsize, GFP_NOFS);
	if (!buffer)
		return -ENOMEM;

	cksum = buffer +
		krb5_shash_size(shash);
	cksum2 = buffer +
		krb5_shash_size(shash) +
		krb5_digest_size(shash);

	/* Calculate the MIC */
	desc = buffer;
	desc->tfm = shash;
	ret = crypto_shash_init(desc);
	if (ret < 0)
		goto error;

	if (metadata) {
		ret = crypto_shash_update(desc, metadata->data, metadata->len);
		if (ret < 0)
			goto error;
	}

	crypto_shash_update_sg(desc, sg, data_offset, data_len);
	crypto_shash_final(desc, cksum);

	ret = -EFAULT;
	done = sg_pcopy_to_buffer(sg, nr_sg, cksum2, krb5->cksum_len, offset);
	if (done != krb5->cksum_len)
		goto error;

	if (memcmp(cksum, cksum2, krb5->cksum_len) != 0) {
		ret = -EBADMSG;
		goto error;
	}

	*_offset += krb5->cksum_len;
	*_len -= krb5->cksum_len;
	ret = 0;

error:
	kfree_sensitive(buffer);
	return ret;
}

const struct krb5_crypto_profile rfc3961_simplified_profile = {
	.calc_PRF		= rfc3961_calc_PRF,
	.calc_Kc		= rfc3961_calc_DK,
	.calc_Ke		= rfc3961_calc_DK,
	.calc_Ki		= rfc3961_calc_DK,
	.derive_encrypt_keys	= authenc_derive_encrypt_keys,
	.load_encrypt_keys	= authenc_load_encrypt_keys,
	.derive_checksum_key	= rfc3961_derive_checksum_key,
	.load_checksum_key	= rfc3961_load_checksum_key,
	.encrypt		= krb5_aead_encrypt,
	.decrypt		= krb5_aead_decrypt,
	.get_mic		= rfc3961_get_mic,
	.verify_mic		= rfc3961_verify_mic,
};
