zephyr: migrate signature type to Kconfig

Handle the CONFIG_BOOT_SIGNATURE_TYPE_xxx values in Zephyr's
mcuboot_config.h by converting them into the platform-agnostic MCUboot
definitions.

This requires some changes to the way the release test Makefile is
structured, since Kconfig symbols cannot be set from the command line.

Instead, use the OVERLAY_CONFIG feature of the Zephyr build system,
which allows specifying extra fragments to merge into the final
.config. (This is an orthogonal mechanism to setting CONF_FILE; it is
used by Zephyr's CI script sanitycheck to add additional fragments, so
it's appropriate for use by MCUboot's testing scripts as well.)

We additionally need to move to a single prj.conf file due to a
dependency issue. We can no longer determine CONF_FILE from the
signature type, since that is now determined from the final .config or
autoconf.h, which is a build output that depends on CONF_FILE.

To move to a single prj.conf:

- delete prj-p256.conf and adjust prj.conf to serve both signature types
- add a top-level mbedTLS configuration file which dispatches to
  the right sub-header depending on the key type
- as a side effect, have the simulator pick the right config file
  depending on the case

This fixes and cleans up quite a bit of the signature type handling,
which had become something of a mess over time. For example, it fixes
a bug in ECDSA mode's configuration that wasn't actually selecting
config-asn1.h, and forces the simulator to use the same mbedTLS
configuration file as builds for real hardware.

Finally, we also have to move the mbedTLS vs. TinyCrypt choice into
mcuboot_config.h at the same time as well, since CMakeLists.txt was
making that decision based on the signature type.

Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt
index a45ca2f..2cc2aea 100644
--- a/boot/zephyr/CMakeLists.txt
+++ b/boot/zephyr/CMakeLists.txt
@@ -12,20 +12,6 @@
 # Configuration choices.
 ########################
 
-# Set CONF_SIGNATURE_TYPE to determine the signature type used.
-# Currently, it should be set to either RSA or ECDSA_P256.
-#
-# To choose RSA (this is the default):
-#
-#     cmake -DCONF_SIGNATURE_TYPE=RSA [...]
-#
-# To use ECDSA_P256:
-#
-#     cmake -DCONF_SIGNATURE_TYPE=ECDSA_P256 [...]
-if (NOT DEFINED CONF_SIGNATURE_TYPE)
-  set(CONF_SIGNATURE_TYPE RSA)
-endif()
-
 # If CONF_VALIDATE_SLOT0 is set, the bootloader attempts to validate
 # the signature of slot0 every boot.  This adds the signature check
 # time to every boot, but can mitigate against some changes that are
@@ -81,28 +67,15 @@
 
 set(MCUBOOT_EXTRA_CFLAGS)
 
-# Determine CFLAGS / MCUBOOT_CONF_FILE / NEED_TINYCRYPT from the signature type.
-if(CONF_SIGNATURE_TYPE STREQUAL RSA)
-  set(MCUBOOT_CONF_FILE prj.conf) # RSA
-  list(APPEND MCUBOOT_EXTRA_CFLAGS "-DMCUBOOT_SIGN_RSA" "-DMCUBOOT_USE_MBED_TLS")
-  set(NEED_TINYCRYPT NO)
-elseif(CONF_SIGNATURE_TYPE STREQUAL ECDSA_P256)
-  set(MCUBOOT_CONF_FILE prj-p256.conf) # ECDSA P-256
-  list(APPEND MCUBOOT_EXTRA_CFLAGS "-DMCUBOOT_SIGN_EC256" "-DMCUBOOT_USE_TINYCRYPT")
-  set(NEED_TINYCRYPT YES)
-else()
-  message(FATAL_ERROR "Invalid CONF_SIGNATURE_TYPE specified: '${CONF_SIGNATURE_TYPE}'")
-endif()
-
 # Board-specific CONF_FILES should get merged into the build as well.
 #
 # Do this by defining the set_conf_file macro:
 # http://docs.zephyrproject.org/application/application.html#application-configuration
 macro(set_conf_file)
   if (EXISTS ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf)
-    set(CONF_FILE "${MCUBOOT_CONF_FILE} ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf")
+    set(CONF_FILE "prj.conf ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf")
   else()
-    set(CONF_FILE "${MCUBOOT_CONF_FILE}")
+    set(CONF_FILE prj.conf)
   endif()
 endmacro()
 
@@ -177,15 +150,6 @@
 # Path to mbed-tls' asn1 parser library.
 set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls")
 
-# Zephyr application include directories.
-if (NOT NEED_TINYCRYPT)
-  # Zephyr's mbedTLS needs this.
-  zephyr_include_directories(include)
-
-  # Use full mbedtls provided by OS for RSA
-  target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/ext/lib/crypto/mbedtls/include)
-endif()
-
 target_include_directories(app PRIVATE include)
 target_include_directories(app PRIVATE targets)
 if(EXISTS "${APPLICATION_SOURCE_DIR}/targets/${BOARD}.h")
@@ -211,8 +175,8 @@
 target_sources(app PRIVATE "${BOOT_DIR}/bootutil/src/image_ec256.c")
 target_sources(app PRIVATE "${BOOT_DIR}/bootutil/src/caps.c")
 
-# Tinycrypt sources and includes, if needed.
-if (NEED_TINYCRYPT)
+if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256)
+  # When using ECDSA signatures, pull in our copy of the tinycrypt library.
   target_include_directories(app PRIVATE "${BOOT_DIR}/zephyr/include")
   target_include_directories(app PRIVATE "${TINYCRYPT_DIR}/include")
   target_include_directories(app PRIVATE "${MBEDTLS_ASN1_DIR}/include")
@@ -222,7 +186,14 @@
   target_sources(app PRIVATE "${TINYCRYPT_DIR}/source/sha256.c")
   target_sources(app PRIVATE "${TINYCRYPT_DIR}/source/utils.c")
 
+  # Additionally pull in just the ASN.1 parser from mbedTLS.
+  target_compile_definitions(app PRIVATE MBEDTLS_CFG_FILE=config-asn1.h)
   target_sources(app PRIVATE "${MBEDTLS_ASN1_DIR}/src/asn1parse.c")
+elseif(CONFIG_BOOT_SIGNATURE_TYPE_RSA)
+  # Use mbedTLS provided by Zephyr for RSA signatures. (Its config file
+  # is set using Kconfig.)
+  zephyr_include_directories(include)
+  target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/ext/lib/crypto/mbedtls/include)
 endif()
 
 if (CONFIG_MCUBOOT_SERIAL)
diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig
index e5f7358..14eba57 100644
--- a/boot/zephyr/Kconfig
+++ b/boot/zephyr/Kconfig
@@ -28,6 +28,7 @@
 config BOOT_SIGNATURE_TYPE_RSA
 	bool "RSA signatures"
 	select BOOT_USE_MBEDTLS
+	select MBEDTLS
 
 config BOOT_SIGNATURE_TYPE_ECDSA_P256
 	bool "Elliptic curve digital signatures with curve P-256"
@@ -35,6 +36,9 @@
 
 endchoice
 
+config MBEDTLS_CFG_FILE
+	default "mcuboot-mbedtls-cfg.h"
+
 config BOOT_VALIDATE_SLOT0
 	bool "Validate image slot 0 on every boot"
 	default y
diff --git a/boot/zephyr/include/config-boot.h b/boot/zephyr/include/config-rsa.h
similarity index 80%
rename from boot/zephyr/include/config-boot.h
rename to boot/zephyr/include/config-rsa.h
index 50bee10..3b5c1f5 100644
--- a/boot/zephyr/include/config-boot.h
+++ b/boot/zephyr/include/config-rsa.h
@@ -26,8 +26,8 @@
  * - RSA or ECDSA signature verification
  */
 
-#ifndef MBEDTLS_CONFIG_BOOT_H
-#define MBEDTLS_CONFIG_BOOT_H
+#ifndef MCUBOOT_MBEDTLS_CONFIG_RSA
+#define MCUBOOT_MBEDTLS_CONFIG_RSA
 
 #ifdef CONFIG_MCUBOOT_SERIAL
 /* Mcuboot uses mbedts-base64 for serial protocol encoding. */
@@ -56,20 +56,8 @@
 #define MBEDTLS_TEST_NULL_ENTROPY
 #endif
 
-/* mbed TLS feature support */
-#ifdef MCUBOOT_SIGN_EC
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
-#define MBEDTLS_ECP_NIST_OPTIM
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECDH_C
-#define MBEDTLS_ECP_C
-#endif
-
-#ifdef MCUBOOT_SIGN_RSA
 #define MBEDTLS_RSA_C
 #define MBEDTLS_PKCS1_V21
-#endif
 
 /* mbed TLS modules */
 #define MBEDTLS_ASN1_PARSE_C
@@ -80,13 +68,8 @@
 #define MBEDTLS_SHA256_C
 
 /* Save RAM by adjusting to our exact needs */
-#ifdef MCUBOOT_SIGN_RSA
 #define MBEDTLS_ECP_MAX_BITS             2048
 #define MBEDTLS_MPI_MAX_SIZE              256
-#else
-#define MBEDTLS_ECP_MAX_BITS             256
-#define MBEDTLS_MPI_MAX_SIZE              32 // 256 bits is 32 bytes
-#endif
 
 #define MBEDTLS_SSL_MAX_CONTENT_LEN 1024
 
@@ -95,4 +78,4 @@
 
 #include "mbedtls/check_config.h"
 
-#endif /* MBEDTLS_CONFIG_BOOT_H */
+#endif /* MCUBOOT_MBEDTLS_CONFIG_RSA */
diff --git a/boot/zephyr/include/mcuboot-mbedtls-cfg.h b/boot/zephyr/include/mcuboot-mbedtls-cfg.h
new file mode 100644
index 0000000..14cd9eb
--- /dev/null
+++ b/boot/zephyr/include/mcuboot-mbedtls-cfg.h
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (C) 2018 Open Source Foundries Limited
+ *  SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _MCUBOOT_MBEDTLS_CONFIG_
+#define _MCUBOOT_MBEDTLS_CONFIG_
+
+/**
+ * @file
+ *
+ * This is the top-level mbedTLS configuration file for MCUboot. The
+ * configuration depends on the signature type, so this file just
+ * pulls in the right header depending on that setting.
+ */
+
+/*
+ * IMPORTANT:
+ *
+ * If you put any "generic" definitions in here, make sure to update
+ * the simulator build.rs accordingly.
+ */
+
+#ifdef CONFIG_BOOT_SIGNATURE_TYPE_RSA
+#include "config-rsa.h"
+#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256)
+#include "config-asn1.h"
+#else
+#error "Cannot configure mbedTLS; signature type is unknown."
+#endif
+
+#endif
diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
index d7d141d..03d1e37 100644
--- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h
+++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h
@@ -18,9 +18,17 @@
  */
 #ifndef __BOOTSIM__
 
-/*
- * Initially blank.
- */
+#ifdef CONFIG_BOOT_SIGNATURE_TYPE_RSA
+#define MCUBOOT_SIGN_RSA
+#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256)
+#define MCUBOOT_SIGN_EC256
+#endif
+
+#ifdef CONFIG_BOOT_USE_MBEDTLS
+#define MCUBOOT_USE_MBED_TLS
+#elif defined(CONFIG_BOOT_USE_TINYCRYPT)
+#define MCUBOOT_USE_TINYCRYPT
+#endif
 
 #endif /* !__BOOTSIM__ */
 
diff --git a/boot/zephyr/keys.c b/boot/zephyr/keys.c
index 56b78df..467a0a1 100644
--- a/boot/zephyr/keys.c
+++ b/boot/zephyr/keys.c
@@ -19,7 +19,17 @@
 
 #include <bootutil/sign_key.h>
 
+/*
+ * Even though this is in principle a Zephyr-specific file, the
+ * simulator builds it and uses it as well. Because of that, we can't
+ * use Kconfig symbols for key types, and have to rely on the MCUBoot
+ * symbols (which Zephyr provides via this header, and the simulator
+ * provides via the compiler command line).
+ */
+#include <mcuboot_config/mcuboot_config.h>
+
 #if defined(MCUBOOT_SIGN_RSA)
+#define HAVE_KEYS
 const unsigned char root_pub_der[] = {
     0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd1, 0x06, 0x08,
     0x1a, 0x18, 0x44, 0x2c, 0x18, 0xe8, 0xfb, 0xfd, 0xf7, 0x0d, 0xa3, 0x4f,
@@ -47,6 +57,7 @@
 };
 const unsigned int root_pub_der_len = 270;
 #elif defined(MCUBOOT_SIGN_EC256)
+#define HAVE_KEYS
 const unsigned char root_pub_der[] = {
     0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
     0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
@@ -65,7 +76,7 @@
 #error "No public key available for given signing algorithm."
 #endif
 
-#if defined(MCUBOOT_SIGN_RSA) || defined(MCUBOOT_SIGN_EC256)
+#if defined(HAVE_KEYS)
 const struct bootutil_key bootutil_keys[] = {
     {
         .key = root_pub_der,
diff --git a/boot/zephyr/os.c b/boot/zephyr/os.c
index deb9dce..dd0d7e4 100644
--- a/boot/zephyr/os.c
+++ b/boot/zephyr/os.c
@@ -22,7 +22,7 @@
 
 #include "os/os_heap.h"
 
-#ifdef MCUBOOT_USE_MBED_TLS
+#ifdef CONFIG_BOOT_USE_MBEDTLS
 
 #include <mbedtls/platform.h>
 #include <mbedtls/memory_buffer_alloc.h>
diff --git a/boot/zephyr/prj-p256.conf b/boot/zephyr/prj-p256.conf
deleted file mode 100644
index 71b52f3..0000000
--- a/boot/zephyr/prj-p256.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-CONFIG_CONSOLE_HANDLER=y
-CONFIG_SYS_LOG=y
-CONFIG_DEBUG=y
-CONFIG_SYSTEM_CLOCK_DISABLE=y
-
-CONFIG_MAIN_STACK_SIZE=10240
-MCUBOOT_MBEDTLS_CFG_FILE="config-asn1.h"
-# CONFIG_TINYCRYPT is not set
-# CONFIG_TINYCRYPT_ECC_DSA is not set
-# CONFIG_TINYCRYPT_SHA256 is not set
-
-### mbedTLS has its own heap
-# CONFIG_HEAP_MEM_POOL_SIZE is not set
-
-CONFIG_FLASH=y
-CONFIG_MPU_ALLOW_FLASH_WRITE=y
-
-### Disable Bluetooth by default
-# CONFIG_BT is not set
-
-CONFIG_MULTITHREADING=n
diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf
index c60c590..50c721f 100644
--- a/boot/zephyr/prj.conf
+++ b/boot/zephyr/prj.conf
@@ -4,13 +4,17 @@
 CONFIG_SYSTEM_CLOCK_DISABLE=y
 
 CONFIG_MAIN_STACK_SIZE=10240
-CONFIG_MBEDTLS=y
-CONFIG_MBEDTLS_BUILTIN=y
-CONFIG_MBEDTLS_CFG_FILE="config-boot.h"
+CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h"
 
 ### mbedTLS has its own heap
 # CONFIG_HEAP_MEM_POOL_SIZE is not set
 
+### We never want Zephyr's copy of tinycrypt.  If tinycrypt is needed,
+### MCUboot has its own copy in tree.
+# CONFIG_TINYCRYPT is not set
+# CONFIG_TINYCRYPT_ECC_DSA is not set
+# CONFIG_TINYCRYPT_SHA256 is not set
+
 CONFIG_FLASH=y
 CONFIG_MPU_ALLOW_FLASH_WRITE=y