aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/apm821xx/patches-4.14/020-0024-crypto-crypto4xx-add-aes-ccm-support.patch
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@gmail.com>2018-01-07 21:27:50 +0100
committerMathias Kresin <dev@kresin.me>2018-01-12 08:00:04 +0100
commit780477d17c0e73e54397a0f3cebff08634e7231a (patch)
tree098826be0c3cbfb24fc1fc15219eed83d915e84a /target/linux/apm821xx/patches-4.14/020-0024-crypto-crypto4xx-add-aes-ccm-support.patch
parente4371779d2691553e6321e87d86212beaaa8b89d (diff)
downloadupstream-780477d17c0e73e54397a0f3cebff08634e7231a.tar.gz
upstream-780477d17c0e73e54397a0f3cebff08634e7231a.tar.bz2
upstream-780477d17c0e73e54397a0f3cebff08634e7231a.zip
apm821xx: backport crypto4xx patches from 4.15
This patch backports changes to crypto4xx in order to get the crypto4xx operational. Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Diffstat (limited to 'target/linux/apm821xx/patches-4.14/020-0024-crypto-crypto4xx-add-aes-ccm-support.patch')
-rw-r--r--target/linux/apm821xx/patches-4.14/020-0024-crypto-crypto4xx-add-aes-ccm-support.patch256
1 files changed, 256 insertions, 0 deletions
diff --git a/target/linux/apm821xx/patches-4.14/020-0024-crypto-crypto4xx-add-aes-ccm-support.patch b/target/linux/apm821xx/patches-4.14/020-0024-crypto-crypto4xx-add-aes-ccm-support.patch
new file mode 100644
index 0000000000..73283f650c
--- /dev/null
+++ b/target/linux/apm821xx/patches-4.14/020-0024-crypto-crypto4xx-add-aes-ccm-support.patch
@@ -0,0 +1,256 @@
+From 65ea8b678fcf385ac18864743bae66c0643e6842 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Wed, 4 Oct 2017 01:00:16 +0200
+Subject: [PATCH 24/25] crypto: crypto4xx - add aes-ccm support
+
+This patch adds aes-ccm support.
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/amcc/crypto4xx_alg.c | 185 +++++++++++++++++++++++++++++++++++
+ drivers/crypto/amcc/crypto4xx_core.c | 23 +++++
+ drivers/crypto/amcc/crypto4xx_core.h | 8 ++
+ 3 files changed, 216 insertions(+)
+
+--- a/drivers/crypto/amcc/crypto4xx_alg.c
++++ b/drivers/crypto/amcc/crypto4xx_alg.c
+@@ -231,6 +231,191 @@ int crypto4xx_rfc3686_decrypt(struct abl
+ ctx->sa_out, ctx->sa_len, 0);
+ }
+
++static inline bool crypto4xx_aead_need_fallback(struct aead_request *req,
++ bool is_ccm, bool decrypt)
++{
++ struct crypto_aead *aead = crypto_aead_reqtfm(req);
++
++ /* authsize has to be a multiple of 4 */
++ if (aead->authsize & 3)
++ return true;
++
++ /*
++ * hardware does not handle cases where cryptlen
++ * is less than a block
++ */
++ if (req->cryptlen < AES_BLOCK_SIZE)
++ return true;
++
++ /* assoc len needs to be a multiple of 4 */
++ if (req->assoclen & 0x3)
++ return true;
++
++ /* CCM supports only counter field length of 2 and 4 bytes */
++ if (is_ccm && !(req->iv[0] == 1 || req->iv[0] == 3))
++ return true;
++
++ /* CCM - fix CBC MAC mismatch in special case */
++ if (is_ccm && decrypt && !req->assoclen)
++ return true;
++
++ return false;
++}
++
++static int crypto4xx_aead_fallback(struct aead_request *req,
++ struct crypto4xx_ctx *ctx, bool do_decrypt)
++{
++ char aead_req_data[sizeof(struct aead_request) +
++ crypto_aead_reqsize(ctx->sw_cipher.aead)]
++ __aligned(__alignof__(struct aead_request));
++
++ struct aead_request *subreq = (void *) aead_req_data;
++
++ memset(subreq, 0, sizeof(aead_req_data));
++
++ aead_request_set_tfm(subreq, ctx->sw_cipher.aead);
++ aead_request_set_callback(subreq, req->base.flags,
++ req->base.complete, req->base.data);
++ aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
++ req->iv);
++ aead_request_set_ad(subreq, req->assoclen);
++ return do_decrypt ? crypto_aead_decrypt(subreq) :
++ crypto_aead_encrypt(subreq);
++}
++
++static int crypto4xx_setup_fallback(struct crypto4xx_ctx *ctx,
++ struct crypto_aead *cipher,
++ const u8 *key,
++ unsigned int keylen)
++{
++ int rc;
++
++ crypto_aead_clear_flags(ctx->sw_cipher.aead, CRYPTO_TFM_REQ_MASK);
++ crypto_aead_set_flags(ctx->sw_cipher.aead,
++ crypto_aead_get_flags(cipher) & CRYPTO_TFM_REQ_MASK);
++ rc = crypto_aead_setkey(ctx->sw_cipher.aead, key, keylen);
++ crypto_aead_clear_flags(cipher, CRYPTO_TFM_RES_MASK);
++ crypto_aead_set_flags(cipher,
++ crypto_aead_get_flags(ctx->sw_cipher.aead) &
++ CRYPTO_TFM_RES_MASK);
++
++ return rc;
++}
++
++/**
++ * AES-CCM Functions
++ */
++
++int crypto4xx_setkey_aes_ccm(struct crypto_aead *cipher, const u8 *key,
++ unsigned int keylen)
++{
++ struct crypto_tfm *tfm = crypto_aead_tfm(cipher);
++ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
++ struct dynamic_sa_ctl *sa;
++ int rc = 0;
++
++ rc = crypto4xx_setup_fallback(ctx, cipher, key, keylen);
++ if (rc)
++ return rc;
++
++ if (ctx->sa_in || ctx->sa_out)
++ crypto4xx_free_sa(ctx);
++
++ rc = crypto4xx_alloc_sa(ctx, SA_AES128_CCM_LEN + (keylen - 16) / 4);
++ if (rc)
++ return rc;
++
++ /* Setup SA */
++ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
++ sa->sa_contents.w = SA_AES_CCM_CONTENTS | (keylen << 2);
++
++ set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV,
++ SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE,
++ SA_NO_HEADER_PROC, SA_HASH_ALG_CBC_MAC,
++ SA_CIPHER_ALG_AES,
++ SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC,
++ SA_OPCODE_HASH_DECRYPT, DIR_INBOUND);
++
++ set_dynamic_sa_command_1(sa, CRYPTO_MODE_CTR, SA_HASH_MODE_HASH,
++ CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF,
++ SA_SEQ_MASK_OFF, SA_MC_ENABLE,
++ SA_NOT_COPY_PAD, SA_COPY_PAYLOAD,
++ SA_NOT_COPY_HDR);
++
++ sa->sa_command_1.bf.key_len = keylen >> 3;
++
++ crypto4xx_memcpy_to_le32(get_dynamic_sa_key_field(sa), key, keylen);
++
++ memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4);
++ sa = (struct dynamic_sa_ctl *) ctx->sa_out;
++
++ set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV,
++ SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE,
++ SA_NO_HEADER_PROC, SA_HASH_ALG_CBC_MAC,
++ SA_CIPHER_ALG_AES,
++ SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC,
++ SA_OPCODE_ENCRYPT_HASH, DIR_OUTBOUND);
++
++ set_dynamic_sa_command_1(sa, CRYPTO_MODE_CTR, SA_HASH_MODE_HASH,
++ CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF,
++ SA_SEQ_MASK_OFF, SA_MC_ENABLE,
++ SA_COPY_PAD, SA_COPY_PAYLOAD,
++ SA_NOT_COPY_HDR);
++
++ sa->sa_command_1.bf.key_len = keylen >> 3;
++ return 0;
++}
++
++static int crypto4xx_crypt_aes_ccm(struct aead_request *req, bool decrypt)
++{
++ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
++ struct crypto_aead *aead = crypto_aead_reqtfm(req);
++ unsigned int len = req->cryptlen;
++ __le32 iv[16];
++ u32 tmp_sa[ctx->sa_len * 4];
++ struct dynamic_sa_ctl *sa = (struct dynamic_sa_ctl *)tmp_sa;
++
++ if (crypto4xx_aead_need_fallback(req, true, decrypt))
++ return crypto4xx_aead_fallback(req, ctx, decrypt);
++
++ if (decrypt)
++ len -= crypto_aead_authsize(aead);
++
++ memcpy(tmp_sa, decrypt ? ctx->sa_in : ctx->sa_out, sizeof(tmp_sa));
++ sa->sa_command_0.bf.digest_len = crypto_aead_authsize(aead) >> 2;
++
++ if (req->iv[0] == 1) {
++ /* CRYPTO_MODE_AES_ICM */
++ sa->sa_command_1.bf.crypto_mode9_8 = 1;
++ }
++
++ iv[3] = cpu_to_le32(0);
++ crypto4xx_memcpy_to_le32(iv, req->iv, 16 - (req->iv[0] + 1));
++
++ return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
++ len, iv, sizeof(iv),
++ sa, ctx->sa_len, req->assoclen);
++}
++
++int crypto4xx_encrypt_aes_ccm(struct aead_request *req)
++{
++ return crypto4xx_crypt_aes_ccm(req, false);
++}
++
++int crypto4xx_decrypt_aes_ccm(struct aead_request *req)
++{
++ return crypto4xx_crypt_aes_ccm(req, true);
++}
++
++int crypto4xx_setauthsize_aead(struct crypto_aead *cipher,
++ unsigned int authsize)
++{
++ struct crypto_tfm *tfm = crypto_aead_tfm(cipher);
++ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
++
++ return crypto_aead_setauthsize(ctx->sw_cipher.aead, authsize);
++}
++
+ /**
+ * HASH SHA1 Functions
+ */
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -1210,6 +1210,29 @@ static struct crypto4xx_alg_common crypt
+ }
+ }
+ } },
++
++ /* AEAD */
++ { .type = CRYPTO_ALG_TYPE_AEAD, .u.aead = {
++ .setkey = crypto4xx_setkey_aes_ccm,
++ .setauthsize = crypto4xx_setauthsize_aead,
++ .encrypt = crypto4xx_encrypt_aes_ccm,
++ .decrypt = crypto4xx_decrypt_aes_ccm,
++ .init = crypto4xx_aead_init,
++ .exit = crypto4xx_aead_exit,
++ .ivsize = AES_BLOCK_SIZE,
++ .maxauthsize = 16,
++ .base = {
++ .cra_name = "ccm(aes)",
++ .cra_driver_name = "ccm-aes-ppc4xx",
++ .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
++ .cra_flags = CRYPTO_ALG_ASYNC |
++ CRYPTO_ALG_NEED_FALLBACK |
++ CRYPTO_ALG_KERN_DRIVER_ONLY,
++ .cra_blocksize = 1,
++ .cra_ctxsize = sizeof(struct crypto4xx_ctx),
++ .cra_module = THIS_MODULE,
++ },
++ } },
+ };
+
+ /**
+--- a/drivers/crypto/amcc/crypto4xx_core.h
++++ b/drivers/crypto/amcc/crypto4xx_core.h
+@@ -222,4 +222,12 @@ static inline void crypto4xx_memcpy_to_l
+ {
+ crypto4xx_memcpy_swab32((u32 *)dst, buf, len);
+ }
++
++int crypto4xx_setauthsize_aead(struct crypto_aead *ciper,
++ unsigned int authsize);
++int crypto4xx_setkey_aes_ccm(struct crypto_aead *cipher,
++ const u8 *key, unsigned int keylen);
++int crypto4xx_encrypt_aes_ccm(struct aead_request *req);
++int crypto4xx_decrypt_aes_ccm(struct aead_request *req);
++
+ #endif