Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2014 Freescale Semiconductor, Inc. * */ #include <cpu_func.h> #include <log.h> #include <malloc.h> #include <memalign.h> #include <fsl_sec.h> #include <string.h> #include <asm/cache.h> #include <linux/errno.h> #include "jobdesc.h" #include "desc.h" #include "jr.h" /** * blob_decap() - Decapsulate the data from a blob * @key_mod: - Key modifier address * @src: - Source address (blob) * @dst: - Destination address (data) * @len: - Size of decapsulated data * * Note: Start and end of the key_mod, src and dst buffers have to be aligned to * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed. * * Returns zero on success, negative on error. */ int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len) { int ret, size, i = 0; u32 *desc; if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { puts("Error: blob_decap: Address arguments are not aligned!\n"); return -EINVAL; } printf("\nDecapsulating blob to get data\n"); desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); if (!desc) { debug("Not enough memory for descriptor allocation\n"); return -ENOMEM; } size = ALIGN(16, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)key_mod, (unsigned long)key_mod + size); size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)src, (unsigned long)src + size); inline_cnstr_jobdesc_blob_decap(desc, key_mod, src, dst, len); debug("Descriptor dump:\n"); for (i = 0; i < 14; i++) debug("Word[%d]: %08x\n", i, *(desc + i)); size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)desc, (unsigned long)desc + size); flush_dcache_range((unsigned long)dst, (unsigned long)dst + size); ret = run_descriptor_jr(desc); if (ret) { /* clear the blob data output buffer */ memset(dst, 0x00, len); size = ALIGN(len, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)dst, (unsigned long)dst + size); printf("Error in blob decapsulation: %d\n", ret); } else { size = ALIGN(len, ARCH_DMA_MINALIGN); invalidate_dcache_range((unsigned long)dst, (unsigned long)dst + size); puts("Blob decapsulation successful.\n"); } free(desc); return ret; } /** * blob_encap() - Encapsulate the data as a blob * @key_mod: - Key modifier address * @src: - Source address (data) * @dst: - Destination address (blob) * @len: - Size of data to be encapsulated * * Note: Start and end of the key_mod, src and dst buffers have to be aligned to * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed. * * Returns zero on success, negative on error. */ int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len) { int ret, size, i = 0; u32 *desc; if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { puts("Error: blob_encap: Address arguments are not aligned!\n"); return -EINVAL; } printf("\nEncapsulating data to form blob\n"); desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); if (!desc) { debug("Not enough memory for descriptor allocation\n"); return -ENOMEM; } size = ALIGN(16, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)key_mod, (unsigned long)key_mod + size); size = ALIGN(len, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)src, (unsigned long)src + size); inline_cnstr_jobdesc_blob_encap(desc, key_mod, src, dst, len); debug("Descriptor dump:\n"); for (i = 0; i < 14; i++) debug("Word[%d]: %08x\n", i, *(desc + i)); size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)desc, (unsigned long)desc + size); flush_dcache_range((unsigned long)dst, (unsigned long)dst + size); ret = run_descriptor_jr(desc); if (ret) { printf("Error in blob encapsulation: %d\n", ret); } else { size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); invalidate_dcache_range((unsigned long)dst, (unsigned long)dst + size); puts("Blob encapsulation successful.\n"); } free(desc); return ret; } #ifdef CONFIG_CMD_DEKBLOB int blob_dek(const u8 *src, u8 *dst, u8 len) { int ret, size, i = 0; u32 *desc; int out_sz = WRP_HDR_SIZE + len + KEY_BLOB_SIZE + MAC_SIZE; puts("\nEncapsulating provided DEK to form blob\n"); desc = memalign(ARCH_DMA_MINALIGN, sizeof(uint32_t) * DEK_BLOB_DESCSIZE); if (!desc) { debug("Not enough memory for descriptor allocation\n"); return -ENOMEM; } ret = inline_cnstr_jobdesc_blob_dek(desc, src, dst, len); if (ret) { debug("Error in Job Descriptor Construction: %d\n", ret); } else { size = roundup(sizeof(uint32_t) * DEK_BLOB_DESCSIZE, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)desc, (unsigned long)desc + size); size = roundup(sizeof(uint8_t) * out_sz, ARCH_DMA_MINALIGN); flush_dcache_range((unsigned long)dst, (unsigned long)dst + size); ret = run_descriptor_jr(desc); } if (ret) { debug("Error in Encapsulation %d\n", ret); goto err; } size = roundup(out_sz, ARCH_DMA_MINALIGN); invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size); puts("DEK Blob\n"); for (i = 0; i < out_sz; i++) printf("%02X", ((uint8_t *)dst)[i]); printf("\n"); err: free(desc); return ret; } #endif |