libcr51sign: Sync with latest code
Change-Id: Id3de25f3b112aa84d4b2342f606a60bb049487c8
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h b/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h
index d56fc05..8a673b2 100644
--- a/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h
+++ b/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h
@@ -167,6 +167,9 @@
// false: if in any non-production mode
bool (*is_production_mode)();
+
+ // @func returns true if the descriptor image size is valid.
+ bool (*image_size_valid)(size_t);
};
struct libcr51sign_validated_regions
diff --git a/subprojects/libcr51sign/src/libcr51sign.c b/subprojects/libcr51sign/src/libcr51sign.c
index d89c88d..b9be35e 100644
--- a/subprojects/libcr51sign/src/libcr51sign.c
+++ b/subprojects/libcr51sign/src/libcr51sign.c
@@ -190,12 +190,12 @@
if (rv != LIBCR51SIGN_SUCCESS)
{
CPRINTS(ctx,
- "validate_transition: failed to read signature struct");
+ "validate_transition: failed to read signature struct\n");
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
if (*(uint32_t*)buffer != SIGNATURE_MAGIC)
{
- CPRINTS(ctx, "validate_transition: bad signature magic");
+ CPRINTS(ctx, "validate_transition: bad signature magic\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
@@ -203,26 +203,26 @@
ctx->descriptor.image_family != IMAGE_FAMILY_ALL &&
ctx->current_image_family != IMAGE_FAMILY_ALL)
{
- CPRINTS(ctx, "validate_transition: invalid image family");
+ CPRINTS(ctx, "validate_transition: invalid image family\n");
return LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY;
}
if (intf->is_production_mode == NULL)
{
- CPRINTS(ctx, "validate_transition: missing is_production_mode");
+ CPRINTS(ctx, "validate_transition: missing is_production_mode\n");
return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
}
if (intf->is_production_mode() &&
(ctx->descriptor.image_type == IMAGE_DEV))
{
- CPRINTS(ctx, "validate_transition: checking exemption allowlist");
+ CPRINTS(ctx, "validate_transition: checking exemption allowlist\n");
// If function is NULL or if the function call return false, return
// error
if (intf->prod_to_dev_downgrade_allowed == NULL ||
!intf->prod_to_dev_downgrade_allowed())
{
- CPRINTS(ctx, "validate_transition: illegal image type");
+ CPRINTS(ctx, "validate_transition: illegal image type\n");
return LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED;
}
}
@@ -249,7 +249,7 @@
{
if (!intf->hash_update)
{
- CPRINTS(ctx, "read_and_hash_update: missing hash_update");
+ CPRINTS(ctx, "read_and_hash_update: missing hash_update\n");
return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
}
do
@@ -295,7 +295,7 @@
if (image_regions == NULL)
{
- CPRINTS(ctx, "Missing image region input");
+ CPRINTS(ctx, "Missing image region input\n");
return LIBCR51SIGN_ERROR_INVALID_REGION_INPUT;
}
@@ -311,7 +311,7 @@
{
CPRINTS(ctx, "validate_payload_regions: "
"ctx->descriptor.region_count is greater "
- "than LIBCR51SIGN_MAX_REGION_COUNT");
+ "than LIBCR51SIGN_MAX_REGION_COUNT\n");
return LIBCR51SIGN_ERROR_INVALID_REGION_SIZE;
}
@@ -324,7 +324,7 @@
if (rv != LIBCR51SIGN_SUCCESS)
{
CPRINTS(ctx,
- "validate_payload_regions: failed to read region array");
+ "validate_payload_regions: failed to read region array\n");
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
@@ -334,21 +334,21 @@
region = image_regions->image_regions + i;
CPRINTS(ctx,
- "validate_payload_regions: region #%d \"%s\" (%x - %x)", i,
- (const char*)region->region_name, region->region_offset,
+ "validate_payload_regions: region #%d \"%s\" (%x - %x)\n",
+ i, (const char*)region->region_name, region->region_offset,
region->region_offset + region->region_size);
if ((region->region_offset % IMAGE_REGION_ALIGNMENT) != 0 ||
(region->region_size % IMAGE_REGION_ALIGNMENT) != 0)
{
- CPRINTS(
- ctx,
- "validate_payload_regions: regions must be sector aligned");
+ CPRINTS(ctx, "validate_payload_regions: regions must be sector "
+ "aligned\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
if (region->region_offset != byte_count ||
region->region_size > image_size - byte_count)
{
- CPRINTS(ctx, "validate_payload_regions: invalid region array");
+ CPRINTS(ctx,
+ "validate_payload_regions: invalid region array\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
byte_count += region->region_size;
@@ -358,7 +358,7 @@
d_region_num = i;
CPRINTS(
ctx,
- "validate_payload_regions: image descriptor in region %d",
+ "validate_payload_regions: image descriptor in region %d\n",
i);
// The descriptor can't span regions.
if (ctx->descriptor.descriptor_area_size > byte_count ||
@@ -367,14 +367,14 @@
CPRINTS(
ctx,
"validate_payload_regions: descriptor must reside in "
- "static region");
+ "static region\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
}
}
if (byte_count != image_size)
{
- CPRINTS(ctx, "validate_payload_regions: invalid image size");
+ CPRINTS(ctx, "validate_payload_regions: invalid image size\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
@@ -390,19 +390,20 @@
magic_and_digest);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx,
- "validate_payload_regions: failed to read hash from flash");
+ CPRINTS(
+ ctx,
+ "validate_payload_regions: failed to read hash from flash\n");
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
if (*(uint32_t*)magic_and_digest != HASH_MAGIC)
{
- CPRINTS(ctx, "validate_payload_regions: bad hash magic");
+ CPRINTS(ctx, "validate_payload_regions: bad hash magic\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
rv = intf->hash_init(ctx, ctx->descriptor.hash_type);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate_payload_regions: hash_init failed");
+ CPRINTS(ctx, "validate_payload_regions: hash_init failed\n");
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
for (i = 0; i < region_count; i++)
@@ -431,7 +432,7 @@
hash_size = (region->region_offset + region->region_size -
hash_start);
}
- CPRINTS("validate_payload_regions: hashing %s (%x - %x)",
+ CPRINTS("validate_payload_regions: hashing %s (%x - %x)\n",
(const char*)region->region_name, hash_start,
hash_start + hash_size);
// Read the image_region array.
@@ -454,7 +455,7 @@
MEMBER_SIZE(struct hash_sha256, hash_magic),
dcrypto_digest, digest_size))
{
- CPRINTS(ctx, "validate_payload_regions: invalid hash");
+ CPRINTS(ctx, "validate_payload_regions: invalid hash\n");
return LIBCR51SIGN_ERROR_INVALID_HASH;
}
// Image is valid.
@@ -570,7 +571,7 @@
if (!intf->hash_init)
{
- CPRINTS(ctx, "validate_signature: missing hash_init");
+ CPRINTS(ctx, "validate_signature: missing hash_init\n");
return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
}
rv = get_hash_type_from_signature(scheme, &hash_type);
@@ -578,30 +579,31 @@
{
CPRINTS(
ctx,
- "validate_payload_regions: hash_type from signature failed");
+ "validate_payload_regions: hash_type from signature failed\n");
return rv;
}
rv = intf->hash_init(ctx, hash_type);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate_payload_regions: hash_init failed");
+ CPRINTS(ctx, "validate_payload_regions: hash_init failed\n");
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
rv = read_and_hash_update(ctx, intf, data_offset, data_size);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate_signature: hash_update failed");
+ CPRINTS(ctx, "validate_signature: hash_update failed\n");
return rv;
}
if (!intf->hash_final)
{
- CPRINTS(ctx, "validate_signature: missing hash_final");
+ CPRINTS(ctx, "validate_signature: missing hash_final\n");
return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
}
rv = intf->hash_final((void*)ctx, dcrypto_digest);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate_signature: hash_final failed (status = %d)",
+ CPRINTS(ctx,
+ "validate_signature: hash_final failed (status = %d)\n",
rv);
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
@@ -616,13 +618,13 @@
{
CPRINTS(
ctx,
- "validate_signature: failed to read signature (status = %d)",
+ "validate_signature: failed to read signature (status = %d)\n",
rv);
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
if (!intf->verify_signature)
{
- CPRINTS(ctx, "validate_signature: missing verify_signature");
+ CPRINTS(ctx, "validate_signature: missing verify_signature\n");
return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
}
rv = get_hash_digest_size(hash_type, &digest_size);
@@ -635,11 +637,11 @@
if (rv != LIBCR51SIGN_SUCCESS)
{
CPRINTS(ctx,
- "validate_signature: verification failed (status = %d)",
+ "validate_signature: verification failed (status = %d)\n",
rv);
return LIBCR51SIGN_ERROR_INVALID_SIGNATURE;
}
- CPRINTS(ctx, "validate_signature: verification succeeded");
+ CPRINTS(ctx, "validate_signature: verification succeeded\n");
return LIBCR51SIGN_SUCCESS;
}
@@ -652,12 +654,12 @@
// and environment
//@param offset Absolute image descriptor flash offset.
//@param relative_offset Image descriptor offset relative to image start.
- //@param image_size Image size in bytes.
+ //@param max_size Maximum size of the flash space in bytes.
//@param descriptor Output pointer to an image_descriptor struct
static failure_reason validate_descriptor(
const struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf,
- uint32_t offset, uint32_t relative_offset, uint32_t image_size)
+ uint32_t offset, uint32_t relative_offset, uint32_t max_size)
{
uint32_t max_descriptor_size, signed_size, signature_scheme,
signature_offset;
@@ -665,11 +667,11 @@
hash_struct_size;
int rv;
- max_descriptor_size = image_size - relative_offset;
- if (image_size < relative_offset ||
+ max_descriptor_size = max_size - relative_offset;
+ if (max_size < relative_offset ||
max_descriptor_size < sizeof(struct image_descriptor))
{
- CPRINTS(ctx, "validate_descriptor: invalid arguments");
+ CPRINTS(ctx, "validate_descriptor: invalid arguments\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
@@ -677,16 +679,31 @@
(uint8_t*)&ctx->descriptor);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate_descriptor: failed to read descriptor");
+ CPRINTS(ctx, "validate_descriptor: failed to read descriptor\n");
return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
}
if (ctx->descriptor.descriptor_magic != DESCRIPTOR_MAGIC ||
ctx->descriptor.descriptor_offset != relative_offset ||
ctx->descriptor.region_count == 0 ||
ctx->descriptor.descriptor_area_size > max_descriptor_size ||
- ctx->descriptor.image_size != image_size)
+ ctx->descriptor.image_size > max_size)
{
- CPRINTS(ctx, "validate_descriptor: invalid descriptor");
+ CPRINTS(ctx, "validate_descriptor: invalid descriptor\n");
+ return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
+ }
+ if (intf->image_size_valid == NULL)
+ {
+ // Preserve original behavior of requiring exact image_size match if
+ // no operator is provided.
+ if (ctx->descriptor.image_size != max_size)
+ {
+ CPRINTS(ctx, "validate_descriptor: invalid image size\n");
+ return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
+ }
+ }
+ else if (!intf->image_size_valid(ctx->descriptor.image_size))
+ {
+ CPRINTS(ctx, "validate_descriptor: invalid image size\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
if (ctx->descriptor.image_type != IMAGE_DEV &&
@@ -695,7 +712,7 @@
ctx->descriptor.image_type != IMAGE_TEST &&
ctx->descriptor.image_type != IMAGE_UNSIGNED_INTEGRITY)
{
- CPRINTS(ctx, "validate_descriptor: bad image type");
+ CPRINTS(ctx, "validate_descriptor: bad image type\n");
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
// Although the image_descriptor struct supports unauthenticated
@@ -712,13 +729,13 @@
rv = is_hash_type_supported(ctx->descriptor.hash_type);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate_payload_regions: invalid hash type");
+ CPRINTS(ctx, "validate_payload_regions: invalid hash type\n");
return rv;
}
if (ctx->descriptor.descriptor_major > MAX_MAJOR_VERSION ||
ctx->descriptor.region_count > LIBCR51SIGN_MAX_REGION_COUNT)
{
- CPRINTS(ctx, "validate_descriptor: unsupported descriptor");
+ CPRINTS(ctx, "validate_descriptor: unsupported descriptor\n");
return LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR;
}
rv =
@@ -751,7 +768,7 @@
if (ctx->descriptor.blob_size >
ctx->descriptor.descriptor_area_size - signed_size)
{
- CPRINTS(ctx, "validate_descriptor: invalid blob size (0x%x)",
+ CPRINTS(ctx, "validate_descriptor: invalid blob size (0x%x)\n",
ctx->descriptor.blob_size);
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
}
@@ -762,7 +779,7 @@
{
CPRINTS(ctx,
"validate_descriptor: invalid descriptor area size "
- "(expected = 0x%x, actual = 0x%x)",
+ "(expected = 0x%x, actual = 0x%x)\n",
ctx->descriptor.descriptor_area_size,
signed_size + signature_struct_size);
return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
@@ -814,7 +831,7 @@
if (!intf->read)
{
- CPRINTS(ctx, "scan_for_magic_8: missing intf->read");
+ CPRINTS(ctx, "scan_for_magic_8: missing intf->read\n");
return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
}
// Align start_offset to the next valid boundary.
@@ -866,12 +883,12 @@
if (!ctx)
{
- CPRINTS(ctx, "MIssing context");
+ CPRINTS(ctx, "Missing context\n");
return LIBCR51SIGN_ERROR_INVALID_CONTEXT;
}
else if (!intf)
{
- CPRINTS(ctx, "Missing interface");
+ CPRINTS(ctx, "Missing interface\n");
return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
}
@@ -880,7 +897,7 @@
&descriptor_offset);
while (rv == LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate: potential image descriptor found @%x ",
+ CPRINTS(ctx, "validate: potential image descriptor found @%x\n",
descriptor_offset);
// Validation is split into 2 functions to minimize
// stack usage.
@@ -890,7 +907,7 @@
ctx->end_offset - ctx->start_offset);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate: validate_descriptor() failed ec%d ",
+ CPRINTS(ctx, "validate: validate_descriptor() failed ec%d\n",
rv);
}
@@ -900,11 +917,11 @@
ctx, intf, descriptor_offset, image_regions);
if (rv == LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "validate: success!");
+ CPRINTS(ctx, "validate: success!\n");
return rv;
}
CPRINTS(ctx,
- "validate: validate_payload_regions() failed ec%d ",
+ "validate: validate_payload_regions() failed ec%d\n",
rv);
}
// Store the first desc fail reason if any
@@ -919,7 +936,7 @@
descriptor_offset, image_limit,
DESCRIPTOR_ALIGNMENT, &descriptor_offset);
}
- CPRINTS(ctx, "validate: failed to validate image ec%d ", rv);
+ CPRINTS(ctx, "validate: failed to validate image ec%d\n", rv);
// If desc validation failed for some reason then return that reason
if (rv_first_desc != LIBCR51SIGN_SUCCESS)
return rv_first_desc;
diff --git a/subprojects/libcr51sign/src/libcr51sign_support.c b/subprojects/libcr51sign/src/libcr51sign_support.c
index 4e9c517..6dddf23 100644
--- a/subprojects/libcr51sign/src/libcr51sign_support.c
+++ b/subprojects/libcr51sign/src/libcr51sign_support.c
@@ -122,11 +122,12 @@
// By default returns error.
int rv = LIBCR51SIGN_ERROR_INVALID_ARGUMENT;
- CPRINTS(ctx, "\n sig_len %zu sig: ", sig_len);
+ CPRINTS(ctx, "sig_len %zu sig: ", sig_len);
for (size_t i = 0; i < sig_len; i++)
{
CPRINTS(ctx, "%x", sig[i]);
}
+ CPRINTS(ctx, "\n");
struct libcr51sign_ctx* lctx = (struct libcr51sign_ctx*)ctx;
FILE* fp = fopen(lctx->keyring, "r");
@@ -135,14 +136,14 @@
BIO* bio = BIO_new(BIO_s_mem());
if (!fp)
{
- CPRINTS(ctx, "\n fopen failed: ");
+ CPRINTS(ctx, "fopen failed\n");
goto clean_up;
}
pkey = PEM_read_PUBKEY(fp, 0, 0, 0);
if (!pkey)
{
- CPRINTS(ctx, "\n Read public key failed: ");
+ CPRINTS(ctx, "Read public key failed\n");
goto clean_up;
}
@@ -154,14 +155,14 @@
pub_rsa = RSAPublicKey_dup(rsa);
if (!RSA_print(bio, pub_rsa, 2))
{
- CPRINTS(ctx, "\n RSA print failed ");
+ CPRINTS(ctx, "RSA print failed\n");
}
if (!pub_rsa)
{
- CPRINTS(ctx, "\n no pub rsa: ");
+ CPRINTS(ctx, "no pub RSA\n");
goto clean_up;
}
- CPRINTS(ctx, "\n public rsa \n");
+ CPRINTS(ctx, "public RSA\n");
char buffer[1024];
while (BIO_read(bio, buffer, sizeof(buffer) - 1) > 0)
{
@@ -171,7 +172,7 @@
rv = get_hash_type_from_signature(sig_scheme, &hash_type);
if (rv != LIBCR51SIGN_SUCCESS)
{
- CPRINTS(ctx, "\n Invalid hash_type! \n");
+ CPRINTS(ctx, "Invalid hash_type!\n");
goto clean_up;
}
int hash_nid = -1;
@@ -193,25 +194,28 @@
// OpenSSL RSA_verify returns 1 on success and 0 on failure
if (!ret)
{
- CPRINTS(ctx, "\n OPENSSL_ERROR: %s \n",
+ CPRINTS(ctx, "OPENSSL_ERROR: %s\n",
ERR_error_string(ERR_get_error(), NULL));
rv = LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
goto clean_up;
}
rv = LIBCR51SIGN_SUCCESS;
- CPRINTS(ctx, "\n sig: ");
+ CPRINTS(ctx, "sig: ");
for (size_t i = 0; i < sig_len; i++)
{
CPRINTS(ctx, "%x", sig[i]);
}
+ CPRINTS(ctx, "\n");
- CPRINTS(ctx, "\n data: ");
+ CPRINTS(ctx, "data: ");
for (size_t i = 0; i < data_len; i++)
{
CPRINTS(ctx, "%x", data[i]);
}
+ CPRINTS(ctx, "\n");
+
const unsigned rsa_size = RSA_size(pub_rsa);
- CPRINTS(ctx, "\n rsa size %d sig_len %d", rsa_size, (uint32_t)sig_len);
+ CPRINTS(ctx, "rsa size %d sig_len %d\n", rsa_size, (uint32_t)sig_len);
clean_up:
if (fp)