xref: /arm-trusted-firmware/drivers/nxp/auth/csf_hdr_parser/plat_img_parser.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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