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