| From 25baaf8e2c93197d063b372ef7b62f2767c7ac0b Mon Sep 17 00:00:00 2001 |
| From: Christian Lamparter <chunkeey@gmail.com> |
| Date: Mon, 22 Apr 2019 13:25:58 +0200 |
| Subject: crypto: crypto4xx - fix ctr-aes missing output IV |
| |
| From: Christian Lamparter <chunkeey@gmail.com> |
| |
| commit 25baaf8e2c93197d063b372ef7b62f2767c7ac0b upstream. |
| |
| Commit 8efd972ef96a ("crypto: testmgr - support checking skcipher output IV") |
| caused the crypto4xx driver to produce the following error: |
| |
| | ctr-aes-ppc4xx encryption test failed (wrong output IV) |
| | on test vector 0, cfg="in-place" |
| |
| This patch fixes this by reworking the crypto4xx_setkey_aes() |
| function to: |
| |
| - not save the iv for ECB (as per 18.2.38 CRYP0_SA_CMD_0: |
| "This bit mut be cleared for DES ECB mode or AES ECB mode, |
| when no IV is used.") |
| |
| - instruct the hardware to save the generated IV for all |
| other modes of operations that have IV and then supply |
| it back to the callee in pretty much the same way as we |
| do it for cbc-aes already. |
| |
| - make it clear that the DIR_(IN|OUT)BOUND is the important |
| bit that tells the hardware to encrypt or decrypt the data. |
| (this is cosmetic - but it hopefully prevents me from |
| getting confused again). |
| |
| - don't load any bogus hash when we don't use any hash |
| operation to begin with. |
| |
| Cc: stable@vger.kernel.org |
| Fixes: f2a13e7cba9e ("crypto: crypto4xx - enable AES RFC3686, ECB, CFB and OFB offloads") |
| Signed-off-by: Christian Lamparter <chunkeey@gmail.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/crypto/amcc/crypto4xx_alg.c | 12 +++++++++--- |
| 1 file changed, 9 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/crypto/amcc/crypto4xx_alg.c |
| +++ b/drivers/crypto/amcc/crypto4xx_alg.c |
| @@ -141,9 +141,10 @@ static int crypto4xx_setkey_aes(struct c |
| /* Setup SA */ |
| sa = ctx->sa_in; |
| |
| - set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, (cm == CRYPTO_MODE_CBC ? |
| - SA_SAVE_IV : SA_NOT_SAVE_IV), |
| - SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE, |
| + set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, (cm == CRYPTO_MODE_ECB ? |
| + SA_NOT_SAVE_IV : SA_SAVE_IV), |
| + SA_NOT_LOAD_HASH, (cm == CRYPTO_MODE_ECB ? |
| + SA_LOAD_IV_FROM_SA : SA_LOAD_IV_FROM_STATE), |
| SA_NO_HEADER_PROC, SA_HASH_ALG_NULL, |
| SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO, |
| SA_OP_GROUP_BASIC, SA_OPCODE_DECRYPT, |
| @@ -162,6 +163,11 @@ static int crypto4xx_setkey_aes(struct c |
| memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4); |
| sa = ctx->sa_out; |
| sa->sa_command_0.bf.dir = DIR_OUTBOUND; |
| + /* |
| + * SA_OPCODE_ENCRYPT is the same value as SA_OPCODE_DECRYPT. |
| + * it's the DIR_(IN|OUT)BOUND that matters |
| + */ |
| + sa->sa_command_0.bf.opcode = SA_OPCODE_ENCRYPT; |
| |
| return 0; |
| } |