Re: [PATCH 07/29] crypto: talitos/hash - Move into separate file

From: Paul Louvel

Date: Thu Jun 04 2026 - 08:37:22 EST


On Mon Jun 1, 2026 at 1:47 PM CEST, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 28/05/2026 à 11:08, Paul Louvel a écrit :
>> Move the ahash algorithm implementations from talitos.c into a dedicated
>> talitos-hash.c file.
>>
>> Signed-off-by: Paul Louvel <paul.louvel@xxxxxxxxxxx>
>
> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@xxxxxxxxxx>
>
> While at it, (maybe another patch) the problem with size 0 hash on SEC1
> is not a driver bug but a hardware bug, it is therefore probably not
> worth a pr_err() because there is nothing the user can do about it and
> it is transparent as there is a workaround in the driver.

I was considering doing it differently too.
Instead of having a special case inside common_nonsnoop_hash(), handle it at the
beginning in ahash_process_req() or ahash_update() : if nbytes == 0 &&
first_request && last_request, create a scatterlist with a single entry. This
entry would be the static array with the padded bit.
It seems to me that it belongs more to the request preparation than to the
common_nonsnoop_hash() function, which is more about mapping the buffers and
preparing the descriptor.

Anyway, I agree with the call to pr_err_once().

>> ---
>> drivers/crypto/talitos/Makefile | 2 +-
>> drivers/crypto/talitos/talitos-hash.c | 832 ++++++++++++++++++++++++++++++++++
>> drivers/crypto/talitos/talitos.c | 807 +--------------------------------
>> drivers/crypto/talitos/talitos.h | 4 +
>> 4 files changed, 847 insertions(+), 798 deletions(-)
>>
>> diff --git a/drivers/crypto/talitos/Makefile b/drivers/crypto/talitos/Makefile
>> index 901ec681f010..40d37f9364ef 100644
>> --- a/drivers/crypto/talitos/Makefile
>> +++ b/drivers/crypto/talitos/Makefile
>> @@ -1,3 +1,3 @@
>> obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
>>
>> -talitos-y := talitos.o talitos-rng.o
>> +talitos-y := talitos.o talitos-rng.o talitos-hash.o
>> diff --git a/drivers/crypto/talitos/talitos-hash.c b/drivers/crypto/talitos/talitos-hash.c
>> new file mode 100644
>> index 000000000000..5792e7093392
>> --- /dev/null
>> +++ b/drivers/crypto/talitos/talitos-hash.c
>> @@ -0,0 +1,832 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +
>> +/*
>> + * Freescale SEC (talitos) hash implementation
>> + *
>> + * Copyright (c) 2006-2011 Freescale Semiconductor, Inc.
>> + */
>> +
>> +#include <linux/scatterlist.h>
>> +
>> +#include <crypto/hash.h>
>> +#include <crypto/internal/hash.h>
>> +#include <crypto/md5.h>
>> +#include <crypto/scatterwalk.h>
>> +#include <crypto/sha1.h>
>> +
>> +#include "talitos.h"
>> +
>> +#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
>> +#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
>> +
>> +struct talitos_ahash_req_ctx {
>> + u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> + unsigned int hw_context_size;
>> + unsigned int swinit;
>> + unsigned int first_request;
>> + unsigned int last_request;
>> + unsigned int to_hash_later;
>> +};
>> +
>> +struct talitos_export_state {
>> + u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> + unsigned int swinit;
>> + unsigned int first_request;
>> + unsigned int last_request;
>> + unsigned int to_hash_later;
>> +};
>> +
>> +static void common_nonsnoop_hash_unmap(struct device *dev,
>> + struct talitos_edesc *edesc,
>> + struct ahash_request *areq)
>> +{
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + struct talitos_private *priv = dev_get_drvdata(dev);
>> + bool is_sec1 = has_ftr_sec1(priv);
>> + struct talitos_desc *desc = &edesc->desc;
>> +
>> + unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
>> +
>> + if (edesc->last && req_ctx->last_request)
>> + memcpy(areq->result, req_ctx->hw_context,
>> + crypto_ahash_digestsize(tfm));
>> +
>> + if (edesc->src)
>> + talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0);
>> +
>> + /* When using hashctx-in, must unmap it. */
>> + if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
>> + unmap_single_talitos_ptr(dev, &desc->ptr[1],
>> + DMA_TO_DEVICE);
>> +
>> + if (edesc->dma_len)
>> + dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
>> + DMA_BIDIRECTIONAL);
>> +}
>> +
>> +static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
>> +{
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> + struct talitos_edesc *next;
>> +
>> + while (edesc) {
>> + next = edesc->next_desc;
>> + common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
>> + kfree(edesc);
>> + edesc = next;
>> + }
>> +}
>> +
>> +static void ahash_done(struct device *dev,
>> + struct talitos_desc *desc, void *context,
>> + int err)
>> +{
>> + struct ahash_request *areq = context;
>> + struct talitos_edesc *edesc =
>> + container_of(desc, struct talitos_edesc, desc);
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + bool is_sec1 = has_ftr_sec1(dev_get_drvdata(dev));
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> + struct talitos_edesc *next;
>> +
>> + if (is_sec1) {
>> + free_edesc_list_from(areq, edesc);
>> + ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> + } else {
>> + next = edesc->next_desc;
>> +
>> + common_nonsnoop_hash_unmap(dev, edesc, areq);
>> + kfree(edesc);
>> +
>> + if (err)
>> + goto out;
>> +
>> + if (next) {
>> + err = talitos_submit(dev, ctx->ch, &next->desc,
>> + ahash_done, areq);
>> + if (err != -EINPROGRESS)
>> + goto out;
>> + return;
>> + }
>> +out:
>> + if (err && next)
>> + free_edesc_list_from(areq, next);
>> + ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> + }
>> +}
>> +
>> +/*
>> + * SEC1 doesn't like hashing of 0 sized message, so we do the padding
>> + * ourself and submit a padded block
>> + */
>> +static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
>> + struct talitos_edesc *edesc,
>> + struct talitos_ptr *ptr)
>> +{
>> + static u8 padded_hash[64] = {
>> + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> + };
>> +
>> + pr_err_once("Bug in SEC1, padding ourself\n");
>> + edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
>> + map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
>> + (char *)padded_hash, DMA_TO_DEVICE);
>> +}
>> +
>> +static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>> + struct ahash_request *areq,
>> + unsigned int length)
>> +{
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + struct device *dev = ctx->dev;
>> + struct talitos_desc *desc = &edesc->desc;
>> + bool sync_needed = false;
>> + struct talitos_private *priv = dev_get_drvdata(dev);
>> + bool is_sec1 = has_ftr_sec1(priv);
>> + int sg_count;
>> +
>> + /* first DWORD empty */
>> +
>> + /* hash context in */
>> + if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
>> + map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
>> + req_ctx->hw_context_size,
>> + req_ctx->hw_context,
>> + DMA_TO_DEVICE);
>> + req_ctx->swinit = 0;
>> + }
>> + /* Indicate next op is not the first. */
>> + req_ctx->first_request = 0;
>> +
>> + /* HMAC key */
>> + if (ctx->keylen)
>> + to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
>> + is_sec1);
>> +
>> + sg_count = edesc->src_nents ?: 1;
>> + if (is_sec1 && sg_count > 1)
>> + sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length);
>> + else if (length)
>> + sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
>> +
>> + /*
>> + * data in
>> + */
>> + sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
>> + sg_count, 0, 0);
>> + if (sg_count > 1)
>> + sync_needed = true;
>> +
>> + /* fifth DWORD empty */
>> +
>> + /* hash/HMAC out -or- hash context out */
>> + if (edesc->last && req_ctx->last_request)
>> + map_single_talitos_ptr(dev, &desc->ptr[5],
>> + crypto_ahash_digestsize(tfm),
>> + req_ctx->hw_context, DMA_FROM_DEVICE);
>> + else
>> + map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
>> + req_ctx->hw_context_size,
>> + req_ctx->hw_context,
>> + DMA_FROM_DEVICE);
>> +
>> + /* last DWORD empty */
>> +
>> + if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
>> + talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
>> +
>> + if (sync_needed)
>> + dma_sync_single_for_device(dev, edesc->dma_link_tbl,
>> + edesc->dma_len, DMA_BIDIRECTIONAL);
>> +}
>> +
>> +static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
>> + struct scatterlist *src,
>> + unsigned int nbytes)
>> +{
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> +
>> + return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
>> + nbytes, 0, 0, 0, areq->base.flags, false);
>> +}
>> +
>> +static struct talitos_edesc *
>> +ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>> + unsigned int blocksize, bool is_sec1)
>> +{
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
>> + size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
>> + TALITOS2_MAX_DATA_LEN;
>> + struct scatterlist tmp[2];
>> + size_t to_hash_this_desc;
>> + struct scatterlist *src;
>> + size_t offset = 0;
>> +
>> + do {
>> + src = scatterwalk_ffwd(tmp, areq->src, offset);
>> +
>> + to_hash_this_desc =
>> + min(nbytes, ALIGN_DOWN(desc_max, blocksize));
>> +
>> + /* Allocate extended descriptor */
>> + edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
>> + if (IS_ERR(edesc)) {
>> + if (first)
>> + free_edesc_list_from(areq, first);
>> + return edesc;
>> + }
>> +
>> + edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
>> + edesc->desc.hdr = ctx->desc_hdr_template;
>> + edesc->first = offset == 0;
>> + edesc->last = nbytes - to_hash_this_desc == 0;
>> +
>> + /* On last one, request SEC to pad; otherwise continue */
>> + if (req_ctx->last_request && edesc->last)
>> + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
>> + else
>> + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
>> +
>> + /* request SEC to INIT hash. */
>> + if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
>> + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
>> +
>> + /*
>> + * When the tfm context has a keylen, it's an HMAC.
>> + * A first or last (ie. not middle) descriptor must request HMAC.
>> + */
>> + if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
>> + (req_ctx->last_request && edesc->last)))
>> + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
>> +
>> + /* clear the DN bit */
>> + if (is_sec1 && !edesc->last)
>> + edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
>> +
>> + common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
>> +
>> + offset += to_hash_this_desc;
>> + nbytes -= to_hash_this_desc;
>> +
>> + if (!prev_edesc)
>> + first = edesc;
>> + else
>> + prev_edesc->next_desc = edesc;
>> + prev_edesc = edesc;
>> + } while (nbytes);
>> +
>> + return first;
>> +}
>> +
>> +static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
>> +{
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + struct talitos_edesc *edesc;
>> + unsigned int blocksize =
>> + crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> + bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
>> + unsigned int nbytes_to_hash;
>> + unsigned int to_hash_later;
>> + struct device *dev = ctx->dev;
>> + int ret;
>> +
>> + nbytes_to_hash = ALIGN_DOWN(nbytes, blocksize);
>> + to_hash_later = nbytes - nbytes_to_hash;
>> +
>> + if (req_ctx->last_request) {
>> + nbytes_to_hash = nbytes;
>> + to_hash_later = 0;
>> + }
>> +
>> + req_ctx->to_hash_later = to_hash_later;
>> +
>> + edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
>> + is_sec1);
>> + if (IS_ERR(edesc))
>> + return PTR_ERR(edesc);
>> +
>> + ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
>> + if (ret != -EINPROGRESS)
>> + free_edesc_list_from(areq, edesc);
>> +
>> + return ret;
>> +}
>> +
>> +static int ahash_init(struct ahash_request *areq)
>> +{
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> + struct device *dev = ctx->dev;
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + unsigned int size;
>> + dma_addr_t dma;
>> +
>> + /* Initialize the context */
>> + req_ctx->first_request = 1;
>> + req_ctx->swinit = 0; /* assume h/w init of context */
>> + size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> + ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> + : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> + req_ctx->hw_context_size = size;
>> + req_ctx->last_request = 0;
>> +
>> + dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> + DMA_TO_DEVICE);
>> + dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * on h/w without explicit sha224 support, we initialize h/w context
>> + * manually with sha224 constants, and tell it to run sha256.
>> + */
>> +static int ahash_init_sha224_swinit(struct ahash_request *areq)
>> +{
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> + req_ctx->hw_context[0] = SHA224_H0;
>> + req_ctx->hw_context[1] = SHA224_H1;
>> + req_ctx->hw_context[2] = SHA224_H2;
>> + req_ctx->hw_context[3] = SHA224_H3;
>> + req_ctx->hw_context[4] = SHA224_H4;
>> + req_ctx->hw_context[5] = SHA224_H5;
>> + req_ctx->hw_context[6] = SHA224_H6;
>> + req_ctx->hw_context[7] = SHA224_H7;
>> +
>> + /* init 64-bit count */
>> + req_ctx->hw_context[8] = 0;
>> + req_ctx->hw_context[9] = 0;
>> +
>> + ahash_init(areq);
>> + req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
>> +
>> + return 0;
>> +}
>> +
>> +static int ahash_update(struct ahash_request *areq)
>> +{
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> + req_ctx->last_request = 0;
>> +
>> + return ahash_process_req(areq, areq->nbytes);
>> +}
>> +
>> +static int ahash_final(struct ahash_request *areq)
>> +{
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> + req_ctx->last_request = 1;
>> +
>> + return ahash_process_req(areq, 0);
>> +}
>> +
>> +static int ahash_finup(struct ahash_request *areq)
>> +{
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> +
>> + req_ctx->last_request = 1;
>> +
>> + return ahash_process_req(areq, areq->nbytes);
>> +}
>> +
>> +static int ahash_digest(struct ahash_request *areq)
>> +{
>> + ahash_init(areq);
>> + return ahash_finup(areq);
>> +}
>> +
>> +static int ahash_digest_sha224_swinit(struct ahash_request *areq)
>> +{
>> + ahash_init_sha224_swinit(areq);
>> + return ahash_finup(areq);
>> +}
>> +
>> +static int ahash_export(struct ahash_request *areq, void *out)
>> +{
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + struct talitos_export_state *export = out;
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> + struct device *dev = ctx->dev;
>> + dma_addr_t dma;
>> +
>> + dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> + DMA_FROM_DEVICE);
>> + dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
>> +
>> + memcpy(export->hw_context, req_ctx->hw_context,
>> + req_ctx->hw_context_size);
>> + export->swinit = req_ctx->swinit;
>> + export->first_request = req_ctx->first_request;
>> + export->last_request = req_ctx->last_request;
>> + export->to_hash_later = req_ctx->to_hash_later;
>> +
>> + return 0;
>> +}
>> +
>> +static int ahash_import(struct ahash_request *areq, const void *in)
>> +{
>> + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> + struct device *dev = ctx->dev;
>> + const struct talitos_export_state *export = in;
>> + unsigned int size;
>> + dma_addr_t dma;
>> +
>> + memset(req_ctx, 0, sizeof(*req_ctx));
>> + size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> + ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> + : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> + req_ctx->hw_context_size = size;
>> + memcpy(req_ctx->hw_context, export->hw_context, size);
>> + req_ctx->swinit = export->swinit;
>> + req_ctx->first_request = export->first_request;
>> + req_ctx->last_request = export->last_request;
>> + req_ctx->to_hash_later = export->to_hash_later;
>> +
>> + dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> + DMA_TO_DEVICE);
>> + dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> +
>> + return 0;
>> +}
>> +
>> +static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
>> + u8 *hash)
>> +{
>> + struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> +
>> + struct scatterlist sg[1];
>> + struct ahash_request *req;
>> + struct crypto_wait wait;
>> + int ret;
>> +
>> + crypto_init_wait(&wait);
>> +
>> + req = ahash_request_alloc(tfm, GFP_KERNEL);
>> + if (!req)
>> + return -ENOMEM;
>> +
>> + /* Keep tfm keylen == 0 during hash of the long key */
>> + ctx->keylen = 0;
>> + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
>> + crypto_req_done, &wait);
>> +
>> + sg_init_one(&sg[0], key, keylen);
>> +
>> + ahash_request_set_crypt(req, sg, hash, keylen);
>> + ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
>> +
>> + ahash_request_free(req);
>> +
>> + return ret;
>> +}
>> +
>> +static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
>> + unsigned int keylen)
>> +{
>> + struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> + struct device *dev = ctx->dev;
>> + unsigned int blocksize =
>> + crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> + unsigned int digestsize = crypto_ahash_digestsize(tfm);
>> + unsigned int keysize = keylen;
>> + u8 hash[SHA512_DIGEST_SIZE];
>> + int ret;
>> +
>> + if (keylen <= blocksize)
>> + memcpy(ctx->key, key, keysize);
>> + else {
>> + /* Must get the hash of the long key */
>> + ret = keyhash(tfm, key, keylen, hash);
>> +
>> + if (ret)
>> + return -EINVAL;
>> +
>> + keysize = digestsize;
>> + memcpy(ctx->key, hash, digestsize);
>> + }
>> +
>> + if (ctx->keylen)
>> + dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
>> +
>> + ctx->keylen = keysize;
>> + ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
>> +
>> + return 0;
>> +}
>> +
>> +static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
>> +{
>> + struct crypto_alg *alg = tfm->__crt_alg;
>> + struct talitos_crypto_alg *talitos_alg;
>> + struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
>> +
>> + talitos_alg = container_of(__crypto_ahash_alg(alg),
>> + struct talitos_crypto_alg,
>> + algt.alg.hash);
>> +
>> + ctx->keylen = 0;
>> + sizeof(struct talitos_ahash_req_ctx));
>> +
>> + return talitos_init_common(ctx, talitos_alg);
>> +}
>> +
>> +static struct talitos_alg_template hash_driver_algs[] = {
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = MD5_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "md5",
>> + .cra_driver_name = "md5-talitos",
>> + .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_MD5,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA1_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "sha1",
>> + .cra_driver_name = "sha1-talitos",
>> + .cra_blocksize = SHA1_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_SHA1,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA224_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "sha224",
>> + .cra_driver_name = "sha224-talitos",
>> + .cra_blocksize = SHA224_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_SHA224,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA256_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "sha256",
>> + .cra_driver_name = "sha256-talitos",
>> + .cra_blocksize = SHA256_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_SHA256,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA384_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "sha384",
>> + .cra_driver_name = "sha384-talitos",
>> + .cra_blocksize = SHA384_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUB |
>> + DESC_HDR_MODE0_MDEUB_SHA384,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA512_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "sha512",
>> + .cra_driver_name = "sha512-talitos",
>> + .cra_blocksize = SHA512_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUB |
>> + DESC_HDR_MODE0_MDEUB_SHA512,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = MD5_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "hmac(md5)",
>> + .cra_driver_name = "hmac-md5-talitos",
>> + .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_MD5,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA1_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "hmac(sha1)",
>> + .cra_driver_name = "hmac-sha1-talitos",
>> + .cra_blocksize = SHA1_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_SHA1,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA224_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "hmac(sha224)",
>> + .cra_driver_name = "hmac-sha224-talitos",
>> + .cra_blocksize = SHA224_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_SHA224,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA256_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "hmac(sha256)",
>> + .cra_driver_name = "hmac-sha256-talitos",
>> + .cra_blocksize = SHA256_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_SHA256,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA384_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "hmac(sha384)",
>> + .cra_driver_name = "hmac-sha384-talitos",
>> + .cra_blocksize = SHA384_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUB |
>> + DESC_HDR_MODE0_MDEUB_SHA384,
>> + },
>> + { .type = CRYPTO_ALG_TYPE_AHASH,
>> + .alg.hash = {
>> + .halg.digestsize = SHA512_DIGEST_SIZE,
>> + .halg.statesize = sizeof(struct talitos_export_state),
>> + .halg.base = {
>> + .cra_name = "hmac(sha512)",
>> + .cra_driver_name = "hmac-sha512-talitos",
>> + .cra_blocksize = SHA512_BLOCK_SIZE,
>> + .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> + .cra_flags = CRYPTO_ALG_ASYNC |
>> + CRYPTO_ALG_ALLOCATES_MEMORY |
>> + CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> + CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> + }
>> + },
>> + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUB |
>> + DESC_HDR_MODE0_MDEUB_SHA512,
>> + }
>> +};
>> +
>> +int talitos_register_hash(struct device *dev)
>> +{
>> + struct talitos_private *priv = dev_get_drvdata(dev);
>> + struct ahash_alg *ahash_alg;
>> + struct crypto_alg *alg;
>> + size_t i;
>> + int ret;
>> +
>> + for (i = 0; i < ARRAY_SIZE(hash_driver_algs); i++) {
>> + if (!talitos_hw_supports(dev,
>> + hash_driver_algs[i].desc_hdr_template))
>> + continue;
>> +
>> + ahash_alg = &hash_driver_algs[i].alg.hash;
>> + alg = &ahash_alg->halg.base;
>> +
>> + alg->cra_init = talitos_cra_init_ahash;
>> + alg->cra_exit = talitos_cra_exit;
>> + ahash_alg->init = ahash_init;
>> + ahash_alg->update = ahash_update;
>> + ahash_alg->final = ahash_final;
>> + ahash_alg->finup = ahash_finup;
>> + ahash_alg->digest = ahash_digest;
>> + if (!strncmp(alg->cra_name, "hmac", 4))
>> + ahash_alg->setkey = ahash_setkey;
>> + ahash_alg->import = ahash_import;
>> + ahash_alg->export = ahash_export;
>> +
>> + if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
>> + !strncmp(alg->cra_name, "hmac", 4)) {
>> + /* not supported */
>> + continue;
>> + }
>> +
>> + if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
>> + (!strcmp(alg->cra_name, "sha224") ||
>> + !strcmp(alg->cra_name, "hmac(sha224)"))) {
>> + ahash_alg->init = ahash_init_sha224_swinit;
>> + ahash_alg->digest = ahash_digest_sha224_swinit;
>> + hash_driver_algs[i].desc_hdr_template =
>> + DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> + DESC_HDR_SEL0_MDEUA |
>> + DESC_HDR_MODE0_MDEU_SHA256;
>> + }
>> +
>> + ret = talitos_register_common(dev, &hash_driver_algs[i]);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + return 0;
>> +}
>> diff --git a/drivers/crypto/talitos/talitos.c b/drivers/crypto/talitos/talitos.c
>> index 869739dcc4d7..b8bcb970d7d5 100644
>> --- a/drivers/crypto/talitos/talitos.c
>> +++ b/drivers/crypto/talitos/talitos.c
>> @@ -831,26 +831,6 @@ DEF_TALITOS2_INTERRUPT(ch1_3, TALITOS2_ISR_CH_1_3_DONE, TALITOS2_ISR_CH_1_3_ERR,
>> */
>> #define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
>>
>> -#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE
>> -#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512
>> -
>> -struct talitos_ahash_req_ctx {
>> - u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> - unsigned int hw_context_size;
>> - unsigned int swinit;
>> - unsigned int first_request;
>> - unsigned int last_request;
>> - unsigned int to_hash_later;
>> -};
>> -
>> -struct talitos_export_state {
>> - u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
>> - unsigned int swinit;
>> - unsigned int first_request;
>> - unsigned int last_request;
>> - unsigned int to_hash_later;
>> -};
>> -
>> static int aead_setkey(struct crypto_aead *authenc,
>> const u8 *key, unsigned int keylen)
>> {
>> @@ -1659,501 +1639,6 @@ static int skcipher_decrypt(struct skcipher_request *areq)
>> return common_nonsnoop(edesc, areq, skcipher_done);
>> }
>>
>> -static void common_nonsnoop_hash_unmap(struct device *dev,
>> - struct talitos_edesc *edesc,
>> - struct ahash_request *areq)
>> -{
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - struct talitos_private *priv = dev_get_drvdata(dev);
>> - bool is_sec1 = has_ftr_sec1(priv);
>> - struct talitos_desc *desc = &edesc->desc;
>> -
>> - unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
>> -
>> - if (edesc->last && req_ctx->last_request)
>> - memcpy(areq->result, req_ctx->hw_context,
>> - crypto_ahash_digestsize(tfm));
>> -
>> - if (edesc->src)
>> - talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0);
>> -
>> - /* When using hashctx-in, must unmap it. */
>> - if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
>> - unmap_single_talitos_ptr(dev, &desc->ptr[1],
>> - DMA_TO_DEVICE);
>> -
>> - if (edesc->dma_len)
>> - dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
>> - DMA_BIDIRECTIONAL);
>> -}
>> -
>> -static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
>> -{
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> - struct talitos_edesc *next;
>> -
>> - while (edesc) {
>> - next = edesc->next_desc;
>> - common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
>> - kfree(edesc);
>> - edesc = next;
>> - }
>> -}
>> -
>> -static void ahash_done(struct device *dev,
>> - struct talitos_desc *desc, void *context,
>> - int err)
>> -{
>> - struct ahash_request *areq = context;
>> - struct talitos_edesc *edesc =
>> - container_of(desc, struct talitos_edesc, desc);
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - bool is_sec1 = has_ftr_sec1(dev_get_drvdata(dev));
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> - struct talitos_edesc *next;
>> -
>> - if (is_sec1) {
>> - free_edesc_list_from(areq, edesc);
>> - ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> - } else {
>> - next = edesc->next_desc;
>> -
>> - common_nonsnoop_hash_unmap(dev, edesc, areq);
>> - kfree(edesc);
>> -
>> - if (err)
>> - goto out;
>> -
>> - if (next) {
>> - err = talitos_submit(dev, ctx->ch, &next->desc,
>> - ahash_done, areq);
>> - if (err != -EINPROGRESS)
>> - goto out;
>> - return;
>> - }
>> -out:
>> - if (err && next)
>> - free_edesc_list_from(areq, next);
>> - ahash_request_complete(areq, err ?: req_ctx->to_hash_later);
>> - }
>> -}
>> -
>> -/*
>> - * SEC1 doesn't like hashing of 0 sized message, so we do the padding
>> - * ourself and submit a padded block
>> - */
>> -static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
>> - struct talitos_edesc *edesc,
>> - struct talitos_ptr *ptr)
>> -{
>> - static u8 padded_hash[64] = {
>> - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
>> - };
>> -
>> - pr_err_once("Bug in SEC1, padding ourself\n");
>> - edesc->desc.hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
>> - map_single_talitos_ptr(ctx->dev, ptr, sizeof(padded_hash),
>> - (char *)padded_hash, DMA_TO_DEVICE);
>> -}
>> -
>> -static void common_nonsnoop_hash(struct talitos_edesc *edesc,
>> - struct ahash_request *areq,
>> - unsigned int length)
>> -{
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - struct device *dev = ctx->dev;
>> - struct talitos_desc *desc = &edesc->desc;
>> - bool sync_needed = false;
>> - struct talitos_private *priv = dev_get_drvdata(dev);
>> - bool is_sec1 = has_ftr_sec1(priv);
>> - int sg_count;
>> -
>> - /* first DWORD empty */
>> -
>> - /* hash context in */
>> - if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
>> - map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
>> - req_ctx->hw_context_size,
>> - req_ctx->hw_context,
>> - DMA_TO_DEVICE);
>> - req_ctx->swinit = 0;
>> - }
>> - /* Indicate next op is not the first. */
>> - req_ctx->first_request = 0;
>> -
>> - /* HMAC key */
>> - if (ctx->keylen)
>> - to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
>> - is_sec1);
>> -
>> - sg_count = edesc->src_nents ?: 1;
>> - if (is_sec1 && sg_count > 1)
>> - sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length);
>> - else if (length)
>> - sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
>> -
>> - /*
>> - * data in
>> - */
>> - sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
>> - sg_count, 0, 0);
>> - if (sg_count > 1)
>> - sync_needed = true;
>> -
>> - /* fifth DWORD empty */
>> -
>> - /* hash/HMAC out -or- hash context out */
>> - if (edesc->last && req_ctx->last_request)
>> - map_single_talitos_ptr(dev, &desc->ptr[5],
>> - crypto_ahash_digestsize(tfm),
>> - req_ctx->hw_context, DMA_FROM_DEVICE);
>> - else
>> - map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
>> - req_ctx->hw_context_size,
>> - req_ctx->hw_context,
>> - DMA_FROM_DEVICE);
>> -
>> - /* last DWORD empty */
>> -
>> - if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
>> - talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
>> -
>> - if (sync_needed)
>> - dma_sync_single_for_device(dev, edesc->dma_link_tbl,
>> - edesc->dma_len, DMA_BIDIRECTIONAL);
>> -}
>> -
>> -static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
>> - struct scatterlist *src,
>> - unsigned int nbytes)
>> -{
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> -
>> - return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
>> - nbytes, 0, 0, 0, areq->base.flags, false);
>> -}
>> -
>> -static struct talitos_edesc *
>> -ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
>> - unsigned int blocksize, bool is_sec1)
>> -{
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
>> - size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
>> - TALITOS2_MAX_DATA_LEN;
>> - struct scatterlist tmp[2];
>> - size_t to_hash_this_desc;
>> - struct scatterlist *src;
>> - size_t offset = 0;
>> -
>> - do {
>> - src = scatterwalk_ffwd(tmp, areq->src, offset);
>> -
>> - to_hash_this_desc =
>> - min(nbytes, ALIGN_DOWN(desc_max, blocksize));
>> -
>> - /* Allocate extended descriptor */
>> - edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
>> - if (IS_ERR(edesc)) {
>> - if (first)
>> - free_edesc_list_from(areq, first);
>> - return edesc;
>> - }
>> -
>> - edesc->src = scatterwalk_ffwd(edesc->bufsl, areq->src, offset);
>> - edesc->desc.hdr = ctx->desc_hdr_template;
>> - edesc->first = offset == 0;
>> - edesc->last = nbytes - to_hash_this_desc == 0;
>> -
>> - /* On last one, request SEC to pad; otherwise continue */
>> - if (req_ctx->last_request && edesc->last)
>> - edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
>> - else
>> - edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
>> -
>> - /* request SEC to INIT hash. */
>> - if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
>> - edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
>> -
>> - /*
>> - * When the tfm context has a keylen, it's an HMAC.
>> - * A first or last (ie. not middle) descriptor must request HMAC.
>> - */
>> - if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
>> - (req_ctx->last_request && edesc->last)))
>> - edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
>> -
>> - /* clear the DN bit */
>> - if (is_sec1 && !edesc->last)
>> - edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
>> -
>> - common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
>> -
>> - offset += to_hash_this_desc;
>> - nbytes -= to_hash_this_desc;
>> -
>> - if (!prev_edesc)
>> - first = edesc;
>> - else
>> - prev_edesc->next_desc = edesc;
>> - prev_edesc = edesc;
>> - } while (nbytes);
>> -
>> - return first;
>> -}
>> -
>> -static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
>> -{
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - struct talitos_edesc *edesc;
>> - unsigned int blocksize =
>> - crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> - bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
>> - unsigned int nbytes_to_hash;
>> - unsigned int to_hash_later;
>> - struct device *dev = ctx->dev;
>> - int ret;
>> -
>> - nbytes_to_hash = ALIGN_DOWN(nbytes, blocksize);
>> - to_hash_later = nbytes - nbytes_to_hash;
>> -
>> - if (req_ctx->last_request) {
>> - nbytes_to_hash = nbytes;
>> - to_hash_later = 0;
>> - }
>> -
>> - req_ctx->to_hash_later = to_hash_later;
>> -
>> - edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
>> - is_sec1);
>> - if (IS_ERR(edesc))
>> - return PTR_ERR(edesc);
>> -
>> - ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
>> - if (ret != -EINPROGRESS)
>> - free_edesc_list_from(areq, edesc);
>> -
>> - return ret;
>> -}
>> -
>> -static int ahash_init(struct ahash_request *areq)
>> -{
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> - struct device *dev = ctx->dev;
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - unsigned int size;
>> - dma_addr_t dma;
>> -
>> - /* Initialize the context */
>> - req_ctx->first_request = 1;
>> - req_ctx->swinit = 0; /* assume h/w init of context */
>> - size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> - ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> - : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> - req_ctx->hw_context_size = size;
>> - req_ctx->last_request = 0;
>> -
>> - dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> - DMA_TO_DEVICE);
>> - dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> -
>> - return 0;
>> -}
>> -
>> -/*
>> - * on h/w without explicit sha224 support, we initialize h/w context
>> - * manually with sha224 constants, and tell it to run sha256.
>> - */
>> -static int ahash_init_sha224_swinit(struct ahash_request *areq)
>> -{
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> - req_ctx->hw_context[0] = SHA224_H0;
>> - req_ctx->hw_context[1] = SHA224_H1;
>> - req_ctx->hw_context[2] = SHA224_H2;
>> - req_ctx->hw_context[3] = SHA224_H3;
>> - req_ctx->hw_context[4] = SHA224_H4;
>> - req_ctx->hw_context[5] = SHA224_H5;
>> - req_ctx->hw_context[6] = SHA224_H6;
>> - req_ctx->hw_context[7] = SHA224_H7;
>> -
>> - /* init 64-bit count */
>> - req_ctx->hw_context[8] = 0;
>> - req_ctx->hw_context[9] = 0;
>> -
>> - ahash_init(areq);
>> - req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
>> -
>> - return 0;
>> -}
>> -
>> -static int ahash_update(struct ahash_request *areq)
>> -{
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> - req_ctx->last_request = 0;
>> -
>> - return ahash_process_req(areq, areq->nbytes);
>> -}
>> -
>> -static int ahash_final(struct ahash_request *areq)
>> -{
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> - req_ctx->last_request = 1;
>> -
>> - return ahash_process_req(areq, 0);
>> -}
>> -
>> -static int ahash_finup(struct ahash_request *areq)
>> -{
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> -
>> - req_ctx->last_request = 1;
>> -
>> - return ahash_process_req(areq, areq->nbytes);
>> -}
>> -
>> -static int ahash_digest(struct ahash_request *areq)
>> -{
>> - ahash_init(areq);
>> - return ahash_finup(areq);
>> -}
>> -
>> -static int ahash_digest_sha224_swinit(struct ahash_request *areq)
>> -{
>> - ahash_init_sha224_swinit(areq);
>> - return ahash_finup(areq);
>> -}
>> -
>> -static int ahash_export(struct ahash_request *areq, void *out)
>> -{
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - struct talitos_export_state *export = out;
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> - struct device *dev = ctx->dev;
>> - dma_addr_t dma;
>> -
>> - dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> - DMA_FROM_DEVICE);
>> - dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_FROM_DEVICE);
>> -
>> - memcpy(export->hw_context, req_ctx->hw_context,
>> - req_ctx->hw_context_size);
>> - export->swinit = req_ctx->swinit;
>> - export->first_request = req_ctx->first_request;
>> - export->last_request = req_ctx->last_request;
>> - export->to_hash_later = req_ctx->to_hash_later;
>> -
>> - return 0;
>> -}
>> -
>> -static int ahash_import(struct ahash_request *areq, const void *in)
>> -{
>> - struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
>> - struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
>> - struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
>> - struct device *dev = ctx->dev;
>> - const struct talitos_export_state *export = in;
>> - unsigned int size;
>> - dma_addr_t dma;
>> -
>> - memset(req_ctx, 0, sizeof(*req_ctx));
>> - size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
>> - ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
>> - : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
>> - req_ctx->hw_context_size = size;
>> - memcpy(req_ctx->hw_context, export->hw_context, size);
>> - req_ctx->swinit = export->swinit;
>> - req_ctx->first_request = export->first_request;
>> - req_ctx->last_request = export->last_request;
>> - req_ctx->to_hash_later = export->to_hash_later;
>> -
>> - dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
>> - DMA_TO_DEVICE);
>> - dma_unmap_single(dev, dma, req_ctx->hw_context_size, DMA_TO_DEVICE);
>> -
>> - return 0;
>> -}
>> -
>> -static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
>> - u8 *hash)
>> -{
>> - struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> -
>> - struct scatterlist sg[1];
>> - struct ahash_request *req;
>> - struct crypto_wait wait;
>> - int ret;
>> -
>> - crypto_init_wait(&wait);
>> -
>> - req = ahash_request_alloc(tfm, GFP_KERNEL);
>> - if (!req)
>> - return -ENOMEM;
>> -
>> - /* Keep tfm keylen == 0 during hash of the long key */
>> - ctx->keylen = 0;
>> - ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
>> - crypto_req_done, &wait);
>> -
>> - sg_init_one(&sg[0], key, keylen);
>> -
>> - ahash_request_set_crypt(req, sg, hash, keylen);
>> - ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
>> -
>> - ahash_request_free(req);
>> -
>> - return ret;
>> -}
>> -
>> -static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
>> - unsigned int keylen)
>> -{
>> - struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
>> - struct device *dev = ctx->dev;
>> - unsigned int blocksize =
>> - crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
>> - unsigned int digestsize = crypto_ahash_digestsize(tfm);
>> - unsigned int keysize = keylen;
>> - u8 hash[SHA512_DIGEST_SIZE];
>> - int ret;
>> -
>> - if (keylen <= blocksize)
>> - memcpy(ctx->key, key, keysize);
>> - else {
>> - /* Must get the hash of the long key */
>> - ret = keyhash(tfm, key, keylen, hash);
>> -
>> - if (ret)
>> - return -EINVAL;
>> -
>> - keysize = digestsize;
>> - memcpy(ctx->key, hash, digestsize);
>> - }
>> -
>> - if (ctx->keylen)
>> - dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
>> -
>> - ctx->keylen = keysize;
>> - ctx->dma_key = dma_map_single(dev, ctx->key, keysize, DMA_TO_DEVICE);
>> -
>> - return 0;
>> -}
>> -
>> static struct talitos_alg_template driver_algs[] = {
>> /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */
>> { .type = CRYPTO_ALG_TYPE_AEAD,
>> @@ -2737,235 +2222,6 @@ static struct talitos_alg_template driver_algs[] = {
>> DESC_HDR_MODE0_DEU_CBC |
>> DESC_HDR_MODE0_DEU_3DES,
>> },
>> - /* AHASH algorithms. */
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = MD5_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "md5",
>> - .cra_driver_name = "md5-talitos",
>> - .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_MD5,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA1_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "sha1",
>> - .cra_driver_name = "sha1-talitos",
>> - .cra_blocksize = SHA1_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_SHA1,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA224_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "sha224",
>> - .cra_driver_name = "sha224-talitos",
>> - .cra_blocksize = SHA224_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_SHA224,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA256_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "sha256",
>> - .cra_driver_name = "sha256-talitos",
>> - .cra_blocksize = SHA256_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_SHA256,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA384_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "sha384",
>> - .cra_driver_name = "sha384-talitos",
>> - .cra_blocksize = SHA384_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUB |
>> - DESC_HDR_MODE0_MDEUB_SHA384,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA512_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "sha512",
>> - .cra_driver_name = "sha512-talitos",
>> - .cra_blocksize = SHA512_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUB |
>> - DESC_HDR_MODE0_MDEUB_SHA512,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = MD5_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "hmac(md5)",
>> - .cra_driver_name = "hmac-md5-talitos",
>> - .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_MD5,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA1_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "hmac(sha1)",
>> - .cra_driver_name = "hmac-sha1-talitos",
>> - .cra_blocksize = SHA1_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_SHA1,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA224_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "hmac(sha224)",
>> - .cra_driver_name = "hmac-sha224-talitos",
>> - .cra_blocksize = SHA224_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_SHA224,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA256_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "hmac(sha256)",
>> - .cra_driver_name = "hmac-sha256-talitos",
>> - .cra_blocksize = SHA256_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_SHA256,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA384_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "hmac(sha384)",
>> - .cra_driver_name = "hmac-sha384-talitos",
>> - .cra_blocksize = SHA384_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUB |
>> - DESC_HDR_MODE0_MDEUB_SHA384,
>> - },
>> - { .type = CRYPTO_ALG_TYPE_AHASH,
>> - .alg.hash = {
>> - .halg.digestsize = SHA512_DIGEST_SIZE,
>> - .halg.statesize = sizeof(struct talitos_export_state),
>> - .halg.base = {
>> - .cra_name = "hmac(sha512)",
>> - .cra_driver_name = "hmac-sha512-talitos",
>> - .cra_blocksize = SHA512_BLOCK_SIZE,
>> - .cra_reqsize = sizeof(struct talitos_ahash_req_ctx),
>> - .cra_flags = CRYPTO_ALG_ASYNC |
>> - CRYPTO_ALG_ALLOCATES_MEMORY |
>> - CRYPTO_AHASH_ALG_BLOCK_ONLY |
>> - CRYPTO_AHASH_ALG_FINAL_NONZERO,
>> - }
>> - },
>> - .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUB |
>> - DESC_HDR_MODE0_MDEUB_SHA512,
>> - }
>> };
>>
>> int talitos_init_common(struct talitos_ctx *ctx,
>> @@ -3014,22 +2270,6 @@ static int talitos_cra_init_skcipher(struct crypto_skcipher *tfm)
>> return talitos_init_common(ctx, talitos_alg);
>> }
>>
>> -static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
>> -{
>> - struct crypto_alg *alg = tfm->__crt_alg;
>> - struct talitos_crypto_alg *talitos_alg;
>> - struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
>> -
>> - talitos_alg = container_of(__crypto_ahash_alg(alg),
>> - struct talitos_crypto_alg,
>> - algt.alg.hash);
>> -
>> - ctx->keylen = 0;
>> - sizeof(struct talitos_ahash_req_ctx));
>> -
>> - return talitos_init_common(ctx, talitos_alg);
>> -}
>> -
>> void talitos_cra_exit(struct crypto_tfm *tfm)
>> {
>> struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
>> @@ -3128,6 +2368,12 @@ int talitos_register_common(struct device *dev,
>> t_alg->algt = *template;
>>
>> switch (t_alg->algt.type) {
>> + case CRYPTO_ALG_TYPE_AHASH:
>> + alg = &t_alg->algt.alg.hash.halg.base;
>> + talitos_alg_set_common(priv, alg, t_alg->algt.priority,
>> + t_alg->algt.type);
>> + ret = crypto_register_ahash(&t_alg->algt.alg.hash);
>> + break;
>> default:
>> dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
>> devm_kfree(dev, t_alg);
>> @@ -3193,37 +2439,6 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
>> return ERR_PTR(-ENOTSUPP);
>> }
>> break;
>> - case CRYPTO_ALG_TYPE_AHASH:
>> - alg = &t_alg->algt.alg.hash.halg.base;
>> - alg->cra_init = talitos_cra_init_ahash;
>> - alg->cra_exit = talitos_cra_exit;
>> - t_alg->algt.alg.hash.init = ahash_init;
>> - t_alg->algt.alg.hash.update = ahash_update;
>> - t_alg->algt.alg.hash.final = ahash_final;
>> - t_alg->algt.alg.hash.finup = ahash_finup;
>> - t_alg->algt.alg.hash.digest = ahash_digest;
>> - if (!strncmp(alg->cra_name, "hmac", 4))
>> - t_alg->algt.alg.hash.setkey = ahash_setkey;
>> - t_alg->algt.alg.hash.import = ahash_import;
>> - t_alg->algt.alg.hash.export = ahash_export;
>> -
>> - if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
>> - !strncmp(alg->cra_name, "hmac", 4)) {
>> - devm_kfree(dev, t_alg);
>> - return ERR_PTR(-ENOTSUPP);
>> - }
>> - if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
>> - (!strcmp(alg->cra_name, "sha224") ||
>> - !strcmp(alg->cra_name, "hmac(sha224)"))) {
>> - t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
>> - t_alg->algt.alg.hash.digest =
>> - ahash_digest_sha224_swinit;
>> - t_alg->algt.desc_hdr_template =
>> - DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
>> - DESC_HDR_SEL0_MDEUA |
>> - DESC_HDR_MODE0_MDEU_SHA256;
>> - }
>> - break;
>> default:
>> dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
>> devm_kfree(dev, t_alg);
>> @@ -3452,6 +2667,10 @@ static int talitos_probe(struct platform_device *ofdev)
>> dev_info(dev, "hwrng\n");
>> }
>>
>> + err = talitos_register_hash(dev);
>> + if (err)
>> + goto err_out;
>> +
>> /* register crypto algorithms the device supports */
>> for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
>> if (talitos_hw_supports(dev,
>> @@ -3479,12 +2698,6 @@ static int talitos_probe(struct platform_device *ofdev)
>> &t_alg->algt.alg.aead);
>> alg = &t_alg->algt.alg.aead.base;
>> break;
>> -
>> - case CRYPTO_ALG_TYPE_AHASH:
>> - err = crypto_register_ahash(
>> - &t_alg->algt.alg.hash);
>> - alg = &t_alg->algt.alg.hash.halg.base;
>> - break;
>> }
>> if (err) {
>> dev_err(dev, "%s alg registration failed\n",
>> diff --git a/drivers/crypto/talitos/talitos.h b/drivers/crypto/talitos/talitos.h
>> index afed9947f4c0..e703c18cb81f 100644
>> --- a/drivers/crypto/talitos/talitos.h
>> +++ b/drivers/crypto/talitos/talitos.h
>> @@ -530,3 +530,7 @@ int talitos_register_common(struct device *dev,
>>
>> int talitos_register_rng(struct device *dev);
>> void talitos_unregister_rng(struct device *dev);
>> +
>> +/* Hash */
>> +
>> +int talitos_register_hash(struct device *dev);


Thanks,

Paul.




--
Paul Louvel, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com