platform: msm_shared: Add changes as per AVB2.0 specs
As per the requirement of AVB2.0 current call flow aboot_init
is updated to make sure that device is booting with AVB2.0
enable.Fix kernel cmdline for recovery and add checks to verify
the boot image.
Change-Id: Icfb250eac71edf07ea6f6123ddd15c6aaaa1629f
diff --git a/include/err.h b/include/err.h
index 265c19c..b4e9c5a 100644
--- a/include/err.h
+++ b/include/err.h
@@ -51,5 +51,11 @@
#define ERR_RECURSE_TOO_DEEP -23
#define ERR_NOT_SUPPORTED -24
#define ERR_TOO_BIG -25
+#define EIO 5 /* I/O error */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define ENODEV 19 /* No such device */
+#define EINVAL 22 /* Invalid argument */
+
#endif
diff --git a/include/platform.h b/include/platform.h
index 55fd39e..f7a14cb 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -92,4 +92,7 @@
bool platform_is_mdm9206();
int is_vb_le_enabled();
void* get_rpmb_snd_rcv_buff();
+int LoadImage(char *Pname, void **ImgBuf, uint32_t *ImgSzActual);
+void boot_verifier_init();
+uint32_t get_page_size();
#endif
diff --git a/platform/msm_shared/avb/OEMPublicKey.h b/platform/msm_shared/avb/OEMPublicKey.h
new file mode 100644
index 0000000..6825696
--- /dev/null
+++ b/platform/msm_shared/avb/OEMPublicKey.h
@@ -0,0 +1,124 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef __OEM_PUBLIC_KEY_H__
+#define __OEM_PUBLIC_KEY_H__
+
+/**
+ * Internal builds use TestKeyRSA4096Public
+ * OEM should replace this Array with public key used to sign boot.img
+ * avbtool extract_public_key --key KEY --output OUTPUT
+ */
+static const char OEMPublicKey[] = {
+ 0x00, 0x00, 0x10, 0x00, 0x55, 0xd9, 0x04, 0xad, 0xd8, 0x04, 0xaf, 0xe3,
+ 0xd3, 0x84, 0x6c, 0x7e, 0x0d, 0x89, 0x3d, 0xc2, 0x8c, 0xd3, 0x12, 0x55,
+ 0xe9, 0x62, 0xc9, 0xf1, 0x0f, 0x5e, 0xcc, 0x16, 0x72, 0xab, 0x44, 0x7c,
+ 0x2c, 0x65, 0x4a, 0x94, 0xb5, 0x16, 0x2b, 0x00, 0xbb, 0x06, 0xef, 0x13,
+ 0x07, 0x53, 0x4c, 0xf9, 0x64, 0xb9, 0x28, 0x7a, 0x1b, 0x84, 0x98, 0x88,
+ 0xd8, 0x67, 0xa4, 0x23, 0xf9, 0xa7, 0x4b, 0xdc, 0x4a, 0x0f, 0xf7, 0x3a,
+ 0x18, 0xae, 0x54, 0xa8, 0x15, 0xfe, 0xb0, 0xad, 0xac, 0x35, 0xda, 0x3b,
+ 0xad, 0x27, 0xbc, 0xaf, 0xe8, 0xd3, 0x2f, 0x37, 0x34, 0xd6, 0x51, 0x2b,
+ 0x6c, 0x5a, 0x27, 0xd7, 0x96, 0x06, 0xaf, 0x6b, 0xb8, 0x80, 0xca, 0xfa,
+ 0x30, 0xb4, 0xb1, 0x85, 0xb3, 0x4d, 0xaa, 0xaa, 0xc3, 0x16, 0x34, 0x1a,
+ 0xb8, 0xe7, 0xc7, 0xfa, 0xf9, 0x09, 0x77, 0xab, 0x97, 0x93, 0xeb, 0x44,
+ 0xae, 0xcf, 0x20, 0xbc, 0xf0, 0x80, 0x11, 0xdb, 0x23, 0x0c, 0x47, 0x71,
+ 0xb9, 0x6d, 0xd6, 0x7b, 0x60, 0x47, 0x87, 0x16, 0x56, 0x93, 0xb7, 0xc2,
+ 0x2a, 0x9a, 0xb0, 0x4c, 0x01, 0x0c, 0x30, 0xd8, 0x93, 0x87, 0xf0, 0xed,
+ 0x6e, 0x8b, 0xbe, 0x30, 0x5b, 0xf6, 0xa6, 0xaf, 0xdd, 0x80, 0x7c, 0x45,
+ 0x5e, 0x8f, 0x91, 0x93, 0x5e, 0x44, 0xfe, 0xb8, 0x82, 0x07, 0xee, 0x79,
+ 0xca, 0xbf, 0x31, 0x73, 0x62, 0x58, 0xe3, 0xcd, 0xc4, 0xbc, 0xc2, 0x11,
+ 0x1d, 0xa1, 0x4a, 0xbf, 0xfe, 0x27, 0x7d, 0xa1, 0xf6, 0x35, 0xa3, 0x5e,
+ 0xca, 0xdc, 0x57, 0x2f, 0x3e, 0xf0, 0xc9, 0x5d, 0x86, 0x6a, 0xf8, 0xaf,
+ 0x66, 0xa7, 0xed, 0xcd, 0xb8, 0xed, 0xa1, 0x5f, 0xba, 0x9b, 0x85, 0x1a,
+ 0xd5, 0x09, 0xae, 0x94, 0x4e, 0x3b, 0xcf, 0xcb, 0x5c, 0xc9, 0x79, 0x80,
+ 0xf7, 0xcc, 0xa6, 0x4a, 0xa8, 0x6a, 0xd8, 0xd3, 0x31, 0x11, 0xf9, 0xf6,
+ 0x02, 0x63, 0x2a, 0x1a, 0x2d, 0xd1, 0x1a, 0x66, 0x1b, 0x16, 0x41, 0xbd,
+ 0xbd, 0xf7, 0x4d, 0xc0, 0x4a, 0xe5, 0x27, 0x49, 0x5f, 0x7f, 0x58, 0xe3,
+ 0x27, 0x2d, 0xe5, 0xc9, 0x66, 0x0e, 0x52, 0x38, 0x16, 0x38, 0xfb, 0x16,
+ 0xeb, 0x53, 0x3f, 0xe6, 0xfd, 0xe9, 0xa2, 0x5e, 0x25, 0x59, 0xd8, 0x79,
+ 0x45, 0xff, 0x03, 0x4c, 0x26, 0xa2, 0x00, 0x5a, 0x8e, 0xc2, 0x51, 0xa1,
+ 0x15, 0xf9, 0x7b, 0xf4, 0x5c, 0x81, 0x9b, 0x18, 0x47, 0x35, 0xd8, 0x2d,
+ 0x05, 0xe9, 0xad, 0x0f, 0x35, 0x74, 0x15, 0xa3, 0x8e, 0x8b, 0xcc, 0x27,
+ 0xda, 0x7c, 0x5d, 0xe4, 0xfa, 0x04, 0xd3, 0x05, 0x0b, 0xba, 0x3a, 0xb2,
+ 0x49, 0x45, 0x2f, 0x47, 0xc7, 0x0d, 0x41, 0x3f, 0x97, 0x80, 0x4d, 0x3f,
+ 0xc1, 0xb5, 0xbb, 0x70, 0x5f, 0xa7, 0x37, 0xaf, 0x48, 0x22, 0x12, 0x45,
+ 0x2e, 0xf5, 0x0f, 0x87, 0x92, 0xe2, 0x84, 0x01, 0xf9, 0x12, 0x0f, 0x14,
+ 0x15, 0x24, 0xce, 0x89, 0x99, 0xee, 0xb9, 0xc4, 0x17, 0x70, 0x70, 0x15,
+ 0xea, 0xbe, 0xc6, 0x6c, 0x1f, 0x62, 0xb3, 0xf4, 0x2d, 0x16, 0x87, 0xfb,
+ 0x56, 0x1e, 0x45, 0xab, 0xae, 0x32, 0xe4, 0x5e, 0x91, 0xed, 0x53, 0x66,
+ 0x5e, 0xbd, 0xed, 0xad, 0xe6, 0x12, 0x39, 0x0d, 0x83, 0xc9, 0xe8, 0x6b,
+ 0x6c, 0x2d, 0xa5, 0xee, 0xc4, 0x5a, 0x66, 0xae, 0x8c, 0x97, 0xd7, 0x0d,
+ 0x6c, 0x49, 0xc7, 0xf5, 0xc4, 0x92, 0x31, 0x8b, 0x09, 0xee, 0x33, 0xda,
+ 0xa9, 0x37, 0xb6, 0x49, 0x18, 0xf8, 0x0e, 0x60, 0x45, 0xc8, 0x33, 0x91,
+ 0xef, 0x20, 0x57, 0x10, 0xbe, 0x78, 0x2d, 0x83, 0x26, 0xd6, 0xca, 0x61,
+ 0xf9, 0x2f, 0xe0, 0xbf, 0x05, 0x30, 0x52, 0x5a, 0x12, 0x1c, 0x00, 0xa7,
+ 0x5d, 0xcc, 0x7c, 0x2e, 0xc5, 0x95, 0x8b, 0xa3, 0x3b, 0xf0, 0x43, 0x2e,
+ 0x5e, 0xdd, 0x00, 0xdb, 0x0d, 0xb3, 0x37, 0x99, 0xa9, 0xcd, 0x9c, 0xb7,
+ 0x43, 0xf7, 0x35, 0x44, 0x21, 0xc2, 0x82, 0x71, 0xab, 0x8d, 0xaa, 0xb4,
+ 0x41, 0x11, 0xec, 0x1e, 0x8d, 0xfc, 0x14, 0x82, 0x92, 0x4e, 0x83, 0x6a,
+ 0x0a, 0x6b, 0x35, 0x5e, 0x5d, 0xe9, 0x5c, 0xcc, 0x8c, 0xde, 0x39, 0xd1,
+ 0x4a, 0x5b, 0x5f, 0x63, 0xa9, 0x64, 0xe0, 0x0a, 0xcb, 0x0b, 0xb8, 0x5a,
+ 0x7c, 0xc3, 0x0b, 0xe6, 0xbe, 0xfe, 0x8b, 0x0f, 0x7d, 0x34, 0x8e, 0x02,
+ 0x66, 0x74, 0x01, 0x6c, 0xca, 0x76, 0xac, 0x7c, 0x67, 0x08, 0x2f, 0x3f,
+ 0x1a, 0xa6, 0x2c, 0x60, 0xb3, 0xff, 0xda, 0x8d, 0xb8, 0x12, 0x0c, 0x00,
+ 0x7f, 0xcc, 0x50, 0xa1, 0x5c, 0x64, 0xa1, 0xe2, 0x5f, 0x32, 0x65, 0xc9,
+ 0x9c, 0xbe, 0xd6, 0x0a, 0x13, 0x87, 0x3c, 0x2a, 0x45, 0x47, 0x0c, 0xca,
+ 0x42, 0x82, 0xfa, 0x89, 0x65, 0xe7, 0x89, 0xb4, 0x8f, 0xf7, 0x1e, 0xe6,
+ 0x23, 0xa5, 0xd0, 0x59, 0x37, 0x79, 0x92, 0xd7, 0xce, 0x3d, 0xfd, 0xe3,
+ 0xa1, 0x0b, 0xcf, 0x6c, 0x85, 0xa0, 0x65, 0xf3, 0x5c, 0xc6, 0x4a, 0x63,
+ 0x5f, 0x6e, 0x3a, 0x3a, 0x2a, 0x8b, 0x6a, 0xb6, 0x2f, 0xbb, 0xf8, 0xb2,
+ 0x4b, 0x62, 0xbc, 0x1a, 0x91, 0x25, 0x66, 0xe3, 0x69, 0xca, 0x60, 0x49,
+ 0x0b, 0xf6, 0x8a, 0xbe, 0x3e, 0x76, 0x53, 0xc2, 0x7a, 0xa8, 0x04, 0x17,
+ 0x75, 0xf1, 0xf3, 0x03, 0x62, 0x1b, 0x85, 0xb2, 0xb0, 0xef, 0x80, 0x15,
+ 0xb6, 0xd4, 0x4e, 0xdf, 0x71, 0xac, 0xdb, 0x2a, 0x04, 0xd4, 0xb4, 0x21,
+ 0xba, 0x65, 0x56, 0x57, 0xe8, 0xfa, 0x84, 0xa2, 0x7d, 0x13, 0x0e, 0xaf,
+ 0xd7, 0x9a, 0x58, 0x2a, 0xa3, 0x81, 0x84, 0x8d, 0x09, 0xa0, 0x6a, 0xc1,
+ 0xbb, 0xd9, 0xf5, 0x86, 0xac, 0xbd, 0x75, 0x61, 0x09, 0xe6, 0x8c, 0x3d,
+ 0x77, 0xb2, 0xed, 0x30, 0x20, 0xe4, 0x00, 0x1d, 0x97, 0xe8, 0xbf, 0xc7,
+ 0x00, 0x1b, 0x21, 0xb1, 0x16, 0xe7, 0x41, 0x67, 0x2e, 0xec, 0x38, 0xbc,
+ 0xe5, 0x1b, 0xb4, 0x06, 0x23, 0x31, 0x71, 0x1c, 0x49, 0xcd, 0x76, 0x4a,
+ 0x76, 0x36, 0x8d, 0xa3, 0x89, 0x8b, 0x4a, 0x7a, 0xf4, 0x87, 0xc8, 0x15,
+ 0x0f, 0x37, 0x39, 0xf6, 0x6d, 0x80, 0x19, 0xef, 0x5c, 0xa8, 0x66, 0xce,
+ 0x1b, 0x16, 0x79, 0x21, 0xdf, 0xd7, 0x31, 0x30, 0xc4, 0x21, 0xdd, 0x34,
+ 0x5b, 0xd2, 0x1a, 0x2b, 0x3e, 0x5d, 0xf7, 0xea, 0xca, 0x05, 0x8e, 0xb7,
+ 0xcb, 0x49, 0x2e, 0xa0, 0xe3, 0xf4, 0xa7, 0x48, 0x19, 0x10, 0x9c, 0x04,
+ 0xa7, 0xf4, 0x28, 0x74, 0xc8, 0x6f, 0x63, 0x20, 0x2b, 0x46, 0x24, 0x26,
+ 0x19, 0x1d, 0xd1, 0x2c, 0x31, 0x6d, 0x5a, 0x29, 0xa2, 0x06, 0xa6, 0xb2,
+ 0x41, 0xcc, 0x0a, 0x27, 0x96, 0x09, 0x96, 0xac, 0x47, 0x65, 0x78, 0x68,
+ 0x51, 0x98, 0xd6, 0xd8, 0xa6, 0x2d, 0xa0, 0xcf, 0xec, 0xe2, 0x74, 0xf2,
+ 0x82, 0xe3, 0x97, 0xd9, 0x7e, 0xd4, 0xf8, 0x0b, 0x70, 0x43, 0x3d, 0xb1,
+ 0x7b, 0x97, 0x80, 0xd6, 0xcb, 0xd7, 0x19, 0xbc, 0x63, 0x0b, 0xfd, 0x4d,
+ 0x88, 0xfe, 0x67, 0xac, 0xb8, 0xcc, 0x50, 0xb7, 0x68, 0xb3, 0x5b, 0xd6,
+ 0x1e, 0x25, 0xfc, 0x5f, 0x3c, 0x8d, 0xb1, 0x33, 0x7c, 0xb3, 0x49, 0x01,
+ 0x3f, 0x71, 0x55, 0x0e, 0x51, 0xba, 0x61, 0x26, 0xfa, 0xea, 0xe5, 0xb5,
+ 0xe8, 0xaa, 0xcf, 0xcd, 0x96, 0x9f, 0xd6, 0xc1, 0x5f, 0x53, 0x91, 0xad,
+ 0x05, 0xde, 0x20, 0xe7, 0x51, 0xda, 0x5b, 0x95, 0x67, 0xed, 0xf4, 0xee,
+ 0x42, 0x65, 0x70, 0x13, 0x0b, 0x70, 0x14, 0x1c, 0xc9, 0xe0, 0x19, 0xca,
+ 0x5f, 0xf5, 0x1d, 0x70, 0x4b, 0x6c, 0x06, 0x74, 0xec, 0xb5, 0x2e, 0x77,
+ 0xe1, 0x74, 0xa1, 0xa3, 0x99, 0xa0, 0x85, 0x9e, 0xf1, 0xac, 0xd8, 0x7e};
+
+#endif /* __OEM_PUBLIC_KEY_H__ */
diff --git a/platform/msm_shared/avb/VerifiedBoot.c b/platform/msm_shared/avb/VerifiedBoot.c
new file mode 100644
index 0000000..ec455d3
--- /dev/null
+++ b/platform/msm_shared/avb/VerifiedBoot.c
@@ -0,0 +1,792 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "libavb/libavb.h"
+#include <malloc.h>
+
+#include <boot_verifier.h>
+#include <ab_partition_parser.h>
+#include <partition_parser.h>
+#include <recovery.h>
+#include <display_menu.h>
+#include <../../../app/aboot/mdtp.h>
+#include <platform/timer.h>
+#include "verifiedboot.h"
+#include <err.h>
+
+#ifndef DTB_PAD_SIZE
+#define DTB_PAD_SIZE 2048
+#endif
+#define INTERMEDIATE_DIGEST_LENGTH 64
+#define MAX_PART_NAME_SIZE 10
+
+#ifndef MDTP_SUPPORT
+int mdtp_activated(bool * activated)
+{
+ return 0;
+}
+void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
+{
+ return;
+}
+#endif
+
+static const CHAR8 *VerifiedState = " androidboot.verifiedbootstate=";
+static const CHAR8 *KeymasterLoadState = " androidboot.keymaster=1";
+static const CHAR8 *Space = " ";
+#if !VERIFIED_BOOT_2
+static const CHAR8 *VerityMode = " androidboot.veritymode=";
+static struct verified_boot_verity_mode VbVm[] =
+{
+ {FALSE, "logging"},
+ {TRUE, "enforcing"},
+};
+#endif
+
+static struct verified_boot_state_name VbSn[] =
+{
+ {GREEN, "green"},
+ {ORANGE, "orange"},
+ {YELLOW, "yellow"},
+ {RED, "red"},
+};
+
+struct boolean_string
+{
+ BOOLEAN value;
+ CHAR8 *name;
+};
+
+static struct boolean_string BooleanString[] =
+{
+ {FALSE, "false"},
+ {TRUE, "true"}
+};
+
+
+typedef struct {
+ AvbOps *Ops;
+ AvbSlotVerifyData *SlotData;
+} VB2Data;
+
+UINT32 GetAVBVersion()
+{
+#if VERIFIED_BOOT_2
+ return 2;
+#elif VERIFIED_BOOT
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+BOOLEAN VerifiedBootEnabled()
+{
+ return (GetAVBVersion() > NO_AVB);
+}
+
+static int GetCurrentSlotSuffix(Slot *CurrentSlot)
+{
+ if (!partition_multislot_is_supported())
+ return ERR_INVALID_ARGS;
+
+ strncpy(CurrentSlot->Suffix,
+ SUFFIX_SLOT(partition_find_active_slot()),
+ MAX_SLOT_SUFFIX_SZ);
+ return 0;
+}
+
+static int check_img_header(void *ImageHdrBuffer, uint32_t ImageHdrSize, uint32_t *imgsizeActual)
+{
+ /* These checks are already done before calling auth remove from here */
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
+ boot_verifier_init();
+#endif
+ return 0;
+}
+
+static int GetActiveSlot(Slot *ActiveSlot)
+{
+ if (!partition_multislot_is_supported())
+ return ERR_INVALID_ARGS;
+ int idx = partition_find_active_slot();
+ if (idx != INVALID)
+ {
+ strncpy(ActiveSlot->Suffix,
+ SUFFIX_SLOT(partition_find_active_slot()),
+ MAX_SLOT_SUFFIX_SZ);
+ return 0;
+ }
+ return ERR_NOT_FOUND;
+}
+
+static int FindBootableSlot(Slot *BootableSlot)
+{
+ int Status = 0;
+
+ if (BootableSlot == NULL) {
+ dprintf(CRITICAL,"FindBootableSlot: input parameter invalid\n");
+ return -ERR_INVALID_ARGS;
+ }
+
+ Status = GetActiveSlot(BootableSlot);
+ if (Status != 0) {
+ /* clear bootable slot */
+ BootableSlot->Suffix[0] = '\0';
+ }
+ return Status;
+}
+
+bool IsSuffixEmpty(Slot *CheckSlot)
+{
+ if (CheckSlot == NULL) {
+ return TRUE;
+ }
+
+ if (strlen((char *)CheckSlot->Suffix) == 0) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int HandleActiveSlotUnbootable()
+{
+ int curr_slot;
+ curr_slot = partition_find_active_slot();
+ partition_deactivate_slot(curr_slot);
+ partition_find_boot_slot();
+
+ // should not reach here
+ return ERROR;
+}
+
+/*
+ * Returns length = 0 when there is failure.
+ */
+uint32_t GetSystemPath(char **SysPath)
+{
+ INT32 Index;
+ UINT32 Lun;
+ CHAR8 PartitionName[MAX_GPT_NAME_SIZE];
+ Slot CurSlot;
+ CHAR8 LunCharMapping[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
+
+ if (GetCurrentSlotSuffix(&CurSlot))
+ return 0;
+
+ *SysPath = malloc(sizeof(char) * MAX_PATH_SIZE);
+ if (!*SysPath) {
+ dprintf(CRITICAL, "Failed to allocated memory for System path query\n");
+ return 0;
+ }
+
+ strncpy(PartitionName, "system", strlen("system") + 1);
+ strncat(PartitionName, CurSlot.Suffix, MAX_GPT_NAME_SIZE - 1);
+
+ Index = partition_get_index(PartitionName);
+ if (Index == INVALID_PTN || Index >= NUM_PARTITIONS) {
+ dprintf(CRITICAL, "System partition does not exit\n");
+ free(*SysPath);
+ return 0;
+ }
+
+ Lun = partition_get_lun(Index);
+ if (platform_boot_dev_isemmc()) {
+ snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/mmcblk0p%d",
+ Index + 1);
+ } else {
+ snprintf(*SysPath, MAX_PATH_SIZE, " root=/dev/sd%c%d",
+ LunCharMapping[Lun],
+ partition_get_index_in_lun(PartitionName, Lun));
+ }
+
+ dprintf(DEBUG, "System Path - %s \n", *SysPath);
+
+ return strlen(*SysPath);
+}
+
+static EFI_STATUS Appendvbcmdline(bootinfo *Info, const CHAR8 *Src)
+{
+ INT32 SrcLen = strlen(Src);
+ CHAR8 *Dst = (CHAR8 *)Info->vbcmdline + Info->vbcmdline_filled_len;
+
+ strlcat(Dst, Src, SrcLen);
+ Info->vbcmdline_filled_len += SrcLen;
+
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS AppendVBCommonCmdLine(bootinfo *Info)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (GetAVBVersion() >= AVB_1) {
+ GUARD(Appendvbcmdline(Info, VerifiedState));
+ GUARD(Appendvbcmdline(Info, VbSn[Info->boot_state].name));
+ }
+ GUARD(Appendvbcmdline(Info, KeymasterLoadState));
+ GUARD(Appendvbcmdline(Info, Space));
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS VBCommonInit(bootinfo *Info)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Info->boot_state = RED;
+
+ // FIXME: Add boot call
+ /* allocate VB command line*/
+ Info->vbcmdline = malloc(2*DTB_PAD_SIZE);
+ if (Info->vbcmdline == NULL) {
+ dprintf(CRITICAL, "VB CmdLine allocation failed!\n");
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ Info->vbcmdline_len = 2*DTB_PAD_SIZE;
+ Info->vbcmdline_filled_len = 0;
+ Info->vbcmdline[Info->vbcmdline_filled_len] = '\0';
+
+ return Status;
+}
+
+#if VERIFIED_BOOT_2
+/* Disable for VB 2.0 as this path is never taken */
+static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
+{
+ return ERROR;
+}
+static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
+{
+ return ERROR;
+}
+#else
+static EFI_STATUS LoadImageNoAuth(bootinfo *Info)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (Info->images[0].image_buffer != NULL && Info->images[0].imgsize > 0) {
+ /* fastboot boot option image already loaded */
+ return Status;
+ }
+
+ Status = LoadImage(Info->pname, (VOID **)&(Info->images[0].image_buffer),
+ (UINT32 *)&(Info->images[0].imgsize));
+ if (Status != EFI_SUCCESS) {
+ dprintf(CRITICAL,
+ "ERROR: Failed to load image from partition: %d\n", Status);
+ return EFI_LOAD_ERROR;
+ }
+ Info->num_loaded_images = 1;
+ Info->images[0].name = malloc(strlen(Info->pname) + 1);
+ strncpy(Info->images[0].name, Info->pname, strlen(Info->pname)); //FIXME
+ return Status;
+}
+
+static EFI_STATUS load_image_and_authVB1(bootinfo *Info)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ CHAR8 StrPname[MAX_GPT_NAME_SIZE];
+ CHAR8 Pname[MAX_GPT_NAME_SIZE];
+ CHAR8 *SystemPath = NULL;
+ UINT32 SystemPathLen = 0;
+ device_info DevInfo_vb;
+
+ GUARD(VBCommonInit(Info));
+ GUARD(LoadImageNoAuth(Info));
+ boot_verifier_init();
+
+ // FIXME: INIT devinfo()
+ DevInfo_vb.is_unlocked = !is_device_locked();
+ DevInfo_vb.is_unlock_critical = !is_device_locked_critical();
+
+ strncpy(StrPname, "/", strlen("/"));
+ strncpy(Pname, Info->pname, strlen(Info->pname));
+ if (Info->multi_slot_boot) {
+ strncat(StrPname, Pname,
+ strlen(Pname) - (MAX_SLOT_SUFFIX_SZ - 1));
+ } else {
+ strncat(StrPname, Pname, strlen(Pname));
+ }
+
+ Status = boot_verify_image((UINT8 *)Info->images[0].image_buffer,
+ Info->images[0].imgsize,
+ StrPname,
+ &Info->boot_state);
+ if (Status != EFI_SUCCESS || Info->boot_state == BOOT_STATE_MAX) {
+ dprintf(CRITICAL, "VBVerifyImage failed with: %d\n", Status);
+ return Status;
+ }
+
+ set_os_version((unsigned char *)Info->images[0].image_buffer);
+ if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
+ return EFI_LOAD_ERROR;
+
+ SystemPathLen = GetSystemPath(&SystemPath);
+ if (SystemPathLen == 0 || SystemPath == NULL) {
+ dprintf(CRITICAL, "GetSystemPath failed!\n");
+ return EFI_LOAD_ERROR;
+ }
+ GUARD(AppendVBCommonCmdLine(Info));
+ GUARD(Appendvbcmdline(Info, VerityMode));
+ GUARD(Appendvbcmdline(Info, VbVm[is_verity_enforcing()].name));
+ GUARD(Appendvbcmdline(Info, SystemPath));
+
+ Info->vb_data = NULL;
+ return Status;
+}
+#endif
+
+static BOOLEAN ResultShouldContinue(AvbSlotVerifyResult Result)
+{
+ switch (Result) {
+ case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
+ return FALSE;
+
+ case AVB_SLOT_VERIFY_RESULT_OK:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+char *pname[] = {
+ "sbl1",
+ "rpm",
+ "tz",
+ "aboot",
+};
+
+static EFI_STATUS load_image_and_authVB2(bootinfo *Info)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ AvbSlotVerifyResult Result;
+ AvbSlotVerifyData *SlotData = NULL;
+ VB2Data *VBData = NULL;
+ AvbOpsUserData *UserData = NULL;
+ AvbOps *Ops = NULL;
+ CHAR8 Pname[MAX_GPT_NAME_SIZE] = {0};
+ CHAR8 *SlotSuffix = NULL;
+ BOOLEAN AllowVerificationError = !is_device_locked();
+ BOOLEAN VerityEnforcing = is_verity_enforcing();
+ const CHAR8 *RequestedPartitionMission[] = {"boot", "dtbo", NULL};
+ const CHAR8 *RequestedPartitionRecovery[] = {"recovery", "dtbo", NULL};
+ const CHAR8 **RequestedPartition = NULL;
+ UINTN NumRequestedPartition = 0;
+ UINT32 ImageHdrSize = 0;
+ UINT32 imgsizeActual = 0;
+ VOID *image_buffer = NULL;
+ UINT32 imgsize = 0;
+ AvbSlotVerifyFlags VerifyFlags = AllowVerificationError ?
+ AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR :
+ AVB_SLOT_VERIFY_FLAGS_NONE;
+ AvbHashtreeErrorMode VerityFlags = AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE;
+ device_info DevInfo_vb;
+
+ Info->boot_state = RED;
+ GUARD(VBCommonInit(Info));
+
+ UserData = avb_calloc(sizeof(AvbOpsUserData));
+ if (UserData == NULL) {
+ dprintf(CRITICAL,
+ "ERROR: Failed to allocate AvbOpsUserData\n");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ Ops = AvbOpsNew(UserData);
+ if (Ops == NULL) {
+ dprintf(CRITICAL, "ERROR: Failed to allocate AvbOps\n");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ if(Info->multi_slot_boot) {
+ strncpy(Pname, Info->pname, strlen(Info->pname));
+ if ((MAX_SLOT_SUFFIX_SZ + 1) > strlen(Pname)) {
+ dprintf(CRITICAL, "ERROR: Can not determine slot suffix\n");
+ Status = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ SlotSuffix = &Pname[strlen(Pname) - MAX_SLOT_SUFFIX_SZ + 1];
+ } else {
+ SlotSuffix = "\0";
+ }
+
+ if(!Info->multi_slot_boot && Info->bootinto_recovery) {
+ RequestedPartition = RequestedPartitionRecovery;
+ NumRequestedPartition = ARRAY_SIZE (RequestedPartitionRecovery) - 1;
+ if (Info->num_loaded_images) {
+ /* fastboot boot option, skip Index 0, as boot image already
+ * loaded */
+ RequestedPartition = &RequestedPartitionRecovery[1];
+ }
+ } else {
+ RequestedPartition = RequestedPartitionMission;
+ NumRequestedPartition = ARRAY_SIZE(RequestedPartitionMission) - 1;
+ if (Info->num_loaded_images) {
+ /* fastboot boot option, skip Index 0, as boot image already
+ * loaded */
+ RequestedPartition = &RequestedPartitionMission[1];
+ }
+ }
+ if (Info->num_loaded_images) {
+ NumRequestedPartition--;
+ }
+
+ // FIXME: is this correct?
+ VerityFlags = VerityEnforcing ?
+ AVB_HASHTREE_ERROR_MODE_RESTART :
+ AVB_HASHTREE_ERROR_MODE_EIO;
+
+ Result = avb_slot_verify(Ops, RequestedPartition, SlotSuffix,
+ VerifyFlags, VerityFlags,
+ &SlotData);
+
+ if (AllowVerificationError && ResultShouldContinue(Result)) {
+ dprintf(CRITICAL, "State: Unlocked, AvbSlotVerify returned "
+ "%s, continue boot\n",
+ avb_slot_verify_result_to_string(Result));
+ } else if (Result != AVB_SLOT_VERIFY_RESULT_OK) {
+ dprintf(CRITICAL,
+ "ERROR: Device State %s, AvbSlotVerify returned %s\n",
+ AllowVerificationError ? "Unlocked" : "Locked",
+ avb_slot_verify_result_to_string(Result));
+ Status = EFI_LOAD_ERROR;
+ Info->boot_state = RED;
+ goto out;
+ }
+
+ for (UINTN ReqIndex = 0; ReqIndex < NumRequestedPartition; ReqIndex++) {
+ dprintf(DEBUG, "Requested Partition: %s\n",
+ RequestedPartition[ReqIndex]);
+ for (UINTN loadedindex = 0;
+ loadedindex < SlotData->num_loaded_partitions; loadedindex++) {
+ dprintf(DEBUG, "Loaded Partition: %s\n",
+ SlotData->loaded_partitions[loadedindex].partition_name);
+ if (!strncmp((const char *)
+ RequestedPartition[ReqIndex],
+ SlotData->loaded_partitions[loadedindex].partition_name,
+ strlen(SlotData->loaded_partitions[loadedindex]
+ .partition_name))) {
+ if (Info->num_loaded_images >= ARRAY_SIZE(Info->images)) {
+ dprintf(CRITICAL, "NumLoadedPartition"
+ "(%d) too large "
+ "max images(%d)\n",
+ Info->num_loaded_images,
+ ARRAY_SIZE(Info->images));
+ Status = EFI_LOAD_ERROR;
+ Info->boot_state = RED;
+ goto out;
+ }
+ Info->images[Info->num_loaded_images].name =
+ SlotData->loaded_partitions[loadedindex].partition_name;
+ Info->images[Info->num_loaded_images].image_buffer =
+ SlotData->loaded_partitions[loadedindex].data;
+ Info->images[Info->num_loaded_images].imgsize =
+ SlotData->loaded_partitions[loadedindex].data_size;
+ Info->num_loaded_images++;
+ break;
+ }
+ }
+ }
+
+ if (Info->num_loaded_images < NumRequestedPartition) {
+ dprintf(CRITICAL, "ERROR: AvbSlotVerify slot data: num of loaded partitions %d, requested %lu\n",Info->num_loaded_images, NumRequestedPartition);
+ Status = EFI_LOAD_ERROR;
+ goto out;
+ }
+
+ dprintf(DEBUG, "Total loaded partition %d\n", Info->num_loaded_images);
+
+ VBData = (VB2Data *)avb_calloc(sizeof(VB2Data));
+ if (VBData == NULL) {
+ dprintf(CRITICAL, "ERROR: Failed to allocate VB2Data\n");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ VBData->Ops = Ops;
+ VBData->SlotData = SlotData;
+ Info->vb_data = (VOID *)VBData;
+
+ ImageHdrSize = get_page_size();
+ GUARD_OUT(getimage(Info, &image_buffer, &imgsize,(!Info->multi_slot_boot && Info->bootinto_recovery) ? "recovery" : "boot") );
+
+ Status = check_img_header(image_buffer, ImageHdrSize, &imgsizeActual);
+ if (Status != EFI_SUCCESS) {
+ dprintf(CRITICAL, "Invalid boot image header:%d\n", Status);
+ goto out;
+ }
+
+ if (imgsizeActual > imgsize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ dprintf(CRITICAL,
+ "Boot size in vbmeta less than actual boot image size "
+ "flash corresponding vbmeta.img\n");
+ goto out;
+ }
+ if (AllowVerificationError) {
+ Info->boot_state = ORANGE;
+ } else {
+ if (UserData->IsUserKey) {
+ Info->boot_state = YELLOW;
+ } else {
+ Info->boot_state = GREEN;
+ }
+ }
+
+ /* command line */
+ GUARD_OUT(AppendVBCommonCmdLine(Info));
+ GUARD_OUT(Appendvbcmdline(Info, SlotData->cmdline));
+ DevInfo_vb.is_unlocked = !is_device_locked();
+ set_os_version((unsigned char *)Info->images[0].image_buffer);
+ if(!send_rot_command((uint32_t)DevInfo_vb.is_unlocked))
+ return EFI_LOAD_ERROR;
+ dprintf(INFO, "VB2: Authenticate complete! boot state is: %s\n",
+ VbSn[Info->boot_state].name);
+
+out:
+ if (Status != EFI_SUCCESS) {
+ if (SlotData != NULL) {
+ avb_slot_verify_data_free(SlotData);
+ }
+ if (Ops != NULL) {
+ AvbOpsFree(Ops);
+ }
+ if (UserData != NULL) {
+ avb_free(UserData);
+ }
+ if (VBData != NULL) {
+ avb_free(VBData);
+ }
+ Info->boot_state = RED;
+ if(Info->multi_slot_boot) {
+ HandleActiveSlotUnbootable();
+ /* HandleActiveSlotUnbootable should have swapped slots and
+ * reboot the device. If no bootable slot found, enter fastboot */
+ dprintf(CRITICAL, "No bootable slots found enter fastboot mode\n");
+ } else {
+ dprintf(CRITICAL, "Non Multi-slot: Unbootable entering fastboot mode\n");
+ }
+
+ }
+
+ dprintf(CRITICAL, "VB2: boot state: %s(%d)\n",
+ VbSn[Info->boot_state].name, Info->boot_state);
+ return Status;
+}
+
+static EFI_STATUS DisplayVerifiedBootScreen(bootinfo *Info)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ CHAR8 ffbm_mode_string[FFBM_MODE_BUF_SIZE] = {'\0'};
+
+ if (GetAVBVersion() < AVB_1) {
+ return EFI_SUCCESS;
+ }
+
+ if (!strncmp(Info->pname, "boot", strlen("boot"))) {
+ Status = get_ffbm(ffbm_mode_string, FFBM_MODE_BUF_SIZE);
+ if (Status != EFI_SUCCESS) {
+ dprintf(DEBUG,
+ "No Ffbm cookie found, ignore: %d\n", Status);
+ ffbm_mode_string[0] = '\0';
+ }
+ }
+
+ dprintf(DEBUG, "Boot State is : %d\n", Info->boot_state);
+ switch (Info->boot_state)
+ {
+ case RED:
+ display_bootverify_menu(DISPLAY_MENU_RED);
+ //if (Status != EFI_SUCCESS) {
+ dprintf(INFO, "Your device is corrupt. It can't be trusted and will not boot." \
+ "\nYour device will shutdown in 30s\n");
+ //}
+ udelay(30000000);
+ shutdown_device();
+ break;
+ case YELLOW:
+ display_bootverify_menu(DISPLAY_MENU_YELLOW);
+ //if (Status == EFI_SUCCESS) {
+ wait_for_users_action();
+ //} else {
+ dprintf(INFO, "Your device has loaded a different operating system." \
+ "\nWait for 5 seconds before proceeding\n");
+ udelay(5000000);
+ //}
+ break;
+ case ORANGE:
+ if (ffbm_mode_string[0] != '\0' && !target_build_variant_user()) {
+ dprintf(DEBUG, "Device will boot into FFBM mode\n");
+ } else {
+ //display_bootverify_menu(DISPLAY_MENU_ORANGE);
+ //if (Status == EFI_SUCCESS) {
+ // wait_for_users_action();
+ //} else {
+ dprintf(INFO, "Device is unlocked, Skipping boot verification\n");
+ udelay(5000000);
+ //}
+ }
+ break;
+ default:
+ break;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS load_image_and_auth(bootinfo *Info)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ BOOLEAN MdtpActive = FALSE;
+ UINT32 AVBVersion = NO_AVB;
+ mdtp_ext_partition_verification_t ext_partition;
+
+ if (Info == NULL) {
+ dprintf(CRITICAL, "Invalid parameter Info\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!Info->multi_slot_boot) {
+ if (Info->bootinto_recovery) {
+ dprintf(INFO, "Booting Into Recovery Mode\n");
+ strncpy(Info->pname, "recovery", strlen("recovery"));
+ } else {
+ dprintf(INFO, "Booting Into Mission Mode\n");
+ strncpy(Info->pname, "boot", strlen("boot"));
+ }
+ } else {
+ Slot CurrentSlot = {{0}};
+
+ GUARD(FindBootableSlot(&CurrentSlot));
+ if (IsSuffixEmpty(&CurrentSlot)) {
+ dprintf(CRITICAL, "No bootable slot\n");
+ return EFI_LOAD_ERROR;
+ }
+ strncpy(Info->pname, "boot", strlen("boot"));
+ strncat(Info->pname, CurrentSlot.Suffix, strlen(CurrentSlot.Suffix));
+ }
+
+ dprintf(DEBUG, "MultiSlot %s, partition name %s\n",
+ BooleanString[Info->multi_slot_boot].name, Info->pname);
+
+ Status = mdtp_activated(&MdtpActive);
+ if (Status) {
+ dprintf(CRITICAL,
+ "Failed to get activation state for MDTP, "
+ "Status=%d."
+ " Considering MDTP as active and continuing \n",
+ Status);
+ if (Status != -1)
+ MdtpActive = TRUE;
+ }
+
+ AVBVersion = GetAVBVersion();
+ dprintf(DEBUG, "AVB version %d\n", AVBVersion);
+
+ /* Load and Authenticate */
+ switch (AVBVersion) {
+ case NO_AVB:
+ return LoadImageNoAuth(Info);
+ break;
+ case AVB_1:
+ Status = load_image_and_authVB1(Info);
+ break;
+ case AVB_2:
+ Status = load_image_and_authVB2(Info);
+ break;
+ default:
+ dprintf(CRITICAL, "Unsupported AVB version %d\n", AVBVersion);
+ Status = EFI_UNSUPPORTED;
+ }
+
+ // if MDTP is active Display Recovery UI
+ if (Status != EFI_SUCCESS && MdtpActive && !target_use_signed_kernel()) {
+ //FIXME: Hard coded to BOOT
+ ext_partition.partition = Info->bootinto_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
+ ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
+ ext_partition.page_size = get_page_size();
+ ext_partition.image_addr = (uint32)Info->images[0].image_buffer;
+ ext_partition.image_size = Info->images[0].imgsize;
+ ext_partition.sig_avail = FALSE;
+ mdtp_fwlock_verify_lock(&ext_partition);
+ }
+
+ if (!is_device_locked() && Status != EFI_SUCCESS) {
+ dprintf(CRITICAL, "load_image_and_auth failed %d\n", Status);
+ return Status;
+ }
+
+ DisplayVerifiedBootScreen(Info);
+
+ return Status;
+}
+
+#if VERIFIED_BOOT_2
+VOID free_verified_boot_resource(bootinfo *Info)
+{
+ dprintf(DEBUG, "free_verified_boot_resource\n");
+
+ if (Info == NULL) {
+ return;
+ }
+
+ VB2Data *VBData = Info->vb_data;
+ if (VBData != NULL) {
+ AvbOps *Ops = VBData->Ops;
+ if (Ops != NULL) {
+ if (Ops->user_data != NULL) {
+ avb_free(Ops->user_data);
+ }
+ AvbOpsFree(Ops);
+ }
+
+ AvbSlotVerifyData *SlotData = VBData->SlotData;
+ if (SlotData != NULL) {
+ avb_slot_verify_data_free(SlotData);
+ }
+ avb_free(VBData);
+ }
+
+ if (Info->vbcmdline != NULL) {
+ free(Info->vbcmdline);
+ }
+ return;
+}
+#else
+VOID free_verified_boot_resource(bootinfo *Info)
+{
+ return;
+}
+#endif
diff --git a/platform/msm_shared/avb/libavb/avb_ops.c b/platform/msm_shared/avb/libavb/avb_ops.c
new file mode 100644
index 0000000..97aa79b
--- /dev/null
+++ b/platform/msm_shared/avb/libavb/avb_ops.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "../OEMPublicKey.h"
+#include "avb_sysdeps.h"
+#include "libavb.h"
+#include <platform.h>
+#include <err.h>
+#include <ab_partition_parser.h>
+#include <partition_parser.h>
+
+struct partition_entry *PtnEntries;
+
+bool IsCurrentSlotSuccessful()
+{
+ struct ab_slot_info slot_info[AB_SUPPORTED_SLOTS];
+ int slot_idx =INVALID;
+
+ slot_idx = partition_find_active_slot();
+ if(slot_idx == INVALID)
+ {
+ dprintf(CRITICAL,
+ "IsCurrentSlotSuccessful: no active slots found!\n");
+ return FALSE;
+ }
+ partition_fill_slot_meta(slot_info);
+ if(!strncmp(slot_info[slot_idx].slot_is_succesful_rsp,"yes",strlen("yes")))
+ return TRUE;
+
+ return FALSE;
+}
+
+static struct partition_entry *Getpartition_entry(const char *Partition)
+{
+ int32_t Index = partition_get_index(Partition);
+ struct partition_entry *partition_entries =
+ partition_get_partition_entries();
+ if (partition_entries == NULL) {
+ dprintf(CRITICAL, "Getpartition_entry: No partition entry found\n");
+ return NULL;
+ }
+
+ PtnEntries = partition_entries;
+
+ if (Index == INVALID_PTN) {
+ dprintf(CRITICAL, "Getpartition_entry: No partition entry for "
+ "%s, invalid index\n", Partition);
+ return NULL;
+ }
+ return &PtnEntries[Index];
+}
+
+int get_unique_guid(const char *Partition, char *unique_guid)
+{
+ struct partition_entry *gp = Getpartition_entry(Partition);
+ if(gp == NULL)
+ {
+ dprintf(CRITICAL, "Partition entry not found\n");
+ return -1;
+
+ }
+ if (!unique_guid)
+ return -1;
+
+ memcpy(unique_guid, gp->unique_partition_guid, UNIQUE_PARTITION_GUID_SIZE);
+
+ return 0;
+}
+
+static struct partition_entry *GetBootpartition_entry(Slot *BootSlot)
+{
+ int32_t Index = INVALID_PTN;
+ struct partition_entry *partition_entries =
+ partition_get_partition_entries();
+ if( BootSlot == NULL)
+ {
+ dprintf(INFO, "No bootable slot found \n");
+ return NULL;
+
+ }
+ if( partition_entries == NULL)
+ {
+ dprintf(INFO, "No partition entry found \n");
+ return NULL;
+
+ }
+ PtnEntries = partition_entries;
+
+ if (strncmp("_a", (const char *)BootSlot->Suffix, strlen((const char *)BootSlot->Suffix)) == 0) {
+ Index = partition_get_index("boot_a");
+ } else if (strncmp("_b", (const char *)BootSlot->Suffix, strlen((const char *)BootSlot->Suffix)) == 0) {
+ Index = partition_get_index("boot_b");
+ } else {
+ dprintf(CRITICAL, "GetBootpartition_entry: No boot partition "
+ "entry for slot %s\n", (char *)BootSlot->Suffix);
+ return NULL;
+ }
+
+ if (Index == INVALID_PTN) {
+ dprintf(CRITICAL,
+ "GetBootpartition_entry: No boot partition entry "
+ "for slot %s, invalid index\n", (char *)BootSlot->Suffix);
+ return NULL;
+ }
+ return &PtnEntries[Index];
+}
+
+AvbIOResult AvbReadFromPartition(AvbOps *Ops, const char *Partition, int64_t ReadOffset,
+ size_t NumBytes, void *Buffer, size_t *OutNumRead)
+{
+ AvbIOResult Result = AVB_IO_RESULT_OK;
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *Page = NULL;
+ UINT32 Offset = 0;
+ UINTN ptn = 0;
+ UINT32 PageSize = 0;
+ UINT32 StartBlock = 0;
+ UINT32 LastBlock = 0;
+ UINT32 FullBlock = 0;
+ UINTN StartPageReadSize = 0;
+ int index = INVALID_PTN;
+
+ if (Partition == NULL || Buffer == NULL || OutNumRead == NULL || NumBytes <= 0) {
+ dprintf(CRITICAL, "bad input paramaters\n");
+ Result = AVB_IO_RESULT_ERROR_IO;
+ goto out;
+ }
+ *OutNumRead = 0;
+
+ if (!strncmp(Partition,"boot",strlen("boot"))) {
+ /* API returns previously loaded Boot Image buffer address and size */
+ get_boot_image_info(Buffer, OutNumRead, "boot");
+ return AVB_IO_RESULT_OK;
+ }
+
+ index = partition_get_index(Partition);
+ ptn = partition_get_offset(index);
+
+ if (ReadOffset < 0) {
+ if ((-ReadOffset) > ptn) {
+ dprintf(CRITICAL,
+ "Negative Offset outside range.\n");
+ Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+ goto out;
+ }
+ Offset = ptn - (-ReadOffset);
+ dprintf(DEBUG,
+ "negative Offset (%lld) converted to (%u) \n", ReadOffset, Offset);
+ } else {
+ // check int64_t to UINT32 converstion?
+ Offset = ReadOffset;
+ }
+
+ if (Offset > ptn) {
+ dprintf(CRITICAL, "Offset outside range.\n");
+ Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+ goto out;
+ }
+
+ if (NumBytes > ptn - Offset) {
+ NumBytes = ptn - Offset;
+ }
+
+ dprintf(CRITICAL,
+ "read from %s, 0x%x bytes at Offset 0x%x, partition size %lu\n",
+ Partition, NumBytes, Offset, ptn);
+
+ /* |NumBytes| and or |Offset| can be unaligned to block size/page size.
+ */
+ //PageSize = mmc_get_device_blocksize();
+ PageSize = get_page_size();
+ Page = avb_malloc(PageSize);
+ if (Page == NULL) {
+ dprintf(CRITICAL, "Allocate for partial read failed!");
+ Result = AVB_IO_RESULT_ERROR_OOM;
+ goto out;
+ }
+
+ StartBlock = Offset / PageSize;
+ LastBlock = (NumBytes + Offset) / PageSize;
+ FullBlock = StartBlock;
+ StartPageReadSize = 0;
+
+ if (Offset % PageSize != 0) {
+ /* Offset not aligned to PageSize*/
+ UINT32 StartPageReadOffset = Offset - (StartBlock * PageSize);
+
+ if (StartBlock == LastBlock) {
+ /* Offset & Offset + NumBytes are in same block */
+ StartPageReadSize = NumBytes;
+ } else {
+ StartPageReadSize = PageSize - StartPageReadOffset;
+ FullBlock++;
+ }
+
+ dprintf(DEBUG,
+ "StartBlock 0x%x, ReadOffset 0x%x, read_size 0x%lx\n",
+ StartBlock, StartPageReadOffset, StartPageReadSize);
+ if (StartPageReadSize <= 0 || StartPageReadOffset >= PageSize ||
+ StartPageReadSize > PageSize - StartPageReadOffset ||
+ StartPageReadSize > NumBytes) {
+ dprintf(CRITICAL,
+ "StartBlock 0x%x, ReadOffset 0x%x, read_size "
+ "0x%lx outside range.\n",
+ StartBlock, StartPageReadOffset, StartPageReadSize);
+ Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+ goto out;
+ }
+
+ Status = mmc_read(ptn, Page, PageSize);
+ if (Status == EFI_SUCCESS) {
+ avb_memcpy(Buffer, Page + StartPageReadOffset, StartPageReadSize);
+ *OutNumRead += StartPageReadSize;
+ } else {
+ *OutNumRead = 0;
+ dprintf(CRITICAL, "ReadBlocks failed %d\n", Status);
+ goto out;
+ }
+ }
+
+ if (*OutNumRead < NumBytes && (NumBytes + Offset) % PageSize != 0) {
+ /* NumBytes + Offset not aligned to PageSize*/
+ /* Offset for last block is always zero, start at Page boundary
+ */
+ UINT32 LastPageReadOffset = 0;
+ UINTN ReadOffset2 = (LastBlock * PageSize);
+ UINTN LastPageReadSize = (Offset + NumBytes) - ReadOffset2;
+
+ dprintf(DEBUG,
+ "LastBlock 0x%x, ReadOffset 0x%x, read_size 0x%lx\n",
+ LastBlock, LastPageReadOffset, LastPageReadSize);
+
+ if (LastPageReadSize <= 0 || LastPageReadSize >= PageSize ||
+ LastPageReadSize > (NumBytes - *OutNumRead)) {
+ dprintf(CRITICAL,
+ "LastBlock 0x%x, ReadOffset 0x%x, read_size "
+ "0x%lx outside range.\n",
+ LastBlock, LastPageReadOffset, LastPageReadSize);
+ Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+ goto out;
+ }
+
+ Status = mmc_read(ptn + ReadOffset2, Page, PageSize);
+ if (Status == EFI_SUCCESS) {
+ avb_memcpy(Buffer + (NumBytes - LastPageReadSize), Page,
+ LastPageReadSize);
+ *OutNumRead += LastPageReadSize;
+ } else {
+ *OutNumRead = 0;
+ dprintf(CRITICAL, "ReadBlocks failed %d\n", Status);
+ goto out;
+ }
+ }
+
+ if (*OutNumRead < NumBytes) {
+ /* full block reads */
+ UINTN FillPageReadSize = NumBytes - *OutNumRead;
+
+ if ((FillPageReadSize % PageSize) != 0 ||
+ (NumBytes - StartPageReadSize) < FillPageReadSize) {
+ dprintf(CRITICAL,
+ "FullBlock 0x%x, ReadOffset 0x%x, read_size "
+ "0x%lx outside range.\n",
+ FullBlock, 0, FillPageReadSize);
+ Result = AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
+ goto out;
+ }
+ dprintf(SPEW,
+ "FullBlock 0x%x, ReadOffset 0x%x, read_size "
+ "0x%lx outside range. StartPageReadSize %#lx PageSize %d ptn %#lx Buffer %p\n",
+ FullBlock, 0, FillPageReadSize, StartPageReadSize, PageSize, ptn, Buffer);
+ Status = mmc_read(ptn + FullBlock * PageSize, Buffer + StartPageReadSize,
+ FillPageReadSize);
+ if (Status == EFI_SUCCESS) {
+ *OutNumRead += FillPageReadSize;
+ } else {
+ *OutNumRead = 0;
+ dprintf(CRITICAL, "ReadBlocks failed %d\n", Status);
+ goto out;
+ }
+ }
+out:
+ if (Page != NULL) {
+ avb_free(Page);
+ }
+
+ return Result;
+}
+
+AvbIOResult AvbWriteToPartition(AvbOps *Ops, const char *Partition, int64_t Offset,
+ size_t NumBytes, const void *Buffer)
+{
+ /* unsupported api */
+ return AVB_IO_RESULT_ERROR_IO;
+}
+
+AvbIOResult
+AvbValidateVbmetaPublicKey(AvbOps *Ops, const uint8_t *PublicKeyData,
+ size_t PublicKeyLength, const uint8_t *PublicKeyMetadata,
+ size_t PublicKeyMetadataLength, bool *OutIsTrusted)
+{
+ UINT8 *UserKeyBuffer = NULL;
+ UINT32 UserKeyLength = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+ AvbOpsUserData *UserData = NULL;
+
+ dprintf(DEBUG, "ValidateVbmetaPublicKey PublicKeyLength %d, "
+ "PublicKeyMetadataLength %d\n",
+ PublicKeyLength, PublicKeyMetadataLength);
+
+ if (Ops == NULL || OutIsTrusted == NULL || PublicKeyData == NULL) {
+ dprintf(CRITICAL, "Invalid parameters\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ Status = get_userkey(&UserKeyBuffer, &UserKeyLength);
+ if (Status != EFI_SUCCESS) {
+ dprintf(CRITICAL, "get_userkey failed\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ UserData = (AvbOpsUserData *)Ops->user_data;
+ UserData->IsUserKey = FALSE;
+
+ if (PublicKeyLength == UserKeyLength &&
+ memcmp(PublicKeyData, UserKeyBuffer, PublicKeyLength) == 0) {
+ *OutIsTrusted = true;
+ UserData->IsUserKey = TRUE;
+ } else if (PublicKeyLength == ARRAY_SIZE(OEMPublicKey) &&
+ memcmp(PublicKeyData, OEMPublicKey, PublicKeyLength) == 0) {
+ *OutIsTrusted = true;
+ } else {
+ *OutIsTrusted = false;
+ memset(UserData->PublicKey, 0, ARRAY_SIZE(UserData->PublicKey));
+ UserData->PublicKeyLen = 0;
+ }
+
+ if (*OutIsTrusted == true) {
+ if (PublicKeyLength > ARRAY_SIZE(UserData->PublicKey)) {
+ dprintf(CRITICAL, "ValidateVbmetaPublicKey: "
+ "public key length too large %d\n",
+ PublicKeyLength);
+ return AVB_IO_RESULT_ERROR_OOM;
+ }
+ memcpy(UserData->PublicKey, PublicKeyData, PublicKeyLength);
+ UserData->PublicKeyLen = PublicKeyLength;
+ }
+ dprintf(DEBUG,
+ "ValidateVbmetaPublicKey OutIsTrusted %d, UserKey %d\n",
+ *OutIsTrusted, UserData->IsUserKey);
+ return AVB_IO_RESULT_OK;
+}
+
+
+AvbIOResult AvbReadRollbackIndex(AvbOps *Ops, size_t RollbackIndexLocation,
+ uint64_t *OutRollbackIndex)
+{
+
+ EFI_STATUS Status = read_rollback_index(RollbackIndexLocation, OutRollbackIndex);
+
+ if (Status != EFI_SUCCESS) {
+ dprintf(CRITICAL, "ReadRollbackIndex failed! %d\n", Status);
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ dprintf(DEBUG,
+ "ReadRollbackIndex Location %zu, RollbackIndex %llu\n",
+ RollbackIndexLocation, *OutRollbackIndex);
+ return AVB_IO_RESULT_OK;
+}
+
+AvbIOResult
+AvbWriteRollbackIndex(AvbOps *Ops, size_t RollbackIndexLocation, uint64_t RollbackIndex)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ dprintf(DEBUG,
+ "WriteRollbackIndex Location %zu, RollbackIndex %llu\n",
+ RollbackIndexLocation, RollbackIndex);
+ /* Update rollback if the current slot is successful */
+ if (IsCurrentSlotSuccessful()) {
+ dprintf(INFO,
+ "Updating rollback index %llu, for location %zu\n",
+ RollbackIndex, RollbackIndexLocation);
+ Status = write_rollback_index(RollbackIndexLocation, RollbackIndex);
+ if (Status != EFI_SUCCESS) {
+ dprintf(CRITICAL, "ReadRollbackIndex failed! %d\n", Status);
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ } else {
+ dprintf(INFO, "Not updating rollback index as current "
+ "slot is not successful\n");
+ }
+ return AVB_IO_RESULT_OK;
+}
+
+AvbIOResult AvbReadIsDeviceUnlocked(AvbOps *Ops, bool *OutIsUnlocked)
+{
+ if (OutIsUnlocked == NULL) {
+ dprintf(CRITICAL, "bad input paramaters\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ *OutIsUnlocked = !is_device_locked();
+ return AVB_IO_RESULT_OK;
+}
+
+static VOID GuidToHex(CHAR8 *Buf, EFI_GUID *Guid)
+{
+ CHAR8 HexDigits[17] = "0123456789abcdef";
+
+ Buf[0] = HexDigits[(Guid->Data1 >> 28) & 0x0f];
+ Buf[1] = HexDigits[(Guid->Data1 >> 24) & 0x0f];
+ Buf[2] = HexDigits[(Guid->Data1 >> 20) & 0x0f];
+ Buf[3] = HexDigits[(Guid->Data1 >> 16) & 0x0f];
+ Buf[4] = HexDigits[(Guid->Data1 >> 12) & 0x0f];
+ Buf[5] = HexDigits[(Guid->Data1 >> 8) & 0x0f];
+ Buf[6] = HexDigits[(Guid->Data1 >> 4) & 0x0f];
+ Buf[7] = HexDigits[(Guid->Data1 >> 0) & 0x0f];
+ Buf[8] = '-';
+ Buf[9] = HexDigits[(Guid->Data2 >> 12) & 0x0f];
+ Buf[10] = HexDigits[(Guid->Data2 >> 8) & 0x0f];
+ Buf[11] = HexDigits[(Guid->Data2 >> 4) & 0x0f];
+ Buf[12] = HexDigits[(Guid->Data2 >> 0) & 0x0f];
+ Buf[13] = '-';
+ Buf[14] = HexDigits[(Guid->Data3 >> 12) & 0x0f];
+ Buf[15] = HexDigits[(Guid->Data3 >> 8) & 0x0f];
+ Buf[16] = HexDigits[(Guid->Data3 >> 4) & 0x0f];
+ Buf[17] = HexDigits[(Guid->Data3 >> 0) & 0x0f];
+ Buf[18] = '-';
+ Buf[19] = HexDigits[(Guid->Data4[0] >> 4) & 0x0f];
+ Buf[20] = HexDigits[(Guid->Data4[0] >> 0) & 0x0f];
+ Buf[21] = HexDigits[(Guid->Data4[1] >> 4) & 0x0f];
+ Buf[22] = HexDigits[(Guid->Data4[1] >> 0) & 0x0f];
+ Buf[23] = '-';
+ Buf[24] = HexDigits[(Guid->Data4[2] >> 4) & 0x0f];
+ Buf[25] = HexDigits[(Guid->Data4[2] >> 0) & 0x0f];
+ Buf[26] = HexDigits[(Guid->Data4[3] >> 4) & 0x0f];
+ Buf[27] = HexDigits[(Guid->Data4[3] >> 0) & 0x0f];
+ Buf[28] = HexDigits[(Guid->Data4[4] >> 4) & 0x0f];
+ Buf[29] = HexDigits[(Guid->Data4[4] >> 0) & 0x0f];
+ Buf[30] = HexDigits[(Guid->Data4[5] >> 4) & 0x0f];
+ Buf[31] = HexDigits[(Guid->Data4[5] >> 0) & 0x0f];
+ Buf[32] = HexDigits[(Guid->Data4[6] >> 4) & 0x0f];
+ Buf[33] = HexDigits[(Guid->Data4[6] >> 0) & 0x0f];
+ Buf[34] = HexDigits[(Guid->Data4[7] >> 4) & 0x0f];
+ Buf[35] = HexDigits[(Guid->Data4[7] >> 0) & 0x0f];
+ Buf[36] = '\0';
+}
+
+AvbIOResult AvbGetUniqueGuidForPartition(AvbOps *Ops, const char *PartitionName,
+ char *GuidBuf, size_t GuidBufSize)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ char unique_partition_guid[UNIQUE_PARTITION_GUID_SIZE];
+ CHAR16 UnicodePartition[MAX_GPT_NAME_SIZE] = {0};
+
+ Status = get_unique_guid(PartitionName, unique_partition_guid);
+ if (Status) {
+ dprintf(CRITICAL,
+ "get_unique_guid: No partition entry for %s\n",
+ PartitionName);
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ if ((strlen(PartitionName) + 1) > ARRAY_SIZE(UnicodePartition)) {
+ dprintf(CRITICAL, "AvbGetUniqueGuidForPartition: Partition "
+ "%s, name too large\n",
+ PartitionName);
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ GuidToHex(GuidBuf, (EFI_GUID *)unique_partition_guid);
+ dprintf(DEBUG, "%s uuid: %s\n", PartitionName, GuidBuf);
+
+ return AVB_IO_RESULT_OK;
+}
+
+AvbIOResult AvbGetSizeOfPartition(AvbOps *Ops, const char *Partition, uint64_t *OutSizeNumBytes)
+{
+ AvbIOResult Result = AVB_IO_RESULT_OK;
+ int index;
+
+ if (Ops == NULL || Partition == NULL || OutSizeNumBytes == NULL) {
+ dprintf(CRITICAL,
+ "AvbGetSizeOfPartition invalid parameter pointers\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ index = partition_get_index(Partition);
+ *OutSizeNumBytes = (uint64_t)partition_get_size(index);
+ if (*OutSizeNumBytes == 0)
+ return AVB_IO_RESULT_ERROR_IO;
+
+ return Result;
+}
+
+AvbOps *AvbOpsNew(VOID *UserData)
+{
+ AvbOps *Ops = avb_calloc(sizeof(AvbOps));
+ if (Ops == NULL) {
+ dprintf(CRITICAL, "Error allocating memory for AvbOps.\n");
+ goto out;
+ }
+
+ Ops->user_data = UserData;
+ Ops->read_from_partition = AvbReadFromPartition;
+ Ops->write_to_partition = AvbWriteToPartition;
+ Ops->validate_vbmeta_public_key = AvbValidateVbmetaPublicKey;
+ Ops->read_rollback_index = AvbReadRollbackIndex;
+ Ops->write_rollback_index = AvbWriteRollbackIndex;
+ Ops->read_is_device_unlocked = AvbReadIsDeviceUnlocked;
+ Ops->get_unique_guid_for_partition = AvbGetUniqueGuidForPartition;
+ Ops->get_size_of_partition = AvbGetSizeOfPartition;
+
+out:
+ return Ops;
+}
+
+VOID AvbOpsFree(AvbOps *Ops)
+{
+ if (Ops != NULL) {
+ avb_free(Ops);
+ }
+}
diff --git a/platform/msm_shared/avb/libavb/avb_ops.h b/platform/msm_shared/avb/libavb/avb_ops.h
index 2cf0f8a..15c7b22 100644
--- a/platform/msm_shared/avb/libavb/avb_ops.h
+++ b/platform/msm_shared/avb/libavb/avb_ops.h
@@ -63,6 +63,13 @@
struct AvbOps;
typedef struct AvbOps AvbOps;
+typedef struct {
+ uint32_t Data1;
+ uint16_t Data2;
+ uint16_t Data3;
+ uint8_t Data4[8];
+} EFI_GUID;
+
/* Forward-declaration of operations in libavb_ab. */
struct AvbABOps;
diff --git a/platform/msm_shared/avb/libavb/avb_sysdeps.h b/platform/msm_shared/avb/libavb/avb_sysdeps.h
index b7c5e8e..55e3e19 100644
--- a/platform/msm_shared/avb/libavb/avb_sysdeps.h
+++ b/platform/msm_shared/avb/libavb/avb_sysdeps.h
@@ -41,6 +41,7 @@
#include <stddef.h>
#include <stdint.h>
#include <verifiedboot.h>
+#include <crypto_hash.h>
/* If you don't have gcc or clang, these attribute macros may need to
* be adjusted.
diff --git a/platform/msm_shared/avb/rules.mk b/platform/msm_shared/avb/rules.mk
new file mode 100644
index 0000000..6795e1d
--- /dev/null
+++ b/platform/msm_shared/avb/rules.mk
@@ -0,0 +1,25 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LK_TOP_DIR)/include -I$(LK_TOP_DIR)/app/aboot -I$(LK_TOP_DIR)/platform/msm_shared -I$(LK_TOP_DIR)/platform/msm_shared/avb -I$(LK_TOP_DIR)/platform/msm_shared/include \
+
+CFLAGS += -DAVB_COMPILATION
+
+OBJS += $(LOCAL_DIR)/libavb/avb_chain_partition_descriptor.o \
+ $(LOCAL_DIR)/libavb/avb_crc32.o \
+ $(LOCAL_DIR)/libavb/avb_crypto.o \
+ $(LOCAL_DIR)/libavb/avb_descriptor.o \
+ $(LOCAL_DIR)/libavb/avb_footer.o \
+ $(LOCAL_DIR)/libavb/avb_hash_descriptor.o \
+ $(LOCAL_DIR)/libavb/avb_hashtree_descriptor.o \
+ $(LOCAL_DIR)/libavb/avb_kernel_cmdline_descriptor.o \
+ $(LOCAL_DIR)/libavb/avb_property_descriptor.o \
+ $(LOCAL_DIR)/libavb/avb_ops.o \
+ $(LOCAL_DIR)/libavb/avb_rsa.o \
+ $(LOCAL_DIR)/libavb/avb_sha256.o \
+ $(LOCAL_DIR)/libavb/avb_sha512.o \
+ $(LOCAL_DIR)/libavb/avb_slot_verify.o \
+ $(LOCAL_DIR)/libavb/avb_sysdeps_posix.o \
+ $(LOCAL_DIR)/libavb/avb_vbmeta_image.o \
+ $(LOCAL_DIR)/libavb/avb_util.o \
+ $(LOCAL_DIR)/libavb/avb_version.o \
+ $(LOCAL_DIR)/VerifiedBoot.o \
diff --git a/platform/msm_shared/display_menu.c b/platform/msm_shared/display_menu.c
index 8b74c9a..c9a58a8 100644
--- a/platform/msm_shared/display_menu.c
+++ b/platform/msm_shared/display_menu.c
@@ -78,7 +78,7 @@
static bool is_thread_start = false;
static struct select_msg_info msg_info;
-#if VERIFIED_BOOT
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
struct boot_verify_info {
int msg_type;
const char *warning_msg;
@@ -248,7 +248,7 @@
unlock_msg_info->info.option_index= 2;
}
-#if VERIFIED_BOOT
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
/* msg_lock need to be holded when call this function. */
void display_bootverify_menu_renew(struct select_msg_info *msg_info, int type)
{
@@ -525,7 +525,7 @@
display_menu_thread_start(fastboot_menu_msg_info);
}
-#if VERIFIED_BOOT
+#if VERIFIED_BOOT || VERIFIED_BOOT_2
void display_bootverify_menu(int type)
{
struct select_msg_info *bootverify_menu_msg_info;
diff --git a/platform/msm_shared/include/boot_device.h b/platform/msm_shared/include/boot_device.h
index 7d2451a..8fe4463 100644
--- a/platform/msm_shared/include/boot_device.h
+++ b/platform/msm_shared/include/boot_device.h
@@ -55,10 +55,40 @@
};
#endif
+#define MAX_NUMBER_OF_LOADED_IMAGES 32
+#ifndef MAX_GPT_NAME_SIZE
+#define MAX_GPT_NAME_SIZE 72
+#endif
+
+typedef struct {
+ char *name;
+ void *image_buffer;
+ uint32_t imgsize;
+} imagedata;
+
+typedef struct bootinfo {
+ int multi_slot_boot;
+ bool bootinto_recovery;
+ bool bootreason_alarm;
+ char pname[MAX_GPT_NAME_SIZE];
+ char bootable_slot[MAX_GPT_NAME_SIZE];
+ imagedata images[MAX_NUMBER_OF_LOADED_IMAGES];
+ uint32_t num_loaded_images;
+ uint32_t boot_state;
+ char *vbcmdline;
+ uint32_t vbcmdline_len;
+ uint32_t vbcmdline_filled_len;
+ void *vb_data;
+} bootinfo;
+
+int getimage(const bootinfo *Info, void **image_buffer, uint32_t *imgsize,
+ char *imgname);
+
void platform_read_boot_config();
uint32_t platform_get_boot_dev();
uint32_t platform_boot_dev_isemmc();
void platform_boot_dev_cmdline(char *buf);
+int get_boot_image_info(void **image_buffer, uint32_t *imgsize,char *imgname);
void *target_mmc_device();
#endif
diff --git a/platform/msm_shared/include/verifiedboot.h b/platform/msm_shared/include/verifiedboot.h
new file mode 100644
index 0000000..9e16982
--- /dev/null
+++ b/platform/msm_shared/include/verifiedboot.h
@@ -0,0 +1,170 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __VERIFIEDBOOT_H__
+#define __VERIFIEDBOOT_H__
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <mmc.h>
+#include <platform.h>
+#include <devinfo.h>
+#include <meta_format.h>
+#include <boot_device.h>
+#include <boot_verifier.h>
+#include <target.h>
+
+typedef enum {
+ NO_AVB = 0,
+ AVB_1,
+ AVB_2,
+ AVB_LE
+} avb_versions;
+
+#define VB_SHA256_SIZE 32
+#define LE_BOOTIMG_SIG_SIZE 256
+#define abort() ASSERT(false);
+#define MAX_PATH_SIZE 64
+
+#define EFIERR(_a) (-1 * (_a))
+
+#define EFI_SUCCESS 0
+#define EFI_LOAD_ERROR EFIERR (1)
+#define EFI_INVALID_PARAMETER EFIERR (2)
+#define EFI_UNSUPPORTED EFIERR (3)
+#define EFI_BAD_BUFFER_SIZE EFIERR (4)
+#define EFI_BUFFER_TOO_SMALL EFIERR (5)
+#define EFI_NOT_READY EFIERR (6)
+#define EFI_DEVICE_ERROR EFIERR (7)
+#define EFI_WRITE_PROTECTED EFIERR (8)
+#define EFI_OUT_OF_RESOURCES EFIERR (9)
+#define EFI_VOLUME_CORRUPTED EFIERR (10)
+#define EFI_VOLUME_FULL EFIERR (11)
+#define EFI_NO_MEDIA EFIERR (12)
+#define EFI_MEDIA_CHANGED EFIERR (13)
+#define EFI_NOT_FOUND EFIERR (14)
+#define EFI_ACCESS_DENIED EFIERR (15)
+#define EFI_NO_RESPONSE EFIERR (16)
+#define EFI_NO_MAPPING EFIERR (17)
+#define EFI_TIMEOUT EFIERR (18)
+#define EFI_NOT_STARTED EFIERR (19)
+#define EFI_ALREADY_STARTED EFIERR (20)
+#define EFI_ABORTED EFIERR (21)
+#define EFI_ICMP_ERROR EFIERR (22)
+
+#define EFI_TFTP_ERROR EFIERR (23)
+#define EFI_PROTOCOL_ERROR EFIERR (24)
+#define EFI_INCOMPATIBLE_VERSION EFIERR (25)
+#define EFI_SECURITY_VIOLATION EFIERR (26)
+#define EFI_CRC_ERROR EFIERR (27)
+#define EFI_END_OF_MEDIA EFIERR (28)
+#define EFI_END_OF_FILE EFIERR (31)
+#define EFI_INVALID_LANGUAGE EFIERR (32)
+
+#define EFI_WARN_UNKNOWN_GLYPH EFIWARN (1)
+#define EFI_WARN_DELETE_FAILURE EFIWARN (2)
+#define EFI_WARN_WRITE_FAILURE EFIWARN (3)
+#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN (4)
+
+typedef int EFI_STATUS;
+typedef bool BOOLEAN;
+typedef char CHAR8;
+typedef int16_t CHAR16;
+typedef void VOID;
+typedef uint8_t UINT8;
+typedef uint16_t UINT16;
+typedef uint32_t UINT32;
+typedef uint64_t UINT64;
+typedef int16_t INT16;
+typedef int32_t INT32;
+typedef int64_t INT64;
+typedef uintptr_t UINTN;
+
+typedef enum {
+ VB_UNDEFINED_HASH = 0,
+ VB_SHA1,
+ VB_SHA256,
+ VB_UNSUPPORTED_HASH,
+ VB_RESERVED_HASH = 0x7fffffff /* force to 32 bits */
+} vb_hash;
+
+#define GUARD(code) \
+ do { \
+ Status = (code); \
+ if (Status != EFI_SUCCESS) { \
+ dprintf(CRITICAL, "Err: line:%d %s() status: %d\n", __LINE__, \
+ __FUNCTION__, Status); \
+ return Status; \
+ } \
+ } while (0)
+
+#define GUARD_OUT(code) \
+ do { \
+ Status = (code); \
+ if (Status != EFI_SUCCESS) { \
+ dprintf(CRITICAL, "Err: line:%d %s() status: %d\n", __LINE__, \
+ __FUNCTION__, Status); \
+ goto out; \
+ } \
+ } while (0)
+
+/* forward declare bootinfo */
+typedef struct bootinfo bootinfo;
+
+BOOLEAN VerifiedBootEnabled();
+
+/**
+ * @return 0 - AVB disabled
+ * 1 - VB 1.0
+ * 2 - VB 2.0
+ * 3 - LE VB
+ */
+UINT32 GetAVBVersion();
+
+/**
+ * Authenticates and loads boot image in
+ * Info->Images on EFI_SUCCESS.
+ * Also provides Verified Boot command
+ * arguments (if any) in Info->vbcmdline
+ *
+ * @return EFI_STATUS
+ */
+int load_image_and_auth(bootinfo *Info);
+
+/**
+ * Free resources/memory allocated by
+ * verified boot, image_buffer, vbcmdline
+ * VBData...
+ *
+ * @return VOID
+ */
+void free_verified_boot_resource(bootinfo *Info);
+
+#endif /* __VERIFIEDBOOT_H__ */
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index f8460ff..82c7d88 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -698,3 +698,8 @@
ifeq ($(ENABLE_RPMB_SUPPORT), 1)
include platform/msm_shared/rpmb/rules.mk
endif
+
+ifeq ($(VERIFIED_BOOT_2), 1)
+OBJS += platform/msm_shared/boot_verifier.o
+endif
+include platform/msm_shared/avb/rules.mk