summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorji.luo <ji.luo@nxp.com>2017-09-02 17:05:22 +0800
committerNeal <nealo@google.com>2017-09-19 16:46:19 -0700
commitba8138a09845c84765817ed7c7b040a18a084b73 (patch)
tree35210c8f3f21a4828619bb25058c9e9a8285f617
parentc95ea55ba4a065bb939caf771209bfbebde9818d (diff)
downloaduboot-imx-ba8138a09845c84765817ed7c7b040a18a084b73.tar.gz
Integrate ATX code into u-boot and fix build error
Change-Id: I6ab29f86df748d173954400d534f1fb3c990f5b9 Signed-off-by: ji.luo <ji.luo@nxp.com>
-rw-r--r--include/fsl_avb.h14
-rw-r--r--lib/Kconfig3
-rw-r--r--lib/avb/Makefile1
-rw-r--r--lib/avb/libavb_atx/Makefile2
-rw-r--r--lib/avb/libavb_atx/avb_atx_ops.h68
-rw-r--r--lib/avb/libavb_atx/avb_atx_types.h78
-rw-r--r--lib/avb/libavb_atx/avb_atx_validate.c246
-rw-r--r--lib/avb/libavb_atx/avb_atx_validate.h77
-rw-r--r--lib/avb/libavb_atx/libavb_atx.h41
9 files changed, 530 insertions, 0 deletions
diff --git a/include/fsl_avb.h b/include/fsl_avb.h
index 66aaec609a..56fb2eb1fb 100644
--- a/include/fsl_avb.h
+++ b/include/fsl_avb.h
@@ -8,6 +8,7 @@
#define __FSL_AVB_H__
#include "../lib/avb/libavb_ab/libavb_ab.h"
+#include "../lib/avb/libavb_atx/libavb_atx.h"
/* Reads |num_bytes| from offset |offset| from partition with name
* |partition| (NUL-terminated UTF-8 string). If |offset| is
* negative, its absolute value should be interpreted as the number
@@ -173,4 +174,17 @@ int avbkey_init(uint8_t *plainkey, uint32_t keylen);
* return slot suffix '_a'/'_b' or NULL */
char *select_slot(AvbABOps *ab_ops);
+/* Reads permanent |attributes| data. There are no restrictions on where this
+ * data is stored. On success, returns AVB_IO_RESULT_OK and populates
+ * |attributes|.
+ */
+AvbIOResult fsl_read_permanent_attributes(
+ AvbAtxOps* atx_ops, AvbAtxPermanentAttributes* attributes);
+
+/* Reads a |hash| of permanent attributes. This hash MUST be retrieved from a
+ * permanently read-only location (e.g. fuses) when a device is LOCKED. On
+ * success, returned AVB_IO_RESULT_OK and populates |hash|.
+ */
+AvbIOResult fsl_read_permanent_attributes_hash(
+ AvbAtxOps* atx_ops, uint8_t hash[AVB_SHA256_DIGEST_SIZE]);
#endif /* __FSL_AVB_H__ */
diff --git a/lib/Kconfig b/lib/Kconfig
index b16062fbe3..e2d2a73721 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -52,6 +52,9 @@ config LIB_RAND
help
This library provides pseudo-random number generator functions.
+config AVB_ATX
+ bool "Enable AVB_ATX support"
+
source lib/dhry/Kconfig
source lib/rsa/Kconfig
diff --git a/lib/avb/Makefile b/lib/avb/Makefile
index 60776e890c..371a594da4 100644
--- a/lib/avb/Makefile
+++ b/lib/avb/Makefile
@@ -12,4 +12,5 @@ subdir-ccflags-y += -D_FILE_OFFSET_BITS=64 \
-std=gnu99
obj-y += libavb/
obj-y += libavb_ab/
+obj-$(CONFIG_AVB_ATX) += libavb_atx/
obj-y += fsl/
diff --git a/lib/avb/libavb_atx/Makefile b/lib/avb/libavb_atx/Makefile
new file mode 100644
index 0000000000..bdd7bccbeb
--- /dev/null
+++ b/lib/avb/libavb_atx/Makefile
@@ -0,0 +1,2 @@
+ccflags-y += -DAVB_COMPILATION
+obj-y += avb_atx_validate.o
diff --git a/lib/avb/libavb_atx/avb_atx_ops.h b/lib/avb/libavb_atx/avb_atx_ops.h
new file mode 100644
index 0000000000..8d2196ba9c
--- /dev/null
+++ b/lib/avb/libavb_atx/avb_atx_ops.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#if !defined(AVB_INSIDE_LIBAVB_ATX_H) && !defined(AVB_COMPILATION)
+#error \
+ "Never include this file directly, include libavb_atx/libavb_atx.h instead."
+#endif
+
+#ifndef AVB_ATX_OPS_H_
+#define AVB_ATX_OPS_H_
+
+#include "../libavb/libavb.h"
+
+#include "../libavb_atx/avb_atx_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AvbAtxOps;
+typedef struct AvbAtxOps AvbAtxOps;
+
+/* An extension to AvbOps required by avb_atx_validate_vbmeta_public_key(). */
+struct AvbAtxOps {
+ /* Operations from libavb. */
+ AvbOps* ops;
+
+ /* Reads permanent |attributes| data. There are no restrictions on where this
+ * data is stored. On success, returns AVB_IO_RESULT_OK and populates
+ * |attributes|.
+ */
+ AvbIOResult (*read_permanent_attributes)(
+ AvbAtxOps* atx_ops, AvbAtxPermanentAttributes* attributes);
+
+ /* Reads a |hash| of permanent attributes. This hash MUST be retrieved from a
+ * permanently read-only location (e.g. fuses) when a device is LOCKED. On
+ * success, returned AVB_IO_RESULT_OK and populates |hash|.
+ */
+ AvbIOResult (*read_permanent_attributes_hash)(
+ AvbAtxOps* atx_ops, uint8_t hash[AVB_SHA256_DIGEST_SIZE]);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AVB_ATX_OPS_H_ */
diff --git a/lib/avb/libavb_atx/avb_atx_types.h b/lib/avb/libavb_atx/avb_atx_types.h
new file mode 100644
index 0000000000..07705498b2
--- /dev/null
+++ b/lib/avb/libavb_atx/avb_atx_types.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#if !defined(AVB_INSIDE_LIBAVB_ATX_H) && !defined(AVB_COMPILATION)
+#error \
+ "Never include this file directly, include libavb_atx/libavb_atx.h instead."
+#endif
+
+#ifndef AVB_ATX_TYPES_H_
+#define AVB_ATX_TYPES_H_
+
+#include "../libavb/libavb.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 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 4096-bit modulus. */
+#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];
+ 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];
+ 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 an Android Things certificate. */
+typedef struct AvbAtxCertificate {
+ AvbAtxCertificateSignedData signed_data;
+ uint8_t signature[AVB_RSA4096_NUM_BYTES];
+} AVB_ATTR_PACKED AvbAtxCertificate;
+
+/* Data structure of Android Things public key metadata in vbmeta. */
+typedef struct AvbAtxPublicKeyMetadata {
+ uint32_t version;
+ AvbAtxCertificate product_intermediate_key_certificate;
+ AvbAtxCertificate product_signing_key_certificate;
+} AVB_ATTR_PACKED AvbAtxPublicKeyMetadata;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AVB_ATX_TYPES_H_ */
diff --git a/lib/avb/libavb_atx/avb_atx_validate.c b/lib/avb/libavb_atx/avb_atx_validate.c
new file mode 100644
index 0000000000..3db455cd9b
--- /dev/null
+++ b/lib/avb/libavb_atx/avb_atx_validate.c
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+#include "../libavb_atx/avb_atx_validate.h"
+
+#include "../libavb/avb_rsa.h"
+#include "../libavb/avb_sha.h"
+#include "../libavb/avb_sysdeps.h"
+#include "../libavb/avb_util.h"
+
+/* Computes the SHA256 |hash| of |length| bytes of |data|. */
+static void sha256(const uint8_t* data,
+ uint32_t length,
+ uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
+ AvbSHA256Ctx context;
+ avb_sha256_init(&context);
+ avb_sha256_update(&context, data, length);
+ uint8_t* tmp = avb_sha256_final(&context);
+ avb_memcpy(hash, tmp, AVB_SHA256_DIGEST_SIZE);
+}
+
+/* Computes the SHA512 |hash| of |length| bytes of |data|. */
+static void sha512(const uint8_t* data,
+ uint32_t length,
+ uint8_t hash[AVB_SHA512_DIGEST_SIZE]) {
+ AvbSHA512Ctx context;
+ avb_sha512_init(&context);
+ avb_sha512_update(&context, data, length);
+ uint8_t* tmp = avb_sha512_final(&context);
+ avb_memcpy(hash, tmp, AVB_SHA512_DIGEST_SIZE);
+}
+
+/* Computes the SHA256 |hash| of a NUL-terminated |str|. */
+static void sha256_str(const char* str, uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
+ sha256((const uint8_t*)str, avb_strlen(str), hash);
+}
+
+/* Verifies structure and |expected_hash| of permanent |attributes|. */
+static bool verify_permanent_attributes(
+ const AvbAtxPermanentAttributes* attributes,
+ uint8_t expected_hash[AVB_SHA256_DIGEST_SIZE]) {
+ uint8_t hash[AVB_SHA256_DIGEST_SIZE];
+
+ if (attributes->version != 1) {
+ avb_error("Unsupported permanent attributes version.\n");
+ return false;
+ }
+ sha256((const uint8_t*)attributes, sizeof(AvbAtxPermanentAttributes), hash);
+ if (0 != avb_safe_memcmp(hash, expected_hash, AVB_SHA256_DIGEST_SIZE)) {
+ avb_error("Invalid permanent attributes.\n");
+ return false;
+ }
+ return true;
+}
+
+/* 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];
+
+ if (certificate->signed_data.version != 1) {
+ avb_error("Unsupported certificate format.\n");
+ return false;
+ }
+ algorithm_data = avb_get_algorithm_data(AVB_ALGORITHM_TYPE_SHA512_RSA4096);
+ sha512((const uint8_t*)&certificate->signed_data,
+ sizeof(AvbAtxCertificateSignedData),
+ certificate_hash);
+ if (!avb_rsa_verify(authority,
+ 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 certificate signature.\n");
+ return false;
+ }
+ 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 certificate usage.\n");
+ return false;
+ }
+ 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;
+}
+
+/* Verifies signature and fields of a PSK certificate. */
+static bool verify_psk_certificate(
+ AvbAtxCertificate* certificate,
+ uint8_t authority[AVB_ATX_PUBLIC_KEY_SIZE],
+ uint64_t minimum_version,
+ uint8_t product_id[AVB_ATX_PRODUCT_ID_SIZE]) {
+ uint8_t expected_subject[AVB_SHA256_DIGEST_SIZE];
+ uint8_t expected_usage[AVB_SHA256_DIGEST_SIZE];
+
+ 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);
+ if (0 != avb_safe_memcmp(certificate->signed_data.subject,
+ expected_subject,
+ AVB_SHA256_DIGEST_SIZE)) {
+ avb_error("Product ID mismatch.\n");
+ return false;
+ }
+ return true;
+}
+
+AvbIOResult avb_atx_validate_vbmeta_public_key(
+ AvbOps* ops,
+ const uint8_t* public_key_data,
+ size_t public_key_length,
+ const uint8_t* public_key_metadata,
+ size_t public_key_metadata_length,
+ bool* out_is_trusted) {
+ AvbIOResult result = AVB_IO_RESULT_OK;
+ AvbAtxPermanentAttributes permanent_attributes;
+ uint8_t permanent_attributes_hash[AVB_SHA256_DIGEST_SIZE];
+ AvbAtxPublicKeyMetadata metadata;
+ uint64_t minimum_version;
+
+ /* Be pessimistic so we can exit early without having to remember to clear.
+ */
+ *out_is_trusted = false;
+
+ /* Read and verify permanent attributes. */
+ result = ops->atx_ops->read_permanent_attributes(ops->atx_ops,
+ &permanent_attributes);
+ if (result != AVB_IO_RESULT_OK) {
+ avb_error("Failed to read permanent attributes.\n");
+ return result;
+ }
+ result = ops->atx_ops->read_permanent_attributes_hash(
+ ops->atx_ops, permanent_attributes_hash);
+ if (result != AVB_IO_RESULT_OK) {
+ avb_error("Failed to read permanent attributes hash.\n");
+ return result;
+ }
+ if (!verify_permanent_attributes(&permanent_attributes,
+ permanent_attributes_hash)) {
+ return AVB_IO_RESULT_OK;
+ }
+
+ /* Sanity check public key metadata. */
+ if (public_key_metadata_length != sizeof(AvbAtxPublicKeyMetadata)) {
+ avb_error("Invalid public key metadata.\n");
+ return AVB_IO_RESULT_OK;
+ }
+ avb_memcpy(&metadata, public_key_metadata, sizeof(AvbAtxPublicKeyMetadata));
+ if (metadata.version != 1) {
+ avb_error("Unsupported public key metadata.\n");
+ return AVB_IO_RESULT_OK;
+ }
+
+ /* Verify the PIK certificate. */
+ result = ops->read_rollback_index(
+ ops, AVB_ATX_PIK_VERSION_LOCATION, &minimum_version);
+ if (result != AVB_IO_RESULT_OK) {
+ avb_error("Failed to read PIK minimum version.\n");
+ return result;
+ }
+ if (!verify_pik_certificate(&metadata.product_intermediate_key_certificate,
+ permanent_attributes.product_root_public_key,
+ minimum_version)) {
+ return AVB_IO_RESULT_OK;
+ }
+
+ /* Verify the PSK certificate. */
+ result = ops->read_rollback_index(
+ ops, AVB_ATX_PSK_VERSION_LOCATION, &minimum_version);
+ if (result != AVB_IO_RESULT_OK) {
+ avb_error("Failed to read PSK minimum version.\n");
+ return result;
+ }
+ if (!verify_psk_certificate(
+ &metadata.product_signing_key_certificate,
+ metadata.product_intermediate_key_certificate.signed_data.public_key,
+ minimum_version,
+ permanent_attributes.product_id)) {
+ return AVB_IO_RESULT_OK;
+ }
+
+ /* Verify the PSK is the same key that verified vbmeta. */
+ 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)) {
+ avb_error("Public key mismatch.\n");
+ return AVB_IO_RESULT_OK;
+ }
+
+ *out_is_trusted = true;
+ return AVB_IO_RESULT_OK;
+}
diff --git a/lib/avb/libavb_atx/avb_atx_validate.h b/lib/avb/libavb_atx/avb_atx_validate.h
new file mode 100644
index 0000000000..a1a83a79a9
--- /dev/null
+++ b/lib/avb/libavb_atx/avb_atx_validate.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#if !defined(AVB_INSIDE_LIBAVB_ATX_H) && !defined(AVB_COMPILATION)
+#error \
+ "Never include this file directly, include libavb_atx/libavb_atx.h instead."
+#endif
+
+#ifndef AVB_ATX_VALIDATE_H_
+#define AVB_ATX_VALIDATE_H_
+
+#include "../libavb_atx/avb_atx_ops.h"
+#include "../libavb_atx/avb_atx_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Rollback index locations for Android Things key versions. */
+#define AVB_ATX_PIK_VERSION_LOCATION 0x1000
+#define AVB_ATX_PSK_VERSION_LOCATION 0x1001
+
+/* 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
+ * implementation uses the metadata expected with Android Things vbmeta images
+ * to perform validation on the public key. The ATX ops must be implemented.
+ * That is, |ops->atx_ops| must be valid.
+ *
+ * There are a multiple values that need verification:
+ * - Permanent Product Attributes: A hash of these attributes is fused into
+ * hardware. Consistency is checked.
+ * - Product Root Key (PRK): This key is provided in permanent attributes and
+ * is the root authority for all Android Things
+ * products.
+ * - Product Intermediate Key (PIK): This key is a rotated intermediary. It is
+ * certified by the PRK.
+ * - 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|.
+ * - 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.
+ */
+AvbIOResult avb_atx_validate_vbmeta_public_key(
+ AvbOps* ops,
+ const uint8_t* public_key_data,
+ size_t public_key_length,
+ const uint8_t* public_key_metadata,
+ size_t public_key_metadata_length,
+ bool* out_is_trusted);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AVB_ATX_VALIDATE_H_ */
diff --git a/lib/avb/libavb_atx/libavb_atx.h b/lib/avb/libavb_atx/libavb_atx.h
new file mode 100644
index 0000000000..90d1aad66d
--- /dev/null
+++ b/lib/avb/libavb_atx/libavb_atx.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef LIBAVB_ATX_H_
+#define LIBAVB_ATX_H_
+
+#include "../libavb/libavb.h"
+
+/* The AVB_INSIDE_LIBAVB_ATX_H preprocessor symbol is used to enforce
+ * library users to include only this file. All public interfaces, and
+ * only public interfaces, must be included here.
+ */
+
+#define AVB_INSIDE_LIBAVB_ATX_H
+#include "avb_atx_ops.h"
+#include "avb_atx_types.h"
+#include "avb_atx_validate.h"
+#undef AVB_INSIDE_LIBAVB_ATX_H
+
+#endif /* LIBAVB_ATX_H_ */