mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
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:
@@ -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)",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user