root/drivers/crypto/inside-secure/eip93/eip93-hash.c
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2024
 *
 * Christian Marangi <ansuelsmth@gmail.com
 */

#include <crypto/sha1.h>
#include <crypto/sha2.h>
#include <crypto/md5.h>
#include <crypto/hmac.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>

#include "eip93-cipher.h"
#include "eip93-hash.h"
#include "eip93-main.h"
#include "eip93-common.h"
#include "eip93-regs.h"

static void eip93_hash_free_data_blocks(struct ahash_request *req)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct eip93_device *eip93 = ctx->eip93;
        struct mkt_hash_block *block, *tmp;

        list_for_each_entry_safe(block, tmp, &rctx->blocks, list) {
                dma_unmap_single(eip93->dev, block->data_dma,
                                 SHA256_BLOCK_SIZE, DMA_TO_DEVICE);
                kfree(block);
        }
        if (!list_empty(&rctx->blocks))
                INIT_LIST_HEAD(&rctx->blocks);

        if (rctx->finalize)
                dma_unmap_single(eip93->dev, rctx->data_dma,
                                 rctx->data_used,
                                 DMA_TO_DEVICE);
}

static void eip93_hash_free_sa_record(struct ahash_request *req)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct eip93_device *eip93 = ctx->eip93;

        if (IS_HMAC(ctx->flags))
                dma_unmap_single(eip93->dev, rctx->sa_record_hmac_base,
                                 sizeof(rctx->sa_record_hmac), DMA_TO_DEVICE);

        dma_unmap_single(eip93->dev, rctx->sa_record_base,
                         sizeof(rctx->sa_record), DMA_TO_DEVICE);
}

void eip93_hash_handle_result(struct crypto_async_request *async, int err)
{
        struct ahash_request *req = ahash_request_cast(async);
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        int digestsize = crypto_ahash_digestsize(ahash);
        struct sa_state *sa_state = &rctx->sa_state;
        struct eip93_device *eip93 = ctx->eip93;
        int i;

        dma_unmap_single(eip93->dev, rctx->sa_state_base,
                         sizeof(*sa_state), DMA_FROM_DEVICE);

        /*
         * With partial_hash assume SHA256_DIGEST_SIZE buffer is passed.
         * This is to handle SHA224 that have a 32 byte intermediate digest.
         */
        if (rctx->partial_hash)
                digestsize = SHA256_DIGEST_SIZE;

        if (rctx->finalize || rctx->partial_hash) {
                /* bytes needs to be swapped for req->result */
                if (!IS_HASH_MD5(ctx->flags)) {
                        for (i = 0; i < digestsize / sizeof(u32); i++) {
                                u32 *digest = (u32 *)sa_state->state_i_digest;

                                digest[i] = be32_to_cpu((__be32 __force)digest[i]);
                        }
                }

                memcpy(req->result, sa_state->state_i_digest, digestsize);
        }

        eip93_hash_free_sa_record(req);
        eip93_hash_free_data_blocks(req);

        ahash_request_complete(req, err);
}

static void eip93_hash_init_sa_state_digest(u32 hash, u8 *digest)
{
        static const u32 sha256_init[] = {
                SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
                SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7
        };
        static const u32 sha224_init[] = {
                SHA224_H0, SHA224_H1, SHA224_H2, SHA224_H3,
                SHA224_H4, SHA224_H5, SHA224_H6, SHA224_H7
        };
        static const u32 sha1_init[] = {
                SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4
        };
        static const u32 md5_init[] = {
                MD5_H0, MD5_H1, MD5_H2, MD5_H3
        };

        /* Init HASH constant */
        switch (hash) {
        case EIP93_HASH_SHA256:
                memcpy(digest, sha256_init, sizeof(sha256_init));
                return;
        case EIP93_HASH_SHA224:
                memcpy(digest, sha224_init, sizeof(sha224_init));
                return;
        case EIP93_HASH_SHA1:
                memcpy(digest, sha1_init, sizeof(sha1_init));
                return;
        case EIP93_HASH_MD5:
                memcpy(digest, md5_init, sizeof(md5_init));
                return;
        default: /* Impossible */
                return;
        }
}

static void eip93_hash_export_sa_state(struct ahash_request *req,
                                       struct eip93_hash_export_state *state)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct sa_state *sa_state = &rctx->sa_state;

        /*
         * EIP93 have special handling for state_byte_cnt in sa_state.
         * Even if a zero packet is passed (and a BADMSG is returned),
         * state_byte_cnt is incremented to the digest handled (with the hash
         * primitive). This is problematic with export/import as EIP93
         * expect 0 state_byte_cnt for the very first iteration.
         */
        if (!rctx->len)
                memset(state->state_len, 0, sizeof(u32) * 2);
        else
                memcpy(state->state_len, sa_state->state_byte_cnt,
                       sizeof(u32) * 2);
        memcpy(state->state_hash, sa_state->state_i_digest,
               SHA256_DIGEST_SIZE);
        state->len = rctx->len;
        state->data_used = rctx->data_used;
}

static void __eip93_hash_init(struct ahash_request *req)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct sa_record *sa_record = &rctx->sa_record;
        int digestsize;

        digestsize = crypto_ahash_digestsize(ahash);

        eip93_set_sa_record(sa_record, 0, ctx->flags);
        sa_record->sa_cmd0_word |= EIP93_SA_CMD_HASH_FROM_STATE;
        sa_record->sa_cmd0_word |= EIP93_SA_CMD_SAVE_HASH;
        sa_record->sa_cmd0_word &= ~EIP93_SA_CMD_OPCODE;
        sa_record->sa_cmd0_word |= FIELD_PREP(EIP93_SA_CMD_OPCODE,
                                              EIP93_SA_CMD_OPCODE_BASIC_OUT_HASH);
        sa_record->sa_cmd0_word &= ~EIP93_SA_CMD_DIGEST_LENGTH;
        sa_record->sa_cmd0_word |= FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH,
                                              digestsize / sizeof(u32));

        /*
         * HMAC special handling
         * Enabling CMD_HMAC force the inner hash to be always finalized.
         * This cause problems on handling message > 64 byte as we
         * need to produce intermediate inner hash on sending intermediate
         * 64 bytes blocks.
         *
         * To handle this, enable CMD_HMAC only on the last block.
         * We make a duplicate of sa_record and on the last descriptor,
         * we pass a dedicated sa_record with CMD_HMAC enabled to make
         * EIP93 apply the outer hash.
         */
        if (IS_HMAC(ctx->flags)) {
                struct sa_record *sa_record_hmac = &rctx->sa_record_hmac;

                memcpy(sa_record_hmac, sa_record, sizeof(*sa_record));
                /* Copy pre-hashed opad for HMAC */
                memcpy(sa_record_hmac->sa_o_digest, ctx->opad, SHA256_DIGEST_SIZE);

                /* Disable HMAC for hash normal sa_record */
                sa_record->sa_cmd1_word &= ~EIP93_SA_CMD_HMAC;
        }

        rctx->len = 0;
        rctx->data_used = 0;
        rctx->partial_hash = false;
        rctx->finalize = false;
        INIT_LIST_HEAD(&rctx->blocks);
}

static int eip93_send_hash_req(struct crypto_async_request *async, u8 *data,
                               dma_addr_t *data_dma, u32 len, bool last)
{
        struct ahash_request *req = ahash_request_cast(async);
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct eip93_device *eip93 = ctx->eip93;
        struct eip93_descriptor cdesc = { };
        dma_addr_t src_addr;
        int ret;

        /* Map block data to DMA */
        src_addr = dma_map_single(eip93->dev, data, len, DMA_TO_DEVICE);
        ret = dma_mapping_error(eip93->dev, src_addr);
        if (ret)
                return ret;

        cdesc.pe_ctrl_stat_word = FIELD_PREP(EIP93_PE_CTRL_PE_READY_DES_TRING_OWN,
                                             EIP93_PE_CTRL_HOST_READY);
        cdesc.sa_addr = rctx->sa_record_base;
        cdesc.arc4_addr = 0;

        cdesc.state_addr = rctx->sa_state_base;
        cdesc.src_addr = src_addr;
        cdesc.pe_length_word = FIELD_PREP(EIP93_PE_LENGTH_HOST_PE_READY,
                                          EIP93_PE_LENGTH_HOST_READY);
        cdesc.pe_length_word |= FIELD_PREP(EIP93_PE_LENGTH_LENGTH,
                                           len);

        cdesc.user_id |= FIELD_PREP(EIP93_PE_USER_ID_DESC_FLAGS, EIP93_DESC_HASH);

        if (last) {
                int crypto_async_idr;

                if (rctx->finalize && !rctx->partial_hash) {
                        /* For last block, pass sa_record with CMD_HMAC enabled */
                        if (IS_HMAC(ctx->flags)) {
                                struct sa_record *sa_record_hmac = &rctx->sa_record_hmac;

                                rctx->sa_record_hmac_base = dma_map_single(eip93->dev,
                                                                           sa_record_hmac,
                                                                           sizeof(*sa_record_hmac),
                                                                           DMA_TO_DEVICE);
                                ret = dma_mapping_error(eip93->dev, rctx->sa_record_hmac_base);
                                if (ret)
                                        return ret;

                                cdesc.sa_addr = rctx->sa_record_hmac_base;
                        }

                        cdesc.pe_ctrl_stat_word |= EIP93_PE_CTRL_PE_HASH_FINAL;
                }

                scoped_guard(spinlock_bh, &eip93->ring->idr_lock)
                        crypto_async_idr = idr_alloc(&eip93->ring->crypto_async_idr, async, 0,
                                                     EIP93_RING_NUM - 1, GFP_ATOMIC);

                cdesc.user_id |= FIELD_PREP(EIP93_PE_USER_ID_CRYPTO_IDR, (u16)crypto_async_idr) |
                                 FIELD_PREP(EIP93_PE_USER_ID_DESC_FLAGS, EIP93_DESC_LAST);
        }

again:
        scoped_guard(spinlock_irqsave, &eip93->ring->write_lock)
                ret = eip93_put_descriptor(eip93, &cdesc);
        if (ret) {
                usleep_range(EIP93_RING_BUSY_DELAY,
                             EIP93_RING_BUSY_DELAY * 2);
                goto again;
        }

        /* Writing new descriptor count starts DMA action */
        writel(1, eip93->base + EIP93_REG_PE_CD_COUNT);

        *data_dma = src_addr;
        return 0;
}

static int eip93_hash_init(struct ahash_request *req)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct sa_state *sa_state = &rctx->sa_state;

        memset(sa_state->state_byte_cnt, 0, sizeof(u32) * 2);
        eip93_hash_init_sa_state_digest(ctx->flags & EIP93_HASH_MASK,
                                        sa_state->state_i_digest);

        __eip93_hash_init(req);

        /* For HMAC setup the initial block for ipad */
        if (IS_HMAC(ctx->flags)) {
                memcpy(rctx->data, ctx->ipad, SHA256_BLOCK_SIZE);

                rctx->data_used = SHA256_BLOCK_SIZE;
                rctx->len += SHA256_BLOCK_SIZE;
        }

        return 0;
}

/*
 * With complete_req true, we wait for the engine to consume all the block in list,
 * else we just queue the block to the engine as final() will wait. This is useful
 * for finup().
 */
static int __eip93_hash_update(struct ahash_request *req, bool complete_req)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_async_request *async = &req->base;
        unsigned int read, to_consume = req->nbytes;
        unsigned int max_read, consumed = 0;
        struct mkt_hash_block *block;
        bool wait_req = false;
        int offset;
        int ret;

        /* Get the offset and available space to fill req data */
        offset = rctx->data_used;
        max_read = SHA256_BLOCK_SIZE - offset;

        /* Consume req in block of SHA256_BLOCK_SIZE.
         * to_read is initially set to space available in the req data
         * and then reset to SHA256_BLOCK_SIZE.
         */
        while (to_consume > max_read) {
                block = kzalloc_obj(*block, GFP_ATOMIC);
                if (!block) {
                        ret = -ENOMEM;
                        goto free_blocks;
                }

                read = sg_pcopy_to_buffer(req->src, sg_nents(req->src),
                                          block->data + offset,
                                          max_read, consumed);

                /*
                 * For first iteration only, copy req data to block
                 * and reset offset and max_read for next iteration.
                 */
                if (offset > 0) {
                        memcpy(block->data, rctx->data, offset);
                        offset = 0;
                        max_read = SHA256_BLOCK_SIZE;
                }

                list_add(&block->list, &rctx->blocks);
                to_consume -= read;
                consumed += read;
        }

        /* Write the remaining data to req data */
        read = sg_pcopy_to_buffer(req->src, sg_nents(req->src),
                                  rctx->data + offset, to_consume,
                                  consumed);
        rctx->data_used = offset + read;

        /* Update counter with processed bytes */
        rctx->len += read + consumed;

        /* Consume all the block added to list */
        list_for_each_entry_reverse(block, &rctx->blocks, list) {
                wait_req = complete_req &&
                            list_is_first(&block->list, &rctx->blocks);

                ret = eip93_send_hash_req(async, block->data,
                                          &block->data_dma,
                                          SHA256_BLOCK_SIZE, wait_req);
                if (ret)
                        goto free_blocks;
        }

        return wait_req ? -EINPROGRESS : 0;

free_blocks:
        eip93_hash_free_data_blocks(req);

        return ret;
}

static int eip93_hash_update(struct ahash_request *req)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct sa_record *sa_record = &rctx->sa_record;
        struct sa_state *sa_state = &rctx->sa_state;
        struct eip93_device *eip93 = ctx->eip93;
        int ret;

        if (!req->nbytes)
                return 0;

        rctx->sa_state_base = dma_map_single(eip93->dev, sa_state,
                                             sizeof(*sa_state),
                                             DMA_TO_DEVICE);
        ret = dma_mapping_error(eip93->dev, rctx->sa_state_base);
        if (ret)
                return ret;

        rctx->sa_record_base = dma_map_single(eip93->dev, sa_record,
                                              sizeof(*sa_record),
                                              DMA_TO_DEVICE);
        ret = dma_mapping_error(eip93->dev, rctx->sa_record_base);
        if (ret)
                goto free_sa_state;

        ret = __eip93_hash_update(req, true);
        if (ret && ret != -EINPROGRESS)
                goto free_sa_record;

        return ret;

free_sa_record:
        dma_unmap_single(eip93->dev, rctx->sa_record_base,
                         sizeof(*sa_record), DMA_TO_DEVICE);

free_sa_state:
        dma_unmap_single(eip93->dev, rctx->sa_state_base,
                         sizeof(*sa_state), DMA_TO_DEVICE);

        return ret;
}

/*
 * With map_data true, we map the sa_record and sa_state. This is needed
 * for finup() as the they are mapped before calling update()
 */
static int __eip93_hash_final(struct ahash_request *req, bool map_dma)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct crypto_async_request *async = &req->base;
        struct sa_record *sa_record = &rctx->sa_record;
        struct sa_state *sa_state = &rctx->sa_state;
        struct eip93_device *eip93 = ctx->eip93;
        int ret;

        /* EIP93 can't handle zero bytes hash */
        if (!rctx->len && !IS_HMAC(ctx->flags)) {
                switch ((ctx->flags & EIP93_HASH_MASK)) {
                case EIP93_HASH_SHA256:
                        memcpy(req->result, sha256_zero_message_hash,
                               SHA256_DIGEST_SIZE);
                        break;
                case EIP93_HASH_SHA224:
                        memcpy(req->result, sha224_zero_message_hash,
                               SHA224_DIGEST_SIZE);
                        break;
                case EIP93_HASH_SHA1:
                        memcpy(req->result, sha1_zero_message_hash,
                               SHA1_DIGEST_SIZE);
                        break;
                case EIP93_HASH_MD5:
                        memcpy(req->result, md5_zero_message_hash,
                               MD5_DIGEST_SIZE);
                        break;
                default: /* Impossible */
                        return -EINVAL;
                }

                return 0;
        }

        /* Signal interrupt from engine is for last block */
        rctx->finalize = true;

        if (map_dma) {
                rctx->sa_state_base = dma_map_single(eip93->dev, sa_state,
                                                     sizeof(*sa_state),
                                                     DMA_TO_DEVICE);
                ret = dma_mapping_error(eip93->dev, rctx->sa_state_base);
                if (ret)
                        return ret;

                rctx->sa_record_base = dma_map_single(eip93->dev, sa_record,
                                                      sizeof(*sa_record),
                                                      DMA_TO_DEVICE);
                ret = dma_mapping_error(eip93->dev, rctx->sa_record_base);
                if (ret)
                        goto free_sa_state;
        }

        /* Send last block */
        ret = eip93_send_hash_req(async, rctx->data, &rctx->data_dma,
                                  rctx->data_used, true);
        if (ret)
                goto free_blocks;

        return -EINPROGRESS;

free_blocks:
        eip93_hash_free_data_blocks(req);

        dma_unmap_single(eip93->dev, rctx->sa_record_base,
                         sizeof(*sa_record), DMA_TO_DEVICE);

free_sa_state:
        dma_unmap_single(eip93->dev, rctx->sa_state_base,
                         sizeof(*sa_state), DMA_TO_DEVICE);

        return ret;
}

static int eip93_hash_final(struct ahash_request *req)
{
        return __eip93_hash_final(req, true);
}

static int eip93_hash_finup(struct ahash_request *req)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
        struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        struct sa_record *sa_record = &rctx->sa_record;
        struct sa_state *sa_state = &rctx->sa_state;
        struct eip93_device *eip93 = ctx->eip93;
        int ret;

        if (rctx->len + req->nbytes || IS_HMAC(ctx->flags)) {
                rctx->sa_state_base = dma_map_single(eip93->dev, sa_state,
                                                     sizeof(*sa_state),
                                                     DMA_TO_DEVICE);
                ret = dma_mapping_error(eip93->dev, rctx->sa_state_base);
                if (ret)
                        return ret;

                rctx->sa_record_base = dma_map_single(eip93->dev, sa_record,
                                                      sizeof(*sa_record),
                                                      DMA_TO_DEVICE);
                ret = dma_mapping_error(eip93->dev, rctx->sa_record_base);
                if (ret)
                        goto free_sa_state;

                ret = __eip93_hash_update(req, false);
                if (ret)
                        goto free_sa_record;
        }

        return __eip93_hash_final(req, false);

free_sa_record:
        dma_unmap_single(eip93->dev, rctx->sa_record_base,
                         sizeof(*sa_record), DMA_TO_DEVICE);
free_sa_state:
        dma_unmap_single(eip93->dev, rctx->sa_state_base,
                         sizeof(*sa_state), DMA_TO_DEVICE);

        return ret;
}

static int eip93_hash_hmac_setkey(struct crypto_ahash *ahash, const u8 *key,
                                  u32 keylen)
{
        unsigned int digestsize = crypto_ahash_digestsize(ahash);
        struct crypto_tfm *tfm = crypto_ahash_tfm(ahash);
        struct eip93_hash_ctx *ctx = crypto_tfm_ctx(tfm);

        return eip93_hmac_setkey(ctx->flags, key, keylen, digestsize,
                                 ctx->ipad, ctx->opad, true);
}

static int eip93_hash_cra_init(struct crypto_tfm *tfm)
{
        struct eip93_hash_ctx *ctx = crypto_tfm_ctx(tfm);
        struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg,
                                struct eip93_alg_template, alg.ahash.halg.base);

        crypto_ahash_set_reqsize_dma(__crypto_ahash_cast(tfm),
                                     sizeof(struct eip93_hash_reqctx));

        ctx->eip93 = tmpl->eip93;
        ctx->flags = tmpl->flags;

        return 0;
}

static int eip93_hash_digest(struct ahash_request *req)
{
        int ret;

        ret = eip93_hash_init(req);
        if (ret)
                return ret;

        return eip93_hash_finup(req);
}

static int eip93_hash_import(struct ahash_request *req, const void *in)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        const struct eip93_hash_export_state *state = in;
        struct sa_state *sa_state = &rctx->sa_state;

        memcpy(sa_state->state_byte_cnt, state->state_len, sizeof(u32) * 2);
        memcpy(sa_state->state_i_digest, state->state_hash, SHA256_DIGEST_SIZE);

        __eip93_hash_init(req);

        rctx->len = state->len;
        rctx->data_used = state->data_used;

        /* Skip copying data if we have nothing to copy */
        if (rctx->len)
                memcpy(rctx->data, state->data, rctx->data_used);

        return 0;
}

static int eip93_hash_export(struct ahash_request *req, void *out)
{
        struct eip93_hash_reqctx *rctx = ahash_request_ctx_dma(req);
        struct eip93_hash_export_state *state = out;

        /* Save the first block in state data */
        if (rctx->len)
                memcpy(state->data, rctx->data, rctx->data_used);

        eip93_hash_export_sa_state(req, state);

        return 0;
}

struct eip93_alg_template eip93_alg_md5 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_MD5,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = MD5_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "md5",
                                .cra_driver_name = "md5-eip93",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};

struct eip93_alg_template eip93_alg_sha1 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_SHA1,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = SHA1_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "sha1",
                                .cra_driver_name = "sha1-eip93",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = SHA1_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};

struct eip93_alg_template eip93_alg_sha224 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_SHA224,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = SHA224_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "sha224",
                                .cra_driver_name = "sha224-eip93",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = SHA224_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};

struct eip93_alg_template eip93_alg_sha256 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_SHA256,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = SHA256_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "sha256",
                                .cra_driver_name = "sha256-eip93",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = SHA256_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};

struct eip93_alg_template eip93_alg_hmac_md5 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_HMAC | EIP93_HASH_MD5,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .setkey = eip93_hash_hmac_setkey,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = MD5_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "hmac(md5)",
                                .cra_driver_name = "hmac(md5-eip93)",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};

struct eip93_alg_template eip93_alg_hmac_sha1 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA1,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .setkey = eip93_hash_hmac_setkey,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = SHA1_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "hmac(sha1)",
                                .cra_driver_name = "hmac(sha1-eip93)",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = SHA1_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};

struct eip93_alg_template eip93_alg_hmac_sha224 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA224,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .setkey = eip93_hash_hmac_setkey,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = SHA224_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "hmac(sha224)",
                                .cra_driver_name = "hmac(sha224-eip93)",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = SHA224_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};

struct eip93_alg_template eip93_alg_hmac_sha256 = {
        .type = EIP93_ALG_TYPE_HASH,
        .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA256,
        .alg.ahash = {
                .init = eip93_hash_init,
                .update = eip93_hash_update,
                .final = eip93_hash_final,
                .finup = eip93_hash_finup,
                .digest = eip93_hash_digest,
                .setkey = eip93_hash_hmac_setkey,
                .export = eip93_hash_export,
                .import = eip93_hash_import,
                .halg = {
                        .digestsize = SHA256_DIGEST_SIZE,
                        .statesize = sizeof(struct eip93_hash_export_state),
                        .base = {
                                .cra_name = "hmac(sha256)",
                                .cra_driver_name = "hmac(sha256-eip93)",
                                .cra_priority = 300,
                                .cra_flags = CRYPTO_ALG_ASYNC |
                                                CRYPTO_ALG_KERN_DRIVER_ONLY |
                                                CRYPTO_ALG_ALLOCATES_MEMORY,
                                .cra_blocksize = SHA256_BLOCK_SIZE,
                                .cra_ctxsize = sizeof(struct eip93_hash_ctx),
                                .cra_init = eip93_hash_cra_init,
                                .cra_module = THIS_MODULE,
                        },
                },
        },
};