summaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorKim Phillips <kim.phillips@freescale.com>2011-05-14 22:08:02 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2011-05-19 14:37:59 +1000
commitddbb80884a37601026ac3e5eaf176c4296231862 (patch)
tree3c4d486db42bbb8dbba59021fbd64aae54486403 /drivers/crypto
parent2930d49768e5276da4fbed9d9cc1bd40ed25818e (diff)
downloadlinux-stable-ddbb80884a37601026ac3e5eaf176c4296231862.tar.gz
linux-stable-ddbb80884a37601026ac3e5eaf176c4296231862.tar.bz2
linux-stable-ddbb80884a37601026ac3e5eaf176c4296231862.zip
crypto: caam - fix decryption shared vs. non-shared key setting
Key sharing is enabled by default in the shared descriptor. Using CBC decrypt, AES has to alter the key in order to decrypt. During high traffic decryption rates, i.e, when sharing starts to take place, we need to use a different OPERATION option to tell AES that the key was already altered by the PRIOR descriptor - we need the following kind of logic: if ( shared ) operation where AES uses decryption key (DK=1) else operation where AES uses encryption key (DK=0) this patch implements this logic using a conditional and a non-conditional local jump within the decryption job descriptor. Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/caamalg.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index b97575e414f6..4c69ba79f900 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -571,9 +571,27 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
/* copy iv from cipher/class1 input context to class2 infifo */
append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | ivsize);
- /* start class 1 (cipher) operation */
- append_operation(desc, ctx->class1_alg_type | OP_ALG_AS_INITFINAL |
- encrypt);
+ if (!encrypt) {
+ u32 *jump_cmd, *uncond_jump_cmd;
+
+ /* JUMP if shared */
+ jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
+
+ /* start class 1 (cipher) operation, non-shared version */
+ append_operation(desc, ctx->class1_alg_type |
+ OP_ALG_AS_INITFINAL);
+
+ uncond_jump_cmd = append_jump(desc, 0);
+
+ set_jump_tgt_here(desc, jump_cmd);
+
+ /* start class 1 (cipher) operation, shared version */
+ append_operation(desc, ctx->class1_alg_type |
+ OP_ALG_AS_INITFINAL | OP_ALG_AAI_DK);
+ set_jump_tgt_here(desc, uncond_jump_cmd);
+ } else
+ append_operation(desc, ctx->class1_alg_type |
+ OP_ALG_AS_INITFINAL | encrypt);
/* load payload & instruct to class2 to snoop class 1 if encrypting */
options = 0;
@@ -762,7 +780,7 @@ static int aead_authenc_decrypt(struct aead_request *req)
req->cryptlen -= ctx->authsize;
/* allocate extended descriptor */
- edesc = ipsec_esp_edesc_alloc(req, 21 * sizeof(u32));
+ edesc = ipsec_esp_edesc_alloc(req, 24 * sizeof(u32));
if (IS_ERR(edesc))
return PTR_ERR(edesc);