aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Kconfig9
-rw-r--r--test/Makefile2
-rw-r--r--test/cmd_ut.c6
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/fdtdec.c59
-rw-r--r--test/dm/test-fdt.c66
-rw-r--r--test/log/Makefile14
-rw-r--r--test/log/nolog_test.c135
-rw-r--r--test/log/syslog_test.c280
-rw-r--r--test/log/test-main.c20
-rw-r--r--test/py/README.md8
-rw-r--r--test/py/tests/test_efi_secboot/conftest.py151
-rw-r--r--test/py/tests/test_efi_secboot/defs.py21
-rw-r--r--test/py/tests/test_efi_secboot/test_authvar.py282
-rw-r--r--test/py/tests/test_efi_secboot/test_signed.py117
-rw-r--r--test/py/tests/test_efi_secboot/test_unsigned.py121
16 files changed, 1290 insertions, 2 deletions
diff --git a/test/Kconfig b/test/Kconfig
index 0157e0b060..28704a25b6 100644
--- a/test/Kconfig
+++ b/test/Kconfig
@@ -40,6 +40,15 @@ config UT_LIB_RSA
endif
+config UT_LOG
+ bool "Unit tests for logging functions"
+ depends on UNIT_TEST
+ default y
+ help
+ Enables the 'ut log' command which tests logging functions like
+ log_err().
+ See also CONFIG_LOG_TEST which provides the 'log test' command.
+
config UT_TIME
bool "Unit tests for time functions"
depends on UNIT_TEST
diff --git a/test/Makefile b/test/Makefile
index 2fe41f489c..2971d0d87f 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -10,5 +10,5 @@ obj-$(CONFIG_SANDBOX) += compression.o
obj-$(CONFIG_SANDBOX) += print_ut.o
obj-$(CONFIG_UT_TIME) += time_ut.o
obj-$(CONFIG_UT_UNICODE) += unicode_ut.o
-obj-$(CONFIG_$(SPL_)LOG) += log/
+obj-y += log/
obj-$(CONFIG_UNIT_TEST) += lib/
diff --git a/test/cmd_ut.c b/test/cmd_ut.c
index a3a9d49f7e..7fdcdbb1a6 100644
--- a/test/cmd_ut.c
+++ b/test/cmd_ut.c
@@ -60,6 +60,9 @@ static cmd_tbl_t cmd_ut_sub[] = {
#ifdef CONFIG_UT_LIB
U_BOOT_CMD_MKENT(lib, CONFIG_SYS_MAXARGS, 1, do_ut_lib, "", ""),
#endif
+#ifdef CONFIG_UT_LOG
+ U_BOOT_CMD_MKENT(log, CONFIG_SYS_MAXARGS, 1, do_ut_log, "", ""),
+#endif
#ifdef CONFIG_UT_TIME
U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),
#endif
@@ -125,6 +128,9 @@ static char ut_help_text[] =
#ifdef CONFIG_UT_LIB
"ut lib [test-name] - test library functions\n"
#endif
+#ifdef CONFIG_UT_LOG
+ "ut log [test-name] - test logging functions\n"
+#endif
#ifdef CONFIG_UT_OPTEE
"ut optee [test-name]\n"
#endif
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 3daf8a544e..f55874c0f2 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_LED) += led.o
obj-$(CONFIG_DM_MAILBOX) += mailbox.o
obj-$(CONFIG_DM_MMC) += mmc.o
obj-y += ofnode.o
+obj-y += fdtdec.o
obj-$(CONFIG_OSD) += osd.o
obj-$(CONFIG_DM_VIDEO) += panel.o
obj-$(CONFIG_DM_PCI) += pci.o
diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c
new file mode 100644
index 0000000000..b2f75b5843
--- /dev/null
+++ b/test/dm/fdtdec.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/of_extra.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+static int dm_test_fdtdec_set_carveout(struct unit_test_state *uts)
+{
+ struct fdt_memory resv;
+ void *blob;
+ const fdt32_t *prop;
+ int blob_sz, len, offset;
+
+ blob_sz = fdt_totalsize(gd->fdt_blob) + 4096;
+ blob = malloc(blob_sz);
+ ut_assertnonnull(blob);
+
+ /* Make a writtable copy of the fdt blob */
+ ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
+
+ resv.start = 0x1000;
+ resv.end = 0x2000;
+ ut_assertok(fdtdec_set_carveout(blob, "/a-test",
+ "memory-region", 2, "test_resv1",
+ &resv));
+
+ resv.start = 0x10000;
+ resv.end = 0x20000;
+ ut_assertok(fdtdec_set_carveout(blob, "/a-test",
+ "memory-region", 1, "test_resv2",
+ &resv));
+
+ resv.start = 0x100000;
+ resv.end = 0x200000;
+ ut_assertok(fdtdec_set_carveout(blob, "/a-test",
+ "memory-region", 0, "test_resv3",
+ &resv));
+
+ offset = fdt_path_offset(blob, "/a-test");
+ ut_assert(offset > 0);
+ prop = fdt_getprop(blob, offset, "memory-region", &len);
+ ut_assertnonnull(prop);
+
+ ut_asserteq(len, 12);
+ ut_assert(fdt_node_offset_by_phandle(blob, fdt32_to_cpu(prop[0])) > 0);
+ ut_assert(fdt_node_offset_by_phandle(blob, fdt32_to_cpu(prop[1])) > 0);
+ ut_assert(fdt_node_offset_by_phandle(blob, fdt32_to_cpu(prop[2])) > 0);
+
+ free(blob);
+
+ return 0;
+}
+DM_TEST(dm_test_fdtdec_set_carveout,
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index 75ae08081c..a56275aef9 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -255,7 +255,7 @@ static int dm_test_fdt(struct unit_test_state *uts)
int ret;
int i;
- ret = dm_scan_fdt(gd->fdt_blob, false);
+ ret = dm_extended_scan_fdt(gd->fdt_blob, false);
ut_assert(!ret);
ret = uclass_get(UCLASS_TEST_FDT, &uc);
@@ -867,6 +867,7 @@ static int dm_test_read_int(struct unit_test_state *uts)
u32 val32;
s32 sval;
uint val;
+ u64 val64;
ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
ut_asserteq_str("a-test", dev->name);
@@ -891,10 +892,48 @@ static int dm_test_read_int(struct unit_test_state *uts)
ut_assertok(dev_read_u32u(dev, "uint-value", &val));
ut_asserteq(-1234, val);
+ ut_assertok(dev_read_u64(dev, "int64-value", &val64));
+ ut_asserteq_64(0x1111222233334444, val64);
+
+ ut_asserteq_64(-EINVAL, dev_read_u64(dev, "missing", &val64));
+ ut_asserteq_64(6, dev_read_u64_default(dev, "missing", 6));
+
+ ut_asserteq_64(0x1111222233334444,
+ dev_read_u64_default(dev, "int64-value", 6));
+
return 0;
}
DM_TEST(dm_test_read_int, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+static int dm_test_read_int_index(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ u32 val32;
+
+ ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
+ ut_asserteq_str("a-test", dev->name);
+
+ ut_asserteq(-EINVAL, dev_read_u32_index(dev, "missing", 0, &val32));
+ ut_asserteq(19, dev_read_u32_index_default(dev, "missing", 0, 19));
+
+ ut_assertok(dev_read_u32_index(dev, "int-array", 0, &val32));
+ ut_asserteq(5678, val32);
+ ut_assertok(dev_read_u32_index(dev, "int-array", 1, &val32));
+ ut_asserteq(9123, val32);
+ ut_assertok(dev_read_u32_index(dev, "int-array", 2, &val32));
+ ut_asserteq(4567, val32);
+ ut_asserteq(-EOVERFLOW, dev_read_u32_index(dev, "int-array", 3,
+ &val32));
+
+ ut_asserteq(5678, dev_read_u32_index_default(dev, "int-array", 0, 2));
+ ut_asserteq(9123, dev_read_u32_index_default(dev, "int-array", 1, 2));
+ ut_asserteq(4567, dev_read_u32_index_default(dev, "int-array", 2, 2));
+ ut_asserteq(2, dev_read_u32_index_default(dev, "int-array", 3, 2));
+
+ return 0;
+}
+DM_TEST(dm_test_read_int_index, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
/* Test iteration through devices by drvdata */
static int dm_test_uclass_drvdata(struct unit_test_state *uts)
{
@@ -953,3 +992,28 @@ static int dm_test_first_child_probe(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_first_child_probe, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that ofdata is read for parents before children */
+static int dm_test_ofdata_order(struct unit_test_state *uts)
+{
+ struct udevice *bus, *dev;
+
+ ut_assertok(uclass_find_first_device(UCLASS_I2C, &bus));
+ ut_assertnonnull(bus);
+ ut_assert(!(bus->flags & DM_FLAG_PLATDATA_VALID));
+
+ ut_assertok(device_find_first_child(bus, &dev));
+ ut_assertnonnull(dev);
+ ut_assert(!(dev->flags & DM_FLAG_PLATDATA_VALID));
+
+ /* read the child's ofdata which should cause the parent's to be read */
+ ut_assertok(device_ofdata_to_platdata(dev));
+ ut_assert(dev->flags & DM_FLAG_PLATDATA_VALID);
+ ut_assert(bus->flags & DM_FLAG_PLATDATA_VALID);
+
+ ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
+ ut_assert(!(bus->flags & DM_FLAG_ACTIVATED));
+
+ return 0;
+}
+DM_TEST(dm_test_ofdata_order, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/log/Makefile b/test/log/Makefile
index e0d0a4745f..4c92550f6e 100644
--- a/test/log/Makefile
+++ b/test/log/Makefile
@@ -3,3 +3,17 @@
# Copyright (c) 2017 Google, Inc
obj-$(CONFIG_LOG_TEST) += log_test.o
+
+ifdef CONFIG_UT_LOG
+
+obj-y += test-main.o
+
+ifdef CONFIG_SANDBOX
+obj-$(CONFIG_LOG_SYSLOG) += syslog_test.o
+endif
+
+ifndef CONFIG_LOG
+obj-$(CONFIG_CONSOLE_RECORD) += nolog_test.o
+endif
+
+endif # CONFIG_UT_LOG
diff --git a/test/log/nolog_test.c b/test/log/nolog_test.c
new file mode 100644
index 0000000000..84619521c9
--- /dev/null
+++ b/test/log/nolog_test.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Logging function tests for CONFIG_LOG=n.
+ */
+
+/* Needed for testing log_debug() */
+#define DEBUG 1
+
+#include <common.h>
+#include <console.h>
+#include <test/log.h>
+#include <test/test.h>
+#include <test/suites.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define BUFFSIZE 32
+
+static int nolog_test_log_err(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ log_err("testing %s\n", "log_err");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "testing log_err"));
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_log_err);
+
+static int nolog_test_log_warning(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ log_warning("testing %s\n", "log_warning");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "testing log_warning"));
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_log_warning);
+
+static int nolog_test_log_notice(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ log_notice("testing %s\n", "log_notice");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "testing log_notice"));
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_log_notice);
+
+static int nolog_test_log_info(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ log_err("testing %s\n", "log_info");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "testing log_info"));
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_log_info);
+
+#undef _DEBUG
+#define _DEBUG 0
+static int nolog_test_nodebug(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ debug("testing %s\n", "debug");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_nodebug);
+
+static int nolog_test_log_nodebug(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ log_debug("testing %s\n", "log_debug");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assert(!strcmp(buf, ""));
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_log_nodebug);
+
+#undef _DEBUG
+#define _DEBUG 1
+static int nolog_test_debug(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ debug("testing %s\n", "debug");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "testing debug"));
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_debug);
+
+static int nolog_test_log_debug(struct unit_test_state *uts)
+{
+ char buf[BUFFSIZE];
+
+ memset(buf, 0, BUFFSIZE);
+ console_record_reset_enable();
+ log_debug("testing %s\n", "log_debug");
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "testing log_debug"));
+ ut_assertok(ut_check_console_end(uts));
+ return 0;
+}
+LOG_TEST(nolog_test_log_debug);
diff --git a/test/log/syslog_test.c b/test/log/syslog_test.c
new file mode 100644
index 0000000000..6ca5760eac
--- /dev/null
+++ b/test/log/syslog_test.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Logging function tests for CONFIG_LOG_SYSLOG=y.
+ *
+ * Invoke the test with: ./u-boot -d arch/sandbox/dts/test.dtb
+ */
+
+/* Override CONFIG_LOG_MAX_LEVEL */
+#define LOG_DEBUG
+
+#include <common.h>
+#include <dm/device.h>
+#include <hexdump.h>
+#include <test/log.h>
+#include <test/test.h>
+#include <test/suites.h>
+#include <test/ut.h>
+#include <asm/eth.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * struct sb_log_env - private data for sandbox ethernet driver
+ *
+ * This structure is used for the private data of the sandbox ethernet
+ * driver.
+ *
+ * @expected: string expected to be written by the syslog driver
+ * @uts: unit test state
+ */
+struct sb_log_env {
+ const char *expected;
+ struct unit_test_state *uts;
+};
+
+/**
+ * sb_log_tx_handler() - transmit callback function
+ *
+ * This callback function is invoked when a network package is sent using the
+ * sandbox Ethernet driver. The private data of the driver holds a sb_log_env
+ * structure with the unit test state and the expected UDP payload.
+ *
+ * The following checks are executed:
+ *
+ * * the Ethernet packet indicates a IP broadcast message
+ * * the IP header is for a local UDP broadcast message to port 514
+ * * the UDP payload matches the expected string
+ *
+ * After testing the pointer to the expected string is set to NULL to signal
+ * that the callback function has been called.
+ *
+ * @dev: sandbox ethernet device
+ * @packet: Ethernet packet
+ * @len: length of Ethernet packet
+ * Return: 0 = success
+ */
+static int sb_log_tx_handler(struct udevice *dev, void *packet,
+ unsigned int len)
+{
+ struct eth_sandbox_priv *priv = dev_get_priv(dev);
+ struct sb_log_env *env = priv->priv;
+ /* uts is updated by the ut_assert* macros */
+ struct unit_test_state *uts = env->uts;
+ char *buf = packet;
+ struct ethernet_hdr *eth_hdr = packet;
+ struct ip_udp_hdr *ip_udp_hdr;
+
+ /* Check Ethernet header */
+ ut_asserteq_mem(&eth_hdr->et_dest, net_bcast_ethaddr, ARP_HLEN);
+ ut_asserteq(ntohs(eth_hdr->et_protlen), PROT_IP);
+
+ /* Check IP header */
+ buf += sizeof(struct ethernet_hdr);
+ ip_udp_hdr = (struct ip_udp_hdr *)buf;
+ ut_asserteq(ip_udp_hdr->ip_p, IPPROTO_UDP);
+ ut_asserteq(ip_udp_hdr->ip_dst.s_addr, 0xffffffff);
+ ut_asserteq(ntohs(ip_udp_hdr->udp_dst), 514);
+ ut_asserteq(UDP_HDR_SIZE + strlen(env->expected) + 1,
+ ntohs(ip_udp_hdr->udp_len));
+
+ /* Check payload */
+ buf += sizeof(struct ip_udp_hdr);
+ ut_asserteq_mem(env->expected, buf,
+ ntohs(ip_udp_hdr->udp_len) - UDP_HDR_SIZE);
+
+ /* Signal that the callback function has been executed */
+ env->expected = NULL;
+
+ return 0;
+}
+
+/**
+ * syslog_test_log_err() - test log_err() function
+ *
+ * @uts: unit test state
+ * Return: 0 = success
+ */
+static int syslog_test_log_err(struct unit_test_state *uts)
+{
+ int old_log_level = gd->default_log_level;
+ struct sb_log_env env;
+
+ gd->log_fmt = LOGF_DEFAULT;
+ gd->default_log_level = LOGL_INFO;
+ env_set("ethact", "eth@10002000");
+ env_set("log_hostname", "sandbox");
+ env.expected = "<3>sandbox uboot: syslog_test_log_err() "
+ "testing log_err\n";
+ env.uts = uts;
+ sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+ /* Used by ut_assert macros in the tx_handler */
+ sandbox_eth_set_priv(0, &env);
+ log_err("testing %s\n", "log_err");
+ /* Check that the callback function was called */
+ sandbox_eth_set_tx_handler(0, NULL);
+ gd->default_log_level = old_log_level;
+
+ return 0;
+}
+LOG_TEST(syslog_test_log_err);
+
+/**
+ * syslog_test_log_warning() - test log_warning() function
+ *
+ * @uts: unit test state
+ * Return: 0 = success
+ */
+static int syslog_test_log_warning(struct unit_test_state *uts)
+{
+ int old_log_level = gd->default_log_level;
+ struct sb_log_env env;
+
+ gd->log_fmt = LOGF_DEFAULT;
+ gd->default_log_level = LOGL_INFO;
+ env_set("ethact", "eth@10002000");
+ env_set("log_hostname", "sandbox");
+ env.expected = "<4>sandbox uboot: syslog_test_log_warning() "
+ "testing log_warning\n";
+ env.uts = uts;
+ sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+ /* Used by ut_assert macros in the tx_handler */
+ sandbox_eth_set_priv(0, &env);
+ log_warning("testing %s\n", "log_warning");
+ sandbox_eth_set_tx_handler(0, NULL);
+ /* Check that the callback function was called */
+ ut_assertnull(env.expected);
+ gd->default_log_level = old_log_level;
+
+ return 0;
+}
+LOG_TEST(syslog_test_log_warning);
+
+/**
+ * syslog_test_log_notice() - test log_notice() function
+ *
+ * @uts: unit test state
+ * Return: 0 = success
+ */
+static int syslog_test_log_notice(struct unit_test_state *uts)
+{
+ int old_log_level = gd->default_log_level;
+ struct sb_log_env env;
+
+ gd->log_fmt = LOGF_DEFAULT;
+ gd->default_log_level = LOGL_INFO;
+ env_set("ethact", "eth@10002000");
+ env_set("log_hostname", "sandbox");
+ env.expected = "<5>sandbox uboot: syslog_test_log_notice() "
+ "testing log_notice\n";
+ env.uts = uts;
+ sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+ /* Used by ut_assert macros in the tx_handler */
+ sandbox_eth_set_priv(0, &env);
+ log_notice("testing %s\n", "log_notice");
+ sandbox_eth_set_tx_handler(0, NULL);
+ /* Check that the callback function was called */
+ ut_assertnull(env.expected);
+ gd->default_log_level = old_log_level;
+
+ return 0;
+}
+LOG_TEST(syslog_test_log_notice);
+
+/**
+ * syslog_test_log_info() - test log_info() function
+ *
+ * @uts: unit test state
+ * Return: 0 = success
+ */
+static int syslog_test_log_info(struct unit_test_state *uts)
+{
+ int old_log_level = gd->default_log_level;
+ struct sb_log_env env;
+
+ gd->log_fmt = LOGF_DEFAULT;
+ gd->default_log_level = LOGL_INFO;
+ env_set("ethact", "eth@10002000");
+ env_set("log_hostname", "sandbox");
+ env.expected = "<6>sandbox uboot: syslog_test_log_info() "
+ "testing log_info\n";
+ env.uts = uts;
+ sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+ /* Used by ut_assert macros in the tx_handler */
+ sandbox_eth_set_priv(0, &env);
+ log_info("testing %s\n", "log_info");
+ sandbox_eth_set_tx_handler(0, NULL);
+ /* Check that the callback function was called */
+ ut_assertnull(env.expected);
+ gd->default_log_level = old_log_level;
+
+ return 0;
+}
+LOG_TEST(syslog_test_log_info);
+
+/**
+ * syslog_test_log_debug() - test log_debug() function
+ *
+ * @uts: unit test state
+ * Return: 0 = success
+ */
+static int syslog_test_log_debug(struct unit_test_state *uts)
+{
+ int old_log_level = gd->default_log_level;
+ struct sb_log_env env;
+
+ gd->log_fmt = LOGF_DEFAULT;
+ gd->default_log_level = LOGL_DEBUG;
+ env_set("ethact", "eth@10002000");
+ env_set("log_hostname", "sandbox");
+ env.expected = "<7>sandbox uboot: syslog_test_log_debug() "
+ "testing log_debug\n";
+ env.uts = uts;
+ sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+ /* Used by ut_assert macros in the tx_handler */
+ sandbox_eth_set_priv(0, &env);
+ log_debug("testing %s\n", "log_debug");
+ sandbox_eth_set_tx_handler(0, NULL);
+ /* Check that the callback function was called */
+ ut_assertnull(env.expected);
+ gd->default_log_level = old_log_level;
+
+ return 0;
+}
+LOG_TEST(syslog_test_log_debug);
+
+/**
+ * syslog_test_log_nodebug() - test logging level filter
+ *
+ * Verify that log_debug() does not lead to a log message if the logging level
+ * is set to LOGL_INFO.
+ *
+ * @uts: unit test state
+ * Return: 0 = success
+ */
+static int syslog_test_log_nodebug(struct unit_test_state *uts)
+{
+ int old_log_level = gd->default_log_level;
+ struct sb_log_env env;
+
+ gd->log_fmt = LOGF_DEFAULT;
+ gd->default_log_level = LOGL_INFO;
+ env_set("ethact", "eth@10002000");
+ env_set("log_hostname", "sandbox");
+ env.expected = "<7>sandbox uboot: syslog_test_log_nodebug() "
+ "testing log_debug\n";
+ env.uts = uts;
+ sandbox_eth_set_tx_handler(0, sb_log_tx_handler);
+ /* Used by ut_assert macros in the tx_handler */
+ sandbox_eth_set_priv(0, &env);
+ log_debug("testing %s\n", "log_debug");
+ sandbox_eth_set_tx_handler(0, NULL);
+ /* Check that the callback function was not called */
+ ut_assertnonnull(env.expected);
+ gd->default_log_level = old_log_level;
+
+ return 0;
+}
+LOG_TEST(syslog_test_log_nodebug);
diff --git a/test/log/test-main.c b/test/log/test-main.c
new file mode 100644
index 0000000000..855de47f33
--- /dev/null
+++ b/test/log/test-main.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Logging function tests.
+ */
+
+#include <common.h>
+#include <console.h>
+#include <test/log.h>
+#include <test/suites.h>
+
+int do_ut_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct unit_test *tests = ll_entry_start(struct unit_test, log_test);
+ const int n_ents = ll_entry_count(struct unit_test, log_test);
+
+ return cmd_ut_category("log", "log_test_",
+ tests, n_ents, argc, argv);
+}
diff --git a/test/py/README.md b/test/py/README.md
index 2e5025258d..fddc104b26 100644
--- a/test/py/README.md
+++ b/test/py/README.md
@@ -37,7 +37,15 @@ will be required. The following is an incomplete list:
| openssl |
| sudo OR guestmount |
| e2fsprogs |
+| util-linux |
+| coreutils |
| dosfstools |
+| efitools |
+| mount |
+| mtools |
+| sbsigntool |
+| udisks2 |
+
Please use the apporirate commands for your distribution to match these tools
up with the package that provides them.
diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py
new file mode 100644
index 0000000000..e542fef6e8
--- /dev/null
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -0,0 +1,151 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2019, Linaro Limited
+# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+
+import os
+import os.path
+import pytest
+import re
+from subprocess import call, check_call, check_output, CalledProcessError
+from defs import *
+
+# from test/py/conftest.py
+def tool_is_in_path(tool):
+ for path in os.environ["PATH"].split(os.pathsep):
+ fn = os.path.join(path, tool)
+ if os.path.isfile(fn) and os.access(fn, os.X_OK):
+ return True
+ return False
+
+#
+# Fixture for UEFI secure boot test
+#
+@pytest.fixture(scope='session')
+def efi_boot_env(request, u_boot_config):
+ """Set up a file system to be used in UEFI secure boot test.
+
+ Args:
+ request: Pytest request object.
+ u_boot_config: U-boot configuration.
+
+ Return:
+ A path to disk image to be used for testing
+ """
+ global HELLO_PATH
+
+ image_path = u_boot_config.persistent_data_dir
+ image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME
+ image_size = EFI_SECBOOT_IMAGE_SIZE
+ part_size = EFI_SECBOOT_PART_SIZE
+ fs_type = EFI_SECBOOT_FS_TYPE
+
+ if HELLO_PATH == '':
+ HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi'
+
+ try:
+ non_root = tool_is_in_path('udisksctl')
+
+ # create a disk/partition
+ check_call('dd if=/dev/zero of=%s bs=1MiB count=%d'
+ % (image_path, image_size), shell=True)
+ check_call('sgdisk %s -n 1:0:+%dMiB'
+ % (image_path, part_size), shell=True)
+ # create a file system
+ check_call('dd if=/dev/zero of=%s.tmp bs=1MiB count=%d'
+ % (image_path, part_size), shell=True)
+ check_call('mkfs -t %s %s.tmp' % (fs_type, image_path), shell=True)
+ check_call('dd if=%s.tmp of=%s bs=1MiB seek=1 count=%d conv=notrunc'
+ % (image_path, image_path, 1), shell=True)
+ check_call('rm %s.tmp' % image_path, shell=True)
+ if non_root:
+ out_data = check_output('udisksctl loop-setup -f %s -o %d'
+ % (image_path, 1048576), shell=True).decode()
+ m = re.search('(?<= as )(.*)\.', out_data)
+ loop_dev = m.group(1)
+ # print 'loop device is: %s' % loop_dev
+ out_data = check_output('udisksctl info -b %s'
+ % loop_dev, shell=True).decode()
+ m = re.search('MountPoints:[ \t]+(.*)', out_data)
+ mnt_point = m.group(1)
+ else:
+ loop_dev = check_output('sudo losetup -o 1MiB --sizelimit %dMiB --show -f %s | tr -d "\n"'
+ % (part_size, image_path), shell=True).decode()
+ mnt_point = '/mnt'
+ check_output('sudo mount -t %s -o umask=000 %s %s'
+ % (fs_type, loop_dev, mnt_point), shell=True)
+
+ # print 'mount point is: %s' % mnt_point
+
+ # suffix
+ # *.key: RSA private key in PEM
+ # *.crt: X509 certificate (self-signed) in PEM
+ # *.esl: signature list
+ # *.hash: message digest of image as signature list
+ # *.auth: signed signature list in signature database format
+ # *.efi: UEFI image
+ # *.efi.signed: signed UEFI image
+
+ # Create signature database
+ ## PK
+ check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ -keyout PK.key -out PK.crt -nodes -days 365'
+ % mnt_point, shell=True)
+ check_call('cd %s; %scert-to-efi-sig-list -g %s PK.crt PK.esl; %ssign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth'
+ % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+ shell=True)
+ ## PK_null for deletion
+ check_call('cd %s; sleep 2; touch PK_null.esl; %ssign-efi-sig-list -c PK.crt -k PK.key PK PK_null.esl PK_null.auth'
+ % (mnt_point, EFITOOLS_PATH), shell=True)
+ ## KEK
+ check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ -keyout KEK.key -out KEK.crt -nodes -days 365'
+ % mnt_point, shell=True)
+ check_call('cd %s; %scert-to-efi-sig-list -g %s KEK.crt KEK.esl; %ssign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth'
+ % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+ shell=True)
+ ## db
+ check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ -keyout db.key -out db.crt -nodes -days 365'
+ % mnt_point, shell=True)
+ check_call('cd %s; %scert-to-efi-sig-list -g %s db.crt db.esl; %ssign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth'
+ % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+ shell=True)
+ ## db1
+ check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db1/ -keyout db1.key -out db1.crt -nodes -days 365'
+ % mnt_point, shell=True)
+ check_call('cd %s; %scert-to-efi-sig-list -g %s db1.crt db1.esl; %ssign-efi-sig-list -c KEK.crt -k KEK.key db db1.esl db1.auth'
+ % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+ shell=True)
+ ## db1-update
+ check_call('cd %s; %ssign-efi-sig-list -a -c KEK.crt -k KEK.key db db1.esl db1-update.auth'
+ % (mnt_point, EFITOOLS_PATH), shell=True)
+ ## dbx
+ check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_dbx/ -keyout dbx.key -out dbx.crt -nodes -days 365'
+ % mnt_point, shell=True)
+ check_call('cd %s; %scert-to-efi-sig-list -g %s dbx.crt dbx.esl; %ssign-efi-sig-list -c KEK.crt -k KEK.key dbx dbx.esl dbx.auth'
+ % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+ shell=True)
+
+ # Copy image
+ check_call('cp %s %s' % (HELLO_PATH, mnt_point), shell=True)
+
+ ## Sign image
+ check_call('cd %s; sbsign --key db.key --cert db.crt helloworld.efi'
+ % mnt_point, shell=True)
+ ## Digest image
+ check_call('cd %s; %shash-to-efi-sig-list helloworld.efi db_hello.hash; %ssign-efi-sig-list -c KEK.crt -k KEK.key db db_hello.hash db_hello.auth'
+ % (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH),
+ shell=True)
+
+ if non_root:
+ check_call('udisksctl unmount -b %s' % loop_dev, shell=True)
+ # not needed
+ # check_call('udisksctl loop-delete -b %s' % loop_dev, shell=True)
+ else:
+ check_call('sudo umount %s' % loop_dev, shell=True)
+ check_call('sudo losetup -d %s' % loop_dev, shell=True)
+
+ except CalledProcessError as e:
+ pytest.skip('Setup failed: %s' % e.cmd)
+ return
+ else:
+ yield image_path
+ finally:
+ call('rm -f %s' % image_path, shell=True)
diff --git a/test/py/tests/test_efi_secboot/defs.py b/test/py/tests/test_efi_secboot/defs.py
new file mode 100644
index 0000000000..d6222809c5
--- /dev/null
+++ b/test/py/tests/test_efi_secboot/defs.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+# Disk image name
+EFI_SECBOOT_IMAGE_NAME='test_efi_secboot.img'
+
+# Size in MiB
+EFI_SECBOOT_IMAGE_SIZE=16
+EFI_SECBOOT_PART_SIZE=8
+
+# Partition file system type
+EFI_SECBOOT_FS_TYPE='vfat'
+
+# Owner guid
+GUID='11111111-2222-3333-4444-123456789abc'
+
+# v1.5.1 or earlier of efitools has a bug in sha256 calculation, and
+# you need build a newer version on your own.
+EFITOOLS_PATH=''
+
+# Hello World application for sandbox
+HELLO_PATH=''
diff --git a/test/py/tests/test_efi_secboot/test_authvar.py b/test/py/tests/test_efi_secboot/test_authvar.py
new file mode 100644
index 0000000000..55dcaa95f1
--- /dev/null
+++ b/test/py/tests/test_efi_secboot/test_authvar.py
@@ -0,0 +1,282 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2019, Linaro Limited
+# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+#
+# U-Boot UEFI: Variable Authentication Test
+
+"""
+This test verifies variable authentication
+"""
+
+import pytest
+import re
+from defs import *
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('efi_secure_boot')
+@pytest.mark.buildconfigspec('cmd_fat')
+@pytest.mark.buildconfigspec('cmd_nvedit_efi')
+@pytest.mark.slow
+class TestEfiAuthVar(object):
+ def test_efi_var_auth1(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 1 - Install signature database
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 1a'):
+ # Test Case 1a, Initial secure state
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'printenv -e SecureBoot'])
+ assert('00000000: 00' in ''.join(output))
+
+ output = u_boot_console.run_command(
+ 'printenv -e SetupMode')
+ assert('00000000: 01' in output)
+
+ with u_boot_console.log.section('Test Case 1b'):
+ # Test Case 1b, PK without AUTHENTICATED_WRITE_ACCESS
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -i 4000000,$filesize PK'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 1c'):
+ # Test Case 1c, install PK
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK',
+ 'printenv -e -n PK'])
+ assert(re.search('PK:', ''.join(output)))
+
+ output = u_boot_console.run_command(
+ 'printenv -e SecureBoot')
+ assert('00000000: 01' in output)
+ output = u_boot_console.run_command(
+ 'printenv -e SetupMode')
+ assert('00000000: 00' in output)
+
+ with u_boot_console.log.section('Test Case 1d'):
+ # Test Case 1d, db/dbx without KEK
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize dbx'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 1e'):
+ # Test Case 1e, install KEK
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -i 4000000,$filesize KEK'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'printenv -e -n KEK'])
+ assert(re.search('KEK:', ''.join(output)))
+
+ output = u_boot_console.run_command(
+ 'printenv -e SecureBoot')
+ assert('00000000: 01' in output)
+
+ with u_boot_console.log.section('Test Case 1f'):
+ # Test Case 1f, install db
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -i 4000000,$filesize db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ output = u_boot_console.run_command(
+ 'printenv -e SecureBoot')
+ assert('00000000: 01' in output)
+
+ with u_boot_console.log.section('Test Case 1g'):
+ # Test Case 1g, install dbx
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -i 4000000,$filesize db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ output = u_boot_console.run_command(
+ 'printenv -e SecureBoot')
+ assert('00000000: 01' in output)
+
+ def test_efi_var_auth2(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 2 - Update database by overwriting
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 2a'):
+ # Test Case 2a, update without AUTHENTICATED_WRITE_ACCESS
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db1.auth',
+ 'setenv -e -nv -bs -rt -i 4000000,$filesize db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 2b'):
+ # Test Case 2b, update without correct signature
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.esl',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 2c'):
+ # Test Case 2c, update with correct signature
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db1.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ def test_efi_var_auth3(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 3 - Append database
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 3a'):
+ # Test Case 3a, update without AUTHENTICATED_WRITE_ACCESS
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db1.auth',
+ 'setenv -e -nv -bs -rt -a -i 4000000,$filesize db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 3b'):
+ # Test Case 3b, update without correct signature
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.esl',
+ 'setenv -e -nv -bs -rt -at -a -i 4000000,$filesize db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 3c'):
+ # Test Case 3c, update with correct signature
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db1.auth',
+ 'setenv -e -nv -bs -rt -at -a -i 4000000,$filesize db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ def test_efi_var_auth4(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 4 - Delete database without authentication
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 4a'):
+ # Test Case 4a, update without AUTHENTICATED_WRITE_ACCESS
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'setenv -e -nv -bs -rt db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 4b'):
+ # Test Case 4b, update without correct signature/data
+ output = u_boot_console.run_command_list([
+ 'setenv -e -nv -bs -rt -at db',
+ 'printenv -e -n -guid d719b2cb-3d3a-4596-a3bc-dad00e67656f db'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('db:', ''.join(output)))
+
+ def test_efi_var_auth5(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 5 - Uninstall(delete) PK
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 5a'):
+ # Test Case 5a, Uninstall PK without correct signature
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'printenv -e -n PK'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('PK:', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 PK_null.esl',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK',
+ 'printenv -e -n PK'])
+ assert(re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('PK:', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 5b'):
+ # Test Case 5b, Uninstall PK with correct signature
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 PK_null.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK',
+ 'printenv -e -n PK'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ assert(re.search('\"PK\" not defined', ''.join(output)))
+
+ output = u_boot_console.run_command(
+ 'printenv -e SecureBoot')
+ assert('00000000: 00' in output)
+ output = u_boot_console.run_command(
+ 'printenv -e SetupMode')
+ assert('00000000: 01' in output)
diff --git a/test/py/tests/test_efi_secboot/test_signed.py b/test/py/tests/test_efi_secboot/test_signed.py
new file mode 100644
index 0000000000..584282b338
--- /dev/null
+++ b/test/py/tests/test_efi_secboot/test_signed.py
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2019, Linaro Limited
+# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+#
+# U-Boot UEFI: Signed Image Authentication Test
+
+"""
+This test verifies image authentication for signed images.
+"""
+
+import pytest
+import re
+from defs import *
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('efi_secure_boot')
+@pytest.mark.buildconfigspec('cmd_efidebug')
+@pytest.mark.buildconfigspec('cmd_fat')
+@pytest.mark.buildconfigspec('cmd_nvedit_efi')
+@pytest.mark.slow
+class TestEfiSignedImage(object):
+ def test_efi_signed_image_auth1(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 1 - authenticated by db
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 1a'):
+ # Test Case 1a, run signed image if no db/dbx
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'efidebug boot add 1 HELLO1 host 0:1 /helloworld.efi.signed ""',
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('Hello, world!', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 1b'):
+ # Test Case 1b, run unsigned image if no db/dbx
+ output = u_boot_console.run_command_list([
+ 'efidebug boot add 2 HELLO2 host 0:1 /helloworld.efi ""',
+ 'efidebug boot next 2',
+ 'bootefi bootmgr'])
+ assert(re.search('Hello, world!', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 1c'):
+ # Test Case 1c, not authenticated by db
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 2',
+ 'bootefi bootmgr'])
+ assert(re.search('\'HELLO2\' failed', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 2',
+ 'efidebug test bootmgr'])
+ assert(re.search('efi_start_image[(][)] returned: 26',
+ ''.join(output)))
+ assert(not re.search('Hello, world!', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 1d'):
+ # Test Case 1d, authenticated by db
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('Hello, world!', ''.join(output)))
+
+ def test_efi_signed_image_auth2(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 2 - rejected by dbx
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 2a'):
+ # Test Case 2a, rejected by dbx
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize dbx',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi.signed ""',
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('\'HELLO\' failed', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 1',
+ 'efidebug test bootmgr'])
+ assert(re.search('efi_start_image[(][)] returned: 26',
+ ''.join(output)))
+ assert(not re.search('Hello, world!', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 2b'):
+ # Test Case 2b, rejected by dbx even if db allows
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('\'HELLO\' failed', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 1',
+ 'efidebug test bootmgr'])
+ assert(re.search('efi_start_image[(][)] returned: 26',
+ ''.join(output)))
+ assert(not re.search('Hello, world!', ''.join(output)))
diff --git a/test/py/tests/test_efi_secboot/test_unsigned.py b/test/py/tests/test_efi_secboot/test_unsigned.py
new file mode 100644
index 0000000000..22d849afb8
--- /dev/null
+++ b/test/py/tests/test_efi_secboot/test_unsigned.py
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2019, Linaro Limited
+# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+#
+# U-Boot UEFI: Signed Image Authentication Test
+
+"""
+This test verifies image authentication for unsigned images.
+"""
+
+import pytest
+import re
+from defs import *
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('efi_secure_boot')
+@pytest.mark.buildconfigspec('cmd_efidebug')
+@pytest.mark.buildconfigspec('cmd_fat')
+@pytest.mark.buildconfigspec('cmd_nvedit_efi')
+@pytest.mark.slow
+class TestEfiUnsignedImage(object):
+ def test_efi_unsigned_image_auth1(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 1 - rejected when not digest in db or dbx
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 1'):
+ # Test Case 1
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('\'HELLO\' failed', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 1',
+ 'efidebug test bootmgr'])
+ assert(re.search('efi_start_image[(][)] returned: 26',
+ ''.join(output)))
+ assert(not re.search('Hello, world!', ''.join(output)))
+
+ def test_efi_unsigned_image_auth2(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 2 - authenticated by digest in db
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 2'):
+ # Test Case 2
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 db_hello.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('Hello, world!', ''.join(output)))
+
+ def test_efi_unsigned_image_auth3(self, u_boot_console, efi_boot_env):
+ """
+ Test Case 3 - rejected by digest in dbx
+ """
+ u_boot_console.restart_uboot()
+ disk_img = efi_boot_env
+ with u_boot_console.log.section('Test Case 3a'):
+ # Test Case 3a, rejected by dbx
+ output = u_boot_console.run_command_list([
+ 'host bind 0 %s' % disk_img,
+ 'fatload host 0:1 4000000 db_hello.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize dbx',
+ 'fatload host 0:1 4000000 KEK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK',
+ 'fatload host 0:1 4000000 PK.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('\'HELLO\' failed', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 1',
+ 'efidebug test bootmgr'])
+ assert(re.search('efi_start_image[(][)] returned: 26',
+ ''.join(output)))
+ assert(not re.search('Hello, world!', ''.join(output)))
+
+ with u_boot_console.log.section('Test Case 3b'):
+ # Test Case 3b, rejected by dbx even if db allows
+ output = u_boot_console.run_command_list([
+ 'fatload host 0:1 4000000 db_hello.auth',
+ 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db'])
+ assert(not re.search('Failed to set EFI variable', ''.join(output)))
+
+ output = u_boot_console.run_command_list([
+ 'efidebug boot add 1 HELLO host 0:1 /helloworld.efi ""',
+ 'efidebug boot next 1',
+ 'bootefi bootmgr'])
+ assert(re.search('\'HELLO\' failed', ''.join(output)))
+ output = u_boot_console.run_command_list([
+ 'efidebug boot next 1',
+ 'efidebug test bootmgr'])
+ assert(re.search('efi_start_image[(][)] returned: 26',
+ ''.join(output)))
+ assert(not re.search('Hello, world!', ''.join(output)))