• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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_atx/avb_atx_validate.h"
26 
27 #include "libavb/avb_rsa.h"
28 #include "libavb/avb_sha.h"
29 #include "libavb/avb_sysdeps.h"
30 #include "libavb/avb_util.h"
31 
32 /* Computes the SHA256 |hash| of |length| bytes of |data|. */
sha256(const uint8_t * data,uint32_t length,uint8_t hash[AVB_SHA256_DIGEST_SIZE])33 static void sha256(const uint8_t* data,
34                    uint32_t length,
35                    uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
36   AvbSHA256Ctx context;
37   avb_sha256_init(&context);
38   avb_sha256_update(&context, data, length);
39   uint8_t* tmp = avb_sha256_final(&context);
40   avb_memcpy(hash, tmp, AVB_SHA256_DIGEST_SIZE);
41 }
42 
43 /* Computes the SHA512 |hash| of |length| bytes of |data|. */
sha512(const uint8_t * data,uint32_t length,uint8_t hash[AVB_SHA512_DIGEST_SIZE])44 static void sha512(const uint8_t* data,
45                    uint32_t length,
46                    uint8_t hash[AVB_SHA512_DIGEST_SIZE]) {
47   AvbSHA512Ctx context;
48   avb_sha512_init(&context);
49   avb_sha512_update(&context, data, length);
50   uint8_t* tmp = avb_sha512_final(&context);
51   avb_memcpy(hash, tmp, AVB_SHA512_DIGEST_SIZE);
52 }
53 
54 /* Computes the SHA256 |hash| of a NUL-terminated |str|. */
sha256_str(const char * str,uint8_t hash[AVB_SHA256_DIGEST_SIZE])55 static void sha256_str(const char* str, uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
56   sha256((const uint8_t*)str, avb_strlen(str), hash);
57 }
58 
59 /* Verifies structure and |expected_hash| of permanent |attributes|. */
verify_permanent_attributes(const AvbAtxPermanentAttributes * attributes,uint8_t expected_hash[AVB_SHA256_DIGEST_SIZE])60 static bool verify_permanent_attributes(
61     const AvbAtxPermanentAttributes* attributes,
62     uint8_t expected_hash[AVB_SHA256_DIGEST_SIZE]) {
63   uint8_t hash[AVB_SHA256_DIGEST_SIZE];
64 
65   if (attributes->version != 1) {
66     avb_error("Unsupported permanent attributes version.\n");
67     return false;
68   }
69   sha256((const uint8_t*)attributes, sizeof(AvbAtxPermanentAttributes), hash);
70   if (0 != avb_safe_memcmp(hash, expected_hash, AVB_SHA256_DIGEST_SIZE)) {
71     avb_error("Invalid permanent attributes.\n");
72     return false;
73   }
74   return true;
75 }
76 
77 /* Verifies the format, key version, usage, and signature of a certificate. */
verify_certificate(AvbAtxCertificate * certificate,uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],uint64_t minimum_key_version,uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE])78 static bool verify_certificate(AvbAtxCertificate* certificate,
79                                uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
80                                uint64_t minimum_key_version,
81                                uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE]) {
82   const AvbAlgorithmData* algorithm_data;
83   uint8_t certificate_hash[AVB_SHA512_DIGEST_SIZE];
84 
85   if (certificate->signed_data.version != 1) {
86     avb_error("Unsupported certificate format.\n");
87     return false;
88   }
89   algorithm_data = avb_get_algorithm_data(AVB_ALGORITHM_TYPE_SHA512_RSA4096);
90   sha512((const uint8_t*)&certificate->signed_data,
91          sizeof(AvbAtxCertificateSignedData),
92          certificate_hash);
93   if (!avb_rsa_verify(authority,
94                       AVB_ATX_PUBLIC_KEY_SIZE,
95                       certificate->signature,
96                       AVB_RSA4096_NUM_BYTES,
97                       certificate_hash,
98                       AVB_SHA512_DIGEST_SIZE,
99                       algorithm_data->padding,
100                       algorithm_data->padding_len)) {
101     avb_error("Invalid certificate signature.\n");
102     return false;
103   }
104   if (certificate->signed_data.key_version < minimum_key_version) {
105     avb_error("Key rollback detected.\n");
106     return false;
107   }
108   if (0 != avb_safe_memcmp(certificate->signed_data.usage,
109                            expected_usage,
110                            AVB_SHA256_DIGEST_SIZE)) {
111     avb_error("Invalid certificate usage.\n");
112     return false;
113   }
114   return true;
115 }
116 
117 /* Verifies signature and fields of a PIK certificate. */
verify_pik_certificate(AvbAtxCertificate * certificate,uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],uint64_t minimum_version)118 static bool verify_pik_certificate(AvbAtxCertificate* certificate,
119                                    uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
120                                    uint64_t minimum_version) {
121   uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
122 
123   sha256_str("com.google.android.things.vboot.ca", expected_usage);
124   if (!verify_certificate(
125           certificate, authority, minimum_version, expected_usage)) {
126     avb_error("Invalid PIK certificate.\n");
127     return false;
128   }
129   return true;
130 }
131 
132 /* Verifies signature and fields of a PSK certificate. */
verify_psk_certificate(AvbAtxCertificate * certificate,uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],uint64_t minimum_version,uint8_t product_id[AVB_ATX_PRODUCT_ID_SIZE])133 static bool verify_psk_certificate(
134     AvbAtxCertificate* certificate,
135     uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
136     uint64_t minimum_version,
137     uint8_t product_id[AVB_ATX_PRODUCT_ID_SIZE]) {
138   uint8_t expected_subject[AVB_SHA256_DIGEST_SIZE];
139   uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
140 
141   sha256_str("com.google.android.things.vboot", expected_usage);
142   if (!verify_certificate(
143           certificate, authority, minimum_version, expected_usage)) {
144     avb_error("Invalid PSK certificate.\n");
145     return false;
146   }
147   sha256(product_id, AVB_ATX_PRODUCT_ID_SIZE, expected_subject);
148   if (0 != avb_safe_memcmp(certificate->signed_data.subject,
149                            expected_subject,
150                            AVB_SHA256_DIGEST_SIZE)) {
151     avb_error("Product ID mismatch.\n");
152     return false;
153   }
154   return true;
155 }
156 
avb_atx_validate_vbmeta_public_key(AvbOps * ops,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_is_trusted)157 AvbIOResult avb_atx_validate_vbmeta_public_key(
158     AvbOps* ops,
159     const uint8_t* public_key_data,
160     size_t public_key_length,
161     const uint8_t* public_key_metadata,
162     size_t public_key_metadata_length,
163     bool* out_is_trusted) {
164   AvbIOResult result = AVB_IO_RESULT_OK;
165   AvbAtxPermanentAttributes permanent_attributes;
166   uint8_t permanent_attributes_hash[AVB_SHA256_DIGEST_SIZE];
167   AvbAtxPublicKeyMetadata metadata;
168   uint64_t minimum_version;
169 
170   /* Be pessimistic so we can exit early without having to remember to clear.
171    */
172   *out_is_trusted = false;
173 
174   /* Read and verify permanent attributes. */
175   result = ops->atx_ops->read_permanent_attributes(ops->atx_ops,
176                                                    &permanent_attributes);
177   if (result != AVB_IO_RESULT_OK) {
178     avb_error("Failed to read permanent attributes.\n");
179     return result;
180   }
181   result = ops->atx_ops->read_permanent_attributes_hash(
182       ops->atx_ops, permanent_attributes_hash);
183   if (result != AVB_IO_RESULT_OK) {
184     avb_error("Failed to read permanent attributes hash.\n");
185     return result;
186   }
187   if (!verify_permanent_attributes(&permanent_attributes,
188                                    permanent_attributes_hash)) {
189     return AVB_IO_RESULT_OK;
190   }
191 
192   /* Sanity check public key metadata. */
193   if (public_key_metadata_length != sizeof(AvbAtxPublicKeyMetadata)) {
194     avb_error("Invalid public key metadata.\n");
195     return AVB_IO_RESULT_OK;
196   }
197   avb_memcpy(&metadata, public_key_metadata, sizeof(AvbAtxPublicKeyMetadata));
198   if (metadata.version != 1) {
199     avb_error("Unsupported public key metadata.\n");
200     return AVB_IO_RESULT_OK;
201   }
202 
203   /* Verify the PIK certificate. */
204   result = ops->read_rollback_index(
205       ops, AVB_ATX_PIK_VERSION_LOCATION, &minimum_version);
206   if (result != AVB_IO_RESULT_OK) {
207     avb_error("Failed to read PIK minimum version.\n");
208     return result;
209   }
210   if (!verify_pik_certificate(&metadata.product_intermediate_key_certificate,
211                               permanent_attributes.product_root_public_key,
212                               minimum_version)) {
213     return AVB_IO_RESULT_OK;
214   }
215 
216   /* Verify the PSK certificate. */
217   result = ops->read_rollback_index(
218       ops, AVB_ATX_PSK_VERSION_LOCATION, &minimum_version);
219   if (result != AVB_IO_RESULT_OK) {
220     avb_error("Failed to read PSK minimum version.\n");
221     return result;
222   }
223   if (!verify_psk_certificate(
224           &metadata.product_signing_key_certificate,
225           metadata.product_intermediate_key_certificate.signed_data.public_key,
226           minimum_version,
227           permanent_attributes.product_id)) {
228     return AVB_IO_RESULT_OK;
229   }
230 
231   /* Verify the PSK is the same key that verified vbmeta. */
232   if (public_key_length != AVB_ATX_PUBLIC_KEY_SIZE) {
233     avb_error("Public key length mismatch.\n");
234     return AVB_IO_RESULT_OK;
235   }
236   if (0 != avb_safe_memcmp(
237                metadata.product_signing_key_certificate.signed_data.public_key,
238                public_key_data,
239                AVB_ATX_PUBLIC_KEY_SIZE)) {
240     avb_error("Public key mismatch.\n");
241     return AVB_IO_RESULT_OK;
242   }
243 
244   *out_is_trusted = true;
245   return AVB_IO_RESULT_OK;
246 }
247