uboot/drivers/crypto/fsl/fsl_blob.c
<<
>>
Prefs
   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