1 /*
2 * Copyright (C) 2020 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 <libavb/avb_crypto.h>
26 #include <libavb/avb_rsa.h>
27 #include <libavb/avb_sha.h>
28 #include <libavb/avb_util.h>
29
30 #include "avb_aftl_types.h"
31 #include "avb_aftl_util.h"
32 #include "avb_aftl_validate.h"
33
34 /* Performs a SHA256 hash operation on data. */
avb_aftl_sha256(uint8_t * data,uint64_t length,uint8_t hash[AVB_AFTL_HASH_SIZE])35 bool avb_aftl_sha256(uint8_t* data,
36 uint64_t length,
37 uint8_t hash[AVB_AFTL_HASH_SIZE]) {
38 AvbSHA256Ctx context;
39 uint8_t* tmp;
40
41 if ((data == NULL) && (length != 0)) return false;
42
43 avb_sha256_init(&context);
44 avb_sha256_update(&context, data, length);
45 tmp = avb_sha256_final(&context);
46 avb_memcpy(hash, tmp, AVB_AFTL_HASH_SIZE);
47 return true;
48 }
49
50 /* Calculates a SHA256 hash of the TrillianLogRootDescriptor in icp_entry.
51
52 The hash is calculated over the entire TrillianLogRootDescriptor
53 structure. Some of the fields in this implementation are dynamically
54 allocated, and so the data needs to be reconstructed so that the hash
55 can be properly calculated. The TrillianLogRootDescriptor is defined
56 here: https://github.com/google/trillian/blob/master/trillian.proto#L255 */
avb_aftl_hash_log_root_descriptor(AftlIcpEntry * icp_entry,uint8_t * hash)57 bool avb_aftl_hash_log_root_descriptor(AftlIcpEntry* icp_entry, uint8_t* hash) {
58 uint8_t* buffer;
59 uint8_t* lrd_offset; /* Byte offset into the descriptor. */
60 uint32_t tlrd_size;
61 uint16_t version;
62 uint64_t tree_size;
63 uint64_t timestamp;
64 uint64_t revision;
65 uint16_t metadata_size;
66 bool retval;
67
68 avb_assert(icp_entry != NULL && hash != NULL);
69
70 /* Size of the non-pointer elements of the TrillianLogRootDescriptor. */
71 tlrd_size = sizeof(uint16_t) * 2 + sizeof(uint64_t) * 3 + sizeof(uint8_t);
72 /* Ensure the log_root_descriptor size is correct. */
73 if (icp_entry->log_root_descriptor_size > AVB_AFTL_MAX_TLRD_SIZE) {
74 avb_error("Invalid log root descriptor size.\n");
75 return false;
76 }
77 if (icp_entry->log_root_descriptor_size !=
78 (tlrd_size + icp_entry->log_root_descriptor.root_hash_size +
79 icp_entry->log_root_descriptor.metadata_size)) {
80 avb_error("Log root descriptor size doesn't match fields.\n");
81 return false;
82 }
83 /* Check that the root_hash exists, and if not, it's size is sane. */
84 if (!icp_entry->log_root_descriptor.root_hash &&
85 (icp_entry->log_root_descriptor.root_hash_size != 0)) {
86 avb_error("Invalid tree root hash values.\n");
87 return false;
88 }
89
90 /* Check that the metadata exists, and if not, it's size is sane. */
91 if (!icp_entry->log_root_descriptor.metadata &&
92 (icp_entry->log_root_descriptor.metadata_size != 0)) {
93 avb_error("Invalid log root descriptor metadata values.\n");
94 return false;
95 }
96 buffer = (uint8_t*)avb_malloc(icp_entry->log_root_descriptor_size);
97 if (buffer == NULL) {
98 avb_error("Allocation failure in avb_aftl_hash_log_root_descriptor.\n");
99 return false;
100 }
101 lrd_offset = buffer;
102 /* Copy in the version, tree_size and root hash length. */
103 /* Ensure endianness is correct. */
104 version = avb_be16toh(icp_entry->log_root_descriptor.version);
105 avb_memcpy(lrd_offset, &version, sizeof(uint16_t));
106 lrd_offset += sizeof(uint16_t);
107 /* Ensure endianness is correct. */
108 tree_size = avb_be64toh(icp_entry->log_root_descriptor.tree_size);
109 avb_memcpy(lrd_offset, &tree_size, sizeof(uint64_t));
110 lrd_offset += sizeof(uint64_t);
111 avb_memcpy(lrd_offset,
112 &(icp_entry->log_root_descriptor.root_hash_size),
113 sizeof(uint8_t));
114 lrd_offset += sizeof(uint8_t);
115 /* Copy the root hash. */
116 if (icp_entry->log_root_descriptor.root_hash_size > 0) {
117 avb_memcpy(lrd_offset,
118 icp_entry->log_root_descriptor.root_hash,
119 icp_entry->log_root_descriptor.root_hash_size);
120 }
121 lrd_offset += icp_entry->log_root_descriptor.root_hash_size;
122 /* Copy in the timestamp, revision, and the metadata length. */
123 /* Ensure endianness is correct. */
124 timestamp = avb_be64toh(icp_entry->log_root_descriptor.timestamp);
125 avb_memcpy(lrd_offset, ×tamp, sizeof(uint64_t));
126 lrd_offset += sizeof(uint64_t);
127 /* Ensure endianness is correct. */
128 revision = avb_be64toh(icp_entry->log_root_descriptor.revision);
129 avb_memcpy(lrd_offset, &revision, sizeof(uint64_t));
130 lrd_offset += sizeof(uint64_t);
131 /* Ensure endianness is correct. */
132 metadata_size = avb_be16toh(icp_entry->log_root_descriptor.metadata_size);
133 avb_memcpy(lrd_offset, &metadata_size, sizeof(uint16_t));
134 lrd_offset += sizeof(uint16_t);
135
136 /* Copy the metadata if it exists. */
137 if (icp_entry->log_root_descriptor.metadata_size > 0) {
138 avb_memcpy(lrd_offset,
139 icp_entry->log_root_descriptor.metadata,
140 icp_entry->log_root_descriptor.metadata_size);
141 }
142 /* Hash the result & clean up. */
143
144 retval = avb_aftl_sha256(buffer, icp_entry->log_root_descriptor_size, hash);
145 avb_free(buffer);
146 return retval;
147 }
148
149 /* Computes a leaf hash as detailed by https://tools.ietf.org/html/rfc6962. */
avb_aftl_rfc6962_hash_leaf(uint8_t * leaf,uint64_t leaf_size,uint8_t * hash)150 bool avb_aftl_rfc6962_hash_leaf(uint8_t* leaf,
151 uint64_t leaf_size,
152 uint8_t* hash) {
153 uint8_t* buffer;
154 bool retval;
155
156 avb_assert(leaf != NULL && hash != NULL);
157 avb_assert(leaf_size != AVB_AFTL_UINT64_MAX);
158
159 buffer = (uint8_t*)avb_malloc(leaf_size + 1);
160
161 if (buffer == NULL) {
162 avb_error("Allocation failure in avb_aftl_rfc6962_hash_leaf.\n");
163 return false;
164 }
165 /* Prefix the data with a '0' for 2nd preimage attack resistance. */
166 buffer[0] = 0;
167
168 if (leaf_size > 0) avb_memcpy(buffer + 1, leaf, leaf_size);
169
170 retval = avb_aftl_sha256(buffer, leaf_size + 1, hash);
171 avb_free(buffer);
172 return retval;
173 }
174
175 /* Computes an inner hash as detailed by https://tools.ietf.org/html/rfc6962. */
avb_aftl_rfc6962_hash_children(uint8_t * left_child,uint64_t left_child_size,uint8_t * right_child,uint64_t right_child_size,uint8_t * hash)176 bool avb_aftl_rfc6962_hash_children(uint8_t* left_child,
177 uint64_t left_child_size,
178 uint8_t* right_child,
179 uint64_t right_child_size,
180 uint8_t* hash) {
181 uint8_t* buffer;
182 uint64_t data_size;
183 bool retval;
184
185 avb_assert(left_child != NULL && right_child != NULL && hash != NULL);
186
187 /* Check for integer overflow. */
188 avb_assert(left_child_size < AVB_AFTL_UINT64_MAX - right_child_size);
189
190 data_size = left_child_size + right_child_size + 1;
191 buffer = (uint8_t*)avb_malloc(data_size);
192 if (buffer == NULL) {
193 avb_error("Allocation failure in avb_aftl_rfc6962_hash_children.\n");
194 return false;
195 }
196
197 /* Prefix the data with '1' for 2nd preimage attack resistance. */
198 buffer[0] = 1;
199
200 /* Copy the left child data, if it exists. */
201 if (left_child_size > 0) avb_memcpy(buffer + 1, left_child, left_child_size);
202 /* Copy the right child data, if it exists. */
203 if (right_child_size > 0)
204 avb_memcpy(buffer + 1 + left_child_size, right_child, right_child_size);
205
206 /* Hash the concatenated data and clean up. */
207 retval = avb_aftl_sha256(buffer, data_size, hash);
208 avb_free(buffer);
209 return retval;
210 }
211
212 /* Computes a subtree hash along tree's right border. */
avb_aftl_chain_border_right(uint8_t * seed,uint64_t seed_size,uint8_t * proof,uint32_t proof_entry_count,uint8_t * hash)213 bool avb_aftl_chain_border_right(uint8_t* seed,
214 uint64_t seed_size,
215 uint8_t* proof,
216 uint32_t proof_entry_count,
217 uint8_t* hash) {
218 size_t i;
219 uint8_t* tmp_hash;
220 uint8_t* tmp = seed;
221 bool retval = true;
222
223 avb_assert(seed_size == AVB_AFTL_HASH_SIZE);
224 avb_assert(seed != NULL && proof != NULL && hash != NULL);
225
226 tmp_hash = (uint8_t*)avb_malloc(AVB_AFTL_HASH_SIZE);
227 if (tmp_hash == NULL) {
228 avb_error("Allocation failure in avb_aftl_chain_border_right.\n");
229 return false;
230 }
231 for (i = 0; i < proof_entry_count; i++) {
232 retval = avb_aftl_rfc6962_hash_children(proof + (i * AVB_AFTL_HASH_SIZE),
233 AVB_AFTL_HASH_SIZE,
234 tmp,
235 AVB_AFTL_HASH_SIZE,
236 tmp_hash);
237 if (!retval) {
238 avb_error("Failed to hash Merkle tree children.\n");
239 break;
240 }
241 tmp = tmp_hash;
242 }
243
244 if (retval) avb_memcpy(hash, tmp, AVB_AFTL_HASH_SIZE);
245
246 avb_free(tmp_hash);
247 return retval;
248 }
249
250 /* Computes a subtree hash on or below the tree's right border. */
avb_aftl_chain_inner(uint8_t * seed,uint64_t seed_size,uint8_t * proof,uint32_t proof_entry_count,uint64_t leaf_index,uint8_t * hash)251 bool avb_aftl_chain_inner(uint8_t* seed,
252 uint64_t seed_size,
253 uint8_t* proof,
254 uint32_t proof_entry_count,
255 uint64_t leaf_index,
256 uint8_t* hash) {
257 size_t i;
258 uint8_t* tmp_hash;
259 uint8_t* tmp = seed;
260 bool retval = true;
261
262 avb_assert(seed_size == AVB_AFTL_HASH_SIZE);
263 avb_assert(seed != NULL && proof != NULL && hash != NULL);
264
265 tmp_hash = (uint8_t*)avb_malloc(AVB_AFTL_HASH_SIZE);
266 if (tmp_hash == NULL) {
267 avb_error("Allocation failure in avb_aftl_chain_inner.\n");
268 return false;
269 }
270 for (i = 0; i < proof_entry_count; i++) {
271 if ((leaf_index >> i & 1) == 0) {
272 retval = avb_aftl_rfc6962_hash_children(tmp,
273 seed_size,
274 proof + (i * AVB_AFTL_HASH_SIZE),
275 AVB_AFTL_HASH_SIZE,
276 tmp_hash);
277 } else {
278 retval = avb_aftl_rfc6962_hash_children(proof + (i * AVB_AFTL_HASH_SIZE),
279 AVB_AFTL_HASH_SIZE,
280 tmp,
281 seed_size,
282 tmp_hash);
283 }
284 if (!retval) {
285 avb_error("Failed to hash Merkle tree children.\n");
286 break;
287 }
288 tmp = tmp_hash;
289 }
290 if (retval) avb_memcpy(hash, tmp, AVB_AFTL_HASH_SIZE);
291 avb_free(tmp_hash);
292 return retval;
293 }
294
295 /* Counts leading zeros. Used in Merkle tree hash validation .*/
avb_aftl_count_leading_zeros(uint64_t val)296 unsigned int avb_aftl_count_leading_zeros(uint64_t val) {
297 int r = 0;
298 if (val == 0) return 64;
299 if (!(val & 0xffffffff00000000u)) {
300 val <<= 32;
301 r += 32;
302 }
303 if (!(val & 0xffff000000000000u)) {
304 val <<= 16;
305 r += 16;
306 }
307 if (!(val & 0xff00000000000000u)) {
308 val <<= 8;
309 r += 8;
310 }
311 if (!(val & 0xf000000000000000u)) {
312 val <<= 4;
313 r += 4;
314 }
315 if (!(val & 0xc000000000000000u)) {
316 val <<= 2;
317 r += 2;
318 }
319 if (!(val & 0x8000000000000000u)) {
320 val <<= 1;
321 r += 1;
322 }
323
324 return r;
325 }
326
327 /* Calculates the expected Merkle tree hash. */
avb_aftl_root_from_icp(uint64_t leaf_index,uint64_t tree_size,uint8_t proof[][AVB_AFTL_HASH_SIZE],uint32_t proof_entry_count,uint8_t * leaf_hash,uint64_t leaf_hash_size,uint8_t * root_hash)328 bool avb_aftl_root_from_icp(uint64_t leaf_index,
329 uint64_t tree_size,
330 uint8_t proof[][AVB_AFTL_HASH_SIZE],
331 uint32_t proof_entry_count,
332 uint8_t* leaf_hash,
333 uint64_t leaf_hash_size,
334 uint8_t* root_hash) {
335 uint64_t inner_proof_size;
336 uint64_t border_proof_size;
337 size_t i;
338 uint8_t hash[AVB_AFTL_HASH_SIZE];
339 uint8_t* inner_proof;
340 uint8_t* border_proof;
341 bool retval;
342
343 avb_assert(proof_entry_count != 0);
344 avb_assert(leaf_hash_size != 0);
345 avb_assert(proof != NULL && leaf_hash != NULL && root_hash != NULL);
346
347 /* This cannot overflow. */
348 inner_proof_size =
349 64 - avb_aftl_count_leading_zeros(leaf_index ^ (tree_size - 1));
350
351 /* Check for integer underflow.*/
352 if ((proof_entry_count - inner_proof_size) > proof_entry_count) {
353 avb_error("Invalid proof entry count value.\n");
354 return false;
355 }
356 border_proof_size = proof_entry_count - inner_proof_size;
357 /* Split the proof into two parts based on the calculated pivot point. */
358 inner_proof = (uint8_t*)avb_malloc(inner_proof_size * AVB_AFTL_HASH_SIZE);
359 if (inner_proof == NULL) {
360 avb_error("Allocation failure in avb_aftl_root_from_icp.\n");
361 return false;
362 }
363 border_proof = (uint8_t*)avb_malloc(border_proof_size * AVB_AFTL_HASH_SIZE);
364 if (border_proof == NULL) {
365 avb_free(inner_proof);
366 avb_error("Allocation failure in avb_aftl_root_from_icp.\n");
367 return false;
368 }
369
370 for (i = 0; i < inner_proof_size; i++) {
371 avb_memcpy(
372 inner_proof + (AVB_AFTL_HASH_SIZE * i), proof[i], AVB_AFTL_HASH_SIZE);
373 }
374 for (i = 0; i < border_proof_size; i++) {
375 avb_memcpy(border_proof + (AVB_AFTL_HASH_SIZE * i),
376 proof[inner_proof_size + i],
377 AVB_AFTL_HASH_SIZE);
378 }
379
380 /* Calculate the root hash and store it in root_hash. */
381 retval = avb_aftl_chain_inner(leaf_hash,
382 leaf_hash_size,
383 inner_proof,
384 inner_proof_size,
385 leaf_index,
386 hash);
387 if (retval)
388 retval = avb_aftl_chain_border_right(
389 hash, AVB_AFTL_HASH_SIZE, border_proof, border_proof_size, root_hash);
390
391 if (inner_proof != NULL) avb_free(inner_proof);
392 if (border_proof != NULL) avb_free(border_proof);
393 return retval;
394 }
395
396 /* Allocates and populates a TrillianLogRootDescriptor element in an
397 AftlIcpEntry from a binary blob.
398 The blob is expected to be pointing to the beginning of a
399 serialized TrillianLogRootDescriptor element of an AftlIcpEntry.
400 The aftl_blob argument is updated to point to the area after the
401 TrillianLogRootDescriptor. aftl_blob_remaining gives the amount of the
402 aftl_blob that is left to parse. */
parse_trillian_log_root_descriptor(AftlIcpEntry * icp_entry,uint8_t ** aftl_blob,size_t aftl_blob_remaining)403 static bool parse_trillian_log_root_descriptor(AftlIcpEntry* icp_entry,
404 uint8_t** aftl_blob,
405 size_t aftl_blob_remaining) {
406 size_t parsed_size;
407
408 avb_assert(icp_entry);
409 avb_assert(aftl_blob);
410 avb_assert(aftl_blob_remaining >= AVB_AFTL_MIN_TLRD_SIZE);
411 /* Copy in the version field from the blob. */
412 avb_memcpy(&(icp_entry->log_root_descriptor.version),
413 *aftl_blob,
414 avb_aftl_member_size(TrillianLogRootDescriptor, version));
415 icp_entry->log_root_descriptor.version =
416 avb_be16toh(icp_entry->log_root_descriptor.version);
417 *aftl_blob += avb_aftl_member_size(TrillianLogRootDescriptor, version);
418 parsed_size = avb_aftl_member_size(TrillianLogRootDescriptor, version);
419 /* Copy in the tree size field from the blob. */
420 avb_memcpy(&(icp_entry->log_root_descriptor.tree_size),
421 *aftl_blob,
422 avb_aftl_member_size(TrillianLogRootDescriptor, tree_size));
423 icp_entry->log_root_descriptor.tree_size =
424 avb_be64toh(icp_entry->log_root_descriptor.tree_size);
425 *aftl_blob += avb_aftl_member_size(TrillianLogRootDescriptor, tree_size);
426 parsed_size += avb_aftl_member_size(TrillianLogRootDescriptor, tree_size);
427 /* Copy in the root hash size field from the blob. */
428 avb_memcpy(&(icp_entry->log_root_descriptor.root_hash_size),
429 *aftl_blob,
430 avb_aftl_member_size(TrillianLogRootDescriptor, root_hash_size));
431 if (icp_entry->log_root_descriptor.root_hash_size != AVB_AFTL_HASH_SIZE) {
432 avb_error("Invalid root hash size.\n");
433 free_aftl_icp_entry(icp_entry);
434 return false;
435 }
436 *aftl_blob += avb_aftl_member_size(TrillianLogRootDescriptor, root_hash_size);
437 parsed_size +=
438 avb_aftl_member_size(TrillianLogRootDescriptor, root_hash_size);
439 /* Copy in the root hash from the blob. */
440 icp_entry->log_root_descriptor.root_hash =
441 (uint8_t*)avb_calloc(icp_entry->log_root_descriptor.root_hash_size);
442 if (!icp_entry->log_root_descriptor.root_hash) {
443 avb_error("Failure to allocate root hash.\n");
444 free_aftl_icp_entry(icp_entry);
445 return false;
446 }
447
448 avb_memcpy(icp_entry->log_root_descriptor.root_hash,
449 *aftl_blob,
450 icp_entry->log_root_descriptor.root_hash_size);
451 *aftl_blob += icp_entry->log_root_descriptor.root_hash_size;
452 parsed_size += icp_entry->log_root_descriptor.root_hash_size;
453 /* Copy in the timestamp field from the blob. */
454 avb_memcpy(&(icp_entry->log_root_descriptor.timestamp),
455 *aftl_blob,
456 avb_aftl_member_size(TrillianLogRootDescriptor, timestamp));
457 icp_entry->log_root_descriptor.timestamp =
458 avb_be64toh(icp_entry->log_root_descriptor.timestamp);
459 *aftl_blob += avb_aftl_member_size(TrillianLogRootDescriptor, timestamp);
460 parsed_size += avb_aftl_member_size(TrillianLogRootDescriptor, timestamp);
461 /* Copy in the revision field from the blob. */
462 avb_memcpy(&(icp_entry->log_root_descriptor.revision),
463 *aftl_blob,
464 avb_aftl_member_size(TrillianLogRootDescriptor, revision));
465 icp_entry->log_root_descriptor.revision =
466 avb_be64toh(icp_entry->log_root_descriptor.revision);
467 *aftl_blob += avb_aftl_member_size(TrillianLogRootDescriptor, revision);
468 parsed_size += avb_aftl_member_size(TrillianLogRootDescriptor, revision);
469 /* Copy in the metadata size field from the blob. */
470 avb_memcpy(&(icp_entry->log_root_descriptor.metadata_size),
471 *aftl_blob,
472 avb_aftl_member_size(TrillianLogRootDescriptor, metadata_size));
473 icp_entry->log_root_descriptor.metadata_size =
474 avb_be16toh(icp_entry->log_root_descriptor.metadata_size);
475 *aftl_blob += avb_aftl_member_size(TrillianLogRootDescriptor, metadata_size);
476 parsed_size += avb_aftl_member_size(TrillianLogRootDescriptor, metadata_size);
477 if (icp_entry->log_root_descriptor.metadata_size >
478 AVB_AFTL_MAX_METADATA_SIZE) {
479 avb_error("Invalid metadata size.\n");
480 free_aftl_icp_entry(icp_entry);
481 return false;
482 }
483 if (icp_entry->log_root_descriptor.metadata_size + parsed_size >
484 aftl_blob_remaining) {
485 avb_error("Invalid AftlDescriptor.\n");
486 free_aftl_icp_entry(icp_entry);
487 return false;
488 }
489 /* If it exists, copy in the metadata field from the blob. */
490 if (icp_entry->log_root_descriptor.metadata_size > 0) {
491 icp_entry->log_root_descriptor.metadata =
492 (uint8_t*)avb_calloc(icp_entry->log_root_descriptor.metadata_size);
493 if (!icp_entry->log_root_descriptor.metadata) {
494 avb_error("Failure to allocate metadata.\n");
495 free_aftl_icp_entry(icp_entry);
496 return false;
497 }
498 avb_memcpy(icp_entry->log_root_descriptor.metadata,
499 *aftl_blob,
500 icp_entry->log_root_descriptor.metadata_size);
501 *aftl_blob += icp_entry->log_root_descriptor.metadata_size;
502 } else {
503 icp_entry->log_root_descriptor.metadata = NULL;
504 }
505 return true;
506 }
507
base64_decode(uint8_t * input,size_t input_size,uint8_t * output,size_t output_size)508 static void base64_decode(uint8_t* input,
509 size_t input_size,
510 uint8_t* output,
511 size_t output_size) {
512 size_t i, j;
513 uint32_t tmp_val;
514 uint8_t decode_table[] = {
515 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1,
516 -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
517 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
518 -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
519 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
520 avb_assert(input != NULL);
521 avb_assert(output != NULL);
522
523 for (i = 0, j = 0; i < input_size; i += 4, j += 3) {
524 tmp_val = decode_table[input[i] - '+'];
525 tmp_val = (tmp_val << 6) | decode_table[input[i + 1] - '+'];
526 tmp_val <<= 6;
527 if (input[i + 2] != '=') tmp_val |= decode_table[input[i + 2] - '+'];
528 tmp_val <<= 6;
529 if (input[i + 3] != '=') tmp_val |= decode_table[input[i + 3] - '+'];
530
531 output[j] = (tmp_val >> 16) & 0xff;
532 if (input[i + 2] != '=') output[j + 1] = (tmp_val >> 8) & 0xff;
533 if (input[i + 3] != '=') output[j + 2] = tmp_val & 0xff;
534 }
535 }
536
find_and_decode_vbmeta_hash(uint8_t * vbmeta_hash,size_t vbmeta_size,uint8_t * json_data,size_t json_data_size)537 static bool find_and_decode_vbmeta_hash(uint8_t* vbmeta_hash,
538 size_t vbmeta_size,
539 uint8_t* json_data,
540 size_t json_data_size) {
541 const char vbmeta_id[] = "\"vbmeta_hash\":";
542 size_t vbmeta_id_size = sizeof(vbmeta_id) - 1;
543 size_t vbmeta_base64_size;
544 uint8_t* vbmeta_ptr;
545 uint8_t* vbmeta_base64;
546
547 avb_assert(vbmeta_hash != NULL);
548 avb_assert(vbmeta_size == AVB_AFTL_HASH_SIZE);
549 avb_assert(json_data != NULL);
550 avb_assert(json_data_size > vbmeta_size);
551
552 vbmeta_ptr = (uint8_t*)avb_strstr((const char*)json_data, vbmeta_id);
553 if (vbmeta_ptr == NULL) {
554 vbmeta_hash = NULL;
555 return false;
556 }
557 /* Jump past the vbmeta_hash identifier */
558 vbmeta_ptr += vbmeta_id_size;
559 if (vbmeta_ptr[0] == '"') {
560 vbmeta_base64_size = 1;
561 while (vbmeta_ptr[vbmeta_base64_size] != '"' &&
562 vbmeta_base64_size <= AVB_AFTL_HASH_SIZE * 4 / 3 + 1) {
563 vbmeta_base64_size++;
564 }
565 vbmeta_base64 = (uint8_t*)avb_calloc(vbmeta_base64_size + 1);
566 if (vbmeta_base64 == NULL) {
567 vbmeta_hash = NULL;
568 return false;
569 }
570 avb_memcpy(vbmeta_base64, vbmeta_ptr + 1, vbmeta_base64_size);
571 base64_decode(vbmeta_base64, vbmeta_base64_size, vbmeta_hash, vbmeta_size);
572 avb_free(vbmeta_base64);
573 } else {
574 vbmeta_hash = NULL;
575 return false;
576 }
577
578 return true;
579 }
580
581 /* Allocates and populates a FirmwareInfo element in an
582 AftlIcpEntry from a binary blob.
583 The blob is expected to be pointing to the beginning of a
584 serialized FirmwareInfo element of an AftlIcpEntry.
585 The aftl_blob argument is updated to point to the area after the
586 FirmwareInfo leaf. */
parse_firmware_info(AftlIcpEntry * icp_entry,uint8_t ** aftl_blob)587 static bool parse_firmware_info(AftlIcpEntry* icp_entry, uint8_t** aftl_blob) {
588 /* Copy in the fw_info leaf bytes from the blob. */
589 /* Parse out and decode in the vbmeta_hash value from the fw_info
590 leaf bytes. */
591 icp_entry->fw_info_leaf.json_data =
592 (uint8_t*)avb_calloc(icp_entry->fw_info_leaf_size);
593 if (icp_entry->fw_info_leaf.json_data == NULL) {
594 avb_error("Failed to allocate for FirmwareInfo leaf.\n");
595 free_aftl_icp_entry(icp_entry);
596 return false;
597 }
598 avb_memcpy(icp_entry->fw_info_leaf.json_data,
599 *aftl_blob,
600 icp_entry->fw_info_leaf_size);
601 *aftl_blob += icp_entry->fw_info_leaf_size;
602
603 icp_entry->fw_info_leaf.vbmeta_hash_size = AVB_AFTL_HASH_SIZE;
604 icp_entry->fw_info_leaf.vbmeta_hash =
605 (uint8_t*)avb_calloc(icp_entry->fw_info_leaf.vbmeta_hash_size);
606 if (icp_entry->fw_info_leaf.vbmeta_hash == NULL) {
607 avb_error("Failed to allocate vbmeta hash.\n");
608 free_aftl_icp_entry(icp_entry);
609 return false;
610 }
611 if (!find_and_decode_vbmeta_hash(icp_entry->fw_info_leaf.vbmeta_hash,
612 icp_entry->fw_info_leaf.vbmeta_hash_size,
613 icp_entry->fw_info_leaf.json_data,
614 icp_entry->fw_info_leaf_size)) {
615 avb_error("Could not parse vbmeta_hash out of FirmwareInfo leaf.\n");
616 free_aftl_icp_entry(icp_entry);
617 return false;
618 }
619
620 return true;
621 }
622
623 /* Allocates and populates an AftlIcpEntry from a binary blob.
624 The blob is expected to be pointing to the beginning of a
625 serialized AftlIcpEntry structure. */
parse_icp_entry(uint8_t ** aftl_blob,size_t * remaining_size)626 AftlIcpEntry* parse_icp_entry(uint8_t** aftl_blob, size_t* remaining_size) {
627 AftlIcpEntry *icp_entry, *tmp_icp_entry;
628 uint32_t proof_size;
629 uint64_t parsed_size;
630
631 /* Make a temp AftlIcpEntry to get the inclusion proof size
632 for memory allocation purposes.*/
633 tmp_icp_entry = (AftlIcpEntry*)*aftl_blob;
634 proof_size = avb_be32toh(tmp_icp_entry->inc_proof_size);
635
636 /* Ensure the calculated size is sane. */
637 if (proof_size > AVB_AFTL_MAX_PROOF_SIZE) {
638 avb_error("Invalid inclusion proof size.\n");
639 return NULL;
640 }
641
642 if (*remaining_size < proof_size + AVB_AFTL_MIN_AFTL_ICP_ENTRY_SIZE) {
643 avb_error("Invalid AftlDescriptor\n");
644 return NULL;
645 }
646
647 icp_entry = (AftlIcpEntry*)avb_calloc(proof_size + sizeof(AftlIcpEntry));
648 if (!icp_entry) {
649 avb_error("Failure allocating AftlIcpEntry\n");
650 return NULL;
651 }
652 /* Copy in the log server URL size field. */
653 avb_memcpy(&(icp_entry->log_url_size),
654 *aftl_blob,
655 avb_aftl_member_size(AftlIcpEntry, log_url_size));
656 icp_entry->log_url_size = avb_be32toh(icp_entry->log_url_size);
657 if (icp_entry->log_url_size > AVB_AFTL_MAX_URL_SIZE) {
658 avb_error("Invalid log URL size.\n");
659 avb_free(icp_entry);
660 return NULL;
661 }
662 *aftl_blob += avb_aftl_member_size(AftlIcpEntry, log_url_size);
663 parsed_size = avb_aftl_member_size(AftlIcpEntry, log_url_size);
664 /* Copy in the leaf index field. */
665 avb_memcpy(&(icp_entry->leaf_index),
666 *aftl_blob,
667 avb_aftl_member_size(AftlIcpEntry, leaf_index));
668 icp_entry->leaf_index = avb_be64toh(icp_entry->leaf_index);
669 *aftl_blob += avb_aftl_member_size(AftlIcpEntry, leaf_index);
670 parsed_size += avb_aftl_member_size(AftlIcpEntry, leaf_index);
671 /* Copy in the TrillianLogRootDescriptor size field. */
672 avb_memcpy(&(icp_entry->log_root_descriptor_size),
673 *aftl_blob,
674 avb_aftl_member_size(AftlIcpEntry, log_root_descriptor_size));
675 icp_entry->log_root_descriptor_size =
676 avb_be32toh(icp_entry->log_root_descriptor_size);
677 if (icp_entry->log_root_descriptor_size < AVB_AFTL_MIN_TLRD_SIZE ||
678 icp_entry->log_root_descriptor_size > AVB_AFTL_MAX_TLRD_SIZE) {
679 avb_error("Invalid TrillianLogRootDescriptor size.\n");
680 avb_free(icp_entry);
681 return NULL;
682 }
683 *aftl_blob += avb_aftl_member_size(AftlIcpEntry, log_root_descriptor_size);
684 parsed_size += avb_aftl_member_size(AftlIcpEntry, log_root_descriptor_size);
685 /* Copy in the FirmwareInfo leaf size field. */
686 avb_memcpy(&(icp_entry->fw_info_leaf_size),
687 *aftl_blob,
688 avb_aftl_member_size(AftlIcpEntry, fw_info_leaf_size));
689 icp_entry->fw_info_leaf_size = avb_be32toh(icp_entry->fw_info_leaf_size);
690 if (icp_entry->fw_info_leaf_size == 0 ||
691 icp_entry->fw_info_leaf_size > AVB_AFTL_MAX_FW_INFO_SIZE) {
692 avb_error("Invalid FirmwareInfo leaf size.\n");
693 avb_free(icp_entry);
694 return NULL;
695 }
696 *aftl_blob += avb_aftl_member_size(AftlIcpEntry, fw_info_leaf_size);
697 parsed_size += avb_aftl_member_size(AftlIcpEntry, fw_info_leaf_size);
698 /* Copy the log root signature size field. */
699 avb_memcpy(&(icp_entry->log_root_sig_size),
700 *aftl_blob,
701 avb_aftl_member_size(AftlIcpEntry, log_root_sig_size));
702 icp_entry->log_root_sig_size = avb_be16toh(icp_entry->log_root_sig_size);
703 if (icp_entry->log_root_sig_size != AVB_AFTL_SIGNATURE_SIZE) {
704 avb_error("Invalid log root signature size.\n");
705 avb_free(icp_entry);
706 return NULL;
707 }
708 *aftl_blob += avb_aftl_member_size(AftlIcpEntry, log_root_sig_size);
709 parsed_size += avb_aftl_member_size(AftlIcpEntry, log_root_sig_size);
710 /* Copy the inclusion proof hash count field. */
711 avb_memcpy(&(icp_entry->proof_hash_count),
712 *aftl_blob,
713 avb_aftl_member_size(AftlIcpEntry, proof_hash_count));
714 *aftl_blob += avb_aftl_member_size(AftlIcpEntry, proof_hash_count);
715 parsed_size += avb_aftl_member_size(AftlIcpEntry, proof_hash_count);
716 /* Copy the inclusion proof size field. */
717 avb_memcpy(&(icp_entry->inc_proof_size),
718 *aftl_blob,
719 avb_aftl_member_size(AftlIcpEntry, inc_proof_size));
720 icp_entry->inc_proof_size = avb_be32toh(icp_entry->inc_proof_size);
721 if (icp_entry->inc_proof_size !=
722 icp_entry->proof_hash_count * AVB_AFTL_HASH_SIZE) {
723 avb_error("Invalid inclusion proof size.\n");
724 avb_free(icp_entry);
725 return NULL;
726 }
727 *aftl_blob += avb_aftl_member_size(AftlIcpEntry, inc_proof_size);
728 parsed_size += avb_aftl_member_size(AftlIcpEntry, inc_proof_size);
729 /* Copy in the log server URL from the blob. */
730 if (!avb_safe_add_to(&parsed_size, icp_entry->log_url_size)) {
731 avb_error("Invalid URL size.\n");
732 free_aftl_icp_entry(icp_entry);
733 return NULL;
734 }
735 if (parsed_size > *remaining_size) {
736 avb_error("Invalid AftlDescriptor.\n");
737 avb_free(icp_entry);
738 return NULL;
739 }
740 icp_entry->log_url = (uint8_t*)avb_calloc(icp_entry->log_url_size);
741 if (!icp_entry->log_url) {
742 avb_error("Failure to allocate URL.\n");
743 free_aftl_icp_entry(icp_entry);
744 return NULL;
745 }
746 avb_memcpy(icp_entry->log_url, *aftl_blob, icp_entry->log_url_size);
747 *aftl_blob += icp_entry->log_url_size;
748
749 /* Populate the TrillianLogRootDescriptor elements. */
750 if (!avb_safe_add_to(&parsed_size, icp_entry->log_root_descriptor_size)) {
751 avb_error("Invalid TrillianLogRootDescriptor size.\n");
752 free_aftl_icp_entry(icp_entry);
753 return NULL;
754 }
755 if (parsed_size > *remaining_size) {
756 avb_error("Invalid AftlDescriptor.\n");
757 free_aftl_icp_entry(icp_entry);
758 return NULL;
759 }
760 if (!parse_trillian_log_root_descriptor(
761 icp_entry, aftl_blob, icp_entry->log_root_descriptor_size)) {
762 return NULL;
763 }
764
765 /* Populate the FirmwareInfo elements. */
766 if (!avb_safe_add_to(&parsed_size, icp_entry->fw_info_leaf_size)) {
767 avb_error("Invalid FirmwareInfo leaf size.\n");
768 free_aftl_icp_entry(icp_entry);
769 return NULL;
770 }
771 if (parsed_size > *remaining_size) {
772 avb_error("Invalid AftlDescriptor.\n");
773 free_aftl_icp_entry(icp_entry);
774 return NULL;
775 }
776 if (!parse_firmware_info(icp_entry, aftl_blob)) return NULL;
777
778 /* Allocate and copy the log root signature from the blob. */
779 if (!avb_safe_add_to(&parsed_size, icp_entry->log_root_sig_size)) {
780 avb_error("Invalid log root signature size.\n");
781 free_aftl_icp_entry(icp_entry);
782 return NULL;
783 }
784 if (parsed_size > *remaining_size) {
785 avb_error("Invalid AftlDescriptor.\n");
786 free_aftl_icp_entry(icp_entry);
787 return NULL;
788 }
789
790 icp_entry->log_root_signature =
791 (uint8_t*)avb_calloc(icp_entry->log_root_sig_size);
792 if (!icp_entry->log_root_signature) {
793 free_aftl_icp_entry(icp_entry);
794 return NULL;
795 }
796 avb_memcpy(
797 icp_entry->log_root_signature, *aftl_blob, icp_entry->log_root_sig_size);
798 *aftl_blob += icp_entry->log_root_sig_size;
799
800 if (!avb_safe_add_to(&parsed_size, icp_entry->inc_proof_size)) {
801 avb_error("Invalid inclusion proof size.\n");
802 free_aftl_icp_entry(icp_entry);
803 return NULL;
804 }
805 if (parsed_size > *remaining_size) {
806 avb_error("Invalid AftlDescriptor.\n");
807 free_aftl_icp_entry(icp_entry);
808 return NULL;
809 }
810
811 /* Finally, copy the proof hash data from the blob to the AftlDescriptor. */
812 avb_memcpy(icp_entry->proofs, *aftl_blob, icp_entry->inc_proof_size);
813 *aftl_blob += icp_entry->inc_proof_size;
814 *remaining_size -= parsed_size;
815
816 return icp_entry;
817 }
818
819 /* Allocate and parse an AftlDescriptor object out of binary data. */
parse_aftl_descriptor(uint8_t * aftl_blob,size_t aftl_blob_size)820 AftlDescriptor* parse_aftl_descriptor(uint8_t* aftl_blob,
821 size_t aftl_blob_size) {
822 AftlDescriptor* aftl_descriptor;
823 AftlIcpHeader* icp_header;
824 size_t aftl_descriptor_size;
825 size_t i;
826 size_t remaining_size;
827
828 /* Ensure the blob is at least large enough for an AftlIcpHeader */
829 avb_assert(aftl_blob_size >= sizeof(AftlIcpHeader));
830 icp_header = (AftlIcpHeader*)aftl_blob;
831 /* Check for the magic value for an AftlIcpHeader. */
832 if (icp_header->magic != AVB_AFTL_MAGIC) {
833 avb_error("Invalid magic number\n");
834 return NULL;
835 }
836 /* Extract the size out of the header. */
837 aftl_descriptor_size = avb_be32toh(icp_header->aftl_descriptor_size);
838 if (aftl_descriptor_size > AVB_AFTL_MAX_AFTL_DESCRIPTOR_SIZE) return NULL;
839 avb_assert(aftl_descriptor_size >= sizeof(AftlIcpHeader) &&
840 aftl_descriptor_size < AVB_AFTL_MAX_AFTL_DESCRIPTOR_SIZE);
841 aftl_descriptor = (AftlDescriptor*)avb_calloc(sizeof(AftlDescriptor));
842 if (!aftl_descriptor) {
843 avb_error("Failed allocation for AftlDescriptor.\n");
844 return NULL;
845 }
846 /* Copy the header bytes directly from the aftl_blob. */
847 avb_memcpy(&(aftl_descriptor->header), aftl_blob, sizeof(AftlIcpHeader));
848 /* Fix endianness. */
849 aftl_descriptor->header.required_icp_version_major =
850 avb_be32toh(aftl_descriptor->header.required_icp_version_major);
851 aftl_descriptor->header.required_icp_version_minor =
852 avb_be32toh(aftl_descriptor->header.required_icp_version_minor);
853 aftl_descriptor->header.aftl_descriptor_size =
854 avb_be32toh(aftl_descriptor->header.aftl_descriptor_size);
855 aftl_descriptor->header.icp_count =
856 avb_be16toh(aftl_descriptor->header.icp_count);
857 /* Allocate memory for the entry array */
858 aftl_descriptor->entries = (AftlIcpEntry**)avb_calloc(
859 sizeof(AftlIcpEntry*) * aftl_descriptor->header.icp_count);
860 if (!aftl_descriptor->entries) {
861 avb_error("Failed allocation for AftlIcpEntry array.\n");
862 avb_free(aftl_descriptor);
863 return NULL;
864 }
865
866 /* Jump past the header and parse out each AftlIcpEntry. */
867 aftl_blob += sizeof(AftlIcpHeader);
868 remaining_size = aftl_blob_size - sizeof(AftlIcpHeader);
869 for (i = 0; i < aftl_descriptor->header.icp_count && remaining_size > 0;
870 i++) {
871 aftl_descriptor->entries[i] = parse_icp_entry(&aftl_blob, &remaining_size);
872 }
873
874 return aftl_descriptor;
875 }
876
877 /* Free an AftlIcpEntry and each allocated sub-element. */
free_aftl_icp_entry(AftlIcpEntry * icp_entry)878 void free_aftl_icp_entry(AftlIcpEntry* icp_entry) {
879 /* Ensure the AftlIcpEntry exists before attempting to free it. */
880 if (icp_entry) {
881 /* Free the log_url and log_root_signature elements if they exist. */
882 if (icp_entry->log_url) avb_free(icp_entry->log_url);
883 if (icp_entry->log_root_signature) avb_free(icp_entry->log_root_signature);
884 /* Free the FirmwareInfo elements if they exist. */
885 if (icp_entry->fw_info_leaf.json_data)
886 avb_free(icp_entry->fw_info_leaf.json_data);
887 if (icp_entry->fw_info_leaf.vbmeta_hash)
888 avb_free(icp_entry->fw_info_leaf.vbmeta_hash);
889 /* Free the TrillianLogRoot elements if they exist. */
890 if (icp_entry->log_root_descriptor.metadata)
891 avb_free(icp_entry->log_root_descriptor.metadata);
892 if (icp_entry->log_root_descriptor.root_hash)
893 avb_free(icp_entry->log_root_descriptor.root_hash);
894 /* Finally, free the AftlIcpEntry. */
895 avb_free(icp_entry);
896 }
897 }
898
899 /* Free the AftlDescriptor and each allocated sub-element. */
free_aftl_descriptor(AftlDescriptor * aftl_descriptor)900 void free_aftl_descriptor(AftlDescriptor* aftl_descriptor) {
901 size_t i;
902
903 /* Ensure the descriptor exists before attempting to free it. */
904 if (!aftl_descriptor) {
905 return;
906 }
907 /* Free the entry array. */
908 if (aftl_descriptor->entries) {
909 /* Walk through each entry, freeing each one. */
910 for (i = 0; i < aftl_descriptor->header.icp_count; i++) {
911 if (aftl_descriptor->entries[i]) {
912 free_aftl_icp_entry(aftl_descriptor->entries[i]);
913 }
914 }
915 avb_free(aftl_descriptor->entries);
916 }
917 avb_free(aftl_descriptor);
918 }
919