brintos

brintos / linux-shallow public Read only

0
0
Text · 10.8 KiB · 3b5c2af Raw
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