u-boot/drivers/crypto/fsl/fsl_blob.c
Tom Rini d678a59d2d Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay
Ethernet"' I failed to notice that b4 noticed it was based on next and
so took that as the base commit and merged that part of next to master.

This reverts commit c8ffd1356d, reversing
changes made to 2ee6f3a5f7.

Reported-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Tom Rini <trini@konsulko.com>
2024-05-19 08:16:36 -06:00

208 lines
5.4 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2014 Freescale Semiconductor, Inc.
*
*/
#include <common.h>
#include <cpu_func.h>
#include <log.h>
#include <malloc.h>
#include <memalign.h>
#include <fsl_sec.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