blob: 8fd6dd63b1d5f068afc72421346833f81dbcab20 [file] [log] [blame]
gaurav ranac3a50422015-02-27 09:45:35 +05301/*
2 * Copyright 2015 Freescale Semiconductor, Inc.
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
8#include <fsl_validate.h>
9#include <fsl_secboot_err.h>
10#include <fsl_sfp.h>
11#include <fsl_sec.h>
12#include <command.h>
13#include <malloc.h>
14#include <dm/uclass.h>
15#include <u-boot/rsa-mod-exp.h>
16#include <hash.h>
17#include <fsl_secboot_err.h>
Aneesh Bansalb3e98202015-12-08 13:54:29 +053018#ifdef CONFIG_LS102XA
gaurav ranac3a50422015-02-27 09:45:35 +053019#include <asm/arch/immap_ls102xa.h>
20#endif
21
22#define SHA256_BITS 256
23#define SHA256_BYTES (256/8)
24#define SHA256_NIBBLES (256/4)
25#define NUM_HEX_CHARS (sizeof(ulong) * 2)
26
Aneesh Bansal24b8fae2015-12-08 14:14:13 +053027#define CHECK_KEY_LEN(key_len) (((key_len) == 2 * KEY_SIZE_BYTES / 4) || \
28 ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
29 ((key_len) == 2 * KEY_SIZE_BYTES))
30
gaurav ranac3a50422015-02-27 09:45:35 +053031/* This array contains DER value for SHA-256 */
32static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
33 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
34 0x04, 0x20
35 };
36
37static u8 hash_val[SHA256_BYTES];
38static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
39
40void branch_to_self(void) __attribute__ ((noreturn));
41
42/*
43 * This function will put core in infinite loop.
44 * This will be called when the ESBC can not proceed further due
45 * to some unknown errors.
46 */
47void branch_to_self(void)
48{
49 printf("Core is in infinite loop due to errors.\n");
50self:
51 goto self;
52}
53
54#if defined(CONFIG_FSL_ISBC_KEY_EXT)
55static u32 check_ie(struct fsl_secboot_img_priv *img)
56{
57 if (img->hdr.ie_flag)
58 return 1;
59
60 return 0;
61}
62
63/* This function returns the CSF Header Address of uboot
64 * For MPC85xx based platforms, the LAW mapping for NOR
65 * flash changes in uboot code. Hence the offset needs
66 * to be calculated and added to the new NOR flash base
67 * address
68 */
69#if defined(CONFIG_MPC85xx)
Aneesh Bansal9c028fa2015-09-17 16:16:34 +053070int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
gaurav ranac3a50422015-02-27 09:45:35 +053071{
72 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
73 u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
74 u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
Aneesh Bansal9c028fa2015-09-17 16:16:34 +053075 u32 flash_addr, addr;
gaurav ranac3a50422015-02-27 09:45:35 +053076 int found = 0;
77 int i = 0;
78
79 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
80 flash_addr = flash_info[i].start[0];
81 addr = flash_info[i].start[0] + csf_flash_offset;
82 if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
Aneesh Bansal9c028fa2015-09-17 16:16:34 +053083 debug("Barker found on addr %x\n", addr);
gaurav ranac3a50422015-02-27 09:45:35 +053084 found = 1;
85 break;
86 }
87 }
88
89 if (!found)
90 return -1;
91
92 *csf_addr = addr;
93 *flash_base_addr = flash_addr;
94
95 return 0;
96}
97#else
98/* For platforms like LS1020, correct flash address is present in
99 * the header. So the function reqturns flash base address as 0
100 */
Aneesh Bansal9c028fa2015-09-17 16:16:34 +0530101int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
gaurav ranac3a50422015-02-27 09:45:35 +0530102{
103 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
104 u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
105
Aneesh Bansalb3e98202015-12-08 13:54:29 +0530106 if (memcmp((u8 *)(uintptr_t)csf_hdr_addr,
107 barker_code, ESBC_BARKER_LEN))
gaurav ranac3a50422015-02-27 09:45:35 +0530108 return -1;
109
110 *csf_addr = csf_hdr_addr;
111 *flash_base_addr = 0;
112 return 0;
113}
114#endif
115
Aneesh Bansal9c028fa2015-09-17 16:16:34 +0530116static int get_ie_info_addr(u32 *ie_addr)
gaurav ranac3a50422015-02-27 09:45:35 +0530117{
118 struct fsl_secboot_img_hdr *hdr;
119 struct fsl_secboot_sg_table *sg_tbl;
Aneesh Bansal9c028fa2015-09-17 16:16:34 +0530120 u32 flash_base_addr, csf_addr;
gaurav ranac3a50422015-02-27 09:45:35 +0530121
122 if (get_csf_base_addr(&csf_addr, &flash_base_addr))
123 return -1;
124
Aneesh Bansalb3e98202015-12-08 13:54:29 +0530125 hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr;
gaurav ranac3a50422015-02-27 09:45:35 +0530126
127 /* For SoC's with Trust Architecture v1 with corenet bus
128 * the sg table field in CSF header has absolute address
129 * for sg table in memory. In other Trust Architecture,
130 * this field specifies the offset of sg table from the
131 * base address of CSF Header
132 */
133#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
134 sg_tbl = (struct fsl_secboot_sg_table *)
Aneesh Bansal9c028fa2015-09-17 16:16:34 +0530135 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
gaurav ranac3a50422015-02-27 09:45:35 +0530136 flash_base_addr);
137#else
Aneesh Bansalb3e98202015-12-08 13:54:29 +0530138 sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
Aneesh Bansal9c028fa2015-09-17 16:16:34 +0530139 (u32)hdr->psgtable);
gaurav ranac3a50422015-02-27 09:45:35 +0530140#endif
141
142 /* IE Key Table is the first entry in the SG Table */
143#if defined(CONFIG_MPC85xx)
144 *ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
145 flash_base_addr;
146#else
147 *ie_addr = sg_tbl->src_addr;
148#endif
149
Aneesh Bansal9c028fa2015-09-17 16:16:34 +0530150 debug("IE Table address is %x\n", *ie_addr);
gaurav ranac3a50422015-02-27 09:45:35 +0530151 return 0;
152}
153
154#endif
155
156#ifdef CONFIG_KEY_REVOCATION
157/* This function checks srk_table_flag in header and set/reset srk_flag.*/
158static u32 check_srk(struct fsl_secboot_img_priv *img)
159{
160 if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
161 return 1;
162
163 return 0;
164}
165
166/* This function returns ospr's key_revoc values.*/
167static u32 get_key_revoc(void)
168{
169 struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
170 return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
171 OSPR_KEY_REVOC_SHIFT;
172}
173
174/* This function checks if selected key is revoked or not.*/
175static u32 is_key_revoked(u32 keynum, u32 rev_flag)
176{
177 if (keynum == UNREVOCABLE_KEY)
178 return 0;
179
180 if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
181 return 1;
182
183 return 0;
184}
185
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530186/* It read validates srk_table key lengths.*/
187static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
gaurav ranac3a50422015-02-27 09:45:35 +0530188{
189 int i = 0;
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530190 u32 ret, key_num, key_revoc_flag, size;
191 struct fsl_secboot_img_hdr *hdr = &img->hdr;
192 void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
193
194 if ((hdr->len_kr.num_srk == 0) ||
195 (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
196 return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
197
198 key_num = hdr->len_kr.srk_sel;
199 if (key_num == 0 || key_num > hdr->len_kr.num_srk)
200 return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
201
202 /* Get revoc key from sfp */
203 key_revoc_flag = get_key_revoc();
204 ret = is_key_revoked(key_num, key_revoc_flag);
205 if (ret)
206 return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
207
208 size = hdr->len_kr.num_srk * sizeof(struct srk_table);
209
210 memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
211
212 for (i = 0; i < hdr->len_kr.num_srk; i++) {
213 if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
gaurav ranac3a50422015-02-27 09:45:35 +0530214 return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
215 }
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530216
217 img->key_len = img->srk_tbl[key_num - 1].key_len;
218
219 memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
220 img->key_len);
221
gaurav ranac3a50422015-02-27 09:45:35 +0530222 return 0;
223}
224#endif
225
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530226static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
227{
228 struct fsl_secboot_img_hdr *hdr = &img->hdr;
229 void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
230
231 /* check key length */
232 if (!CHECK_KEY_LEN(hdr->key_len))
233 return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
234
235 memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
236
237 img->key_len = hdr->key_len;
238
239 return 0;
240}
241
242#if defined(CONFIG_FSL_ISBC_KEY_EXT)
243static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
244{
245 struct fsl_secboot_img_hdr *hdr = &img->hdr;
246 u32 ie_key_len, ie_revoc_flag, ie_num;
247 struct ie_key_info *ie_info;
248
249 if (get_ie_info_addr(&img->ie_addr))
250 return ERROR_IE_TABLE_NOT_FOUND;
251 ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
252 if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
253 return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
254
255 ie_num = hdr->ie_key_sel;
256 if (ie_num == 0 || ie_num > ie_info->num_keys)
257 return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
258
259 ie_revoc_flag = ie_info->key_revok;
260 if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
261 return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
262
263 ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
264
265 if (!CHECK_KEY_LEN(ie_key_len))
266 return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
267
268 memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
269 ie_key_len);
270
271 img->key_len = ie_key_len;
272 return 0;
273}
274#endif
275
276
gaurav ranac3a50422015-02-27 09:45:35 +0530277/* This function return length of public key.*/
278static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
279{
280 return img->key_len;
281}
282
283/*
284 * Handles the ESBC uboot client header verification failure.
285 * This function handles all the errors which might occur in the
286 * parsing and checking of ESBC uboot client header. It will also
287 * set the error bits in the SEC_MON.
288 */
289static void fsl_secboot_header_verification_failure(void)
290{
291 struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
292 (CONFIG_SYS_SEC_MON_ADDR);
293 struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
294 u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
295
296 /* 29th bit of OSPR is ITS */
297 u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
298
299 /*
300 * Read the SEC_MON status register
301 * Read SSM_ST field
302 */
303 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
304 if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
305 if (its == 1)
306 change_sec_mon_state(HPSR_SSM_ST_TRUST,
307 HPSR_SSM_ST_SOFT_FAIL);
308 else
309 change_sec_mon_state(HPSR_SSM_ST_TRUST,
310 HPSR_SSM_ST_NON_SECURE);
311 }
312
313 printf("Generating reset request\n");
314 do_reset(NULL, 0, 0, NULL);
315}
316
317/*
318 * Handles the ESBC uboot client image verification failure.
319 * This function handles all the errors which might occur in the
320 * public key hash comparison and signature verification of
321 * ESBC uboot client image. It will also
322 * set the error bits in the SEC_MON.
323 */
324static void fsl_secboot_image_verification_failure(void)
325{
326 struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
327 (CONFIG_SYS_SEC_MON_ADDR);
328 struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
329 u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
330
Aneesh Bansal52b4b2d2015-10-12 22:05:50 +0530331 u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
gaurav ranac3a50422015-02-27 09:45:35 +0530332
333 /*
334 * Read the SEC_MON status register
335 * Read SSM_ST field
336 */
337 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
338 if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
339 if (its == 1) {
340 change_sec_mon_state(HPSR_SSM_ST_TRUST,
341 HPSR_SSM_ST_SOFT_FAIL);
342
343 printf("Generating reset request\n");
344 do_reset(NULL, 0, 0, NULL);
345 } else {
346 change_sec_mon_state(HPSR_SSM_ST_TRUST,
347 HPSR_SSM_ST_NON_SECURE);
348 }
349 }
350}
351
352static void fsl_secboot_bootscript_parse_failure(void)
353{
354 fsl_secboot_header_verification_failure();
355}
356
357/*
358 * Handles the errors in esbc boot.
359 * This function handles all the errors which might occur in the
360 * esbc boot phase. It will call the appropriate api to log the
361 * errors and set the error bits in the SEC_MON.
362 */
363void fsl_secboot_handle_error(int error)
364{
365 const struct fsl_secboot_errcode *e;
366
367 for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
368 e++) {
369 if (e->errcode == error)
370 printf("ERROR :: %x :: %s\n", error, e->name);
371 }
372
Aneesh Bansal8a47d5c2016-01-22 16:37:28 +0530373 /* If Boot Mode is secure, transition the SNVS state and issue
374 * reset based on type of failure and ITS setting.
375 * If Boot mode is non-secure, return from this function.
376 */
377 if (fsl_check_boot_mode_secure() == 0)
378 return;
379
gaurav ranac3a50422015-02-27 09:45:35 +0530380 switch (error) {
381 case ERROR_ESBC_CLIENT_HEADER_BARKER:
382 case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
383 case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
384 case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
385 case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
386 case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
387 case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
388 case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
389 case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
390 case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
391#ifdef CONFIG_KEY_REVOCATION
392 case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
393 case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
394 case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
395 case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
396#endif
397#if defined(CONFIG_FSL_ISBC_KEY_EXT)
398 /*@fallthrough@*/
399 case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
400 case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
401 case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
402 case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
403 case ERROR_IE_TABLE_NOT_FOUND:
404#endif
405 fsl_secboot_header_verification_failure();
406 break;
407 case ERROR_ESBC_SEC_RESET:
408 case ERROR_ESBC_SEC_DEQ:
409 case ERROR_ESBC_SEC_ENQ:
410 case ERROR_ESBC_SEC_DEQ_TO:
411 case ERROR_ESBC_SEC_JOBQ_STATUS:
412 case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
413 case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
414 fsl_secboot_image_verification_failure();
415 break;
416 case ERROR_ESBC_MISSING_BOOTM:
417 fsl_secboot_bootscript_parse_failure();
418 break;
419 case ERROR_ESBC_WRONG_CMD:
420 default:
421 branch_to_self();
422 break;
423 }
424}
425
426static void fsl_secblk_handle_error(int error)
427{
428 switch (error) {
429 case ERROR_ESBC_SEC_ENQ:
430 fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
431 break;
432 case ERROR_ESBC_SEC_DEQ:
433 fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
434 break;
435 case ERROR_ESBC_SEC_DEQ_TO:
436 fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
437 break;
438 default:
439 printf("Job Queue Output status %x\n", error);
440 fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
441 break;
442 }
443}
444
445/*
446 * Calculate hash of key obtained via offset present in ESBC uboot
447 * client hdr. This function calculates the hash of key which is obtained
448 * through offset present in ESBC uboot client header.
449 */
450static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
451{
452 struct hash_algo *algo;
453 void *ctx;
454 int i, srk = 0;
455 int ret = 0;
456 const char *algo_name = "sha256";
457
458 /* Calculate hash of the esbc key */
459 ret = hash_progressive_lookup_algo(algo_name, &algo);
460 if (ret)
461 return ret;
462
463 ret = algo->hash_init(algo, &ctx);
464 if (ret)
465 return ret;
466
467 /* Update hash for ESBC key */
468#ifdef CONFIG_KEY_REVOCATION
469 if (check_srk(img)) {
470 ret = algo->hash_update(algo, ctx,
Aneesh Bansalb3e98202015-12-08 13:54:29 +0530471 (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
472 img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
gaurav ranac3a50422015-02-27 09:45:35 +0530473 srk = 1;
474 }
475#endif
476 if (!srk)
477 ret = algo->hash_update(algo, ctx,
478 img->img_key, img->key_len, 1);
479 if (ret)
480 return ret;
481
482 /* Copy hash at destination buffer */
483 ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
484 if (ret)
485 return ret;
486
487 for (i = 0; i < SHA256_BYTES; i++)
488 img->img_key_hash[i] = hash_val[i];
489
490 return 0;
491}
492
493/*
494 * Calculate hash of ESBC hdr and ESBC. This function calculates the
495 * single hash of ESBC header and ESBC image. If SG flag is on, all
496 * SG entries are also hashed alongwith the complete SG table.
497 */
498static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
499{
500 struct hash_algo *algo;
501 void *ctx;
502 int ret = 0;
503 int key_hash = 0;
504 const char *algo_name = "sha256";
505
506 /* Calculate the hash of the ESBC */
507 ret = hash_progressive_lookup_algo(algo_name, &algo);
508 if (ret)
509 return ret;
510
511 ret = algo->hash_init(algo, &ctx);
512 /* Copy hash at destination buffer */
513 if (ret)
514 return ret;
515
516 /* Update hash for CSF Header */
517 ret = algo->hash_update(algo, ctx,
518 (u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
519 if (ret)
520 return ret;
521
522 /* Update the hash with that of srk table if srk flag is 1
523 * If IE Table is selected, key is not added in the hash
524 * If neither srk table nor IE key table available, add key
525 * from header in the hash calculation
526 */
527#ifdef CONFIG_KEY_REVOCATION
528 if (check_srk(img)) {
529 ret = algo->hash_update(algo, ctx,
Aneesh Bansalb3e98202015-12-08 13:54:29 +0530530 (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
531 img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
gaurav ranac3a50422015-02-27 09:45:35 +0530532 key_hash = 1;
533 }
534#endif
535#if defined(CONFIG_FSL_ISBC_KEY_EXT)
536 if (!key_hash && check_ie(img))
537 key_hash = 1;
538#endif
539 if (!key_hash)
540 ret = algo->hash_update(algo, ctx,
541 img->img_key, img->hdr.key_len, 0);
542 if (ret)
543 return ret;
544
545 /* Update hash for actual Image */
546 ret = algo->hash_update(algo, ctx,
Aneesh Bansal85921ba2015-12-08 14:14:15 +0530547 (u8 *)img->img_addr, img->img_size, 1);
gaurav ranac3a50422015-02-27 09:45:35 +0530548 if (ret)
549 return ret;
550
551 /* Copy hash at destination buffer */
552 ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
553 if (ret)
554 return ret;
555
556 return 0;
557}
558
559/*
560 * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
561 * pointers for padding, DER value and hash. And finally, constructs EM'
562 * which includes hash of complete CSF header and ESBC image. If SG flag
563 * is on, hash of SG table and entries is also included.
564 */
565static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
566{
567 /*
568 * RSA PKCSv1.5 encoding format for encoded message is below
569 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
570 * PS is Padding String
571 * DER is DER value for SHA-256
572 * Hash is SHA-256 hash
573 * *********************************************************
574 * representative points to first byte of EM initially and is
575 * filled with 0x0
576 * representative is incremented by 1 and second byte is filled
577 * with 0x1
578 * padding points to third byte of EM
579 * digest points to full length of EM - 32 bytes
580 * hash_id (DER value) points to 19 bytes before pDigest
581 * separator is one byte which separates padding and DER
582 */
583
584 size_t len;
585 u8 *representative;
586 u8 *padding, *digest;
587 u8 *hash_id, *separator;
588 int i;
589
590 len = (get_key_len(img) / 2) - 1;
591 representative = img->img_encoded_hash_second;
592 representative[0] = 0;
593 representative[1] = 1; /* block type 1 */
594
595 padding = &representative[2];
596 digest = &representative[1] + len - 32;
597 hash_id = digest - sizeof(hash_identifier);
598 separator = hash_id - 1;
599
600 /* fill padding area pointed by padding with 0xff */
601 memset(padding, 0xff, separator - padding);
602
603 /* fill byte pointed by separator */
604 *separator = 0;
605
606 /* fill SHA-256 DER value pointed by HashId */
607 memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
608
609 /* fill hash pointed by Digest */
610 for (i = 0; i < SHA256_BYTES; i++)
611 digest[i] = hash_val[i];
612}
613
614/*
615 * Reads and validates the ESBC client header.
616 * This function reads key and signature from the ESBC client header.
617 * If Scatter/Gather flag is on, lengths and offsets of images
618 * present as SG entries are also read. This function also checks
619 * whether the header is valid or not.
620 */
621static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
622{
623 char buf[20];
624 struct fsl_secboot_img_hdr *hdr = &img->hdr;
Aneesh Bansalb3e98202015-12-08 13:54:29 +0530625 void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
gaurav ranac3a50422015-02-27 09:45:35 +0530626 u8 *k, *s;
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530627 u32 ret = 0;
628
gaurav ranac3a50422015-02-27 09:45:35 +0530629#ifdef CONFIG_KEY_REVOCATION
gaurav ranac3a50422015-02-27 09:45:35 +0530630#endif
631 int key_found = 0;
632
633 /* check barker code */
634 if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
635 return ERROR_ESBC_CLIENT_HEADER_BARKER;
636
Aneesh Bansal85921ba2015-12-08 14:14:15 +0530637 /* If Image Address is not passed as argument to function,
638 * then Address and Size must be read from the Header.
639 */
640 if (img->img_addr == 0) {
641 #ifdef CONFIG_ESBC_ADDR_64BIT
642 img->img_addr = hdr->pimg64;
643 #else
644 img->img_addr = hdr->pimg;
645 #endif
646 }
647
648 sprintf(buf, "%lx", img->img_addr);
gaurav ranac3a50422015-02-27 09:45:35 +0530649 setenv("img_addr", buf);
650
651 if (!hdr->img_size)
652 return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
653
Aneesh Bansal85921ba2015-12-08 14:14:15 +0530654 img->img_size = hdr->img_size;
655
gaurav ranac3a50422015-02-27 09:45:35 +0530656 /* Key checking*/
657#ifdef CONFIG_KEY_REVOCATION
658 if (check_srk(img)) {
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530659 ret = read_validate_srk_tbl(img);
gaurav ranac3a50422015-02-27 09:45:35 +0530660 if (ret != 0)
661 return ret;
gaurav ranac3a50422015-02-27 09:45:35 +0530662 key_found = 1;
663 }
664#endif
665
666#if defined(CONFIG_FSL_ISBC_KEY_EXT)
667 if (!key_found && check_ie(img)) {
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530668 ret = read_validate_ie_tbl(img);
669 if (ret != 0)
670 return ret;
gaurav ranac3a50422015-02-27 09:45:35 +0530671 key_found = 1;
672 }
673#endif
674
675 if (key_found == 0) {
Aneesh Bansal24b8fae2015-12-08 14:14:13 +0530676 ret = read_validate_single_key(img);
677 if (ret != 0)
678 return ret;
gaurav ranac3a50422015-02-27 09:45:35 +0530679 key_found = 1;
680 }
681
682 /* check signaure */
683 if (get_key_len(img) == 2 * hdr->sign_len) {
684 /* check signature length */
685 if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
686 (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
687 (hdr->sign_len == KEY_SIZE_BYTES)))
688 return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
689 } else {
690 return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
691 }
692
693 memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
694
695 /* No SG support */
696 if (hdr->sg_flag)
697 return ERROR_ESBC_CLIENT_HEADER_SG;
698
699 /* modulus most significant bit should be set */
700 k = (u8 *)&img->img_key;
701
702 if ((k[0] & 0x80) == 0)
703 return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
704
705 /* modulus value should be odd */
706 if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
707 return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
708
709 /* Check signature value < modulus value */
710 s = (u8 *)&img->img_sign;
711
712 if (!(memcmp(s, k, hdr->sign_len) < 0))
713 return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
714
715 return ESBC_VALID_HDR;
716}
717
718static inline int str2longbe(const char *p, ulong *num)
719{
720 char *endptr;
721 ulong tmp;
722
723 if (!p) {
724 return 0;
725 } else {
726 tmp = simple_strtoul(p, &endptr, 16);
727 if (sizeof(ulong) == 4)
728 *num = cpu_to_be32(tmp);
729 else
730 *num = cpu_to_be64(tmp);
731 }
732
733 return *p != '\0' && *endptr == '\0';
734}
Aneesh Bansal9cd689c2015-12-08 14:14:14 +0530735/* Function to calculate the ESBC Image Hash
736 * and hash from Digital signature.
737 * The Two hash's are compared to yield the
738 * result of signature validation.
739 */
740static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
741{
742 int ret;
743 uint32_t key_len;
744 struct key_prop prop;
745#if !defined(USE_HOSTCC)
746 struct udevice *mod_exp_dev;
747#endif
748 ret = calc_esbchdr_esbc_hash(img);
749 if (ret)
750 return ret;
751
752 /* Construct encoded hash EM' wrt PKCSv1.5 */
753 construct_img_encoded_hash_second(img);
754
755 /* Fill prop structure for public key */
756 memset(&prop, 0, sizeof(struct key_prop));
757 key_len = get_key_len(img) / 2;
758 prop.modulus = img->img_key;
759 prop.public_exponent = img->img_key + key_len;
760 prop.num_bits = key_len * 8;
761 prop.exp_len = key_len;
762
763 ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
764 if (ret) {
765 printf("RSA: Can't find Modular Exp implementation\n");
766 return -EINVAL;
767 }
768
769 ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
770 &prop, img->img_encoded_hash);
771 if (ret)
772 return ret;
773
774 /*
775 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
776 * memcmp returns zero on success
777 * memcmp returns non-zero on failure
778 */
779 ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
780 img->hdr.sign_len);
781
782 if (ret)
783 return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;
784
785 return 0;
786}
gaurav ranac3a50422015-02-27 09:45:35 +0530787
Aneesh Bansal85921ba2015-12-08 14:14:15 +0530788int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
789 uintptr_t img_addr)
gaurav ranac3a50422015-02-27 09:45:35 +0530790{
791 struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
792 ulong hash[SHA256_BYTES/sizeof(ulong)];
793 char hash_str[NUM_HEX_CHARS + 1];
gaurav ranac3a50422015-02-27 09:45:35 +0530794 struct fsl_secboot_img_priv *img;
795 struct fsl_secboot_img_hdr *hdr;
796 void *esbc;
797 int ret, i, hash_cmd = 0;
798 u32 srk_hash[8];
gaurav ranac3a50422015-02-27 09:45:35 +0530799
Aneesh Bansal2b379bf2015-12-08 14:14:12 +0530800 if (arg_hash_str != NULL) {
801 const char *cp = arg_hash_str;
gaurav ranac3a50422015-02-27 09:45:35 +0530802 int i = 0;
803
804 if (*cp == '0' && *(cp + 1) == 'x')
805 cp += 2;
806
807 /* The input string expected is in hex, where
808 * each 4 bits would be represented by a hex
809 * sha256 hash is 256 bits long, which would mean
810 * num of characters = 256 / 4
811 */
812 if (strlen(cp) != SHA256_NIBBLES) {
813 printf("%s is not a 256 bits hex string as expected\n",
Aneesh Bansal2b379bf2015-12-08 14:14:12 +0530814 arg_hash_str);
gaurav ranac3a50422015-02-27 09:45:35 +0530815 return -1;
816 }
817
818 for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
819 strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
820 NUM_HEX_CHARS);
821 hash_str[NUM_HEX_CHARS] = '\0';
822 if (!str2longbe(hash_str, &hash[i])) {
823 printf("%s is not a 256 bits hex string ",
Aneesh Bansal2b379bf2015-12-08 14:14:12 +0530824 arg_hash_str);
gaurav ranac3a50422015-02-27 09:45:35 +0530825 return -1;
826 }
827 }
828
829 hash_cmd = 1;
830 }
831
832 img = malloc(sizeof(struct fsl_secboot_img_priv));
833
834 if (!img)
835 return -1;
836
837 memset(img, 0, sizeof(struct fsl_secboot_img_priv));
838
Aneesh Bansal85921ba2015-12-08 14:14:15 +0530839 /* Update the information in Private Struct */
gaurav ranac3a50422015-02-27 09:45:35 +0530840 hdr = &img->hdr;
Aneesh Bansal2b379bf2015-12-08 14:14:12 +0530841 img->ehdrloc = haddr;
Aneesh Bansal85921ba2015-12-08 14:14:15 +0530842 img->img_addr = img_addr;
843 esbc = (u8 *)img->ehdrloc;
gaurav ranac3a50422015-02-27 09:45:35 +0530844
845 memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
846
847 /* read and validate esbc header */
848 ret = read_validate_esbc_client_header(img);
849
850 if (ret != ESBC_VALID_HDR) {
851 fsl_secboot_handle_error(ret);
852 goto exit;
853 }
854
855 /* SRKH present in SFP */
856 for (i = 0; i < NUM_SRKH_REGS; i++)
857 srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
858
859 /*
860 * Calculate hash of key obtained via offset present in
861 * ESBC uboot client hdr
862 */
863 ret = calc_img_key_hash(img);
864 if (ret) {
865 fsl_secblk_handle_error(ret);
866 goto exit;
867 }
868
869 /* Compare hash obtained above with SRK hash present in SFP */
870 if (hash_cmd)
871 ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
872 else
873 ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
874
875#if defined(CONFIG_FSL_ISBC_KEY_EXT)
876 if (!hash_cmd && check_ie(img))
877 ret = 0;
878#endif
879
880 if (ret != 0) {
881 fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
882 goto exit;
883 }
884
Aneesh Bansal9cd689c2015-12-08 14:14:14 +0530885 ret = calculate_cmp_img_sig(img);
gaurav ranac3a50422015-02-27 09:45:35 +0530886 if (ret) {
Aneesh Bansal9cd689c2015-12-08 14:14:14 +0530887 fsl_secboot_handle_error(ret);
gaurav ranac3a50422015-02-27 09:45:35 +0530888 goto exit;
889 }
890
gaurav ranac3a50422015-02-27 09:45:35 +0530891exit:
Aneesh Bansal2b379bf2015-12-08 14:14:12 +0530892 return ret;
gaurav ranac3a50422015-02-27 09:45:35 +0530893}