linux/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * sun8i-ss.h - hardware cryptographic offloader for
   4 * Allwinner A80/A83T SoC
   5 *
   6 * Copyright (C) 2016-2019 Corentin LABBE <clabbe.montjoie@gmail.com>
   7 */
   8#include <crypto/aes.h>
   9#include <crypto/des.h>
  10#include <crypto/engine.h>
  11#include <crypto/rng.h>
  12#include <crypto/skcipher.h>
  13#include <linux/atomic.h>
  14#include <linux/debugfs.h>
  15#include <linux/crypto.h>
  16#include <crypto/internal/hash.h>
  17#include <crypto/md5.h>
  18#include <crypto/sha1.h>
  19#include <crypto/sha2.h>
  20
  21#define SS_START        1
  22
  23#define SS_ENCRYPTION           0
  24#define SS_DECRYPTION           BIT(6)
  25
  26#define SS_ALG_AES              0
  27#define SS_ALG_DES              (1 << 2)
  28#define SS_ALG_3DES             (2 << 2)
  29#define SS_ALG_MD5              (3 << 2)
  30#define SS_ALG_PRNG             (4 << 2)
  31#define SS_ALG_SHA1             (6 << 2)
  32#define SS_ALG_SHA224           (7 << 2)
  33#define SS_ALG_SHA256           (8 << 2)
  34
  35#define SS_CTL_REG              0x00
  36#define SS_INT_CTL_REG          0x04
  37#define SS_INT_STA_REG          0x08
  38#define SS_KEY_ADR_REG          0x10
  39#define SS_IV_ADR_REG           0x18
  40#define SS_SRC_ADR_REG          0x20
  41#define SS_DST_ADR_REG          0x28
  42#define SS_LEN_ADR_REG          0x30
  43
  44#define SS_ID_NOTSUPP           0xFF
  45
  46#define SS_ID_CIPHER_AES        0
  47#define SS_ID_CIPHER_DES        1
  48#define SS_ID_CIPHER_DES3       2
  49#define SS_ID_CIPHER_MAX        3
  50
  51#define SS_ID_OP_ECB    0
  52#define SS_ID_OP_CBC    1
  53#define SS_ID_OP_MAX    2
  54
  55#define SS_AES_128BITS 0
  56#define SS_AES_192BITS 1
  57#define SS_AES_256BITS 2
  58
  59#define SS_OP_ECB       0
  60#define SS_OP_CBC       (1 << 13)
  61
  62#define SS_ID_HASH_MD5  0
  63#define SS_ID_HASH_SHA1 1
  64#define SS_ID_HASH_SHA224       2
  65#define SS_ID_HASH_SHA256       3
  66#define SS_ID_HASH_MAX  4
  67
  68#define SS_FLOW0        BIT(30)
  69#define SS_FLOW1        BIT(31)
  70
  71#define SS_PRNG_CONTINUE        BIT(18)
  72
  73#define MAX_SG 8
  74
  75#define MAXFLOW 2
  76
  77#define SS_MAX_CLOCKS 2
  78
  79#define SS_DIE_ID_SHIFT 20
  80#define SS_DIE_ID_MASK  0x07
  81
  82#define PRNG_DATA_SIZE (160 / 8)
  83#define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8)
  84
  85/*
  86 * struct ss_clock - Describe clocks used by sun8i-ss
  87 * @name:       Name of clock needed by this variant
  88 * @freq:       Frequency to set for each clock
  89 * @max_freq:   Maximum frequency for each clock
  90 */
  91struct ss_clock {
  92        const char *name;
  93        unsigned long freq;
  94        unsigned long max_freq;
  95};
  96
  97/*
  98 * struct ss_variant - Describe SS capability for each variant hardware
  99 * @alg_cipher: list of supported ciphers. for each SS_ID_ this will give the
 100 *              coresponding SS_ALG_XXX value
 101 * @alg_hash:   list of supported hashes. for each SS_ID_ this will give the
 102 *              corresponding SS_ALG_XXX value
 103 * @op_mode:    list of supported block modes
 104 * @ss_clks:    list of clock needed by this variant
 105 */
 106struct ss_variant {
 107        char alg_cipher[SS_ID_CIPHER_MAX];
 108        char alg_hash[SS_ID_HASH_MAX];
 109        u32 op_mode[SS_ID_OP_MAX];
 110        struct ss_clock ss_clks[SS_MAX_CLOCKS];
 111};
 112
 113struct sginfo {
 114        u32 addr;
 115        u32 len;
 116};
 117
 118/*
 119 * struct sun8i_ss_flow - Information used by each flow
 120 * @engine:     ptr to the crypto_engine for this flow
 121 * @complete:   completion for the current task on this flow
 122 * @status:     set to 1 by interrupt if task is done
 123 * @stat_req:   number of request done by this flow
 124 */
 125struct sun8i_ss_flow {
 126        struct crypto_engine *engine;
 127        struct completion complete;
 128        int status;
 129#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
 130        unsigned long stat_req;
 131#endif
 132};
 133
 134/*
 135 * struct sun8i_ss_dev - main container for all this driver information
 136 * @base:       base address of SS
 137 * @ssclks:     clocks used by SS
 138 * @reset:      pointer to reset controller
 139 * @dev:        the platform device
 140 * @mlock:      Control access to device registers
 141 * @flows:      array of all flow
 142 * @flow:       flow to use in next request
 143 * @variant:    pointer to variant specific data
 144 * @dbgfs_dir:  Debugfs dentry for statistic directory
 145 * @dbgfs_stats: Debugfs dentry for statistic counters
 146 */
 147struct sun8i_ss_dev {
 148        void __iomem *base;
 149        struct clk *ssclks[SS_MAX_CLOCKS];
 150        struct reset_control *reset;
 151        struct device *dev;
 152        struct mutex mlock;
 153        struct sun8i_ss_flow *flows;
 154        atomic_t flow;
 155        const struct ss_variant *variant;
 156#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
 157        struct dentry *dbgfs_dir;
 158        struct dentry *dbgfs_stats;
 159#endif
 160};
 161
 162/*
 163 * struct sun8i_cipher_req_ctx - context for a skcipher request
 164 * @t_src:              list of mapped SGs with their size
 165 * @t_dst:              list of mapped SGs with their size
 166 * @p_key:              DMA address of the key
 167 * @p_iv:               DMA address of the IV
 168 * @method:             current algorithm for this request
 169 * @op_mode:            op_mode for this request
 170 * @op_dir:             direction (encrypt vs decrypt) for this request
 171 * @flow:               the flow to use for this request
 172 * @ivlen:              size of biv
 173 * @keylen:             keylen for this request
 174 * @biv:                buffer which contain the IV
 175 * @fallback_req:       request struct for invoking the fallback skcipher TFM
 176 */
 177struct sun8i_cipher_req_ctx {
 178        struct sginfo t_src[MAX_SG];
 179        struct sginfo t_dst[MAX_SG];
 180        u32 p_key;
 181        u32 p_iv;
 182        u32 method;
 183        u32 op_mode;
 184        u32 op_dir;
 185        int flow;
 186        unsigned int ivlen;
 187        unsigned int keylen;
 188        void *biv;
 189        struct skcipher_request fallback_req;   // keep at the end
 190};
 191
 192/*
 193 * struct sun8i_cipher_tfm_ctx - context for a skcipher TFM
 194 * @enginectx:          crypto_engine used by this TFM
 195 * @key:                pointer to key data
 196 * @keylen:             len of the key
 197 * @ss:                 pointer to the private data of driver handling this TFM
 198 * @fallback_tfm:       pointer to the fallback TFM
 199 *
 200 * enginectx must be the first element
 201 */
 202struct sun8i_cipher_tfm_ctx {
 203        struct crypto_engine_ctx enginectx;
 204        u32 *key;
 205        u32 keylen;
 206        struct sun8i_ss_dev *ss;
 207        struct crypto_skcipher *fallback_tfm;
 208};
 209
 210/*
 211 * struct sun8i_ss_prng_ctx - context for PRNG TFM
 212 * @seed:       The seed to use
 213 * @slen:       The size of the seed
 214 */
 215struct sun8i_ss_rng_tfm_ctx {
 216        void *seed;
 217        unsigned int slen;
 218};
 219
 220/*
 221 * struct sun8i_ss_hash_tfm_ctx - context for an ahash TFM
 222 * @enginectx:          crypto_engine used by this TFM
 223 * @fallback_tfm:       pointer to the fallback TFM
 224 * @ss:                 pointer to the private data of driver handling this TFM
 225 *
 226 * enginectx must be the first element
 227 */
 228struct sun8i_ss_hash_tfm_ctx {
 229        struct crypto_engine_ctx enginectx;
 230        struct crypto_ahash *fallback_tfm;
 231        struct sun8i_ss_dev *ss;
 232};
 233
 234/*
 235 * struct sun8i_ss_hash_reqctx - context for an ahash request
 236 * @t_src:      list of DMA address and size for source SGs
 237 * @t_dst:      list of DMA address and size for destination SGs
 238 * @fallback_req:       pre-allocated fallback request
 239 * @method:     the register value for the algorithm used by this request
 240 * @flow:       the flow to use for this request
 241 */
 242struct sun8i_ss_hash_reqctx {
 243        struct sginfo t_src[MAX_SG];
 244        struct sginfo t_dst[MAX_SG];
 245        struct ahash_request fallback_req;
 246        u32 method;
 247        int flow;
 248};
 249
 250/*
 251 * struct sun8i_ss_alg_template - crypto_alg template
 252 * @type:               the CRYPTO_ALG_TYPE for this template
 253 * @ss_algo_id:         the SS_ID for this template
 254 * @ss_blockmode:       the type of block operation SS_ID
 255 * @ss:                 pointer to the sun8i_ss_dev structure associated with
 256 *                      this template
 257 * @alg:                one of sub struct must be used
 258 * @stat_req:           number of request done on this template
 259 * @stat_fb:            number of request which has fallbacked
 260 * @stat_bytes:         total data size done by this template
 261 */
 262struct sun8i_ss_alg_template {
 263        u32 type;
 264        u32 ss_algo_id;
 265        u32 ss_blockmode;
 266        struct sun8i_ss_dev *ss;
 267        union {
 268                struct skcipher_alg skcipher;
 269                struct rng_alg rng;
 270                struct ahash_alg hash;
 271        } alg;
 272#ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
 273        unsigned long stat_req;
 274        unsigned long stat_fb;
 275        unsigned long stat_bytes;
 276#endif
 277};
 278
 279int sun8i_ss_enqueue(struct crypto_async_request *areq, u32 type);
 280
 281int sun8i_ss_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
 282                        unsigned int keylen);
 283int sun8i_ss_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,
 284                         unsigned int keylen);
 285int sun8i_ss_cipher_init(struct crypto_tfm *tfm);
 286void sun8i_ss_cipher_exit(struct crypto_tfm *tfm);
 287int sun8i_ss_skdecrypt(struct skcipher_request *areq);
 288int sun8i_ss_skencrypt(struct skcipher_request *areq);
 289
 290int sun8i_ss_get_engine_number(struct sun8i_ss_dev *ss);
 291
 292int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx, const char *name);
 293int sun8i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
 294                           unsigned int slen, u8 *dst, unsigned int dlen);
 295int sun8i_ss_prng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);
 296int sun8i_ss_prng_init(struct crypto_tfm *tfm);
 297void sun8i_ss_prng_exit(struct crypto_tfm *tfm);
 298
 299int sun8i_ss_hash_crainit(struct crypto_tfm *tfm);
 300void sun8i_ss_hash_craexit(struct crypto_tfm *tfm);
 301int sun8i_ss_hash_init(struct ahash_request *areq);
 302int sun8i_ss_hash_export(struct ahash_request *areq, void *out);
 303int sun8i_ss_hash_import(struct ahash_request *areq, const void *in);
 304int sun8i_ss_hash_final(struct ahash_request *areq);
 305int sun8i_ss_hash_update(struct ahash_request *areq);
 306int sun8i_ss_hash_finup(struct ahash_request *areq);
 307int sun8i_ss_hash_digest(struct ahash_request *areq);
 308int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq);
 309