Commit d7af2baa authored by Breno Lima's avatar Breno Lima Committed by York Sun
Browse files

crypto/fsl: Fix HW accelerated hash commands

The hash command function were not flushing the dcache before passing data
to CAAM/DMA and not invalidating the dcache when getting data back.

Due the data cache incoherency, HW accelerated hash commands used to fail
with CAAM errors like "Invalid KEY Command".

Check if pbuf and pout buffers are properly aligned to the cache line size
and flush/invalidate the memory regions to address this issue.

This solution is based in a previous work from Clemens Gruber in
commit 598e9dcc

 ("crypto/fsl: fix BLOB encapsulation and
Reported-by: Anatolij Gustschin's avatarAnatolij Gustschin <>
Signed-off-by: default avatarBreno Lima <>
Reviewed-by: default avatarYork Sun <>
parent 6d48d1c4
......@@ -390,7 +390,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
if (multi_hash()) {
struct hash_algo *algo;
uint8_t output[HASH_MAX_DIGEST_SIZE];
u8 *output;
uint8_t vsum[HASH_MAX_DIGEST_SIZE];
void *buf;
......@@ -405,6 +405,9 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
return 1;
output = memalign(ARCH_DMA_MINALIGN,
sizeof(uint32_t) * HASH_MAX_DIGEST_SIZE);
buf = map_sysmem(addr, len);
algo->hash_func_ws(buf, len, output, algo->chunk_size);
......@@ -440,6 +443,8 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
store_result(algo, output, *argv,
flags & HASH_FLAG_ENV);
/* Horrible code size hack for boards that just want crc32 */
......@@ -7,6 +7,7 @@
#include <common.h>
#include <malloc.h>
#include <memalign.h>
#include "jobdesc.h"
#include "desc.h"
#include "jr.h"
......@@ -163,20 +164,37 @@ int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
int ret = 0;
uint32_t *desc;
unsigned int size;
desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE);
if (!desc) {
debug("Not enough memory for descriptor allocation\n");
return -ENOMEM;
if (!IS_ALIGNED((uintptr_t)pbuf, ARCH_DMA_MINALIGN) ||
!IS_ALIGNED((uintptr_t)pout, ARCH_DMA_MINALIGN)) {
puts("Error: Address arguments are not aligned\n");
return -EINVAL;
size = ALIGN(buf_len, ARCH_DMA_MINALIGN);
flush_dcache_range((unsigned long)pbuf, (unsigned long)pbuf + size);
inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
flush_dcache_range((unsigned long)desc, (unsigned long)desc + size);
ret = run_descriptor_jr(desc);
size = ALIGN(driver_hash[algo].digestsize, ARCH_DMA_MINALIGN);
invalidate_dcache_range((unsigned long)pout,
(unsigned long)pout + size);
return ret;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment