xref: /rk3399_rockchip-uboot/lib/avb/libavb_atx/avb_atx_validate.c (revision 37a7bc39c0a3beca986e8c1c85d1dd6b9921e313)
1*37a7bc39SJason Zhu /*
2*37a7bc39SJason Zhu  * Copyright (C) 2016 The Android Open Source Project
3*37a7bc39SJason Zhu  *
4*37a7bc39SJason Zhu  * Permission is hereby granted, free of charge, to any person
5*37a7bc39SJason Zhu  * obtaining a copy of this software and associated documentation
6*37a7bc39SJason Zhu  * files (the "Software"), to deal in the Software without
7*37a7bc39SJason Zhu  * restriction, including without limitation the rights to use, copy,
8*37a7bc39SJason Zhu  * modify, merge, publish, distribute, sublicense, and/or sell copies
9*37a7bc39SJason Zhu  * of the Software, and to permit persons to whom the Software is
10*37a7bc39SJason Zhu  * furnished to do so, subject to the following conditions:
11*37a7bc39SJason Zhu  *
12*37a7bc39SJason Zhu  * The above copyright notice and this permission notice shall be
13*37a7bc39SJason Zhu  * included in all copies or substantial portions of the Software.
14*37a7bc39SJason Zhu  *
15*37a7bc39SJason Zhu  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*37a7bc39SJason Zhu  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*37a7bc39SJason Zhu  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*37a7bc39SJason Zhu  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19*37a7bc39SJason Zhu  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20*37a7bc39SJason Zhu  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*37a7bc39SJason Zhu  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*37a7bc39SJason Zhu  * SOFTWARE.
23*37a7bc39SJason Zhu  */
24*37a7bc39SJason Zhu 
25*37a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h>
26*37a7bc39SJason Zhu 
27*37a7bc39SJason Zhu #include <android_avb/avb_rsa.h>
28*37a7bc39SJason Zhu #include <android_avb/avb_sha.h>
29*37a7bc39SJason Zhu #include <android_avb/avb_sysdeps.h>
30*37a7bc39SJason Zhu #include <android_avb/avb_util.h>
31*37a7bc39SJason Zhu 
32*37a7bc39SJason Zhu /* Computes the SHA256 |hash| of |length| bytes of |data|. */
33*37a7bc39SJason Zhu static void sha256(const uint8_t* data,
34*37a7bc39SJason Zhu                    uint32_t length,
35*37a7bc39SJason Zhu                    uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
36*37a7bc39SJason Zhu   AvbSHA256Ctx context;
37*37a7bc39SJason Zhu   avb_sha256_init(&context);
38*37a7bc39SJason Zhu   avb_sha256_update(&context, data, length);
39*37a7bc39SJason Zhu   uint8_t* tmp = avb_sha256_final(&context);
40*37a7bc39SJason Zhu   avb_memcpy(hash, tmp, AVB_SHA256_DIGEST_SIZE);
41*37a7bc39SJason Zhu }
42*37a7bc39SJason Zhu 
43*37a7bc39SJason Zhu /* Computes the SHA512 |hash| of |length| bytes of |data|. */
44*37a7bc39SJason Zhu static void sha512(const uint8_t* data,
45*37a7bc39SJason Zhu                    uint32_t length,
46*37a7bc39SJason Zhu                    uint8_t hash[AVB_SHA512_DIGEST_SIZE]) {
47*37a7bc39SJason Zhu   AvbSHA512Ctx context;
48*37a7bc39SJason Zhu   avb_sha512_init(&context);
49*37a7bc39SJason Zhu   avb_sha512_update(&context, data, length);
50*37a7bc39SJason Zhu   uint8_t* tmp = avb_sha512_final(&context);
51*37a7bc39SJason Zhu   avb_memcpy(hash, tmp, AVB_SHA512_DIGEST_SIZE);
52*37a7bc39SJason Zhu }
53*37a7bc39SJason Zhu 
54*37a7bc39SJason Zhu /* Computes the SHA256 |hash| of a NUL-terminated |str|. */
55*37a7bc39SJason Zhu static void sha256_str(const char* str, uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
56*37a7bc39SJason Zhu   sha256((const uint8_t*)str, avb_strlen(str), hash);
57*37a7bc39SJason Zhu }
58*37a7bc39SJason Zhu 
59*37a7bc39SJason Zhu /* Verifies structure and |expected_hash| of permanent |attributes|. */
60*37a7bc39SJason Zhu static bool verify_permanent_attributes(
61*37a7bc39SJason Zhu     const AvbAtxPermanentAttributes* attributes,
62*37a7bc39SJason Zhu     uint8_t expected_hash[AVB_SHA256_DIGEST_SIZE]) {
63*37a7bc39SJason Zhu   uint8_t hash[AVB_SHA256_DIGEST_SIZE];
64*37a7bc39SJason Zhu 
65*37a7bc39SJason Zhu   if (attributes->version != 1) {
66*37a7bc39SJason Zhu     avb_error("Unsupported permanent attributes version.\n");
67*37a7bc39SJason Zhu     return false;
68*37a7bc39SJason Zhu   }
69*37a7bc39SJason Zhu   sha256((const uint8_t*)attributes, sizeof(AvbAtxPermanentAttributes), hash);
70*37a7bc39SJason Zhu   if (0 != avb_safe_memcmp(hash, expected_hash, AVB_SHA256_DIGEST_SIZE)) {
71*37a7bc39SJason Zhu     avb_error("Invalid permanent attributes.\n");
72*37a7bc39SJason Zhu     return false;
73*37a7bc39SJason Zhu   }
74*37a7bc39SJason Zhu   return true;
75*37a7bc39SJason Zhu }
76*37a7bc39SJason Zhu 
77*37a7bc39SJason Zhu /* Verifies the format, key version, usage, and signature of a certificate. */
78*37a7bc39SJason Zhu static bool verify_certificate(AvbAtxCertificate* certificate,
79*37a7bc39SJason Zhu                                uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
80*37a7bc39SJason Zhu                                uint64_t minimum_key_version,
81*37a7bc39SJason Zhu                                uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE]) {
82*37a7bc39SJason Zhu   const AvbAlgorithmData* algorithm_data;
83*37a7bc39SJason Zhu   uint8_t certificate_hash[AVB_SHA512_DIGEST_SIZE];
84*37a7bc39SJason Zhu 
85*37a7bc39SJason Zhu   if (certificate->signed_data.version != 1) {
86*37a7bc39SJason Zhu     avb_error("Unsupported certificate format.\n");
87*37a7bc39SJason Zhu     return false;
88*37a7bc39SJason Zhu   }
89*37a7bc39SJason Zhu   algorithm_data = avb_get_algorithm_data(AVB_ALGORITHM_TYPE_SHA512_RSA4096);
90*37a7bc39SJason Zhu   sha512((const uint8_t*)&certificate->signed_data,
91*37a7bc39SJason Zhu          sizeof(AvbAtxCertificateSignedData),
92*37a7bc39SJason Zhu          certificate_hash);
93*37a7bc39SJason Zhu   if (!avb_rsa_verify(authority,
94*37a7bc39SJason Zhu                       AVB_ATX_PUBLIC_KEY_SIZE,
95*37a7bc39SJason Zhu                       certificate->signature,
96*37a7bc39SJason Zhu                       AVB_RSA4096_NUM_BYTES,
97*37a7bc39SJason Zhu                       certificate_hash,
98*37a7bc39SJason Zhu                       AVB_SHA512_DIGEST_SIZE,
99*37a7bc39SJason Zhu                       algorithm_data->padding,
100*37a7bc39SJason Zhu                       algorithm_data->padding_len)) {
101*37a7bc39SJason Zhu     avb_error("Invalid certificate signature.\n");
102*37a7bc39SJason Zhu     return false;
103*37a7bc39SJason Zhu   }
104*37a7bc39SJason Zhu   if (certificate->signed_data.key_version < minimum_key_version) {
105*37a7bc39SJason Zhu     avb_error("Key rollback detected.\n");
106*37a7bc39SJason Zhu     return false;
107*37a7bc39SJason Zhu   }
108*37a7bc39SJason Zhu   if (0 != avb_safe_memcmp(certificate->signed_data.usage,
109*37a7bc39SJason Zhu                            expected_usage,
110*37a7bc39SJason Zhu                            AVB_SHA256_DIGEST_SIZE)) {
111*37a7bc39SJason Zhu     avb_error("Invalid certificate usage.\n");
112*37a7bc39SJason Zhu     return false;
113*37a7bc39SJason Zhu   }
114*37a7bc39SJason Zhu   return true;
115*37a7bc39SJason Zhu }
116*37a7bc39SJason Zhu 
117*37a7bc39SJason Zhu /* Verifies signature and fields of a PIK certificate. */
118*37a7bc39SJason Zhu static bool verify_pik_certificate(AvbAtxCertificate* certificate,
119*37a7bc39SJason Zhu                                    uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
120*37a7bc39SJason Zhu                                    uint64_t minimum_version) {
121*37a7bc39SJason Zhu   uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
122*37a7bc39SJason Zhu 
123*37a7bc39SJason Zhu   sha256_str("com.google.android.things.vboot.ca", expected_usage);
124*37a7bc39SJason Zhu   if (!verify_certificate(
125*37a7bc39SJason Zhu           certificate, authority, minimum_version, expected_usage)) {
126*37a7bc39SJason Zhu     avb_error("Invalid PIK certificate.\n");
127*37a7bc39SJason Zhu     return false;
128*37a7bc39SJason Zhu   }
129*37a7bc39SJason Zhu   return true;
130*37a7bc39SJason Zhu }
131*37a7bc39SJason Zhu 
132*37a7bc39SJason Zhu /* Verifies signature and fields of a PSK certificate. */
133*37a7bc39SJason Zhu static bool verify_psk_certificate(
134*37a7bc39SJason Zhu     AvbAtxCertificate* certificate,
135*37a7bc39SJason Zhu     uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
136*37a7bc39SJason Zhu     uint64_t minimum_version,
137*37a7bc39SJason Zhu     uint8_t product_id[AVB_ATX_PRODUCT_ID_SIZE]) {
138*37a7bc39SJason Zhu   uint8_t expected_subject[AVB_SHA256_DIGEST_SIZE];
139*37a7bc39SJason Zhu   uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
140*37a7bc39SJason Zhu 
141*37a7bc39SJason Zhu   sha256_str("com.google.android.things.vboot", expected_usage);
142*37a7bc39SJason Zhu   if (!verify_certificate(
143*37a7bc39SJason Zhu           certificate, authority, minimum_version, expected_usage)) {
144*37a7bc39SJason Zhu     avb_error("Invalid PSK certificate.\n");
145*37a7bc39SJason Zhu     return false;
146*37a7bc39SJason Zhu   }
147*37a7bc39SJason Zhu   sha256(product_id, AVB_ATX_PRODUCT_ID_SIZE, expected_subject);
148*37a7bc39SJason Zhu   if (0 != avb_safe_memcmp(certificate->signed_data.subject,
149*37a7bc39SJason Zhu                            expected_subject,
150*37a7bc39SJason Zhu                            AVB_SHA256_DIGEST_SIZE)) {
151*37a7bc39SJason Zhu     avb_error("Product ID mismatch.\n");
152*37a7bc39SJason Zhu     return false;
153*37a7bc39SJason Zhu   }
154*37a7bc39SJason Zhu   return true;
155*37a7bc39SJason Zhu }
156*37a7bc39SJason Zhu 
157*37a7bc39SJason Zhu AvbIOResult avb_atx_validate_vbmeta_public_key(
158*37a7bc39SJason Zhu     AvbOps* ops,
159*37a7bc39SJason Zhu     const uint8_t* public_key_data,
160*37a7bc39SJason Zhu     size_t public_key_length,
161*37a7bc39SJason Zhu     const uint8_t* public_key_metadata,
162*37a7bc39SJason Zhu     size_t public_key_metadata_length,
163*37a7bc39SJason Zhu     bool* out_is_trusted) {
164*37a7bc39SJason Zhu   AvbIOResult result = AVB_IO_RESULT_OK;
165*37a7bc39SJason Zhu   AvbAtxPermanentAttributes permanent_attributes;
166*37a7bc39SJason Zhu   uint8_t permanent_attributes_hash[AVB_SHA256_DIGEST_SIZE];
167*37a7bc39SJason Zhu   AvbAtxPublicKeyMetadata metadata;
168*37a7bc39SJason Zhu   uint64_t minimum_version;
169*37a7bc39SJason Zhu 
170*37a7bc39SJason Zhu   /* Be pessimistic so we can exit early without having to remember to clear.
171*37a7bc39SJason Zhu    */
172*37a7bc39SJason Zhu   *out_is_trusted = false;
173*37a7bc39SJason Zhu 
174*37a7bc39SJason Zhu   /* Read and verify permanent attributes. */
175*37a7bc39SJason Zhu   result = ops->atx_ops->read_permanent_attributes(ops->atx_ops,
176*37a7bc39SJason Zhu                                                    &permanent_attributes);
177*37a7bc39SJason Zhu   if (result != AVB_IO_RESULT_OK) {
178*37a7bc39SJason Zhu     avb_error("Failed to read permanent attributes.\n");
179*37a7bc39SJason Zhu     return result;
180*37a7bc39SJason Zhu   }
181*37a7bc39SJason Zhu   result = ops->atx_ops->read_permanent_attributes_hash(
182*37a7bc39SJason Zhu       ops->atx_ops, permanent_attributes_hash);
183*37a7bc39SJason Zhu   if (result != AVB_IO_RESULT_OK) {
184*37a7bc39SJason Zhu     avb_error("Failed to read permanent attributes hash.\n");
185*37a7bc39SJason Zhu     return result;
186*37a7bc39SJason Zhu   }
187*37a7bc39SJason Zhu   if (!verify_permanent_attributes(&permanent_attributes,
188*37a7bc39SJason Zhu                                    permanent_attributes_hash)) {
189*37a7bc39SJason Zhu     return AVB_IO_RESULT_OK;
190*37a7bc39SJason Zhu   }
191*37a7bc39SJason Zhu 
192*37a7bc39SJason Zhu   /* Sanity check public key metadata. */
193*37a7bc39SJason Zhu   if (public_key_metadata_length != sizeof(AvbAtxPublicKeyMetadata)) {
194*37a7bc39SJason Zhu     avb_error("Invalid public key metadata.\n");
195*37a7bc39SJason Zhu     return AVB_IO_RESULT_OK;
196*37a7bc39SJason Zhu   }
197*37a7bc39SJason Zhu   avb_memcpy(&metadata, public_key_metadata, sizeof(AvbAtxPublicKeyMetadata));
198*37a7bc39SJason Zhu   if (metadata.version != 1) {
199*37a7bc39SJason Zhu     avb_error("Unsupported public key metadata.\n");
200*37a7bc39SJason Zhu     return AVB_IO_RESULT_OK;
201*37a7bc39SJason Zhu   }
202*37a7bc39SJason Zhu 
203*37a7bc39SJason Zhu   /* Verify the PIK certificate. */
204*37a7bc39SJason Zhu   result = ops->read_rollback_index(
205*37a7bc39SJason Zhu       ops, AVB_ATX_PIK_VERSION_LOCATION, &minimum_version);
206*37a7bc39SJason Zhu   if (result != AVB_IO_RESULT_OK) {
207*37a7bc39SJason Zhu     avb_error("Failed to read PIK minimum version.\n");
208*37a7bc39SJason Zhu     return result;
209*37a7bc39SJason Zhu   }
210*37a7bc39SJason Zhu   if (!verify_pik_certificate(&metadata.product_intermediate_key_certificate,
211*37a7bc39SJason Zhu                               permanent_attributes.product_root_public_key,
212*37a7bc39SJason Zhu                               minimum_version)) {
213*37a7bc39SJason Zhu     return AVB_IO_RESULT_OK;
214*37a7bc39SJason Zhu   }
215*37a7bc39SJason Zhu 
216*37a7bc39SJason Zhu   /* Verify the PSK certificate. */
217*37a7bc39SJason Zhu   result = ops->read_rollback_index(
218*37a7bc39SJason Zhu       ops, AVB_ATX_PSK_VERSION_LOCATION, &minimum_version);
219*37a7bc39SJason Zhu   if (result != AVB_IO_RESULT_OK) {
220*37a7bc39SJason Zhu     avb_error("Failed to read PSK minimum version.\n");
221*37a7bc39SJason Zhu     return result;
222*37a7bc39SJason Zhu   }
223*37a7bc39SJason Zhu   if (!verify_psk_certificate(
224*37a7bc39SJason Zhu           &metadata.product_signing_key_certificate,
225*37a7bc39SJason Zhu           metadata.product_intermediate_key_certificate.signed_data.public_key,
226*37a7bc39SJason Zhu           minimum_version,
227*37a7bc39SJason Zhu           permanent_attributes.product_id)) {
228*37a7bc39SJason Zhu     return AVB_IO_RESULT_OK;
229*37a7bc39SJason Zhu   }
230*37a7bc39SJason Zhu 
231*37a7bc39SJason Zhu   /* Verify the PSK is the same key that verified vbmeta. */
232*37a7bc39SJason Zhu   if (public_key_length != AVB_ATX_PUBLIC_KEY_SIZE) {
233*37a7bc39SJason Zhu     avb_error("Public key length mismatch.\n");
234*37a7bc39SJason Zhu     return AVB_IO_RESULT_OK;
235*37a7bc39SJason Zhu   }
236*37a7bc39SJason Zhu   if (0 != avb_safe_memcmp(
237*37a7bc39SJason Zhu                metadata.product_signing_key_certificate.signed_data.public_key,
238*37a7bc39SJason Zhu                public_key_data,
239*37a7bc39SJason Zhu                AVB_ATX_PUBLIC_KEY_SIZE)) {
240*37a7bc39SJason Zhu     avb_error("Public key mismatch.\n");
241*37a7bc39SJason Zhu     return AVB_IO_RESULT_OK;
242*37a7bc39SJason Zhu   }
243*37a7bc39SJason Zhu 
244*37a7bc39SJason Zhu   /* Report the key versions used during verification. */
245*37a7bc39SJason Zhu   ops->atx_ops->set_key_version(
246*37a7bc39SJason Zhu       ops->atx_ops,
247*37a7bc39SJason Zhu       AVB_ATX_PIK_VERSION_LOCATION,
248*37a7bc39SJason Zhu       metadata.product_intermediate_key_certificate.signed_data.key_version);
249*37a7bc39SJason Zhu   ops->atx_ops->set_key_version(
250*37a7bc39SJason Zhu       ops->atx_ops,
251*37a7bc39SJason Zhu       AVB_ATX_PSK_VERSION_LOCATION,
252*37a7bc39SJason Zhu       metadata.product_signing_key_certificate.signed_data.key_version);
253*37a7bc39SJason Zhu 
254*37a7bc39SJason Zhu   *out_is_trusted = true;
255*37a7bc39SJason Zhu   return AVB_IO_RESULT_OK;
256*37a7bc39SJason Zhu }
257