From 6faf0265c9b58db2c15b53f6d29025629d52f882 Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Thu, 9 Jun 2016 14:09:39 -0700 Subject: Verify wipe package when wiping A/B device in recovery. To increase the security of wiping A/B devices, let uncrypt write wipe package in misc partition. Then recovery verifies the wipe package before wiping the device. Bug: 29159185 Change-Id: I186691bab1928d3dc036bc5542abd64a81bc2168 --- install.cpp | 60 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 23 deletions(-) (limited to 'install.cpp') diff --git a/install.cpp b/install.cpp index 5a439a1d6..518337fef 100644 --- a/install.cpp +++ b/install.cpp @@ -70,20 +70,27 @@ static int parse_build_number(std::string str) { return -1; } -// Read the build.version.incremental of src/tgt from the metadata and log it to last_install. -static void read_source_target_build(ZipArchive* zip, std::vector& log_buffer) { +bool read_metadata_from_package(ZipArchive* zip, std::string* meta_data) { const ZipEntry* meta_entry = mzFindZipEntry(zip, METADATA_PATH); if (meta_entry == nullptr) { LOGE("Failed to find %s in update package.\n", METADATA_PATH); - return; + return false; } - std::string meta_data(meta_entry->uncompLen, '\0'); - if (!mzReadZipEntry(zip, meta_entry, &meta_data[0], meta_entry->uncompLen)) { + meta_data->resize(meta_entry->uncompLen, '\0'); + if (!mzReadZipEntry(zip, meta_entry, &(*meta_data)[0], meta_entry->uncompLen)) { LOGE("Failed to read metadata in update package.\n"); - return; + return false; } + return true; +} +// Read the build.version.incremental of src/tgt from the metadata and log it to last_install. +static void read_source_target_build(ZipArchive* zip, std::vector& log_buffer) { + std::string meta_data; + if (!read_metadata_from_package(zip, &meta_data)) { + return; + } // Examples of the pre-build and post-build strings in metadata: // pre-build-incremental=2943039 // post-build-incremental=2951741 @@ -300,31 +307,16 @@ really_install_package(const char *path, bool* wipe_cache, bool needs_mount, return INSTALL_CORRUPT; } - // Load keys. - std::vector loadedKeys; - if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) { - LOGE("Failed to load keys\n"); - return INSTALL_CORRUPT; - } - LOGI("%zu key(s) loaded from %s\n", loadedKeys.size(), PUBLIC_KEYS_FILE); - // Verify package. - ui->Print("Verifying update package...\n"); - auto t0 = std::chrono::system_clock::now(); - int err = verify_file(map.addr, map.length, loadedKeys); - std::chrono::duration duration = std::chrono::system_clock::now() - t0; - ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err); - if (err != VERIFY_SUCCESS) { - LOGE("signature verification failed\n"); + if (!verify_package(map.addr, map.length)) { log_buffer.push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure)); - sysReleaseMap(&map); return INSTALL_CORRUPT; } // Try to open the package. ZipArchive zip; - err = mzOpenZipArchive(map.addr, map.length, &zip); + int err = mzOpenZipArchive(map.addr, map.length, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); log_buffer.push_back(android::base::StringPrintf("error: %d", kZipOpenFailure)); @@ -387,3 +379,25 @@ install_package(const char* path, bool* wipe_cache, const char* install_file, } return result; } + +bool verify_package(const unsigned char* package_data, size_t package_size) { + std::vector loadedKeys; + if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) { + LOGE("Failed to load keys\n"); + return false; + } + LOGI("%zu key(s) loaded from %s\n", loadedKeys.size(), PUBLIC_KEYS_FILE); + + // Verify package. + ui->Print("Verifying update package...\n"); + auto t0 = std::chrono::system_clock::now(); + int err = verify_file(const_cast(package_data), package_size, loadedKeys); + std::chrono::duration duration = std::chrono::system_clock::now() - t0; + ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err); + if (err != VERIFY_SUCCESS) { + LOGE("Signature verification failed\n"); + LOGE("error: %d\n", kZipVerificationFailure); + return false; + } + return true; +} -- cgit v1.2.3