xref: /rk3399_rockchip-uboot/lib/avb/libavb_user/avb_ops_user.c (revision 7c1937d6d1c7daf8e59b4760f8adc7ee42bd7bea)
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 <android_avb/avb_ops_user.h>
36 #include <android_avb/libavb_ab.h>
37 #include <android_avb/avb_atx_validate.h>
38 #include <android_avb/avb_atx_types.h>
39 #include <optee_include/OpteeClientInterface.h>
40 #include <optee_include/tee_api_defines.h>
41 #include <android_avb/avb_vbmeta_image.h>
42 #include <android_avb/avb_atx_validate.h>
43 #include <boot_rkimg.h>
44 
45 static void byte_to_block(int64_t *offset,
46 			  size_t *num_bytes,
47 			  lbaint_t *offset_blk,
48 			  lbaint_t *blkcnt)
49 {
50 	*offset_blk = (lbaint_t)(*offset / 512);
51 	if (*num_bytes % 512 == 0) {
52 		if (*offset % 512 == 0)
53 			*blkcnt = (lbaint_t)(*num_bytes / 512);
54 		else
55 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
56 	} else {
57 		if (*offset % 512 == 0) {
58 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
59 		} else {
60 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
61 			    (*offset % 512) + (*num_bytes % 512) == 512) {
62 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
63 			} else {
64 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
65 			}
66 		}
67 	}
68 }
69 
70 static AvbIOResult read_from_partition(AvbOps *ops,
71 				       const char *partition,
72 				       int64_t offset,
73 				       size_t num_bytes,
74 				       void *buffer,
75 				       size_t *out_num_read)
76 {
77 	struct blk_desc *dev_desc;
78 	lbaint_t offset_blk, blkcnt;
79 	disk_partition_t part_info;
80 
81 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
82 	dev_desc = rockchip_get_bootdev();
83 	if (!dev_desc) {
84 		printf("%s: Could not find device\n", __func__);
85 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
86 	}
87 
88 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
89 		printf("Could not find \"%s\" partition\n", partition);
90 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
91 	}
92 
93 	if ((offset % 512 == 0) && (num_bytes % 512 == 0)) {
94 		blk_dread(dev_desc, part_info.start + offset_blk,
95 			  blkcnt, buffer);
96 		*out_num_read = blkcnt * 512;
97 	} else {
98 		char *buffer_temp;
99 
100 		buffer_temp = malloc(512 * blkcnt);
101 		if (!buffer_temp) {
102 			printf("malloc error!\n");
103 			return AVB_IO_RESULT_ERROR_OOM;
104 		}
105 		blk_dread(dev_desc, part_info.start + offset_blk,
106 			  blkcnt, buffer_temp);
107 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
108 		*out_num_read = num_bytes;
109 		free(buffer_temp);
110 	}
111 
112 	return AVB_IO_RESULT_OK;
113 }
114 
115 static AvbIOResult write_to_partition(AvbOps *ops,
116 				      const char *partition,
117 				      int64_t offset,
118 				      size_t num_bytes,
119 				      const void *buffer)
120 {
121 	struct blk_desc *dev_desc;
122 	char *buffer_temp;
123 	disk_partition_t part_info;
124 	lbaint_t offset_blk, blkcnt;
125 
126 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
127 	buffer_temp = malloc(512 * blkcnt);
128 	if (!buffer_temp) {
129 		printf("malloc error!\n");
130 		return AVB_IO_RESULT_ERROR_OOM;
131 	}
132 	memset(buffer_temp, 0, 512 * blkcnt);
133 	dev_desc = rockchip_get_bootdev();
134 	if (!dev_desc) {
135 		printf("%s: Could not find device\n", __func__);
136 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
137 	}
138 
139 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
140 		printf("Could not find \"%s\" partition\n", partition);
141 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
142 	}
143 
144 	if ((offset % 512 != 0) && (num_bytes % 512) != 0)
145 		blk_dread(dev_desc, part_info.start + offset_blk,
146 			  blkcnt, buffer_temp);
147 
148 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
149 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
150 	free(buffer_temp);
151 
152 	return AVB_IO_RESULT_OK;
153 }
154 
155 static AvbIOResult
156 validate_vbmeta_public_key(AvbOps *ops,
157 			   const uint8_t *public_key_data,
158 			   size_t public_key_length,
159 			   const uint8_t *public_key_metadata,
160 			   size_t public_key_metadata_length,
161 			   bool *out_is_trusted)
162 {
163 #ifdef AVB_VBMETA_PUBLIC_KEY_VALIDATE
164 	if (out_is_trusted) {
165 		avb_atx_validate_vbmeta_public_key(ops,
166 						   public_key_data,
167 						   public_key_length,
168 						   public_key_metadata,
169 						   public_key_metadata_length,
170 						   out_is_trusted);
171 	}
172 #else
173 	if (out_is_trusted)
174 		*out_is_trusted = true;
175 #endif
176 	return AVB_IO_RESULT_OK;
177 }
178 
179 static AvbIOResult read_rollback_index(AvbOps *ops,
180 				       size_t rollback_index_location,
181 				       uint64_t *out_rollback_index)
182 {
183 	if (out_rollback_index) {
184 #ifdef CONFIG_OPTEE_CLIENT
185 		int ret;
186 
187 		ret = trusty_read_rollback_index(rollback_index_location,
188 						 out_rollback_index);
189 		switch (ret) {
190 		case TEE_SUCCESS:
191 			ret = AVB_IO_RESULT_OK;
192 			break;
193 		case TEE_ERROR_GENERIC:
194 		case TEE_ERROR_NO_DATA:
195 		case TEE_ERROR_ITEM_NOT_FOUND:
196 			*out_rollback_index = 0;
197 			ret = trusty_write_rollback_index(rollback_index_location,
198 							  *out_rollback_index);
199 			if (ret) {
200 				printf("%s: init rollback index error\n",
201 				       __FILE__);
202 				ret = AVB_IO_RESULT_ERROR_IO;
203 			} else {
204 				ret =
205 				trusty_read_rollback_index(rollback_index_location,
206 							   out_rollback_index);
207 				if (ret)
208 					ret = AVB_IO_RESULT_ERROR_IO;
209 				else
210 					ret = AVB_IO_RESULT_OK;
211 			}
212 			break;
213 		default:
214 			ret = AVB_IO_RESULT_ERROR_IO;
215 			printf("%s: trusty_read_rollback_index failed",
216 			       __FILE__);
217 		}
218 
219 		return ret;
220 #endif
221 	}
222 	return AVB_IO_RESULT_ERROR_IO;
223 }
224 
225 static AvbIOResult write_rollback_index(AvbOps *ops,
226 					size_t rollback_index_location,
227 					uint64_t rollback_index)
228 {
229 #ifdef CONFIG_OPTEE_CLIENT
230 	if (trusty_write_rollback_index(rollback_index_location,
231 					rollback_index)) {
232 		printf("%s: Fail to write rollback index\n", __FILE__);
233 		return AVB_IO_RESULT_ERROR_IO;
234 	}
235 	return AVB_IO_RESULT_OK;
236 #endif
237 	return AVB_IO_RESULT_ERROR_IO;
238 }
239 
240 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
241 {
242 	if (out_is_unlocked) {
243 #ifdef CONFIG_OPTEE_CLIENT
244 		int ret;
245 
246 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
247 		switch (ret) {
248 		case TEE_SUCCESS:
249 			ret = AVB_IO_RESULT_OK;
250 			break;
251 		case TEE_ERROR_GENERIC:
252 		case TEE_ERROR_NO_DATA:
253 		case TEE_ERROR_ITEM_NOT_FOUND:
254 			*out_is_unlocked = 1;
255 			if (trusty_write_lock_state(*out_is_unlocked)) {
256 				printf("%s: init lock state error\n", __FILE__);
257 				ret = AVB_IO_RESULT_ERROR_IO;
258 			} else {
259 				ret =
260 				trusty_read_lock_state((uint8_t *)out_is_unlocked);
261 				if (ret == 0)
262 					ret = AVB_IO_RESULT_OK;
263 				else
264 					ret = AVB_IO_RESULT_ERROR_IO;
265 			}
266 			break;
267 		default:
268 			ret = AVB_IO_RESULT_ERROR_IO;
269 			printf("%s: trusty_read_lock_state failed\n", __FILE__);
270 		}
271 		return ret;
272 #endif
273 	}
274 	return AVB_IO_RESULT_ERROR_IO;
275 }
276 
277 static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
278 {
279 	if (out_is_unlocked) {
280 #ifdef CONFIG_OPTEE_CLIENT
281 		if (trusty_write_lock_state(*out_is_unlocked)) {
282 			printf("%s: Fail to write lock state\n", __FILE__);
283 			return AVB_IO_RESULT_ERROR_IO;
284 		}
285 		return AVB_IO_RESULT_OK;
286 #endif
287 	}
288 	return AVB_IO_RESULT_ERROR_IO;
289 }
290 
291 static AvbIOResult get_size_of_partition(AvbOps *ops,
292 					 const char *partition,
293 					 uint64_t *out_size_in_bytes)
294 {
295 	struct blk_desc *dev_desc;
296 	disk_partition_t part_info;
297 
298 	dev_desc = rockchip_get_bootdev();
299 	if (!dev_desc) {
300 		printf("%s: Could not find device\n", __func__);
301 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
302 	}
303 
304 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
305 		printf("Could not find \"%s\" partition\n", partition);
306 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
307 	}
308 	*out_size_in_bytes = (part_info.size) * 512;
309 	return AVB_IO_RESULT_OK;
310 }
311 
312 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
313 						 const char *partition,
314 						 char *guid_buf,
315 						 size_t guid_buf_size)
316 {
317 	struct blk_desc *dev_desc;
318 	disk_partition_t part_info;
319 
320 	dev_desc = rockchip_get_bootdev();
321 	if (!dev_desc) {
322 		printf("%s: Could not find device\n", __func__);
323 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
324 	}
325 
326 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
327 		printf("Could not find \"%s\" partition\n", partition);
328 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
329 	}
330 	if (guid_buf && guid_buf_size > 0)
331 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
332 
333 	return AVB_IO_RESULT_OK;
334 }
335 
336 /* read permanent attributes from rpmb */
337 AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops,
338 			       AvbAtxPermanentAttributes *attributes)
339 {
340 	if (attributes) {
341 #ifdef CONFIG_OPTEE_CLIENT
342 		trusty_read_permanent_attributes((uint8_t *)attributes,
343 						 sizeof(struct AvbAtxPermanentAttributes));
344 		return AVB_IO_RESULT_OK;
345 #endif
346 	}
347 
348 	return -1;
349 }
350 
351 /*read permanent attributes hash from efuse */
352 AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops,
353 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
354 {
355 #ifdef CONFIG_OPTEE_CLIENT
356 	if (trusty_read_attribute_hash((uint32_t *)hash,
357 				       AVB_SHA256_DIGEST_SIZE / 4))
358 		return -1;
359 #else
360 	avb_error("Please open the macro!\n");
361 	return -1;
362 #endif
363 	return AVB_IO_RESULT_OK;
364 }
365 
366 static void avb_set_key_version(AvbAtxOps *atx_ops,
367 				size_t rollback_index_location,
368 				uint64_t key_version)
369 {
370 #ifdef CONFIG_OPTEE_CLIENT
371 	if (trusty_write_rollback_index(rollback_index_location, key_version))
372 		printf("%s: Fail to write rollback index\n", __FILE__);
373 #endif
374 }
375 
376 AvbIOResult rk_get_random(AvbAtxOps *atx_ops,
377 			  size_t num_bytes,
378 			  uint8_t *output)
379 {
380 	int i;
381 	unsigned int seed;
382 
383 	seed = (unsigned int)get_timer(0);
384 	for (i = 0; i < num_bytes; i++) {
385 		srand(seed);
386 		output[i] = (uint8_t)(rand());
387 		seed = (unsigned int)(output[i]);
388 	}
389 
390 	return 0;
391 }
392 
393 AvbOps *avb_ops_user_new(void)
394 {
395 	AvbOps *ops;
396 
397 	ops = calloc(1, sizeof(AvbOps));
398 	if (!ops) {
399 		avb_error("Error allocating memory for AvbOps.\n");
400 		goto out;
401 	}
402 	ops->ab_ops = calloc(1, sizeof(AvbABOps));
403 	if (!ops->ab_ops) {
404 		avb_error("Error allocating memory for AvbABOps.\n");
405 		free(ops);
406 		goto out;
407 	}
408 
409 	ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
410 	if (!ops->atx_ops) {
411 		avb_error("Error allocating memory for AvbAtxOps.\n");
412 		free(ops->ab_ops);
413 		free(ops);
414 		goto out;
415 	}
416 	ops->ab_ops->ops = ops;
417 	ops->atx_ops->ops = ops;
418 
419 	ops->read_from_partition = read_from_partition;
420 	ops->write_to_partition = write_to_partition;
421 	ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
422 	ops->read_rollback_index = read_rollback_index;
423 	ops->write_rollback_index = write_rollback_index;
424 	ops->read_is_device_unlocked = read_is_device_unlocked;
425 	ops->write_is_device_unlocked = write_is_device_unlocked;
426 	ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
427 	ops->get_size_of_partition = get_size_of_partition;
428 	ops->ab_ops->read_ab_metadata = avb_ab_data_read;
429 	ops->ab_ops->write_ab_metadata = avb_ab_data_write;
430 	ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
431 	ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
432 	ops->atx_ops->set_key_version = avb_set_key_version;
433 	ops->atx_ops->get_random = rk_get_random;
434 
435 out:
436 	return ops;
437 }
438 
439 void avb_ops_user_free(AvbOps *ops)
440 {
441 	free(ops->ab_ops);
442 	free(ops->atx_ops);
443 	free(ops);
444 }
445