refine avbVerifier; fix AuthBlob bug

1. AuthBlob bug: if change algorithm_type from 0 to non-zero values,
    auth_blob should not be empty
2. avbVerifier:
    move key file to config/pubkey
    add gradle task "v1/v2" to verify normal/recovery flow
pull/41/head
cfig 5 years ago
parent e5b03661f8
commit 67667c803c
No known key found for this signature in database
GPG Key ID: B104C307F0FDABB7

1
.gitignore vendored

@ -1,2 +1,3 @@
.idea
.gradle
build/

@ -24,7 +24,7 @@ Supported images:
(2) These utilities are known to work for Nexus/Pixel boot.img for the following Android releases:
- AOSP master
- Lollipop (5.0) - Q preview
- Lollipop (5.0) - Android 10
## 2. Usage
Clone this repo with minimal depth:

@ -34,3 +34,16 @@ model {
}
}
}
task v1(type:Exec) {
workingDir "."
environment preloads: "vbmeta boot", requests: "boot dtbo", suffix: ""
commandLine "./build/exe/avbVerifier/avbVerifier"
}
task v2(type:Exec) {
description "verify non-AB recovery mode"
workingDir "."
environment preloads: "", requests: "recovery", suffix: ""
commandLine "./build/exe/avbVerifier/avbVerifier"
}

@ -15,8 +15,11 @@
#include "helper.hpp"
std::vector<std::string> splitString(const std::string& subject) {
if (subject.size() == 0) {
return std::vector<std::string>();
}
static const std::regex re{"\\s+"};
std::vector<std::string> container{
std::vector<std::string> container {
std::sregex_token_iterator(subject.begin(), subject.end(), re, -1),
std::sregex_token_iterator()
};
@ -24,27 +27,63 @@ std::vector<std::string> splitString(const std::string& subject) {
}
int main(int, char**) {
auto cfigOps = CfigAvbOps();
auto preloads = getenv("preload");
int flags = AVB_SLOT_VERIFY_FLAGS_NONE;
//param 1: preload partitions
auto preloads = getenv("preloads");
if (preloads == NULL) {
} else {
preloads = (char*) "";
}
std::cout << "[" << __FUNCTION__ << "]: partitions to preload: " << preloads << std::endl;
//param 2: requested partitions
auto requests = getenv("requests");
if (requests == NULL) {
requests = (char*) "";
}
std::cout << "[" << __FUNCTION__ << "]: requested partitions: " << requests << std::endl;
auto requestVec = splitString(requests);
//example: const char* requestedPartitions[] = { (const char*) "boot", (const char*)NULL };
const char* requestedPartitions[requestVec.size() + 1];
for (int i = 0; i< requestVec.size(); i++) {
requestedPartitions[i] = requestVec[i].c_str();
if (requestVec[i] == "recovery") {
flags |= AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION;
std::cout << "[" << __FUNCTION__ << "]: using NO-VBMETA mode for recovery" << std::endl;
}
}
requestedPartitions[requestVec.size()] = (const char*)NULL;
//param3: ab_suffix
auto abSuffix = getenv("suffix");
if (abSuffix == NULL) {
abSuffix = (char*) "";
}
std::cout << "[" << __FUNCTION__ << "]: ab_suffix: " << abSuffix << std::endl;
//main
auto cfigOps = CfigAvbOps();
{//preload partitions
auto preloadVec = splitString(preloads);
for (auto item: preloadVec) {
cfigOps.preload_partition(item);
}
}
cfigOps.preload_partition("vbmeta");
bool isDeviceLocked = true;
cfigOps.avb_ops_.read_is_device_unlocked(NULL, &isDeviceLocked);
if (isDeviceLocked) {
flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR;
}
std::cout << "[" << __FUNCTION__ << "]: flags: " << flags << std::endl;
AvbSlotVerifyData *slotData = NULL;
const char* requestedPartitions[] = { (const char*) "boot", (const char*)NULL };
AvbSlotVerifyResult result = avb_slot_verify(
&(cfigOps.avb_ops_),
requestedPartitions,
"",
AVB_SLOT_VERIFY_FLAGS_NONE,
abSuffix, /* ab_suffix */
static_cast<AvbSlotVerifyFlags>(flags), /* AvbSlotVerifyFlags */
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
&slotData);
std::cout << "AvbSlotVerifyResult = " << toString(result) << std::endl;
if (AVB_SLOT_VERIFY_RESULT_OK == result) {
auto outFile = "verify_result.json";
std::cout << "Writing result to " << outFile << "... ";
@ -52,6 +91,9 @@ int main(int, char**) {
outJson << toString(slotData);
outJson.close();
std::cout << " done" << std::endl;
std::cout << "Run:\n python -m json.tool " << outFile << std::endl;
}
if (slotData) { avb_slot_verify_data_free(slotData); }
std::cerr << "\n\tVerify Result: " << toString(result) << std::endl;
return 0;
}

@ -22,7 +22,7 @@ static std::string expected_public_key_;
static std::string expected_public_key_metadata_;
static auto lockStatusFile = "config/locked";
static auto pubkeyFile = "config/rsa4096.pubkey";
static auto pubkeyFile = "config/pubkey";
static std::string read_line(std::string file);
@ -347,7 +347,7 @@ bool CfigAvbOps::preload_partition(std::string partition) {
preloaded_partitions_[partition] = buffer;
fprintf(stderr,
fprintf(stdout,
"[%s()]: partition [%s] preloaded\n",
__FUNCTION__,
partition.c_str());

@ -298,12 +298,7 @@ class Avb {
}.encode()
//2 - auth blob
var authBlob = byteArrayOf()
if (ai.authBlob != null) {
authBlob = AuthBlob.createBlob(headerBlob, auxBlob, alg.name)
} else {
log.info("No auth blob")
}
val authBlob = AuthBlob.createBlob(headerBlob, auxBlob, alg.name)
return Helper.join(headerBlob, authBlob, auxBlob)
}

@ -19,7 +19,7 @@ data class AuthBlob(
val alg = Algorithms.get(algorithm_name)!!
val authBlockSize = Helper.round_to_multiple((alg.hash_num_bytes + alg.signature_num_bytes).toLong(), 64)
if (0L == authBlockSize) {
log.info("No auth blob")
log.info("No auth blob for algorithm " + alg.name)
return byteArrayOf()
}

Loading…
Cancel
Save