xref: /rk3399_rockchip-uboot/common/attestation_key.c (revision d5f538dc02e53c7267fcd4a914104071fca889b5)
1 /*
2  * Copyright 2018, Rockchip Electronics Co., Ltd
3  * qiujian, <qiujian@rock-chips.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include "attestation_key.h"
9 
10 #include <common.h>
11 #include <malloc.h>
12 
13 #include <optee_include/OpteeClientApiLib.h>
14 
15 /* attestation data offset*/
16 #define ATTESTATION_DATA_OFFSET  65536
17 
18 /* block size */
19 #define ATTESTATION_DATA_BLOCK_SIZE 512
20 
21 /* attestation data block offset */
22 #define ATTESTATION_DATA_BLOCK_OFFSET (ATTESTATION_DATA_OFFSET / ATTESTATION_DATA_BLOCK_SIZE)
23 
24 #define ATAP_BLOB_LEN_MAX 2048
25 #define ATAP_CERT_CHAIN_LEN_MAX 8192
26 #define ATAP_CERT_CHAIN_ENTRIES_MAX 8
27 
28 /*
29  * Name of the attestation key file is
30  * ATTESTATION_KEY_PREFIX.%algorithm,
31  * where algorithm is either "EC" or "RSA"
32  */
33 #define ATTESTATION_KEY_PREFIX "PrivateKey"
34 
35 /*
36  * Name of the attestation certificate file is
37  * ATTESTATION_CERT_PREFIX.%algorithm.%index,
38  * where index is the index within the certificate chain.
39  */
40 #define ATTESTATION_CERT_PREFIX "CertificateChain"
41 
42 /* Maximum file name size.*/
43 #define STORAGE_ID_LENGTH_MAX  64
44 
45 typedef enum{
46 	KM_ALGORITHM_RSA = 1,
47 	KM_ALGORITHM_EC = 3,
48 } keymaster_algorithm_t;
49 
50 typedef struct {
51 	uint8_t *data;
52 	uint32_t data_length;
53 } atap_blob;
54 
55 typedef struct {
56 	atap_blob entries[ATAP_CERT_CHAIN_ENTRIES_MAX];
57 	uint32_t entry_count;
58 } atap_certchain;
59 
60 uint32_t write_to_keymaster(uint8_t *filename, uint32_t filename_size,
61 				uint8_t *data, uint32_t data_size);
62 
63 static const char *get_keyslot_str(keymaster_algorithm_t key_type)
64 {
65 	switch (key_type) {
66 	case KM_ALGORITHM_RSA:
67 		return "RSA";
68 	case KM_ALGORITHM_EC:
69 		return "EC";
70 	default:
71 		return "";
72 	}
73 }
74 
75 static void free_blob(atap_blob blob)
76 {
77 	if (blob.data)
78 		free(blob.data);
79 
80 	blob.data_length = 0;
81 }
82 
83 static void free_cert_chain(atap_certchain cert_chain)
84 {
85 	unsigned int i = 0;
86 
87 	for (i = 0; i < cert_chain.entry_count; ++i) {
88 		if (cert_chain.entries[i].data)
89 			free(cert_chain.entries[i].data);
90 
91 		cert_chain.entries[i].data_length = 0;
92 	}
93 	memset(&cert_chain, 0, sizeof(atap_certchain));
94 }
95 
96 static void copy_from_buf(uint8_t **buf_ptr, void *data, uint32_t data_size)
97 {
98 	memcpy(data, *buf_ptr, data_size);
99 	*buf_ptr += data_size;
100 }
101 
102 static void copy_uint32_from_buf(uint8_t **buf_ptr, uint32_t *x)
103 {
104 	copy_from_buf(buf_ptr, x, sizeof(uint32_t));
105 }
106 
107 static bool copy_blob_from_buf(uint8_t **buf_ptr, atap_blob *blob)
108 {
109 	memset(blob, 0, sizeof(atap_blob));
110 	copy_uint32_from_buf(buf_ptr, &blob->data_length);
111 
112 	if (blob->data_length > ATAP_BLOB_LEN_MAX)
113 		return false;
114 
115 	if (blob->data_length) {
116 		blob->data = (uint8_t *) malloc(blob->data_length);
117 		if (blob->data == NULL)
118 			return false;
119 
120 		copy_from_buf(buf_ptr, blob->data, blob->data_length);
121 	}
122 	return true;
123 }
124 
125 static bool copy_cert_chain_from_buf(uint8_t **buf_ptr,
126 					atap_certchain *cert_chain)
127 {
128 	uint32_t cert_chain_size = 0;
129 	int32_t bytes_remaining = 0;
130 	size_t i = 0;
131 	bool retval = true;
132 
133 	memset(cert_chain, 0, sizeof(atap_certchain));
134 
135 	/* Copy size of cert chain, as it is a Variable field. */
136 	copy_from_buf(buf_ptr, &cert_chain_size, sizeof(cert_chain_size));
137 
138 	if (cert_chain_size > ATAP_CERT_CHAIN_LEN_MAX)
139 		return false;
140 
141 	if (cert_chain_size == 0)
142 		return true;
143 
144 	bytes_remaining = cert_chain_size;
145 	for (i = 0; i < ATAP_CERT_CHAIN_ENTRIES_MAX; ++i) {
146 		if (!copy_blob_from_buf(buf_ptr, &cert_chain->entries[i])) {
147 			retval = false;
148 			break;
149 		}
150 
151 		++cert_chain->entry_count;
152 		bytes_remaining -= (sizeof(uint32_t) +
153 					cert_chain->entries[i].data_length);
154 
155 		if (bytes_remaining <= 0) {
156 			retval = (bytes_remaining == 0);
157 			break;
158 		}
159 	}
160 	if (retval == false)
161 		free_cert_chain(*cert_chain);
162 
163 	return retval;
164 }
165 
166 /* validate attestation data head. */
167 static bool validate_ca_header(const uint8_t *buf, uint32_t buf_size)
168 {
169 
170 	if (buf[0] != 'C' || buf[1] != 'A' || buf[2] != 0)
171 		return false;
172 
173 	uint32_t data_size;
174 
175 	memcpy(&data_size, buf + 3, sizeof(uint32_t));
176 
177 	if (data_size <= 0 || data_size > ATTESTATION_DATA_OFFSET) {
178 		printf("invalide data_size:%d\n", data_size);
179 		return false;
180 	}
181 
182 	uint32_t real_size;
183 
184 	memcpy(&real_size, buf + 3 + sizeof(uint32_t), sizeof(uint32_t));
185 	if (real_size <= 0 || real_size > data_size) {
186 		printf("invalide real_size:%d\n", real_size);
187 		return false;
188 	}
189 	return true;
190 }
191 
192 /* write key to security storage. */
193 static uint32_t write_key(keymaster_algorithm_t key_type,
194 				const uint8_t *key, uint32_t key_size)
195 {
196 	char key_file[STORAGE_ID_LENGTH_MAX] = {0};
197 
198 	snprintf(key_file, STORAGE_ID_LENGTH_MAX, "%s.%s", ATTESTATION_KEY_PREFIX,
199 		get_keyslot_str(key_type));
200 	write_to_keymaster((uint8_t *)key_file, strlen(key_file),
201 				(uint8_t *)key, key_size);
202 	return 0;
203 }
204 
205 /* write cert to security storage. */
206 static uint32_t write_cert(keymaster_algorithm_t key_type, const uint8_t *cert,
207 				uint32_t cert_size, uint32_t index)
208 {
209 	char cert_file[STORAGE_ID_LENGTH_MAX] = {0};
210 
211 	snprintf(cert_file, STORAGE_ID_LENGTH_MAX, "%s.%s.%d", ATTESTATION_CERT_PREFIX,
212 		get_keyslot_str(key_type), index);
213 	write_to_keymaster((uint8_t *)cert_file, strlen(cert_file),
214 				(uint8_t *)cert, cert_size);
215 	return 0;
216 }
217 
218 /* write cert chain length to security storage. */
219 static uint32_t write_cert_chain_length(keymaster_algorithm_t key_type,
220 				uint8_t chain_len)
221 {
222 	char cert_chain_length_file[STORAGE_ID_LENGTH_MAX] = {0};
223 	uint8_t data = chain_len;
224 	uint32_t len = 1;
225 
226 	snprintf(cert_chain_length_file, STORAGE_ID_LENGTH_MAX, "%s.%s.length",
227 		ATTESTATION_CERT_PREFIX, get_keyslot_str(key_type));
228 	write_to_keymaster((uint8_t *)cert_chain_length_file,
229 				strlen(cert_chain_length_file), &data, len);
230 
231 	return 0;
232 }
233 
234 atap_result load_attestation_key(struct blk_desc *dev_desc,
235 				disk_partition_t *misc_partition)
236 {
237 	int ret;
238 
239 	if (!dev_desc) {
240 		printf("%s: Could not find device\n", __func__);
241 		return ATAP_RESULT_ERROR_DEVICE_NOT_FOUND;
242 	}
243 
244 	if (misc_partition == NULL) {
245 		printf("misc partition not found!\n");
246 		return ATAP_RESULT_ERROR_PARTITION_NOT_FOUND;
247 	}
248 
249 	/* get attestation data offset from misc partition */
250 	lbaint_t key_offset = misc_partition->start +
251 				misc_partition->size - ATTESTATION_DATA_BLOCK_OFFSET;
252 
253 	/* read ca head from attestation data offset */
254 	uint8_t ca_headr[ATTESTATION_DATA_BLOCK_SIZE];
255 
256 	ret = blk_dread(dev_desc, key_offset, 1, ca_headr);
257 	if (ret != 1) {
258 		printf("failed to read ca head from misc\n");
259 		return ATAP_RESULT_ERROR_BLOCK_READ;
260 	}
261 
262 	if (!validate_ca_header(ca_headr, sizeof(ca_headr))) {
263 		printf("ca head not found\n");
264 		return ATAP_RESULT_ERROR_INVALID_HEAD;
265 	}
266 
267 	/* get attestation data size from ca head */
268 	uint32_t real_size;
269 
270 	memcpy(&real_size, ca_headr + 3 + sizeof(uint32_t), sizeof(uint32_t));
271 
272 	/* calculate real block size of attestation data */
273 	int real_block_num = real_size / ATTESTATION_DATA_BLOCK_SIZE;
274 
275 	if (real_size % ATTESTATION_DATA_BLOCK_SIZE != 0)
276 		real_block_num++;
277 
278 	unsigned char keybuf[ATTESTATION_DATA_OFFSET] = {0};
279 
280 	/* check block size */
281 	if (real_block_num <= 0 || real_block_num > ATTESTATION_DATA_BLOCK_OFFSET) {
282 		printf("invalidate real_block_num:%d\n", real_block_num);
283 		return ATAP_RESULT_ERROR_INVALID_BLOCK_NUM;
284 	}
285 
286 	/* read all attestation data from misc */
287 	if (blk_dread(dev_desc, key_offset, real_block_num, keybuf) != real_block_num) {
288 		printf("failed to read misc key\n");
289 		return ATAP_RESULT_ERROR_BLOCK_READ;
290 	}
291 
292 	/* read device id from buf*/
293 	uint32_t device_id_size = 0;
294 	uint8_t device_id[32] = {0};
295 
296 	memcpy(&device_id_size, keybuf + 16, sizeof(uint32_t));
297 	if (device_id_size < 0 || device_id_size > sizeof(device_id)) {
298 		printf("invalidate device_id_size:%d\n", device_id_size);
299 		return ATAP_RESULT_ERROR_INVALID_DEVICE_ID;
300 	}
301 
302 	memcpy(device_id, keybuf + 16 + sizeof(uint32_t), device_id_size);
303 	debug("device_id:%s\n", device_id);
304 
305 	/* read algorithm from buf */
306 	uint8_t *key_buf = keybuf + 16 + sizeof(uint32_t) + device_id_size;
307 	uint32_t algorithm;
308 
309 	copy_uint32_from_buf(&key_buf, &algorithm);
310 	debug("\n algorithm:%d\n", algorithm);
311 
312 	/* read rsa private key */
313 	atap_blob key;
314 
315 	if (copy_blob_from_buf(&key_buf, &key) == false) {
316 		printf("copy_blob_from_buf failed!\n");
317 		return ATAP_RESULT_ERROR_BUF_COPY;
318 	}
319 	/* write rsa private key to security storage*/
320 	write_key(KM_ALGORITHM_RSA, key.data, key.data_length);
321 
322 	/* read rsa cert chain */
323 	atap_certchain certchain;
324 
325 	if (copy_cert_chain_from_buf(&key_buf, &certchain) == false) {
326 		printf("copy_cert_chain_from_buf failed!\n");
327 		return ATAP_RESULT_ERROR_BUF_COPY;
328 	}
329 
330 	/* write rsa cert chain size to security storage*/
331 	write_cert_chain_length(KM_ALGORITHM_RSA,
332 				(uint8_t) certchain.entry_count);
333 
334 	/* write rsa cert chain data to security storage*/
335 	int i = 0;
336 
337 	for (i = 0; i < certchain.entry_count; ++i) {
338 		write_cert(KM_ALGORITHM_RSA, certchain.entries[i].data,
339 			certchain.entries[i].data_length, i);
340 	}
341 
342 	/* read ec algorithm */
343 	copy_uint32_from_buf(&key_buf, &algorithm);
344 	debug("\n algorithm:%d\n", algorithm);
345 
346 	/* read ec private key */
347 	free_blob(key);
348 	if (copy_blob_from_buf(&key_buf, &key) == false) {
349 		printf("copy_blob_from_buf failed!\n");
350 		return ATAP_RESULT_ERROR_BUF_COPY;
351 	}
352 
353 	/* write ec private key to security storage*/
354 	write_key(KM_ALGORITHM_EC, key.data, key.data_length);
355 
356 	/* read ec cert chain */
357 	free_cert_chain(certchain);
358 	if (copy_cert_chain_from_buf(&key_buf, &certchain) == false) {
359 		printf("copy_cert_chain_from_buf failed!\n");
360 		return ATAP_RESULT_ERROR_BUF_COPY;
361 	}
362 	/* write ec cert chain size to security storage*/
363 	write_cert_chain_length(KM_ALGORITHM_EC,
364 					(uint8_t) certchain.entry_count);
365 
366 	/* write ec cert chain to security storage*/
367 	for (i = 0; i < certchain.entry_count; ++i) {
368 		write_cert(KM_ALGORITHM_EC, certchain.entries[i].data,
369 			certchain.entries[i].data_length, i);
370 	}
371 
372 	memset(keybuf, 0, sizeof(keybuf));
373 
374 	/* wipe attestation data from misc*/
375 	if (blk_dwrite(dev_desc, key_offset, real_block_num, keybuf) != real_block_num) {
376 		printf("StorageWriteLba failed\n");
377 		return ATAP_RESULT_ERROR_BLOCK_WRITE;
378 	}
379 
380 	return ATAP_RESULT_OK;
381 }
382