2474 lines · 66.2 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * K3 SA2UL crypto accelerator driver * * Copyright (C) 2018-2020 Texas Instruments Incorporated - http://www.ti.com * * Authors:	Keerthy *		Vitaly Andrianov *		Tero Kristo */#include <linux/bitfield.h>#include <linux/clk.h>#include <linux/dma-mapping.h>#include <linux/dmaengine.h>#include <linux/dmapool.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/of.h>#include <linux/of_platform.h>#include <linux/platform_device.h>#include <linux/pm_runtime.h> #include <crypto/aes.h>#include <crypto/authenc.h>#include <crypto/utils.h>#include <crypto/des.h>#include <crypto/internal/aead.h>#include <crypto/internal/hash.h>#include <crypto/internal/skcipher.h>#include <crypto/scatterwalk.h>#include <crypto/sha1.h>#include <crypto/sha2.h> #include "sa2ul.h" /* Byte offset for key in encryption security context */#define SC_ENC_KEY_OFFSET (1 + 27 + 4)/* Byte offset for Aux-1 in encryption security context */#define SC_ENC_AUX1_OFFSET (1 + 27 + 4 + 32) #define SA_CMDL_UPD_ENC         0x0001#define SA_CMDL_UPD_AUTH        0x0002#define SA_CMDL_UPD_ENC_IV      0x0004#define SA_CMDL_UPD_AUTH_IV     0x0008#define SA_CMDL_UPD_AUX_KEY     0x0010 #define SA_AUTH_SUBKEY_LEN	16#define SA_CMDL_PAYLOAD_LENGTH_MASK	0xFFFF#define SA_CMDL_SOP_BYPASS_LEN_MASK	0xFF000000 #define MODE_CONTROL_BYTES	27#define SA_HASH_PROCESSING	0#define SA_CRYPTO_PROCESSING	0#define SA_UPLOAD_HASH_TO_TLR	BIT(6) #define SA_SW0_FLAGS_MASK	0xF0000#define SA_SW0_CMDL_INFO_MASK	0x1F00000#define SA_SW0_CMDL_PRESENT	BIT(4)#define SA_SW0_ENG_ID_MASK	0x3E000000#define SA_SW0_DEST_INFO_PRESENT	BIT(30)#define SA_SW2_EGRESS_LENGTH		0xFF000000#define SA_BASIC_HASH		0x10 #define SHA256_DIGEST_WORDS    8/* Make 32-bit word from 4 bytes */#define SA_MK_U32(b0, b1, b2, b3) (((b0) << 24) | ((b1) << 16) | \				   ((b2) << 8) | (b3)) /* size of SCCTL structure in bytes */#define SA_SCCTL_SZ 16 /* Max Authentication tag size */#define SA_MAX_AUTH_TAG_SZ 64 enum sa_algo_id {	SA_ALG_CBC_AES = 0,	SA_ALG_EBC_AES,	SA_ALG_CBC_DES3,	SA_ALG_ECB_DES3,	SA_ALG_SHA1,	SA_ALG_SHA256,	SA_ALG_SHA512,	SA_ALG_AUTHENC_SHA1_AES,	SA_ALG_AUTHENC_SHA256_AES,}; struct sa_match_data {	u8 priv;	u8 priv_id;	u32 supported_algos;}; static struct device *sa_k3_dev; /** * struct sa_cmdl_cfg - Command label configuration descriptor * @aalg: authentication algorithm ID * @enc_eng_id: Encryption Engine ID supported by the SA hardware * @auth_eng_id: Authentication Engine ID * @iv_size: Initialization Vector size * @akey: Authentication key * @akey_len: Authentication key length * @enc: True, if this is an encode request */struct sa_cmdl_cfg {	int aalg;	u8 enc_eng_id;	u8 auth_eng_id;	u8 iv_size;	const u8 *akey;	u16 akey_len;	bool enc;}; /** * struct algo_data - Crypto algorithm specific data * @enc_eng: Encryption engine info structure * @auth_eng: Authentication engine info structure * @auth_ctrl: Authentication control word * @hash_size: Size of digest * @iv_idx: iv index in psdata * @iv_out_size: iv out size * @ealg_id: Encryption Algorithm ID * @aalg_id: Authentication algorithm ID * @mci_enc: Mode Control Instruction for Encryption algorithm * @mci_dec: Mode Control Instruction for Decryption * @inv_key: Whether the encryption algorithm demands key inversion * @ctx: Pointer to the algorithm context * @keyed_mac: Whether the authentication algorithm has key * @prep_iopad: Function pointer to generate intermediate ipad/opad */struct algo_data {	struct sa_eng_info enc_eng;	struct sa_eng_info auth_eng;	u8 auth_ctrl;	u8 hash_size;	u8 iv_idx;	u8 iv_out_size;	u8 ealg_id;	u8 aalg_id;	u8 *mci_enc;	u8 *mci_dec;	bool inv_key;	struct sa_tfm_ctx *ctx;	bool keyed_mac;	void (*prep_iopad)(struct algo_data *algo, const u8 *key,			   u16 key_sz, __be32 *ipad, __be32 *opad);}; /** * struct sa_alg_tmpl: A generic template encompassing crypto/aead algorithms * @type: Type of the crypto algorithm. * @alg: Union of crypto algorithm definitions. * @registered: Flag indicating if the crypto algorithm is already registered */struct sa_alg_tmpl {	u32 type;		/* CRYPTO_ALG_TYPE from <linux/crypto.h> */	union {		struct skcipher_alg skcipher;		struct ahash_alg ahash;		struct aead_alg aead;	} alg;	bool registered;}; /** * struct sa_mapped_sg: scatterlist information for tx and rx * @mapped: Set to true if the @sgt is mapped * @dir: mapping direction used for @sgt * @split_sg: Set if the sg is split and needs to be freed up * @static_sg: Static scatterlist entry for overriding data * @sgt: scatterlist table for DMA API use */struct sa_mapped_sg {	bool mapped;	enum dma_data_direction dir;	struct scatterlist static_sg;	struct scatterlist *split_sg;	struct sg_table sgt;};/** * struct sa_rx_data: RX Packet miscellaneous data place holder * @req: crypto request data pointer * @ddev: pointer to the DMA device * @tx_in: dma_async_tx_descriptor pointer for rx channel * @mapped_sg: Information on tx (0) and rx (1) scatterlist DMA mapping * @enc: Flag indicating either encryption or decryption * @enc_iv_size: Initialisation vector size * @iv_idx: Initialisation vector index */struct sa_rx_data {	void *req;	struct device *ddev;	struct dma_async_tx_descriptor *tx_in;	struct sa_mapped_sg mapped_sg[2];	u8 enc;	u8 enc_iv_size;	u8 iv_idx;}; /** * struct sa_req: SA request definition * @dev: device for the request * @size: total data to the xmitted via DMA * @enc_offset: offset of cipher data * @enc_size: data to be passed to cipher engine * @enc_iv: cipher IV * @auth_offset: offset of the authentication data * @auth_size: size of the authentication data * @auth_iv: authentication IV * @type: algorithm type for the request * @cmdl: command label pointer * @base: pointer to the base request * @ctx: pointer to the algorithm context data * @enc: true if this is an encode request * @src: source data * @dst: destination data * @callback: DMA callback for the request * @mdata_size: metadata size passed to DMA */struct sa_req {	struct device *dev;	u16 size;	u8 enc_offset;	u16 enc_size;	u8 *enc_iv;	u8 auth_offset;	u16 auth_size;	u8 *auth_iv;	u32 type;	u32 *cmdl;	struct crypto_async_request *base;	struct sa_tfm_ctx *ctx;	bool enc;	struct scatterlist *src;	struct scatterlist *dst;	dma_async_tx_callback callback;	u16 mdata_size;}; /* * Mode Control Instructions for various Key lengths 128, 192, 256 * For CBC (Cipher Block Chaining) mode for encryption */static u8 mci_cbc_enc_array[3][MODE_CONTROL_BYTES] = {	{	0x61, 0x00, 0x00, 0x18, 0x88, 0x0a, 0xaa, 0x4b, 0x7e, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x61, 0x00, 0x00, 0x18, 0x88, 0x4a, 0xaa, 0x4b, 0x7e, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x61, 0x00, 0x00, 0x18, 0x88, 0x8a, 0xaa, 0x4b, 0x7e, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},}; /* * Mode Control Instructions for various Key lengths 128, 192, 256 * For CBC (Cipher Block Chaining) mode for decryption */static u8 mci_cbc_dec_array[3][MODE_CONTROL_BYTES] = {	{	0x71, 0x00, 0x00, 0x80, 0x8a, 0xca, 0x98, 0xf4, 0x40, 0xc0,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x71, 0x00, 0x00, 0x84, 0x8a, 0xca, 0x98, 0xf4, 0x40, 0xc0,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x71, 0x00, 0x00, 0x88, 0x8a, 0xca, 0x98, 0xf4, 0x40, 0xc0,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},}; /* * Mode Control Instructions for various Key lengths 128, 192, 256 * For CBC (Cipher Block Chaining) mode for encryption */static u8 mci_cbc_enc_no_iv_array[3][MODE_CONTROL_BYTES] = {	{	0x21, 0x00, 0x00, 0x18, 0x88, 0x0a, 0xaa, 0x4b, 0x7e, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x21, 0x00, 0x00, 0x18, 0x88, 0x4a, 0xaa, 0x4b, 0x7e, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x21, 0x00, 0x00, 0x18, 0x88, 0x8a, 0xaa, 0x4b, 0x7e, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},}; /* * Mode Control Instructions for various Key lengths 128, 192, 256 * For CBC (Cipher Block Chaining) mode for decryption */static u8 mci_cbc_dec_no_iv_array[3][MODE_CONTROL_BYTES] = {	{	0x31, 0x00, 0x00, 0x80, 0x8a, 0xca, 0x98, 0xf4, 0x40, 0xc0,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x31, 0x00, 0x00, 0x84, 0x8a, 0xca, 0x98, 0xf4, 0x40, 0xc0,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x31, 0x00, 0x00, 0x88, 0x8a, 0xca, 0x98, 0xf4, 0x40, 0xc0,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},}; /* * Mode Control Instructions for various Key lengths 128, 192, 256 * For ECB (Electronic Code Book) mode for encryption */static u8 mci_ecb_enc_array[3][27] = {	{	0x21, 0x00, 0x00, 0x80, 0x8a, 0x04, 0xb7, 0x90, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x21, 0x00, 0x00, 0x84, 0x8a, 0x04, 0xb7, 0x90, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x21, 0x00, 0x00, 0x88, 0x8a, 0x04, 0xb7, 0x90, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},}; /* * Mode Control Instructions for various Key lengths 128, 192, 256 * For ECB (Electronic Code Book) mode for decryption */static u8 mci_ecb_dec_array[3][27] = {	{	0x31, 0x00, 0x00, 0x80, 0x8a, 0x04, 0xb7, 0x90, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x31, 0x00, 0x00, 0x84, 0x8a, 0x04, 0xb7, 0x90, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},	{	0x31, 0x00, 0x00, 0x88, 0x8a, 0x04, 0xb7, 0x90, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00	},}; /* * Mode Control Instructions for DES algorithm * For CBC (Cipher Block Chaining) mode and ECB mode * encryption and for decryption respectively */static u8 mci_cbc_3des_enc_array[MODE_CONTROL_BYTES] = {	0x60, 0x00, 0x00, 0x18, 0x88, 0x52, 0xaa, 0x4b, 0x7e, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00,}; static u8 mci_cbc_3des_dec_array[MODE_CONTROL_BYTES] = {	0x70, 0x00, 0x00, 0x85, 0x0a, 0xca, 0x98, 0xf4, 0x40, 0xc0, 0x00, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00,}; static u8 mci_ecb_3des_enc_array[MODE_CONTROL_BYTES] = {	0x20, 0x00, 0x00, 0x85, 0x0a, 0x04, 0xb7, 0x90, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00,}; static u8 mci_ecb_3des_dec_array[MODE_CONTROL_BYTES] = {	0x30, 0x00, 0x00, 0x85, 0x0a, 0x04, 0xb7, 0x90, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00,}; /* * Perform 16 byte or 128 bit swizzling * The SA2UL Expects the security context to * be in little Endian and the bus width is 128 bits or 16 bytes * Hence swap 16 bytes at a time from higher to lower address */static void sa_swiz_128(u8 *in, u16 len){	u8 data[16];	int i, j; 	for (i = 0; i < len; i += 16) {		memcpy(data, &in[i], 16);		for (j = 0; j < 16; j++)			in[i + j] = data[15 - j];	}} /* Prepare the ipad and opad from key as per SHA algorithm step 1*/static void prepare_kipad(u8 *k_ipad, const u8 *key, u16 key_sz){	int i; 	for (i = 0; i < key_sz; i++)		k_ipad[i] = key[i] ^ 0x36; 	/* Instead of XOR with 0 */	for (; i < SHA1_BLOCK_SIZE; i++)		k_ipad[i] = 0x36;} static void prepare_kopad(u8 *k_opad, const u8 *key, u16 key_sz){	int i; 	for (i = 0; i < key_sz; i++)		k_opad[i] = key[i] ^ 0x5c; 	/* Instead of XOR with 0 */	for (; i < SHA1_BLOCK_SIZE; i++)		k_opad[i] = 0x5c;} static void sa_export_shash(void *state, struct shash_desc *hash,			    int digest_size, __be32 *out){	struct sha1_state *sha1;	struct sha256_state *sha256;	u32 *result; 	switch (digest_size) {	case SHA1_DIGEST_SIZE:		sha1 = state;		result = sha1->state;		break;	case SHA256_DIGEST_SIZE:		sha256 = state;		result = sha256->state;		break;	default:		dev_err(sa_k3_dev, "%s: bad digest_size=%d\n", __func__,			digest_size);		return;	} 	crypto_shash_export(hash, state); 	cpu_to_be32_array(out, result, digest_size / 4);} static void sa_prepare_iopads(struct algo_data *data, const u8 *key,			      u16 key_sz, __be32 *ipad, __be32 *opad){	SHASH_DESC_ON_STACK(shash, data->ctx->shash);	int block_size = crypto_shash_blocksize(data->ctx->shash);	int digest_size = crypto_shash_digestsize(data->ctx->shash);	union {		struct sha1_state sha1;		struct sha256_state sha256;		u8 k_pad[SHA1_BLOCK_SIZE];	} sha; 	shash->tfm = data->ctx->shash; 	prepare_kipad(sha.k_pad, key, key_sz); 	crypto_shash_init(shash);	crypto_shash_update(shash, sha.k_pad, block_size);	sa_export_shash(&sha, shash, digest_size, ipad); 	prepare_kopad(sha.k_pad, key, key_sz); 	crypto_shash_init(shash);	crypto_shash_update(shash, sha.k_pad, block_size); 	sa_export_shash(&sha, shash, digest_size, opad); 	memzero_explicit(&sha, sizeof(sha));} /* Derive the inverse key used in AES-CBC decryption operation */static inline int sa_aes_inv_key(u8 *inv_key, const u8 *key, u16 key_sz){	struct crypto_aes_ctx ctx;	int key_pos; 	if (aes_expandkey(&ctx, key, key_sz)) {		dev_err(sa_k3_dev, "%s: bad key len(%d)\n", __func__, key_sz);		return -EINVAL;	} 	/* work around to get the right inverse for AES_KEYSIZE_192 size keys */	if (key_sz == AES_KEYSIZE_192) {		ctx.key_enc[52] = ctx.key_enc[51] ^ ctx.key_enc[46];		ctx.key_enc[53] = ctx.key_enc[52] ^ ctx.key_enc[47];	} 	/* Based crypto_aes_expand_key logic */	switch (key_sz) {	case AES_KEYSIZE_128:	case AES_KEYSIZE_192:		key_pos = key_sz + 24;		break; 	case AES_KEYSIZE_256:		key_pos = key_sz + 24 - 4;		break; 	default:		dev_err(sa_k3_dev, "%s: bad key len(%d)\n", __func__, key_sz);		return -EINVAL;	} 	memcpy(inv_key, &ctx.key_enc[key_pos], key_sz);	return 0;

Lines 1–500 of 2474.