~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 24f8519ff609134e31b30357ace96290fb1ecfd6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/* SPDX-License-Identifier: MIT */
/*
 * Copyright (C) 2016 The Android Open Source Project
 */

#if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
#error "Never include this file directly, include libavb.h instead."
#endif

#ifndef AVB_VBMETA_IMAGE_H_
#define AVB_VBMETA_IMAGE_H_

#include "avb_sysdeps.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "avb_crypto.h"
#include "avb_descriptor.h"

/* Size of the vbmeta image header. */
#define AVB_VBMETA_IMAGE_HEADER_SIZE 256

/* Magic for the vbmeta image header. */
#define AVB_MAGIC "AVB0"
#define AVB_MAGIC_LEN 4

/* Maximum size of the release string including the terminating NUL byte. */
#define AVB_RELEASE_STRING_SIZE 48

/* Flags for the vbmeta image.
 *
 * AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED: If this flag is set,
 * hashtree image verification will be disabled.
 *
 * AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED: If this flag is set,
 * verification will be disabled and descriptors will not be parsed.
 */
typedef enum {
  AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED = (1 << 0),
  AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED = (1 << 1)
} AvbVBMetaImageFlags;

/* Binary format for header of the vbmeta image.
 *
 * The vbmeta image consists of three blocks:
 *
 *  +-----------------------------------------+
 *  | Header data - fixed size                |
 *  +-----------------------------------------+
 *  | Authentication data - variable size     |
 *  +-----------------------------------------+
 *  | Auxiliary data - variable size          |
 *  +-----------------------------------------+
 *
 * The "Header data" block is described by this struct and is always
 * |AVB_VBMETA_IMAGE_HEADER_SIZE| bytes long.
 *
 * The "Authentication data" block is |authentication_data_block_size|
 * bytes long and contains the hash and signature used to authenticate
 * the vbmeta image. The type of the hash and signature is defined by
 * the |algorithm_type| field.
 *
 * The "Auxiliary data" is |auxiliary_data_block_size| bytes long and
 * contains the auxiliary data including the public key used to make
 * the signature and descriptors.
 *
 * The public key is at offset |public_key_offset| with size
 * |public_key_size| in this block. The size of the public key data is
 * defined by the |algorithm_type| field. The format of the public key
 * data is described in the |AvbRSAPublicKeyHeader| struct.
 *
 * The descriptors starts at |descriptors_offset| from the beginning
 * of the "Auxiliary Data" block and take up |descriptors_size|
 * bytes. Each descriptor is stored as a |AvbDescriptor| with tag and
 * number of bytes following. The number of descriptors can be
 * determined by walking this data until |descriptors_size| is
 * exhausted.
 *
 * The size of each of the "Authentication data" and "Auxiliary data"
 * blocks must be divisible by 64. This is to ensure proper alignment.
 *
 * Descriptors are free-form blocks stored in a part of the vbmeta
 * image subject to the same integrity checks as the rest of the
 * image. See the documentation for |AvbDescriptor| for well-known
 * descriptors. See avb_descriptor_foreach() for a convenience
 * function to iterate over descriptors.
 *
 * This struct is versioned, see the |required_libavb_version_major|
 * and |required_libavb_version_minor| fields. This represents the
 * minimum version of libavb required to verify the header and depends
 * on the features (e.g. algorithms, descriptors) used. Note that this
 * may be 1.0 even if generated by an avbtool from 1.4 but where no
 * features introduced after 1.0 has been used. See the "Versioning
 * and compatibility" section in the README.md file for more details.
 *
 * All fields are stored in network byte order when serialized. To
 * generate a copy with fields swapped to native byte order, use the
 * function avb_vbmeta_image_header_to_host_byte_order().
 *
 * Before reading and/or using any of this data, you MUST verify it
 * using avb_vbmeta_image_verify() and reject it unless it's signed by
 * a known good public key.
 */
typedef struct AvbVBMetaImageHeader {
  /*   0: Four bytes equal to "AVB0" (AVB_MAGIC). */
  uint8_t magic[AVB_MAGIC_LEN];

  /*   4: The major version of libavb required for this header. */
  uint32_t required_libavb_version_major;
  /*   8: The minor version of libavb required for this header. */
  uint32_t required_libavb_version_minor;

  /*  12: The size of the signature block. */
  uint64_t authentication_data_block_size;
  /*  20: The size of the auxiliary data block. */
  uint64_t auxiliary_data_block_size;

  /*  28: The verification algorithm used, see |AvbAlgorithmType| enum. */
  uint32_t algorithm_type;

  /*  32: Offset into the "Authentication data" block of hash data. */
  uint64_t hash_offset;
  /*  40: Length of the hash data. */
  uint64_t hash_size;

  /*  48: Offset into the "Authentication data" block of signature data. */
  uint64_t signature_offset;
  /*  56: Length of the signature data. */
  uint64_t signature_size;

  /*  64: Offset into the "Auxiliary data" block of public key data. */
  uint64_t public_key_offset;
  /*  72: Length of the public key data. */
  uint64_t public_key_size;

  /*  80: Offset into the "Auxiliary data" block of public key metadata. */
  uint64_t public_key_metadata_offset;
  /*  88: Length of the public key metadata. Must be set to zero if there
   *  is no public key metadata.
   */
  uint64_t public_key_metadata_size;

  /*  96: Offset into the "Auxiliary data" block of descriptor data. */
  uint64_t descriptors_offset;
  /* 104: Length of descriptor data. */
  uint64_t descriptors_size;

  /* 112: The rollback index which can be used to prevent rollback to
   *  older versions.
   */
  uint64_t rollback_index;

  /* 120: Flags from the AvbVBMetaImageFlags enumeration. This must be
   * set to zero if the vbmeta image is not a top-level image.
   */
  uint32_t flags;

  /* 124: Reserved to ensure |release_string| start on a 16-byte
   * boundary. Must be set to zeroes.
   */
  uint8_t reserved0[4];

  /* 128: The release string from avbtool, e.g. "avbtool 1.0.0" or
   * "avbtool 1.0.0 xyz_board Git-234abde89". Is guaranteed to be NUL
   * terminated. Applications must not make assumptions about how this
   * string is formatted.
   */
  uint8_t release_string[AVB_RELEASE_STRING_SIZE];

  /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE
   * bytes. This must be set to zeroes.
   */
  uint8_t reserved[80];
} AVB_ATTR_PACKED AvbVBMetaImageHeader;

/* Copies |src| to |dest|, byte-swapping fields in the process.
 *
 * Make sure you've verified |src| using avb_vbmeta_image_verify()
 * before accessing the data and/or using this function.
 */
void avb_vbmeta_image_header_to_host_byte_order(const AvbVBMetaImageHeader* src,
                                                AvbVBMetaImageHeader* dest);

/* Return codes used in avb_vbmeta_image_verify().
 *
 * AVB_VBMETA_VERIFY_RESULT_OK is returned if the vbmeta image header
 * is valid, the hash is correct and the signature is correct. Keep in
 * mind that you still need to check that you know the public key used
 * to sign the image, see avb_vbmeta_image_verify() for details.
 *
 * AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED is returned if the vbmeta
 * image header is valid but there is no signature or hash.
 *
 * AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER is returned if the
 * header of the vbmeta image is invalid, for example, invalid magic
 * or inconsistent data.
 *
 * AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION is returned if a) the
 * vbmeta image requires a minimum version of libavb which exceeds the
 * version of libavb used; or b) the vbmeta image major version
 * differs from the major version of libavb in use.
 *
 * AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH is returned if the hash
 * stored in the "Authentication data" block does not match the
 * calculated hash.
 *
 * AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH is returned if the
 * signature stored in the "Authentication data" block is invalid or
 * doesn't match the public key stored in the vbmeta image.
 */
typedef enum {
  AVB_VBMETA_VERIFY_RESULT_OK,
  AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED,
  AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
  AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION,
  AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH,
  AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH,
} AvbVBMetaVerifyResult;

/* Get a textual representation of |result|. */
const char* avb_vbmeta_verify_result_to_string(AvbVBMetaVerifyResult result);

/* Checks that vbmeta image at |data| of size |length| is a valid
 * vbmeta image. The complete contents of the vbmeta image must be
 * passed in. It's fine if |length| is bigger than the actual image,
 * typically callers of this function will load the entire contents of
 * the 'vbmeta_a' or 'vbmeta_b' partition and pass in its length (for
 * example, 1 MiB).
 *
 * See the |AvbVBMetaImageHeader| struct for information about the
 * three blocks (header, authentication, auxiliary) that make up a
 * vbmeta image.
 *
 * If the function returns |AVB_VBMETA_VERIFY_RESULT_OK| and
 * |out_public_key_data| is non-NULL, it will be set to point inside
 * |data| for where the serialized public key data is stored and
 * |out_public_key_length|, if non-NULL, will be set to the length of
 * the public key data. If there is no public key in the metadata then
 * |out_public_key_data| is set to NULL.
 *
 * See the |AvbVBMetaVerifyResult| enum for possible return values.
 *
 * VERY IMPORTANT:
 *
 *   1. Even if |AVB_VBMETA_VERIFY_RESULT_OK| is returned, you still
 *      need to check that the public key embedded in the image
 *      matches a known key! You can use 'avbtool extract_public_key'
 *      to extract the key (at build time, then store it along your
 *      code) and compare it to what is returned in
 *      |out_public_key_data|.
 *
 *   2. You need to check the |rollback_index| field against a stored
 *      value in NVRAM and reject the vbmeta image if the value in
 *      NVRAM is bigger than |rollback_index|. You must also update
 *      the value stored in NVRAM to the smallest value of
 *      |rollback_index| field from boot images in all bootable and
 *      authentic slots marked as GOOD.
 *
 * This is a low-level function to only verify the vbmeta data - you
 * are likely looking for avb_slot_verify() instead for verifying
 * integrity data for a whole set of partitions.
 */
AvbVBMetaVerifyResult avb_vbmeta_image_verify(
    const uint8_t* data,
    size_t length,
    const uint8_t** out_public_key_data,
    size_t* out_public_key_length) AVB_ATTR_WARN_UNUSED_RESULT;

#ifdef __cplusplus
}
#endif

#endif /* AVB_VBMETA_IMAGE_H_ */