crypto: caam - generate hash keys in-place
When generating a split key or hashing the key, DMA mapping the key buffers coming directly from user is incorrect, since they are not guaranteed to be DMAable. Update driver to first copy user-provided key in the output buffer ("key_out") and then use this buffer for in-place computation (split key generation, respectively key hashing). Signed-off-by: Horia Geantă <horia.geanta@nxp.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
8e731ee5e2
commit
307244452d
2 changed files with 23 additions and 47 deletions
|
@ -395,13 +395,13 @@ static int acmac_set_sh_desc(struct crypto_ahash *ahash)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Digest hash size if it is too large */
|
/* Digest hash size if it is too large */
|
||||||
static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
|
static int hash_digest_key(struct caam_hash_ctx *ctx, u32 *keylen, u8 *key,
|
||||||
u32 *keylen, u8 *key_out, u32 digestsize)
|
u32 digestsize)
|
||||||
{
|
{
|
||||||
struct device *jrdev = ctx->jrdev;
|
struct device *jrdev = ctx->jrdev;
|
||||||
u32 *desc;
|
u32 *desc;
|
||||||
struct split_key_result result;
|
struct split_key_result result;
|
||||||
dma_addr_t src_dma, dst_dma;
|
dma_addr_t key_dma;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
desc = kmalloc(CAAM_CMD_SZ * 8 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
|
desc = kmalloc(CAAM_CMD_SZ * 8 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
|
||||||
|
@ -412,18 +412,9 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
|
||||||
|
|
||||||
init_job_desc(desc, 0);
|
init_job_desc(desc, 0);
|
||||||
|
|
||||||
src_dma = dma_map_single(jrdev, (void *)key_in, *keylen,
|
key_dma = dma_map_single(jrdev, key, *keylen, DMA_BIDIRECTIONAL);
|
||||||
DMA_TO_DEVICE);
|
if (dma_mapping_error(jrdev, key_dma)) {
|
||||||
if (dma_mapping_error(jrdev, src_dma)) {
|
dev_err(jrdev, "unable to map key memory\n");
|
||||||
dev_err(jrdev, "unable to map key input memory\n");
|
|
||||||
kfree(desc);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
dst_dma = dma_map_single(jrdev, (void *)key_out, digestsize,
|
|
||||||
DMA_FROM_DEVICE);
|
|
||||||
if (dma_mapping_error(jrdev, dst_dma)) {
|
|
||||||
dev_err(jrdev, "unable to map key output memory\n");
|
|
||||||
dma_unmap_single(jrdev, src_dma, *keylen, DMA_TO_DEVICE);
|
|
||||||
kfree(desc);
|
kfree(desc);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -431,16 +422,16 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
|
||||||
/* Job descriptor to perform unkeyed hash on key_in */
|
/* Job descriptor to perform unkeyed hash on key_in */
|
||||||
append_operation(desc, ctx->adata.algtype | OP_ALG_ENCRYPT |
|
append_operation(desc, ctx->adata.algtype | OP_ALG_ENCRYPT |
|
||||||
OP_ALG_AS_INITFINAL);
|
OP_ALG_AS_INITFINAL);
|
||||||
append_seq_in_ptr(desc, src_dma, *keylen, 0);
|
append_seq_in_ptr(desc, key_dma, *keylen, 0);
|
||||||
append_seq_fifo_load(desc, *keylen, FIFOLD_CLASS_CLASS2 |
|
append_seq_fifo_load(desc, *keylen, FIFOLD_CLASS_CLASS2 |
|
||||||
FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_MSG);
|
FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_MSG);
|
||||||
append_seq_out_ptr(desc, dst_dma, digestsize, 0);
|
append_seq_out_ptr(desc, key_dma, digestsize, 0);
|
||||||
append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
|
append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
|
||||||
LDST_SRCDST_BYTE_CONTEXT);
|
LDST_SRCDST_BYTE_CONTEXT);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_hex_dump(KERN_ERR, "key_in@"__stringify(__LINE__)": ",
|
print_hex_dump(KERN_ERR, "key_in@"__stringify(__LINE__)": ",
|
||||||
DUMP_PREFIX_ADDRESS, 16, 4, key_in, *keylen, 1);
|
DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1);
|
||||||
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
|
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
|
||||||
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
|
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -456,12 +447,10 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_hex_dump(KERN_ERR,
|
print_hex_dump(KERN_ERR,
|
||||||
"digested key@"__stringify(__LINE__)": ",
|
"digested key@"__stringify(__LINE__)": ",
|
||||||
DUMP_PREFIX_ADDRESS, 16, 4, key_in,
|
DUMP_PREFIX_ADDRESS, 16, 4, key, digestsize, 1);
|
||||||
digestsize, 1);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
dma_unmap_single(jrdev, src_dma, *keylen, DMA_TO_DEVICE);
|
dma_unmap_single(jrdev, key_dma, *keylen, DMA_BIDIRECTIONAL);
|
||||||
dma_unmap_single(jrdev, dst_dma, digestsize, DMA_FROM_DEVICE);
|
|
||||||
|
|
||||||
*keylen = digestsize;
|
*keylen = digestsize;
|
||||||
|
|
||||||
|
@ -485,13 +474,10 @@ static int ahash_setkey(struct crypto_ahash *ahash,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (keylen > blocksize) {
|
if (keylen > blocksize) {
|
||||||
hashed_key = kmalloc_array(digestsize,
|
hashed_key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
|
||||||
sizeof(*hashed_key),
|
|
||||||
GFP_KERNEL | GFP_DMA);
|
|
||||||
if (!hashed_key)
|
if (!hashed_key)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
ret = hash_digest_key(ctx, key, &keylen, hashed_key,
|
ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize);
|
||||||
digestsize);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto bad_free_key;
|
goto bad_free_key;
|
||||||
key = hashed_key;
|
key = hashed_key;
|
||||||
|
|
|
@ -48,7 +48,7 @@ int gen_split_key(struct device *jrdev, u8 *key_out,
|
||||||
{
|
{
|
||||||
u32 *desc;
|
u32 *desc;
|
||||||
struct split_key_result result;
|
struct split_key_result result;
|
||||||
dma_addr_t dma_addr_in, dma_addr_out;
|
dma_addr_t dma_addr;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
adata->keylen = split_key_len(adata->algtype & OP_ALG_ALGSEL_MASK);
|
adata->keylen = split_key_len(adata->algtype & OP_ALG_ALGSEL_MASK);
|
||||||
|
@ -71,22 +71,17 @@ int gen_split_key(struct device *jrdev, u8 *key_out,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen,
|
memcpy(key_out, key_in, keylen);
|
||||||
DMA_TO_DEVICE);
|
|
||||||
if (dma_mapping_error(jrdev, dma_addr_in)) {
|
dma_addr = dma_map_single(jrdev, key_out, adata->keylen_pad,
|
||||||
dev_err(jrdev, "unable to map key input memory\n");
|
DMA_BIDIRECTIONAL);
|
||||||
|
if (dma_mapping_error(jrdev, dma_addr)) {
|
||||||
|
dev_err(jrdev, "unable to map key memory\n");
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_addr_out = dma_map_single(jrdev, key_out, adata->keylen_pad,
|
|
||||||
DMA_FROM_DEVICE);
|
|
||||||
if (dma_mapping_error(jrdev, dma_addr_out)) {
|
|
||||||
dev_err(jrdev, "unable to map key output memory\n");
|
|
||||||
goto out_unmap_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_job_desc(desc, 0);
|
init_job_desc(desc, 0);
|
||||||
append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG);
|
append_key(desc, dma_addr, keylen, CLASS_2 | KEY_DEST_CLASS_REG);
|
||||||
|
|
||||||
/* Sets MDHA up into an HMAC-INIT */
|
/* Sets MDHA up into an HMAC-INIT */
|
||||||
append_operation(desc, (adata->algtype & OP_ALG_ALGSEL_MASK) |
|
append_operation(desc, (adata->algtype & OP_ALG_ALGSEL_MASK) |
|
||||||
|
@ -104,12 +99,10 @@ int gen_split_key(struct device *jrdev, u8 *key_out,
|
||||||
* FIFO_STORE with the explicit split-key content store
|
* FIFO_STORE with the explicit split-key content store
|
||||||
* (0x26 output type)
|
* (0x26 output type)
|
||||||
*/
|
*/
|
||||||
append_fifo_store(desc, dma_addr_out, adata->keylen,
|
append_fifo_store(desc, dma_addr, adata->keylen,
|
||||||
LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK);
|
LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
|
|
||||||
DUMP_PREFIX_ADDRESS, 16, 4, key_in, keylen, 1);
|
|
||||||
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
|
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
|
||||||
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
|
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -129,10 +122,7 @@ int gen_split_key(struct device *jrdev, u8 *key_out,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_unmap_single(jrdev, dma_addr_out, adata->keylen_pad,
|
dma_unmap_single(jrdev, dma_addr, adata->keylen_pad, DMA_BIDIRECTIONAL);
|
||||||
DMA_FROM_DEVICE);
|
|
||||||
out_unmap_in:
|
|
||||||
dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE);
|
|
||||||
out_free:
|
out_free:
|
||||||
kfree(desc);
|
kfree(desc);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Reference in a new issue