xref: /rk3399_rockchip-uboot/lib/avb/libavb_user/avb_ops_user.c (revision daae0a01d6548c381f7126747a8ef273189b547e)
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include <common.h>
26 #include <image.h>
27 #include <android_image.h>
28 #include <malloc.h>
29 #include <mapmem.h>
30 #include <errno.h>
31 #include <command.h>
32 #include <mmc.h>
33 #include <blk.h>
34 #include <part.h>
35 #include <stdio.h>
36 #include <android_avb/avb_ops_user.h>
37 #include <android_avb/libavb_ab.h>
38 #include <android_avb/avb_atx_validate.h>
39 #include <android_avb/avb_atx_types.h>
40 #include <optee_include/OpteeClientInterface.h>
41 #include <optee_include/tee_api_defines.h>
42 #include <android_avb/avb_vbmeta_image.h>
43 #include <android_avb/avb_atx_validate.h>
44 #include <boot_rkimg.h>
45 
46 static void byte_to_block(int64_t *offset,
47 			  size_t *num_bytes,
48 			  lbaint_t *offset_blk,
49 			  lbaint_t *blkcnt)
50 {
51 	*offset_blk = (lbaint_t)(*offset / 512);
52 	if (*num_bytes % 512 == 0) {
53 		if (*offset % 512 == 0)
54 			*blkcnt = (lbaint_t)(*num_bytes / 512);
55 		else
56 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
57 	} else {
58 		if (*offset % 512 == 0) {
59 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
60 		} else {
61 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
62 			    (*offset % 512) + (*num_bytes % 512) == 512) {
63 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
64 			} else {
65 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
66 			}
67 		}
68 	}
69 }
70 
71 static AvbIOResult get_size_of_partition(AvbOps *ops,
72 					 const char *partition,
73 					 uint64_t *out_size_in_bytes)
74 {
75 	struct blk_desc *dev_desc;
76 	disk_partition_t part_info;
77 
78 	dev_desc = rockchip_get_bootdev();
79 	if (!dev_desc) {
80 		printf("%s: Could not find device\n", __func__);
81 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
82 	}
83 
84 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
85 		printf("Could not find \"%s\" partition\n", partition);
86 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
87 	}
88 	*out_size_in_bytes = (part_info.size) * 512;
89 	return AVB_IO_RESULT_OK;
90 }
91 
92 static AvbIOResult read_from_partition(AvbOps *ops,
93 				       const char *partition,
94 				       int64_t offset,
95 				       size_t num_bytes,
96 				       void *buffer,
97 				       size_t *out_num_read)
98 {
99 	struct blk_desc *dev_desc;
100 	lbaint_t offset_blk, blkcnt;
101 	disk_partition_t part_info;
102 	uint64_t partition_size;
103 
104 	if (offset < 0) {
105 		if (get_size_of_partition(ops, partition, &partition_size))
106 			return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
107 
108 		if (-offset > partition_size)
109 			return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
110 
111 		offset = partition_size - (-offset);
112 	}
113 
114 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
115 	dev_desc = rockchip_get_bootdev();
116 	if (!dev_desc) {
117 		printf("%s: Could not find device\n", __func__);
118 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
119 	}
120 
121 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
122 		printf("Could not find \"%s\" partition\n", partition);
123 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
124 	}
125 
126 	if ((offset % 512 == 0) && (num_bytes % 512 == 0)) {
127 		blk_dread(dev_desc, part_info.start + offset_blk,
128 			  blkcnt, buffer);
129 		*out_num_read = blkcnt * 512;
130 	} else {
131 		char *buffer_temp;
132 
133 		buffer_temp = malloc(512 * blkcnt);
134 		if (!buffer_temp) {
135 			printf("malloc error!\n");
136 			return AVB_IO_RESULT_ERROR_OOM;
137 		}
138 		blk_dread(dev_desc, part_info.start + offset_blk,
139 			  blkcnt, buffer_temp);
140 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
141 		*out_num_read = num_bytes;
142 		free(buffer_temp);
143 	}
144 
145 	return AVB_IO_RESULT_OK;
146 }
147 
148 static AvbIOResult write_to_partition(AvbOps *ops,
149 				      const char *partition,
150 				      int64_t offset,
151 				      size_t num_bytes,
152 				      const void *buffer)
153 {
154 	struct blk_desc *dev_desc;
155 	char *buffer_temp;
156 	disk_partition_t part_info;
157 	lbaint_t offset_blk, blkcnt;
158 
159 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
160 	buffer_temp = malloc(512 * blkcnt);
161 	if (!buffer_temp) {
162 		printf("malloc error!\n");
163 		return AVB_IO_RESULT_ERROR_OOM;
164 	}
165 	memset(buffer_temp, 0, 512 * blkcnt);
166 	dev_desc = rockchip_get_bootdev();
167 	if (!dev_desc) {
168 		printf("%s: Could not find device\n", __func__);
169 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
170 	}
171 
172 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
173 		printf("Could not find \"%s\" partition\n", partition);
174 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
175 	}
176 
177 	if ((offset % 512 != 0) && (num_bytes % 512) != 0)
178 		blk_dread(dev_desc, part_info.start + offset_blk,
179 			  blkcnt, buffer_temp);
180 
181 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
182 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
183 	free(buffer_temp);
184 
185 	return AVB_IO_RESULT_OK;
186 }
187 
188 static AvbIOResult
189 validate_vbmeta_public_key(AvbOps *ops,
190 			   const uint8_t *public_key_data,
191 			   size_t public_key_length,
192 			   const uint8_t *public_key_metadata,
193 			   size_t public_key_metadata_length,
194 			   bool *out_is_trusted)
195 {
196 /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
197 #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
198     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
199 	if (out_is_trusted) {
200 		avb_atx_validate_vbmeta_public_key(ops,
201 						   public_key_data,
202 						   public_key_length,
203 						   public_key_metadata,
204 						   public_key_metadata_length,
205 						   out_is_trusted);
206 	}
207 #else
208 	if (out_is_trusted)
209 		*out_is_trusted = true;
210 #endif
211 	return AVB_IO_RESULT_OK;
212 }
213 
214 static AvbIOResult read_rollback_index(AvbOps *ops,
215 				       size_t rollback_index_location,
216 				       uint64_t *out_rollback_index)
217 {
218 	if (out_rollback_index) {
219 #ifdef CONFIG_OPTEE_CLIENT
220 		int ret;
221 
222 		ret = trusty_read_rollback_index(rollback_index_location,
223 						 out_rollback_index);
224 		switch (ret) {
225 		case TEE_SUCCESS:
226 			ret = AVB_IO_RESULT_OK;
227 			break;
228 		case TEE_ERROR_GENERIC:
229 		case TEE_ERROR_NO_DATA:
230 		case TEE_ERROR_ITEM_NOT_FOUND:
231 			*out_rollback_index = 0;
232 			ret = trusty_write_rollback_index(rollback_index_location,
233 							  *out_rollback_index);
234 			if (ret) {
235 				printf("%s: init rollback index error\n",
236 				       __FILE__);
237 				ret = AVB_IO_RESULT_ERROR_IO;
238 			} else {
239 				ret =
240 				trusty_read_rollback_index(rollback_index_location,
241 							   out_rollback_index);
242 				if (ret)
243 					ret = AVB_IO_RESULT_ERROR_IO;
244 				else
245 					ret = AVB_IO_RESULT_OK;
246 			}
247 			break;
248 		default:
249 			ret = AVB_IO_RESULT_ERROR_IO;
250 			printf("%s: trusty_read_rollback_index failed",
251 			       __FILE__);
252 		}
253 
254 		return ret;
255 #endif
256 	}
257 	return AVB_IO_RESULT_ERROR_IO;
258 }
259 
260 static AvbIOResult write_rollback_index(AvbOps *ops,
261 					size_t rollback_index_location,
262 					uint64_t rollback_index)
263 {
264 #ifdef CONFIG_OPTEE_CLIENT
265 	if (trusty_write_rollback_index(rollback_index_location,
266 					rollback_index)) {
267 		printf("%s: Fail to write rollback index\n", __FILE__);
268 		return AVB_IO_RESULT_ERROR_IO;
269 	}
270 	return AVB_IO_RESULT_OK;
271 #endif
272 	return AVB_IO_RESULT_ERROR_IO;
273 }
274 
275 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
276 {
277 	if (out_is_unlocked) {
278 #ifdef CONFIG_OPTEE_CLIENT
279 		int ret;
280 
281 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
282 		switch (ret) {
283 		case TEE_SUCCESS:
284 			ret = AVB_IO_RESULT_OK;
285 			break;
286 		case TEE_ERROR_GENERIC:
287 		case TEE_ERROR_NO_DATA:
288 		case TEE_ERROR_ITEM_NOT_FOUND:
289 			*out_is_unlocked = 1;
290 			if (trusty_write_lock_state(*out_is_unlocked)) {
291 				printf("%s: init lock state error\n", __FILE__);
292 				ret = AVB_IO_RESULT_ERROR_IO;
293 			} else {
294 				ret =
295 				trusty_read_lock_state((uint8_t *)out_is_unlocked);
296 				if (ret == 0)
297 					ret = AVB_IO_RESULT_OK;
298 				else
299 					ret = AVB_IO_RESULT_ERROR_IO;
300 			}
301 			break;
302 		default:
303 			ret = AVB_IO_RESULT_ERROR_IO;
304 			printf("%s: trusty_read_lock_state failed\n", __FILE__);
305 		}
306 		return ret;
307 #endif
308 	}
309 	return AVB_IO_RESULT_ERROR_IO;
310 }
311 
312 static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
313 {
314 	if (out_is_unlocked) {
315 #ifdef CONFIG_OPTEE_CLIENT
316 		if (trusty_write_lock_state(*out_is_unlocked)) {
317 			printf("%s: Fail to write lock state\n", __FILE__);
318 			return AVB_IO_RESULT_ERROR_IO;
319 		}
320 		return AVB_IO_RESULT_OK;
321 #endif
322 	}
323 	return AVB_IO_RESULT_ERROR_IO;
324 }
325 
326 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
327 						 const char *partition,
328 						 char *guid_buf,
329 						 size_t guid_buf_size)
330 {
331 	struct blk_desc *dev_desc;
332 	disk_partition_t part_info;
333 
334 	dev_desc = rockchip_get_bootdev();
335 	if (!dev_desc) {
336 		printf("%s: Could not find device\n", __func__);
337 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
338 	}
339 
340 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
341 		printf("Could not find \"%s\" partition\n", partition);
342 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
343 	}
344 	if (guid_buf && guid_buf_size > 0)
345 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
346 
347 	return AVB_IO_RESULT_OK;
348 }
349 
350 /* read permanent attributes from rpmb */
351 AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops,
352 			       AvbAtxPermanentAttributes *attributes)
353 {
354 	if (attributes) {
355 #ifdef CONFIG_OPTEE_CLIENT
356 		trusty_read_permanent_attributes((uint8_t *)attributes,
357 						 sizeof(struct AvbAtxPermanentAttributes));
358 		return AVB_IO_RESULT_OK;
359 #endif
360 	}
361 
362 	return -1;
363 }
364 
365 /*read permanent attributes hash from efuse */
366 AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops,
367 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
368 {
369 #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
370 #ifdef CONFIG_OPTEE_CLIENT
371 	if (trusty_read_attribute_hash((uint32_t *)hash,
372 				       AVB_SHA256_DIGEST_SIZE / 4))
373 		return -1;
374 #else
375 	avb_error("Please open the macro!\n");
376 	return -1;
377 #endif
378 #endif
379 	return AVB_IO_RESULT_OK;
380 }
381 
382 static void avb_set_key_version(AvbAtxOps *atx_ops,
383 				size_t rollback_index_location,
384 				uint64_t key_version)
385 {
386 #ifdef CONFIG_OPTEE_CLIENT
387 	uint64_t key_version_temp = 0;
388 
389 	if (trusty_read_rollback_index(rollback_index_location, &key_version_temp))
390 		printf("%s: Fail to read rollback index\n", __FILE__);
391 	if (key_version_temp == key_version)
392 		return;
393 	if (trusty_write_rollback_index(rollback_index_location, key_version))
394 		printf("%s: Fail to write rollback index\n", __FILE__);
395 #endif
396 }
397 
398 AvbIOResult rk_get_random(AvbAtxOps *atx_ops,
399 			  size_t num_bytes,
400 			  uint8_t *output)
401 {
402 	int i;
403 	unsigned int seed;
404 
405 	seed = (unsigned int)get_timer(0);
406 	for (i = 0; i < num_bytes; i++) {
407 		srand(seed);
408 		output[i] = (uint8_t)(rand());
409 		seed = (unsigned int)(output[i]);
410 	}
411 
412 	return 0;
413 }
414 
415 #ifdef CONFIG_ANDROID_BOOT_IMAGE
416 static AvbIOResult get_preloaded_partition(AvbOps* ops,
417 					   const char* partition,
418 					   size_t num_bytes,
419 					   uint8_t** out_pointer,
420 					   size_t* out_num_bytes_preloaded,
421 					   int allow_verification_error)
422 {
423 	struct blk_desc *dev_desc;
424 	ulong load_addr;
425 	int ret;
426 
427 	/* no need go further */
428 	if (!allow_verification_error)
429 		return AVB_IO_RESULT_OK;
430 
431 	printf("get image from preloaded partition...\n");
432 	dev_desc = rockchip_get_bootdev();
433 	if (!dev_desc)
434 	    return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
435 
436 	load_addr = env_get_ulong("kernel_addr_r", 16, 0);
437 	if (!load_addr)
438 		return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
439 
440 	ret = android_image_load_by_partname(dev_desc, partition, &load_addr);
441 	if (!ret) {
442 		*out_pointer = (u8 *)load_addr;
443 		*out_num_bytes_preloaded = num_bytes; /* return what it expects */
444 		ret = AVB_SLOT_VERIFY_RESULT_OK;
445 	} else {
446 		ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
447 	}
448 
449 	return ret;
450 }
451 #endif
452 
453 AvbIOResult validate_public_key_for_partition(AvbOps *ops,
454 					      const char *partition,
455 					      const uint8_t *public_key_data,
456 					      size_t public_key_length,
457 					      const uint8_t *public_key_metadata,
458 					      size_t public_key_metadata_length,
459 					      bool *out_is_trusted,
460 					      uint32_t *out_rollback_index_location)
461 {
462 /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
463 #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
464     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
465 	if (out_is_trusted) {
466 		avb_atx_validate_vbmeta_public_key(ops,
467 						   public_key_data,
468 						   public_key_length,
469 						   public_key_metadata,
470 						   public_key_metadata_length,
471 						   out_is_trusted);
472 	}
473 #else
474 	if (out_is_trusted)
475 		*out_is_trusted = true;
476 #endif
477 	*out_rollback_index_location = 0;
478 	return AVB_IO_RESULT_OK;
479 }
480 
481 AvbOps *avb_ops_user_new(void)
482 {
483 	AvbOps *ops;
484 
485 	ops = calloc(1, sizeof(AvbOps));
486 	if (!ops) {
487 		avb_error("Error allocating memory for AvbOps.\n");
488 		goto out;
489 	}
490 	ops->ab_ops = calloc(1, sizeof(AvbABOps));
491 	if (!ops->ab_ops) {
492 		avb_error("Error allocating memory for AvbABOps.\n");
493 		free(ops);
494 		goto out;
495 	}
496 
497 	ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
498 	if (!ops->atx_ops) {
499 		avb_error("Error allocating memory for AvbAtxOps.\n");
500 		free(ops->ab_ops);
501 		free(ops);
502 		goto out;
503 	}
504 	ops->ab_ops->ops = ops;
505 	ops->atx_ops->ops = ops;
506 
507 	ops->read_from_partition = read_from_partition;
508 	ops->write_to_partition = write_to_partition;
509 	ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
510 	ops->read_rollback_index = read_rollback_index;
511 	ops->write_rollback_index = write_rollback_index;
512 	ops->read_is_device_unlocked = read_is_device_unlocked;
513 	ops->write_is_device_unlocked = write_is_device_unlocked;
514 	ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
515 	ops->get_size_of_partition = get_size_of_partition;
516 #ifdef CONFIG_ANDROID_BOOT_IMAGE
517 	ops->get_preloaded_partition = get_preloaded_partition;
518 #endif
519 	ops->validate_public_key_for_partition = validate_public_key_for_partition;
520 	ops->ab_ops->read_ab_metadata = avb_ab_data_read;
521 	ops->ab_ops->write_ab_metadata = avb_ab_data_write;
522 	ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
523 	ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
524 	ops->atx_ops->set_key_version = avb_set_key_version;
525 	ops->atx_ops->get_random = rk_get_random;
526 
527 out:
528 	return ops;
529 }
530 
531 void avb_ops_user_free(AvbOps *ops)
532 {
533 	free(ops->ab_ops);
534 	free(ops->atx_ops);
535 	free(ops);
536 }
537