Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed IV chaining bug in CAAM for ECB #44

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions crypto/tcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,12 +856,11 @@ static int test_acipher_cycles(struct skcipher_request *req, int enc,

static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
struct cipher_speed_template *template,
unsigned int tcount, u8 *keysize, bool async)
unsigned int tcount, u8 *keysize, bool async, char *iv)
{
unsigned int ret, i, j, k, iv_len;
struct tcrypt_result tresult;
const char *key;
char iv[128];
struct skcipher_request *req;
struct crypto_skcipher *tfm;
const char *e;
Expand Down Expand Up @@ -953,8 +952,8 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
}

iv_len = crypto_skcipher_ivsize(tfm);
if (iv_len)
memset(&iv, 0xff, iv_len);
if (iv && iv_len)
memset(iv, 0xff, iv_len);

skcipher_request_set_crypt(req, sg, sg, *b_size, iv);

Expand Down Expand Up @@ -986,16 +985,18 @@ static void test_acipher_speed(const char *algo, int enc, unsigned int secs,
struct cipher_speed_template *template,
unsigned int tcount, u8 *keysize)
{
char iv[128];
return test_skcipher_speed(algo, enc, secs, template, tcount, keysize,
true);
true, iv);
}

static void test_cipher_speed(const char *algo, int enc, unsigned int secs,
struct cipher_speed_template *template,
unsigned int tcount, u8 *keysize)
{
char iv[128];
return test_skcipher_speed(algo, enc, secs, template, tcount, keysize,
false);
false, iv);
}

static void test_available(void)
Expand Down Expand Up @@ -2039,6 +2040,13 @@ static int do_test(const char *alg, u32 type, u32 mask, int m)
speed_template_8_32);
break;

case 900:
test_skcipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
speed_template_16_24_32, true, NULL);
test_skcipher_speed("ecb(aes)", DECRYPT, sec, NULL, 0,
speed_template_16_24_32, true, NULL);
break;

case 1000:
test_available();
break;
Expand Down
21 changes: 11 additions & 10 deletions drivers/crypto/caam/caamalg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2075,17 +2075,13 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
* The crypto API expects us to set the IV (req->info) to the last
* ciphertext block. This is used e.g. by the CTS mode.
*/
scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize,
ivsize, 0);
if ((ctx->class1_alg_type & OP_ALG_AAI_MASK) != OP_ALG_AAI_ECB) {
scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize,
ivcopy, 0);
}

kfree(edesc);

/* Pass IV along for cbc */
if ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC) {
scatterwalk_map_and_copy(req->info, req->dst,
req->nbytes - bsize, ivcopy, 0);
}

ablkcipher_request_complete(req, err);
}

Expand All @@ -2095,7 +2091,10 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
struct ablkcipher_request *req = context;
struct ablkcipher_edesc *edesc;
struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
int bsize = crypto_ablkcipher_blocksize(ablkcipher);
int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
size_t ivcopy = min_t(size_t, bsize, ivsize);

#ifdef DEBUG
dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
Expand All @@ -2121,8 +2120,10 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
* The crypto API expects us to set the IV (req->info) to the last
* ciphertext block.
*/
scatterwalk_map_and_copy(req->info, req->src, req->nbytes - ivsize,
ivsize, 0);
if ((ctx->class1_alg_type & OP_ALG_AAI_MASK) != OP_ALG_AAI_ECB) {
scatterwalk_map_and_copy(req->info, req->src, req->nbytes - ivsize,
ivcopy, 0);
}

kfree(edesc);

Expand Down