forked from Minki/linux
crypto: caam - Detect hardware features during algorithm registration
Register only algorithms supported by CAAM hardware, using the CHA version and instantiation registers to identify hardware capabilities. Signed-off-by: Victoria Milhoan <vicki.milhoan@freescale.com> Tested-by: Horia Geantă <horia.geanta@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
350cdfeba8
commit
bf83490ee4
@ -4371,8 +4371,10 @@ static int __init caam_algapi_init(void)
|
||||
struct device_node *dev_node;
|
||||
struct platform_device *pdev;
|
||||
struct device *ctrldev;
|
||||
void *priv;
|
||||
struct caam_drv_private *priv;
|
||||
int i = 0, err = 0;
|
||||
u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
|
||||
unsigned int md_limit = SHA512_DIGEST_SIZE;
|
||||
bool registered = false;
|
||||
|
||||
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
|
||||
@ -4402,16 +4404,39 @@ static int __init caam_algapi_init(void)
|
||||
|
||||
INIT_LIST_HEAD(&alg_list);
|
||||
|
||||
/* register crypto algorithms the device supports */
|
||||
for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
|
||||
/* TODO: check if h/w supports alg */
|
||||
struct caam_crypto_alg *t_alg;
|
||||
/*
|
||||
* Register crypto algorithms the device supports.
|
||||
* First, detect presence and attributes of DES, AES, and MD blocks.
|
||||
*/
|
||||
cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
|
||||
cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
|
||||
des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
|
||||
aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
|
||||
md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
|
||||
|
||||
t_alg = caam_alg_alloc(&driver_algs[i]);
|
||||
/* If MD is present, limit digest size based on LP256 */
|
||||
if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
|
||||
md_limit = SHA256_DIGEST_SIZE;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
|
||||
struct caam_crypto_alg *t_alg;
|
||||
struct caam_alg_template *alg = driver_algs + i;
|
||||
u32 alg_sel = alg->class1_alg_type & OP_ALG_ALGSEL_MASK;
|
||||
|
||||
/* Skip DES algorithms if not supported by device */
|
||||
if (!des_inst &&
|
||||
((alg_sel == OP_ALG_ALGSEL_3DES) ||
|
||||
(alg_sel == OP_ALG_ALGSEL_DES)))
|
||||
continue;
|
||||
|
||||
/* Skip AES algorithms if not supported by device */
|
||||
if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
|
||||
continue;
|
||||
|
||||
t_alg = caam_alg_alloc(alg);
|
||||
if (IS_ERR(t_alg)) {
|
||||
err = PTR_ERR(t_alg);
|
||||
pr_warn("%s alg allocation failed\n",
|
||||
driver_algs[i].driver_name);
|
||||
pr_warn("%s alg allocation failed\n", alg->driver_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -4429,6 +4454,37 @@ static int __init caam_algapi_init(void)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
|
||||
struct caam_aead_alg *t_alg = driver_aeads + i;
|
||||
u32 c1_alg_sel = t_alg->caam.class1_alg_type &
|
||||
OP_ALG_ALGSEL_MASK;
|
||||
u32 c2_alg_sel = t_alg->caam.class2_alg_type &
|
||||
OP_ALG_ALGSEL_MASK;
|
||||
u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
|
||||
|
||||
/* Skip DES algorithms if not supported by device */
|
||||
if (!des_inst &&
|
||||
((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
|
||||
(c1_alg_sel == OP_ALG_ALGSEL_DES)))
|
||||
continue;
|
||||
|
||||
/* Skip AES algorithms if not supported by device */
|
||||
if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Check support for AES algorithms not available
|
||||
* on LP devices.
|
||||
*/
|
||||
if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
|
||||
if (alg_aai == OP_ALG_AAI_GCM)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Skip algorithms requiring message digests
|
||||
* if MD or MD size is not supported by device.
|
||||
*/
|
||||
if (c2_alg_sel &&
|
||||
(!md_inst || (t_alg->aead.maxauthsize > md_limit)))
|
||||
continue;
|
||||
|
||||
caam_aead_alg_init(t_alg);
|
||||
|
||||
|
@ -1883,8 +1883,10 @@ static int __init caam_algapi_hash_init(void)
|
||||
struct device_node *dev_node;
|
||||
struct platform_device *pdev;
|
||||
struct device *ctrldev;
|
||||
void *priv;
|
||||
int i = 0, err = 0;
|
||||
struct caam_drv_private *priv;
|
||||
unsigned int md_limit = SHA512_DIGEST_SIZE;
|
||||
u32 cha_inst, cha_vid;
|
||||
|
||||
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
|
||||
if (!dev_node) {
|
||||
@ -1910,19 +1912,40 @@ static int __init caam_algapi_hash_init(void)
|
||||
if (!priv)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Register crypto algorithms the device supports. First, identify
|
||||
* presence and attributes of MD block.
|
||||
*/
|
||||
cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
|
||||
cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
|
||||
|
||||
/*
|
||||
* Skip registration of any hashing algorithms if MD block
|
||||
* is not present.
|
||||
*/
|
||||
if (!((cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT))
|
||||
return -ENODEV;
|
||||
|
||||
/* Limit digest size based on LP256 */
|
||||
if ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256)
|
||||
md_limit = SHA256_DIGEST_SIZE;
|
||||
|
||||
INIT_LIST_HEAD(&hash_list);
|
||||
|
||||
/* register crypto algorithms the device supports */
|
||||
for (i = 0; i < ARRAY_SIZE(driver_hash); i++) {
|
||||
/* TODO: check if h/w supports alg */
|
||||
struct caam_hash_alg *t_alg;
|
||||
struct caam_hash_template *alg = driver_hash + i;
|
||||
|
||||
/* If MD size is not supported by device, skip registration */
|
||||
if (alg->template_ahash.halg.digestsize > md_limit)
|
||||
continue;
|
||||
|
||||
/* register hmac version */
|
||||
t_alg = caam_hash_alloc(&driver_hash[i], true);
|
||||
t_alg = caam_hash_alloc(alg, true);
|
||||
if (IS_ERR(t_alg)) {
|
||||
err = PTR_ERR(t_alg);
|
||||
pr_warn("%s alg allocation failed\n",
|
||||
driver_hash[i].driver_name);
|
||||
pr_warn("%s alg allocation failed\n", alg->driver_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1935,11 +1958,10 @@ static int __init caam_algapi_hash_init(void)
|
||||
list_add_tail(&t_alg->entry, &hash_list);
|
||||
|
||||
/* register unkeyed version */
|
||||
t_alg = caam_hash_alloc(&driver_hash[i], false);
|
||||
t_alg = caam_hash_alloc(alg, false);
|
||||
if (IS_ERR(t_alg)) {
|
||||
err = PTR_ERR(t_alg);
|
||||
pr_warn("%s alg allocation failed\n",
|
||||
driver_hash[i].driver_name);
|
||||
pr_warn("%s alg allocation failed\n", alg->driver_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ static int __init caam_rng_init(void)
|
||||
struct device_node *dev_node;
|
||||
struct platform_device *pdev;
|
||||
struct device *ctrldev;
|
||||
void *priv;
|
||||
struct caam_drv_private *priv;
|
||||
int err;
|
||||
|
||||
dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
|
||||
@ -342,6 +342,10 @@ static int __init caam_rng_init(void)
|
||||
if (!priv)
|
||||
return -ENODEV;
|
||||
|
||||
/* Check for an instantiated RNG before registration */
|
||||
if (!(rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & CHA_ID_LS_RNG_MASK))
|
||||
return -ENODEV;
|
||||
|
||||
dev = caam_jr_alloc();
|
||||
if (IS_ERR(dev)) {
|
||||
pr_err("Job Ring Device allocation for transform failed\n");
|
||||
|
@ -156,9 +156,16 @@ struct jr_outentry {
|
||||
#define CHA_NUM_MS_DECONUM_SHIFT 24
|
||||
#define CHA_NUM_MS_DECONUM_MASK (0xfull << CHA_NUM_MS_DECONUM_SHIFT)
|
||||
|
||||
/* CHA Version IDs */
|
||||
/*
|
||||
* CHA version IDs / instantiation bitfields
|
||||
* Defined for use with the cha_id fields in perfmon, but the same shift/mask
|
||||
* selectors can be used to pull out the number of instantiated blocks within
|
||||
* cha_num fields in perfmon because the locations are the same.
|
||||
*/
|
||||
#define CHA_ID_LS_AES_SHIFT 0
|
||||
#define CHA_ID_LS_AES_MASK (0xfull << CHA_ID_LS_AES_SHIFT)
|
||||
#define CHA_ID_LS_AES_LP (0x3ull << CHA_ID_LS_AES_SHIFT)
|
||||
#define CHA_ID_LS_AES_HP (0x4ull << CHA_ID_LS_AES_SHIFT)
|
||||
|
||||
#define CHA_ID_LS_DES_SHIFT 4
|
||||
#define CHA_ID_LS_DES_MASK (0xfull << CHA_ID_LS_DES_SHIFT)
|
||||
@ -168,6 +175,9 @@ struct jr_outentry {
|
||||
|
||||
#define CHA_ID_LS_MD_SHIFT 12
|
||||
#define CHA_ID_LS_MD_MASK (0xfull << CHA_ID_LS_MD_SHIFT)
|
||||
#define CHA_ID_LS_MD_LP256 (0x0ull << CHA_ID_LS_MD_SHIFT)
|
||||
#define CHA_ID_LS_MD_LP512 (0x1ull << CHA_ID_LS_MD_SHIFT)
|
||||
#define CHA_ID_LS_MD_HP (0x2ull << CHA_ID_LS_MD_SHIFT)
|
||||
|
||||
#define CHA_ID_LS_RNG_SHIFT 16
|
||||
#define CHA_ID_LS_RNG_MASK (0xfull << CHA_ID_LS_RNG_SHIFT)
|
||||
|
Loading…
Reference in New Issue
Block a user