xref: /rk3399_ARM-atf/plat/intel/soc/common/socfpga_vab.c (revision a4defaefe65379554f464e9cf2b4f4d9818740aa)
1 /*
2  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
3  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
4  * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include <assert.h>
10 #include <errno.h>
11 
12 #include "../lib/sha/sha.h"
13 
14 #include <arch_helpers.h>
15 #include <common/bl_common.h>
16 #include <common/debug.h>
17 #include <common/desc_image_load.h>
18 #include <common/tbbr/tbbr_img_def.h>
19 #include <drivers/delay_timer.h>
20 #include <lib/mmio.h>
21 #include <lib/utils.h>
22 #include <plat/common/platform.h>
23 #include <tools_share/firmware_image_package.h>
24 
25 #include "socfpga_mailbox.h"
26 #include "socfpga_private.h"
27 #include "socfpga_vab.h"
28 
29 size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
30 {
31 	uint8_t *img_buf_end = img_buf + img_buf_sz;
32 	uint32_t cert_sz = get_unaligned_le32(img_buf_end - sizeof(uint32_t));
33 	uint8_t *p = img_buf_end - cert_sz - sizeof(uint32_t);
34 
35 	/* Ensure p is pointing within the img_buf */
36 	if (p < img_buf || p > (img_buf_end - VAB_CERT_HEADER_SIZE))
37 		return 0;
38 
39 	if (get_unaligned_le32(p) == SDM_CERT_MAGIC_NUM)
40 		return (size_t)(p - img_buf);
41 
42 	return 0;
43 }
44 
45 int socfpga_vab_init(unsigned int image_id)
46 {
47 	int ret = 0;
48 	size_t image_size;
49 	void *image_base_ptr;
50 	/*
51 	 * Get information about the images to load.
52 	 */
53 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
54 
55 	assert(bl_mem_params);
56 
57 	if (bl_mem_params == NULL) {
58 		ERROR("SOCFPGA VAB Init failed\n");
59 		return -EINITREJECTED;
60 	}
61 
62 	if ((image_id == BL31_IMAGE_ID) || (image_id == BL33_IMAGE_ID)) {
63 		image_base_ptr = (void *)bl_mem_params->image_info.image_base;
64 		image_size = bl_mem_params->image_info.image_size;
65 		ret = socfpga_vab_authentication(&image_base_ptr, &image_size);
66 	}
67 
68 	return ret;
69 }
70 
71 int socfpga_vab_authentication(void **p_image, size_t *p_size)
72 {
73 	int retry_count = 20;
74 	uint8_t hash384[FCS_SHA384_WORD_SIZE];
75 	uint64_t img_addr, mbox_data_addr;
76 	uint32_t img_sz, mbox_data_sz;
77 	uint8_t *cert_hash_ptr, *mbox_relocate_data_addr;
78 	uint32_t resp = 0, resp_len = 1;
79 	int ret = 0;
80 	uint8_t u8_buf_static[MBOX_DATA_MAX_LEN];
81 
82 	mbox_relocate_data_addr = u8_buf_static;
83 
84 	img_addr = (uintptr_t)*p_image;
85 	img_sz = get_img_size((uint8_t *)img_addr, *p_size);
86 
87 	if (!img_sz) {
88 		ERROR("VAB certificate not found in image!\n");
89 		return -ENOVABCERT;
90 	}
91 
92 	if (!IS_BYTE_ALIGNED(img_sz, sizeof(uint32_t))) {
93 		ERROR("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
94 		return -EIMGERR;
95 	}
96 
97 	/* Generate HASH384 from the image */
98 	sha384_start((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
99 	cert_hash_ptr = (uint8_t *)(img_addr + img_sz + VAB_CERT_MAGIC_OFFSET +
100 								VAB_CERT_FIT_SHA384_OFFSET);
101 
102 	/*
103 	 * Compare the SHA384 found in certificate against the SHA384
104 	 * calculated from image
105 	 */
106 	if (memcmp(hash384, cert_hash_ptr, FCS_SHA384_WORD_SIZE)) {
107 		ERROR("SHA384 does not match!\n");
108 		return -EKEYREJECTED;
109 	}
110 
111 	mbox_data_addr = img_addr + img_sz - sizeof(uint32_t);
112 	/* Size in word (32bits) */
113 	mbox_data_sz = (BYTE_ALIGN(*p_size - img_sz, sizeof(uint32_t))) >> 2;
114 
115 	VERBOSE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
116 
117 	memcpy_s(mbox_relocate_data_addr, (mbox_data_sz * sizeof(uint32_t)) / MBOX_WORD_BYTE,
118 		(uint8_t *)mbox_data_addr, (mbox_data_sz * sizeof(uint32_t)) / MBOX_WORD_BYTE);
119 
120 	*((unsigned int *)mbox_relocate_data_addr) = 0;
121 
122 	do {
123 		/* Invoke SMC call to ATF to send the VAB certificate to SDM */
124 		ret  = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_VAB_SRC_CERT,
125 (uint32_t *)mbox_relocate_data_addr, mbox_data_sz, 0, &resp, &resp_len);
126 
127 		/* If SDM is not available, just delay 50ms and retry again */
128 		/* 0x1FF = The device is busy */
129 		if (ret == MBOX_RESP_ERR(0x1FF)) {
130 			mdelay(50);
131 		} else {
132 			break;
133 		}
134 	} while (--retry_count);
135 
136 	/* Free the relocate certificate memory space */
137 	zeromem((void *)&mbox_relocate_data_addr, sizeof(uint32_t));
138 
139 	/* Exclude the size of the VAB certificate from image size */
140 	*p_size = img_sz;
141 
142 	if (ret) {
143 		/*
144 		 * Unsupported mailbox command or device not in the
145 		 * owned/secure state
146 		 */
147 		 /* 0x85 = Not allowed under current security setting */
148 		if (ret == MBOX_RESP_ERR(0x85)) {
149 			/* SDM bypass authentication */
150 			ERROR("Image Authentication bypassed at address\n");
151 			return 0;
152 		}
153 		ERROR("VAB certificate authentication failed in SDM\n");
154 		/* 0x1FF = The device is busy */
155 		if (ret == MBOX_RESP_ERR(0x1FF)) {
156 			ERROR("Operation timed out\n");
157 			return -ETIMEOUT;
158 		} else if (ret == MBOX_WRONG_ID) {
159 			ERROR("No such process\n");
160 			return -EPROCESS;
161 		}
162 		return -EAUTH;
163 	} else {
164 		/* If Certificate Process Status has error */
165 		if (resp) {
166 			ERROR("VAB certificate execution format error\n");
167 			return -EIMGERR;
168 		}
169 	}
170 
171 	NOTICE("%s 0x%lx (%d bytes)\n", "Image Authentication passed at address", img_addr, img_sz);
172 	return ret;
173 }
174 
175 uint32_t get_unaligned_le32(const void *p)
176 {
177 	return le32_to_cpue((uint32_t *)p);
178 }
179