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