Skip to content

Commit 5d9147d

Browse files
Akhil Rgregkh
authored andcommitted
crypto: tegra - Use separate buffer for setkey
[ Upstream commit bcfc8fc ] The buffer which sends the commands to host1x was shared for all tasks in the engine. This causes a problem with the setkey() function as it gets called asynchronous to the crypto engine queue. Modifying the same cmdbuf in setkey() will corrupt the ongoing host1x task and in turn break the encryption/decryption operation. Hence use a separate cmdbuf for setkey(). Fixes: 0880bb3 ("crypto: tegra - Add Tegra Security Engine driver") Signed-off-by: Akhil R <[email protected]> Signed-off-by: Herbert Xu <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent f23dfee commit 5d9147d

File tree

5 files changed

+37
-21
lines changed

5 files changed

+37
-21
lines changed

drivers/crypto/tegra/tegra-se-aes.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
282282

283283
/* Prepare the command and submit for execution */
284284
cmdlen = tegra_aes_prep_cmd(ctx, rctx);
285-
ret = tegra_se_host1x_submit(se, cmdlen);
285+
ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
286286

287287
/* Copy the result */
288288
tegra_aes_update_iv(req, ctx);
@@ -719,7 +719,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct
719719

720720
cmdlen = tegra_gmac_prep_cmd(ctx, rctx);
721721

722-
return tegra_se_host1x_submit(se, cmdlen);
722+
return tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
723723
}
724724

725725
static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx *rctx)
@@ -736,7 +736,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
736736

737737
/* Prepare command and submit */
738738
cmdlen = tegra_gcm_crypt_prep_cmd(ctx, rctx);
739-
ret = tegra_se_host1x_submit(se, cmdlen);
739+
ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
740740
if (ret)
741741
return ret;
742742

@@ -759,7 +759,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
759759

760760
/* Prepare command and submit */
761761
cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx);
762-
ret = tegra_se_host1x_submit(se, cmdlen);
762+
ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
763763
if (ret)
764764
return ret;
765765

@@ -891,7 +891,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req
891891
/* Prepare command and submit */
892892
cmdlen = tegra_cbcmac_prep_cmd(ctx, rctx);
893893

894-
return tegra_se_host1x_submit(se, cmdlen);
894+
return tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
895895
}
896896

897897
static int tegra_ccm_set_msg_len(u8 *block, unsigned int msglen, int csize)
@@ -1098,7 +1098,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx
10981098

10991099
/* Prepare command and submit */
11001100
cmdlen = tegra_ctr_prep_cmd(ctx, rctx);
1101-
ret = tegra_se_host1x_submit(se, cmdlen);
1101+
ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
11021102
if (ret)
11031103
return ret;
11041104

@@ -1521,8 +1521,8 @@ static int tegra_cmac_do_update(struct ahash_request *req)
15211521
tegra_cmac_paste_result(ctx->se, rctx);
15221522

15231523
cmdlen = tegra_cmac_prep_cmd(ctx, rctx);
1524+
ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
15241525

1525-
ret = tegra_se_host1x_submit(se, cmdlen);
15261526
/*
15271527
* If this is not the final update, copy the intermediate results
15281528
* from the registers so that it can be used in the next 'update'
@@ -1555,7 +1555,7 @@ static int tegra_cmac_do_final(struct ahash_request *req)
15551555

15561556
/* Prepare command and submit */
15571557
cmdlen = tegra_cmac_prep_cmd(ctx, rctx);
1558-
ret = tegra_se_host1x_submit(se, cmdlen);
1558+
ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
15591559
if (ret)
15601560
goto out;
15611561

drivers/crypto/tegra/tegra-se-hash.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,9 @@ static int tegra_sha_do_update(struct ahash_request *req)
300300
{
301301
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
302302
struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
303+
struct tegra_se *se = ctx->se;
303304
unsigned int nblks, nresidue, size, ret;
304-
u32 *cpuvaddr = ctx->se->cmdbuf->addr;
305+
u32 *cpuvaddr = se->cmdbuf->addr;
305306

306307
nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
307308
nblks = (req->nbytes + rctx->residue.size) / rctx->blk_size;
@@ -353,19 +354,19 @@ static int tegra_sha_do_update(struct ahash_request *req)
353354
* This is to support the import/export functionality.
354355
*/
355356
if (!(rctx->task & SHA_FIRST))
356-
tegra_sha_paste_hash_result(ctx->se, rctx);
357+
tegra_sha_paste_hash_result(se, rctx);
357358

358-
size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx);
359+
size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
359360

360-
ret = tegra_se_host1x_submit(ctx->se, size);
361+
ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
361362

362363
/*
363364
* If this is not the final update, copy the intermediate results
364365
* from the registers so that it can be used in the next 'update'
365366
* call. This is to support the import/export functionality.
366367
*/
367368
if (!(rctx->task & SHA_FINAL))
368-
tegra_sha_copy_hash_result(ctx->se, rctx);
369+
tegra_sha_copy_hash_result(se, rctx);
369370

370371
return ret;
371372
}
@@ -388,7 +389,7 @@ static int tegra_sha_do_final(struct ahash_request *req)
388389

389390
size = tegra_sha_prep_cmd(se, cpuvaddr, rctx);
390391

391-
ret = tegra_se_host1x_submit(se, size);
392+
ret = tegra_se_host1x_submit(se, se->cmdbuf, size);
392393
if (ret)
393394
goto out;
394395

drivers/crypto/tegra/tegra-se-key.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,17 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key,
115115
u32 keylen, u16 slot, u32 alg)
116116
{
117117
const u32 *keyval = (u32 *)key;
118-
u32 *addr = se->cmdbuf->addr, size;
118+
u32 *addr = se->keybuf->addr, size;
119+
int ret;
120+
121+
mutex_lock(&kslt_lock);
119122

120123
size = tegra_key_prep_ins_cmd(se, addr, keyval, keylen, slot, alg);
124+
ret = tegra_se_host1x_submit(se, se->keybuf, size);
121125

122-
return tegra_se_host1x_submit(se, size);
126+
mutex_unlock(&kslt_lock);
127+
128+
return ret;
123129
}
124130

125131
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)

drivers/crypto/tegra/tegra-se-main.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi
141141
return cmdbuf;
142142
}
143143

144-
int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
144+
int tegra_se_host1x_submit(struct tegra_se *se, struct tegra_se_cmdbuf *cmdbuf, u32 size)
145145
{
146146
struct host1x_job *job;
147147
int ret;
@@ -160,9 +160,9 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
160160
job->engine_fallback_streamid = se->stream_id;
161161
job->engine_streamid_offset = SE_STREAM_ID;
162162

163-
se->cmdbuf->words = size;
163+
cmdbuf->words = size;
164164

165-
host1x_job_add_gather(job, &se->cmdbuf->bo, size, 0);
165+
host1x_job_add_gather(job, &cmdbuf->bo, size, 0);
166166

167167
ret = host1x_job_pin(job, se->dev);
168168
if (ret) {
@@ -220,14 +220,22 @@ static int tegra_se_client_init(struct host1x_client *client)
220220
goto syncpt_put;
221221
}
222222

223+
se->keybuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
224+
if (!se->keybuf) {
225+
ret = -ENOMEM;
226+
goto cmdbuf_put;
227+
}
228+
223229
ret = se->hw->init_alg(se);
224230
if (ret) {
225231
dev_err(se->dev, "failed to register algorithms\n");
226-
goto cmdbuf_put;
232+
goto keybuf_put;
227233
}
228234

229235
return 0;
230236

237+
keybuf_put:
238+
tegra_se_cmdbuf_put(&se->keybuf->bo);
231239
cmdbuf_put:
232240
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
233241
syncpt_put:

drivers/crypto/tegra/tegra-se.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ struct tegra_se {
420420
struct host1x_client client;
421421
struct host1x_channel *channel;
422422
struct tegra_se_cmdbuf *cmdbuf;
423+
struct tegra_se_cmdbuf *keybuf;
423424
struct crypto_engine *engine;
424425
struct host1x_syncpt *syncpt;
425426
struct device *dev;
@@ -502,7 +503,7 @@ void tegra_deinit_hash(struct tegra_se *se);
502503
int tegra_key_submit(struct tegra_se *se, const u8 *key,
503504
u32 keylen, u32 alg, u32 *keyid);
504505
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg);
505-
int tegra_se_host1x_submit(struct tegra_se *se, u32 size);
506+
int tegra_se_host1x_submit(struct tegra_se *se, struct tegra_se_cmdbuf *cmdbuf, u32 size);
506507

507508
/* HOST1x OPCODES */
508509
static inline u32 host1x_opcode_setpayload(unsigned int payload)

0 commit comments

Comments
 (0)