/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://opensource.org/licenses/CDDL-1.0.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2013 Saso Kiselkov. All rights reserved.
 */

#include <sys/modctl.h>
#include <sys/crypto/common.h>
#include <sys/crypto/spi.h>
#include <sys/sysmacros.h>
#define	SKEIN_MODULE_IMPL
#include <sys/skein.h>

/*
 * Like the sha2 module, we create the skein module with two modlinkages:
 * - modlmisc to allow direct calls to Skein_* API functions.
 * - modlcrypto to integrate well into the Kernel Crypto Framework (KCF).
 */
static struct modlmisc modlmisc = {
	&mod_cryptoops,
	"Skein Message-Digest Algorithm"
};

static struct modlcrypto modlcrypto = {
	&mod_cryptoops,
	"Skein Kernel SW Provider"
};

static struct modlinkage modlinkage = {
	MODREV_1, {&modlmisc, &modlcrypto, NULL}
};

static crypto_mech_info_t skein_mech_info_tab[] = {
	{CKM_SKEIN_256, SKEIN_256_MECH_INFO_TYPE,
	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
	{CKM_SKEIN_256_MAC, SKEIN_256_MAC_MECH_INFO_TYPE,
	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 1, INT_MAX,
	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
	{CKM_SKEIN_512, SKEIN_512_MECH_INFO_TYPE,
	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
	{CKM_SKEIN_512_MAC, SKEIN_512_MAC_MECH_INFO_TYPE,
	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 1, INT_MAX,
	    CRYPTO_KEYSIZE_UNIT_IN_BYTES},
	{CKM_SKEIN1024, SKEIN1024_MECH_INFO_TYPE,
	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
	{CKM_SKEIN1024_MAC, SKEIN1024_MAC_MECH_INFO_TYPE,
	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC, 1, INT_MAX,
	    CRYPTO_KEYSIZE_UNIT_IN_BYTES}
};

static void skein_provider_status(crypto_provider_handle_t, uint_t *);

static crypto_control_ops_t skein_control_ops = {
	skein_provider_status
};

static int skein_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
    crypto_req_handle_t);
static int skein_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
    crypto_req_handle_t);
static int skein_update(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
static int skein_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
static int skein_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
    crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
    crypto_req_handle_t);

static crypto_digest_ops_t skein_digest_ops = {
	.digest_init = skein_digest_init,
	.digest = skein_digest,
	.digest_update = skein_update,
	.digest_key = NULL,
	.digest_final = skein_final,
	.digest_atomic = skein_digest_atomic
};

static int skein_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
    crypto_spi_ctx_template_t, crypto_req_handle_t);
static int skein_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
    crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
    crypto_spi_ctx_template_t, crypto_req_handle_t);

static crypto_mac_ops_t skein_mac_ops = {
	.mac_init = skein_mac_init,
	.mac = NULL,
	.mac_update = skein_update, /* using regular digest update is OK here */
	.mac_final = skein_final,   /* using regular digest final is OK here */
	.mac_atomic = skein_mac_atomic,
	.mac_verify_atomic = NULL
};

static int skein_create_ctx_template(crypto_provider_handle_t,
    crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
    size_t *, crypto_req_handle_t);
static int skein_free_context(crypto_ctx_t *);

static crypto_ctx_ops_t skein_ctx_ops = {
	.create_ctx_template = skein_create_ctx_template,
	.free_context = skein_free_context
};

static crypto_ops_t skein_crypto_ops = {{{{{
	&skein_control_ops,
	&skein_digest_ops,
	NULL,
	&skein_mac_ops,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	&skein_ctx_ops,
}}}}};

static crypto_provider_info_t skein_prov_info = {{{{
	CRYPTO_SPI_VERSION_1,
	"Skein Software Provider",
	CRYPTO_SW_PROVIDER,
	NULL,
	&skein_crypto_ops,
	sizeof (skein_mech_info_tab) / sizeof (crypto_mech_info_t),
	skein_mech_info_tab
}}}};

static crypto_kcf_provider_handle_t skein_prov_handle = 0;

typedef struct skein_ctx {
	skein_mech_type_t		sc_mech_type;
	size_t				sc_digest_bitlen;
	/*LINTED(E_ANONYMOUS_UNION_DECL)*/
	union {
		Skein_256_Ctxt_t	sc_256;
		Skein_512_Ctxt_t	sc_512;
		Skein1024_Ctxt_t	sc_1024;
	};
} skein_ctx_t;
#define	SKEIN_CTX(_ctx_)	((skein_ctx_t *)((_ctx_)->cc_provider_private))
#define	SKEIN_CTX_LVALUE(_ctx_)	(_ctx_)->cc_provider_private
#define	SKEIN_OP(_skein_ctx, _op, ...)					\
	do {								\
		skein_ctx_t	*sc = (_skein_ctx);			\
		switch (sc->sc_mech_type) {				\
		case SKEIN_256_MECH_INFO_TYPE:				\
		case SKEIN_256_MAC_MECH_INFO_TYPE:			\
			(void) Skein_256_ ## _op(&sc->sc_256, __VA_ARGS__);\
			break;						\
		case SKEIN_512_MECH_INFO_TYPE:				\
		case SKEIN_512_MAC_MECH_INFO_TYPE:			\
			(void) Skein_512_ ## _op(&sc->sc_512, __VA_ARGS__);\
			break;						\
		case SKEIN1024_MECH_INFO_TYPE:				\
		case SKEIN1024_MAC_MECH_INFO_TYPE:			\
			(void) Skein1024_ ## _op(&sc->sc_1024, __VA_ARGS__);\
			break;						\
		}							\
		_NOTE(CONSTCOND)					\
	} while (0)

static int
skein_get_digest_bitlen(const crypto_mechanism_t *mechanism, size_t *result)
{
	if (mechanism->cm_param != NULL) {
		/*LINTED(E_BAD_PTR_CAST_ALIGN)*/
		skein_param_t	*param = (skein_param_t *)mechanism->cm_param;

		if (mechanism->cm_param_len != sizeof (*param) ||
		    param->sp_digest_bitlen == 0) {
			return (CRYPTO_MECHANISM_PARAM_INVALID);
		}
		*result = param->sp_digest_bitlen;
	} else {
		switch (mechanism->cm_type) {
		case SKEIN_256_MECH_INFO_TYPE:
			*result = 256;
			break;
		case SKEIN_512_MECH_INFO_TYPE:
			*result = 512;
			break;
		case SKEIN1024_MECH_INFO_TYPE:
			*result = 1024;
			break;
		default:
			return (CRYPTO_MECHANISM_INVALID);
		}
	}
	return (CRYPTO_SUCCESS);
}

int
skein_mod_init(void)
{
	int error;

	if ((error = mod_install(&modlinkage)) != 0)
		return (error);

	/*
	 * Try to register with KCF - failure shouldn't unload us, since we
	 * still may want to continue providing misc/skein functionality.
	 */
	(void) crypto_register_provider(&skein_prov_info, &skein_prov_handle);

	return (0);
}

int
skein_mod_fini(void)
{
	int ret;

	if (skein_prov_handle != 0) {
		if ((ret = crypto_unregister_provider(skein_prov_handle)) !=
		    CRYPTO_SUCCESS) {
			cmn_err(CE_WARN,
			    "skein _fini: crypto_unregister_provider() "
			    "failed (0x%x)", ret);
			return (EBUSY);
		}
		skein_prov_handle = 0;
	}

	return (mod_remove(&modlinkage));
}

/*
 * KCF software provider control entry points.
 */
/* ARGSUSED */
static void
skein_provider_status(crypto_provider_handle_t provider, uint_t *status)
{
	*status = CRYPTO_PROVIDER_READY;
}

/*
 * General Skein hashing helper functions.
 */

/*
 * Performs an Update on a context with uio input data.
 */
static int
skein_digest_update_uio(skein_ctx_t *ctx, const crypto_data_t *data)
{
	off_t		offset = data->cd_offset;
	size_t		length = data->cd_length;
	uint_t		vec_idx = 0;
	size_t		cur_len;
	const uio_t	*uio = data->cd_uio;

	/* we support only kernel buffer */
	if (uio->uio_segflg != UIO_SYSSPACE)
		return (CRYPTO_ARGUMENTS_BAD);

	/*
	 * Jump to the first iovec containing data to be
	 * digested.
	 */
	while (vec_idx < uio->uio_iovcnt &&
	    offset >= uio->uio_iov[vec_idx].iov_len) {
		offset -= uio->uio_iov[vec_idx].iov_len;
		vec_idx++;
	}
	if (vec_idx == uio->uio_iovcnt) {
		/*
		 * The caller specified an offset that is larger than the
		 * total size of the buffers it provided.
		 */
		return (CRYPTO_DATA_LEN_RANGE);
	}

	/*
	 * Now do the digesting on the iovecs.
	 */
	while (vec_idx < uio->uio_iovcnt && length > 0) {
		cur_len = MIN(uio->uio_iov[vec_idx].iov_len - offset, length);
		SKEIN_OP(ctx, Update, (uint8_t *)uio->uio_iov[vec_idx].iov_base
		    + offset, cur_len);
		length -= cur_len;
		vec_idx++;
		offset = 0;
	}

	if (vec_idx == uio->uio_iovcnt && length > 0) {
		/*
		 * The end of the specified iovec's was reached but
		 * the length requested could not be processed, i.e.
		 * The caller requested to digest more data than it provided.
		 */
		return (CRYPTO_DATA_LEN_RANGE);
	}

	return (CRYPTO_SUCCESS);
}

/*
 * Performs a Final on a context and writes to a uio digest output.
 */
static int
skein_digest_final_uio(skein_ctx_t *ctx, crypto_data_t *digest,
    crypto_req_handle_t req)
{
	off_t	offset = digest->cd_offset;
	uint_t	vec_idx = 0;
	uio_t	*uio = digest->cd_uio;

	/* we support only kernel buffer */
	if (uio->uio_segflg != UIO_SYSSPACE)
		return (CRYPTO_ARGUMENTS_BAD);

	/*
	 * Jump to the first iovec containing ptr to the digest to be returned.
	 */
	while (vec_idx < uio->uio_iovcnt &&
	    offset >= uio->uio_iov[vec_idx].iov_len) {
		offset -= uio->uio_iov[vec_idx].iov_len;
		vec_idx++;
	}
	if (vec_idx == uio->uio_iovcnt) {
		/*
		 * The caller specified an offset that is larger than the
		 * total size of the buffers it provided.
		 */
		return (CRYPTO_DATA_LEN_RANGE);
	}
	if (offset + CRYPTO_BITS2BYTES(ctx->sc_digest_bitlen) <=
	    uio->uio_iov[vec_idx].iov_len) {
		/* The computed digest will fit in the current iovec. */
		SKEIN_OP(ctx, Final,
		    (uchar_t *)uio->uio_iov[vec_idx].iov_base + offset);
	} else {
		uint8_t *digest_tmp;
		off_t scratch_offset = 0;
		size_t length = CRYPTO_BITS2BYTES(ctx->sc_digest_bitlen);
		size_t cur_len;

		digest_tmp = kmem_alloc(CRYPTO_BITS2BYTES(
		    ctx->sc_digest_bitlen), crypto_kmflag(req));
		if (digest_tmp == NULL)
			return (CRYPTO_HOST_MEMORY);
		SKEIN_OP(ctx, Final, digest_tmp);
		while (vec_idx < uio->uio_iovcnt && length > 0) {
			cur_len = MIN(uio->uio_iov[vec_idx].iov_len - offset,
			    length);
			bcopy(digest_tmp + scratch_offset,
			    uio->uio_iov[vec_idx].iov_base + offset, cur_len);

			length -= cur_len;
			vec_idx++;
			scratch_offset += cur_len;
			offset = 0;
		}
		kmem_free(digest_tmp, CRYPTO_BITS2BYTES(ctx->sc_digest_bitlen));

		if (vec_idx == uio->uio_iovcnt && length > 0) {
			/*
			 * The end of the specified iovec's was reached but
			 * the length requested could not be processed, i.e.
			 * The caller requested to digest more data than it
			 * provided.
			 */
			return (CRYPTO_DATA_LEN_RANGE);
		}
	}

	return (CRYPTO_SUCCESS);
}

/*
 * KCF software provider digest entry points.
 */

/*
 * Initializes a skein digest context to the configuration in `mechanism'.
 * The mechanism cm_type must be one of SKEIN_*_MECH_INFO_TYPE. The cm_param
 * field may contain a skein_param_t structure indicating the length of the
 * digest the algorithm should produce. Otherwise the default output lengths
 * are applied (32 bytes for Skein-256, 64 bytes for Skein-512 and 128 bytes
 * for Skein-1024).
 */
static int
skein_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
    crypto_req_handle_t req)
{
	int	error = CRYPTO_SUCCESS;

	if (!VALID_SKEIN_DIGEST_MECH(mechanism->cm_type))
		return (CRYPTO_MECHANISM_INVALID);

	SKEIN_CTX_LVALUE(ctx) = kmem_alloc(sizeof (*SKEIN_CTX(ctx)),
	    crypto_kmflag(req));
	if (SKEIN_CTX(ctx) == NULL)
		return (CRYPTO_HOST_MEMORY);

	SKEIN_CTX(ctx)->sc_mech_type = mechanism->cm_type;
	error = skein_get_digest_bitlen(mechanism,
	    &SKEIN_CTX(ctx)->sc_digest_bitlen);
	if (error != CRYPTO_SUCCESS)
		goto errout;
	SKEIN_OP(SKEIN_CTX(ctx), Init, SKEIN_CTX(ctx)->sc_digest_bitlen);

	return (CRYPTO_SUCCESS);
errout:
	bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	SKEIN_CTX_LVALUE(ctx) = NULL;
	return (error);
}

/*
 * Executes a skein_update and skein_digest on a pre-initialized crypto
 * context in a single step. See the documentation to these functions to
 * see what to pass here.
 */
static int
skein_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
    crypto_req_handle_t req)
{
	int error = CRYPTO_SUCCESS;

	ASSERT(SKEIN_CTX(ctx) != NULL);

	if (digest->cd_length <
	    CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen)) {
		digest->cd_length =
		    CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen);
		return (CRYPTO_BUFFER_TOO_SMALL);
	}

	error = skein_update(ctx, data, req);
	if (error != CRYPTO_SUCCESS) {
		bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
		kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
		SKEIN_CTX_LVALUE(ctx) = NULL;
		digest->cd_length = 0;
		return (error);
	}
	error = skein_final(ctx, digest, req);

	return (error);
}

/*
 * Performs a skein Update with the input message in `data' (successive calls
 * can push more data). This is used both for digest and MAC operation.
 * Supported input data formats are raw, uio and mblk.
 */
/*ARGSUSED*/
static int
skein_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
{
	int error = CRYPTO_SUCCESS;

	ASSERT(SKEIN_CTX(ctx) != NULL);

	switch (data->cd_format) {
	case CRYPTO_DATA_RAW:
		SKEIN_OP(SKEIN_CTX(ctx), Update,
		    (uint8_t *)data->cd_raw.iov_base + data->cd_offset,
		    data->cd_length);
		break;
	case CRYPTO_DATA_UIO:
		error = skein_digest_update_uio(SKEIN_CTX(ctx), data);
		break;
	default:
		error = CRYPTO_ARGUMENTS_BAD;
	}

	return (error);
}

/*
 * Performs a skein Final, writing the output to `digest'. This is used both
 * for digest and MAC operation.
 * Supported output digest formats are raw, uio and mblk.
 */
/*ARGSUSED*/
static int
skein_final(crypto_ctx_t *ctx, crypto_data_t *digest, crypto_req_handle_t req)
{
	int error = CRYPTO_SUCCESS;

	ASSERT(SKEIN_CTX(ctx) != NULL);

	if (digest->cd_length <
	    CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen)) {
		digest->cd_length =
		    CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen);
		return (CRYPTO_BUFFER_TOO_SMALL);
	}

	switch (digest->cd_format) {
	case CRYPTO_DATA_RAW:
		SKEIN_OP(SKEIN_CTX(ctx), Final,
		    (uint8_t *)digest->cd_raw.iov_base + digest->cd_offset);
		break;
	case CRYPTO_DATA_UIO:
		error = skein_digest_final_uio(SKEIN_CTX(ctx), digest, req);
		break;
	default:
		error = CRYPTO_ARGUMENTS_BAD;
	}

	if (error == CRYPTO_SUCCESS)
		digest->cd_length =
		    CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen);
	else
		digest->cd_length = 0;

	bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	kmem_free(SKEIN_CTX(ctx), sizeof (*(SKEIN_CTX(ctx))));
	SKEIN_CTX_LVALUE(ctx) = NULL;

	return (error);
}

/*
 * Performs a full skein digest computation in a single call, configuring the
 * algorithm according to `mechanism', reading the input to be digested from
 * `data' and writing the output to `digest'.
 * Supported input/output formats are raw, uio and mblk.
 */
/*ARGSUSED*/
static int
skein_digest_atomic(crypto_provider_handle_t provider,
    crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
    crypto_data_t *data, crypto_data_t *digest, crypto_req_handle_t req)
{
	int		error;
	skein_ctx_t	skein_ctx;
	crypto_ctx_t	ctx;
	SKEIN_CTX_LVALUE(&ctx) = &skein_ctx;

	/* Init */
	if (!VALID_SKEIN_DIGEST_MECH(mechanism->cm_type))
		return (CRYPTO_MECHANISM_INVALID);
	skein_ctx.sc_mech_type = mechanism->cm_type;
	error = skein_get_digest_bitlen(mechanism, &skein_ctx.sc_digest_bitlen);
	if (error != CRYPTO_SUCCESS)
		goto out;
	SKEIN_OP(&skein_ctx, Init, skein_ctx.sc_digest_bitlen);

	if ((error = skein_update(&ctx, data, digest)) != CRYPTO_SUCCESS)
		goto out;
	if ((error = skein_final(&ctx, data, digest)) != CRYPTO_SUCCESS)
		goto out;

out:
	if (error == CRYPTO_SUCCESS)
		digest->cd_length =
		    CRYPTO_BITS2BYTES(skein_ctx.sc_digest_bitlen);
	else
		digest->cd_length = 0;
	bzero(&skein_ctx, sizeof (skein_ctx));

	return (error);
}

/*
 * Helper function that builds a Skein MAC context from the provided
 * mechanism and key.
 */
static int
skein_mac_ctx_build(skein_ctx_t *ctx, crypto_mechanism_t *mechanism,
    crypto_key_t *key)
{
	int error;

	if (!VALID_SKEIN_MAC_MECH(mechanism->cm_type))
		return (CRYPTO_MECHANISM_INVALID);
	if (key->ck_format != CRYPTO_KEY_RAW)
		return (CRYPTO_ARGUMENTS_BAD);
	ctx->sc_mech_type = mechanism->cm_type;
	error = skein_get_digest_bitlen(mechanism, &ctx->sc_digest_bitlen);
	if (error != CRYPTO_SUCCESS)
		return (error);
	SKEIN_OP(ctx, InitExt, ctx->sc_digest_bitlen, 0, key->ck_data,
	    CRYPTO_BITS2BYTES(key->ck_length));

	return (CRYPTO_SUCCESS);
}

/*
 * KCF software provide mac entry points.
 */
/*
 * Initializes a skein MAC context. You may pass a ctx_template, in which
 * case the template will be reused to make initialization more efficient.
 * Otherwise a new context will be constructed. The mechanism cm_type must
 * be one of SKEIN_*_MAC_MECH_INFO_TYPE. Same as in skein_digest_init, you
 * may pass a skein_param_t in cm_param to configure the length of the
 * digest. The key must be in raw format.
 */
static int
skein_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
    crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
    crypto_req_handle_t req)
{
	int	error;

	SKEIN_CTX_LVALUE(ctx) = kmem_alloc(sizeof (*SKEIN_CTX(ctx)),
	    crypto_kmflag(req));
	if (SKEIN_CTX(ctx) == NULL)
		return (CRYPTO_HOST_MEMORY);

	if (ctx_template != NULL) {
		bcopy(ctx_template, SKEIN_CTX(ctx),
		    sizeof (*SKEIN_CTX(ctx)));
	} else {
		error = skein_mac_ctx_build(SKEIN_CTX(ctx), mechanism, key);
		if (error != CRYPTO_SUCCESS)
			goto errout;
	}

	return (CRYPTO_SUCCESS);
errout:
	bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
	return (error);
}

/*
 * The MAC update and final calls are reused from the regular digest code.
 */

/*ARGSUSED*/
/*
 * Same as skein_digest_atomic, performs an atomic Skein MAC operation in
 * one step. All the same properties apply to the arguments of this
 * function as to those of the partial operations above.
 */
static int
skein_mac_atomic(crypto_provider_handle_t provider,
    crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
    crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
    crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
{
	/* faux crypto context just for skein_digest_{update,final} */
	int		error;
	crypto_ctx_t	ctx;
	skein_ctx_t	skein_ctx;
	SKEIN_CTX_LVALUE(&ctx) = &skein_ctx;

	if (ctx_template != NULL) {
		bcopy(ctx_template, &skein_ctx, sizeof (skein_ctx));
	} else {
		error = skein_mac_ctx_build(&skein_ctx, mechanism, key);
		if (error != CRYPTO_SUCCESS)
			goto errout;
	}

	if ((error = skein_update(&ctx, data, req)) != CRYPTO_SUCCESS)
		goto errout;
	if ((error = skein_final(&ctx, mac, req)) != CRYPTO_SUCCESS)
		goto errout;

	return (CRYPTO_SUCCESS);
errout:
	bzero(&skein_ctx, sizeof (skein_ctx));
	return (error);
}

/*
 * KCF software provider context management entry points.
 */

/*
 * Constructs a context template for the Skein MAC algorithm. The same
 * properties apply to the arguments of this function as to those of
 * skein_mac_init.
 */
/*ARGSUSED*/
static int
skein_create_ctx_template(crypto_provider_handle_t provider,
    crypto_mechanism_t *mechanism, crypto_key_t *key,
    crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
    crypto_req_handle_t req)
{
	int		error;
	skein_ctx_t	*ctx_tmpl;

	ctx_tmpl = kmem_alloc(sizeof (*ctx_tmpl), crypto_kmflag(req));
	if (ctx_tmpl == NULL)
		return (CRYPTO_HOST_MEMORY);
	error = skein_mac_ctx_build(ctx_tmpl, mechanism, key);
	if (error != CRYPTO_SUCCESS)
		goto errout;
	*ctx_template = ctx_tmpl;
	*ctx_template_size = sizeof (*ctx_tmpl);

	return (CRYPTO_SUCCESS);
errout:
	bzero(ctx_tmpl, sizeof (*ctx_tmpl));
	kmem_free(ctx_tmpl, sizeof (*ctx_tmpl));
	return (error);
}

/*
 * Frees a skein context in a parent crypto context.
 */
static int
skein_free_context(crypto_ctx_t *ctx)
{
	if (SKEIN_CTX(ctx) != NULL) {
		bzero(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
		kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
		SKEIN_CTX_LVALUE(ctx) = NULL;
	}

	return (CRYPTO_SUCCESS);
}
