1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. 3*91f16700Schasinglulu * Copyright 2017-2021 NXP 4*91f16700Schasinglulu * 5*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 6*91f16700Schasinglulu * 7*91f16700Schasinglulu */ 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <assert.h> 10*91f16700Schasinglulu #include <stddef.h> 11*91f16700Schasinglulu #include <stdint.h> 12*91f16700Schasinglulu #include <string.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include <arch_helpers.h> 15*91f16700Schasinglulu #include <cassert.h> 16*91f16700Schasinglulu #include <common/debug.h> 17*91f16700Schasinglulu #include <csf_hdr.h> 18*91f16700Schasinglulu #include <dcfg.h> 19*91f16700Schasinglulu #include <drivers/auth/crypto_mod.h> 20*91f16700Schasinglulu #include <lib/utils.h> 21*91f16700Schasinglulu #include <sfp.h> 22*91f16700Schasinglulu 23*91f16700Schasinglulu /* Maximum OID string length ("a.b.c.d.e.f ...") */ 24*91f16700Schasinglulu #define MAX_OID_STR_LEN 64 25*91f16700Schasinglulu 26*91f16700Schasinglulu #define LIB_NAME "NXP CSFv2" 27*91f16700Schasinglulu 28*91f16700Schasinglulu #ifdef CSF_HDR_CH3 29*91f16700Schasinglulu /* Barker Code for LS Ch3 ESBC Header */ 30*91f16700Schasinglulu static const uint8_t barker_code[CSF_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 }; 31*91f16700Schasinglulu #else 32*91f16700Schasinglulu static const uint8_t barker_code[CSF_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 }; 33*91f16700Schasinglulu #endif 34*91f16700Schasinglulu 35*91f16700Schasinglulu #define CHECK_KEY_LEN(key_len) (((key_len) == 2 * RSA_1K_KEY_SZ_BYTES) || \ 36*91f16700Schasinglulu ((key_len) == 2 * RSA_2K_KEY_SZ_BYTES) || \ 37*91f16700Schasinglulu ((key_len) == 2 * RSA_4K_KEY_SZ_BYTES)) 38*91f16700Schasinglulu 39*91f16700Schasinglulu /* Flag to indicate if values are there in rotpk_hash_table */ 40*91f16700Schasinglulu bool rotpk_not_dpld = true; 41*91f16700Schasinglulu uint8_t rotpk_hash_table[MAX_KEY_ENTRIES][SHA256_BYTES] __aligned(CACHE_WRITEBACK_GRANULE); 42*91f16700Schasinglulu uint32_t num_rotpk_hash_entries; 43*91f16700Schasinglulu 44*91f16700Schasinglulu /* 45*91f16700Schasinglulu * This function deploys the hashes of the various platform keys in 46*91f16700Schasinglulu * rotpk_hash_table. This is done in case of secure boot after comparison 47*91f16700Schasinglulu * of table's hash with the hash in SFP fuses. This installation is done 48*91f16700Schasinglulu * only in the first header parsing. 49*91f16700Schasinglulu */ 50*91f16700Schasinglulu static int deploy_rotpk_hash_table(void *srk_buffer, uint16_t num_srk) 51*91f16700Schasinglulu { 52*91f16700Schasinglulu void *ctx; 53*91f16700Schasinglulu int ret = 0; 54*91f16700Schasinglulu int i, j = 0; 55*91f16700Schasinglulu unsigned int digest_size = SHA256_BYTES; 56*91f16700Schasinglulu enum hash_algo algo = SHA256; 57*91f16700Schasinglulu uint8_t hash[SHA256_BYTES]; 58*91f16700Schasinglulu uint32_t srk_hash[SHA256_BYTES/4] __aligned(CACHE_WRITEBACK_GRANULE); 59*91f16700Schasinglulu struct srk_table *srktbl = (void *)srk_buffer; 60*91f16700Schasinglulu struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(get_sfp_addr() 61*91f16700Schasinglulu + SFP_FUSE_REGS_OFFSET); 62*91f16700Schasinglulu 63*91f16700Schasinglulu 64*91f16700Schasinglulu if (num_srk > MAX_KEY_ENTRIES) { 65*91f16700Schasinglulu return -1; 66*91f16700Schasinglulu } 67*91f16700Schasinglulu 68*91f16700Schasinglulu ret = hash_init(algo, &ctx); 69*91f16700Schasinglulu if (ret != 0) { 70*91f16700Schasinglulu return -1; 71*91f16700Schasinglulu } 72*91f16700Schasinglulu 73*91f16700Schasinglulu /* Update hash with that of SRK table */ 74*91f16700Schasinglulu ret = hash_update(algo, ctx, (uint8_t *)((uint8_t *)srk_buffer), 75*91f16700Schasinglulu num_srk * sizeof(struct srk_table)); 76*91f16700Schasinglulu if (ret != 0) { 77*91f16700Schasinglulu return -1; 78*91f16700Schasinglulu } 79*91f16700Schasinglulu 80*91f16700Schasinglulu /* Copy hash at destination buffer */ 81*91f16700Schasinglulu ret = hash_final(algo, ctx, hash, digest_size); 82*91f16700Schasinglulu if (ret != 0) { 83*91f16700Schasinglulu return -1; 84*91f16700Schasinglulu } 85*91f16700Schasinglulu 86*91f16700Schasinglulu /* Add comparison of hash with SFP hash here */ 87*91f16700Schasinglulu for (i = 0; i < SHA256_BYTES/4; i++) { 88*91f16700Schasinglulu srk_hash[i] = 89*91f16700Schasinglulu mmio_read_32((uintptr_t)&sfp_ccsr_regs->srk_hash[i]); 90*91f16700Schasinglulu } 91*91f16700Schasinglulu 92*91f16700Schasinglulu VERBOSE("SRK table HASH\n"); 93*91f16700Schasinglulu for (i = 0; i < 8; i++) { 94*91f16700Schasinglulu VERBOSE("%x\n", *((uint32_t *)hash + i)); 95*91f16700Schasinglulu } 96*91f16700Schasinglulu 97*91f16700Schasinglulu if (memcmp(hash, srk_hash, SHA256_BYTES) != 0) { 98*91f16700Schasinglulu ERROR("Error in installing ROTPK table\n"); 99*91f16700Schasinglulu ERROR("SRK hash doesn't match the fuse hash\n"); 100*91f16700Schasinglulu return -1; 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu /* Hash table already deployed */ 104*91f16700Schasinglulu if (rotpk_not_dpld == false) { 105*91f16700Schasinglulu return 0; 106*91f16700Schasinglulu } 107*91f16700Schasinglulu 108*91f16700Schasinglulu for (i = 0; i < num_srk; i++) { 109*91f16700Schasinglulu ret = hash_init(algo, &ctx); 110*91f16700Schasinglulu if (ret != 0) { 111*91f16700Schasinglulu return -1; 112*91f16700Schasinglulu } 113*91f16700Schasinglulu 114*91f16700Schasinglulu /* Update hash with that of SRK table */ 115*91f16700Schasinglulu ret = hash_update(algo, ctx, srktbl[i].pkey, srktbl[i].key_len); 116*91f16700Schasinglulu if (ret != 0) { 117*91f16700Schasinglulu return -1; 118*91f16700Schasinglulu } 119*91f16700Schasinglulu 120*91f16700Schasinglulu /* Copy hash at destination buffer */ 121*91f16700Schasinglulu ret = hash_final(algo, ctx, rotpk_hash_table[i], digest_size); 122*91f16700Schasinglulu if (ret != 0) { 123*91f16700Schasinglulu return -1; 124*91f16700Schasinglulu } 125*91f16700Schasinglulu VERBOSE("Table key %d HASH\n", i); 126*91f16700Schasinglulu for (j = 0; j < 8; j++) { 127*91f16700Schasinglulu VERBOSE("%x\n", *((uint32_t *)rotpk_hash_table[i] + j)); 128*91f16700Schasinglulu } 129*91f16700Schasinglulu } 130*91f16700Schasinglulu rotpk_not_dpld = false; 131*91f16700Schasinglulu num_rotpk_hash_entries = num_srk; 132*91f16700Schasinglulu 133*91f16700Schasinglulu return 0; 134*91f16700Schasinglulu } 135*91f16700Schasinglulu 136*91f16700Schasinglulu /* 137*91f16700Schasinglulu * Calculate hash of ESBC hdr and ESBC. This function calculates the 138*91f16700Schasinglulu * single hash of ESBC header and ESBC image 139*91f16700Schasinglulu */ 140*91f16700Schasinglulu int calc_img_hash(struct csf_hdr *hdr, 141*91f16700Schasinglulu void *img_addr, uint32_t img_size, 142*91f16700Schasinglulu uint8_t *img_hash, uint32_t *hash_len) 143*91f16700Schasinglulu { 144*91f16700Schasinglulu void *ctx; 145*91f16700Schasinglulu int ret = 0; 146*91f16700Schasinglulu unsigned int digest_size = SHA256_BYTES; 147*91f16700Schasinglulu enum hash_algo algo = SHA256; 148*91f16700Schasinglulu 149*91f16700Schasinglulu ret = hash_init(algo, &ctx); 150*91f16700Schasinglulu /* Copy hash at destination buffer */ 151*91f16700Schasinglulu if (ret != 0) { 152*91f16700Schasinglulu return -1; 153*91f16700Schasinglulu } 154*91f16700Schasinglulu 155*91f16700Schasinglulu /* Update hash for CSF Header */ 156*91f16700Schasinglulu ret = hash_update(algo, ctx, (uint8_t *)hdr, sizeof(struct csf_hdr)); 157*91f16700Schasinglulu if (ret != 0) { 158*91f16700Schasinglulu return -1; 159*91f16700Schasinglulu } 160*91f16700Schasinglulu 161*91f16700Schasinglulu /* Update hash with that of SRK table */ 162*91f16700Schasinglulu ret = hash_update(algo, ctx, 163*91f16700Schasinglulu (uint8_t *)((uint8_t *)hdr + hdr->srk_tbl_off), 164*91f16700Schasinglulu hdr->len_kr.num_srk * sizeof(struct srk_table)); 165*91f16700Schasinglulu if (ret != 0) { 166*91f16700Schasinglulu return -1; 167*91f16700Schasinglulu } 168*91f16700Schasinglulu 169*91f16700Schasinglulu /* Update hash for actual Image */ 170*91f16700Schasinglulu ret = hash_update(algo, ctx, (uint8_t *)(img_addr), img_size); 171*91f16700Schasinglulu if (ret != 0) { 172*91f16700Schasinglulu return -1; 173*91f16700Schasinglulu } 174*91f16700Schasinglulu 175*91f16700Schasinglulu /* Copy hash at destination buffer */ 176*91f16700Schasinglulu ret = hash_final(algo, ctx, img_hash, digest_size); 177*91f16700Schasinglulu if (ret != 0) { 178*91f16700Schasinglulu return -1; 179*91f16700Schasinglulu } 180*91f16700Schasinglulu 181*91f16700Schasinglulu *hash_len = digest_size; 182*91f16700Schasinglulu 183*91f16700Schasinglulu VERBOSE("IMG encoded HASH\n"); 184*91f16700Schasinglulu for (int i = 0; i < 8; i++) { 185*91f16700Schasinglulu VERBOSE("%x\n", *((uint32_t *)img_hash + i)); 186*91f16700Schasinglulu } 187*91f16700Schasinglulu 188*91f16700Schasinglulu return 0; 189*91f16700Schasinglulu } 190*91f16700Schasinglulu 191*91f16700Schasinglulu /* This function checks if selected key is revoked or not.*/ 192*91f16700Schasinglulu static uint32_t is_key_revoked(uint32_t keynum, uint32_t rev_flag) 193*91f16700Schasinglulu { 194*91f16700Schasinglulu if (keynum == UNREVOCABLE_KEY) { 195*91f16700Schasinglulu return 0; 196*91f16700Schasinglulu } 197*91f16700Schasinglulu 198*91f16700Schasinglulu if (((uint32_t)(1 << (REVOC_KEY_ALIGN - keynum)) & rev_flag) != 0) { 199*91f16700Schasinglulu return 1; 200*91f16700Schasinglulu } 201*91f16700Schasinglulu 202*91f16700Schasinglulu return 0; 203*91f16700Schasinglulu } 204*91f16700Schasinglulu 205*91f16700Schasinglulu /* Parse the header to extract the type of key, 206*91f16700Schasinglulu * Check if key is not revoked 207*91f16700Schasinglulu * and return the key , key length and key_type 208*91f16700Schasinglulu */ 209*91f16700Schasinglulu static int32_t get_key(struct csf_hdr *hdr, uint8_t **key, uint32_t *len, 210*91f16700Schasinglulu enum sig_alg *key_type) 211*91f16700Schasinglulu { 212*91f16700Schasinglulu int i = 0; 213*91f16700Schasinglulu uint32_t ret = 0U; 214*91f16700Schasinglulu uint32_t key_num, key_revoc_flag; 215*91f16700Schasinglulu void *esbc = hdr; 216*91f16700Schasinglulu struct srk_table *srktbl = (void *)((uint8_t *)esbc + hdr->srk_tbl_off); 217*91f16700Schasinglulu bool sb; 218*91f16700Schasinglulu uint32_t mode; 219*91f16700Schasinglulu 220*91f16700Schasinglulu /* We currently support only RSA keys and signature */ 221*91f16700Schasinglulu *key_type = RSA; 222*91f16700Schasinglulu 223*91f16700Schasinglulu /* Check for number of SRK entries */ 224*91f16700Schasinglulu if ((hdr->len_kr.num_srk == 0) || 225*91f16700Schasinglulu (hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) { 226*91f16700Schasinglulu ERROR("Error in NUM entries in SRK Table\n"); 227*91f16700Schasinglulu return -1; 228*91f16700Schasinglulu } 229*91f16700Schasinglulu 230*91f16700Schasinglulu /* 231*91f16700Schasinglulu * Check the key number field. It should be not greater than 232*91f16700Schasinglulu * number of entries in SRK table. 233*91f16700Schasinglulu */ 234*91f16700Schasinglulu key_num = hdr->len_kr.srk_sel; 235*91f16700Schasinglulu if ((key_num == 0) || (key_num > hdr->len_kr.num_srk)) { 236*91f16700Schasinglulu ERROR("Invalid Key number\n"); 237*91f16700Schasinglulu return -1; 238*91f16700Schasinglulu } 239*91f16700Schasinglulu 240*91f16700Schasinglulu /* Get revoc key from sfp */ 241*91f16700Schasinglulu key_revoc_flag = get_key_revoc(); 242*91f16700Schasinglulu 243*91f16700Schasinglulu /* Check if selected key has been revoked */ 244*91f16700Schasinglulu ret = is_key_revoked(key_num, key_revoc_flag); 245*91f16700Schasinglulu if (ret != 0) { 246*91f16700Schasinglulu ERROR("Selected key has been revoked\n"); 247*91f16700Schasinglulu return -1; 248*91f16700Schasinglulu } 249*91f16700Schasinglulu 250*91f16700Schasinglulu /* Check for valid key length - allowed key sized 1k, 2k and 4K */ 251*91f16700Schasinglulu for (i = 0; i < hdr->len_kr.num_srk; i++) { 252*91f16700Schasinglulu if (CHECK_KEY_LEN(srktbl[i].key_len) == 0) { 253*91f16700Schasinglulu ERROR("Invalid key length\n"); 254*91f16700Schasinglulu return -1; 255*91f16700Schasinglulu } 256*91f16700Schasinglulu } 257*91f16700Schasinglulu 258*91f16700Schasinglulu /* We don't return error from here. While parsing we just try to 259*91f16700Schasinglulu * install the srk table. Failure needs to be taken care of in 260*91f16700Schasinglulu * case of secure boot. This failure will be handled at the time 261*91f16700Schasinglulu * of rotpk comparison in plat_get_rotpk_info function 262*91f16700Schasinglulu */ 263*91f16700Schasinglulu sb = check_boot_mode_secure(&mode); 264*91f16700Schasinglulu if (sb) { 265*91f16700Schasinglulu ret = deploy_rotpk_hash_table(srktbl, hdr->len_kr.num_srk); 266*91f16700Schasinglulu if (ret != 0) { 267*91f16700Schasinglulu ERROR("ROTPK FAILURE\n"); 268*91f16700Schasinglulu /* For ITS =1 , return failure */ 269*91f16700Schasinglulu if (mode != 0) { 270*91f16700Schasinglulu return -1; 271*91f16700Schasinglulu } 272*91f16700Schasinglulu ERROR("SECURE BOOT DEV-ENV MODE:\n"); 273*91f16700Schasinglulu ERROR("\tCHECK ROTPK !\n"); 274*91f16700Schasinglulu ERROR("\tCONTINUING ON FAILURE...\n"); 275*91f16700Schasinglulu } 276*91f16700Schasinglulu } 277*91f16700Schasinglulu 278*91f16700Schasinglulu /* Return the length of the selected key */ 279*91f16700Schasinglulu *len = srktbl[key_num - 1].key_len; 280*91f16700Schasinglulu 281*91f16700Schasinglulu /* Point key to the selected key */ 282*91f16700Schasinglulu *key = (uint8_t *)&(srktbl[key_num - 1].pkey); 283*91f16700Schasinglulu 284*91f16700Schasinglulu return 0; 285*91f16700Schasinglulu } 286*91f16700Schasinglulu 287*91f16700Schasinglulu /* 288*91f16700Schasinglulu * This function would parse the CSF header and do the following: 289*91f16700Schasinglulu * 1. Basic integrity checks 290*91f16700Schasinglulu * 2. Key checks and extract the key from SRK/IE Table 291*91f16700Schasinglulu * 3. Key hash comparison with SRKH in fuses in case of SRK Table 292*91f16700Schasinglulu * 4. OEM/UID checks - To be added 293*91f16700Schasinglulu * 5. Hash calculation for various components used in signature 294*91f16700Schasinglulu * 6. Signature integrity checks 295*91f16700Schasinglulu * return -> 0 on success, -1 on failure 296*91f16700Schasinglulu */ 297*91f16700Schasinglulu int validate_esbc_header(void *img_hdr, void **img_key, uint32_t *key_len, 298*91f16700Schasinglulu void **img_sign, uint32_t *sign_len, 299*91f16700Schasinglulu enum sig_alg *algo) 300*91f16700Schasinglulu { 301*91f16700Schasinglulu struct csf_hdr *hdr = img_hdr; 302*91f16700Schasinglulu uint8_t *s; 303*91f16700Schasinglulu int32_t ret = 0; 304*91f16700Schasinglulu void *esbc = (uint8_t *)img_hdr; 305*91f16700Schasinglulu uint8_t *key; 306*91f16700Schasinglulu uint32_t klen; 307*91f16700Schasinglulu 308*91f16700Schasinglulu /* check barker code */ 309*91f16700Schasinglulu if (memcmp(hdr->barker, barker_code, CSF_BARKER_LEN) != 0) { 310*91f16700Schasinglulu ERROR("Wrong barker code in header\n"); 311*91f16700Schasinglulu return -1; 312*91f16700Schasinglulu } 313*91f16700Schasinglulu 314*91f16700Schasinglulu ret = get_key(hdr, &key, &klen, algo); 315*91f16700Schasinglulu if (ret != 0) { 316*91f16700Schasinglulu return -1; 317*91f16700Schasinglulu } 318*91f16700Schasinglulu 319*91f16700Schasinglulu /* check signaure */ 320*91f16700Schasinglulu if (klen == (2 * hdr->sign_len)) { 321*91f16700Schasinglulu /* check signature length */ 322*91f16700Schasinglulu if (((hdr->sign_len == RSA_1K_KEY_SZ_BYTES) || 323*91f16700Schasinglulu (hdr->sign_len == RSA_2K_KEY_SZ_BYTES) || 324*91f16700Schasinglulu (hdr->sign_len == RSA_4K_KEY_SZ_BYTES)) == 0) { 325*91f16700Schasinglulu ERROR("Wrong Signature length in header\n"); 326*91f16700Schasinglulu return -1; 327*91f16700Schasinglulu } 328*91f16700Schasinglulu } else { 329*91f16700Schasinglulu ERROR("RSA key length not twice the signature length\n"); 330*91f16700Schasinglulu return -1; 331*91f16700Schasinglulu } 332*91f16700Schasinglulu 333*91f16700Schasinglulu /* modulus most significant bit should be set */ 334*91f16700Schasinglulu 335*91f16700Schasinglulu if ((key[0] & 0x80) == 0U) { 336*91f16700Schasinglulu ERROR("RSA Public key MSB not set\n"); 337*91f16700Schasinglulu return -1; 338*91f16700Schasinglulu } 339*91f16700Schasinglulu 340*91f16700Schasinglulu /* modulus value should be odd */ 341*91f16700Schasinglulu if ((key[klen / 2 - 1] & 0x1) == 0U) { 342*91f16700Schasinglulu ERROR("Public key Modulus in header not odd\n"); 343*91f16700Schasinglulu return -1; 344*91f16700Schasinglulu } 345*91f16700Schasinglulu 346*91f16700Schasinglulu /* Check signature value < modulus value */ 347*91f16700Schasinglulu s = (uint8_t *)(esbc + hdr->psign); 348*91f16700Schasinglulu 349*91f16700Schasinglulu if (!(memcmp(s, key, hdr->sign_len) < 0)) { 350*91f16700Schasinglulu ERROR("Signature not less than modulus"); 351*91f16700Schasinglulu return -1; 352*91f16700Schasinglulu } 353*91f16700Schasinglulu 354*91f16700Schasinglulu /* Populate the return addresses */ 355*91f16700Schasinglulu *img_sign = (void *)(s); 356*91f16700Schasinglulu 357*91f16700Schasinglulu /* Save the length of signature */ 358*91f16700Schasinglulu *sign_len = hdr->sign_len; 359*91f16700Schasinglulu 360*91f16700Schasinglulu *img_key = (uint8_t *)key; 361*91f16700Schasinglulu 362*91f16700Schasinglulu *key_len = klen; 363*91f16700Schasinglulu 364*91f16700Schasinglulu return ret; 365*91f16700Schasinglulu } 366