394 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * sun8i-ce.h - hardware cryptographic offloader for4 * Allwinner H3/A64/H5/H2+/H6 SoC5 *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/skcipher.h>12#include <linux/atomic.h>13#include <linux/debugfs.h>14#include <linux/crypto.h>15#include <linux/hw_random.h>16#include <crypto/internal/hash.h>17#include <crypto/md5.h>18#include <crypto/rng.h>19#include <crypto/sha1.h>20#include <crypto/sha2.h>21 22/* CE Registers */23#define CE_TDQ 0x0024#define CE_CTR 0x0425#define CE_ICR 0x0826#define CE_ISR 0x0C27#define CE_TLR 0x1028#define CE_TSR 0x1429#define CE_ESR 0x1830#define CE_CSSGR 0x1C31#define CE_CDSGR 0x2032#define CE_CSAR 0x2433#define CE_CDAR 0x2834#define CE_TPR 0x2C35 36/* Used in struct ce_task */37/* ce_task common */38#define CE_ENCRYPTION 039#define CE_DECRYPTION BIT(8)40 41#define CE_COMM_INT BIT(31)42 43/* ce_task symmetric */44#define CE_AES_128BITS 045#define CE_AES_192BITS 146#define CE_AES_256BITS 247 48#define CE_OP_ECB 049#define CE_OP_CBC (1 << 8)50 51#define CE_ALG_AES 052#define CE_ALG_DES 153#define CE_ALG_3DES 254#define CE_ALG_MD5 1655#define CE_ALG_SHA1 1756#define CE_ALG_SHA224 1857#define CE_ALG_SHA256 1958#define CE_ALG_SHA384 2059#define CE_ALG_SHA512 2160#define CE_ALG_TRNG 4861#define CE_ALG_PRNG 4962#define CE_ALG_TRNG_V2 0x1c63#define CE_ALG_PRNG_V2 0x1d64 65/* Used in ce_variant */66#define CE_ID_NOTSUPP 0xFF67 68#define CE_ID_CIPHER_AES 069#define CE_ID_CIPHER_DES 170#define CE_ID_CIPHER_DES3 271#define CE_ID_CIPHER_MAX 372 73#define CE_ID_HASH_MD5 074#define CE_ID_HASH_SHA1 175#define CE_ID_HASH_SHA224 276#define CE_ID_HASH_SHA256 377#define CE_ID_HASH_SHA384 478#define CE_ID_HASH_SHA512 579#define CE_ID_HASH_MAX 680 81#define CE_ID_OP_ECB 082#define CE_ID_OP_CBC 183#define CE_ID_OP_MAX 284 85/* Used in CE registers */86#define CE_ERR_ALGO_NOTSUP BIT(0)87#define CE_ERR_DATALEN BIT(1)88#define CE_ERR_KEYSRAM BIT(2)89#define CE_ERR_ADDR_INVALID BIT(5)90#define CE_ERR_KEYLADDER BIT(6)91 92#define ESR_H3 093#define ESR_A64 194#define ESR_R40 295#define ESR_H5 396#define ESR_H6 497#define ESR_D1 598 99#define PRNG_DATA_SIZE (160 / 8)100#define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8)101#define PRNG_LD BIT(17)102 103#define CE_DIE_ID_SHIFT 16104#define CE_DIE_ID_MASK 0x07105 106#define MAX_SG 8107 108#define CE_MAX_CLOCKS 4109 110#define MAXFLOW 4111 112/*113 * struct ce_clock - Describe clocks used by sun8i-ce114 * @name: Name of clock needed by this variant115 * @freq: Frequency to set for each clock116 * @max_freq: Maximum frequency for each clock (generally given by datasheet)117 */118struct ce_clock {119 const char *name;120 unsigned long freq;121 unsigned long max_freq;122};123 124/*125 * struct ce_variant - Describe CE capability for each variant hardware126 * @alg_cipher: list of supported ciphers. for each CE_ID_ this will give the127 * coresponding CE_ALG_XXX value128 * @alg_hash: list of supported hashes. for each CE_ID_ this will give the129 * corresponding CE_ALG_XXX value130 * @op_mode: list of supported block modes131 * @cipher_t_dlen_in_bytes: Does the request size for cipher is in132 * bytes or words133 * @hash_t_dlen_in_bytes: Does the request size for hash is in134 * bits or words135 * @prng_t_dlen_in_bytes: Does the request size for PRNG is in136 * bytes or words137 * @trng_t_dlen_in_bytes: Does the request size for TRNG is in138 * bytes or words139 * @ce_clks: list of clocks needed by this variant140 * @esr: The type of error register141 * @prng: The CE_ALG_XXX value for the PRNG142 * @trng: The CE_ALG_XXX value for the TRNG143 */144struct ce_variant {145 char alg_cipher[CE_ID_CIPHER_MAX];146 char alg_hash[CE_ID_HASH_MAX];147 u32 op_mode[CE_ID_OP_MAX];148 bool cipher_t_dlen_in_bytes;149 bool hash_t_dlen_in_bits;150 bool prng_t_dlen_in_bytes;151 bool trng_t_dlen_in_bytes;152 bool needs_word_addresses;153 struct ce_clock ce_clks[CE_MAX_CLOCKS];154 int esr;155 unsigned char prng;156 unsigned char trng;157};158 159struct sginfo {160 __le32 addr;161 __le32 len;162} __packed;163 164/*165 * struct ce_task - CE Task descriptor166 * The structure of this descriptor could be found in the datasheet167 */168struct ce_task {169 __le32 t_id;170 __le32 t_common_ctl;171 __le32 t_sym_ctl;172 __le32 t_asym_ctl;173 __le32 t_key;174 __le32 t_iv;175 __le32 t_ctr;176 __le32 t_dlen;177 struct sginfo t_src[MAX_SG];178 struct sginfo t_dst[MAX_SG];179 __le32 next;180 __le32 reserved[3];181} __packed __aligned(8);182 183/*184 * struct sun8i_ce_flow - Information used by each flow185 * @engine: ptr to the crypto_engine for this flow186 * @complete: completion for the current task on this flow187 * @status: set to 1 by interrupt if task is done188 * @t_phy: Physical address of task189 * @tl: pointer to the current ce_task for this flow190 * @backup_iv: buffer which contain the next IV to store191 * @bounce_iv: buffer which contain the IV192 * @stat_req: number of request done by this flow193 */194struct sun8i_ce_flow {195 struct crypto_engine *engine;196 struct completion complete;197 int status;198 dma_addr_t t_phy;199 int timeout;200 struct ce_task *tl;201 void *backup_iv;202 void *bounce_iv;203#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG204 unsigned long stat_req;205#endif206};207 208/*209 * struct sun8i_ce_dev - main container for all this driver information210 * @base: base address of CE211 * @ceclks: clocks used by CE212 * @reset: pointer to reset controller213 * @dev: the platform device214 * @mlock: Control access to device registers215 * @rnglock: Control access to the RNG (dedicated channel 3)216 * @chanlist: array of all flow217 * @flow: flow to use in next request218 * @variant: pointer to variant specific data219 * @dbgfs_dir: Debugfs dentry for statistic directory220 * @dbgfs_stats: Debugfs dentry for statistic counters221 */222struct sun8i_ce_dev {223 void __iomem *base;224 struct clk *ceclks[CE_MAX_CLOCKS];225 struct reset_control *reset;226 struct device *dev;227 struct mutex mlock;228 struct mutex rnglock;229 struct sun8i_ce_flow *chanlist;230 atomic_t flow;231 const struct ce_variant *variant;232#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG233 struct dentry *dbgfs_dir;234 struct dentry *dbgfs_stats;235#endif236#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG237 struct hwrng trng;238#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG239 unsigned long hwrng_stat_req;240 unsigned long hwrng_stat_bytes;241#endif242#endif243};244 245static inline u32 desc_addr_val(struct sun8i_ce_dev *dev, dma_addr_t addr)246{247 if (dev->variant->needs_word_addresses)248 return addr / 4;249 250 return addr;251}252 253static inline __le32 desc_addr_val_le32(struct sun8i_ce_dev *dev,254 dma_addr_t addr)255{256 return cpu_to_le32(desc_addr_val(dev, addr));257}258 259/*260 * struct sun8i_cipher_req_ctx - context for a skcipher request261 * @op_dir: direction (encrypt vs decrypt) for this request262 * @flow: the flow to use for this request263 * @ivlen: size of bounce_iv264 * @nr_sgs: The number of source SG (as given by dma_map_sg())265 * @nr_sgd: The number of destination SG (as given by dma_map_sg())266 * @addr_iv: The IV addr returned by dma_map_single, need to unmap later267 * @addr_key: The key addr returned by dma_map_single, need to unmap later268 * @fallback_req: request struct for invoking the fallback skcipher TFM269 */270struct sun8i_cipher_req_ctx {271 u32 op_dir;272 int flow;273 unsigned int ivlen;274 int nr_sgs;275 int nr_sgd;276 dma_addr_t addr_iv;277 dma_addr_t addr_key;278 struct skcipher_request fallback_req; // keep at the end279};280 281/*282 * struct sun8i_cipher_tfm_ctx - context for a skcipher TFM283 * @key: pointer to key data284 * @keylen: len of the key285 * @ce: pointer to the private data of driver handling this TFM286 * @fallback_tfm: pointer to the fallback TFM287 */288struct sun8i_cipher_tfm_ctx {289 u32 *key;290 u32 keylen;291 struct sun8i_ce_dev *ce;292 struct crypto_skcipher *fallback_tfm;293};294 295/*296 * struct sun8i_ce_hash_tfm_ctx - context for an ahash TFM297 * @ce: pointer to the private data of driver handling this TFM298 * @fallback_tfm: pointer to the fallback TFM299 */300struct sun8i_ce_hash_tfm_ctx {301 struct sun8i_ce_dev *ce;302 struct crypto_ahash *fallback_tfm;303};304 305/*306 * struct sun8i_ce_hash_reqctx - context for an ahash request307 * @fallback_req: pre-allocated fallback request308 * @flow: the flow to use for this request309 */310struct sun8i_ce_hash_reqctx {311 struct ahash_request fallback_req;312 int flow;313};314 315/*316 * struct sun8i_ce_prng_ctx - context for PRNG TFM317 * @seed: The seed to use318 * @slen: The size of the seed319 */320struct sun8i_ce_rng_tfm_ctx {321 void *seed;322 unsigned int slen;323};324 325/*326 * struct sun8i_ce_alg_template - crypto_alg template327 * @type: the CRYPTO_ALG_TYPE for this template328 * @ce_algo_id: the CE_ID for this template329 * @ce_blockmode: the type of block operation CE_ID330 * @ce: pointer to the sun8i_ce_dev structure associated with331 * this template332 * @alg: one of sub struct must be used333 * @stat_req: number of request done on this template334 * @stat_fb: number of request which has fallbacked335 * @stat_bytes: total data size done by this template336 */337struct sun8i_ce_alg_template {338 u32 type;339 u32 ce_algo_id;340 u32 ce_blockmode;341 struct sun8i_ce_dev *ce;342 union {343 struct skcipher_engine_alg skcipher;344 struct ahash_engine_alg hash;345 struct rng_alg rng;346 } alg;347 unsigned long stat_req;348 unsigned long stat_fb;349 unsigned long stat_bytes;350 unsigned long stat_fb_maxsg;351 unsigned long stat_fb_leniv;352 unsigned long stat_fb_len0;353 unsigned long stat_fb_mod16;354 unsigned long stat_fb_srcali;355 unsigned long stat_fb_srclen;356 unsigned long stat_fb_dstali;357 unsigned long stat_fb_dstlen;358 char fbname[CRYPTO_MAX_ALG_NAME];359};360 361int sun8i_ce_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,362 unsigned int keylen);363int sun8i_ce_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,364 unsigned int keylen);365int sun8i_ce_cipher_init(struct crypto_tfm *tfm);366void sun8i_ce_cipher_exit(struct crypto_tfm *tfm);367int sun8i_ce_cipher_do_one(struct crypto_engine *engine, void *areq);368int sun8i_ce_skdecrypt(struct skcipher_request *areq);369int sun8i_ce_skencrypt(struct skcipher_request *areq);370 371int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce);372 373int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name);374 375int sun8i_ce_hash_init_tfm(struct crypto_ahash *tfm);376void sun8i_ce_hash_exit_tfm(struct crypto_ahash *tfm);377int sun8i_ce_hash_init(struct ahash_request *areq);378int sun8i_ce_hash_export(struct ahash_request *areq, void *out);379int sun8i_ce_hash_import(struct ahash_request *areq, const void *in);380int sun8i_ce_hash_final(struct ahash_request *areq);381int sun8i_ce_hash_update(struct ahash_request *areq);382int sun8i_ce_hash_finup(struct ahash_request *areq);383int sun8i_ce_hash_digest(struct ahash_request *areq);384int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq);385 386int sun8i_ce_prng_generate(struct crypto_rng *tfm, const u8 *src,387 unsigned int slen, u8 *dst, unsigned int dlen);388int sun8i_ce_prng_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);389void sun8i_ce_prng_exit(struct crypto_tfm *tfm);390int sun8i_ce_prng_init(struct crypto_tfm *tfm);391 392int sun8i_ce_hwrng_register(struct sun8i_ce_dev *ce);393void sun8i_ce_hwrng_unregister(struct sun8i_ce_dev *ce);394