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