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