crypto: rockchip: v3: add crypto version check

Add automatic check, can be automatically trimmed according
 to the register supported algorithm.

Signed-off-by: Lin Jinhan <troy.lin@rock-chips.com>
Change-Id: Ie807cba240389466be1d1f177bbc9b35a47efecb
This commit is contained in:
Lin Jinhan
2022-03-04 09:10:15 +08:00
committed by Tao Huang
parent f68bea16c9
commit 6b2fcae1a6
8 changed files with 186 additions and 23 deletions

View File

@@ -443,6 +443,8 @@ static int rk_crypto_register(struct rk_crypto_dev *rk_dev)
algs_name = soc_data->valid_algs_name;
rk_dev->request_crypto(rk_dev, __func__);
for (i = 0; i < soc_data->valid_algs_num; i++, algs_name++) {
tmp_algs = rk_crypto_find_algs(rk_dev, *algs_name);
if (!tmp_algs) {
@@ -450,6 +452,11 @@ static int rk_crypto_register(struct rk_crypto_dev *rk_dev)
continue;
}
if (soc_data->hw_is_algo_valid && !soc_data->hw_is_algo_valid(rk_dev, tmp_algs)) {
CRYPTO_TRACE("%s skipped!!!\n", *algs_name);
continue;
}
CRYPTO_TRACE("%s matched!!!\n", *algs_name);
tmp_algs->rk_dev = rk_dev;
@@ -482,6 +489,9 @@ static int rk_crypto_register(struct rk_crypto_dev *rk_dev)
CRYPTO_TRACE("%s register OK!!!\n", *algs_name);
}
rk_dev->release_crypto(rk_dev, __func__);
return 0;
err_cipher_algs:
@@ -499,6 +509,9 @@ err_cipher_algs:
else if (tmp_algs->type == ALG_TYPE_ASYM)
crypto_unregister_akcipher(&tmp_algs->alg.asym);
}
rk_dev->release_crypto(rk_dev, __func__);
return err;
}
@@ -510,6 +523,8 @@ static void rk_crypto_unregister(struct rk_crypto_dev *rk_dev)
algs_name = rk_dev->soc_data->valid_algs_name;
rk_dev->request_crypto(rk_dev, __func__);
for (i = 0; i < rk_dev->soc_data->valid_algs_num; i++, algs_name++) {
tmp_algs = rk_crypto_find_algs(rk_dev, *algs_name);
if (!tmp_algs)
@@ -522,6 +537,8 @@ static void rk_crypto_unregister(struct rk_crypto_dev *rk_dev)
else if (tmp_algs->type == ALG_TYPE_ASYM)
crypto_unregister_akcipher(&tmp_algs->alg.asym);
}
rk_dev->release_crypto(rk_dev, __func__);
}
static void rk_crypto_request(struct rk_crypto_dev *rk_dev, const char *name)
@@ -575,15 +592,6 @@ static char *crypto_full_algs_name[] = {
"rsa"
};
static char *crypto_rv1106_algs_name[] = {
"ecb(aes)", "cbc(aes)", "cfb(aes)", "ofb(aes)", "ctr(aes)",
"ecb(des)", "cbc(des)", "cfb(des)", "ofb(des)",
"ecb(des3_ede)", "cbc(des3_ede)", "cfb(des3_ede)", "ofb(des3_ede)",
"sha1", "sha224", "sha256", "md5",
"hmac(sha1)", "hmac(sha256)", "hmac(md5)",
"rsa"
};
static const struct rk_crypto_soc_data px30_soc_data =
RK_CRYPTO_V2_SOC_DATA_INIT(crypto_no_sm_algs_name, false);
@@ -594,7 +602,7 @@ static const struct rk_crypto_soc_data full_soc_data =
RK_CRYPTO_V2_SOC_DATA_INIT(crypto_full_algs_name, false);
static const struct rk_crypto_soc_data cryto_v3_soc_data =
RK_CRYPTO_V3_SOC_DATA_INIT(crypto_rv1106_algs_name);
RK_CRYPTO_V3_SOC_DATA_INIT(crypto_full_algs_name);
static char *rk3288_cipher_algs[] = {
"ecb(aes)", "cbc(aes)",

View File

@@ -46,19 +46,6 @@
#define RK_FLAG_FINAL BIT(0)
#define RK_FLAG_UPDATE BIT(1)
struct rk_crypto_soc_data {
const char *crypto_ver;
char **valid_algs_name;
int valid_algs_num;
unsigned int hw_info_size;
bool use_soft_aes192;
int default_pka_offset;
int (*hw_init)(struct device *dev, void *hw_info);
void (*hw_deinit)(struct device *dev, void *hw_info);
const char * const *(*hw_get_rsts)(uint32_t *num);
struct rk_crypto_algt **(*hw_get_algts)(uint32_t *num);
};
struct rk_crypto_dev {
struct device *dev;
struct reset_control *rst;
@@ -94,6 +81,21 @@ struct rk_crypto_dev {
struct crypto_async_request *async_req);
};
struct rk_crypto_soc_data {
const char *crypto_ver;
char **valid_algs_name;
int valid_algs_num;
unsigned int hw_info_size;
bool use_soft_aes192;
int default_pka_offset;
int (*hw_init)(struct device *dev, void *hw_info);
void (*hw_deinit)(struct device *dev, void *hw_info);
const char * const *(*hw_get_rsts)(uint32_t *num);
struct rk_crypto_algt **(*hw_get_algts)(uint32_t *num);
bool (*hw_is_algo_valid)(struct rk_crypto_dev *rk_dev,
struct rk_crypto_algt *aglt);
};
struct rk_alg_ops {
int (*start)(struct rk_crypto_dev *rk_dev);
int (*update)(struct rk_crypto_dev *rk_dev);
@@ -213,6 +215,8 @@ enum rk_hash_algo {
HASH_ALGO_SHA384,
HASH_ALGO_SHA512,
HASH_ALGO_SM3,
HASH_ALGO_SHA512_224,
HASH_ALGO_SHA512_256,
};
enum rk_cipher_algo {
@@ -229,6 +233,11 @@ enum rk_cipher_mode {
CIPHER_MODE_OFB,
CIPHER_MODE_CTR,
CIPHER_MODE_XTS,
CIPHER_MODE_CTS,
CIPHER_MODE_CCM,
CIPHER_MODE_GCM,
CIPHER_MODE_CMAC,
CIPHER_MODE_CBCMAC,
};
#define DES_MIN_KEY_SIZE DES_KEY_SIZE

View File

@@ -53,3 +53,8 @@ struct rk_crypto_algt **rk_hw_crypto_v1_get_algts(uint32_t *num)
return crypto_v1_algs;
}
bool rk_hw_crypto_v1_algo_valid(struct rk_crypto_dev *rk_dev, struct rk_crypto_algt *aglt)
{
return true;
}

View File

@@ -20,6 +20,7 @@ struct rk_hw_crypto_v1_info {
.hw_deinit = rk_hw_crypto_v1_deinit,\
.hw_get_rsts = rk_hw_crypto_v1_get_rsts,\
.hw_get_algts = rk_hw_crypto_v1_get_algts,\
.hw_is_algo_valid = rk_hw_crypto_v1_algo_valid,\
.hw_info_size = sizeof(struct rk_hw_crypto_v1_info),\
.default_pka_offset = 0,\
}
@@ -43,6 +44,7 @@ int rk_hw_crypto_v1_init(struct device *dev, void *hw_info);
void rk_hw_crypto_v1_deinit(struct device *dev, void *hw_info);
const char * const *rk_hw_crypto_v1_get_rsts(uint32_t *num);
struct rk_crypto_algt **rk_hw_crypto_v1_get_algts(uint32_t *num);
bool rk_hw_crypto_v1_algo_valid(struct rk_crypto_dev *rk_dev, struct rk_crypto_algt *aglt);
#else
@@ -50,6 +52,11 @@ static inline int rk_hw_crypto_v1_init(struct device *dev, void *hw_info) { retu
static inline void rk_hw_crypto_v1_deinit(struct device *dev, void *hw_info) {}
static inline const char * const *rk_hw_crypto_v1_get_rsts(uint32_t *num) { return NULL; }
static inline struct rk_crypto_algt **rk_hw_crypto_v1_get_algts(uint32_t *num) { return NULL; }
static inline bool rk_hw_crypto_v1_algo_valid(struct rk_crypto_dev *rk_dev,
struct rk_crypto_algt *aglt)
{
return false;
}
#endif /* end of IS_ENABLED(CONFIG_CRYPTO_DEV_ROCKCHIP_V1) */

View File

@@ -100,3 +100,8 @@ struct rk_crypto_algt **rk_hw_crypto_v2_get_algts(uint32_t *num)
return crypto_v2_algs;
}
bool rk_hw_crypto_v2_algo_valid(struct rk_crypto_dev *rk_dev, struct rk_crypto_algt *aglt)
{
return true;
}

View File

@@ -32,6 +32,7 @@ struct rk_hw_crypto_v2_info {
.hw_deinit = rk_hw_crypto_v2_deinit,\
.hw_get_rsts = rk_hw_crypto_v2_get_rsts,\
.hw_get_algts = rk_hw_crypto_v2_get_algts,\
.hw_is_algo_valid = rk_hw_crypto_v2_algo_valid,\
.hw_info_size = sizeof(struct rk_hw_crypto_v2_info),\
.default_pka_offset = 0x0480,\
}
@@ -82,6 +83,7 @@ int rk_hw_crypto_v2_init(struct device *dev, void *hw_info);
void rk_hw_crypto_v2_deinit(struct device *dev, void *hw_info);
const char * const *rk_hw_crypto_v2_get_rsts(uint32_t *num);
struct rk_crypto_algt **rk_hw_crypto_v2_get_algts(uint32_t *num);
bool rk_hw_crypto_v2_algo_valid(struct rk_crypto_dev *rk_dev, struct rk_crypto_algt *aglt);
#else
@@ -89,6 +91,11 @@ static inline int rk_hw_crypto_v2_init(struct device *dev, void *hw_info) { retu
static inline void rk_hw_crypto_v2_deinit(struct device *dev, void *hw_info) {}
static inline const char * const *rk_hw_crypto_v2_get_rsts(uint32_t *num) { return NULL; }
static inline struct rk_crypto_algt **rk_hw_crypto_v2_get_algts(uint32_t *num) { return NULL; }
static inline bool rk_hw_crypto_v2_algo_valid(struct rk_crypto_dev *rk_dev,
struct rk_crypto_algt *aglt)
{
return false;
}
#endif /* end of IS_ENABLED(CONFIG_CRYPTO_DEV_ROCKCHIP_V2) */

View File

@@ -12,6 +12,40 @@
#include "rk_crypto_v3.h"
#include "rk_crypto_v3_reg.h"
static const u32 cipher_mode2bit_mask[] = {
[CIPHER_MODE_ECB] = CRYPTO_ECB_FLAG,
[CIPHER_MODE_CBC] = CRYPTO_CBC_FLAG,
[CIPHER_MODE_CFB] = CRYPTO_CFB_FLAG,
[CIPHER_MODE_OFB] = CRYPTO_OFB_FLAG,
[CIPHER_MODE_CTR] = CRYPTO_CTR_FLAG,
[CIPHER_MODE_XTS] = CRYPTO_XTS_FLAG,
[CIPHER_MODE_CTS] = CRYPTO_CTS_FLAG,
[CIPHER_MODE_CCM] = CRYPTO_CCM_FLAG,
[CIPHER_MODE_GCM] = CRYPTO_GCM_FLAG,
[CIPHER_MODE_CMAC] = CRYPTO_CMAC_FLAG,
[CIPHER_MODE_CBCMAC] = CRYPTO_CBCMAC_FLAG,
};
static const u32 hash_algo2bit_mask[] = {
[HASH_ALGO_SHA1] = CRYPTO_HASH_SHA1_FLAG,
[HASH_ALGO_SHA224] = CRYPTO_HASH_SHA224_FLAG,
[HASH_ALGO_SHA256] = CRYPTO_HASH_SHA256_FLAG,
[HASH_ALGO_SHA384] = CRYPTO_HASH_SHA384_FLAG,
[HASH_ALGO_SHA512] = CRYPTO_HASH_SHA512_FLAG,
[HASH_ALGO_SHA512_224] = CRYPTO_HASH_SHA512_224_FLAG,
[HASH_ALGO_SHA512_256] = CRYPTO_HASH_SHA512_256_FLAG,
[HASH_ALGO_MD5] = CRYPTO_HASH_MD5_FLAG,
[HASH_ALGO_SM3] = CRYPTO_HASH_SM3_FLAG,
};
static const u32 hmac_algo2bit_mask[] = {
[HASH_ALGO_SHA1] = CRYPTO_HMAC_SHA1_FLAG,
[HASH_ALGO_SHA256] = CRYPTO_HMAC_SHA256_FLAG,
[HASH_ALGO_SHA512] = CRYPTO_HMAC_SHA512_FLAG,
[HASH_ALGO_MD5] = CRYPTO_HMAC_MD5_FLAG,
[HASH_ALGO_SM3] = CRYPTO_HMAC_SM3_FLAG,
};
static const char * const crypto_v3_rsts[] = {
"crypto-rst",
};
@@ -59,6 +93,71 @@ static struct rk_crypto_algt *crypto_v3_algs[] = {
&rk_v2_asym_rsa, /* rsa */
};
static bool rk_is_cipher_support(struct rk_crypto_dev *rk_dev, u32 algo, u32 mode, u32 key_len)
{
u32 version = 0;
u32 mask = 0;
bool key_len_valid = true;
switch (algo) {
case CIPHER_ALGO_DES:
case CIPHER_ALGO_DES3_EDE:
version = CRYPTO_READ(rk_dev, CRYPTO_DES_VERSION);
if (key_len == 8)
key_len_valid = true;
else if (key_len == 16 || key_len == 24)
key_len_valid = version & CRYPTO_TDES_FLAG;
else
key_len_valid = false;
break;
case CIPHER_ALGO_AES:
version = CRYPTO_READ(rk_dev, CRYPTO_AES_VERSION);
if (key_len == 16)
key_len_valid = version & CRYPTO_AES128_FLAG;
else if (key_len == 24)
key_len_valid = version & CRYPTO_AES192_FLAG;
else if (key_len == 32)
key_len_valid = version & CRYPTO_AES256_FLAG;
else
key_len_valid = false;
break;
case CIPHER_ALGO_SM4:
version = CRYPTO_READ(rk_dev, CRYPTO_SM4_VERSION);
key_len_valid = (key_len == SM4_KEY_SIZE) ? true : false;
break;
default:
return false;
}
mask = cipher_mode2bit_mask[mode];
if (key_len == 0)
key_len_valid = true;
return (version & mask) && key_len_valid;
}
static bool rk_is_hash_support(struct rk_crypto_dev *rk_dev, u32 algo, u32 type)
{
u32 version = 0;
u32 mask = 0;
if (type == ALG_TYPE_HMAC) {
version = CRYPTO_READ(rk_dev, CRYPTO_HMAC_VERSION);
mask = hmac_algo2bit_mask[algo];
} else if (type == ALG_TYPE_HASH) {
version = CRYPTO_READ(rk_dev, CRYPTO_HASH_VERSION);
mask = hash_algo2bit_mask[algo];
} else {
return false;
}
return version & mask;
}
int rk_hw_crypto_v3_init(struct device *dev, void *hw_info)
{
int err = 0;
@@ -102,3 +201,19 @@ struct rk_crypto_algt **rk_hw_crypto_v3_get_algts(uint32_t *num)
return crypto_v3_algs;
}
bool rk_hw_crypto_v3_algo_valid(struct rk_crypto_dev *rk_dev, struct rk_crypto_algt *aglt)
{
if (aglt->type == ALG_TYPE_CIPHER) {
CRYPTO_TRACE("CIPHER");
return rk_is_cipher_support(rk_dev, aglt->algo, aglt->mode, 0);
} else if (aglt->type == ALG_TYPE_HASH || aglt->type == ALG_TYPE_HMAC) {
CRYPTO_TRACE("HASH/HMAC");
return rk_is_hash_support(rk_dev, aglt->algo, aglt->type);
} else if (aglt->type == ALG_TYPE_ASYM) {
CRYPTO_TRACE("RSA");
return true;
} else {
return false;
}
}

View File

@@ -23,6 +23,7 @@ struct rk_hw_crypto_v3_info {
.hw_deinit = rk_hw_crypto_v3_deinit,\
.hw_get_rsts = rk_hw_crypto_v3_get_rsts,\
.hw_get_algts = rk_hw_crypto_v3_get_algts,\
.hw_is_algo_valid = rk_hw_crypto_v3_algo_valid,\
.hw_info_size = sizeof(struct rk_hw_crypto_v3_info),\
.default_pka_offset = 0x0480,\
}
@@ -74,6 +75,7 @@ int rk_hw_crypto_v3_init(struct device *dev, void *hw_info);
void rk_hw_crypto_v3_deinit(struct device *dev, void *hw_info);
const char * const *rk_hw_crypto_v3_get_rsts(uint32_t *num);
struct rk_crypto_algt **rk_hw_crypto_v3_get_algts(uint32_t *num);
bool rk_hw_crypto_v3_algo_valid(struct rk_crypto_dev *rk_dev, struct rk_crypto_algt *aglt);
#else
@@ -81,6 +83,11 @@ static inline int rk_hw_crypto_v3_init(struct device *dev, void *hw_info) { retu
static inline void rk_hw_crypto_v3_deinit(struct device *dev, void *hw_info) {}
static inline const char * const *rk_hw_crypto_v3_get_rsts(uint32_t *num) { return NULL; }
static inline struct rk_crypto_algt **rk_hw_crypto_v3_get_algts(uint32_t *num) { return NULL; }
static inline bool rk_hw_crypto_v3_algo_valid(struct rk_crypto_dev *rk_dev,
struct rk_crypto_algt *aglt)
{
return false;
}
#endif /* end of IS_ENABLED(CONFIG_CRYPTO_DEV_ROCKCHIP_V3) */