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