libavb_atx: Remove GSK rollback index and increase key size.
- The GSK rollback index was redundant with existing vbmeta rollback
protection. It has been removed.
- ATX now uses 4096-bit keys.
- Added a test data generator script.
This change breaks compatibility of ATX data structures.
Bug: 35767054
Test: unit tests
Change-Id: Ifff377c88abd531a394afe9e71fbc1307a7f834e
diff --git a/avbtool b/avbtool
index 6ebbd8c..a855e84 100755
--- a/avbtool
+++ b/avbtool
@@ -2570,14 +2570,8 @@
signature = bytearray()
if authority_key_path:
padding_and_hash = bytearray()
- algorithm_name = None
- hasher = None
- if is_intermediate_authority:
- hasher = hashlib.sha512()
- algorithm_name = 'SHA512_RSA4096'
- else:
- hasher = hashlib.sha256()
- algorithm_name = 'SHA256_RSA2048'
+ algorithm_name = 'SHA512_RSA4096'
+ hasher = hashlib.sha512()
padding_and_hash.extend(ALGORITHMS[algorithm_name].padding)
hasher.update(signed_data)
padding_and_hash.extend(hasher.digest())
@@ -2602,14 +2596,15 @@
Raises:
AvbError: If an argument is incorrect.
"""
- if len(product_id) != 16:
+ EXPECTED_PRODUCT_ID_SIZE = 16
+ if len(product_id) != EXPECTED_PRODUCT_ID_SIZE:
raise AvbError('Invalid Product ID length.')
output.write(struct.pack('<I', 1)) # Format Version
write_rsa_key(output, Crypto.PublicKey.RSA.importKey(root_authority_key))
output.write(product_id)
def make_atx_metadata(self, output, intermediate_key_certificate,
- product_key_certificate, google_key_version):
+ product_key_certificate):
"""Implements the 'make_atx_metadata' command.
Android Things metadata are included in vbmeta images to facilitate
@@ -2624,20 +2619,18 @@
product_key_certificate: A certificate file as output by
make_atx_certificate with
is_intermediate_authority set to false.
- google_key_version: The version of the Google Signing Key used in the
- associated vbmeta image.
Raises:
AvbError: If an argument is incorrect.
"""
- if len(intermediate_key_certificate) != 1108:
+ EXPECTED_CERTIFICATE_SIZE = 1620
+ if len(intermediate_key_certificate) != EXPECTED_CERTIFICATE_SIZE:
raise AvbError('Invalid intermediate key certificate length.')
- if len(product_key_certificate) != 852:
+ if len(product_key_certificate) != EXPECTED_CERTIFICATE_SIZE:
raise AvbError('Invalid product key certificate length.')
output.write(struct.pack('<I', 1)) # Format Version
output.write(intermediate_key_certificate)
output.write(product_key_certificate)
- output.write(struct.pack('<Q', google_key_version))
def calc_hash_level_offsets(image_size, block_size, digest_size):
@@ -3098,10 +3091,6 @@
help='Path to product key certificate file',
type=argparse.FileType('rb'),
required=True)
- sub_parser.add_argument('--google_key_version',
- help=('Version of the Google signing key'),
- type=parse_number,
- default=0)
sub_parser.set_defaults(func=self.make_atx_metadata)
args = parser.parse_args(argv[1:])
@@ -3203,8 +3192,7 @@
"""Implements the 'make_atx_metadata' sub-command."""
self.avb.make_atx_metadata(args.output,
args.intermediate_key_certificate.read(),
- args.product_key_certificate.read(),
- args.google_key_version)
+ args.product_key_certificate.read())
if __name__ == '__main__':
diff --git a/libavb_atx/avb_atx_types.h b/libavb_atx/avb_atx_types.h
index ae1b438..6d69859 100644
--- a/libavb_atx/avb_atx_types.h
+++ b/libavb_atx/avb_atx_types.h
@@ -39,46 +39,36 @@
/* Size in bytes of an Android Things product ID. */
#define AVB_ATX_PRODUCT_ID_SIZE 16
-/* Size in bytes of a serialized public key with a 2048-bit modulus. */
-#define AVB_ATX_PUBLIC_KEY_SIZE_2048 (sizeof(AvbRSAPublicKeyHeader) + 512)
-
/* Size in bytes of a serialized public key with a 4096-bit modulus. */
-#define AVB_ATX_PUBLIC_KEY_SIZE_4096 (sizeof(AvbRSAPublicKeyHeader) + 1024)
+#define AVB_ATX_PUBLIC_KEY_SIZE (sizeof(AvbRSAPublicKeyHeader) + 1024)
/* Data structure of Android Things permanent attributes. */
typedef struct AvbAtxPermanentAttributes {
uint32_t version;
- uint8_t product_root_public_key[AVB_ATX_PUBLIC_KEY_SIZE_4096];
+ uint8_t product_root_public_key[AVB_ATX_PUBLIC_KEY_SIZE];
uint8_t product_id[AVB_ATX_PRODUCT_ID_SIZE];
} AVB_ATTR_PACKED AvbAtxPermanentAttributes;
/* Data structure of signed fields in an Android Things certificate. */
typedef struct AvbAtxCertificateSignedData {
uint32_t version;
- uint8_t public_key[AVB_ATX_PUBLIC_KEY_SIZE_2048];
+ uint8_t public_key[AVB_ATX_PUBLIC_KEY_SIZE];
uint8_t subject[AVB_SHA256_DIGEST_SIZE];
uint8_t usage[AVB_SHA256_DIGEST_SIZE];
uint64_t key_version;
} AVB_ATTR_PACKED AvbAtxCertificateSignedData;
-/* Data structure of a certificate signed by a 4096-bit key. */
-typedef struct AvbAtxCertificate4096 {
+/* Data structure of an Android Things certificate. */
+typedef struct AvbAtxCertificate {
AvbAtxCertificateSignedData signed_data;
uint8_t signature[AVB_RSA4096_NUM_BYTES];
-} AVB_ATTR_PACKED AvbAtxCertificate4096;
-
-/* Data structure of a certificate signed by a 2048-bit key. */
-typedef struct AvbAtxCertificate2048 {
- AvbAtxCertificateSignedData signed_data;
- uint8_t signature[AVB_RSA2048_NUM_BYTES];
-} AVB_ATTR_PACKED AvbAtxCertificate2048;
+} AVB_ATTR_PACKED AvbAtxCertificate;
/* Data structure of Android Things public key metadata in vbmeta. */
typedef struct AvbAtxPublicKeyMetadata {
uint32_t version;
- AvbAtxCertificate4096 product_intermediate_key_certificate;
- AvbAtxCertificate2048 product_signing_key_certificate;
- uint64_t google_signing_key_version;
+ AvbAtxCertificate product_intermediate_key_certificate;
+ AvbAtxCertificate product_signing_key_certificate;
} AVB_ATTR_PACKED AvbAtxPublicKeyMetadata;
#ifdef __cplusplus
diff --git a/libavb_atx/avb_atx_validate.c b/libavb_atx/avb_atx_validate.c
index 7a29d66..fb200c1 100644
--- a/libavb_atx/avb_atx_validate.c
+++ b/libavb_atx/avb_atx_validate.c
@@ -74,17 +74,16 @@
return true;
}
-/* Verifies signature and fields of a PIK certificate. */
-static bool verify_pik_certificate(
- AvbAtxCertificate4096* certificate,
- uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE_4096],
- uint64_t minimum_version) {
+/* Verifies the format, key version, usage, and signature of a certificate. */
+static bool verify_certificate(AvbAtxCertificate* certificate,
+ uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
+ uint64_t minimum_key_version,
+ uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE]) {
const AvbAlgorithmData* algorithm_data;
uint8_t certificate_hash[AVB_SHA512_DIGEST_SIZE];
- uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
if (certificate->signed_data.version != 1) {
- avb_error("Unsupported PIK certificate format.\n");
+ avb_error("Unsupported certificate format.\n");
return false;
}
algorithm_data = avb_get_algorithm_data(AVB_ALGORITHM_TYPE_SHA512_RSA4096);
@@ -92,25 +91,39 @@
sizeof(AvbAtxCertificateSignedData),
certificate_hash);
if (!avb_rsa_verify(authority,
- AVB_ATX_PUBLIC_KEY_SIZE_4096,
+ AVB_ATX_PUBLIC_KEY_SIZE,
certificate->signature,
AVB_RSA4096_NUM_BYTES,
certificate_hash,
AVB_SHA512_DIGEST_SIZE,
algorithm_data->padding,
algorithm_data->padding_len)) {
- avb_error("Invalid PIK certificate signature.\n");
+ avb_error("Invalid certificate signature.\n");
return false;
}
- sha256_str("com.google.android.things.vboot.ca", expected_usage);
+ if (certificate->signed_data.key_version < minimum_key_version) {
+ avb_error("Key rollback detected.\n");
+ return false;
+ }
if (0 != avb_safe_memcmp(certificate->signed_data.usage,
expected_usage,
AVB_SHA256_DIGEST_SIZE)) {
- avb_error("Invalid PIK certificate usage.\n");
+ avb_error("Invalid certificate usage.\n");
return false;
}
- if (certificate->signed_data.key_version < minimum_version) {
- avb_error("PIK rollback detected.\n");
+ return true;
+}
+
+/* Verifies signature and fields of a PIK certificate. */
+static bool verify_pik_certificate(AvbAtxCertificate* certificate,
+ uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
+ uint64_t minimum_version) {
+ uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
+
+ sha256_str("com.google.android.things.vboot.ca", expected_usage);
+ if (!verify_certificate(
+ certificate, authority, minimum_version, expected_usage)) {
+ avb_error("Invalid PIK certificate.\n");
return false;
}
return true;
@@ -118,31 +131,17 @@
/* Verifies signature and fields of a PSK certificate. */
static bool verify_psk_certificate(
- AvbAtxCertificate2048* certificate,
- uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE_2048],
+ AvbAtxCertificate* certificate,
+ uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
uint64_t minimum_version,
uint8_t product_id[AVB_ATX_PRODUCT_ID_SIZE]) {
- const AvbAlgorithmData* algorithm_data;
- uint8_t certificate_hash[AVB_SHA256_DIGEST_SIZE];
uint8_t expected_subject[AVB_SHA256_DIGEST_SIZE];
uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
- if (certificate->signed_data.version != 1) {
- avb_error("Unsupported PSK certificate format.\n");
- return false;
- }
- algorithm_data = avb_get_algorithm_data(AVB_ALGORITHM_TYPE_SHA256_RSA2048);
- sha256((const uint8_t*)&certificate->signed_data,
- sizeof(AvbAtxCertificateSignedData),
- certificate_hash);
- if (!avb_rsa_verify(authority,
- AVB_ATX_PUBLIC_KEY_SIZE_2048,
- certificate->signature,
- AVB_RSA2048_NUM_BYTES,
- certificate_hash,
- AVB_SHA256_DIGEST_SIZE,
- algorithm_data->padding,
- algorithm_data->padding_len)) {
- avb_error("Invalid PSK certificate signature.\n");
+
+ sha256_str("com.google.android.things.vboot", expected_usage);
+ if (!verify_certificate(
+ certificate, authority, minimum_version, expected_usage)) {
+ avb_error("Invalid PSK certificate.\n");
return false;
}
sha256(product_id, AVB_ATX_PRODUCT_ID_SIZE, expected_subject);
@@ -152,17 +151,6 @@
avb_error("Product ID mismatch.\n");
return false;
}
- sha256_str("com.google.android.things.vboot", expected_usage);
- if (0 != avb_safe_memcmp(certificate->signed_data.usage,
- expected_usage,
- AVB_SHA256_DIGEST_SIZE)) {
- avb_error("Invalid PSK certificate usage.\n");
- return false;
- }
- if (certificate->signed_data.key_version < minimum_version) {
- avb_error("PSK rollback detected.\n");
- return false;
- }
return true;
}
@@ -179,7 +167,8 @@
AvbAtxPublicKeyMetadata metadata;
uint64_t minimum_version;
- /* Be pessimistic so we can exit early without having to remember to clear. */
+ /* Be pessimistic so we can exit early without having to remember to clear.
+ */
*out_is_trusted = false;
/* Read and verify permanent attributes. */
@@ -240,30 +229,18 @@
}
/* Verify the PSK is the same key that verified vbmeta. */
- if (public_key_length != AVB_ATX_PUBLIC_KEY_SIZE_2048) {
+ if (public_key_length != AVB_ATX_PUBLIC_KEY_SIZE) {
avb_error("Public key length mismatch.\n");
return AVB_IO_RESULT_OK;
}
if (0 != avb_safe_memcmp(
metadata.product_signing_key_certificate.signed_data.public_key,
public_key_data,
- AVB_ATX_PUBLIC_KEY_SIZE_2048)) {
+ AVB_ATX_PUBLIC_KEY_SIZE)) {
avb_error("Public key mismatch.\n");
return AVB_IO_RESULT_OK;
}
- /* Verify the GSK minimum version. */
- result = ops->read_rollback_index(
- ops, AVB_ATX_GSK_VERSION_LOCATION, &minimum_version);
- if (result != AVB_IO_RESULT_OK) {
- avb_error("Failed to read GSK minimum version.\n");
- return result;
- }
- if (metadata.google_signing_key_version < minimum_version) {
- avb_error("Google signing key rollback detected.\n");
- return AVB_IO_RESULT_OK;
- }
-
*out_is_trusted = true;
return AVB_IO_RESULT_OK;
}
diff --git a/libavb_atx/avb_atx_validate.h b/libavb_atx/avb_atx_validate.h
index 07c154e..41faac1 100644
--- a/libavb_atx/avb_atx_validate.h
+++ b/libavb_atx/avb_atx_validate.h
@@ -40,7 +40,6 @@
/* Rollback index locations for Android Things key versions. */
#define AVB_ATX_PIK_VERSION_LOCATION 0x1000
#define AVB_ATX_PSK_VERSION_LOCATION 0x1001
-#define AVB_ATX_GSK_VERSION_LOCATION 0x1002
/* An implementation of validate_vbmeta_public_key for Android Things. See
* libavb/avb_ops.h for details on validate_vbmeta_public_key in general. This
@@ -59,10 +58,6 @@
* - Product Signing Key (PSK): This key is a rotated authority for a specific
* Android Things product. It is certified by a
* PIK and must match |public_key_data|.
- * - Google Signing Key (GSK): This key is a rotated authority for system and
- * boot partitions built by Google. The key is
- * already verified as part of vbmeta so only the
- * key version needs verification here.
* - Product ID: This value is provided in permanent attributes and is unique
* to a specific Android Things product. This value must match
* the subject of the PSK certificate.
diff --git a/test/avb_atx_generate_test_data b/test/avb_atx_generate_test_data
new file mode 100755
index 0000000..019c845
--- /dev/null
+++ b/test/avb_atx_generate_test_data
@@ -0,0 +1,81 @@
+#!/bin/bash
+
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use, copy,
+# modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+# This shell-script generates ATX test data in the working directory.
+# An avbtool executable is assumed to reside in the parent directory
+# of this script.
+#
+# The *atx* test data in the test/data/ directory was generated with
+# this script. It is consistent with the expectations of avbtool unit
+# tests and ATX unit tests. This script exists as a record of how the
+# data was generated and as a convenience if it ever needs to be
+# generated again.
+#
+# Typical usage:
+#
+# $ cd test/data; ../avb_atx_generate_test_data
+
+set -e
+
+TMP_FILE=$(mktemp /tmp/atx_generator.XXXXXXXXXX)
+trap "rm -f '${TMP_FILE}'" EXIT
+
+AVBTOOL=$(dirname "$0")/../avbtool
+
+echo AVBTOOL = ${AVBTOOL}
+
+# Get a random product ID.
+head -c 16 /dev/urandom > atx_product_id.bin
+
+# Generate key pairs.
+openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM \
+ -out testkey_atx_prk.pem
+openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM \
+ -out testkey_atx_pik.pem
+openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM \
+ -out testkey_atx_psk.pem
+
+# Construct permanent attributes.
+${AVBTOOL} make_atx_permanent_attributes --output=atx_permanent_attributes.bin \
+ --product_id=atx_product_id.bin --root_authority_key=testkey_atx_prk.pem
+
+# Construct a PIK certificate.
+echo -n "fake PIK subject" > ${TMP_FILE}
+${AVBTOOL} make_atx_certificate --output=atx_pik_certificate.bin \
+ --subject=${TMP_FILE} --subject_key=testkey_atx_pik.pem \
+ --subject_is_intermediate_authority --subject_key_version 42 \
+ --authority_key=testkey_atx_prk.pem
+
+# Construct a PSK certificate.
+${AVBTOOL} make_atx_certificate --output=atx_psk_certificate.bin \
+ --subject=atx_product_id.bin --subject_key=testkey_atx_psk.pem \
+ --subject_key_version 42 --authority_key=testkey_atx_pik.pem
+
+# Construct metadata.
+${AVBTOOL} make_atx_metadata --output=atx_metadata.bin \
+ --intermediate_key_certificate=atx_pik_certificate.bin \
+ --product_key_certificate=atx_psk_certificate.bin
+
diff --git a/test/avb_atx_validate_unittest.cc b/test/avb_atx_validate_unittest.cc
index 6efa856..1436b0b 100644
--- a/test/avb_atx_validate_unittest.cc
+++ b/test/avb_atx_validate_unittest.cc
@@ -42,8 +42,8 @@
const char kMetadataPath[] = "test/data/atx_metadata.bin";
const char kPermanentAttributesPath[] =
"test/data/atx_permanent_attributes.bin";
-const char kPRKPrivateKeyPath[] = "test/data/testkey_rsa4096.pem";
-const char kPIKPrivateKeyPath[] = "test/data/testkey_rsa2048.pem";
+const char kPRKPrivateKeyPath[] = "test/data/testkey_atx_prk.pem";
+const char kPIKPrivateKeyPath[] = "test/data/testkey_atx_pik.pem";
class ScopedRSA {
public:
@@ -59,24 +59,16 @@
}
}
- // PKCS #1 v1.5 signature using SHA512 if |rsa_| is 4096 bits, SHA256
- // otherwise. Returns true on success.
+ // PKCS #1 v1.5 signature using SHA512. Returns true on success.
bool Sign(const void* data_to_sign, size_t length, uint8_t signature[]) {
- bool use_sha512 = (RSA_size(rsa_) == AVB_RSA4096_NUM_BYTES);
uint8_t digest[AVB_SHA512_DIGEST_SIZE];
- unsigned int digest_size =
- use_sha512 ? AVB_SHA512_DIGEST_SIZE : AVB_SHA256_DIGEST_SIZE;
const unsigned char* data_to_sign_buf =
reinterpret_cast<const unsigned char*>(data_to_sign);
- if (use_sha512) {
- SHA512(data_to_sign_buf, length, digest);
- } else {
- SHA256(data_to_sign_buf, length, digest);
- }
+ SHA512(data_to_sign_buf, length, digest);
unsigned int signature_length = 0;
- return (1 == RSA_sign(use_sha512 ? NID_sha512 : NID_sha256,
+ return (1 == RSA_sign(NID_sha512,
digest,
- digest_size,
+ AVB_SHA512_DIGEST_SIZE,
signature,
&signature_length,
rsa_));
@@ -98,9 +90,8 @@
ReadDefaultData();
ops_.set_delegate(this);
ops_.set_permanent_attributes(attributes_);
- ops_.set_stored_rollback_indexes({{AVB_ATX_PIK_VERSION_LOCATION, 0},
- {AVB_ATX_PSK_VERSION_LOCATION, 0},
- {AVB_ATX_GSK_VERSION_LOCATION, 0}});
+ ops_.set_stored_rollback_indexes(
+ {{AVB_ATX_PIK_VERSION_LOCATION, 0}, {AVB_ATX_PSK_VERSION_LOCATION, 0}});
}
// FakeAvbOpsDelegate methods.
@@ -137,9 +128,7 @@
if ((fail_read_pik_rollback_index_ &&
rollback_index_slot == AVB_ATX_PIK_VERSION_LOCATION) ||
(fail_read_psk_rollback_index_ &&
- rollback_index_slot == AVB_ATX_PSK_VERSION_LOCATION) ||
- (fail_read_gsk_rollback_index_ &&
- rollback_index_slot == AVB_ATX_GSK_VERSION_LOCATION)) {
+ rollback_index_slot == AVB_ATX_PSK_VERSION_LOCATION)) {
return AVB_IO_RESULT_ERROR_IO;
}
return ops_.read_rollback_index(
@@ -188,7 +177,7 @@
return avb_atx_validate_vbmeta_public_key(
ops_.avb_ops(),
metadata_.product_signing_key_certificate.signed_data.public_key,
- AVB_ATX_PUBLIC_KEY_SIZE_2048,
+ AVB_ATX_PUBLIC_KEY_SIZE,
reinterpret_cast<const uint8_t*>(&metadata_),
sizeof(metadata_),
is_trusted);
@@ -208,7 +197,7 @@
void SignPSKCertificate() {
memset(metadata_.product_signing_key_certificate.signature,
0,
- AVB_RSA2048_NUM_BYTES);
+ AVB_RSA4096_NUM_BYTES);
ScopedRSA key(kPIKPrivateKeyPath);
ASSERT_TRUE(key.Sign(&metadata_.product_signing_key_certificate.signed_data,
sizeof(AvbAtxCertificateSignedData),
@@ -222,7 +211,6 @@
bool fail_read_permanent_attributes_hash_{false};
bool fail_read_pik_rollback_index_{false};
bool fail_read_psk_rollback_index_{false};
- bool fail_read_gsk_rollback_index_{false};
private:
void ReadDefaultData() {
@@ -251,7 +239,7 @@
std::string old_psk_sig(
reinterpret_cast<char*>(
metadata_.product_signing_key_certificate.signature),
- AVB_RSA2048_NUM_BYTES);
+ AVB_RSA4096_NUM_BYTES);
SignPIKCertificate();
SignPSKCertificate();
std::string new_pik_sig(
@@ -261,7 +249,7 @@
std::string new_psk_sig(
reinterpret_cast<char*>(
metadata_.product_signing_key_certificate.signature),
- AVB_RSA2048_NUM_BYTES);
+ AVB_RSA4096_NUM_BYTES);
EXPECT_EQ(old_pik_sig, new_pik_sig);
EXPECT_EQ(old_psk_sig, new_psk_sig);
bool is_trusted = false;
@@ -307,7 +295,7 @@
return avb_atx_validate_vbmeta_public_key(
ops_.avb_ops(),
metadata_.product_signing_key_certificate.signed_data.public_key,
- AVB_ATX_PUBLIC_KEY_SIZE_2048,
+ AVB_ATX_PUBLIC_KEY_SIZE,
reinterpret_cast<const uint8_t*>(&metadata_),
GetParam(),
is_trusted);
@@ -407,8 +395,7 @@
{{AVB_ATX_PIK_VERSION_LOCATION,
metadata_.product_intermediate_key_certificate.signed_data.key_version +
1},
- {AVB_ATX_PSK_VERSION_LOCATION, 0},
- {AVB_ATX_GSK_VERSION_LOCATION, 0}});
+ {AVB_ATX_PSK_VERSION_LOCATION, 0}});
bool is_trusted = true;
EXPECT_EQ(AVB_IO_RESULT_OK, Validate(&is_trusted));
EXPECT_FALSE(is_trusted);
@@ -484,8 +471,8 @@
ops_.set_stored_rollback_indexes(
{{AVB_ATX_PIK_VERSION_LOCATION, 0},
{AVB_ATX_PSK_VERSION_LOCATION,
- metadata_.product_signing_key_certificate.signed_data.key_version + 1},
- {AVB_ATX_GSK_VERSION_LOCATION, 0}});
+ metadata_.product_signing_key_certificate.signed_data.key_version +
+ 1}});
bool is_trusted = true;
EXPECT_EQ(AVB_IO_RESULT_OK, Validate(&is_trusted));
EXPECT_FALSE(is_trusted);
@@ -518,43 +505,25 @@
AvbAtxValidateTestWithPublicKeyLength,
::testing::Values(0,
1,
- AVB_ATX_PUBLIC_KEY_SIZE_2048 - 1,
- AVB_ATX_PUBLIC_KEY_SIZE_2048 + 1,
- AVB_ATX_PUBLIC_KEY_SIZE_4096,
+ AVB_ATX_PUBLIC_KEY_SIZE - 1,
+ AVB_ATX_PUBLIC_KEY_SIZE + 1,
+ AVB_ATX_PUBLIC_KEY_SIZE - 512,
-1));
TEST_F(AvbAtxValidateTest, PSKMismatch) {
- uint8_t bad_key[AVB_ATX_PUBLIC_KEY_SIZE_2048] = {};
+ uint8_t bad_key[AVB_ATX_PUBLIC_KEY_SIZE] = {};
bool is_trusted = true;
EXPECT_EQ(AVB_IO_RESULT_OK,
avb_atx_validate_vbmeta_public_key(
ops_.avb_ops(),
bad_key,
- AVB_ATX_PUBLIC_KEY_SIZE_2048,
+ AVB_ATX_PUBLIC_KEY_SIZE,
reinterpret_cast<const uint8_t*>(&metadata_),
sizeof(metadata_),
&is_trusted));
EXPECT_FALSE(is_trusted);
}
-TEST_F(AvbAtxValidateTest, FailReadGSKRollbackIndex) {
- fail_read_gsk_rollback_index_ = true;
- bool is_trusted = true;
- EXPECT_EQ(AVB_IO_RESULT_ERROR_IO, Validate(&is_trusted));
- EXPECT_FALSE(is_trusted);
-}
-
-TEST_F(AvbAtxValidateTest, GSKRollback) {
- ops_.set_stored_rollback_indexes(
- {{AVB_ATX_PIK_VERSION_LOCATION, 0},
- {AVB_ATX_PSK_VERSION_LOCATION, 0},
- {AVB_ATX_GSK_VERSION_LOCATION,
- metadata_.google_signing_key_version + 1}});
- bool is_trusted = true;
- EXPECT_EQ(AVB_IO_RESULT_OK, Validate(&is_trusted));
- EXPECT_FALSE(is_trusted);
-}
-
// A fixture for testing avb_slot_verify() with ATX.
class AvbAtxSlotVerifyTest : public BaseAvbToolTest, public FakeAvbOpsDelegate {
public:
@@ -571,8 +540,7 @@
{2, 0},
{3, 0},
{AVB_ATX_PIK_VERSION_LOCATION, 0},
- {AVB_ATX_PSK_VERSION_LOCATION, 0},
- {AVB_ATX_GSK_VERSION_LOCATION, 0}});
+ {AVB_ATX_PSK_VERSION_LOCATION, 0}});
ops_.set_stored_is_device_unlocked(false);
}
@@ -665,13 +633,13 @@
std::string metadata_option = "--public_key_metadata=";
metadata_option += kMetadataPath;
GenerateVBMetaImage("vbmeta_a.img",
- "SHA256_RSA2048",
+ "SHA512_RSA4096",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"),
+ base::FilePath("test/data/testkey_atx_psk.pem"),
metadata_option);
ops_.set_expected_public_key(
- PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
+ PublicKeyAVB(base::FilePath("test/data/testkey_atx_psk.pem")));
AvbSlotVerifyData* slot_data = NULL;
const char* requested_partitions[] = {"boot", NULL};
diff --git a/test/avbtool_unittest.cc b/test/avbtool_unittest.cc
index 924dfbb..be53d55 100644
--- a/test/avbtool_unittest.cc
+++ b/test/avbtool_unittest.cc
@@ -1424,21 +1424,24 @@
}
TEST_F(AvbToolTest, MakeAtxPikCertificate) {
+ base::FilePath subject_path = testdir_.Append("tmp_subject");
+ ASSERT_TRUE(base::WriteFile(subject_path, "fake PIK subject", 16));
base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
EXPECT_COMMAND(
0,
- "openssl pkey -pubout -in test/data/testkey_rsa2048.pem -out %s",
+ "openssl pkey -pubout -in test/data/testkey_atx_pik.pem -out %s",
pubkey_path.value().c_str());
base::FilePath output_path = testdir_.Append("tmp_certificate.bin");
EXPECT_COMMAND(0,
"./avbtool make_atx_certificate"
- " --subject test/data/small_blob.bin"
+ " --subject %s"
" --subject_key %s"
" --subject_key_version 42"
" --subject_is_intermediate_authority"
- " --authority_key test/data/testkey_rsa4096.pem"
+ " --authority_key test/data/testkey_atx_prk.pem"
" --output %s",
+ subject_path.value().c_str(),
pubkey_path.value().c_str(),
output_path.value().c_str());
@@ -1451,7 +1454,7 @@
base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
EXPECT_COMMAND(
0,
- "openssl pkey -pubout -in test/data/testkey_rsa2048.pem -out %s",
+ "openssl pkey -pubout -in test/data/testkey_atx_psk.pem -out %s",
pubkey_path.value().c_str());
base::FilePath output_path = testdir_.Append("tmp_certificate.bin");
@@ -1460,7 +1463,7 @@
" --subject test/data/atx_product_id.bin"
" --subject_key %s"
" --subject_key_version 42"
- " --authority_key test/data/testkey_rsa2048.pem"
+ " --authority_key test/data/testkey_atx_pik.pem"
" --output %s",
pubkey_path.value().c_str(),
output_path.value().c_str());
@@ -1474,7 +1477,7 @@
base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
EXPECT_COMMAND(
0,
- "openssl pkey -pubout -in test/data/testkey_rsa4096.pem -out %s",
+ "openssl pkey -pubout -in test/data/testkey_atx_prk.pem -out %s",
pubkey_path.value().c_str());
base::FilePath output_path = testdir_.Append("tmp_attributes.bin");
@@ -1499,7 +1502,6 @@
"./avbtool make_atx_metadata"
" --intermediate_key_certificate test/data/atx_pik_certificate.bin"
" --product_key_certificate test/data/atx_psk_certificate.bin"
- " --google_key_version 42"
" --output %s",
output_path.value().c_str());
diff --git a/test/data/atx_metadata.bin b/test/data/atx_metadata.bin
index 3b53bbc..0915664 100644
--- a/test/data/atx_metadata.bin
+++ b/test/data/atx_metadata.bin
Binary files differ
diff --git a/test/data/atx_permanent_attributes.bin b/test/data/atx_permanent_attributes.bin
index be63c86..fe53db2 100644
--- a/test/data/atx_permanent_attributes.bin
+++ b/test/data/atx_permanent_attributes.bin
Binary files differ
diff --git a/test/data/atx_pik_certificate.bin b/test/data/atx_pik_certificate.bin
index d0b4a7b..6e01e6c 100644
--- a/test/data/atx_pik_certificate.bin
+++ b/test/data/atx_pik_certificate.bin
Binary files differ
diff --git a/test/data/atx_product_id.bin b/test/data/atx_product_id.bin
index d5648fa..59f5893 100644
--- a/test/data/atx_product_id.bin
+++ b/test/data/atx_product_id.bin
@@ -1 +1 @@
-tùAö®÷ ìí=±]
\ No newline at end of file
+?8˾VÌ=л5
§Ò
\ No newline at end of file
diff --git a/test/data/atx_psk_certificate.bin b/test/data/atx_psk_certificate.bin
index abec3ce..6710ae4 100644
--- a/test/data/atx_psk_certificate.bin
+++ b/test/data/atx_psk_certificate.bin
Binary files differ
diff --git a/test/data/testkey_atx_pik.pem b/test/data/testkey_atx_pik.pem
new file mode 100644
index 0000000..5f34cb9
--- /dev/null
+++ b/test/data/testkey_atx_pik.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDoTSKaxoiUJhZ9
+Wb4fT59s9ZZsyIjewnmAhS/+gPTeOY7L+cpo+iDSeTAOOAw++ZcQZiGeQLwLO6DK
+Aq2ujqi8ycwMx49aZsMcAKwyIMl2SoMZOgducS27z+Mzv4+FBoLV52eYVr+Idiat
+b2ogciK8TEviBF7URyQa6wsdGrY4HwG7kEBL1NiZngkl24U+HNHlzn9L3/C6pg39
+g5KIQyNNjIFzTqGnr1Q0lCNLCR/UP8NtQ0koUL26MeDJk8qANTkI3ihpw27CFmWy
+8R9VK7EDkAgs/C7dqBlcVJvVptu9Gih7Yltfsqeq23W87J/JvxE+NSU/iipITHZe
+1IdC2dhntAysKa5r+kikyO6uh9fN7siBzNBlTBRHtEaaNcOxaGMHf87J/SktamMT
+pvy+NIVe7bdjtDyyd4FVo5dS65QTBt//E5FKUrxShCP7ww2L65xbldXdBjE4JSyQ
+gpVrvDMne5+Ro0If1GYnfjgwsIWq/AAm7pZ8bzZOw0HtgjJbCI4HmkJG32wXAIzA
+L00S6nICiq4Q3oWnf1mNIDTM6hrcCJxAqS3t1JSqpM5EkTOFg0SZ3y83vcogxr2a
+NqP/LI+02FQRirgBwRWdngUbc7mbXG5jhuYirnl52ofzhzwWrGe/iKGzhzZWnjNx
+logXB9N2n7E14D0LzmLmE8sALnBr+wIDAQABAoICAHHI3otbdajDYz6xB4xErv1q
+6eyM6WXbcjI+irypo8d5//TvfHKhGhSeIajFUVJDZPg2Xn8qjDEgWui4GSSoYgRe
+/+C+mvwX27fKqI3BO40CgGaJ4vv42gLlmA9P5FevUcS+nSKkUxrfbKCFM0GDRnpf
+EMg7hcuKsSeyO3ZdECY7IdkilivOrO3J2AdAGGrNKQ7cb8PVhA+YqL+lg8/UuuUQ
+TpQRTuNY4PEEIqltZbbMKMhLLfleWyBpsAZsqsLTzwUF9Fuhy42r9NKKguNwDDuH
+gEmwmLAf15Q/KTmkint85ZlSGxmr466v4mLQsI/cU/DZjU4rOfzB3zUh+sMG+5UZ
+OB1aCHdMIxTMBfSUqehPNP7Fe59+OmwYezhMkfy7jJat81OobUvyqLwR/Nx5qNvs
+Ry5JOJaLPIouee9Dc3Wp1uEetgAfXj+0CmWyQCzdz5NkwX0nIssXr+9eUmlwgBO+
+FdY72z8Nf84h74aZqcN4ysqU14YeIjv95U5TFQJ7Dj72DDir33t61etCIDceUpxG
+y0gnGmnh7xZvVmP8rfnuXhbo4hNwxsXfReKQnP51V4yHIp2AtCReGwexRjGB6iky
+K3v2XHKJnRIUFd5y7vhEfo/jj/e1GU9P6FFznJLhET5RS07JDhWhZRyvwcoa+muv
+lxcFjysQb7z7dFGJSELBAoIBAQD7/Onpp9M5DniJnS8vVcFSpndpqd1M1f6ZBPQy
+Owh9LOVSdJoBsaMuXStilKGxA2BqS4Ty3fww6urIjqYYL0R4q9+dSYAWBX/cGx+/
+yypaPAMA/Vjv/0dPM9pY/lwyeIYUXYjU3sNewK3fgfvxc6piAAVwNfHCegbdHhNR
+gCmeeszhmSnbdFZXM9EyzTXpDVb3IWE9mhQ9oYNDxQgQplMcrb30z3AEAV9ZjwGU
++/elaBvvebPrl6un9drAO2qVXMinjCXJTiWaJdlNZkTeYCeGqXHt4xeZJUGeWdVa
+aI3s1MPPxxzXi4FlwND8sinnRdPh4w0ZjA9RlkumwCJMBgFhAoIBAQDr//ri23dX
+6qX7dmZvdrF9E5ksPZxPZBmBZ0ymSCgxWwHd6DC74EMv406BuccloBxIRW9YAe0/
+ZMNFvHYz/LPYa8eRFTcG34SSkMjWCPo0ywQFjAe0zpCJMpeqJ3BccZ51l5HjU4IH
+8BMW83LOE3f47D0W6Sy98T2eTvJPnJ/lqck6rDvWY/G8b5rwchrScIo6+gV5fPbm
+QX1fgyUrOrp5dfgDuAGfuEi/5ZoZKUNAX9KNREBV5XGqR+GPe3dxFwB50zA0aEQM
+NUUbb85vSD/JoABTgyw33B+ZXnVbQ3cH9/s/TfOtg+DcJCNv4FOY/CVF+jEAQI1a
+eiXrjYCjT/7bAoIBAQD69hoogOJWstjNhWRW6jtNi0jmTSx/t6iG0W47EJwVvr7t
+bf9rrHTuWhA5b/nRB6HgezH/h6IBPhVyhM9aysiQvexJA8izJer/VWw7YaXelGIR
+fEA1VbK5aNUPSNSd13cBlV4PU4SUO6VvMk+vWxjX3VmNNcx/eXSYh7mJs/C/S2H9
+VMNhMu5CjvLMe6AzaPuxyObFqUx7TP4kYnjzzBJ+P3Mt++J9urgxw8E5lfBAJf2c
+dUMBYd6tuqeQSByQgQW+CFAhutisOwG+mhoAtxbmgJ9c4ozAE2DUync4QWUH96bE
+qnNJIEFRC8WXxgEBuoOZNr33MYyYHu1dN4Fw4ZJBAoIBAHX9r3PIgiyEdqP4mFJW
+J3r/V2+VBhdzVoUqHlpsbRvwAkjuE597Clxg6xlUxsp6+Gjxvi9kFzfAqxislvR6
+/XfQuyBAWRiom+GjXaYVKvNGJSaY0imFtSHDF6zMtxKhA7aLJzdewv4w+3pYESgS
+98KOaiSQQ/xbJpGFqwQ+rHronmElR21y3qN1sSNSCTL5bUL7Sc1puw934rTkHqs0
+W5Lqdit1zeoK+uRmaNr3lFYVEnHqk7feVSvrcEyKUDdMZsKB4fHxx0PLRlfnWHCu
+0KV/x2n5hRwQhAPsBASzAEoNo6IM2S4BZ2To9Ia0w1cTiZco9WLI42M++sKAJraA
+Ak0CggEBALwQ3FKc/dc9j3lSx43RH29rOZDXACJdA7vwWRucmdXoTlKxtNEB+Q6A
+ycWsHsrgrfa1IqsXJu+uezDB3TlCq+YjElxUnZJopPJQJISRtaJYcMQ3GpU+eS+L
+6IhGPhOuzQ7HxgKyxFVrNi7SVpODKS305rZUI1BoY5zFuZtRjx6uDV4R4jIVZczV
+y9mXACViqGQBxRCIYV2W5iCPIzG02mzK62QilS+dqCGhKY4oTxfNzOy5huvtGXhK
+Y5bwRFG1RPZj8TAyp0WVUIXgyOyt6AgqUZpQW6LWgWxcJecCpPM2ch4adNyusNgi
+WM8yjCL8U3+kfP4L6uIgmAuVcmbrX68=
+-----END PRIVATE KEY-----
diff --git a/test/data/testkey_atx_prk.pem b/test/data/testkey_atx_prk.pem
new file mode 100644
index 0000000..17a8cce
--- /dev/null
+++ b/test/data/testkey_atx_prk.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+MSKHJYIcbmEACtr9tALUhZo5SkjMLrQ=
+-----END PRIVATE KEY-----
diff --git a/test/data/testkey_atx_psk.pem b/test/data/testkey_atx_psk.pem
new file mode 100644
index 0000000..71bfebf
--- /dev/null
+++ b/test/data/testkey_atx_psk.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+PqPOQDQM7f0JPuFGA9kFRaKUQygQckw=
+-----END PRIVATE KEY-----