xref: /rk3399_ARM-atf/drivers/io/io_encrypted.c (revision 091576e7f1fa0ca7360732d290a28ff2dc2a16e6)
1*2be57b86SSumit Garg /*
2*2be57b86SSumit Garg  * Copyright (c) 2020, Linaro Limited. All rights reserved.
3*2be57b86SSumit Garg  * Author: Sumit Garg <sumit.garg@linaro.org>
4*2be57b86SSumit Garg  *
5*2be57b86SSumit Garg  * SPDX-License-Identifier: BSD-3-Clause
6*2be57b86SSumit Garg  */
7*2be57b86SSumit Garg 
8*2be57b86SSumit Garg #include <assert.h>
9*2be57b86SSumit Garg #include <errno.h>
10*2be57b86SSumit Garg #include <stdint.h>
11*2be57b86SSumit Garg #include <string.h>
12*2be57b86SSumit Garg 
13*2be57b86SSumit Garg #include <platform_def.h>
14*2be57b86SSumit Garg 
15*2be57b86SSumit Garg #include <common/bl_common.h>
16*2be57b86SSumit Garg #include <common/debug.h>
17*2be57b86SSumit Garg #include <drivers/auth/crypto_mod.h>
18*2be57b86SSumit Garg #include <drivers/io/io_driver.h>
19*2be57b86SSumit Garg #include <drivers/io/io_encrypted.h>
20*2be57b86SSumit Garg #include <drivers/io/io_storage.h>
21*2be57b86SSumit Garg #include <lib/utils.h>
22*2be57b86SSumit Garg #include <plat/common/platform.h>
23*2be57b86SSumit Garg #include <tools_share/firmware_encrypted.h>
24*2be57b86SSumit Garg #include <tools_share/uuid.h>
25*2be57b86SSumit Garg 
26*2be57b86SSumit Garg static uintptr_t backend_dev_handle;
27*2be57b86SSumit Garg static uintptr_t backend_dev_spec;
28*2be57b86SSumit Garg static uintptr_t backend_handle;
29*2be57b86SSumit Garg static uintptr_t backend_image_spec;
30*2be57b86SSumit Garg 
31*2be57b86SSumit Garg static io_dev_info_t enc_dev_info;
32*2be57b86SSumit Garg 
33*2be57b86SSumit Garg /* Encrypted firmware driver functions */
34*2be57b86SSumit Garg static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
35*2be57b86SSumit Garg static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
36*2be57b86SSumit Garg 			  io_entity_t *entity);
37*2be57b86SSumit Garg static int enc_file_len(io_entity_t *entity, size_t *length);
38*2be57b86SSumit Garg static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
39*2be57b86SSumit Garg 			  size_t *length_read);
40*2be57b86SSumit Garg static int enc_file_close(io_entity_t *entity);
41*2be57b86SSumit Garg static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
42*2be57b86SSumit Garg static int enc_dev_close(io_dev_info_t *dev_info);
43*2be57b86SSumit Garg 
is_valid_header(struct fw_enc_hdr * header)44*2be57b86SSumit Garg static inline int is_valid_header(struct fw_enc_hdr *header)
45*2be57b86SSumit Garg {
46*2be57b86SSumit Garg 	if (header->magic == ENC_HEADER_MAGIC)
47*2be57b86SSumit Garg 		return 1;
48*2be57b86SSumit Garg 	else
49*2be57b86SSumit Garg 		return 0;
50*2be57b86SSumit Garg }
51*2be57b86SSumit Garg 
device_type_enc(void)52*2be57b86SSumit Garg static io_type_t device_type_enc(void)
53*2be57b86SSumit Garg {
54*2be57b86SSumit Garg 	return IO_TYPE_ENCRYPTED;
55*2be57b86SSumit Garg }
56*2be57b86SSumit Garg 
57*2be57b86SSumit Garg static const io_dev_connector_t enc_dev_connector = {
58*2be57b86SSumit Garg 	.dev_open = enc_dev_open
59*2be57b86SSumit Garg };
60*2be57b86SSumit Garg 
61*2be57b86SSumit Garg static const io_dev_funcs_t enc_dev_funcs = {
62*2be57b86SSumit Garg 	.type = device_type_enc,
63*2be57b86SSumit Garg 	.open = enc_file_open,
64*2be57b86SSumit Garg 	.seek = NULL,
65*2be57b86SSumit Garg 	.size = enc_file_len,
66*2be57b86SSumit Garg 	.read = enc_file_read,
67*2be57b86SSumit Garg 	.write = NULL,
68*2be57b86SSumit Garg 	.close = enc_file_close,
69*2be57b86SSumit Garg 	.dev_init = enc_dev_init,
70*2be57b86SSumit Garg 	.dev_close = enc_dev_close,
71*2be57b86SSumit Garg };
72*2be57b86SSumit Garg 
enc_dev_open(const uintptr_t dev_spec,io_dev_info_t ** dev_info)73*2be57b86SSumit Garg static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
74*2be57b86SSumit Garg {
75*2be57b86SSumit Garg 	assert(dev_info != NULL);
76*2be57b86SSumit Garg 
77*2be57b86SSumit Garg 	enc_dev_info.funcs = &enc_dev_funcs;
78*2be57b86SSumit Garg 	*dev_info = &enc_dev_info;
79*2be57b86SSumit Garg 
80*2be57b86SSumit Garg 	return 0;
81*2be57b86SSumit Garg }
82*2be57b86SSumit Garg 
enc_dev_init(io_dev_info_t * dev_info,const uintptr_t init_params)83*2be57b86SSumit Garg static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
84*2be57b86SSumit Garg {
85*2be57b86SSumit Garg 	int result;
86*2be57b86SSumit Garg 	unsigned int image_id = (unsigned int)init_params;
87*2be57b86SSumit Garg 
88*2be57b86SSumit Garg 	/* Obtain a reference to the image by querying the platform layer */
89*2be57b86SSumit Garg 	result = plat_get_image_source(image_id, &backend_dev_handle,
90*2be57b86SSumit Garg 				       &backend_dev_spec);
91*2be57b86SSumit Garg 	if (result != 0) {
92*2be57b86SSumit Garg 		WARN("Failed to obtain reference to image id=%u (%i)\n",
93*2be57b86SSumit Garg 			image_id, result);
94*2be57b86SSumit Garg 		return -ENOENT;
95*2be57b86SSumit Garg 	}
96*2be57b86SSumit Garg 
97*2be57b86SSumit Garg 	return result;
98*2be57b86SSumit Garg }
99*2be57b86SSumit Garg 
enc_dev_close(io_dev_info_t * dev_info)100*2be57b86SSumit Garg static int enc_dev_close(io_dev_info_t *dev_info)
101*2be57b86SSumit Garg {
102*2be57b86SSumit Garg 	backend_dev_handle = (uintptr_t)NULL;
103*2be57b86SSumit Garg 	backend_dev_spec = (uintptr_t)NULL;
104*2be57b86SSumit Garg 
105*2be57b86SSumit Garg 	return 0;
106*2be57b86SSumit Garg }
107*2be57b86SSumit Garg 
enc_file_open(io_dev_info_t * dev_info,const uintptr_t spec,io_entity_t * entity)108*2be57b86SSumit Garg static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
109*2be57b86SSumit Garg 			 io_entity_t *entity)
110*2be57b86SSumit Garg {
111*2be57b86SSumit Garg 	int result;
112*2be57b86SSumit Garg 
113*2be57b86SSumit Garg 	assert(spec != 0);
114*2be57b86SSumit Garg 	assert(entity != NULL);
115*2be57b86SSumit Garg 
116*2be57b86SSumit Garg 	backend_image_spec = spec;
117*2be57b86SSumit Garg 
118*2be57b86SSumit Garg 	result = io_open(backend_dev_handle, backend_image_spec,
119*2be57b86SSumit Garg 			 &backend_handle);
120*2be57b86SSumit Garg 	if (result != 0) {
121*2be57b86SSumit Garg 		WARN("Failed to open backend device (%i)\n", result);
122*2be57b86SSumit Garg 		result = -ENOENT;
123*2be57b86SSumit Garg 	}
124*2be57b86SSumit Garg 
125*2be57b86SSumit Garg 	return result;
126*2be57b86SSumit Garg }
127*2be57b86SSumit Garg 
enc_file_len(io_entity_t * entity,size_t * length)128*2be57b86SSumit Garg static int enc_file_len(io_entity_t *entity, size_t *length)
129*2be57b86SSumit Garg {
130*2be57b86SSumit Garg 	int result;
131*2be57b86SSumit Garg 
132*2be57b86SSumit Garg 	assert(entity != NULL);
133*2be57b86SSumit Garg 	assert(length != NULL);
134*2be57b86SSumit Garg 
135*2be57b86SSumit Garg 	result = io_size(backend_handle, length);
136*2be57b86SSumit Garg 	if (result != 0) {
137*2be57b86SSumit Garg 		WARN("Failed to read blob length (%i)\n", result);
138*2be57b86SSumit Garg 		return -ENOENT;
139*2be57b86SSumit Garg 	}
140*2be57b86SSumit Garg 
141*2be57b86SSumit Garg 	/*
142*2be57b86SSumit Garg 	 * Encryption header is attached at the beginning of the encrypted file
143*2be57b86SSumit Garg 	 * and is not considered a part of the payload.
144*2be57b86SSumit Garg 	 */
145*2be57b86SSumit Garg 	if (*length < sizeof(struct fw_enc_hdr))
146*2be57b86SSumit Garg 		return -EIO;
147*2be57b86SSumit Garg 
148*2be57b86SSumit Garg 	*length -= sizeof(struct fw_enc_hdr);
149*2be57b86SSumit Garg 
150*2be57b86SSumit Garg 	return result;
151*2be57b86SSumit Garg }
152*2be57b86SSumit Garg 
enc_file_read(io_entity_t * entity,uintptr_t buffer,size_t length,size_t * length_read)153*2be57b86SSumit Garg static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
154*2be57b86SSumit Garg 			 size_t *length_read)
155*2be57b86SSumit Garg {
156*2be57b86SSumit Garg 	int result;
157*2be57b86SSumit Garg 	struct fw_enc_hdr header;
158*2be57b86SSumit Garg 	enum fw_enc_status_t fw_enc_status;
159*2be57b86SSumit Garg 	size_t bytes_read;
160*2be57b86SSumit Garg 	uint8_t key[ENC_MAX_KEY_SIZE];
161*2be57b86SSumit Garg 	size_t key_len = sizeof(key);
162*2be57b86SSumit Garg 	unsigned int key_flags = 0;
163*2be57b86SSumit Garg 	const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)backend_image_spec;
164*2be57b86SSumit Garg 
165*2be57b86SSumit Garg 	assert(entity != NULL);
166*2be57b86SSumit Garg 	assert(length_read != NULL);
167*2be57b86SSumit Garg 
168*2be57b86SSumit Garg 	result = io_read(backend_handle, (uintptr_t)&header, sizeof(header),
169*2be57b86SSumit Garg 			 &bytes_read);
170*2be57b86SSumit Garg 	if (result != 0) {
171*2be57b86SSumit Garg 		WARN("Failed to read encryption header (%i)\n", result);
172*2be57b86SSumit Garg 		return -ENOENT;
173*2be57b86SSumit Garg 	}
174*2be57b86SSumit Garg 
175*2be57b86SSumit Garg 	if (!is_valid_header(&header)) {
176*2be57b86SSumit Garg 		WARN("Encryption header check failed.\n");
177*2be57b86SSumit Garg 		return -ENOENT;
178*2be57b86SSumit Garg 	}
179*2be57b86SSumit Garg 
180*2be57b86SSumit Garg 	VERBOSE("Encryption header looks OK.\n");
181*2be57b86SSumit Garg 	fw_enc_status = header.flags & FW_ENC_STATUS_FLAG_MASK;
182*2be57b86SSumit Garg 
183*2be57b86SSumit Garg 	if ((header.iv_len > ENC_MAX_IV_SIZE) ||
184*2be57b86SSumit Garg 	    (header.tag_len > ENC_MAX_TAG_SIZE)) {
185*2be57b86SSumit Garg 		WARN("Incorrect IV or tag length\n");
186*2be57b86SSumit Garg 		return -ENOENT;
187*2be57b86SSumit Garg 	}
188*2be57b86SSumit Garg 
189*2be57b86SSumit Garg 	result = io_read(backend_handle, buffer, length, &bytes_read);
190*2be57b86SSumit Garg 	if (result != 0) {
191*2be57b86SSumit Garg 		WARN("Failed to read encrypted payload (%i)\n", result);
192*2be57b86SSumit Garg 		return -ENOENT;
193*2be57b86SSumit Garg 	}
194*2be57b86SSumit Garg 
195*2be57b86SSumit Garg 	*length_read = bytes_read;
196*2be57b86SSumit Garg 
197*2be57b86SSumit Garg 	result = plat_get_enc_key_info(fw_enc_status, key, &key_len, &key_flags,
198*2be57b86SSumit Garg 				       (uint8_t *)&uuid_spec->uuid,
199*2be57b86SSumit Garg 				       sizeof(uuid_t));
200*2be57b86SSumit Garg 	if (result != 0) {
201*2be57b86SSumit Garg 		WARN("Failed to obtain encryption key (%i)\n", result);
202*2be57b86SSumit Garg 		return -ENOENT;
203*2be57b86SSumit Garg 	}
204*2be57b86SSumit Garg 
205*2be57b86SSumit Garg 	result = crypto_mod_auth_decrypt(header.dec_algo,
206*2be57b86SSumit Garg 					 (void *)buffer, *length_read, key,
207*2be57b86SSumit Garg 					 key_len, key_flags, header.iv,
208*2be57b86SSumit Garg 					 header.iv_len, header.tag,
209*2be57b86SSumit Garg 					 header.tag_len);
210*2be57b86SSumit Garg 	memset(key, 0, key_len);
211*2be57b86SSumit Garg 
212*2be57b86SSumit Garg 	if (result != 0) {
213*2be57b86SSumit Garg 		ERROR("File decryption failed (%i)\n", result);
214*2be57b86SSumit Garg 		return -ENOENT;
215*2be57b86SSumit Garg 	}
216*2be57b86SSumit Garg 
217*2be57b86SSumit Garg 	return result;
218*2be57b86SSumit Garg }
219*2be57b86SSumit Garg 
enc_file_close(io_entity_t * entity)220*2be57b86SSumit Garg static int enc_file_close(io_entity_t *entity)
221*2be57b86SSumit Garg {
222*2be57b86SSumit Garg 	io_close(backend_handle);
223*2be57b86SSumit Garg 
224*2be57b86SSumit Garg 	backend_image_spec = (uintptr_t)NULL;
225*2be57b86SSumit Garg 	entity->info = 0;
226*2be57b86SSumit Garg 
227*2be57b86SSumit Garg 	return 0;
228*2be57b86SSumit Garg }
229*2be57b86SSumit Garg 
230*2be57b86SSumit Garg /* Exported functions */
231*2be57b86SSumit Garg 
232*2be57b86SSumit Garg /* Register the Encrypted Firmware driver with the IO abstraction */
register_io_dev_enc(const io_dev_connector_t ** dev_con)233*2be57b86SSumit Garg int register_io_dev_enc(const io_dev_connector_t **dev_con)
234*2be57b86SSumit Garg {
235*2be57b86SSumit Garg 	int result;
236*2be57b86SSumit Garg 
237*2be57b86SSumit Garg 	assert(dev_con != NULL);
238*2be57b86SSumit Garg 
239*2be57b86SSumit Garg 	result = io_register_device(&enc_dev_info);
240*2be57b86SSumit Garg 	if (result == 0)
241*2be57b86SSumit Garg 		*dev_con = &enc_dev_connector;
242*2be57b86SSumit Garg 
243*2be57b86SSumit Garg 	return result;
244*2be57b86SSumit Garg }
245