uboot/board/xilinx/zynq/cmds.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2018 Xilinx, Inc.
   4 */
   5
   6#include <common.h>
   7#include <command.h>
   8#include <log.h>
   9#include <asm/global_data.h>
  10#include <asm/io.h>
  11#include <asm/arch/hardware.h>
  12#include <asm/arch/sys_proto.h>
  13#include <malloc.h>
  14#include <linux/bitops.h>
  15#include <u-boot/md5.h>
  16#include <u-boot/rsa.h>
  17#include <u-boot/rsa-mod-exp.h>
  18#include <u-boot/sha256.h>
  19#include <zynqpl.h>
  20#include <fpga.h>
  21#include <zynq_bootimg.h>
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25#ifdef CONFIG_CMD_ZYNQ_RSA
  26
  27#define ZYNQ_EFUSE_RSA_ENABLE_MASK      0x400
  28#define ZYNQ_ATTRIBUTE_PL_IMAGE_MASK            0x20
  29#define ZYNQ_ATTRIBUTE_CHECKSUM_TYPE_MASK       0x7000
  30#define ZYNQ_ATTRIBUTE_RSA_PRESENT_MASK         0x8000
  31#define ZYNQ_ATTRIBUTE_RSA_PART_OWNER_MASK      0x30000
  32
  33#define ZYNQ_RSA_MODULAR_SIZE                   256
  34#define ZYNQ_RSA_MODULAR_EXT_SIZE               256
  35#define ZYNQ_RSA_EXPO_SIZE                      64
  36#define ZYNQ_RSA_SPK_SIGNATURE_SIZE             256
  37#define ZYNQ_RSA_PARTITION_SIGNATURE_SIZE       256
  38#define ZYNQ_RSA_SIGNATURE_SIZE                 0x6C0
  39#define ZYNQ_RSA_HEADER_SIZE                    4
  40#define ZYNQ_RSA_MAGIC_WORD_SIZE                60
  41#define ZYNQ_RSA_PART_OWNER_UBOOT               1
  42#define ZYNQ_RSA_ALIGN_PPK_START                64
  43
  44#define WORD_LENGTH_SHIFT       2
  45
  46static u8 *ppkmodular;
  47static u8 *ppkmodularex;
  48
  49struct zynq_rsa_public_key {
  50        uint len;               /* Length of modulus[] in number of u32 */
  51        u32 n0inv;              /* -1 / modulus[0] mod 2^32 */
  52        u32 *modulus;   /* modulus as little endian array */
  53        u32 *rr;                /* R^2 as little endian array */
  54};
  55
  56static struct zynq_rsa_public_key public_key;
  57
  58static struct partition_hdr part_hdr[ZYNQ_MAX_PARTITION_NUMBER];
  59
  60/*
  61 * Extract the primary public key components from already autheticated FSBL
  62 */
  63static void zynq_extract_ppk(u32 fsbl_len)
  64{
  65        u32 padsize;
  66        u8 *ppkptr;
  67
  68        debug("%s\n", __func__);
  69
  70        /*
  71         * Extract the authenticated PPK from OCM i.e at end of the FSBL
  72         */
  73        ppkptr = (u8 *)(fsbl_len + ZYNQ_OCM_BASEADDR);
  74        padsize = ((u32)ppkptr % ZYNQ_RSA_ALIGN_PPK_START);
  75        if (padsize)
  76                ppkptr += (ZYNQ_RSA_ALIGN_PPK_START - padsize);
  77
  78        ppkptr += ZYNQ_RSA_HEADER_SIZE;
  79
  80        ppkptr += ZYNQ_RSA_MAGIC_WORD_SIZE;
  81
  82        ppkmodular = (u8 *)ppkptr;
  83        ppkptr += ZYNQ_RSA_MODULAR_SIZE;
  84        ppkmodularex = (u8 *)ppkptr;
  85        ppkptr += ZYNQ_RSA_MODULAR_EXT_SIZE;
  86}
  87
  88/*
  89 * Calculate the inverse(-1 / modulus[0] mod 2^32 ) for the PPK
  90 */
  91static u32 zynq_calc_inv(void)
  92{
  93        u32 modulus = public_key.modulus[0];
  94        u32 tmp = BIT(1);
  95        u32 inverse;
  96
  97        inverse = modulus & BIT(0);
  98
  99        while (tmp) {
 100                inverse *= 2 - modulus * inverse;
 101                tmp *= tmp;
 102        }
 103
 104        return ~(inverse - 1);
 105}
 106
 107/*
 108 * Recreate the signature by padding the bytes and verify with hash value
 109 */
 110static int zynq_pad_and_check(u8 *signature, u8 *hash)
 111{
 112        u8 padding[] = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48,
 113                        0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04,
 114                        0x20};
 115        u8 *pad_ptr = signature + 256;
 116        u32 pad = 202;
 117        u32 ii;
 118
 119        /*
 120         * Re-Create PKCS#1v1.5 Padding
 121         * MSB  ----------------------------------------------------LSB
 122         * 0x0 || 0x1 || 0xFF(for 202 bytes) || 0x0 || T_padding || SHA256 Hash
 123         */
 124        if (*--pad_ptr != 0 || *--pad_ptr != 1)
 125                return -1;
 126
 127        for (ii = 0; ii < pad; ii++) {
 128                if (*--pad_ptr != 0xFF)
 129                        return -1;
 130        }
 131
 132        if (*--pad_ptr != 0)
 133                return -1;
 134
 135        for (ii = 0; ii < sizeof(padding); ii++) {
 136                if (*--pad_ptr != padding[ii])
 137                        return -1;
 138        }
 139
 140        for (ii = 0; ii < 32; ii++) {
 141                if (*--pad_ptr != hash[ii])
 142                        return -1;
 143        }
 144        return 0;
 145}
 146
 147/*
 148 * Verify and extract the hash value from signature using the public key
 149 * and compare it with calculated hash value.
 150 */
 151static int zynq_rsa_verify_key(const struct zynq_rsa_public_key *key,
 152                               const u8 *sig, const u32 sig_len, const u8 *hash)
 153{
 154        int status;
 155        void *buf;
 156
 157        if (!key || !sig || !hash)
 158                return -1;
 159
 160        if (sig_len != (key->len * sizeof(u32))) {
 161                printf("Signature is of incorrect length %d\n", sig_len);
 162                return -1;
 163        }
 164
 165        /* Sanity check for stack size */
 166        if (sig_len > ZYNQ_RSA_SPK_SIGNATURE_SIZE) {
 167                printf("Signature length %u exceeds maximum %d\n", sig_len,
 168                       ZYNQ_RSA_SPK_SIGNATURE_SIZE);
 169                return -1;
 170        }
 171
 172        buf = malloc(sig_len);
 173        if (!buf)
 174                return -1;
 175
 176        memcpy(buf, sig, sig_len);
 177
 178        status = zynq_pow_mod((u32 *)key, (u32 *)buf);
 179        if (status == -1) {
 180                free(buf);
 181                return status;
 182        }
 183
 184        status = zynq_pad_and_check((u8 *)buf, (u8 *)hash);
 185
 186        free(buf);
 187        return status;
 188}
 189
 190/*
 191 * Authenticate the partition
 192 */
 193static int zynq_authenticate_part(u8 *buffer, u32 size)
 194{
 195        u8 hash_signature[32];
 196        u8 *spk_modular;
 197        u8 *spk_modular_ex;
 198        u8 *signature_ptr;
 199        u32 status;
 200
 201        debug("%s\n", __func__);
 202
 203        signature_ptr = (u8 *)(buffer + size - ZYNQ_RSA_SIGNATURE_SIZE);
 204
 205        signature_ptr += ZYNQ_RSA_HEADER_SIZE;
 206
 207        signature_ptr += ZYNQ_RSA_MAGIC_WORD_SIZE;
 208
 209        ppkmodular = (u8 *)signature_ptr;
 210        signature_ptr += ZYNQ_RSA_MODULAR_SIZE;
 211        ppkmodularex = signature_ptr;
 212        signature_ptr += ZYNQ_RSA_MODULAR_EXT_SIZE;
 213        signature_ptr += ZYNQ_RSA_EXPO_SIZE;
 214
 215        sha256_csum_wd((const unsigned char *)signature_ptr,
 216                       (ZYNQ_RSA_MODULAR_EXT_SIZE + ZYNQ_RSA_EXPO_SIZE +
 217                       ZYNQ_RSA_MODULAR_SIZE),
 218                       (unsigned char *)hash_signature, 0x1000);
 219
 220        spk_modular = (u8 *)signature_ptr;
 221        signature_ptr += ZYNQ_RSA_MODULAR_SIZE;
 222        spk_modular_ex = (u8 *)signature_ptr;
 223        signature_ptr += ZYNQ_RSA_MODULAR_EXT_SIZE;
 224        signature_ptr += ZYNQ_RSA_EXPO_SIZE;
 225
 226        public_key.len = ZYNQ_RSA_MODULAR_SIZE / sizeof(u32);
 227        public_key.modulus = (u32 *)ppkmodular;
 228        public_key.rr = (u32 *)ppkmodularex;
 229        public_key.n0inv = zynq_calc_inv();
 230
 231        status = zynq_rsa_verify_key(&public_key, signature_ptr,
 232                                     ZYNQ_RSA_SPK_SIGNATURE_SIZE,
 233                                     hash_signature);
 234        if (status)
 235                return status;
 236
 237        signature_ptr += ZYNQ_RSA_SPK_SIGNATURE_SIZE;
 238
 239        sha256_csum_wd((const unsigned char *)buffer,
 240                       (size - ZYNQ_RSA_PARTITION_SIGNATURE_SIZE),
 241                       (unsigned char *)hash_signature, 0x1000);
 242
 243        public_key.len = ZYNQ_RSA_MODULAR_SIZE / sizeof(u32);
 244        public_key.modulus = (u32 *)spk_modular;
 245        public_key.rr = (u32 *)spk_modular_ex;
 246        public_key.n0inv = zynq_calc_inv();
 247
 248        return zynq_rsa_verify_key(&public_key, (u8 *)signature_ptr,
 249                                   ZYNQ_RSA_PARTITION_SIGNATURE_SIZE,
 250                                   (u8 *)hash_signature);
 251}
 252
 253/*
 254 * Parses the partition header and verfies the authenticated and
 255 * encrypted image.
 256 */
 257static int zynq_verify_image(u32 src_ptr)
 258{
 259        u32 silicon_ver, image_base_addr, status;
 260        u32 partition_num = 0;
 261        u32 efuseval, srcaddr, size, fsbl_len;
 262        struct partition_hdr *hdr_ptr;
 263        u32 part_data_len, part_img_len, part_attr;
 264        u32 part_load_addr, part_dst_addr, part_chksum_offset;
 265        u32 part_start_addr, part_total_size, partitioncount;
 266        bool encrypt_part_flag = false;
 267        bool part_chksum_flag = false;
 268        bool signed_part_flag = false;
 269
 270        image_base_addr = src_ptr;
 271
 272        silicon_ver = zynq_get_silicon_version();
 273
 274        /* RSA not supported in silicon versions 1.0 and 2.0 */
 275        if (silicon_ver == 0 || silicon_ver == 1)
 276                return -1;
 277
 278        zynq_get_partition_info(image_base_addr, &fsbl_len,
 279                                &part_hdr[0]);
 280
 281        /* Extract ppk if efuse was blown Otherwise return error */
 282        efuseval = readl(&efuse_base->status);
 283        if (!(efuseval & ZYNQ_EFUSE_RSA_ENABLE_MASK))
 284                return -1;
 285
 286        zynq_extract_ppk(fsbl_len);
 287
 288        partitioncount = zynq_get_part_count(&part_hdr[0]);
 289
 290        /*
 291         * As the first two partitions are related to fsbl,
 292         * we can ignore those two in bootimage and the below
 293         * code doesn't need to validate it as fsbl is already
 294         * done by now
 295         */
 296        if (partitioncount <= 2 ||
 297            partitioncount > ZYNQ_MAX_PARTITION_NUMBER)
 298                return -1;
 299
 300        while (partition_num < partitioncount) {
 301                if (((part_hdr[partition_num].partitionattr &
 302                   ZYNQ_ATTRIBUTE_RSA_PART_OWNER_MASK) >> 16) !=
 303                   ZYNQ_RSA_PART_OWNER_UBOOT) {
 304                        printf("UBOOT is not Owner for partition %d\n",
 305                               partition_num);
 306                        partition_num++;
 307                        continue;
 308                }
 309                hdr_ptr = &part_hdr[partition_num];
 310                status = zynq_validate_hdr(hdr_ptr);
 311                if (status)
 312                        return status;
 313
 314                part_data_len = hdr_ptr->datawordlen;
 315                part_img_len = hdr_ptr->imagewordlen;
 316                part_attr = hdr_ptr->partitionattr;
 317                part_load_addr = hdr_ptr->loadaddr;
 318                part_chksum_offset = hdr_ptr->checksumoffset;
 319                part_start_addr = hdr_ptr->partitionstart;
 320                part_total_size = hdr_ptr->partitionwordlen;
 321
 322                if (part_data_len != part_img_len) {
 323                        debug("Encrypted\n");
 324                        encrypt_part_flag = true;
 325                }
 326
 327                if (part_attr & ZYNQ_ATTRIBUTE_CHECKSUM_TYPE_MASK)
 328                        part_chksum_flag = true;
 329
 330                if (part_attr & ZYNQ_ATTRIBUTE_RSA_PRESENT_MASK) {
 331                        debug("RSA Signed\n");
 332                        signed_part_flag = true;
 333                        size = part_total_size << WORD_LENGTH_SHIFT;
 334                } else {
 335                        size = part_img_len;
 336                }
 337
 338                if (!signed_part_flag && !part_chksum_flag) {
 339                        printf("Partition not signed & no chksum\n");
 340                        partition_num++;
 341                        continue;
 342                }
 343
 344                srcaddr = image_base_addr +
 345                          (part_start_addr << WORD_LENGTH_SHIFT);
 346
 347                /*
 348                 * This validation is just for PS DDR.
 349                 * TODO: Update this for PL DDR check as well.
 350                 */
 351                if (part_load_addr < gd->bd->bi_dram[0].start &&
 352                    ((part_load_addr + part_data_len) >
 353                    (gd->bd->bi_dram[0].start +
 354                     gd->bd->bi_dram[0].size))) {
 355                        printf("INVALID_LOAD_ADDRESS_FAIL\n");
 356                        return -1;
 357                }
 358
 359                if (part_attr & ZYNQ_ATTRIBUTE_PL_IMAGE_MASK)
 360                        part_load_addr = srcaddr;
 361                else
 362                        memcpy((u32 *)part_load_addr, (u32 *)srcaddr,
 363                               size);
 364
 365                if (part_chksum_flag) {
 366                        part_chksum_offset = image_base_addr +
 367                                             (part_chksum_offset <<
 368                                             WORD_LENGTH_SHIFT);
 369                        status = zynq_validate_partition(part_load_addr,
 370                                                         (part_total_size <<
 371                                                          WORD_LENGTH_SHIFT),
 372                                                         part_chksum_offset);
 373                        if (status != 0) {
 374                                printf("PART_CHKSUM_FAIL\n");
 375                                return -1;
 376                        }
 377                        debug("Partition Validation Done\n");
 378                }
 379
 380                if (signed_part_flag) {
 381                        status = zynq_authenticate_part((u8 *)part_load_addr,
 382                                                        size);
 383                        if (status != 0) {
 384                                printf("AUTHENTICATION_FAIL\n");
 385                                return -1;
 386                        }
 387                        debug("Authentication Done\n");
 388                }
 389
 390                if (encrypt_part_flag) {
 391                        debug("DECRYPTION\n");
 392
 393                        part_dst_addr = part_load_addr;
 394
 395                        if (part_attr & ZYNQ_ATTRIBUTE_PL_IMAGE_MASK) {
 396                                partition_num++;
 397                                continue;
 398                        }
 399
 400                        status = zynq_decrypt_load(part_load_addr,
 401                                                   part_img_len,
 402                                                   part_dst_addr,
 403                                                   part_data_len,
 404                                                   BIT_NONE);
 405                        if (status != 0) {
 406                                printf("DECRYPTION_FAIL\n");
 407                                return -1;
 408                        }
 409                }
 410                partition_num++;
 411        }
 412
 413        return 0;
 414}
 415
 416static int do_zynq_rsa(struct cmd_tbl *cmdtp, int flag, int argc,
 417                       char *const argv[])
 418{
 419        u32 src_ptr;
 420        char *endp;
 421
 422        if (argc != cmdtp->maxargs)
 423                return CMD_RET_FAILURE;
 424
 425        src_ptr = hextoul(argv[2], &endp);
 426        if (*argv[2] == 0 || *endp != 0)
 427                return CMD_RET_USAGE;
 428
 429        if (zynq_verify_image(src_ptr))
 430                return CMD_RET_FAILURE;
 431
 432        return CMD_RET_SUCCESS;
 433}
 434#endif
 435
 436#ifdef CONFIG_CMD_ZYNQ_AES
 437static int zynq_decrypt_image(struct cmd_tbl *cmdtp, int flag, int argc,
 438                              char *const argv[])
 439{
 440        char *endp;
 441        u32 srcaddr, srclen, dstaddr, dstlen;
 442        int status;
 443        u8 imgtype = BIT_NONE;
 444
 445        if (argc < 5 && argc > cmdtp->maxargs)
 446                return CMD_RET_USAGE;
 447
 448        if (argc == 5) {
 449                if (!strcmp("load", argv[2]))
 450                        imgtype = BIT_FULL;
 451                else if (!strcmp("loadp", argv[2]))
 452                        imgtype = BIT_PARTIAL;
 453                else
 454                        return CMD_RET_USAGE;
 455
 456                srcaddr = hextoul(argv[3], &endp);
 457                if (*argv[3] == 0 || *endp != 0)
 458                        return CMD_RET_USAGE;
 459                srclen = hextoul(argv[4], &endp);
 460                if (*argv[4] == 0 || *endp != 0)
 461                        return CMD_RET_USAGE;
 462
 463                dstaddr = 0xFFFFFFFF;
 464                dstlen = srclen;
 465        } else {
 466                srcaddr = hextoul(argv[2], &endp);
 467                if (*argv[2] == 0 || *endp != 0)
 468                        return CMD_RET_USAGE;
 469                srclen = hextoul(argv[3], &endp);
 470                if (*argv[3] == 0 || *endp != 0)
 471                        return CMD_RET_USAGE;
 472                dstaddr = hextoul(argv[4], &endp);
 473                if (*argv[4] == 0 || *endp != 0)
 474                        return CMD_RET_USAGE;
 475                dstlen = hextoul(argv[5], &endp);
 476                if (*argv[5] == 0 || *endp != 0)
 477                        return CMD_RET_USAGE;
 478        }
 479
 480        /*
 481         * Roundup source and destination lengths to
 482         * word size
 483         */
 484        if (srclen % 4)
 485                srclen = roundup(srclen, 4);
 486        if (dstlen % 4)
 487                dstlen = roundup(dstlen, 4);
 488
 489        status = zynq_decrypt_load(srcaddr, srclen >> 2, dstaddr,
 490                                   dstlen >> 2, imgtype);
 491        if (status != 0)
 492                return CMD_RET_FAILURE;
 493
 494        return CMD_RET_SUCCESS;
 495}
 496#endif
 497
 498static struct cmd_tbl zynq_commands[] = {
 499#ifdef CONFIG_CMD_ZYNQ_RSA
 500        U_BOOT_CMD_MKENT(rsa, 3, 1, do_zynq_rsa, "", ""),
 501#endif
 502#ifdef CONFIG_CMD_ZYNQ_AES
 503        U_BOOT_CMD_MKENT(aes, 6, 1, zynq_decrypt_image, "", ""),
 504#endif
 505};
 506
 507static int do_zynq(struct cmd_tbl *cmdtp, int flag, int argc,
 508                   char *const argv[])
 509{
 510        struct cmd_tbl *zynq_cmd;
 511        int ret;
 512
 513        if (!ARRAY_SIZE(zynq_commands)) {
 514                puts("No zynq specific command enabled\n");
 515                return CMD_RET_USAGE;
 516        }
 517
 518        if (argc < 2)
 519                return CMD_RET_USAGE;
 520        zynq_cmd = find_cmd_tbl(argv[1], zynq_commands,
 521                                ARRAY_SIZE(zynq_commands));
 522        if (!zynq_cmd)
 523                return CMD_RET_USAGE;
 524
 525        ret = zynq_cmd->cmd(zynq_cmd, flag, argc, argv);
 526
 527        return cmd_process_error(zynq_cmd, ret);
 528}
 529
 530#ifdef CONFIG_SYS_LONGHELP
 531static char zynq_help_text[] =
 532        ""
 533#ifdef CONFIG_CMD_ZYNQ_RSA
 534        "rsa <baseaddr>  - Verifies the authenticated and encrypted\n"
 535        "                  zynq images and loads them back to load\n"
 536        "                  addresses as specified in BOOT image(BOOT.BIN)\n"
 537#endif
 538#ifdef CONFIG_CMD_ZYNQ_AES
 539        "aes <srcaddr> <srclen> <dstaddr> <dstlen>\n"
 540        "                - Decrypts the encrypted image present in source\n"
 541        "                  address and places the decrypted image at\n"
 542        "                  destination address\n"
 543        "aes load <srcaddr> <srclen>\n"
 544        "aes loadp <srcaddr> <srclen>\n"
 545        "       if operation type is load or loadp, it loads the encrypted\n"
 546        "       full or partial bitstream on to PL respectively.\n"
 547#endif
 548        ;
 549#endif
 550
 551U_BOOT_CMD(zynq,        6,      0,      do_zynq,
 552           "Zynq specific commands", zynq_help_text
 553);
 554