linux/drivers/crypto/caam/caamhash_desc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
   2/*
   3 * Shared descriptors for ahash algorithms
   4 *
   5 * Copyright 2017-2019 NXP
   6 */
   7
   8#include "compat.h"
   9#include "desc_constr.h"
  10#include "caamhash_desc.h"
  11
  12/**
  13 * cnstr_shdsc_ahash - ahash shared descriptor
  14 * @desc: pointer to buffer used for descriptor construction
  15 * @adata: pointer to authentication transform definitions.
  16 *         A split key is required for SEC Era < 6; the size of the split key
  17 *         is specified in this case.
  18 *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
  19 *         SHA256, SHA384, SHA512}.
  20 * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
  21 * @digestsize: algorithm's digest size
  22 * @ctx_len: size of Context Register
  23 * @import_ctx: true if previous Context Register needs to be restored
  24 *              must be true for ahash update and final
  25 *              must be false for for ahash first and digest
  26 * @era: SEC Era
  27 */
  28void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
  29                       int digestsize, int ctx_len, bool import_ctx, int era)
  30{
  31        u32 op = adata->algtype;
  32
  33        init_sh_desc(desc, HDR_SHARE_SERIAL);
  34
  35        /* Append key if it has been set; ahash update excluded */
  36        if (state != OP_ALG_AS_UPDATE && adata->keylen) {
  37                u32 *skip_key_load;
  38
  39                /* Skip key loading if already shared */
  40                skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  41                                            JUMP_COND_SHRD);
  42
  43                if (era < 6)
  44                        append_key_as_imm(desc, adata->key_virt,
  45                                          adata->keylen_pad,
  46                                          adata->keylen, CLASS_2 |
  47                                          KEY_DEST_MDHA_SPLIT | KEY_ENC);
  48                else
  49                        append_proto_dkp(desc, adata);
  50
  51                set_jump_tgt_here(desc, skip_key_load);
  52
  53                op |= OP_ALG_AAI_HMAC_PRECOMP;
  54        }
  55
  56        /* If needed, import context from software */
  57        if (import_ctx)
  58                append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB |
  59                                LDST_SRCDST_BYTE_CONTEXT);
  60
  61        /* Class 2 operation */
  62        append_operation(desc, op | state | OP_ALG_ENCRYPT);
  63
  64        /*
  65         * Load from buf and/or src and write to req->result or state->context
  66         * Calculate remaining bytes to read
  67         */
  68        append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
  69        /* Read remaining bytes */
  70        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
  71                             FIFOLD_TYPE_MSG | KEY_VLF);
  72        /* Store class2 context bytes */
  73        append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
  74                         LDST_SRCDST_BYTE_CONTEXT);
  75}
  76EXPORT_SYMBOL(cnstr_shdsc_ahash);
  77
  78/**
  79 * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based
  80 *                       hash algorithms
  81 * @desc: pointer to buffer used for descriptor construction
  82 * @adata: pointer to authentication transform definitions.
  83 * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
  84 * @digestsize: algorithm's digest size
  85 * @ctx_len: size of Context Register
  86 * @key_dma: I/O Virtual Address of the key
  87 */
  88void cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state,
  89                         int digestsize, int ctx_len, dma_addr_t key_dma)
  90{
  91        u32 *skip_key_load;
  92
  93        init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
  94
  95        /* Skip loading of key, context if already shared */
  96        skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
  97
  98        if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) {
  99                append_key_as_imm(desc, adata->key_virt, adata->keylen,
 100                                  adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
 101        } else { /* UPDATE, FINALIZE */
 102                if (is_xcbc_aes(adata->algtype))
 103                        /* Load K1 */
 104                        append_key(desc, adata->key_dma, adata->keylen,
 105                                   CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
 106                else /* CMAC */
 107                        append_key_as_imm(desc, adata->key_virt, adata->keylen,
 108                                          adata->keylen, CLASS_1 |
 109                                          KEY_DEST_CLASS_REG);
 110                /* Restore context */
 111                append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB |
 112                                LDST_SRCDST_BYTE_CONTEXT);
 113        }
 114
 115        set_jump_tgt_here(desc, skip_key_load);
 116
 117        /* Class 1 operation */
 118        append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT);
 119
 120        /*
 121         * Load from buf and/or src and write to req->result or state->context
 122         * Calculate remaining bytes to read
 123         */
 124        append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 125
 126        /* Read remaining bytes */
 127        append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
 128                             FIFOLD_TYPE_MSG | FIFOLDST_VLF);
 129
 130        /*
 131         * Save context:
 132         * - xcbc: partial hash, keys K2 and K3
 133         * - cmac: partial hash, constant L = E(K,0)
 134         */
 135        append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
 136                         LDST_SRCDST_BYTE_CONTEXT);
 137        if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT)
 138                /* Save K1 */
 139                append_fifo_store(desc, key_dma, adata->keylen,
 140                                  LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK);
 141}
 142EXPORT_SYMBOL(cnstr_shdsc_sk_hash);
 143
 144MODULE_LICENSE("Dual BSD/GPL");
 145MODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
 146MODULE_AUTHOR("NXP Semiconductors");
 147