121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen/* 221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * Copyright (C) 2016 The Android Open Source Project 321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * 4c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * Permission is hereby granted, free of charge, to any person 5c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * obtaining a copy of this software and associated documentation 6c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * files (the "Software"), to deal in the Software without 7c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * restriction, including without limitation the rights to use, copy, 8c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * modify, merge, publish, distribute, sublicense, and/or sell copies 9c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * of the Software, and to permit persons to whom the Software is 10c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * furnished to do so, subject to the following conditions: 1121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * 12c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * The above copyright notice and this permission notice shall be 13c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * included in all copies or substantial portions of the Software. 1421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * 15c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22c612e2e353444f6ad714e43702c2afd057516254David Zeuthen * SOFTWARE. 2321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen */ 2421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 2521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen#include "avb_vbmeta_image.h" 26c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn#include "avb_crypto.h" 2721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen#include "avb_rsa.h" 2821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen#include "avb_sha.h" 2921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen#include "avb_util.h" 30e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen#include "avb_version.h" 3121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 3221e95266704e572ced1c633bbc4aea9f42afa0a5David ZeuthenAvbVBMetaVerifyResult avb_vbmeta_image_verify( 334b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen const uint8_t* data, 344b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen size_t length, 354b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen const uint8_t** out_public_key_data, 3621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen size_t* out_public_key_length) { 3721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen AvbVBMetaVerifyResult ret; 3821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen AvbVBMetaImageHeader h; 3921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint8_t* computed_hash; 40c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn const AvbAlgorithmData* algorithm; 4121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen AvbSHA256Ctx sha256_ctx; 4221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen AvbSHA512Ctx sha512_ctx; 4321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen const uint8_t* header_block; 4421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen const uint8_t* authentication_block; 4521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen const uint8_t* auxiliary_block; 4621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen int verification_result; 4721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 4821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER; 4921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 500155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen if (out_public_key_data != NULL) { 510155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen *out_public_key_data = NULL; 520155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen } 530155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen if (out_public_key_length != NULL) { 540155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen *out_public_key_length = 0; 550155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen } 5621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 5721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Ensure magic is correct. */ 5821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (avb_safe_memcmp(data, AVB_MAGIC, AVB_MAGIC_LEN) != 0) { 5921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Magic is incorrect.\n"); 6021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 6121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 6221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 6321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Before we byteswap, ensure length is long enough. */ 6421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (length < sizeof(AvbVBMetaImageHeader)) { 6521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Length is smaller than header.\n"); 6621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 6721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 6821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_vbmeta_image_header_to_host_byte_order((const AvbVBMetaImageHeader*)data, 6921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen &h); 7021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 71e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen /* Ensure we don't attempt to access any fields if we do not meet 72e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen * the specified minimum version of libavb. 7321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen */ 74e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen if ((h.required_libavb_version_major != AVB_VERSION_MAJOR) || 75e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen (h.required_libavb_version_minor > AVB_VERSION_MINOR)) { 76e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen avb_error("Mismatch between image version and libavb version.\n"); 77e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen ret = AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION; 78e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen goto out; 79e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen } 80e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen 81e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen /* Ensure |release_string| ends with a NUL byte. */ 82e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen if (h.release_string[AVB_RELEASE_STRING_SIZE - 1] != '\0') { 83e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen avb_error("Release string does not end with a NUL byte.\n"); 8421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 8521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 8621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 8721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Ensure inner block sizes are multiple of 64. */ 8821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if ((h.authentication_data_block_size & 0x3f) != 0 || 8921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen (h.auxiliary_data_block_size & 0x3f) != 0) { 9021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Block size is not a multiple of 64.\n"); 9121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 9221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 9321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 9421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Ensure block sizes all add up to at most |length|. */ 9521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t block_total = sizeof(AvbVBMetaImageHeader); 9621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (!avb_safe_add_to(&block_total, h.authentication_data_block_size) || 9721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen !avb_safe_add_to(&block_total, h.auxiliary_data_block_size)) { 9821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Overflow while computing size of boot image.\n"); 9921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 10021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 10121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (block_total > length) { 10221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Block sizes add up to more than given length.\n"); 10321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 10421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 10521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 10621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uintptr_t data_ptr = (uintptr_t)data; 10721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Ensure passed in memory doesn't wrap. */ 10821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (!avb_safe_add(NULL, (uint64_t)data_ptr, length)) { 10921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Boot image location and length mismatch.\n"); 11021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 11121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 11221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 11321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Ensure hash and signature are entirely in the Authentication data block. */ 11421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t hash_end; 11521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (!avb_safe_add(&hash_end, h.hash_offset, h.hash_size) || 11621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen hash_end > h.authentication_data_block_size) { 11721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Hash is not entirely in its block.\n"); 11821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 11921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 12021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t signature_end; 12121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (!avb_safe_add(&signature_end, h.signature_offset, h.signature_size) || 12221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen signature_end > h.authentication_data_block_size) { 12321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Signature is not entirely in its block.\n"); 12421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 12521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 12621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 12721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Ensure public key is entirely in the Auxiliary data block. */ 12821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen uint64_t pubkey_end; 12921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (!avb_safe_add(&pubkey_end, h.public_key_offset, h.public_key_size) || 13021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen pubkey_end > h.auxiliary_data_block_size) { 13121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Public key is not entirely in its block.\n"); 13221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 13321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 13421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 13518666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen /* Ensure public key metadata (if set) is entirely in the Auxiliary 13618666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen * data block. */ 13718666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen if (h.public_key_metadata_size > 0) { 13818666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen uint64_t pubkey_md_end; 1394b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (!avb_safe_add(&pubkey_md_end, 1404b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen h.public_key_metadata_offset, 14118666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen h.public_key_metadata_size) || 14218666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen pubkey_md_end > h.auxiliary_data_block_size) { 14318666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen avb_error("Public key metadata is not entirely in its block.\n"); 14418666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen goto out; 14518666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen } 14618666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen } 14718666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen 14821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Bail early if there's no hash or signature. */ 14921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (h.algorithm_type == AVB_ALGORITHM_TYPE_NONE) { 15021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED; 15121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 15221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 15321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 154c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn /* Ensure algorithm field is supported. */ 155c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn algorithm = avb_get_algorithm_data(h.algorithm_type); 156c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn if (!algorithm) { 157c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn avb_error("Invalid or unknown algorithm.\n"); 158c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn goto out; 159c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn } 160c9fa424bdae2d7d631c613ef168c73ff1d61d5e5Darren Krahn 16121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Bail if the embedded hash size doesn't match the chosen algorithm. */ 16221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (h.hash_size != algorithm->hash_len) { 16321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Embedded hash has wrong size.\n"); 16421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 16521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 16621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 16721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* No overflow checks needed from here-on after since all block 16821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen * sizes and offsets have been verified above. 16921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen */ 17021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 17121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen header_block = data; 17221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen authentication_block = header_block + sizeof(AvbVBMetaImageHeader); 17321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen auxiliary_block = authentication_block + h.authentication_data_block_size; 17421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 17521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen switch (h.algorithm_type) { 17621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Explicit fall-through: */ 17721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen case AVB_ALGORITHM_TYPE_SHA256_RSA2048: 17821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen case AVB_ALGORITHM_TYPE_SHA256_RSA4096: 17921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen case AVB_ALGORITHM_TYPE_SHA256_RSA8192: 18021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_sha256_init(&sha256_ctx); 1814b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen avb_sha256_update( 1824b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen &sha256_ctx, header_block, sizeof(AvbVBMetaImageHeader)); 1834b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen avb_sha256_update( 1844b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen &sha256_ctx, auxiliary_block, h.auxiliary_data_block_size); 18521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen computed_hash = avb_sha256_final(&sha256_ctx); 18621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen break; 18721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen /* Explicit fall-through: */ 18821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen case AVB_ALGORITHM_TYPE_SHA512_RSA2048: 18921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen case AVB_ALGORITHM_TYPE_SHA512_RSA4096: 19021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen case AVB_ALGORITHM_TYPE_SHA512_RSA8192: 19121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_sha512_init(&sha512_ctx); 1924b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen avb_sha512_update( 1934b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen &sha512_ctx, header_block, sizeof(AvbVBMetaImageHeader)); 1944b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen avb_sha512_update( 1954b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen &sha512_ctx, auxiliary_block, h.auxiliary_data_block_size); 19621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen computed_hash = avb_sha512_final(&sha512_ctx); 19721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen break; 19821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen default: 19921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Unknown algorithm.\n"); 20021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 20121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 20221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 2034b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen if (avb_safe_memcmp(authentication_block + h.hash_offset, 2044b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen computed_hash, 20521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen h.hash_size) != 0) { 20621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_error("Hash does not match!\n"); 20721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH; 20821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 20921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 21021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 21121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen verification_result = 2124b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen avb_rsa_verify(auxiliary_block + h.public_key_offset, 2134b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen h.public_key_size, 21421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen authentication_block + h.signature_offset, 2154b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen h.signature_size, 2164b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen authentication_block + h.hash_offset, 2174b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen h.hash_size, 2184b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen algorithm->padding, 2194b6a634e48353da1e119ebe0287299f7b919d778David Zeuthen algorithm->padding_len); 22021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 22121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen if (verification_result == 0) { 22221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH; 22321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen goto out; 22421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen } 22521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 2260155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen if (h.public_key_size > 0) { 2270155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen if (out_public_key_data != NULL) { 2280155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen *out_public_key_data = auxiliary_block + h.public_key_offset; 2290155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen } 2300155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen if (out_public_key_length != NULL) { 2310155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen *out_public_key_length = h.public_key_size; 2320155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen } 2330155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen } 23421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 23521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen ret = AVB_VBMETA_VERIFY_RESULT_OK; 23621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 23721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenout: 23821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen return ret; 23921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 24021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 24121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthenvoid avb_vbmeta_image_header_to_host_byte_order(const AvbVBMetaImageHeader* src, 24221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen AvbVBMetaImageHeader* dest) { 24321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_memcpy(dest, src, sizeof(AvbVBMetaImageHeader)); 24421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 245e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen dest->required_libavb_version_major = 246e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen avb_be32toh(dest->required_libavb_version_major); 247e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen dest->required_libavb_version_minor = 248e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen avb_be32toh(dest->required_libavb_version_minor); 24921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 25021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->authentication_data_block_size = 25121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_be64toh(dest->authentication_data_block_size); 25221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->auxiliary_data_block_size = 25321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen avb_be64toh(dest->auxiliary_data_block_size); 25421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 25521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->algorithm_type = avb_be32toh(dest->algorithm_type); 25621e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 25721e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->hash_offset = avb_be64toh(dest->hash_offset); 25821e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->hash_size = avb_be64toh(dest->hash_size); 25921e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 26021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->signature_offset = avb_be64toh(dest->signature_offset); 26121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->signature_size = avb_be64toh(dest->signature_size); 26221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 26321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->public_key_offset = avb_be64toh(dest->public_key_offset); 26421e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->public_key_size = avb_be64toh(dest->public_key_size); 26521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 26618666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen dest->public_key_metadata_offset = 26718666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen avb_be64toh(dest->public_key_metadata_offset); 26818666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen dest->public_key_metadata_size = avb_be64toh(dest->public_key_metadata_size); 26918666abc5d8276a743111e6c3608e66f6c85fb51David Zeuthen 27021e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->descriptors_offset = avb_be64toh(dest->descriptors_offset); 27121e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->descriptors_size = avb_be64toh(dest->descriptors_size); 27221e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen 27321e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen dest->rollback_index = avb_be64toh(dest->rollback_index); 274fd41eb9a7848ad8d2ae0a80186e461741bf134f1David Zeuthen dest->flags = avb_be32toh(dest->flags); 27521e95266704e572ced1c633bbc4aea9f42afa0a5David Zeuthen} 2760155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen 2770155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthenconst char* avb_vbmeta_verify_result_to_string(AvbVBMetaVerifyResult result) { 2780155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen const char* ret = NULL; 2790155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen 2800155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen switch (result) { 2810155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen case AVB_VBMETA_VERIFY_RESULT_OK: 2820155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen ret = "OK"; 2830155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen break; 2840155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen case AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED: 2850155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen ret = "OK_NOT_SIGNED"; 2860155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen break; 2870155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen case AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER: 2880155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen ret = "INVALID_VBMETA_HEADER"; 2890155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen break; 290e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION: 291e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen ret = "UNSUPPORTED_VERSION"; 292e3cadcacd798effe83b1593dba1ee0e3d84cf6e4David Zeuthen break; 2930155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen case AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH: 2940155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen ret = "HASH_MISMATCH"; 2950155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen break; 2960155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen case AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH: 2970155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen ret = "SIGNATURE_MISMATCH"; 2980155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen break; 2990155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen /* Do not add a 'default:' case here because of -Wswitch. */ 3000155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen } 3010155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen 3020155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen if (ret == NULL) { 3030155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen avb_error("Unknown AvbVBMetaVerifyResult value.\n"); 3040155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen ret = "(unknown)"; 3050155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen } 3060155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen 3070155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen return ret; 3080155e6b158bdc5b3a442f16a5dc124d5dee9c71cDavid Zeuthen} 309