xref: /rk3399_rockchip-uboot/lib/avb/libavb_user/avb_ops_user.c (revision e17ddcea32b2fa7b82fb079f37195855a55e39a2)
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 		}
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 read_from_partition(AvbOps* ops,
72                                        const char* partition,
73                                        int64_t offset,
74                                        size_t num_bytes,
75                                        void* buffer,
76                                        size_t* out_num_read)
77 {
78 	struct blk_desc *dev_desc;
79 	lbaint_t offset_blk, blkcnt;
80 	disk_partition_t part_info;
81 
82 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
83 	dev_desc = rockchip_get_bootdev();
84 	if (!dev_desc) {
85 		printf("%s: Could not find device\n", __func__);
86 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
87 	}
88 
89 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
90 		printf("Could not find \"%s\" partition\n", partition);
91 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
92 	}
93 
94 	if((offset % 512 == 0) && (num_bytes % 512 == 0)) {
95 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
96 		*out_num_read = blkcnt * 512;
97 	} else {
98 		char *buffer_temp;
99 		buffer_temp = malloc(512 * blkcnt);
100 		if (buffer_temp == NULL) {
101 			printf("malloc error!\n");
102 			return AVB_IO_RESULT_ERROR_OOM;
103 		}
104 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp);
105 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
106 		*out_num_read = num_bytes;
107 		free(buffer_temp);
108 	}
109 
110 	return AVB_IO_RESULT_OK;
111 }
112 
113 static AvbIOResult write_to_partition(AvbOps* ops,
114                                       const char* partition,
115                                       int64_t offset,
116                                       size_t num_bytes,
117                                       const void* buffer)
118 {
119 	struct blk_desc *dev_desc;
120 	char *buffer_temp;
121 	disk_partition_t part_info;
122 	lbaint_t offset_blk, blkcnt;
123 
124 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
125 	buffer_temp = malloc(512 * blkcnt);
126 	if (buffer_temp == NULL) {
127 		printf("malloc error!\n");
128 		return AVB_IO_RESULT_ERROR_OOM;
129 	}
130 	memset(buffer_temp, 0, 512 * blkcnt);
131 	dev_desc = rockchip_get_bootdev();
132 	if (!dev_desc) {
133 		printf("%s: Could not find device\n", __func__);
134 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
135 	}
136 
137 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
138 		printf("Could not find \"%s\" partition\n", partition);
139 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
140 	}
141 
142 	if ((offset % 512 != 0) && (num_bytes % 512) != 0) {
143 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp);
144 	}
145 
146 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
147 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
148 	free(buffer_temp);
149 
150 	return AVB_IO_RESULT_OK;
151 }
152 
153 static AvbIOResult validate_vbmeta_public_key(
154 	AvbOps *ops,
155 	const uint8_t *public_key_data,
156 	size_t public_key_length,
157 	const uint8_t *public_key_metadata,
158 	size_t public_key_metadata_length,
159 	bool *out_is_trusted)
160 {
161 #ifdef AVB_VBMETA_PUBLIC_KEY_VALIDATE
162 	if (out_is_trusted != NULL) {
163 		avb_atx_validate_vbmeta_public_key(ops,
164 						   public_key_data,
165 						   public_key_length,
166 						   public_key_metadata,
167 						   public_key_metadata_length,
168 						   out_is_trusted);
169 	}
170 #else
171 	if (out_is_trusted != NULL) {
172 		*out_is_trusted = true;
173 	}
174 #endif
175 	return AVB_IO_RESULT_OK;
176 }
177 
178 static AvbIOResult read_rollback_index(AvbOps *ops,
179                                        size_t rollback_index_location,
180                                        uint64_t *out_rollback_index)
181 {
182 	if (out_rollback_index != NULL) {
183 #ifdef CONFIG_OPTEE_CLIENT
184 		int ret;
185 		ret = trusty_read_rollback_index(rollback_index_location,
186 						 out_rollback_index);
187 		if (ret == TEE_ERROR_ITEM_NOT_FOUND) {
188 			*out_rollback_index = 0;
189 			ret = trusty_write_rollback_index(rollback_index_location,
190 							  *out_rollback_index);
191 			if (ret != 0) {
192 				printf("%s: init rollback index error\n", __FILE__);
193 				return AVB_IO_RESULT_ERROR_IO;
194 			}
195 			ret = trusty_read_rollback_index(rollback_index_location,
196 							 out_rollback_index);
197 			if (ret == 0)
198 				return AVB_IO_RESULT_OK;
199 		} else if (ret == 0) {
200 			return AVB_IO_RESULT_OK;
201 		} else {
202 			printf("trusty_read_rollback_index ret = %x\n", ret);
203 			return AVB_IO_RESULT_ERROR_IO;
204 		}
205 #endif
206 	}
207 	return AVB_IO_RESULT_ERROR_IO;
208 }
209 
210 static AvbIOResult write_rollback_index(AvbOps *ops,
211                                         size_t rollback_index_location,
212                                         uint64_t rollback_index)
213 {
214 #ifdef CONFIG_OPTEE_CLIENT
215 	if (trusty_write_rollback_index(rollback_index_location, rollback_index)) {
216 		printf("%s: Fail to write rollback index\n", __FILE__);
217 		return AVB_IO_RESULT_ERROR_IO;
218 	}
219 	return AVB_IO_RESULT_OK;
220 #endif
221 	return AVB_IO_RESULT_ERROR_IO;
222 }
223 
224 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
225 {
226 	if (out_is_unlocked != NULL) {
227 #ifdef CONFIG_OPTEE_CLIENT
228 		int ret;
229 
230 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
231 		if (ret == TEE_ERROR_ITEM_NOT_FOUND) {
232 			*out_is_unlocked = 1;
233 			if (trusty_write_lock_state(*out_is_unlocked)) {
234 				printf("%s: init lock state error\n", __FILE__);
235 				return AVB_IO_RESULT_ERROR_IO;
236 			}
237 
238 			ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
239 			if(ret == 0)
240 				return 0;
241 		} else if (ret == 0) {
242 			return AVB_IO_RESULT_OK;
243 		} else {
244 			printf("read_is_device_unlocked ret = %x\n", ret);
245 			return AVB_IO_RESULT_ERROR_IO;
246 		}
247 #endif
248 	}
249 	return AVB_IO_RESULT_ERROR_IO;
250 }
251 
252 static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
253 {
254 	if (out_is_unlocked != NULL) {
255 #ifdef CONFIG_OPTEE_CLIENT
256 		if (trusty_write_lock_state(*out_is_unlocked)) {
257 			printf("%s: Fail to write lock state\n", __FILE__);
258 			return AVB_IO_RESULT_ERROR_IO;
259 		}
260 		return AVB_IO_RESULT_OK;
261 #endif
262 	}
263 	return AVB_IO_RESULT_ERROR_IO;
264 }
265 
266 static AvbIOResult get_size_of_partition(AvbOps *ops,
267                                          const char *partition,
268                                          uint64_t *out_size_in_bytes)
269 {
270 	struct blk_desc *dev_desc;
271 	disk_partition_t part_info;
272 
273 	dev_desc = rockchip_get_bootdev();
274 	if (!dev_desc) {
275 		printf("%s: Could not find device\n", __func__);
276 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
277 	}
278 
279 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
280 		printf("Could not find \"%s\" partition\n", partition);
281 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
282 	}
283 	*out_size_in_bytes = (part_info.size) * 512;
284 	return AVB_IO_RESULT_OK;
285 }
286 
287 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
288                                                  const char *partition,
289                                                  char *guid_buf,
290                                                  size_t guid_buf_size)
291 {
292 	struct blk_desc *dev_desc;
293 	disk_partition_t part_info;
294 	dev_desc = rockchip_get_bootdev();
295 	if (!dev_desc) {
296 		printf("%s: Could not find device\n", __func__);
297 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
298 	}
299 
300 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
301 		printf("Could not find \"%s\" partition\n", partition);
302 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
303 	}
304 	if (guid_buf != NULL && guid_buf_size > 0) {
305 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
306 	}
307 	return AVB_IO_RESULT_OK;
308 }
309 
310 /* read permanent attributes from rpmb */
311 AvbIOResult avb_read_perm_attr(AvbAtxOps* atx_ops,
312 			       AvbAtxPermanentAttributes* attributes)
313 {
314 	if (attributes != NULL) {
315 #ifdef CONFIG_OPTEE_CLIENT
316 		trusty_read_permanent_attributes((uint8_t *)attributes,
317 						 sizeof(struct AvbAtxPermanentAttributes));
318 		return AVB_IO_RESULT_OK;
319 #endif
320 	}
321 
322 	return -1;
323 }
324 
325 /*read permanent attributes hash from efuse */
326 AvbIOResult avb_read_perm_attr_hash(AvbAtxOps* atx_ops,
327 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
328 {
329 #ifdef CONFIG_OPTEE_CLIENT
330 	if (trusty_read_attribute_hash((uint32_t *)hash, AVB_SHA256_DIGEST_SIZE / 4))
331 		return -1;
332 #else
333 	avb_error("Please open the macro!\n");
334 	return -1;
335 #endif
336 	return AVB_IO_RESULT_OK;
337 }
338 
339 AvbOps* avb_ops_user_new(void) {
340   AvbOps* ops;
341 
342   ops = calloc(1, sizeof(AvbOps));
343   if (ops == NULL) {
344     avb_error("Error allocating memory for AvbOps.\n");
345     goto out;
346   }
347 
348   ops->ab_ops = calloc(1, sizeof(AvbABOps));
349   if (ops->ab_ops == NULL) {
350     avb_error("Error allocating memory for AvbABOps.\n");
351     free(ops);
352     goto out;
353   }
354 
355   ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
356   if (ops->atx_ops == NULL) {
357     avb_error("Error allocating memory for AvbAtxOps.\n");
358     free(ops->ab_ops);
359     free(ops);
360     goto out;
361   }
362   ops->ab_ops->ops = ops;
363   ops->atx_ops->ops = ops;
364 
365   ops->read_from_partition = read_from_partition;
366   ops->write_to_partition = write_to_partition;
367   ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
368   ops->read_rollback_index = read_rollback_index;
369   ops->write_rollback_index = write_rollback_index;
370   ops->read_is_device_unlocked = read_is_device_unlocked;
371   ops->write_is_device_unlocked = write_is_device_unlocked;
372   ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
373   ops->get_size_of_partition = get_size_of_partition;
374   ops->ab_ops->read_ab_metadata = avb_ab_data_read;
375   ops->ab_ops->write_ab_metadata = avb_ab_data_write;
376   ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
377   ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
378 
379 out:
380   return ops;
381 }
382 
383 
384 void avb_ops_user_free(AvbOps* ops) {
385   free(ops->ab_ops);
386   free(ops->atx_ops);
387   free(ops);
388 }
389