diff options
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r-- | drivers/crypto/caam/caamalg.c | 84 | ||||
-rw-r--r-- | drivers/crypto/caam/caamalg_qi.c | 73 | ||||
-rw-r--r-- | drivers/crypto/caam/caamalg_qi2.c | 251 | ||||
-rw-r--r-- | drivers/crypto/caam/caamalg_qi2.h | 2 | ||||
-rw-r--r-- | drivers/crypto/caam/caampkc.c | 2 | ||||
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 20 | ||||
-rw-r--r-- | drivers/crypto/caam/error.c | 4 | ||||
-rw-r--r-- | drivers/crypto/caam/intern.h | 4 | ||||
-rw-r--r-- | drivers/crypto/caam/jr.c | 31 | ||||
-rw-r--r-- | drivers/crypto/caam/qi.c | 4 | ||||
-rw-r--r-- | drivers/crypto/caam/regs.h | 3 |
11 files changed, 303 insertions, 175 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 579578498deb..c0ece44f303b 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -89,6 +89,7 @@ struct caam_alg_entry { int class2_alg_type; bool rfc3686; bool geniv; + bool nodkp; }; struct caam_aead_alg { @@ -638,6 +639,39 @@ badkey: return -EINVAL; } +static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key, + unsigned int keylen) +{ + struct crypto_authenc_keys keys; + u32 flags; + int err; + + err = crypto_authenc_extractkeys(&keys, key, keylen); + if (unlikely(err)) + goto badkey; + + err = -EINVAL; + if (keys.enckeylen != DES3_EDE_KEY_SIZE) + goto badkey; + + flags = crypto_aead_get_flags(aead); + err = __des3_verify_key(&flags, keys.enckey); + if (unlikely(err)) { + crypto_aead_set_flags(aead, flags); + goto out; + } + + err = aead_setkey(aead, key, keylen); + +out: + memzero_explicit(&keys, sizeof(keys)); + return err; + +badkey: + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + goto out; +} + static int gcm_setkey(struct crypto_aead *aead, const u8 *key, unsigned int keylen) { @@ -2019,6 +2053,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, }, }, { @@ -2037,6 +2072,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, }, }, /* Galois Counter Mode */ @@ -2056,6 +2092,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, }, }, /* single-pass ipsec_esp descriptor */ @@ -2457,7 +2494,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2479,7 +2516,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2502,7 +2539,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2525,7 +2562,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2548,7 +2585,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2571,7 +2608,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2594,7 +2631,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2617,7 +2654,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2640,7 +2677,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2663,7 +2700,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2686,7 +2723,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2709,7 +2746,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -3301,6 +3338,7 @@ static struct caam_aead_alg driver_aeads[] = { OP_ALG_AAI_AEAD, .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | OP_ALG_AAI_AEAD, + .nodkp = true, }, }, { @@ -3323,6 +3361,7 @@ static struct caam_aead_alg driver_aeads[] = { OP_ALG_AAI_AEAD, .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | OP_ALG_AAI_AEAD, + .nodkp = true, }, }, }; @@ -3384,8 +3423,7 @@ static int caam_aead_init(struct crypto_aead *tfm) container_of(alg, struct caam_aead_alg, aead); struct caam_ctx *ctx = crypto_aead_ctx(tfm); - return caam_init_common(ctx, &caam_alg->caam, - alg->setkey == aead_setkey); + return caam_init_common(ctx, &caam_alg->caam, !caam_alg->caam.nodkp); } static void caam_exit_common(struct caam_ctx *ctx) @@ -3460,7 +3498,7 @@ static int __init caam_algapi_init(void) u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst; u32 arc4_inst; unsigned int md_limit = SHA512_DIGEST_SIZE; - bool registered = false; + bool registered = false, gcm_support; dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); if (!dev_node) { @@ -3493,7 +3531,7 @@ static int __init caam_algapi_init(void) * First, detect presence and attributes of DES, AES, and MD blocks. */ if (priv->era < 10) { - u32 cha_vid, cha_inst; + u32 cha_vid, cha_inst, aes_rn; cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls); aes_vid = cha_vid & CHA_ID_LS_AES_MASK; @@ -3508,6 +3546,10 @@ static int __init caam_algapi_init(void) CHA_ID_LS_ARC4_SHIFT; ccha_inst = 0; ptha_inst = 0; + + aes_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls) & + CHA_ID_LS_AES_MASK; + gcm_support = !(aes_vid == CHA_VER_VID_AES_LP && aes_rn < 8); } else { u32 aesa, mdha; @@ -3523,6 +3565,8 @@ static int __init caam_algapi_init(void) ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK; ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK; arc4_inst = rd_reg32(&priv->ctrl->vreg.afha) & CHA_VER_NUM_MASK; + + gcm_support = aesa & CHA_VER_MISC_AES_GCM; } /* If MD is present, limit digest size based on LP256 */ @@ -3595,11 +3639,9 @@ static int __init caam_algapi_init(void) if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst) continue; - /* - * Check support for AES algorithms not available - * on LP devices. - */ - if (aes_vid == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM) + /* Skip GCM algorithms if not supported by device */ + if (c1_alg_sel == OP_ALG_ALGSEL_AES && + alg_aai == OP_ALG_AAI_GCM && !gcm_support) continue; /* diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index c61921d32489..d290d6b41825 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -36,6 +36,7 @@ struct caam_alg_entry { int class2_alg_type; bool rfc3686; bool geniv; + bool nodkp; }; struct caam_aead_alg { @@ -292,6 +293,39 @@ badkey: return -EINVAL; } +static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key, + unsigned int keylen) +{ + struct crypto_authenc_keys keys; + u32 flags; + int err; + + err = crypto_authenc_extractkeys(&keys, key, keylen); + if (unlikely(err)) + goto badkey; + + err = -EINVAL; + if (keys.enckeylen != DES3_EDE_KEY_SIZE) + goto badkey; + + flags = crypto_aead_get_flags(aead); + err = __des3_verify_key(&flags, keys.enckey); + if (unlikely(err)) { + crypto_aead_set_flags(aead, flags); + goto out; + } + + err = aead_setkey(aead, key, keylen); + +out: + memzero_explicit(&keys, sizeof(keys)); + return err; + +badkey: + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + goto out; +} + static int gcm_set_sh_desc(struct crypto_aead *aead) { struct caam_ctx *ctx = crypto_aead_ctx(aead); @@ -667,6 +701,13 @@ badkey: return -EINVAL; } +static int des3_skcipher_setkey(struct crypto_skcipher *skcipher, + const u8 *key, unsigned int keylen) +{ + return unlikely(des3_verify_key(skcipher, key)) ?: + skcipher_setkey(skcipher, key, keylen); +} + static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, unsigned int keylen) { @@ -1382,7 +1423,7 @@ static struct caam_skcipher_alg driver_algs[] = { .cra_driver_name = "cbc-3des-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = skcipher_setkey, + .setkey = des3_skcipher_setkey, .encrypt = skcipher_encrypt, .decrypt = skcipher_decrypt, .min_keysize = DES3_EDE_KEY_SIZE, @@ -1483,6 +1524,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, }, }, { @@ -1501,6 +1543,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, }, }, /* Galois Counter Mode */ @@ -1520,6 +1563,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, } }, /* single-pass ipsec_esp descriptor */ @@ -1798,7 +1842,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1820,7 +1864,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1843,7 +1887,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1866,7 +1910,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1889,7 +1933,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1912,7 +1956,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1935,7 +1979,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1958,7 +2002,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1981,7 +2025,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2004,7 +2048,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2027,7 +2071,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2050,7 +2094,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2393,8 +2437,7 @@ static int caam_aead_init(struct crypto_aead *tfm) aead); struct caam_ctx *ctx = crypto_aead_ctx(tfm); - return caam_init_common(ctx, &caam_alg->caam, - alg->setkey == aead_setkey); + return caam_init_common(ctx, &caam_alg->caam, !caam_alg->caam.nodkp); } static void caam_exit_common(struct caam_ctx *ctx) diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c index c2c1abc68f81..2b2980a8a9b9 100644 --- a/drivers/crypto/caam/caamalg_qi2.c +++ b/drivers/crypto/caam/caamalg_qi2.c @@ -42,6 +42,7 @@ struct caam_alg_entry { int class2_alg_type; bool rfc3686; bool geniv; + bool nodkp; }; struct caam_aead_alg { @@ -323,6 +324,39 @@ badkey: return -EINVAL; } +static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key, + unsigned int keylen) +{ + struct crypto_authenc_keys keys; + u32 flags; + int err; + + err = crypto_authenc_extractkeys(&keys, key, keylen); + if (unlikely(err)) + goto badkey; + + err = -EINVAL; + if (keys.enckeylen != DES3_EDE_KEY_SIZE) + goto badkey; + + flags = crypto_aead_get_flags(aead); + err = __des3_verify_key(&flags, keys.enckey); + if (unlikely(err)) { + crypto_aead_set_flags(aead, flags); + goto out; + } + + err = aead_setkey(aead, key, keylen); + +out: + memzero_explicit(&keys, sizeof(keys)); + return err; + +badkey: + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + goto out; +} + static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, bool encrypt) { @@ -938,6 +972,13 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, return 0; } +static int des3_skcipher_setkey(struct crypto_skcipher *skcipher, + const u8 *key, unsigned int keylen) +{ + return unlikely(des3_verify_key(skcipher, key)) ?: + skcipher_setkey(skcipher, key, keylen); +} + static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, unsigned int keylen) { @@ -1440,7 +1481,7 @@ static int caam_cra_init_aead(struct crypto_aead *tfm) crypto_aead_set_reqsize(tfm, sizeof(struct caam_request)); return caam_cra_init(crypto_aead_ctx(tfm), &caam_alg->caam, - alg->setkey == aead_setkey); + !caam_alg->caam.nodkp); } static void caam_exit_common(struct caam_ctx *ctx) @@ -1484,7 +1525,7 @@ static struct caam_skcipher_alg driver_algs[] = { .cra_driver_name = "cbc-3des-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = skcipher_setkey, + .setkey = des3_skcipher_setkey, .encrypt = skcipher_encrypt, .decrypt = skcipher_decrypt, .min_keysize = DES3_EDE_KEY_SIZE, @@ -1601,6 +1642,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, }, }, { @@ -1619,6 +1661,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, }, }, /* Galois Counter Mode */ @@ -1638,6 +1681,7 @@ static struct caam_aead_alg driver_aeads[] = { }, .caam = { .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, + .nodkp = true, } }, /* single-pass ipsec_esp descriptor */ @@ -1916,7 +1960,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1938,7 +1982,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1961,7 +2005,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -1984,7 +2028,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2007,7 +2051,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2030,7 +2074,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2053,7 +2097,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2076,7 +2120,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2099,7 +2143,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2122,7 +2166,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2145,7 +2189,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2168,7 +2212,7 @@ static struct caam_aead_alg driver_aeads[] = { "cbc-des3_ede-caam-qi2", .cra_blocksize = DES3_EDE_BLOCK_SIZE, }, - .setkey = aead_setkey, + .setkey = des3_aead_setkey, .setauthsize = aead_setauthsize, .encrypt = aead_encrypt, .decrypt = aead_decrypt, @@ -2715,6 +2759,7 @@ static struct caam_aead_alg driver_aeads[] = { OP_ALG_AAI_AEAD, .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | OP_ALG_AAI_AEAD, + .nodkp = true, }, }, { @@ -2737,6 +2782,7 @@ static struct caam_aead_alg driver_aeads[] = { OP_ALG_AAI_AEAD, .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | OP_ALG_AAI_AEAD, + .nodkp = true, }, }, { @@ -2854,6 +2900,7 @@ struct caam_hash_state { struct caam_request caam_req; dma_addr_t buf_dma; dma_addr_t ctx_dma; + int ctx_dma_len; u8 buf_0[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned; int buflen_0; u8 buf_1[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned; @@ -2927,6 +2974,7 @@ static inline int ctx_map_to_qm_sg(struct device *dev, struct caam_hash_state *state, int ctx_len, struct dpaa2_sg_entry *qm_sg, u32 flag) { + state->ctx_dma_len = ctx_len; state->ctx_dma = dma_map_single(dev, state->caam_ctx, ctx_len, flag); if (dma_mapping_error(dev, state->ctx_dma)) { dev_err(dev, "unable to map ctx\n"); @@ -3018,13 +3066,13 @@ static void split_key_sh_done(void *cbk_ctx, u32 err) } /* Digest hash size if it is too large */ -static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in, - u32 *keylen, u8 *key_out, u32 digestsize) +static int hash_digest_key(struct caam_hash_ctx *ctx, u32 *keylen, u8 *key, + u32 digestsize) { struct caam_request *req_ctx; u32 *desc; struct split_key_sh_result result; - dma_addr_t src_dma, dst_dma; + dma_addr_t key_dma; struct caam_flc *flc; dma_addr_t flc_dma; int ret = -ENOMEM; @@ -3041,17 +3089,10 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in, if (!flc) goto err_flc; - src_dma = dma_map_single(ctx->dev, (void *)key_in, *keylen, - DMA_TO_DEVICE); - if (dma_mapping_error(ctx->dev, src_dma)) { - dev_err(ctx->dev, "unable to map key input memory\n"); - goto err_src_dma; - } - dst_dma = dma_map_single(ctx->dev, (void *)key_out, digestsize, - DMA_FROM_DEVICE); - if (dma_mapping_error(ctx->dev, dst_dma)) { - dev_err(ctx->dev, "unable to map key output memory\n"); - goto err_dst_dma; + key_dma = dma_map_single(ctx->dev, key, *keylen, DMA_BIDIRECTIONAL); + if (dma_mapping_error(ctx->dev, key_dma)) { + dev_err(ctx->dev, "unable to map key memory\n"); + goto err_key_dma; } desc = flc->sh_desc; @@ -3076,14 +3117,14 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in, dpaa2_fl_set_final(in_fle, true); dpaa2_fl_set_format(in_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(in_fle, src_dma); + dpaa2_fl_set_addr(in_fle, key_dma); dpaa2_fl_set_len(in_fle, *keylen); dpaa2_fl_set_format(out_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(out_fle, dst_dma); + dpaa2_fl_set_addr(out_fle, key_dma); dpaa2_fl_set_len(out_fle, digestsize); print_hex_dump_debug("key_in@" __stringify(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, key_in, *keylen, 1); + DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1); print_hex_dump_debug("shdesc@" __stringify(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); @@ -3103,17 +3144,15 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in, wait_for_completion(&result.completion); ret = result.err; print_hex_dump_debug("digested key@" __stringify(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, key_in, + DUMP_PREFIX_ADDRESS, 16, 4, key, digestsize, 1); } dma_unmap_single(ctx->dev, flc_dma, sizeof(flc->flc) + desc_bytes(desc), DMA_TO_DEVICE); err_flc_dma: - dma_unmap_single(ctx->dev, dst_dma, digestsize, DMA_FROM_DEVICE); -err_dst_dma: - dma_unmap_single(ctx->dev, src_dma, *keylen, DMA_TO_DEVICE); -err_src_dma: + dma_unmap_single(ctx->dev, key_dma, *keylen, DMA_BIDIRECTIONAL); +err_key_dma: kfree(flc); err_flc: kfree(req_ctx); @@ -3135,12 +3174,10 @@ static int ahash_setkey(struct crypto_ahash *ahash, const u8 *key, dev_dbg(ctx->dev, "keylen %d blocksize %d\n", keylen, blocksize); if (keylen > blocksize) { - hashed_key = kmalloc_array(digestsize, sizeof(*hashed_key), - GFP_KERNEL | GFP_DMA); + hashed_key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA); if (!hashed_key) return -ENOMEM; - ret = hash_digest_key(ctx, key, &keylen, hashed_key, - digestsize); + ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize); if (ret) goto bad_free_key; key = hashed_key; @@ -3165,14 +3202,12 @@ bad_free_key: } static inline void ahash_unmap(struct device *dev, struct ahash_edesc *edesc, - struct ahash_request *req, int dst_len) + struct ahash_request *req) { struct caam_hash_state *state = ahash_request_ctx(req); if (edesc->src_nents) dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE); - if (edesc->dst_dma) - dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE); if (edesc->qm_sg_bytes) dma_unmap_single(dev, edesc->qm_sg_dma, edesc->qm_sg_bytes, @@ -3187,18 +3222,15 @@ static inline void ahash_unmap(struct device *dev, struct ahash_edesc *edesc, static inline void ahash_unmap_ctx(struct device *dev, struct ahash_edesc *edesc, - struct ahash_request *req, int dst_len, - u32 flag) + struct ahash_request *req, u32 flag) { - struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); - struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct caam_hash_state *state = ahash_request_ctx(req); if (state->ctx_dma) { - dma_unmap_single(dev, state->ctx_dma, ctx->ctx_len, flag); + dma_unmap_single(dev, state->ctx_dma, state->ctx_dma_len, flag); state->ctx_dma = 0; } - ahash_unmap(dev, edesc, req, dst_len); + ahash_unmap(dev, edesc, req); } static void ahash_done(void *cbk_ctx, u32 status) @@ -3219,16 +3251,13 @@ static void ahash_done(void *cbk_ctx, u32 status) ecode = -EIO; } - ahash_unmap(ctx->dev, edesc, req, digestsize); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); + memcpy(req->result, state->caam_ctx, digestsize); qi_cache_free(edesc); print_hex_dump_debug("ctx@" __stringify(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, ctx->ctx_len, 1); - if (req->result) - print_hex_dump_debug("result@" __stringify(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, req->result, - digestsize, 1); req->base.complete(&req->base, ecode); } @@ -3250,7 +3279,7 @@ static void ahash_done_bi(void *cbk_ctx, u32 status) ecode = -EIO; } - ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_BIDIRECTIONAL); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); switch_buf(state); qi_cache_free(edesc); @@ -3283,16 +3312,13 @@ static void ahash_done_ctx_src(void *cbk_ctx, u32 status) ecode = -EIO; } - ahash_unmap_ctx(ctx->dev, edesc, req, digestsize, DMA_TO_DEVICE); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); + memcpy(req->result, state->caam_ctx, digestsize); qi_cache_free(edesc); print_hex_dump_debug("ctx@" __stringify(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, ctx->ctx_len, 1); - if (req->result) - print_hex_dump_debug("result@" __stringify(__LINE__)": ", - DUMP_PREFIX_ADDRESS, 16, 4, req->result, - digestsize, 1); req->base.complete(&req->base, ecode); } @@ -3314,7 +3340,7 @@ static void ahash_done_ctx_dst(void *cbk_ctx, u32 status) ecode = -EIO; } - ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_FROM_DEVICE); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); switch_buf(state); qi_cache_free(edesc); @@ -3452,7 +3478,7 @@ static int ahash_update_ctx(struct ahash_request *req) return ret; unmap_ctx: - ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_BIDIRECTIONAL); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); qi_cache_free(edesc); return ret; } @@ -3484,7 +3510,7 @@ static int ahash_final_ctx(struct ahash_request *req) sg_table = &edesc->sgt[0]; ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table, - DMA_TO_DEVICE); + DMA_BIDIRECTIONAL); if (ret) goto unmap_ctx; @@ -3503,22 +3529,13 @@ static int ahash_final_ctx(struct ahash_request *req) } edesc->qm_sg_bytes = qm_sg_bytes; - edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize, - DMA_FROM_DEVICE); - if (dma_mapping_error(ctx->dev, edesc->dst_dma)) { - dev_err(ctx->dev, "unable to map dst\n"); - edesc->dst_dma = 0; - ret = -ENOMEM; - goto unmap_ctx; - } - memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); dpaa2_fl_set_final(in_fle, true); dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen); dpaa2_fl_set_format(out_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(out_fle, edesc->dst_dma); + dpaa2_fl_set_addr(out_fle, state->ctx_dma); dpaa2_fl_set_len(out_fle, digestsize); req_ctx->flc = &ctx->flc[FINALIZE]; @@ -3533,7 +3550,7 @@ static int ahash_final_ctx(struct ahash_request *req) return ret; unmap_ctx: - ahash_unmap_ctx(ctx->dev, edesc, req, digestsize, DMA_FROM_DEVICE); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); qi_cache_free(edesc); return ret; } @@ -3586,7 +3603,7 @@ static int ahash_finup_ctx(struct ahash_request *req) sg_table = &edesc->sgt[0]; ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table, - DMA_TO_DEVICE); + DMA_BIDIRECTIONAL); if (ret) goto unmap_ctx; @@ -3605,22 +3622,13 @@ static int ahash_finup_ctx(struct ahash_request *req) } edesc->qm_sg_bytes = qm_sg_bytes; - edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize, - DMA_FROM_DEVICE); - if (dma_mapping_error(ctx->dev, edesc->dst_dma)) { - dev_err(ctx->dev, "unable to map dst\n"); - edesc->dst_dma = 0; - ret = -ENOMEM; - goto unmap_ctx; - } - memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); dpaa2_fl_set_final(in_fle, true); dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen + req->nbytes); dpaa2_fl_set_format(out_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(out_fle, edesc->dst_dma); + dpaa2_fl_set_addr(out_fle, state->ctx_dma); dpaa2_fl_set_len(out_fle, digestsize); req_ctx->flc = &ctx->flc[FINALIZE]; @@ -3635,7 +3643,7 @@ static int ahash_finup_ctx(struct ahash_request *req) return ret; unmap_ctx: - ahash_unmap_ctx(ctx->dev, edesc, req, digestsize, DMA_FROM_DEVICE); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); qi_cache_free(edesc); return ret; } @@ -3704,18 +3712,19 @@ static int ahash_digest(struct ahash_request *req) dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src)); } - edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize, + state->ctx_dma_len = digestsize; + state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize, DMA_FROM_DEVICE); - if (dma_mapping_error(ctx->dev, edesc->dst_dma)) { - dev_err(ctx->dev, "unable to map dst\n"); - edesc->dst_dma = 0; + if (dma_mapping_error(ctx->dev, state->ctx_dma)) { + dev_err(ctx->dev, "unable to map ctx\n"); + state->ctx_dma = 0; goto unmap; } dpaa2_fl_set_final(in_fle, true); dpaa2_fl_set_len(in_fle, req->nbytes); dpaa2_fl_set_format(out_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(out_fle, edesc->dst_dma); + dpaa2_fl_set_addr(out_fle, state->ctx_dma); dpaa2_fl_set_len(out_fle, digestsize); req_ctx->flc = &ctx->flc[DIGEST]; @@ -3729,7 +3738,7 @@ static int ahash_digest(struct ahash_request *req) return ret; unmap: - ahash_unmap(ctx->dev, edesc, req, digestsize); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); qi_cache_free(edesc); return ret; } @@ -3755,27 +3764,39 @@ static int ahash_final_no_ctx(struct ahash_request *req) if (!edesc) return ret; - state->buf_dma = dma_map_single(ctx->dev, buf, buflen, DMA_TO_DEVICE); - if (dma_mapping_error(ctx->dev, state->buf_dma)) { - dev_err(ctx->dev, "unable to map src\n"); - goto unmap; + if (buflen) { + state->buf_dma = dma_map_single(ctx->dev, buf, buflen, + DMA_TO_DEVICE); + if (dma_mapping_error(ctx->dev, state->buf_dma)) { + dev_err(ctx->dev, "unable to map src\n"); + goto unmap; + } } - edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize, + state->ctx_dma_len = digestsize; + state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize, DMA_FROM_DEVICE); - if (dma_mapping_error(ctx->dev, edesc->dst_dma)) { - dev_err(ctx->dev, "unable to map dst\n"); - edesc->dst_dma = 0; + if (dma_mapping_error(ctx->dev, state->ctx_dma)) { + dev_err(ctx->dev, "unable to map ctx\n"); + state->ctx_dma = 0; goto unmap; } memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); dpaa2_fl_set_final(in_fle, true); - dpaa2_fl_set_format(in_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(in_fle, state->buf_dma); - dpaa2_fl_set_len(in_fle, buflen); + /* + * crypto engine requires the input entry to be present when + * "frame list" FD is used. + * Since engine does not support FMT=2'b11 (unused entry type), leaving + * in_fle zeroized (except for "Final" flag) is the best option. + */ + if (buflen) { + dpaa2_fl_set_format(in_fle, dpaa2_fl_single); + dpaa2_fl_set_addr(in_fle, state->buf_dma); + dpaa2_fl_set_len(in_fle, buflen); + } dpaa2_fl_set_format(out_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(out_fle, edesc->dst_dma); + dpaa2_fl_set_addr(out_fle, state->ctx_dma); dpaa2_fl_set_len(out_fle, digestsize); req_ctx->flc = &ctx->flc[DIGEST]; @@ -3790,7 +3811,7 @@ static int ahash_final_no_ctx(struct ahash_request *req) return ret; unmap: - ahash_unmap(ctx->dev, edesc, req, digestsize); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); qi_cache_free(edesc); return ret; } @@ -3870,6 +3891,7 @@ static int ahash_update_no_ctx(struct ahash_request *req) } edesc->qm_sg_bytes = qm_sg_bytes; + state->ctx_dma_len = ctx->ctx_len; state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, ctx->ctx_len, DMA_FROM_DEVICE); if (dma_mapping_error(ctx->dev, state->ctx_dma)) { @@ -3918,7 +3940,7 @@ static int ahash_update_no_ctx(struct ahash_request *req) return ret; unmap_ctx: - ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_TO_DEVICE); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_TO_DEVICE); qi_cache_free(edesc); return ret; } @@ -3983,11 +4005,12 @@ static int ahash_finup_no_ctx(struct ahash_request *req) } edesc->qm_sg_bytes = qm_sg_bytes; - edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize, + state->ctx_dma_len = digestsize; + state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize, DMA_FROM_DEVICE); - if (dma_mapping_error(ctx->dev, edesc->dst_dma)) { - dev_err(ctx->dev, "unable to map dst\n"); - edesc->dst_dma = 0; + if (dma_mapping_error(ctx->dev, state->ctx_dma)) { + dev_err(ctx->dev, "unable to map ctx\n"); + state->ctx_dma = 0; ret = -ENOMEM; goto unmap; } @@ -3998,7 +4021,7 @@ static int ahash_finup_no_ctx(struct ahash_request *req) dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); dpaa2_fl_set_len(in_fle, buflen + req->nbytes); dpaa2_fl_set_format(out_fle, dpaa2_fl_single); - dpaa2_fl_set_addr(out_fle, edesc->dst_dma); + dpaa2_fl_set_addr(out_fle, state->ctx_dma); dpaa2_fl_set_len(out_fle, digestsize); req_ctx->flc = &ctx->flc[DIGEST]; @@ -4013,7 +4036,7 @@ static int ahash_finup_no_ctx(struct ahash_request *req) return ret; unmap: - ahash_unmap(ctx->dev, edesc, req, digestsize); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); qi_cache_free(edesc); return -ENOMEM; } @@ -4100,6 +4123,7 @@ static int ahash_update_first(struct ahash_request *req) scatterwalk_map_and_copy(next_buf, req->src, to_hash, *next_buflen, 0); + state->ctx_dma_len = ctx->ctx_len; state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, ctx->ctx_len, DMA_FROM_DEVICE); if (dma_mapping_error(ctx->dev, state->ctx_dma)) { @@ -4143,7 +4167,7 @@ static int ahash_update_first(struct ahash_request *req) return ret; unmap_ctx: - ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_TO_DEVICE); + ahash_unmap_ctx(ctx->dev, edesc, req, DMA_TO_DEVICE); qi_cache_free(edesc); return ret; } @@ -4162,6 +4186,7 @@ static int ahash_init(struct ahash_request *req) state->final = ahash_final_no_ctx; state->ctx_dma = 0; + state->ctx_dma_len = 0; state->current_buf = 0; state->buf_dma = 0; state->buflen_0 = 0; diff --git a/drivers/crypto/caam/caamalg_qi2.h b/drivers/crypto/caam/caamalg_qi2.h index 20890780fb82..be5085451053 100644 --- a/drivers/crypto/caam/caamalg_qi2.h +++ b/drivers/crypto/caam/caamalg_qi2.h @@ -162,14 +162,12 @@ struct skcipher_edesc { /* * ahash_edesc - s/w-extended ahash descriptor - * @dst_dma: I/O virtual address of req->result * @qm_sg_dma: I/O virtual address of h/w link table * @src_nents: number of segments in input scatterlist * @qm_sg_bytes: length of dma mapped qm_sg space * @sgt: pointer to h/w link table */ struct ahash_edesc { - dma_addr_t dst_dma; dma_addr_t qm_sg_dma; int src_nents; int qm_sg_bytes; diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c index 58285642306e..fe24485274e1 100644 --- a/drivers/crypto/caam/caampkc.c +++ b/drivers/crypto/caam/caampkc.c @@ -994,8 +994,6 @@ static void caam_rsa_exit_tfm(struct crypto_akcipher *tfm) static struct akcipher_alg caam_rsa = { .encrypt = caam_rsa_enc, .decrypt = caam_rsa_dec, - .sign = caam_rsa_dec, - .verify = caam_rsa_enc, .set_pub_key = caam_rsa_set_pub_key, .set_priv_key = caam_rsa_set_priv_key, .max_size = caam_rsa_max_size, diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 858bdc9ab4a3..fec39c35c877 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -468,6 +468,24 @@ static int caam_get_era(struct caam_ctrl __iomem *ctrl) return caam_get_era_from_hw(ctrl); } +/* + * ERRATA: imx6 devices (imx6D, imx6Q, imx6DL, imx6S, imx6DP and imx6QP) + * have an issue wherein AXI bus transactions may not occur in the correct + * order. This isn't a problem running single descriptors, but can be if + * running multiple concurrent descriptors. Reworking the driver to throttle + * to single requests is impractical, thus the workaround is to limit the AXI + * pipeline to a depth of 1 (from it's default of 4) to preclude this situation + * from occurring. + */ +static void handle_imx6_err005766(u32 *mcr) +{ + if (of_machine_is_compatible("fsl,imx6q") || + of_machine_is_compatible("fsl,imx6dl") || + of_machine_is_compatible("fsl,imx6qp")) + clrsetbits_32(mcr, MCFGR_AXIPIPE_MASK, + 1 << MCFGR_AXIPIPE_SHIFT); +} + static const struct of_device_id caam_match[] = { { .compatible = "fsl,sec-v4.0", @@ -640,6 +658,8 @@ static int caam_probe(struct platform_device *pdev) (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); + handle_imx6_err005766(&ctrl->mcr); + /* * Read the Compile Time paramters and SCFGR to determine * if Virtualization is enabled for this platform diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c index 21a70fd32f5d..4da844e4b61d 100644 --- a/drivers/crypto/caam/error.c +++ b/drivers/crypto/caam/error.c @@ -22,7 +22,7 @@ void caam_dump_sg(const char *level, const char *prefix_str, int prefix_type, size_t len; void *buf; - for (it = sg; it && tlen > 0 ; it = sg_next(sg)) { + for (it = sg; it && tlen > 0 ; it = sg_next(it)) { /* * make sure the scatterlist's page * has a valid virtual memory mapping @@ -138,7 +138,7 @@ static const struct { { 0x46, "Annotation length exceeds offset (reuse mode)"}, { 0x48, "Annotation output enabled but ASA limited by ASAR (reuse mode)"}, { 0x49, "Data offset correction exceeds input frame data length (reuse mode)"}, - { 0x4B, "Annotation output enabled but ASA cannote be expanded (frame list)"}, + { 0x4B, "Annotation output enabled but ASA cannot be expanded (frame list)"}, { 0x51, "Unsupported IF reuse mode"}, { 0x52, "Unsupported FL use mode"}, { 0x53, "Unsupported RJD use mode"}, diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index 5869ad58d497..3392615dc91b 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h @@ -49,13 +49,11 @@ struct caam_drv_private_jr { atomic_t tfm_count ____cacheline_aligned; /* Job ring info */ - int ringsize; /* Size of rings (assume input = output) */ struct caam_jrentry_info *entinfo; /* Alloc'ed 1 per ring entry */ spinlock_t inplock ____cacheline_aligned; /* Input ring index lock */ - int inp_ring_write_index; /* Input index "tail" */ + u32 inpring_avail; /* Number of free entries in input ring */ int head; /* entinfo (s/w ring) head index */ dma_addr_t *inpring; /* Base of input ring, alloc DMA-safe */ - spinlock_t outlock ____cacheline_aligned; /* Output ring index lock */ int out_ring_read_index; /* Output index "tail" */ int tail; /* entinfo (s/w ring) tail index */ struct jr_outentry *outring; /* Base of output ring, DMA-safe */ diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index d50085a03597..1de2562d0982 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -170,13 +170,13 @@ static void caam_jr_dequeue(unsigned long devarg) void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg); u32 *userdesc, userstatus; void *userarg; + u32 outring_used = 0; - while (rd_reg32(&jrp->rregs->outring_used)) { + while (outring_used || + (outring_used = rd_reg32(&jrp->rregs->outring_used))) { head = READ_ONCE(jrp->head); - spin_lock(&jrp->outlock); - sw_idx = tail = jrp->tail; hw_idx = jrp->out_ring_read_index; @@ -199,7 +199,7 @@ static void caam_jr_dequeue(unsigned long devarg) /* mark completed, avoid matching on a recycled desc addr */ jrp->entinfo[sw_idx].desc_addr_dma = 0; - /* Stash callback params for use outside of lock */ + /* Stash callback params */ usercall = jrp->entinfo[sw_idx].callbk; userarg = jrp->entinfo[sw_idx].cbkarg; userdesc = jrp->entinfo[sw_idx].desc_addr_virt; @@ -232,10 +232,9 @@ static void caam_jr_dequeue(unsigned long devarg) jrp->tail = tail; } - spin_unlock(&jrp->outlock); - /* Finally, execute user's callback */ usercall(dev, userdesc, userstatus, userarg); + outring_used--; } /* reenable / unmask IRQs */ @@ -345,7 +344,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, head = jrp->head; tail = READ_ONCE(jrp->tail); - if (!rd_reg32(&jrp->rregs->inpring_avail) || + if (!jrp->inpring_avail || CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { spin_unlock_bh(&jrp->inplock); dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); @@ -359,7 +358,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, head_entry->cbkarg = areq; head_entry->desc_addr_dma = desc_dma; - jrp->inpring[jrp->inp_ring_write_index] = cpu_to_caam_dma(desc_dma); + jrp->inpring[head] = cpu_to_caam_dma(desc_dma); /* * Guarantee that the descriptor's DMA address has been written to @@ -368,18 +367,22 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, */ smp_wmb(); - jrp->inp_ring_write_index = (jrp->inp_ring_write_index + 1) & - (JOBR_DEPTH - 1); jrp->head = (head + 1) & (JOBR_DEPTH - 1); /* * Ensure that all job information has been written before - * notifying CAAM that a new job was added to the input ring. + * notifying CAAM that a new job was added to the input ring + * using a memory barrier. The wr_reg32() uses api iowrite32() + * to do the register write. iowrite32() issues a memory barrier + * before the write operation. */ - wmb(); wr_reg32(&jrp->rregs->inpring_jobadd, 1); + jrp->inpring_avail--; + if (!jrp->inpring_avail) + jrp->inpring_avail = rd_reg32(&jrp->rregs->inpring_avail); + spin_unlock_bh(&jrp->inplock); return 0; @@ -431,7 +434,6 @@ static int caam_jr_init(struct device *dev) jrp->entinfo[i].desc_addr_dma = !0; /* Setup rings */ - jrp->inp_ring_write_index = 0; jrp->out_ring_read_index = 0; jrp->head = 0; jrp->tail = 0; @@ -441,10 +443,9 @@ static int caam_jr_init(struct device *dev) wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); - jrp->ringsize = JOBR_DEPTH; + jrp->inpring_avail = JOBR_DEPTH; spin_lock_init(&jrp->inplock); - spin_lock_init(&jrp->outlock); /* Select interrupt coalescing parameters */ clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC | diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c index 7cb8b1755e57..9f08f84cca59 100644 --- a/drivers/crypto/caam/qi.c +++ b/drivers/crypto/caam/qi.c @@ -318,7 +318,7 @@ int caam_drv_ctx_update(struct caam_drv_ctx *drv_ctx, u32 *sh_desc) /* Create a new req FQ in parked state */ new_fq = create_caam_req_fq(drv_ctx->qidev, drv_ctx->rsp_fq, drv_ctx->context_a, 0); - if (IS_ERR_OR_NULL(new_fq)) { + if (IS_ERR(new_fq)) { dev_err(qidev, "FQ allocation for shdesc update failed\n"); return PTR_ERR(new_fq); } @@ -431,7 +431,7 @@ struct caam_drv_ctx *caam_drv_ctx_init(struct device *qidev, /* Attach request FQ */ drv_ctx->req_fq = create_caam_req_fq(qidev, drv_ctx->rsp_fq, hwdesc, QMAN_INITFQ_FLAG_SCHED); - if (IS_ERR_OR_NULL(drv_ctx->req_fq)) { + if (IS_ERR(drv_ctx->req_fq)) { dev_err(qidev, "create_caam_req_fq failed\n"); dma_unmap_single(qidev, hwdesc, size, DMA_BIDIRECTIONAL); kfree(drv_ctx); diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index 3cd0822ea819..8591914d5c51 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -253,6 +253,9 @@ struct version_regs { #define CHA_VER_VID_SHIFT 24 #define CHA_VER_VID_MASK (0xffull << CHA_VER_VID_SHIFT) +/* CHA Miscellaneous Information - AESA_MISC specific */ +#define CHA_VER_MISC_AES_GCM BIT(1 + CHA_VER_MISC_SHIFT) + /* * caam_perfmon - Performance Monitor/Secure Memory Status/ * CAAM Global Status/Component Version IDs |