xref: /OK3568_Linux_fs/kernel/drivers/crypto/rockchip/rk_crypto_v3.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Crypto acceleration support for Rockchip Crypto V3
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2022, Rockchip Electronics Co., Ltd
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Lin Jinhan <troy.lin@rock-chips.com>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include "rk_crypto_core.h"
12*4882a593Smuzhiyun #include "rk_crypto_v3.h"
13*4882a593Smuzhiyun #include "rk_crypto_v3_reg.h"
14*4882a593Smuzhiyun #include "rk_crypto_utils.h"
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun static const u32 cipher_mode2bit_mask[] = {
17*4882a593Smuzhiyun 	[CIPHER_MODE_ECB]      = CRYPTO_ECB_FLAG,
18*4882a593Smuzhiyun 	[CIPHER_MODE_CBC]      = CRYPTO_CBC_FLAG,
19*4882a593Smuzhiyun 	[CIPHER_MODE_CFB]      = CRYPTO_CFB_FLAG,
20*4882a593Smuzhiyun 	[CIPHER_MODE_OFB]      = CRYPTO_OFB_FLAG,
21*4882a593Smuzhiyun 	[CIPHER_MODE_CTR]      = CRYPTO_CTR_FLAG,
22*4882a593Smuzhiyun 	[CIPHER_MODE_XTS]      = CRYPTO_XTS_FLAG,
23*4882a593Smuzhiyun 	[CIPHER_MODE_CTS]      = CRYPTO_CTS_FLAG,
24*4882a593Smuzhiyun 	[CIPHER_MODE_CCM]      = CRYPTO_CCM_FLAG,
25*4882a593Smuzhiyun 	[CIPHER_MODE_GCM]      = CRYPTO_GCM_FLAG,
26*4882a593Smuzhiyun 	[CIPHER_MODE_CMAC]     = CRYPTO_CMAC_FLAG,
27*4882a593Smuzhiyun 	[CIPHER_MODE_CBCMAC]   = CRYPTO_CBCMAC_FLAG,
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun static const u32 hash_algo2bit_mask[] = {
31*4882a593Smuzhiyun 	[HASH_ALGO_SHA1]       = CRYPTO_HASH_SHA1_FLAG,
32*4882a593Smuzhiyun 	[HASH_ALGO_SHA224]     = CRYPTO_HASH_SHA224_FLAG,
33*4882a593Smuzhiyun 	[HASH_ALGO_SHA256]     = CRYPTO_HASH_SHA256_FLAG,
34*4882a593Smuzhiyun 	[HASH_ALGO_SHA384]     = CRYPTO_HASH_SHA384_FLAG,
35*4882a593Smuzhiyun 	[HASH_ALGO_SHA512]     = CRYPTO_HASH_SHA512_FLAG,
36*4882a593Smuzhiyun 	[HASH_ALGO_SHA512_224] = CRYPTO_HASH_SHA512_224_FLAG,
37*4882a593Smuzhiyun 	[HASH_ALGO_SHA512_256] = CRYPTO_HASH_SHA512_256_FLAG,
38*4882a593Smuzhiyun 	[HASH_ALGO_MD5]        = CRYPTO_HASH_MD5_FLAG,
39*4882a593Smuzhiyun 	[HASH_ALGO_SM3]        = CRYPTO_HASH_SM3_FLAG,
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun static const u32 hmac_algo2bit_mask[] = {
43*4882a593Smuzhiyun 	[HASH_ALGO_SHA1]       = CRYPTO_HMAC_SHA1_FLAG,
44*4882a593Smuzhiyun 	[HASH_ALGO_SHA256]     = CRYPTO_HMAC_SHA256_FLAG,
45*4882a593Smuzhiyun 	[HASH_ALGO_SHA512]     = CRYPTO_HMAC_SHA512_FLAG,
46*4882a593Smuzhiyun 	[HASH_ALGO_MD5]        = CRYPTO_HMAC_MD5_FLAG,
47*4882a593Smuzhiyun 	[HASH_ALGO_SM3]        = CRYPTO_HMAC_SM3_FLAG,
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun static const char * const crypto_v3_rsts[] = {
51*4882a593Smuzhiyun 	 "crypto-rst",
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun static struct rk_crypto_algt *crypto_v3_algs[] = {
55*4882a593Smuzhiyun 	&rk_v3_ecb_sm4_alg,		/* ecb(sm4) */
56*4882a593Smuzhiyun 	&rk_v3_cbc_sm4_alg,		/* cbc(sm4) */
57*4882a593Smuzhiyun 	&rk_v3_xts_sm4_alg,		/* xts(sm4) */
58*4882a593Smuzhiyun 	&rk_v3_cfb_sm4_alg,		/* cfb(sm4) */
59*4882a593Smuzhiyun 	&rk_v3_ofb_sm4_alg,		/* ofb(sm4) */
60*4882a593Smuzhiyun 	&rk_v3_ctr_sm4_alg,		/* ctr(sm4) */
61*4882a593Smuzhiyun 	&rk_v3_gcm_sm4_alg,		/* ctr(sm4) */
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	&rk_v3_ecb_aes_alg,		/* ecb(aes) */
64*4882a593Smuzhiyun 	&rk_v3_cbc_aes_alg,		/* cbc(aes) */
65*4882a593Smuzhiyun 	&rk_v3_xts_aes_alg,		/* xts(aes) */
66*4882a593Smuzhiyun 	&rk_v3_cfb_aes_alg,		/* cfb(aes) */
67*4882a593Smuzhiyun 	&rk_v3_ofb_aes_alg,		/* ofb(aes) */
68*4882a593Smuzhiyun 	&rk_v3_ctr_aes_alg,		/* ctr(aes) */
69*4882a593Smuzhiyun 	&rk_v3_gcm_aes_alg,		/* gcm(aes) */
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	&rk_v3_ecb_des_alg,		/* ecb(des) */
72*4882a593Smuzhiyun 	&rk_v3_cbc_des_alg,		/* cbc(des) */
73*4882a593Smuzhiyun 	&rk_v3_cfb_des_alg,		/* cfb(des) */
74*4882a593Smuzhiyun 	&rk_v3_ofb_des_alg,		/* ofb(des) */
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	&rk_v3_ecb_des3_ede_alg,	/* ecb(des3_ede) */
77*4882a593Smuzhiyun 	&rk_v3_cbc_des3_ede_alg,	/* cbc(des3_ede) */
78*4882a593Smuzhiyun 	&rk_v3_cfb_des3_ede_alg,	/* cfb(des3_ede) */
79*4882a593Smuzhiyun 	&rk_v3_ofb_des3_ede_alg,	/* ofb(des3_ede) */
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	&rk_v3_ahash_sha1,		/* sha1 */
82*4882a593Smuzhiyun 	&rk_v3_ahash_sha224,		/* sha224 */
83*4882a593Smuzhiyun 	&rk_v3_ahash_sha256,		/* sha256 */
84*4882a593Smuzhiyun 	&rk_v3_ahash_sha384,		/* sha384 */
85*4882a593Smuzhiyun 	&rk_v3_ahash_sha512,		/* sha512 */
86*4882a593Smuzhiyun 	&rk_v3_ahash_md5,		/* md5 */
87*4882a593Smuzhiyun 	&rk_v3_ahash_sm3,		/* sm3 */
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	&rk_v3_hmac_sha1,		/* hmac(sha1) */
90*4882a593Smuzhiyun 	&rk_v3_hmac_sha256,		/* hmac(sha256) */
91*4882a593Smuzhiyun 	&rk_v3_hmac_sha512,		/* hmac(sha512) */
92*4882a593Smuzhiyun 	&rk_v3_hmac_md5,		/* hmac(md5) */
93*4882a593Smuzhiyun 	&rk_v3_hmac_sm3,		/* hmac(sm3) */
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	/* Shared v2 version implementation */
96*4882a593Smuzhiyun 	&rk_v2_asym_rsa,		/* rsa */
97*4882a593Smuzhiyun };
98*4882a593Smuzhiyun 
rk_is_cipher_support(struct rk_crypto_dev * rk_dev,u32 algo,u32 mode,u32 key_len)99*4882a593Smuzhiyun static bool rk_is_cipher_support(struct rk_crypto_dev *rk_dev, u32 algo, u32 mode, u32 key_len)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	u32 version = 0;
102*4882a593Smuzhiyun 	u32 mask = 0;
103*4882a593Smuzhiyun 	bool key_len_valid = true;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	switch (algo) {
106*4882a593Smuzhiyun 	case CIPHER_ALGO_DES:
107*4882a593Smuzhiyun 	case CIPHER_ALGO_DES3_EDE:
108*4882a593Smuzhiyun 		version = CRYPTO_READ(rk_dev, CRYPTO_DES_VERSION);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 		if (key_len == 8)
111*4882a593Smuzhiyun 			key_len_valid = true;
112*4882a593Smuzhiyun 		else if (key_len == 16 || key_len == 24)
113*4882a593Smuzhiyun 			key_len_valid = version & CRYPTO_TDES_FLAG;
114*4882a593Smuzhiyun 		else
115*4882a593Smuzhiyun 			key_len_valid = false;
116*4882a593Smuzhiyun 		break;
117*4882a593Smuzhiyun 	case CIPHER_ALGO_AES:
118*4882a593Smuzhiyun 		version = CRYPTO_READ(rk_dev, CRYPTO_AES_VERSION);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 		if (key_len == 16)
121*4882a593Smuzhiyun 			key_len_valid = version & CRYPTO_AES128_FLAG;
122*4882a593Smuzhiyun 		else if (key_len == 24)
123*4882a593Smuzhiyun 			key_len_valid = version & CRYPTO_AES192_FLAG;
124*4882a593Smuzhiyun 		else if (key_len == 32)
125*4882a593Smuzhiyun 			key_len_valid = version & CRYPTO_AES256_FLAG;
126*4882a593Smuzhiyun 		else
127*4882a593Smuzhiyun 			key_len_valid = false;
128*4882a593Smuzhiyun 		break;
129*4882a593Smuzhiyun 	case CIPHER_ALGO_SM4:
130*4882a593Smuzhiyun 		version = CRYPTO_READ(rk_dev, CRYPTO_SM4_VERSION);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 		key_len_valid = (key_len == SM4_KEY_SIZE) ? true : false;
133*4882a593Smuzhiyun 		break;
134*4882a593Smuzhiyun 	default:
135*4882a593Smuzhiyun 		return false;
136*4882a593Smuzhiyun 	}
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	mask = cipher_mode2bit_mask[mode];
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	if (key_len == 0)
141*4882a593Smuzhiyun 		key_len_valid = true;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	return (version & mask) && key_len_valid;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
rk_is_hash_support(struct rk_crypto_dev * rk_dev,u32 algo,u32 type)146*4882a593Smuzhiyun static bool rk_is_hash_support(struct rk_crypto_dev *rk_dev, u32 algo, u32 type)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	u32 version = 0;
149*4882a593Smuzhiyun 	u32 mask = 0;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	if (type == ALG_TYPE_HMAC) {
152*4882a593Smuzhiyun 		version = CRYPTO_READ(rk_dev, CRYPTO_HMAC_VERSION);
153*4882a593Smuzhiyun 		mask    = hmac_algo2bit_mask[algo];
154*4882a593Smuzhiyun 	} else if (type == ALG_TYPE_HASH) {
155*4882a593Smuzhiyun 		version = CRYPTO_READ(rk_dev, CRYPTO_HASH_VERSION);
156*4882a593Smuzhiyun 		mask    = hash_algo2bit_mask[algo];
157*4882a593Smuzhiyun 	} else {
158*4882a593Smuzhiyun 		return false;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	return version & mask;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
rk_hw_crypto_v3_init(struct device * dev,void * hw_info)164*4882a593Smuzhiyun int rk_hw_crypto_v3_init(struct device *dev, void *hw_info)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	struct rk_hw_crypto_v3_info *info =
167*4882a593Smuzhiyun 		(struct rk_hw_crypto_v3_info *)hw_info;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	if (!dev || !hw_info)
170*4882a593Smuzhiyun 		return -EINVAL;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	memset(info, 0x00, sizeof(*info));
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	return rk_crypto_hw_desc_alloc(dev, &info->hw_desc);
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
rk_hw_crypto_v3_deinit(struct device * dev,void * hw_info)177*4882a593Smuzhiyun void rk_hw_crypto_v3_deinit(struct device *dev, void *hw_info)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	struct rk_hw_crypto_v3_info *info =
180*4882a593Smuzhiyun 		(struct rk_hw_crypto_v3_info *)hw_info;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	if (!dev || !hw_info)
183*4882a593Smuzhiyun 		return;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	rk_crypto_hw_desc_free(&info->hw_desc);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun 
rk_hw_crypto_v3_get_rsts(uint32_t * num)188*4882a593Smuzhiyun const char * const *rk_hw_crypto_v3_get_rsts(uint32_t *num)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	*num = ARRAY_SIZE(crypto_v3_rsts);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	return crypto_v3_rsts;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
rk_hw_crypto_v3_get_algts(uint32_t * num)195*4882a593Smuzhiyun struct rk_crypto_algt **rk_hw_crypto_v3_get_algts(uint32_t *num)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	*num = ARRAY_SIZE(crypto_v3_algs);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	return crypto_v3_algs;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
rk_hw_crypto_v3_algo_valid(struct rk_crypto_dev * rk_dev,struct rk_crypto_algt * aglt)202*4882a593Smuzhiyun bool rk_hw_crypto_v3_algo_valid(struct rk_crypto_dev *rk_dev, struct rk_crypto_algt *aglt)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	if (aglt->type == ALG_TYPE_CIPHER || aglt->type == ALG_TYPE_AEAD) {
205*4882a593Smuzhiyun 		CRYPTO_TRACE("CIPHER");
206*4882a593Smuzhiyun 		return rk_is_cipher_support(rk_dev, aglt->algo, aglt->mode, 0);
207*4882a593Smuzhiyun 	} else if (aglt->type == ALG_TYPE_HASH || aglt->type == ALG_TYPE_HMAC) {
208*4882a593Smuzhiyun 		CRYPTO_TRACE("HASH/HMAC");
209*4882a593Smuzhiyun 		return rk_is_hash_support(rk_dev, aglt->algo, aglt->type);
210*4882a593Smuzhiyun 	} else if (aglt->type == ALG_TYPE_ASYM) {
211*4882a593Smuzhiyun 		CRYPTO_TRACE("RSA");
212*4882a593Smuzhiyun 		return true;
213*4882a593Smuzhiyun 	} else {
214*4882a593Smuzhiyun 		return false;
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218