• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &timestamp, 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