Home | History | Annotate | Download | only in fsl
      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