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