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