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