summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-03-15 08:41:14 -0400
committerTom Rini <trini@konsulko.com>2021-03-15 08:41:14 -0400
commit1876b390f31afca15de334e499aa071b0bf64a44 (patch)
treeb22356b605c5881781ab4ea88743054558753149
parentc57ec2c2bab00c02a457ca70624c1333c60c2ec0 (diff)
parent7f047b4f5b4c86b53dbdd002322dcbf007f80623 (diff)
downloadu-boot-1876b390f31afca15de334e499aa071b0bf64a44.tar.gz
u-boot-1876b390f31afca15de334e499aa071b0bf64a44.tar.xz
u-boot-1876b390f31afca15de334e499aa071b0bf64a44.zip
Merge branch '2021-03-12-assorted-improvements' into next
- More log enhancements - A few warning fixes in some cases - Secure Channel Protocol 03 (SCP03) support for TEEs
-rw-r--r--arch/Kconfig2
-rw-r--r--cmd/Kconfig9
-rw-r--r--cmd/Makefile3
-rw-r--r--cmd/scp03.c52
-rw-r--r--common/Kconfig8
-rw-r--r--common/Makefile1
-rw-r--r--common/log.c16
-rw-r--r--common/log_console.c26
-rw-r--r--common/scp03.c53
-rw-r--r--doc/arch/sandbox.rst2
-rw-r--r--doc/develop/logging.rst31
-rw-r--r--doc/usage/index.rst1
-rw-r--r--doc/usage/scp03.rst33
-rw-r--r--drivers/tee/optee/Kconfig6
-rw-r--r--drivers/tee/sandbox.c54
-rw-r--r--drivers/tpm/tpm2_tis_sandbox.c2
-rw-r--r--include/asm-generic/global_data.h6
-rw-r--r--include/log.h36
-rw-r--r--include/scp03.h21
-rw-r--r--include/tee/optee_ta_scp03.h21
-rw-r--r--test/dm/acpi.c12
-rw-r--r--test/log/cont_test.c19
-rw-r--r--test/py/tests/test_scp03.py27
23 files changed, 407 insertions, 34 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 27843cd79c..7023223927 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -142,6 +142,8 @@ config SANDBOX
imply AVB_VERIFY
imply LIBAVB
imply CMD_AVB
+ imply SCP03
+ imply CMD_SCP03
imply UDP_FUNCTION_FASTBOOT
imply VIRTIO_MMIO
imply VIRTIO_PCI
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 4defbd9cf9..960080d6d4 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2022,12 +2022,19 @@ config HASH_VERIFY
help
Add -v option to verify data against a hash.
+config CMD_SCP03
+ bool "scp03 - SCP03 enable and rotate/provision operations"
+ depends on SCP03
+ help
+ This command provides access to a Trusted Application
+ running in a TEE to request Secure Channel Protocol 03
+ (SCP03) enablement and/or rotation of its SCP03 keys.
+
config CMD_TPM_V1
bool
config CMD_TPM_V2
bool
- select CMD_LOG
config CMD_TPM
bool "Enable the 'tpm' command"
diff --git a/cmd/Makefile b/cmd/Makefile
index 176bf925fd..a7017e8452 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -193,6 +193,9 @@ obj-$(CONFIG_CMD_BLOB) += blob.o
# Android Verified Boot 2.0
obj-$(CONFIG_CMD_AVB) += avb.o
+# Foundries.IO SCP03
+obj-$(CONFIG_CMD_SCP03) += scp03.o
+
obj-$(CONFIG_ARM) += arm/
obj-$(CONFIG_RISCV) += riscv/
obj-$(CONFIG_SANDBOX) += sandbox/
diff --git a/cmd/scp03.c b/cmd/scp03.c
new file mode 100644
index 0000000000..655e0bba08
--- /dev/null
+++ b/cmd/scp03.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <env.h>
+#include <scp03.h>
+
+int do_scp03_enable(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (argc != 1)
+ return CMD_RET_USAGE;
+
+ if (tee_enable_scp03()) {
+ printf("TEE failed to enable SCP03\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("SCP03 is enabled\n");
+
+ return CMD_RET_SUCCESS;
+}
+
+int do_scp03_provision(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (argc != 1)
+ return CMD_RET_USAGE;
+
+ if (tee_provision_scp03()) {
+ printf("TEE failed to provision SCP03 keys\n");
+ return CMD_RET_FAILURE;
+ }
+
+ printf("SCP03 is provisioned\n");
+
+ return CMD_RET_SUCCESS;
+}
+
+static char text[] =
+ "provides a command to enable SCP03 and provision the SCP03 keys\n"
+ " enable - enable SCP03 on the TEE\n"
+ " provision - provision SCP03 on the TEE\n";
+
+U_BOOT_CMD_WITH_SUBCMDS(scp03, "Secure Channel Protocol 03 control", text,
+ U_BOOT_SUBCMD_MKENT(enable, 1, 1, do_scp03_enable),
+ U_BOOT_SUBCMD_MKENT(provision, 1, 1, do_scp03_provision));
+
diff --git a/common/Kconfig b/common/Kconfig
index 2bb3798f80..482f123534 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -588,6 +588,14 @@ config AVB_BUF_SIZE
endif # AVB_VERIFY
+config SCP03
+ bool "Build SCP03 - Secure Channel Protocol O3 - controls"
+ depends on OPTEE || SANDBOX
+ depends on TEE
+ help
+ This option allows U-Boot to enable and or provision SCP03 on an OPTEE
+ controlled Secured Element.
+
config SPL_HASH
bool # "Support hashing API (SHA1, SHA256, etc.)"
help
diff --git a/common/Makefile b/common/Makefile
index daeea67cf2..215b8b26fd 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -137,3 +137,4 @@ obj-$(CONFIG_CMD_LOADB) += xyzModem.o
obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o
obj-$(CONFIG_AVB_VERIFY) += avb_verify.o
+obj-$(CONFIG_SCP03) += scp03.o
diff --git a/common/log.c b/common/log.c
index 6b0034c3ba..ea407c6db9 100644
--- a/common/log.c
+++ b/common/log.c
@@ -153,7 +153,7 @@ static bool log_passes_filters(struct log_device *ldev, struct log_rec *rec)
{
struct log_filter *filt;
- if (rec->force_debug)
+ if (rec->flags & LOGRECF_FORCE_DEBUG)
return true;
/* If there are no filters, filter on the default log level */
@@ -218,8 +218,11 @@ static int log_dispatch(struct log_rec *rec, const char *fmt, va_list args)
if ((ldev->flags & LOGDF_ENABLE) &&
log_passes_filters(ldev, rec)) {
if (!rec->msg) {
- vsnprintf(buf, sizeof(buf), fmt, args);
+ int len;
+
+ len = vsnprintf(buf, sizeof(buf), fmt, args);
rec->msg = buf;
+ gd->log_cont = len && buf[len - 1] != '\n';
}
ldev->drv->emit(ldev, rec);
}
@@ -245,7 +248,11 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file,
rec.cat = cat;
rec.level = level & LOGL_LEVEL_MASK;
- rec.force_debug = level & LOGL_FORCE_DEBUG;
+ rec.flags = 0;
+ if (level & LOGL_FORCE_DEBUG)
+ rec.flags |= LOGRECF_FORCE_DEBUG;
+ if (gd->log_cont)
+ rec.flags |= LOGRECF_CONT;
rec.file = file;
rec.line = line;
rec.func = func;
@@ -255,7 +262,8 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file,
gd->log_drop_count++;
/* display dropped traces with console puts and DEBUG_UART */
- if (rec.level <= CONFIG_LOG_DEFAULT_LEVEL || rec.force_debug) {
+ if (rec.level <= CONFIG_LOG_DEFAULT_LEVEL ||
+ rec.flags & LOGRECF_FORCE_DEBUG) {
char buf[CONFIG_SYS_CBSIZE];
va_start(args, fmt);
diff --git a/common/log_console.c b/common/log_console.c
index 6abb13c93b..3f6177499e 100644
--- a/common/log_console.c
+++ b/common/log_console.c
@@ -15,6 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int log_console_emit(struct log_device *ldev, struct log_rec *rec)
{
int fmt = gd->log_fmt;
+ bool add_space = false;
/*
* The output format is designed to give someone a fighting chance of
@@ -26,18 +27,21 @@ static int log_console_emit(struct log_device *ldev, struct log_rec *rec)
* - function is an identifier and ends with ()
* - message has a space before it unless it is on its own
*/
- if (fmt & BIT(LOGF_LEVEL))
- printf("%s.", log_get_level_name(rec->level));
- if (fmt & BIT(LOGF_CAT))
- printf("%s,", log_get_cat_name(rec->cat));
- if (fmt & BIT(LOGF_FILE))
- printf("%s:", rec->file);
- if (fmt & BIT(LOGF_LINE))
- printf("%d-", rec->line);
- if (fmt & BIT(LOGF_FUNC))
- printf("%s()", rec->func);
+ if (!(rec->flags & LOGRECF_CONT) && fmt != BIT(LOGF_MSG)) {
+ add_space = true;
+ if (fmt & BIT(LOGF_LEVEL))
+ printf("%s.", log_get_level_name(rec->level));
+ if (fmt & BIT(LOGF_CAT))
+ printf("%s,", log_get_cat_name(rec->cat));
+ if (fmt & BIT(LOGF_FILE))
+ printf("%s:", rec->file);
+ if (fmt & BIT(LOGF_LINE))
+ printf("%d-", rec->line);
+ if (fmt & BIT(LOGF_FUNC))
+ printf("%s()", rec->func);
+ }
if (fmt & BIT(LOGF_MSG))
- printf("%s%s", fmt != BIT(LOGF_MSG) ? " " : "", rec->msg);
+ printf("%s%s", add_space ? " " : "", rec->msg);
return 0;
}
diff --git a/common/scp03.c b/common/scp03.c
new file mode 100644
index 0000000000..09ef7b5ba3
--- /dev/null
+++ b/common/scp03.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+
+#include <common.h>
+#include <scp03.h>
+#include <tee.h>
+#include <tee/optee_ta_scp03.h>
+
+static int scp03_enable(bool provision)
+{
+ const struct tee_optee_ta_uuid uuid = PTA_SCP03_UUID;
+ struct tee_open_session_arg session;
+ struct tee_invoke_arg invoke;
+ struct tee_param param;
+ struct udevice *tee = NULL;
+
+ tee = tee_find_device(tee, NULL, NULL, NULL);
+ if (!tee)
+ return -ENODEV;
+
+ memset(&session, 0, sizeof(session));
+ tee_optee_ta_uuid_to_octets(session.uuid, &uuid);
+ if (tee_open_session(tee, &session, 0, NULL))
+ return -ENXIO;
+
+ memset(&param, 0, sizeof(param));
+ param.attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
+ param.u.value.a = provision;
+
+ memset(&invoke, 0, sizeof(invoke));
+ invoke.func = PTA_CMD_ENABLE_SCP03;
+ invoke.session = session.session;
+
+ if (tee_invoke_func(tee, &invoke, 1, &param))
+ return -EIO;
+
+ tee_close_session(tee, session.session);
+
+ return 0;
+}
+
+int tee_enable_scp03(void)
+{
+ return scp03_enable(false);
+}
+
+int tee_provision_scp03(void)
+{
+ return scp03_enable(true);
+}
diff --git a/doc/arch/sandbox.rst b/doc/arch/sandbox.rst
index 1638b05000..8b18a22117 100644
--- a/doc/arch/sandbox.rst
+++ b/doc/arch/sandbox.rst
@@ -82,7 +82,7 @@ console::
You can issue commands as your would normally. If the command you want is
not supported you can add it to include/configs/sandbox.h.
-To exit, type 'reset' or press Ctrl-C.
+To exit, type 'poweroff' or press Ctrl-C.
Console / LCD support
diff --git a/doc/develop/logging.rst b/doc/develop/logging.rst
index 60c18c5b3a..f4e925048e 100644
--- a/doc/develop/logging.rst
+++ b/doc/develop/logging.rst
@@ -96,16 +96,45 @@ Also debug() and error() will generate log records - these use LOG_CATEGORY
as the category, so you should #define this right at the top of the source
file to ensure the category is correct.
+Generally each log format_string ends with a newline. If it does not, then the
+next log statement will have the LOGRECF_CONT flag set. This can be used to
+continue the statement on the same line as the previous one without emitting
+new header information (such as category/level). This behaviour is implemented
+with log_console. Here is an example that prints a list all on one line with
+the tags at the start:
+
+.. code-block:: c
+
+ log_debug("Here is a list:");
+ for (i = 0; i < count; i++)
+ log_debug(" item %d", i);
+ log_debug("\n");
+
+Also see the special category LOGL_CONT and level LOGC_CONT.
+
You can also define CONFIG_LOG_ERROR_RETURN to enable the log_ret() macro. This
can be used whenever your function returns an error value:
.. code-block:: c
- return log_ret(uclass_first_device(UCLASS_MMC, &dev));
+ return log_ret(uclass_first_device_err(UCLASS_MMC, &dev));
This will write a log record when an error code is detected (a value < 0). This
can make it easier to trace errors that are generated deep in the call stack.
+The log_msg_ret() variant will print a short string if CONFIG_LOG_ERROR_RETURN
+is enabled. So long as the string is unique within the function you can normally
+determine exactly which call failed:
+
+.. code-block:: c
+
+ ret = gpio_request_by_name(dev, "cd-gpios", 0, &desc, GPIOD_IS_IN);
+ if (ret)
+ return log_msg_ret("gpio", ret);
+
+Some functions return 0 for success and any other value is an error. For these,
+log_retz() and log_msg_retz() are available.
+
Convenience functions
~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index f7b706f916..7fac2e4f27 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -33,3 +33,4 @@ Shell commands
qfw
sbi
true
+ scp03
diff --git a/doc/usage/scp03.rst b/doc/usage/scp03.rst
new file mode 100644
index 0000000000..7ff87ed85a
--- /dev/null
+++ b/doc/usage/scp03.rst
@@ -0,0 +1,33 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+scp03 command
+=============
+
+Synopsis
+--------
+
+::
+
+ scp03 enable
+ scp03 provision
+
+Description
+-----------
+
+The *scp03* command calls into a Trusted Application executing in a
+Trusted Execution Environment to enable (if present) the Secure
+Channel Protocol 03 stablished between the processor and the secure
+element.
+
+This protocol encrypts all the communication between the processor and
+the secure element using a set of pre-defined keys. These keys can be
+rotated (provisioned) using the *provision* request.
+
+See also
+--------
+
+For some information on the internals implemented in the TEE, please
+check the GlobalPlatform documentation on `Secure Channel Protocol '03'`_
+
+.. _Secure Channel Protocol '03':
+ https://globalplatform.org/wp-content/uploads/2014/07/GPC_2.3_D_SCP03_v1.1.2_PublicRelease.pdf
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index 65622f30b1..d03028070b 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -31,6 +31,12 @@ config OPTEE_TA_RPC_TEST
permits to test reverse RPC calls to TEE supplicant. Should
be used only in sandbox env.
+config OPTEE_TA_SCP03
+ bool "Support SCP03 TA"
+ default y
+ help
+ Enables support for controlling (enabling, provisioning) the
+ Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA.
endmenu
endif
diff --git a/drivers/tee/sandbox.c b/drivers/tee/sandbox.c
index 3a1d34d6fc..35e8542fa3 100644
--- a/drivers/tee/sandbox.c
+++ b/drivers/tee/sandbox.c
@@ -8,6 +8,7 @@
#include <tee.h>
#include <tee/optee_ta_avb.h>
#include <tee/optee_ta_rpc_test.h>
+#include <tee/optee_ta_scp03.h>
#include "optee/optee_msg.h"
#include "optee/optee_private.h"
@@ -68,6 +69,7 @@ void *optee_alloc_and_init_page_list(void *buf, ulong len,
return NULL;
}
+#if defined(CONFIG_OPTEE_TA_SCP03) || defined(CONFIG_OPTEE_TA_AVB)
static u32 get_attr(uint n, uint num_params, struct tee_param *params)
{
if (n >= num_params)
@@ -79,7 +81,7 @@ static u32 get_attr(uint n, uint num_params, struct tee_param *params)
static u32 check_params(u8 p0, u8 p1, u8 p2, u8 p3, uint num_params,
struct tee_param *params)
{
- u8 p[] = { p0, p1, p2, p3};
+ u8 p[] = { p0, p1, p2, p3 };
uint n;
for (n = 0; n < ARRAY_SIZE(p); n++)
@@ -97,6 +99,50 @@ bad_params:
return TEE_ERROR_BAD_PARAMETERS;
}
+#endif
+
+#ifdef CONFIG_OPTEE_TA_SCP03
+static u32 pta_scp03_open_session(struct udevice *dev, uint num_params,
+ struct tee_param *params)
+{
+ /*
+ * We don't expect additional parameters when opening a session to
+ * this TA.
+ */
+ return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+}
+
+static u32 pta_scp03_invoke_func(struct udevice *dev, u32 func, uint num_params,
+ struct tee_param *params)
+{
+ u32 res;
+ static bool enabled;
+
+ switch (func) {
+ case PTA_CMD_ENABLE_SCP03:
+ res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ TEE_PARAM_ATTR_TYPE_NONE,
+ num_params, params);
+ if (res)
+ return res;
+
+ if (!enabled) {
+ enabled = true;
+ } else {
+ }
+
+ if (params[0].u.value.a)
+
+ return TEE_SUCCESS;
+ default:
+ return TEE_ERROR_NOT_SUPPORTED;
+ }
+}
+#endif
#ifdef CONFIG_OPTEE_TA_AVB
static u32 ta_avb_open_session(struct udevice *dev, uint num_params,
@@ -357,6 +403,12 @@ static const struct ta_entry ta_entries[] = {
.invoke_func = ta_rpc_test_invoke_func,
},
#endif
+#ifdef CONFIG_OPTEE_TA_SCP03
+ { .uuid = PTA_SCP03_UUID,
+ .open_session = pta_scp03_open_session,
+ .invoke_func = pta_scp03_invoke_func,
+ },
+#endif
};
static void sandbox_tee_get_version(struct udevice *dev,
diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index c74bacfd71..24c804a564 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -285,7 +285,7 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
length = get_unaligned_be32(sent);
sent += sizeof(length);
if (length != send_size) {
- printf("TPM2: Unmatching length, received: %ld, expected: %d\n",
+ printf("TPM2: Unmatching length, received: %zd, expected: %d\n",
send_size, length);
rc = TPM2_RC_SIZE;
sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index b6a9991fc9..c24f5e0e97 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -410,6 +410,12 @@ struct global_data {
* This value is used as logging level for continuation messages.
*/
int logl_prev;
+ /**
+ * @log_cont: Previous log line did not finished wtih \n
+ *
+ * This allows for chained log messages on the same line
+ */
+ bool log_cont;
#endif
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
diff --git a/include/log.h b/include/log.h
index 2d27f9f657..6ef891d4d2 100644
--- a/include/log.h
+++ b/include/log.h
@@ -316,12 +316,40 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line,
__ret); \
__ret; \
})
+
+/*
+ * Similar to the above, but any non-zero value is consider an error, not just
+ * values less than 0.
+ */
+#define log_retz(_ret) ({ \
+ int __ret = (_ret); \
+ if (__ret) \
+ log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \
+ __ret; \
+ })
+#define log_msg_retz(_msg, _ret) ({ \
+ int __ret = (_ret); \
+ if (__ret) \
+ log(LOG_CATEGORY, LOGL_ERR, "%s: returning err=%d\n", _msg, \
+ __ret); \
+ __ret; \
+ })
#else
/* Non-logging versions of the above which just return the error code */
#define log_ret(_ret) (_ret)
#define log_msg_ret(_msg, _ret) ((void)(_msg), _ret)
+#define log_retz(_ret) (_ret)
+#define log_msg_retz(_msg, _ret) ((void)(_msg), _ret)
#endif
+/** * enum log_rec_flags - Flags for a log record */
+enum log_rec_flags {
+ /** @LOGRECF_FORCE_DEBUG: Force output of debug record */
+ LOGRECF_FORCE_DEBUG = BIT(0),
+ /** @LOGRECF_CONT: Continuation of previous log record */
+ LOGRECF_CONT = BIT(1),
+};
+
/**
* struct log_rec - a single log record
*
@@ -337,18 +365,18 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line,
*
* @cat: Category, representing a uclass or part of U-Boot
* @level: Severity level, less severe is higher
- * @force_debug: Force output of debug
- * @file: Name of file where the log record was generated (not allocated)
* @line: Line number where the log record was generated
+ * @flags: Flags for log record (enum log_rec_flags)
+ * @file: Name of file where the log record was generated (not allocated)
* @func: Function where the log record was generated (not allocated)
* @msg: Log message (allocated)
*/
struct log_rec {
enum log_category_t cat;
enum log_level_t level;
- bool force_debug;
+ u16 line;
+ u8 flags;
const char *file;
- int line;
const char *func;
const char *msg;
};
diff --git a/include/scp03.h b/include/scp03.h
new file mode 100644
index 0000000000..729667ccd1
--- /dev/null
+++ b/include/scp03.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+
+#ifndef _SCP03_H
+#define _SCP03_H
+
+/*
+ * Requests to OPTEE to enable or provision the Secure Channel Protocol on its
+ * Secure Element
+ *
+ * If key provisioning is requested, OPTEE shall generate new SCP03 keys and
+ * write them to the Secure Element.
+ *
+ * Both functions return < 0 on error else 0.
+ */
+int tee_enable_scp03(void);
+int tee_provision_scp03(void);
+#endif /* _SCP03_H */
diff --git a/include/tee/optee_ta_scp03.h b/include/tee/optee_ta_scp03.h
new file mode 100644
index 0000000000..13f9956d98
--- /dev/null
+++ b/include/tee/optee_ta_scp03.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * (C) Copyright 2021, Foundries.IO
+ *
+ */
+#ifndef __TA_SCP03_H
+#define __TA_SCP03_H
+
+#define PTA_SCP03_UUID { 0xbe0e5821, 0xe718, 0x4f77, \
+ { 0xab, 0x3e, 0x8e, 0x6c, 0x73, 0xa9, 0xc7, 0x35 } }
+
+/*
+ * Enable Secure Channel Protocol functionality (SCP03) on the Secure Element.
+ * Setting the operation value to something different than NULL will trigger
+ * the SCP03 provisioning request.
+ *
+ * in params[0].a = operation
+ */
+#define PTA_CMD_ENABLE_SCP03 0
+
+#endif /*__TA_SCP03_H*/
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index 240187c523..2edab7be54 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -360,24 +360,24 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
run_command("acpi list", 0);
addr = (ulong)map_to_sysmem(buf);
ut_assert_nextline("ACPI tables start at %lx", addr);
- ut_assert_nextline("RSDP %08lx %06lx (v02 U-BOOT)", addr,
+ ut_assert_nextline("RSDP %08lx %06zx (v02 U-BOOT)", addr,
sizeof(struct acpi_rsdp));
addr = ALIGN(addr + sizeof(struct acpi_rsdp), 16);
- ut_assert_nextline("RSDT %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("RSDT %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_table_header) +
3 * sizeof(u32), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_rsdt), 16);
- ut_assert_nextline("XSDT %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("XSDT %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_table_header) +
3 * sizeof(u64), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_xsdt), 64);
- ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
- ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
- ut_assert_nextline("DMAR %08lx %06lx (v01 U-BOOT U-BOOTBL %x INTL 0)",
+ ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)",
addr, sizeof(struct acpi_dmar), U_BOOT_BUILD_DATE);
ut_assert_console_end();
diff --git a/test/log/cont_test.c b/test/log/cont_test.c
index 16379a74be..de7b7f064c 100644
--- a/test/log/cont_test.c
+++ b/test/log/cont_test.c
@@ -15,8 +15,6 @@
DECLARE_GLOBAL_DATA_PTR;
-#define BUFFSIZE 64
-
static int log_test_cont(struct unit_test_state *uts)
{
int log_fmt;
@@ -29,12 +27,13 @@ static int log_test_cont(struct unit_test_state *uts)
gd->log_fmt = (1 << LOGF_CAT) | (1 << LOGF_LEVEL) | (1 << LOGF_MSG);
gd->default_log_level = LOGL_INFO;
console_record_reset_enable();
- log(LOGC_ARCH, LOGL_ERR, "ea%d ", 1);
+ log(LOGC_ARCH, LOGL_ERR, "ea%d\n", 1);
log(LOGC_CONT, LOGL_CONT, "cc%d\n", 2);
gd->default_log_level = log_level;
gd->log_fmt = log_fmt;
gd->flags &= ~GD_FLG_RECORD;
- ut_assertok(ut_check_console_line(uts, "ERR.arch, ea1 ERR.arch, cc2"));
+ ut_assertok(ut_check_console_line(uts, "ERR.arch, ea1"));
+ ut_assertok(ut_check_console_line(uts, "ERR.arch, cc2"));
ut_assertok(ut_check_console_end(uts));
/* Write a third message which is not a continuation */
@@ -48,6 +47,18 @@ static int log_test_cont(struct unit_test_state *uts)
ut_assertok(ut_check_console_line(uts, "INFO.efi, ie3"));
ut_assertok(ut_check_console_end(uts));
+ /* Write two messages without a newline between them */
+ gd->log_fmt = (1 << LOGF_CAT) | (1 << LOGF_LEVEL) | (1 << LOGF_MSG);
+ gd->default_log_level = LOGL_INFO;
+ console_record_reset_enable();
+ log(LOGC_ARCH, LOGL_ERR, "ea%d ", 1);
+ log(LOGC_CONT, LOGL_CONT, "cc%d\n", 2);
+ gd->default_log_level = log_level;
+ gd->log_fmt = log_fmt;
+ gd->flags &= ~GD_FLG_RECORD;
+ ut_assertok(ut_check_console_line(uts, "ERR.arch, ea1 cc2"));
+ ut_assertok(ut_check_console_end(uts));
+
return 0;
}
LOG_TEST(log_test_cont);
diff --git a/test/py/tests/test_scp03.py b/test/py/tests/test_scp03.py
new file mode 100644
index 0000000000..1f689252dd
--- /dev/null
+++ b/test/py/tests/test_scp03.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2021 Foundries.io Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+# SCP03 command test
+
+"""
+This tests SCP03 command in U-boot.
+
+For additional details check doc/usage/scp03.rst
+"""
+
+import pytest
+import u_boot_utils as util
+
+@pytest.mark.buildconfigspec('cmd_scp03')
+def test_scp03(u_boot_console):
+ """Enable and provision keys with SCP03
+ """
+
+ success_str1 = "SCP03 is enabled"
+ success_str2 = "SCP03 is provisioned"
+
+ response = u_boot_console.run_command('scp03 enable')
+ assert success_str1 in response
+ response = u_boot_console.run_command('scp03 provision')
+ assert success_str2 in response