1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <types.h>
8 #include <asm/cpu.h>
9 #include <asm/pgtable.h>
10 #include <rtl.h>
11 #include <logmsg.h>
12 #include <asm/seed.h>
13 #include "seed_sbl.h"
14 
15 #define SEED_ENTRY_TYPE_SVNSEED         0x1U
16 /* #define SEED_ENTRY_TYPE_RPMBSEED        0x2U */
17 
18 /* #define SEED_ENTRY_USAGE_USEED          0x1U */
19 #define SEED_ENTRY_USAGE_DSEED          0x2U
20 
21 struct seed_list_hob {
22 	uint8_t revision;
23 	uint8_t reserved0[3];
24 	uint32_t buffer_size;
25 	uint8_t total_seed_count;
26 	uint8_t reserved1[3];
27 };
28 
29 struct seed_entry {
30 	/* SVN based seed or RPMB seed or attestation key_box */
31 	uint8_t type;
32 	/* For SVN seed: useed or dseed
33 	 * For RPMB seed: serial number based or not
34 	 */
35 	uint8_t usage;
36 	/* index for the same type and usage seed */
37 	uint8_t index;
38 	uint8_t reserved;
39 	/* reserved for future use */
40 	uint16_t flags;
41 	/* Total size of this seed entry */
42 	uint16_t seed_entry_size;
43 	/* SVN seed: struct seed_info
44 	 * RPMB seed: uint8_t rpmb_key[key_len]
45 	 */
46 	uint8_t seed[0];
47 };
48 
49 /*
50  * parse_seed_sbl
51  *
52  * description:
53  *    This function parse seed_list which provided by SBL
54  *
55  * input:
56  *    cmdline       pointer to cmdline string
57  *
58  * return value:
59  *    true if parse successfully, otherwise false.
60  */
parse_seed_sbl(uint64_t addr,struct physical_seed * phy_seed)61 bool parse_seed_sbl(uint64_t addr, struct physical_seed *phy_seed)
62 {
63 	uint8_t i;
64 	uint8_t dseed_index = 0U;
65 	struct image_boot_params *boot_params = NULL;
66 	struct seed_list_hob *seed_hob = NULL;
67 	struct seed_entry *entry = NULL;
68 	struct seed_info *seed_list = NULL;
69 	bool status = false;
70 
71 	boot_params = (struct image_boot_params *)hpa2hva(addr);
72 
73 	if (boot_params != NULL) {
74 		seed_hob = (struct seed_list_hob *)hpa2hva(boot_params->p_seed_list);
75 	}
76 
77 	if ((seed_hob != NULL) && (phy_seed != NULL)) {
78 		status = true;
79 
80 		seed_list = phy_seed->seed_list;
81 
82 		entry = (struct seed_entry *)((uint8_t *)seed_hob + sizeof(struct seed_list_hob));
83 
84 		for (i = 0U; i < seed_hob->total_seed_count; i++) {
85 			if (entry != NULL) {
86 				/* retrieve dseed */
87 				if ((SEED_ENTRY_TYPE_SVNSEED == entry->type) &&
88 				    (SEED_ENTRY_USAGE_DSEED == entry->usage)) {
89 
90 					/* The seed_entry with same type/usage are always
91 					 * arranged by index in order of 0~3.
92 					 */
93 					if ((entry->index != dseed_index) ||
94 					    (entry->index >= BOOTLOADER_SEED_MAX_ENTRIES)) {
95 						status = false;
96 						break;
97 					}
98 
99 					(void)memcpy_s((void *)&seed_list[dseed_index], sizeof(struct seed_info),
100 							(void *)&entry->seed[0U], sizeof(struct seed_info));
101 					dseed_index++;
102 
103 					/* erase original seed in seed entry */
104 					(void)memset((void *)&entry->seed[0U], 0U, sizeof(struct seed_info));
105 				}
106 
107 				entry = (struct seed_entry *)((uint8_t *)entry + entry->seed_entry_size);
108 			}
109 		}
110 
111 		if (status) {
112 			phy_seed->num_seeds = dseed_index;
113 		}
114 	}
115 
116 	return status;
117 }
118