uboot/arch/arm/mach-imx/parse-container.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2018-2019 NXP
   4 */
   5
   6#include <common.h>
   7#include <errno.h>
   8#include <log.h>
   9#include <spl.h>
  10#include <asm/mach-imx/image.h>
  11#ifdef CONFIG_AHAB_BOOT
  12#include <asm/arch/sci/sci.h>
  13#endif
  14
  15#define SEC_SECURE_RAM_BASE             0x31800000UL
  16#define SEC_SECURE_RAM_END_BASE         (SEC_SECURE_RAM_BASE + 0xFFFFUL)
  17#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE      0x60000000UL
  18
  19#define SECO_PT         2U
  20
  21#ifdef CONFIG_AHAB_BOOT
  22static int authenticate_image(struct boot_img_t *img, int image_index)
  23{
  24        sc_faddr_t start, end;
  25        sc_rm_mr_t mr;
  26        int err;
  27        int ret = 0;
  28
  29        debug("img %d, dst 0x%x, src 0x%x, size 0x%x\n",
  30              image_index, (uint32_t)img->dst, img->offset, img->size);
  31
  32        /* Find the memreg and set permission for seco pt */
  33        err = sc_rm_find_memreg(-1, &mr,
  34                                img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
  35                                ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1);
  36
  37        if (err) {
  38                printf("can't find memreg for image %d load address 0x%x, error %d\n",
  39                       image_index, img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), err);
  40                return -ENOMEM;
  41        }
  42
  43        err = sc_rm_get_memreg_info(-1, mr, &start, &end);
  44        if (!err)
  45                debug("memreg %u 0x%x -- 0x%x\n", mr, start, end);
  46
  47        err = sc_rm_set_memreg_permissions(-1, mr,
  48                                           SECO_PT, SC_RM_PERM_FULL);
  49        if (err) {
  50                printf("set permission failed for img %d, error %d\n",
  51                       image_index, err);
  52                return -EPERM;
  53        }
  54
  55        err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE,
  56                                   1 << image_index);
  57        if (err) {
  58                printf("authenticate img %d failed, return %d\n",
  59                       image_index, err);
  60                ret = -EIO;
  61        }
  62
  63        err = sc_rm_set_memreg_permissions(-1, mr,
  64                                           SECO_PT, SC_RM_PERM_NONE);
  65        if (err) {
  66                printf("remove permission failed for img %d, error %d\n",
  67                       image_index, err);
  68                ret = -EPERM;
  69        }
  70
  71        return ret;
  72}
  73#endif
  74
  75static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
  76                                          struct spl_load_info *info,
  77                                          struct container_hdr *container,
  78                                          int image_index,
  79                                          u32 container_sector)
  80{
  81        struct boot_img_t *images;
  82        ulong sector;
  83        u32 sectors;
  84
  85        if (image_index > container->num_images) {
  86                debug("Invalid image number\n");
  87                return NULL;
  88        }
  89
  90        images = (struct boot_img_t *)((u8 *)container +
  91                                       sizeof(struct container_hdr));
  92
  93        if (images[image_index].offset % info->bl_len) {
  94                printf("%s: image%d offset not aligned to %u\n",
  95                       __func__, image_index, info->bl_len);
  96                return NULL;
  97        }
  98
  99        sectors = roundup(images[image_index].size, info->bl_len) /
 100                info->bl_len;
 101        sector = images[image_index].offset / info->bl_len +
 102                container_sector;
 103
 104        debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
 105              container, sector, sectors);
 106        if (info->read(info, sector, sectors,
 107                       (void *)images[image_index].entry) != sectors) {
 108                printf("%s wrong\n", __func__);
 109                return NULL;
 110        }
 111
 112#ifdef CONFIG_AHAB_BOOT
 113        if (authenticate_image(&images[image_index], image_index)) {
 114                printf("Failed to authenticate image %d\n", image_index);
 115                return NULL;
 116        }
 117#endif
 118
 119        return &images[image_index];
 120}
 121
 122static int read_auth_container(struct spl_image_info *spl_image,
 123                               struct spl_load_info *info, ulong sector)
 124{
 125        struct container_hdr *container = NULL;
 126        u16 length;
 127        u32 sectors;
 128        int i, size, ret = 0;
 129
 130        size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
 131        sectors = size / info->bl_len;
 132
 133        /*
 134         * It will not override the ATF code, so safe to use it here,
 135         * no need malloc
 136         */
 137        container = (struct container_hdr *)spl_get_load_buffer(-size, size);
 138
 139        debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
 140              container, sector, sectors);
 141        if (info->read(info, sector, sectors, container) != sectors)
 142                return -EIO;
 143
 144        if (container->tag != 0x87 && container->version != 0x0) {
 145                printf("Wrong container header");
 146                return -ENOENT;
 147        }
 148
 149        if (!container->num_images) {
 150                printf("Wrong container, no image found");
 151                return -ENOENT;
 152        }
 153
 154        length = container->length_lsb + (container->length_msb << 8);
 155        debug("Container length %u\n", length);
 156
 157        if (length > CONTAINER_HDR_ALIGNMENT) {
 158                size = roundup(length, info->bl_len);
 159                sectors = size / info->bl_len;
 160
 161                container = (struct container_hdr *)spl_get_load_buffer(-size, size);
 162
 163                debug("%s: container: %p sector: %lu sectors: %u\n",
 164                      __func__, container, sector, sectors);
 165                if (info->read(info, sector, sectors, container) !=
 166                    sectors)
 167                        return -EIO;
 168        }
 169
 170#ifdef CONFIG_AHAB_BOOT
 171        memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container,
 172               ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
 173
 174        ret = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER,
 175                                   SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE);
 176        if (ret) {
 177                printf("authenticate container hdr failed, return %d\n", ret);
 178                return ret;
 179        }
 180#endif
 181
 182        for (i = 0; i < container->num_images; i++) {
 183                struct boot_img_t *image = read_auth_image(spl_image, info,
 184                                                           container, i,
 185                                                           sector);
 186
 187                if (!image) {
 188                        ret = -EINVAL;
 189                        goto end_auth;
 190                }
 191
 192                if (i == 0) {
 193                        spl_image->load_addr = image->dst;
 194                        spl_image->entry_point = image->entry;
 195                }
 196        }
 197
 198end_auth:
 199#ifdef CONFIG_AHAB_BOOT
 200        if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0))
 201                printf("Error: release container failed!\n");
 202#endif
 203        return ret;
 204}
 205
 206int spl_load_imx_container(struct spl_image_info *spl_image,
 207                           struct spl_load_info *info, ulong sector)
 208{
 209        return read_auth_container(spl_image, info, sector);
 210}
 211