crypto: sa2ul - Add support for AM64
The sa2ul module in am64 have limited support for algorithms, and the priv and priv_id used on the platform is different compared to AM654 or j721e. Use match data to get the SoC specific information and use it throughout the driver. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Vaibhav Gupta <v_gupta@ti.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
e8a4529d45
commit
0bc42311cd
@ -69,8 +69,24 @@
|
|||||||
/* Max Authentication tag size */
|
/* Max Authentication tag size */
|
||||||
#define SA_MAX_AUTH_TAG_SZ 64
|
#define SA_MAX_AUTH_TAG_SZ 64
|
||||||
|
|
||||||
#define PRIV_ID 0x1
|
enum sa_algo_id {
|
||||||
#define PRIV 0x1
|
SA_ALG_CBC_AES = 0,
|
||||||
|
SA_ALG_EBC_AES,
|
||||||
|
SA_ALG_CBC_DES3,
|
||||||
|
SA_ALG_ECB_DES3,
|
||||||
|
SA_ALG_SHA1,
|
||||||
|
SA_ALG_SHA256,
|
||||||
|
SA_ALG_SHA512,
|
||||||
|
SA_ALG_AUTHENC_SHA1_AES,
|
||||||
|
SA_ALG_AUTHENC_SHA256_AES,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sa_match_data {
|
||||||
|
u8 priv;
|
||||||
|
u8 priv_id;
|
||||||
|
u32 supported_algos;
|
||||||
|
bool skip_engine_control;
|
||||||
|
};
|
||||||
|
|
||||||
static struct device *sa_k3_dev;
|
static struct device *sa_k3_dev;
|
||||||
|
|
||||||
@ -696,8 +712,9 @@ static void sa_dump_sc(u8 *buf, dma_addr_t dma_addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int sa_init_sc(struct sa_ctx_info *ctx, const u8 *enc_key,
|
int sa_init_sc(struct sa_ctx_info *ctx, const struct sa_match_data *match_data,
|
||||||
u16 enc_key_sz, const u8 *auth_key, u16 auth_key_sz,
|
const u8 *enc_key, u16 enc_key_sz,
|
||||||
|
const u8 *auth_key, u16 auth_key_sz,
|
||||||
struct algo_data *ad, u8 enc, u32 *swinfo)
|
struct algo_data *ad, u8 enc, u32 *swinfo)
|
||||||
{
|
{
|
||||||
int enc_sc_offset = 0;
|
int enc_sc_offset = 0;
|
||||||
@ -732,8 +749,8 @@ int sa_init_sc(struct sa_ctx_info *ctx, const u8 *enc_key,
|
|||||||
sc_buf[SA_CTX_SCCTL_OWNER_OFFSET] = 0;
|
sc_buf[SA_CTX_SCCTL_OWNER_OFFSET] = 0;
|
||||||
memcpy(&sc_buf[2], &sc_id, 2);
|
memcpy(&sc_buf[2], &sc_id, 2);
|
||||||
sc_buf[4] = 0x0;
|
sc_buf[4] = 0x0;
|
||||||
sc_buf[5] = PRIV_ID;
|
sc_buf[5] = match_data->priv_id;
|
||||||
sc_buf[6] = PRIV;
|
sc_buf[6] = match_data->priv;
|
||||||
sc_buf[7] = 0x0;
|
sc_buf[7] = 0x0;
|
||||||
|
|
||||||
/* Prepare context for encryption engine */
|
/* Prepare context for encryption engine */
|
||||||
@ -892,8 +909,8 @@ static int sa_cipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Setup Encryption Security Context & Command label template */
|
/* Setup Encryption Security Context & Command label template */
|
||||||
if (sa_init_sc(&ctx->enc, key, keylen, NULL, 0, ad, 1,
|
if (sa_init_sc(&ctx->enc, ctx->dev_data->match_data, key, keylen, NULL, 0,
|
||||||
&ctx->enc.epib[1]))
|
ad, 1, &ctx->enc.epib[1]))
|
||||||
goto badkey;
|
goto badkey;
|
||||||
|
|
||||||
cmdl_len = sa_format_cmdl_gen(&cfg,
|
cmdl_len = sa_format_cmdl_gen(&cfg,
|
||||||
@ -905,8 +922,8 @@ static int sa_cipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
|||||||
ctx->enc.cmdl_size = cmdl_len;
|
ctx->enc.cmdl_size = cmdl_len;
|
||||||
|
|
||||||
/* Setup Decryption Security Context & Command label template */
|
/* Setup Decryption Security Context & Command label template */
|
||||||
if (sa_init_sc(&ctx->dec, key, keylen, NULL, 0, ad, 0,
|
if (sa_init_sc(&ctx->dec, ctx->dev_data->match_data, key, keylen, NULL, 0,
|
||||||
&ctx->dec.epib[1]))
|
ad, 0, &ctx->dec.epib[1]))
|
||||||
goto badkey;
|
goto badkey;
|
||||||
|
|
||||||
cfg.enc_eng_id = ad->enc_eng.eng_id;
|
cfg.enc_eng_id = ad->enc_eng.eng_id;
|
||||||
@ -1450,9 +1467,10 @@ static int sa_sha_setup(struct sa_tfm_ctx *ctx, struct algo_data *ad)
|
|||||||
cfg.akey = NULL;
|
cfg.akey = NULL;
|
||||||
cfg.akey_len = 0;
|
cfg.akey_len = 0;
|
||||||
|
|
||||||
|
ctx->dev_data = dev_get_drvdata(sa_k3_dev);
|
||||||
/* Setup Encryption Security Context & Command label template */
|
/* Setup Encryption Security Context & Command label template */
|
||||||
if (sa_init_sc(&ctx->enc, NULL, 0, NULL, 0, ad, 0,
|
if (sa_init_sc(&ctx->enc, ctx->dev_data->match_data, NULL, 0, NULL, 0,
|
||||||
&ctx->enc.epib[1]))
|
ad, 0, &ctx->enc.epib[1]))
|
||||||
goto badkey;
|
goto badkey;
|
||||||
|
|
||||||
cmdl_len = sa_format_cmdl_gen(&cfg,
|
cmdl_len = sa_format_cmdl_gen(&cfg,
|
||||||
@ -1720,6 +1738,7 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memzero_explicit(ctx, sizeof(*ctx));
|
memzero_explicit(ctx, sizeof(*ctx));
|
||||||
|
ctx->dev_data = data;
|
||||||
|
|
||||||
ctx->shash = crypto_alloc_shash(hash, 0, CRYPTO_ALG_NEED_FALLBACK);
|
ctx->shash = crypto_alloc_shash(hash, 0, CRYPTO_ALG_NEED_FALLBACK);
|
||||||
if (IS_ERR(ctx->shash)) {
|
if (IS_ERR(ctx->shash)) {
|
||||||
@ -1821,8 +1840,8 @@ static int sa_aead_setkey(struct crypto_aead *authenc,
|
|||||||
cfg.akey_len = keys.authkeylen;
|
cfg.akey_len = keys.authkeylen;
|
||||||
|
|
||||||
/* Setup Encryption Security Context & Command label template */
|
/* Setup Encryption Security Context & Command label template */
|
||||||
if (sa_init_sc(&ctx->enc, keys.enckey, keys.enckeylen,
|
if (sa_init_sc(&ctx->enc, ctx->dev_data->match_data, keys.enckey,
|
||||||
keys.authkey, keys.authkeylen,
|
keys.enckeylen, keys.authkey, keys.authkeylen,
|
||||||
ad, 1, &ctx->enc.epib[1]))
|
ad, 1, &ctx->enc.epib[1]))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -1835,8 +1854,8 @@ static int sa_aead_setkey(struct crypto_aead *authenc,
|
|||||||
ctx->enc.cmdl_size = cmdl_len;
|
ctx->enc.cmdl_size = cmdl_len;
|
||||||
|
|
||||||
/* Setup Decryption Security Context & Command label template */
|
/* Setup Decryption Security Context & Command label template */
|
||||||
if (sa_init_sc(&ctx->dec, keys.enckey, keys.enckeylen,
|
if (sa_init_sc(&ctx->dec, ctx->dev_data->match_data, keys.enckey,
|
||||||
keys.authkey, keys.authkeylen,
|
keys.enckeylen, keys.authkey, keys.authkeylen,
|
||||||
ad, 0, &ctx->dec.epib[1]))
|
ad, 0, &ctx->dec.epib[1]))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -1954,7 +1973,7 @@ static int sa_aead_decrypt(struct aead_request *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct sa_alg_tmpl sa_algs[] = {
|
static struct sa_alg_tmpl sa_algs[] = {
|
||||||
{
|
[SA_ALG_CBC_AES] = {
|
||||||
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
||||||
.alg.skcipher = {
|
.alg.skcipher = {
|
||||||
.base.cra_name = "cbc(aes)",
|
.base.cra_name = "cbc(aes)",
|
||||||
@ -1977,7 +1996,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.decrypt = sa_decrypt,
|
.decrypt = sa_decrypt,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_EBC_AES] = {
|
||||||
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
||||||
.alg.skcipher = {
|
.alg.skcipher = {
|
||||||
.base.cra_name = "ecb(aes)",
|
.base.cra_name = "ecb(aes)",
|
||||||
@ -1999,7 +2018,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.decrypt = sa_decrypt,
|
.decrypt = sa_decrypt,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_CBC_DES3] = {
|
||||||
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
||||||
.alg.skcipher = {
|
.alg.skcipher = {
|
||||||
.base.cra_name = "cbc(des3_ede)",
|
.base.cra_name = "cbc(des3_ede)",
|
||||||
@ -2022,7 +2041,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.decrypt = sa_decrypt,
|
.decrypt = sa_decrypt,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_ECB_DES3] = {
|
||||||
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
||||||
.alg.skcipher = {
|
.alg.skcipher = {
|
||||||
.base.cra_name = "ecb(des3_ede)",
|
.base.cra_name = "ecb(des3_ede)",
|
||||||
@ -2044,7 +2063,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.decrypt = sa_decrypt,
|
.decrypt = sa_decrypt,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_SHA1] = {
|
||||||
.type = CRYPTO_ALG_TYPE_AHASH,
|
.type = CRYPTO_ALG_TYPE_AHASH,
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
@ -2073,7 +2092,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.import = sa_sha_import,
|
.import = sa_sha_import,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_SHA256] = {
|
||||||
.type = CRYPTO_ALG_TYPE_AHASH,
|
.type = CRYPTO_ALG_TYPE_AHASH,
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
@ -2102,7 +2121,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.import = sa_sha_import,
|
.import = sa_sha_import,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_SHA512] = {
|
||||||
.type = CRYPTO_ALG_TYPE_AHASH,
|
.type = CRYPTO_ALG_TYPE_AHASH,
|
||||||
.alg.ahash = {
|
.alg.ahash = {
|
||||||
.halg.base = {
|
.halg.base = {
|
||||||
@ -2131,7 +2150,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.import = sa_sha_import,
|
.import = sa_sha_import,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_AUTHENC_SHA1_AES] = {
|
||||||
.type = CRYPTO_ALG_TYPE_AEAD,
|
.type = CRYPTO_ALG_TYPE_AEAD,
|
||||||
.alg.aead = {
|
.alg.aead = {
|
||||||
.base = {
|
.base = {
|
||||||
@ -2158,7 +2177,7 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
.decrypt = sa_aead_decrypt,
|
.decrypt = sa_aead_decrypt,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
[SA_ALG_AUTHENC_SHA256_AES] = {
|
||||||
.type = CRYPTO_ALG_TYPE_AEAD,
|
.type = CRYPTO_ALG_TYPE_AEAD,
|
||||||
.alg.aead = {
|
.alg.aead = {
|
||||||
.base = {
|
.base = {
|
||||||
@ -2189,13 +2208,19 @@ static struct sa_alg_tmpl sa_algs[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Register the algorithms in crypto framework */
|
/* Register the algorithms in crypto framework */
|
||||||
static void sa_register_algos(const struct device *dev)
|
static void sa_register_algos(struct sa_crypto_data *dev_data)
|
||||||
{
|
{
|
||||||
|
const struct sa_match_data *match_data = dev_data->match_data;
|
||||||
|
struct device *dev = dev_data->dev;
|
||||||
char *alg_name;
|
char *alg_name;
|
||||||
u32 type;
|
u32 type;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(sa_algs); i++) {
|
for (i = 0; i < ARRAY_SIZE(sa_algs); i++) {
|
||||||
|
/* Skip unsupported algos */
|
||||||
|
if (!(match_data->supported_algos & BIT(i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
type = sa_algs[i].type;
|
type = sa_algs[i].type;
|
||||||
if (type == CRYPTO_ALG_TYPE_SKCIPHER) {
|
if (type == CRYPTO_ALG_TYPE_SKCIPHER) {
|
||||||
alg_name = sa_algs[i].alg.skcipher.base.cra_name;
|
alg_name = sa_algs[i].alg.skcipher.base.cra_name;
|
||||||
@ -2333,14 +2358,39 @@ static int sa_link_child(struct device *dev, void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct sa_match_data am654_match_data = {
|
||||||
|
.priv = 1,
|
||||||
|
.priv_id = 1,
|
||||||
|
.supported_algos = GENMASK(SA_ALG_AUTHENC_SHA256_AES, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sa_match_data am64_match_data = {
|
||||||
|
.priv = 0,
|
||||||
|
.priv_id = 0,
|
||||||
|
.supported_algos = BIT(SA_ALG_CBC_AES) |
|
||||||
|
BIT(SA_ALG_EBC_AES) |
|
||||||
|
BIT(SA_ALG_SHA256) |
|
||||||
|
BIT(SA_ALG_SHA512) |
|
||||||
|
BIT(SA_ALG_AUTHENC_SHA256_AES),
|
||||||
|
.skip_engine_control = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id of_match[] = {
|
||||||
|
{ .compatible = "ti,j721e-sa2ul", .data = &am654_match_data, },
|
||||||
|
{ .compatible = "ti,am654-sa2ul", .data = &am654_match_data, },
|
||||||
|
{ .compatible = "ti,am64-sa2ul", .data = &am64_match_data, },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, of_match);
|
||||||
|
|
||||||
static int sa_ul_probe(struct platform_device *pdev)
|
static int sa_ul_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
const struct of_device_id *match;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *node = dev->of_node;
|
struct device_node *node = dev->of_node;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
static void __iomem *saul_base;
|
static void __iomem *saul_base;
|
||||||
struct sa_crypto_data *dev_data;
|
struct sa_crypto_data *dev_data;
|
||||||
u32 val;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dev_data = devm_kzalloc(dev, sizeof(*dev_data), GFP_KERNEL);
|
dev_data = devm_kzalloc(dev, sizeof(*dev_data), GFP_KERNEL);
|
||||||
@ -2366,18 +2416,28 @@ static int sa_ul_probe(struct platform_device *pdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto disable_pm_runtime;
|
goto disable_pm_runtime;
|
||||||
|
|
||||||
|
match = of_match_node(of_match, dev->of_node);
|
||||||
|
if (!match) {
|
||||||
|
dev_err(dev, "No compatible match found\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
dev_data->match_data = match->data;
|
||||||
|
|
||||||
spin_lock_init(&dev_data->scid_lock);
|
spin_lock_init(&dev_data->scid_lock);
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
saul_base = devm_ioremap_resource(dev, res);
|
saul_base = devm_ioremap_resource(dev, res);
|
||||||
|
|
||||||
dev_data->base = saul_base;
|
dev_data->base = saul_base;
|
||||||
val = SA_EEC_ENCSS_EN | SA_EEC_AUTHSS_EN | SA_EEC_CTXCACH_EN |
|
|
||||||
SA_EEC_CPPI_PORT_IN_EN | SA_EEC_CPPI_PORT_OUT_EN |
|
|
||||||
SA_EEC_TRNG_EN;
|
|
||||||
|
|
||||||
writel_relaxed(val, saul_base + SA_ENGINE_ENABLE_CONTROL);
|
if (!dev_data->match_data->skip_engine_control) {
|
||||||
|
u32 val = SA_EEC_ENCSS_EN | SA_EEC_AUTHSS_EN | SA_EEC_CTXCACH_EN |
|
||||||
|
SA_EEC_CPPI_PORT_IN_EN | SA_EEC_CPPI_PORT_OUT_EN |
|
||||||
|
SA_EEC_TRNG_EN;
|
||||||
|
|
||||||
sa_register_algos(dev);
|
writel_relaxed(val, saul_base + SA_ENGINE_ENABLE_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
sa_register_algos(dev_data);
|
||||||
|
|
||||||
ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
|
ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -2423,13 +2483,6 @@ static int sa_ul_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id of_match[] = {
|
|
||||||
{.compatible = "ti,j721e-sa2ul",},
|
|
||||||
{.compatible = "ti,am654-sa2ul",},
|
|
||||||
{},
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(of, of_match);
|
|
||||||
|
|
||||||
static struct platform_driver sa_ul_driver = {
|
static struct platform_driver sa_ul_driver = {
|
||||||
.probe = sa_ul_probe,
|
.probe = sa_ul_probe,
|
||||||
.remove = sa_ul_remove,
|
.remove = sa_ul_remove,
|
||||||
|
@ -171,9 +171,12 @@ struct sa_tfm_ctx;
|
|||||||
#define SA_UNSAFE_DATA_SZ_MIN 240
|
#define SA_UNSAFE_DATA_SZ_MIN 240
|
||||||
#define SA_UNSAFE_DATA_SZ_MAX 256
|
#define SA_UNSAFE_DATA_SZ_MAX 256
|
||||||
|
|
||||||
|
struct sa_match_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct sa_crypto_data - Crypto driver instance data
|
* struct sa_crypto_data - Crypto driver instance data
|
||||||
* @base: Base address of the register space
|
* @base: Base address of the register space
|
||||||
|
* @soc_data: Pointer to SoC specific data
|
||||||
* @pdev: Platform device pointer
|
* @pdev: Platform device pointer
|
||||||
* @sc_pool: security context pool
|
* @sc_pool: security context pool
|
||||||
* @dev: Device pointer
|
* @dev: Device pointer
|
||||||
@ -189,6 +192,7 @@ struct sa_tfm_ctx;
|
|||||||
*/
|
*/
|
||||||
struct sa_crypto_data {
|
struct sa_crypto_data {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
const struct sa_match_data *match_data;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
struct dma_pool *sc_pool;
|
struct dma_pool *sc_pool;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
Loading…
Reference in New Issue
Block a user