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 <common/debug.h> 16*91f16700Schasinglulu #include <csf_hdr.h> 17*91f16700Schasinglulu #include <drivers/auth/crypto_mod.h> 18*91f16700Schasinglulu #include <drivers/auth/img_parser_mod.h> 19*91f16700Schasinglulu #include <lib/utils.h> 20*91f16700Schasinglulu #include <sfp.h> 21*91f16700Schasinglulu 22*91f16700Schasinglulu /* Temporary variables to speed up the authentication parameters search. These 23*91f16700Schasinglulu * variables are assigned once during the integrity check and used any time an 24*91f16700Schasinglulu * authentication parameter is requested, so we do not have to parse the image 25*91f16700Schasinglulu * again. 26*91f16700Schasinglulu */ 27*91f16700Schasinglulu 28*91f16700Schasinglulu /* Hash of Image + CSF Header + SRK table */ 29*91f16700Schasinglulu uint8_t img_hash[SHA256_BYTES] __aligned(CACHE_WRITEBACK_GRANULE); 30*91f16700Schasinglulu uint32_t hash_len; 31*91f16700Schasinglulu 32*91f16700Schasinglulu /* Key being used for authentication 33*91f16700Schasinglulu * Points to the key in CSF header copied in DDR 34*91f16700Schasinglulu * ESBC client key 35*91f16700Schasinglulu */ 36*91f16700Schasinglulu void *img_key; 37*91f16700Schasinglulu uint32_t key_len; 38*91f16700Schasinglulu 39*91f16700Schasinglulu /* ESBC client signature */ 40*91f16700Schasinglulu void *img_sign; 41*91f16700Schasinglulu uint32_t sign_len; 42*91f16700Schasinglulu enum sig_alg alg; 43*91f16700Schasinglulu 44*91f16700Schasinglulu /* Maximum OID string length ("a.b.c.d.e.f ...") */ 45*91f16700Schasinglulu #define MAX_OID_STR_LEN 64 46*91f16700Schasinglulu 47*91f16700Schasinglulu #define LIB_NAME "NXP CSFv2" 48*91f16700Schasinglulu 49*91f16700Schasinglulu /* 50*91f16700Schasinglulu * Clear all static temporary variables. 51*91f16700Schasinglulu */ 52*91f16700Schasinglulu static void clear_temp_vars(void) 53*91f16700Schasinglulu { 54*91f16700Schasinglulu #define ZERO_AND_CLEAN(x) \ 55*91f16700Schasinglulu do { \ 56*91f16700Schasinglulu zeromem(&x, sizeof(x)); \ 57*91f16700Schasinglulu clean_dcache_range((uintptr_t)&x, sizeof(x)); \ 58*91f16700Schasinglulu } while (0) 59*91f16700Schasinglulu 60*91f16700Schasinglulu ZERO_AND_CLEAN(img_key); 61*91f16700Schasinglulu ZERO_AND_CLEAN(img_sign); 62*91f16700Schasinglulu ZERO_AND_CLEAN(img_hash); 63*91f16700Schasinglulu ZERO_AND_CLEAN(key_len); 64*91f16700Schasinglulu ZERO_AND_CLEAN(hash_len); 65*91f16700Schasinglulu ZERO_AND_CLEAN(sign_len); 66*91f16700Schasinglulu 67*91f16700Schasinglulu #undef ZERO_AND_CLEAN 68*91f16700Schasinglulu } 69*91f16700Schasinglulu 70*91f16700Schasinglulu /* Exported functions */ 71*91f16700Schasinglulu 72*91f16700Schasinglulu static void init(void) 73*91f16700Schasinglulu { 74*91f16700Schasinglulu clear_temp_vars(); 75*91f16700Schasinglulu } 76*91f16700Schasinglulu 77*91f16700Schasinglulu /* 78*91f16700Schasinglulu * This function would check the integrity of the CSF header 79*91f16700Schasinglulu */ 80*91f16700Schasinglulu static int check_integrity(void *img, unsigned int img_len) 81*91f16700Schasinglulu { 82*91f16700Schasinglulu int ret; 83*91f16700Schasinglulu 84*91f16700Schasinglulu /* 85*91f16700Schasinglulu * The image file has been successfully loaded till here. 86*91f16700Schasinglulu * 87*91f16700Schasinglulu * Flush the image to main memory so that it can be authenticated 88*91f16700Schasinglulu * by CAAM, a HW accelerator regardless of cache and MMU state. 89*91f16700Schasinglulu */ 90*91f16700Schasinglulu flush_dcache_range((uintptr_t) img, img_len); 91*91f16700Schasinglulu 92*91f16700Schasinglulu /* 93*91f16700Schasinglulu * Image is appended at an offset of 16K (IMG_OFFSET) to the header. 94*91f16700Schasinglulu * So the size in header should be equal to img_len - IMG_OFFSET 95*91f16700Schasinglulu */ 96*91f16700Schasinglulu VERBOSE("Barker code is %x\n", *(unsigned int *)img); 97*91f16700Schasinglulu ret = validate_esbc_header(img, &img_key, &key_len, &img_sign, 98*91f16700Schasinglulu &sign_len, &alg); 99*91f16700Schasinglulu if (ret < 0) { 100*91f16700Schasinglulu ERROR("Header authentication failed\n"); 101*91f16700Schasinglulu clear_temp_vars(); 102*91f16700Schasinglulu return IMG_PARSER_ERR; 103*91f16700Schasinglulu } 104*91f16700Schasinglulu /* Calculate the hash of various components from the image */ 105*91f16700Schasinglulu ret = calc_img_hash(img, (uint8_t *)img + CSF_HDR_SZ, 106*91f16700Schasinglulu img_len - CSF_HDR_SZ, img_hash, &hash_len); 107*91f16700Schasinglulu if (ret != 0) { 108*91f16700Schasinglulu ERROR("Issue in hash calculation %d\n", ret); 109*91f16700Schasinglulu clear_temp_vars(); 110*91f16700Schasinglulu return IMG_PARSER_ERR; 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu return IMG_PARSER_OK; 114*91f16700Schasinglulu } 115*91f16700Schasinglulu 116*91f16700Schasinglulu /* 117*91f16700Schasinglulu * Extract an authentication parameter from CSF header 118*91f16700Schasinglulu * 119*91f16700Schasinglulu * CSF header has already been parsed and the required information like 120*91f16700Schasinglulu * hash of data, signature, length stored in global variables has been 121*91f16700Schasinglulu * extracted in chek_integrity function. This data 122*91f16700Schasinglulu * is returned back to the caller. 123*91f16700Schasinglulu */ 124*91f16700Schasinglulu static int get_auth_param(const auth_param_type_desc_t *type_desc, 125*91f16700Schasinglulu void *img, unsigned int img_len, 126*91f16700Schasinglulu void **param, unsigned int *param_len) 127*91f16700Schasinglulu { 128*91f16700Schasinglulu int rc = IMG_PARSER_OK; 129*91f16700Schasinglulu 130*91f16700Schasinglulu /* We do not use img because the check_integrity function has already 131*91f16700Schasinglulu * extracted the relevant data ( pk, sig_alg, etc) 132*91f16700Schasinglulu */ 133*91f16700Schasinglulu 134*91f16700Schasinglulu switch (type_desc->type) { 135*91f16700Schasinglulu 136*91f16700Schasinglulu /* Hash will be returned for comparison with signature */ 137*91f16700Schasinglulu case AUTH_PARAM_HASH: 138*91f16700Schasinglulu *param = (void *)img_hash; 139*91f16700Schasinglulu *param_len = (unsigned int)SHA256_BYTES; 140*91f16700Schasinglulu break; 141*91f16700Schasinglulu 142*91f16700Schasinglulu /* Return the public key used for signature extracted from the SRK table 143*91f16700Schasinglulu * after checks with key revocation 144*91f16700Schasinglulu */ 145*91f16700Schasinglulu case AUTH_PARAM_PUB_KEY: 146*91f16700Schasinglulu /* Get the subject public key */ 147*91f16700Schasinglulu /* For a 1K key - the length would be 2k/8 = 0x100 bytes 148*91f16700Schasinglulu * 2K RSA key - 0x200 , 4K RSA - 0x400 149*91f16700Schasinglulu */ 150*91f16700Schasinglulu *param = img_key; 151*91f16700Schasinglulu *param_len = (unsigned int)key_len; 152*91f16700Schasinglulu break; 153*91f16700Schasinglulu 154*91f16700Schasinglulu /* Call a function to tell if signature is RSA or ECDSA. ECDSA to be 155*91f16700Schasinglulu * supported in later platforms like LX2 etc 156*91f16700Schasinglulu */ 157*91f16700Schasinglulu case AUTH_PARAM_SIG_ALG: 158*91f16700Schasinglulu /* Algo will be signature - RSA or ECDSA on hash */ 159*91f16700Schasinglulu *param = (void *)&alg; 160*91f16700Schasinglulu *param_len = 4U; 161*91f16700Schasinglulu break; 162*91f16700Schasinglulu 163*91f16700Schasinglulu /* Return the signature */ 164*91f16700Schasinglulu case AUTH_PARAM_SIG: 165*91f16700Schasinglulu *param = img_sign; 166*91f16700Schasinglulu *param_len = (unsigned int)sign_len; 167*91f16700Schasinglulu break; 168*91f16700Schasinglulu 169*91f16700Schasinglulu case AUTH_PARAM_NV_CTR: 170*91f16700Schasinglulu 171*91f16700Schasinglulu default: 172*91f16700Schasinglulu rc = IMG_PARSER_ERR_NOT_FOUND; 173*91f16700Schasinglulu break; 174*91f16700Schasinglulu } 175*91f16700Schasinglulu 176*91f16700Schasinglulu return rc; 177*91f16700Schasinglulu } 178*91f16700Schasinglulu 179*91f16700Schasinglulu REGISTER_IMG_PARSER_LIB(IMG_PLAT, LIB_NAME, init, 180*91f16700Schasinglulu check_integrity, get_auth_param); 181