Commit 1d7f31a55b284ea5bf206ea30e07cc96c851c6ec

Authored by Clemens Gruber
Committed by Ye Li
1 parent b4b1dc8ed7

crypto/fsl: fix BLOB encapsulation and decapsulation

The blob_encap and blob_decap functions were not flushing the dcache
before passing data to CAAM/DMA and not invalidating the dcache when
getting data back.
Therefore, blob encapsulation and decapsulation failed with errors like
the following due to data cache incoherency:
"40000006: DECO: desc idx 0: Invalid KEY command"

To ensure coherency, we require the key_mod, src and dst buffers to be
aligned to the cache line size and flush/invalidate the memory regions.
The same requirements apply to the job descriptor.

Tested on an i.MX6Q board.

Reviewed-by: Sumit Garg <sumit.garg@nxp.com>
Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
[Breno: Backported to v2017.03]
Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>

(cherry picked from commit f4e19b92bc40184eee7d33e53cd190dfb692b196)

Showing 2 changed files with 91 additions and 16 deletions Side-by-side Diff

drivers/crypto/fsl/fsl_blob.c
... ... @@ -7,63 +7,138 @@
7 7  
8 8 #include <common.h>
9 9 #include <malloc.h>
  10 +#include <memalign.h>
10 11 #include <fsl_sec.h>
11 12 #include <linux/errno.h>
12 13 #include "jobdesc.h"
13 14 #include "desc.h"
14 15 #include "jr.h"
15 16  
  17 +/**
  18 + * blob_decap() - Decapsulate the data from a blob
  19 + * @key_mod: - Key modifier address
  20 + * @src: - Source address (blob)
  21 + * @dst: - Destination address (data)
  22 + * @len: - Size of decapsulated data
  23 + *
  24 + * Note: Start and end of the key_mod, src and dst buffers have to be aligned to
  25 + * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed.
  26 + *
  27 + * Returns zero on success, negative on error.
  28 + */
16 29 int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
17 30 {
18   - int ret, i = 0;
  31 + int ret, size, i = 0;
19 32 u32 *desc;
20 33  
  34 + if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) ||
  35 + !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) ||
  36 + !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) {
  37 + puts("Error: blob_decap: Address arguments are not aligned!\n");
  38 + return -EINVAL;
  39 + }
  40 +
21 41 printf("\nDecapsulating blob to get data\n");
22   - desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
  42 + desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE);
23 43 if (!desc) {
24 44 debug("Not enough memory for descriptor allocation\n");
25   - return -1;
  45 + return -ENOMEM;
26 46 }
27 47  
  48 + size = ALIGN(16, ARCH_DMA_MINALIGN);
  49 + flush_dcache_range((unsigned long)key_mod,
  50 + (unsigned long)key_mod + size);
  51 +
  52 + size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN);
  53 + flush_dcache_range((unsigned long)src,
  54 + (unsigned long)src + size);
  55 +
28 56 inline_cnstr_jobdesc_blob_decap(desc, key_mod, src, dst, len);
29 57  
30 58 debug("Descriptor dump:\n");
31 59 for (i = 0; i < 14; i++)
32 60 debug("Word[%d]: %08x\n", i, *(desc + i));
  61 +
  62 + size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN);
  63 + flush_dcache_range((unsigned long)desc,
  64 + (unsigned long)desc + size);
  65 +
33 66 ret = run_descriptor_jr(desc);
34 67  
35   - if (ret)
36   - printf("Error in Decapsulation %d\n", ret);
37   - else
38   - printf("Decapsulation Success\n");
  68 + if (ret) {
  69 + printf("Error in blob decapsulation: %d\n", ret);
  70 + } else {
  71 + size = ALIGN(len, ARCH_DMA_MINALIGN);
  72 + invalidate_dcache_range((unsigned long)dst,
  73 + (unsigned long)dst + size);
39 74  
  75 + puts("Blob decapsulation successful.\n");
  76 + }
  77 +
40 78 free(desc);
41 79 return ret;
42 80 }
43 81  
  82 +/**
  83 + * blob_encap() - Encapsulate the data as a blob
  84 + * @key_mod: - Key modifier address
  85 + * @src: - Source address (data)
  86 + * @dst: - Destination address (blob)
  87 + * @len: - Size of data to be encapsulated
  88 + *
  89 + * Note: Start and end of the key_mod, src and dst buffers have to be aligned to
  90 + * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed.
  91 + *
  92 + * Returns zero on success, negative on error.
  93 + */
44 94 int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
45 95 {
46   - int ret, i = 0;
  96 + int ret, size, i = 0;
47 97 u32 *desc;
48 98  
  99 + if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) ||
  100 + !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) ||
  101 + !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) {
  102 + puts("Error: blob_encap: Address arguments are not aligned!\n");
  103 + return -EINVAL;
  104 + }
  105 +
49 106 printf("\nEncapsulating data to form blob\n");
50   - desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
  107 + desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE);
51 108 if (!desc) {
52 109 debug("Not enough memory for descriptor allocation\n");
53   - return -1;
  110 + return -ENOMEM;
54 111 }
55 112  
  113 + size = ALIGN(16, ARCH_DMA_MINALIGN);
  114 + flush_dcache_range((unsigned long)key_mod,
  115 + (unsigned long)key_mod + size);
  116 +
  117 + size = ALIGN(len, ARCH_DMA_MINALIGN);
  118 + flush_dcache_range((unsigned long)src,
  119 + (unsigned long)src + size);
  120 +
56 121 inline_cnstr_jobdesc_blob_encap(desc, key_mod, src, dst, len);
57 122  
58 123 debug("Descriptor dump:\n");
59 124 for (i = 0; i < 14; i++)
60 125 debug("Word[%d]: %08x\n", i, *(desc + i));
  126 +
  127 + size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN);
  128 + flush_dcache_range((unsigned long)desc,
  129 + (unsigned long)desc + size);
  130 +
61 131 ret = run_descriptor_jr(desc);
62 132  
63   - if (ret)
64   - printf("Error in Encapsulation %d\n", ret);
65   - else
66   - printf("Encapsulation Success\n");
  133 + if (ret) {
  134 + printf("Error in blob encapsulation: %d\n", ret);
  135 + } else {
  136 + size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN);
  137 + invalidate_dcache_range((unsigned long)dst,
  138 + (unsigned long)dst + size);
  139 +
  140 + puts("Blob encapsulation successful.\n");
  141 + }
67 142  
68 143 free(desc);
69 144 return ret;
... ... @@ -215,6 +215,8 @@
215 215 #define SG_ENTRY_OFFSET_SHIFT 0
216 216 };
217 217  
  218 +#define BLOB_SIZE(x) ((x) + 32 + 16) /* Blob buffer size */
  219 +
218 220 #if defined(CONFIG_MX6) || defined(CONFIG_MX7)
219 221 /* Job Ring Base Address */
220 222 #define JR_BASE_ADDR(x) (CONFIG_SYS_FSL_SEC_ADDR + 0x1000 * (x + 1))
... ... @@ -273,8 +275,6 @@
273 275 #define KS_G1 (1 << JR_MID) /* CAAM only */
274 276 #define PERM 0x0000B008 /* Clear on release, lock SMAP
275 277 * lock SMAG group 1 Blob */
276   -
277   -#define BLOB_SIZE(x) (x + 32 + 16) /* Blob buffer size */
278 278  
279 279 /* HAB WRAPPED KEY header */
280 280 #define WRP_HDR_SIZE 0x08