[PATCH 00/16] wolfssl SSL impl, PKCS#11 AES, AES key len

158 views
Skip to first unread message

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:36 AM9/16/20
to swup...@googlegroups.com, Bastian Germann
From: Bastian Germann <ba...@linutronix.de>

Hi,

This series consists of three parts. Any of the three parts could also be
imported to SWUpdate without the others.

The first 7 commits add wolfSSL as an alternative SSL/crypto implementation.
This can only be used with the OpenSSL compatibility layer built in. The CMS
image verification cannot be used with any wolfSSL version but may be added
later. It is blocked from being used if wolfSSL is enabled.

The following commits add a new feature to use PKCS#11 support for the
AES image decryption. This needs a wolfSSL build with PKCS#11 support enabled
which is not in the default build up to the current version.
As I like to use this along with CMS, I made the PKCS#11 implementation work
with any of the SSL implementations, not only wolfSSL.

A PKCS#11-using application is encouraged to address any key material via a
RFC7512 URI. p11-kit is used as a parser. If you prefer a more lightweight
solution (Using ordered, space separated fields or implementing a simple
parser) then I am happy to send a follow-up series with that change.

I tested the implementation with wolfSSL 4.4.0 and 4.5.0 along with softhsm2.
To import a key, use softhsm2-util with the --aes parameter.
Using GnuTLS's p11tool for the import will not work.

The last five commits implement other AES key lengths additionally to AES256.

Bastian Germann (16):
Kbuild: Add wolfSSL as SSL implementation
Rename wolfSSL incompatible definition
sslapi: Move CMS-only functions to conditional
sslapi: Add X509 related wolfSSL definitions
Makefile.flags: Add missing wolfSSL definitions
mongoose: Hide deprecated function for wolfSSL
sslapi: Add wolfSSL compatibility macro
pkcs11: Implement based on wolfSSL and p11-kit
Kbuild: Add PKCS11 option
pkcs11: Differentiate key handling based on config
doc: Add note on the PKCS#11 libraries
doc: encrypted images: Add a PKCS#11 section
encrypted images: Accept other AES key lengths
encrypted images: Implement other key lengths in providers
doc: encrypted images: Using different key lenghts
encrypted images: Test other key lengths

Kconfig | 37 ++++--
Makefile.deps | 8 ++
Makefile.flags | 12 ++
core/cpio_utils.c | 4 +-
core/network_thread.c | 2 +
core/util.c | 44 ++++++-
corelib/Makefile | 13 +-
corelib/swupdate_decrypt.c | 17 ++-
corelib/swupdate_decrypt_mbedtls.c | 25 +++-
corelib/swupdate_decrypt_pkcs11.c | 184 +++++++++++++++++++++++++++++
doc/source/encrypted_images.rst | 14 ++-
doc/source/swupdate.rst | 7 +-
handlers/ubivol_handler.c | 4 +-
include/sslapi.h | 80 +++++++++----
include/util.h | 6 +-
mongoose/Config.in | 4 +-
mongoose/Makefile | 2 +-
mongoose/mongoose.c | 2 +-
suricatta/Config.in | 4 +-
test/Makefile | 2 +
test/test_crypt.c | 46 ++++++--
21 files changed, 444 insertions(+), 73 deletions(-)
create mode 100644 corelib/swupdate_decrypt_pkcs11.c

--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:36 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

wolfSSL has an OpenSSL compatibility layer which lacks CMS support
as of version 4.5.0. All other code can be built with wolfSSL.
Add it as a new SSL implementation.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
Kconfig | 24 ++++++++++++++++--------
Makefile.deps | 4 ++++
Makefile.flags | 5 +++++
corelib/Makefile | 5 ++++-
include/sslapi.h | 2 +-
mongoose/Config.in | 4 ++--
mongoose/Makefile | 2 +-
suricatta/Config.in | 4 ++--
8 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/Kconfig b/Kconfig
index 444eb1f..2d2cca6 100644
--- a/Kconfig
+++ b/Kconfig
@@ -77,6 +77,10 @@ config HAVE_LIBCRYPTO
bool
option env="HAVE_LIBCRYPTO"

+config HAVE_WOLFSSL
+ bool
+ option env="HAVE_WOLFSSL"
+
config HAVE_MBEDTLS
bool
option env="HAVE_MBEDTLS"
@@ -347,6 +351,10 @@ choice
bool "OpenSSL"
depends on HAVE_LIBSSL

+ config SSL_IMPL_WOLFSSL
+ bool "wolfSSL (with OpenSSL compatibility layer)"
+ depends on HAVE_WOLFSSL
+
config SSL_IMPL_MBEDTLS
bool "mbedTLS"
depends on HAVE_MBEDTLS
@@ -369,7 +377,7 @@ config DOWNLOAD_SSL
bool "Enable SSL support for image downloading"
default n
depends on DOWNLOAD
- depends on SSL_IMPL_OPENSSL || SSL_IMPL_MBEDTLS
+ depends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS
select CHANNEL_CURL_SSL
help
Enable SSL and checksum verification support in channels
@@ -383,18 +391,18 @@ config CHANNEL_CURL
config CHANNEL_CURL_SSL
bool
depends on CHANNEL_CURL
- depends on SSL_IMPL_OPENSSL || SSL_IMPL_MBEDTLS
+ depends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS
select CURL_SSL

config HASH_VERIFY
bool "Allow to add sha256 hash to each image"
- depends on SSL_IMPL_OPENSSL || SSL_IMPL_MBEDTLS
+ depends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS
help
Allow to add a sha256 hash to an artifact.
This is automatically set in case of Signed Image

comment "Hash checking needs an SSL implementation"
- depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_MBEDTLS
+ depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_WOLFSSL && !SSL_IMPL_MBEDTLS

config DISABLE_CPIO_CRC
bool "Disable cpio CRC verify if SHA 256 is enabled"
@@ -410,10 +418,10 @@ config DISABLE_CPIO_CRC

config SIGNED_IMAGES
bool "Enable verification of signed images"
- depends on SSL_IMPL_OPENSSL || SSL_IMPL_MBEDTLS
+ depends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS
select HASH_VERIFY
comment "Image signature verification needs an SSL implementation"
- depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_MBEDTLS
+ depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_WOLFSSL && !SSL_IMPL_MBEDTLS

choice
prompt "Signature verification algorithm"
@@ -450,9 +458,9 @@ endmenu

config ENCRYPTED_IMAGES
bool "Images can be encrypted with a symmetric key"
- depends on SSL_IMPL_OPENSSL || SSL_IMPL_MBEDTLS
+ depends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS
comment "Image encryption needs an SSL implementation"
- depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_MBEDTLS
+ depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_WOLFSSL && !SSL_IMPL_MBEDTLS

source suricatta/Config.in

diff --git a/Makefile.deps b/Makefile.deps
index b90ca0d..0949628 100644
--- a/Makefile.deps
+++ b/Makefile.deps
@@ -62,6 +62,10 @@ ifeq ($(HAVE_LIBCRYPTO),)
export HAVE_LIBCRYPTO = y
endif

+ifeq ($(HAVE_WOLFSSL),)
+export HAVE_WOLFSSL = y
+endif
+
ifeq ($(HAVE_MBEDTLS),)
export HAVE_MBEDTLS = y
endif
diff --git a/Makefile.flags b/Makefile.flags
index dfd7531..a5d3b0e 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -149,6 +149,11 @@ ifeq ($(CONFIG_SSL_IMPL_OPENSSL),y)
LDLIBS += crypto ssl
endif

+ifeq ($(CONFIG_SSL_IMPL_WOLFSSL),y)
+KBUILD_CPPFLAGS += -I/usr/include/wolfssl
+LDLIBS += wolfssl
+endif
+
ifeq ($(CONFIG_SSL_IMPL_MBEDTLS),y)
LDLIBS += mbedcrypto mbedtls mbedx509
endif
diff --git a/corelib/Makefile b/corelib/Makefile
index f4dca4c..8a9fea0 100644
--- a/corelib/Makefile
+++ b/corelib/Makefile
@@ -5,11 +5,14 @@
lib-$(CONFIG_DOWNLOAD) += downloader.o
lib-$(CONFIG_MTD) += mtd-interface.o
lib-$(CONFIG_LUA) += lua_interface.o lua_compat.o
-ifeq ($(CONFIG_SSL_IMPL_OPENSSL),y)
+ifeq ($(CONFIG_SSL_IMPL_OPENSSL)$(CONFIG_SSL_IMPL_WOLFSSL),y)
lib-$(CONFIG_HASH_VERIFY) += verify_signature.o
lib-$(CONFIG_ENCRYPTED_IMAGES) += swupdate_decrypt.o
lib-$(CONFIG_SIGALG_RAWRSA) += swupdate_rsa_verify.o
lib-$(CONFIG_SIGALG_RSAPSS) += swupdate_rsa_verify.o
+endif
+ifeq ($(CONFIG_SSL_IMPL_OPENSSL),y)
+# wolfSSL does not support CMS in the compatibility layer yet
lib-$(CONFIG_SIGALG_CMS) += swupdate_cms_verify.o
endif
ifeq ($(CONFIG_SSL_IMPL_MBEDTLS),y)
diff --git a/include/sslapi.h b/include/sslapi.h
index 12591a3..5336920 100644
--- a/include/sslapi.h
+++ b/include/sslapi.h
@@ -18,7 +18,7 @@
*/
#if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_ENCRYPTED_IMAGES) || \
defined(CONFIG_CHANNEL_CURL_SSL)
-#if defined(CONFIG_SSL_IMPL_OPENSSL)
+#if defined(CONFIG_SSL_IMPL_OPENSSL) || defined(CONFIG_SSL_IMPL_WOLFSSL)
#include <openssl/bio.h>
#include <openssl/objects.h>
#include <openssl/err.h>
diff --git a/mongoose/Config.in b/mongoose/Config.in
index e315eb2..e0944fd 100644
--- a/mongoose/Config.in
+++ b/mongoose/Config.in
@@ -28,11 +28,11 @@ config MONGOOSEIPV6
config MONGOOSESSL
bool "SSL support"
depends on MONGOOSE
- depends on SSL_IMPL_OPENSSL || SSL_IMPL_MBEDTLS
+ depends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS
help
It enables SSL support into mongoose

comment "SSL support needs an SSL implementation"
- depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_MBEDTLS
+ depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_WOLFSSL && !SSL_IMPL_MBEDTLS

endif
diff --git a/mongoose/Makefile b/mongoose/Makefile
index 59bf508..851a476 100644
--- a/mongoose/Makefile
+++ b/mongoose/Makefile
@@ -7,7 +7,7 @@ KBUILD_CFLAGS += -DMG_ENABLE_IPV6=1
endif
ifneq ($(CONFIG_MONGOOSESSL),)
KBUILD_CFLAGS += -DMG_ENABLE_SSL=1
-ifeq ($(CONFIG_SSL_IMPL_OPENSSL),y)
+ifeq ($(CONFIG_SSL_IMPL_OPENSSL)$(CONFIG_SSL_IMPL_WOLFSSL),y)
KBUILD_CFLAGS += -DMG_SSL_IF=MG_SSL_IF_OPENSSL
endif
ifeq ($(CONFIG_SSL_IMPL_MBEDTLS),y)
diff --git a/suricatta/Config.in b/suricatta/Config.in
index 8ae27e2..1e340ec 100644
--- a/suricatta/Config.in
+++ b/suricatta/Config.in
@@ -21,13 +21,13 @@ menu "Features"
config SURICATTA_SSL
bool "SSL support"
default n
- depends on SSL_IMPL_OPENSSL || SSL_IMPL_MBEDTLS
+ depends on SSL_IMPL_OPENSSL || SSL_IMPL_WOLFSSL || SSL_IMPL_MBEDTLS
select CHANNEL_CURL_SSL
help
Enable SSL and checksum verification support in suricatta.

comment "SSL support needs an SSL implementation"
- depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_MBEDTLS
+ depends on !SSL_IMPL_OPENSSL && !SSL_IMPL_WOLFSSL && !SSL_IMPL_MBEDTLS


endmenu
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:38 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

The section explains which option to enable and how to set the PKCS#11 URI.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Acked-by: Torben Hohn <torbe...@linutronix.de>
---
doc/source/encrypted_images.rst | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/doc/source/encrypted_images.rst b/doc/source/encrypted_images.rst
index e71cdd8..822012d 100644
--- a/doc/source/encrypted_images.rst
+++ b/doc/source/encrypted_images.rst
@@ -109,3 +109,14 @@ Running SWUpdate with Encrypted Images
Symmetric encryption support is activated by setting the ``ENCRYPTED_IMAGES``
option in SWUpdate's configuration. Use the `-K` parameter to provide the
symmetric key file generated above to SWUpdate.
+
+Decrypting with a PKCS#11 token
+-------------------------------
+
+PKCS#11 support is activated by setting the ``PKCS11`` option in SWUpdate's
+configuration. The key file has to have a PKCS#11 URL instead of the key then,
+containing at least the elements of this example:
+
+::
+
+ pkcs11:slot-id=42;id=%CA%FE%BA%BE?pin-value=1234&module-path=/usr/lib/libsofthsm2.so 65D793B87B6724BB27954C7664F15FF3
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:38 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

Some X509 definitions are not in the OpenSSL compatibility layer,
so add their native names.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
include/sslapi.h | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/include/sslapi.h b/include/sslapi.h
index 14e4397..74bd424 100644
--- a/include/sslapi.h
+++ b/include/sslapi.h
@@ -57,8 +57,13 @@ static inline uint32_t SSL_X509_get_extended_key_usage(X509 *x)
#endif
#endif /* CONFIG_SIGALG_CMS */

+#ifdef CONFIG_SSL_IMPL_WOLFSSL
+#define X509_PURPOSE_CODE_SIGN EXTKEYUSE_CODESIGN
+#define SSL_PURPOSE_EMAIL_PROT EXTKEYUSE_EMAILPROT
+#else
#define X509_PURPOSE_CODE_SIGN (X509_PURPOSE_MAX + 1)
#define SSL_PURPOSE_EMAIL_PROT X509_PURPOSE_SMIME_SIGN
+#endif
#define SSL_PURPOSE_CODE_SIGN X509_PURPOSE_CODE_SIGN
#define SSL_PURPOSE_DEFAULT SSL_PURPOSE_EMAIL_PROT

--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:38 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

The SSL_X509_get_exten* functions are only used by the CMS implementation.
Move them to the CMS conditional area to be compatible with wolfSSL.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
include/sslapi.h | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/include/sslapi.h b/include/sslapi.h
index dbdffa0..14e4397 100644
--- a/include/sslapi.h
+++ b/include/sslapi.h
@@ -28,16 +28,34 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/aes.h>
+#include <openssl/opensslv.h>

#ifdef CONFIG_SIGALG_CMS
#if defined(LIBRESSL_VERSION_NUMBER)
#error "LibreSSL does not support CMS, please select RSA PKCS"
#else
#include <openssl/cms.h>
+
+static inline uint32_t SSL_X509_get_extension_flags(X509 *x)
+{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ return x->ex_flags;
+#else
+ return X509_get_extension_flags(x);
#endif
+}
+
+static inline uint32_t SSL_X509_get_extended_key_usage(X509 *x)
+{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ return x->ex_xkusage;
+#else
+ return X509_get_extended_key_usage(x);
#endif
+}

-#include <openssl/opensslv.h>
+#endif
+#endif /* CONFIG_SIGALG_CMS */

#define X509_PURPOSE_CODE_SIGN (X509_PURPOSE_MAX + 1)
#define SSL_PURPOSE_EMAIL_PROT X509_PURPOSE_SMIME_SIGN
@@ -79,24 +97,6 @@ struct swupdate_digest {
#define swupdate_crypto_init()
#endif

-static inline uint32_t SSL_X509_get_extension_flags(X509 *x)
-{
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
- return x->ex_flags;
-#else
- return X509_get_extension_flags(x);
-#endif
-}
-
-static inline uint32_t SSL_X509_get_extended_key_usage(X509 *x)
-{
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
- return x->ex_xkusage;
-#else
- return X509_get_extended_key_usage(x);
-#endif
-}
-
#elif defined(CONFIG_SSL_IMPL_MBEDTLS)
#include <mbedtls/md.h>
#include <mbedtls/pk.h>
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:39 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

Accept AES128 and AES192 keys in addition to AES256.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
core/util.c | 29 ++++++++++++++++++++++++-----
include/util.h | 4 ++++
2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/core/util.c b/core/util.c
index d0db48a..7c0d417 100644
--- a/core/util.c
+++ b/core/util.c
@@ -29,16 +29,18 @@
#include "generated/autoconf.h"

/*
- * key is 256 bit for aes_256
- * ivt is 128 bit
+ * key is 256 bit for max aes_256
+ * keylen is the actual aes key length
+ * ivt is 128 bit
*/
struct decryption_key {
#ifdef CONFIG_PKCS11
char * key;
#else
- unsigned char key[32];
+ unsigned char key[AES_256_KEY_LEN];
#endif
- unsigned char ivt[16];
+ char keylen;
+ unsigned char ivt[AES_BLK_SIZE];
};

static struct decryption_key *aes_key = NULL;
@@ -560,6 +562,12 @@ unsigned char *get_aes_key(void) {
return aes_key->key;
}

+char get_aes_keylen(void) {
+ if (!aes_key)
+ return -1;
+ return aes_key->keylen;
+}
+
unsigned char *get_aes_ivt(void) {
if (!aes_key)
return NULL;
@@ -588,7 +596,18 @@ int set_aes_key(const char *key, const char *ivt)
return -ENOMEM;
strncpy(aes_key->key, key, keylen);
#else
- ret |= ascii_to_bin(aes_key->key, sizeof(aes_key->key), key);
+ keylen = strlen(key);
+ switch (keylen) {
+ case AES_128_KEY_LEN * 2:
+ case AES_192_KEY_LEN * 2:
+ case AES_256_KEY_LEN * 2:
+ // valid hex string size for AES 128/192/256
+ aes_key->keylen = keylen / 2;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ret |= ascii_to_bin(aes_key->key, aes_key->keylen, key);
#endif

if (ret) {
diff --git a/include/util.h b/include/util.h
index d77025d..bf8d8a0 100644
--- a/include/util.h
+++ b/include/util.h
@@ -24,6 +24,9 @@

#define SWUPDATE_SHA_DIGEST_LENGTH 20
#define AES_BLK_SIZE 16
+#define AES_128_KEY_LEN 16
+#define AES_192_KEY_LEN 24
+#define AES_256_KEY_LEN 32

#define HWID_REGEXP_PREFIX "#RE:"
#define SWUPDATE_ALIGN(A,S) (((A) + (S) - 1) & ~((S) - 1))
@@ -227,6 +230,7 @@ void free_string_array(char **nodes);
/* Decryption key functions */
int load_decryption_key(char *fname);
unsigned char *get_aes_key(void);
+char get_aes_keylen(void);
unsigned char *get_aes_ivt(void);
int set_aes_key(const char *key, const char *ivt);
int set_aes_ivt(const char *ivt);
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:39 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

Each SSL implementation used to have only AES256 support.
Implement AES128 and AES192 for all SSL implementations with all key sizes
possible at runtime.

The PKCS#11 operations are bound to the stored key size anyway.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
core/cpio_utils.c | 2 +-
corelib/swupdate_decrypt.c | 17 +++++++++++++++--
corelib/swupdate_decrypt_mbedtls.c | 25 ++++++++++++++++++++++---
corelib/swupdate_decrypt_pkcs11.c | 3 ++-
include/sslapi.h | 4 ++--
test/test_crypt.c | 4 ++--
6 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/core/cpio_utils.c b/core/cpio_utils.c
index f9f5bbe..465a473 100644
--- a/core/cpio_utils.c
+++ b/core/cpio_utils.c
@@ -453,7 +453,7 @@ int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs, unsi
ivt = ivtbuf;
} else
ivt = get_aes_ivt();
- decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, ivt);
+ decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, get_aes_keylen(), ivt);
if (!decrypt_state.dcrypt) {
ERROR("decrypt initialization failure, aborting");
ret = -EFAULT;
diff --git a/corelib/swupdate_decrypt.c b/corelib/swupdate_decrypt.c
index f14ca9c..2d1fedb 100644
--- a/corelib/swupdate_decrypt.c
+++ b/corelib/swupdate_decrypt.c
@@ -17,9 +17,10 @@
#include "sslapi.h"
#include "util.h"

-struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char *iv)
+struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv)
{
struct swupdate_digest *dgst;
+ const EVP_CIPHER *cipher;
int ret;

if ((key == NULL) || (iv == NULL)) {
@@ -27,7 +28,19 @@ struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char
return NULL;
}

- const EVP_CIPHER *cipher = EVP_aes_256_cbc();
+ switch (keylen) {
+ case AES_128_KEY_LEN:
+ cipher = EVP_aes_128_cbc();
+ break;
+ case AES_192_KEY_LEN:
+ cipher = EVP_aes_192_cbc();
+ break;
+ case AES_256_KEY_LEN:
+ cipher = EVP_aes_256_cbc();
+ break;
+ default:
+ return NULL;
+ }

dgst = calloc(1, sizeof(*dgst));
if (!dgst) {
diff --git a/corelib/swupdate_decrypt_mbedtls.c b/corelib/swupdate_decrypt_mbedtls.c
index c970b9b..c282cb5 100644
--- a/corelib/swupdate_decrypt_mbedtls.c
+++ b/corelib/swupdate_decrypt_mbedtls.c
@@ -3,10 +3,12 @@
#include "sslapi.h"
#include "util.h"

-struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char *iv)
+struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv)
{
struct swupdate_digest *dgst;
+ mbedtls_cipher_type_t cipher_type;
const mbedtls_cipher_info_t *cipher_info;
+ int key_bitlen;
int error;

if ((key == NULL) || (iv == NULL)) {
@@ -14,7 +16,24 @@ struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char
return NULL;
}

- cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CBC);
+ switch (keylen) {
+ case AES_128_KEY_LEN:
+ cipher_type = MBEDTLS_CIPHER_AES_128_CBC;
+ key_bitlen = 128;
+ break;
+ case AES_192_KEY_LEN:
+ cipher_type = MBEDTLS_CIPHER_AES_192_CBC;
+ key_bitlen = 192;
+ break;
+ case AES_256_KEY_LEN:
+ cipher_type = MBEDTLS_CIPHER_AES_256_CBC;
+ key_bitlen = 256;
+ break;
+ default:
+ return NULL;
+ }
+
+ cipher_info = mbedtls_cipher_info_from_type(cipher_type);
if (!cipher_info) {
ERROR("mbedtls_cipher_info_from_type");
return NULL;
@@ -33,7 +52,7 @@ struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char
goto fail;
}

- error = mbedtls_cipher_setkey(&dgst->mbedtls_cipher_context, key, 256, MBEDTLS_DECRYPT);
+ error = mbedtls_cipher_setkey(&dgst->mbedtls_cipher_context, key, key_bitlen, MBEDTLS_DECRYPT);
if (error) {
ERROR("mbedtls_cipher_setkey: %d", error);
goto fail;
diff --git a/corelib/swupdate_decrypt_pkcs11.c b/corelib/swupdate_decrypt_pkcs11.c
index 1ca0a93..203eea6 100644
--- a/corelib/swupdate_decrypt_pkcs11.c
+++ b/corelib/swupdate_decrypt_pkcs11.c
@@ -22,7 +22,8 @@ static void wolfssl_debug(int __attribute__ ((__unused__)) level, const char *co
}
#endif

-struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *uri, unsigned char *iv)
+struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *uri,
+ char __attribute__ ((__unused__)) keylen, unsigned char *iv)
{
struct swupdate_digest *dgst;
const char *library;
diff --git a/include/sslapi.h b/include/sslapi.h
index 5a3236a..9a6af4f 100644
--- a/include/sslapi.h
+++ b/include/sslapi.h
@@ -179,7 +179,7 @@ int swupdate_HASH_compare(const unsigned char *hash1, const unsigned char *hash2
#endif

#ifdef CONFIG_ENCRYPTED_IMAGES
-struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, unsigned char *iv);
+struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv);
int swupdate_DECRYPT_update(struct swupdate_digest *dgst, unsigned char *buf,
int *outlen, const unsigned char *cryptbuf, int inlen);
int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf,
@@ -190,7 +190,7 @@ void swupdate_DECRYPT_cleanup(struct swupdate_digest *dgst);
* Note: macro for swupdate_DECRYPT_init is
* just to avoid compiler warnings
*/
-#define swupdate_DECRYPT_init(key, iv) (((key != NULL) | (ivt != NULL)) ? NULL : NULL)
+#define swupdate_DECRYPT_init(key, keylen, iv) (((key != NULL) | (ivt != NULL)) ? NULL : NULL)
#define swupdate_DECRYPT_update(p, buf, len, cbuf, inlen) (-1)
#define swupdate_DECRYPT_final(p, buf, len) (-1)
#define swupdate_DECRYPT_cleanup(p)
diff --git a/test/test_crypt.c b/test/test_crypt.c
index 2481d69..4a28874 100644
--- a/test/test_crypt.c
+++ b/test/test_crypt.c
@@ -43,7 +43,7 @@ static void hex2bin(unsigned char *dest, const unsigned char *source)
static void do_crypt(struct cryptdata *crypt, unsigned char *CRYPTTEXT, unsigned char *PLAINTEXT)
{
int len;
- void *dcrypt = swupdate_DECRYPT_init(crypt->key, crypt->iv);
+ void *dcrypt = swupdate_DECRYPT_init(crypt->key, 32, crypt->iv);
assert_non_null(dcrypt);

unsigned char *buffer = calloc(1, strlen((const char *)CRYPTTEXT) + EVP_MAX_BLOCK_LENGTH);
@@ -114,7 +114,7 @@ static void test_crypt_failure(void **state)
hex2bin((crypt.crypttext = calloc(1, strlen((const char *)CRYPTTEXT))), CRYPTTEXT);

int len;
- void *dcrypt = swupdate_DECRYPT_init(crypt.key, crypt.iv);
+ void *dcrypt = swupdate_DECRYPT_init(crypt.key, 32, crypt.iv);
assert_non_null(dcrypt);

unsigned char *buffer = calloc(1, strlen((const char *)CRYPTTEXT) + EVP_MAX_BLOCK_LENGTH);
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:39 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
doc/source/encrypted_images.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/doc/source/encrypted_images.rst b/doc/source/encrypted_images.rst
index 822012d..b155590 100644
--- a/doc/source/encrypted_images.rst
+++ b/doc/source/encrypted_images.rst
@@ -2,7 +2,8 @@ Symmetrically Encrypted Update Images
=====================================

SWUpdate allows one to symmetrically encrypt update images using the
-256 bit AES block cipher in CBC mode.
+AES block cipher in CBC mode. The following shows encryption with 256
+bit key length but you may use other key lengths as well.


Building an Encrypted SWU Image
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:40 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

Rework the test_crypt to test each AES key length.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
test/test_crypt.c | 44 +++++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/test/test_crypt.c b/test/test_crypt.c
index 4a28874..7d82bc5 100644
--- a/test/test_crypt.c
+++ b/test/test_crypt.c
@@ -40,10 +40,10 @@ static void hex2bin(unsigned char *dest, const unsigned char *source)
}
}

-static void do_crypt(struct cryptdata *crypt, unsigned char *CRYPTTEXT, unsigned char *PLAINTEXT)
+static void do_crypt(struct cryptdata *crypt, char keylen, unsigned char *CRYPTTEXT, unsigned char *PLAINTEXT)
{
int len;
- void *dcrypt = swupdate_DECRYPT_init(crypt->key, 32, crypt->iv);
+ void *dcrypt = swupdate_DECRYPT_init(crypt->key, keylen, crypt->iv);
assert_non_null(dcrypt);

unsigned char *buffer = calloc(1, strlen((const char *)CRYPTTEXT) + EVP_MAX_BLOCK_LENGTH);
@@ -58,13 +58,34 @@ static void do_crypt(struct cryptdata *crypt, unsigned char *CRYPTTEXT, unsigned
free(buffer);
}

-static void test_crypt_1(void **state)
+static void test_crypt_128(void **state)
{
(void)state;

- unsigned char KEY[] = "E5E9FA1BA31ECD1AE84F75CAAA474F3A663F05F412028F81DA65D26EE56424B2";
+ unsigned char KEY[] = "E5E9FA1BA31ECD1AE84F75CAAA474FB2";
unsigned char IV[] = "E93DA465B309C53FEC5FF93C9637DA58";
- unsigned char CRYPTTEXT[] = "E4B7745CA14039555CECD548BB33E0C3";
+ unsigned char CRYPTTEXT[] = "a68148be39f9c60175ccc31c19ab92e7";
+ unsigned char PLAINTEXT[] = "CRYPTTEST";
+
+ struct cryptdata crypt;
+ hex2bin((crypt.key = calloc(1, strlen((const char *)KEY))), KEY);
+ hex2bin((crypt.iv = calloc(1, strlen((const char *)IV))), IV);
+ hex2bin((crypt.crypttext = calloc(1, strlen((const char *)CRYPTTEXT))), CRYPTTEXT);
+
+ do_crypt(&crypt, 16, &CRYPTTEXT[0], &PLAINTEXT[0]);
+
+ free(crypt.key);
+ free(crypt.iv);
+ free(crypt.crypttext);
+}
+
+static void test_crypt_192(void **state)
+{
+ (void)state;
+
+ unsigned char KEY[] = "F8A4B2D01A4A28C39E50D789C5B3CC386E56B63F16A7211A";
+ unsigned char IV[] = "08E8E00743E98EE82B90BBCC0DE83A77";
+ unsigned char CRYPTTEXT[] = "b5adf128eed12c9f13bd85cfdbe2d0fc";
unsigned char PLAINTEXT[] = "CRYPTTEST";

struct cryptdata crypt;
@@ -72,14 +93,14 @@ static void test_crypt_1(void **state)
hex2bin((crypt.iv = calloc(1, strlen((const char *)IV))), IV);
hex2bin((crypt.crypttext = calloc(1, strlen((const char *)CRYPTTEXT))), CRYPTTEXT);

- do_crypt(&crypt, &CRYPTTEXT[0], &PLAINTEXT[0]);
+ do_crypt(&crypt, 24, &CRYPTTEXT[0], &PLAINTEXT[0]);

free(crypt.key);
free(crypt.iv);
free(crypt.crypttext);
}

-static void test_crypt_2(void **state)
+static void test_crypt_256(void **state)
{
(void)state;

@@ -93,7 +114,7 @@ static void test_crypt_2(void **state)
hex2bin((crypt.iv = calloc(1, strlen((const char *)IV))), IV);
hex2bin((crypt.crypttext = calloc(1, strlen((const char *)CRYPTTEXT))), CRYPTTEXT);

- do_crypt(&crypt, &CRYPTTEXT[0], &PLAINTEXT[0]);
+ do_crypt(&crypt, 32, &CRYPTTEXT[0], &PLAINTEXT[0]);

free(crypt.key);
free(crypt.iv);
@@ -132,9 +153,10 @@ int main(void)
{
int error_count = 0;
const struct CMUnitTest crypt_tests[] = {
- cmocka_unit_test(test_crypt_1),
- cmocka_unit_test(test_crypt_failure),
- cmocka_unit_test(test_crypt_2)
+ cmocka_unit_test(test_crypt_128),
+ cmocka_unit_test(test_crypt_192),
+ cmocka_unit_test(test_crypt_256),
+ cmocka_unit_test(test_crypt_failure)
};
error_count += cmocka_run_group_tests_name("crypt", crypt_tests, NULL, NULL);
return error_count;
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:40 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

The library information is outdated.
Fix obvious desinformation and add p11-kit and wolfssl for PKCS#11.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Reviewed-by: Torben Hohn <torbe...@linutronix.de>
---
doc/source/swupdate.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/doc/source/swupdate.rst b/doc/source/swupdate.rst
index 9ab6bbf..5301693 100644
--- a/doc/source/swupdate.rst
+++ b/doc/source/swupdate.rst
@@ -207,10 +207,11 @@ There are only a few libraries that are required to compile SWUpdate.
They are commonly not exported and not installed, but they are
linked by SWUpdate to reuse the same functions for upgrading
MTD and UBI volumes.
-- openssl: required with the Webserver
+- openssl / wolfssl / mbedtls (optional) for cryptographic operations
+- p11-kit & wolfssl (optional) for PKCS#11 support
- Lua: liblua and the development headers.
-- libz, libcrypto are always linked.
-- libconfig: it is used by the default parser.
+- libz is always linked.
+- libconfig (optional) for the default parser
- libarchive (optional) for archive handler
- librsync (optional) for support to apply rdiff patches
- libjson (optional) for JSON parser and Hawkbit
--
2.28.0

ba...@linutronix.de

unread,
Sep 16, 2020, 9:58:40 AM9/16/20
to swup...@googlegroups.com, Bastian Germann, Torben Hohn
From: Bastian Germann <ba...@linutronix.de>

Add a PKCS#11 implementation for encrypted images. This replaces the
image decryption once activated. The interface stays the same but the key
is interpreted as PKCS#11 URI, which is first parsed via p11-kit. This
seems to be the most advanced parser implementation out there.

For the PKCS#11 abstraction, wolfSSL is used because it has first-class
support and AES is supported well, as opposed to OpenSSL that needs an
engine loaded at run time with the most prominent PKCS#11 engine not
supporting AES.

wolfSSL comes up with the concept of a crypto device that you register so
that the normal AES operations can be outsourced to them.

wolfSSL does not implement PKCS#7 padding in the AES operations, which is
needed because the encrypted images use it. Implement the unpadding in
swupdate_DECRYPT_final which operates on one block that is remembered from
the last AES decryption.

The decryption and PKCS#11 handling need context structs to live during
all decryption steps. Extend the existing decryption_key struct with them.

Signed-off-by: Bastian Germann <ba...@linutronix.de>
Acked-by: Torben Hohn <torbe...@linutronix.de>
---
corelib/swupdate_decrypt_pkcs11.c | 183 ++++++++++++++++++++++++++++++
include/sslapi.h | 28 ++++-
2 files changed, 208 insertions(+), 3 deletions(-)
create mode 100644 corelib/swupdate_decrypt_pkcs11.c

diff --git a/corelib/swupdate_decrypt_pkcs11.c b/corelib/swupdate_decrypt_pkcs11.c
new file mode 100644
index 0000000..1ca0a93
--- /dev/null
+++ b/corelib/swupdate_decrypt_pkcs11.c
@@ -0,0 +1,183 @@
+/*
+ * (C) Copyright 2020, Linutronix GmbH
+ * Author: Bastian Germann
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "swupdate.h"
+#include "sslapi.h"
+#include "util.h"
+#include <wolfssl/wolfcrypt/error-crypt.h>
+#include <wolfssl/wolfcrypt/logging.h>
+
+#ifdef DEBUG_WOLFSSL
+static void wolfssl_debug(int __attribute__ ((__unused__)) level, const char *const msg)
+{
+ DEBUG("%s", msg);
+}
+#endif
+
+struct swupdate_digest *swupdate_DECRYPT_init(unsigned char *uri, unsigned char *iv)
+{
+ struct swupdate_digest *dgst;
+ const char *library;
+ const char *pin;
+ const char *msg;
+ CK_ATTRIBUTE_PTR key_id;
+ int slot_id;
+ int err = 0;
+ int dev_id = 1;
+
+ if ((uri == NULL) || (iv == NULL)) {
+ ERROR("PKCS#11 URI or AES IV missing for decryption!");
+ return NULL;
+ }
+
+ dgst = calloc(1, sizeof(*dgst));
+ if (!dgst) {
+ return NULL;
+ }
+
+ dgst->p11uri = p11_kit_uri_new();
+ err = p11_kit_uri_parse(uri, P11_KIT_URI_FOR_ANY, dgst->p11uri);
+ if (err) {
+ msg = p11_kit_uri_message(err);
+ ERROR("PKCS#11 URI: %s", msg);
+ return NULL;
+ }
+
+ slot_id = p11_kit_uri_get_slot_id(dgst->p11uri);
+ key_id = p11_kit_uri_get_attribute(dgst->p11uri, CKA_ID);
+ pin = p11_kit_uri_get_pin_value(dgst->p11uri);
+ library = p11_kit_uri_get_module_path(dgst->p11uri);
+ if (slot_id == -1 || key_id == NULL || pin == NULL || library == NULL) {
+ ERROR("PKCS#11 URI must contain slot-id, id, pin-value, and module-path.");
+ goto err_free;
+ }
+
+ // Set up a valid PKCS#7 block plus one state octet
+ for (int i = 0; i <= AES_BLK_SIZE; i++) {
+ dgst->last_decr[i] = AES_BLK_SIZE;
+ }
+
+#ifdef DEBUG_WOLFSSL
+ wolfSSL_SetLoggingCb(wolfssl_debug);
+ wolfSSL_Debugging_ON();
+#endif
+ wolfCrypt_Init();
+ err = wc_Pkcs11_Initialize(&dgst->pkdev, library, NULL);
+ if (err)
+ goto err_msg;
+
+ err = wc_Pkcs11Token_Init(&dgst->pktoken, &dgst->pkdev, slot_id,
+ "unspecified", pin, strlen(pin));
+ if (err)
+ goto err_msg;
+
+ err = wc_CryptoCb_RegisterDevice(dev_id, wc_Pkcs11_CryptoDevCb, &dgst->pktoken);
+ if (err)
+ goto err_msg;
+
+ err = wc_AesInit_Id(&dgst->ctxdec, key_id->pValue, key_id->ulValueLen, NULL, dev_id);
+ if (err)
+ goto err_msg;
+
+ err = wc_AesSetIV(&dgst->ctxdec, iv);
+ if (err)
+ goto err_msg;
+
+ INFO("PKCS#11 key set up successfully.");
+ return dgst;
+
+err_msg:
+ msg = wc_GetErrorString(err);
+ ERROR("PKCS#11 initialization failed: %s", msg);
+
+err_free:
+ if (&dgst->pktoken)
+ wc_Pkcs11Token_Final(&dgst->pktoken);
+ if (&dgst->pkdev)
+ wc_Pkcs11_Finalize(&dgst->pkdev);
+
+ p11_kit_uri_free(dgst->p11uri);
+ free(dgst);
+
+ return NULL;
+}
+
+int swupdate_DECRYPT_update(struct swupdate_digest *dgst, unsigned char *buf,
+ int *outlen, const unsigned char *cryptbuf, int inlen)
+{
+ unsigned char pad_buf[inlen];
+ const char *msg;
+ int err;
+ int one_off_sz = inlen - AES_BLK_SIZE;
+
+ if (inlen < AES_BLK_SIZE)
+ return -EFAULT;
+
+ err = wc_AesCbcDecrypt(&dgst->ctxdec, pad_buf, cryptbuf, inlen);
+ if (err) {
+ msg = wc_GetErrorString(err);
+ ERROR("PKCS#11 AES decryption failed: %s", msg);
+ return -EFAULT;
+ }
+
+ if (dgst->last_decr[AES_BLK_SIZE]) {
+ // This is for the first decryption operation
+ memcpy(buf, pad_buf, one_off_sz);
+ dgst->last_decr[AES_BLK_SIZE] = 0;
+ *outlen = one_off_sz;
+ } else {
+ memcpy(buf, dgst->last_decr, AES_BLK_SIZE);
+ memcpy(buf[AES_BLK_SIZE], pad_buf, one_off_sz);
+ *outlen = inlen;
+ }
+ // Remember the last decrypted block which might contain padding
+ memcpy(dgst->last_decr, &pad_buf[one_off_sz], AES_BLK_SIZE);
+
+ return 0;
+}
+
+// Gets rid of PKCS#7 padding
+int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf, int *outlen)
+{
+ unsigned char last_oct = dgst->last_decr[AES_BLK_SIZE - 1];
+ if (last_oct > AES_BLK_SIZE || last_oct == 0) {
+ ERROR("AES: Invalid PKCS#7 padding.");
+ return -EFAULT;
+ }
+
+ for (int i = 2; i <= last_oct; i++) {
+ if (dgst->last_decr[AES_BLK_SIZE - i] != last_oct) {
+ ERROR("AES: Invalid PKCS#7 padding.");
+ return -EFAULT;
+ }
+ }
+
+ *outlen = AES_BLK_SIZE - last_oct;
+ memcpy(buf, dgst->last_decr, *outlen);
+
+ return 0;
+}
+
+void swupdate_DECRYPT_cleanup(struct swupdate_digest *dgst)
+{
+ if (dgst) {
+ if (&dgst->pktoken)
+ wc_Pkcs11Token_Final(&dgst->pktoken);
+ if (&dgst->pkdev)
+ wc_Pkcs11_Finalize(&dgst->pkdev);
+ p11_kit_uri_free(dgst->p11uri);
+
+ free(dgst);
+ dgst = NULL;
+ }
+
+ wolfCrypt_Cleanup();
+}
diff --git a/include/sslapi.h b/include/sslapi.h
index 97e1f5c..5a3236a 100644
--- a/include/sslapi.h
+++ b/include/sslapi.h
@@ -18,6 +18,16 @@
*/
#if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_ENCRYPTED_IMAGES) || \
defined(CONFIG_CHANNEL_CURL_SSL)
+
+#ifdef CONFIG_PKCS11
+#include <wolfssl/options.h>
+#include <wolfssl/wolfcrypt/aes.h>
+#include <wolfssl/wolfcrypt/wc_pkcs11.h>
+// Exclude p11-kit's pkcs11.h to prevent conflicting with wolfssl's
+#define PKCS11_H 1
+#include <p11-kit/uri.h>
+#endif
+
#if defined(CONFIG_SSL_IMPL_OPENSSL) || defined(CONFIG_SSL_IMPL_WOLFSSL)
#include <openssl/bio.h>
#include <openssl/objects.h>
@@ -74,7 +84,13 @@ struct swupdate_digest {
EVP_PKEY_CTX *ckey; /* this is used for RSA key */
X509_STORE *certs; /* this is used if CMS is set */
EVP_MD_CTX *ctx;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+#ifdef CONFIG_PKCS11
+ unsigned char last_decr[AES_BLOCK_SIZE + 1];
+ P11KitUri *p11uri;
+ Aes ctxdec;
+ Pkcs11Dev pkdev;
+ Pkcs11Token pktoken;
+#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
EVP_CIPHER_CTX ctxdec;
#else
EVP_CIPHER_CTX *ctxdec;
@@ -119,9 +135,15 @@ struct swupdate_digest {
#ifdef CONFIG_SIGNED_IMAGES
mbedtls_pk_context mbedtls_pk_context;
#endif /* CONFIG_SIGNED_IMAGES */
-#ifdef CONFIG_ENCRYPTED_IMAGES
+#ifdef CONFIG_PKCS11
+ unsigned char last_decr[AES_BLOCK_SIZE + 1];
+ P11KitUri *p11uri;
+ Aes ctxdec;
+ Pkcs11Dev pkdev;
+ Pkcs11Token pktoken;
+#elif defined(CONFIG_ENCRYPTED_IMAGES)
mbedtls_cipher_context_t mbedtls_cipher_context;
-#endif /* CONFIG_ENCRYPTED_IMAGES */
+#endif /* CONFIG_PKCS11 */
};

#else /* CONFIG_SSL_IMPL */
--
2.28.0

Stefano Babic

unread,
Sep 17, 2020, 5:08:09 AM9/17/20
to ba...@linutronix.de, swup...@googlegroups.com
Hi Bastian,

thanks for your work ! A first preview:

On 16.09.20 15:58, ba...@linutronix.de wrote:
> From: Bastian Germann <ba...@linutronix.de>
>
> Hi,
>
> This series consists of three parts. Any of the three parts could also be
> imported to SWUpdate without the others.
>
> The first 7 commits add wolfSSL as an alternative SSL/crypto implementation.
> This can only be used with the OpenSSL compatibility layer built in. The CMS
> image verification cannot be used with any wolfSSL version but may be added
> later. It is blocked from being used if wolfSSL is enabled.

Ok, understood. So support you introduce is for feature compatibility
new to mbedTLS (signed images via RSA keys).

>
> The following commits add a new feature to use PKCS#11 support for the
> AES image decryption. This needs a wolfSSL build with PKCS#11 support enabled
> which is not in the default build up to the current version.
> As I like to use this along with CMS, I made the PKCS#11 implementation work
> with any of the SSL implementations, not only wolfSSL.

Very good, appreciated.

Can you ask under which systems you have tested ? I guess you tested
under Debian / Elbe, have you also tested on OE / Buildroot ? And have
you tested with OpenSSL / mBEDTLS, too (or one of them) ?

This is not a blocking point, but just to note and we can ask if there
is maybe other users for the missing buildsystems (mainly Buildroot as I
have currently no project with it).

>
> A PKCS#11-using application is encouraged to address any key material via a
> RFC7512 URI. p11-kit is used as a parser. If you prefer a more lightweight
> solution (Using ordered, space separated fields or implementing a simple
> parser) then I am happy to send a follow-up series with that change.

Let this away, I do not want to reinvent the wheel.

Meta-swupdate allows to get private key using HSM to sign the image with
PKCS#11 as well.

>
> I tested the implementation with wolfSSL 4.4.0 and 4.5.0 along with softhsm2.

Ah, ok.

> To import a key, use softhsm2-util with the --aes parameter.
> Using GnuTLS's p11tool for the import will not work.
>

It would be interesting if this could be tested with a real HSM, too.

> The last five commits implement other AES key lengths additionally to AES256.

ok, nice - good plan, I will then split myself in 3 logical areas and
apply them in sequence.
Best regards,
Stefano Babic

--
=====================================================================
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de
=====================================================================

Bastian Germann

unread,
Sep 17, 2020, 6:04:08 AM9/17/20
to Stefano Babic, swup...@googlegroups.com
Am 17.09.20 um 11:08 schrieb Stefano Babic:
> Hi Bastian,
>
> thanks for your work ! A first preview:
>
> On 16.09.20 15:58, ba...@linutronix.de wrote:
>> From: Bastian Germann <ba...@linutronix.de>
>>
>> Hi,
>>
>> This series consists of three parts. Any of the three parts could also be
>> imported to SWUpdate without the others.
>>
>> The first 7 commits add wolfSSL as an alternative SSL/crypto implementation.
>> This can only be used with the OpenSSL compatibility layer built in. The CMS
>> image verification cannot be used with any wolfSSL version but may be added
>> later. It is blocked from being used if wolfSSL is enabled.
>
> Ok, understood. So support you introduce is for feature compatibility
> new to mbedTLS (signed images via RSA keys).

That is right.

>> The following commits add a new feature to use PKCS#11 support for the
>> AES image decryption. This needs a wolfSSL build with PKCS#11 support enabled
>> which is not in the default build up to the current version.
>> As I like to use this along with CMS, I made the PKCS#11 implementation work
>> with any of the SSL implementations, not only wolfSSL.
>
> Very good, appreciated.
>
> Can you ask under which systems you have tested ? I guess you tested
> under Debian / Elbe, have you also tested on OE / Buildroot ? And have
> you tested with OpenSSL / mBEDTLS, too (or one of them) ?

I tested with Debian only. I tested the feature to work along with
OpenSSL and mbedTLS as well.

> This is not a blocking point, but just to note and we can ask if there
> is maybe other users for the missing buildsystems (mainly Buildroot as I
> have currently no project with it).
>
>>
>> A PKCS#11-using application is encouraged to address any key material via a
>> RFC7512 URI. p11-kit is used as a parser. If you prefer a more lightweight
>> solution (Using ordered, space separated fields or implementing a simple
>> parser) then I am happy to send a follow-up series with that change.
>
> Let this away, I do not want to reinvent the wheel.
>
> Meta-swupdate allows to get private key using HSM to sign the image with
> PKCS#11 as well.

Adding meta-swupdate support for encryption via PKCS#11 might be
problematic because the openssl PKCS#11 engine lacks AES support. Maybe
there is another tool available in OpenEmbedded that one can use for that.

>> I tested the implementation with wolfSSL 4.4.0 and 4.5.0 along with softhsm2.
>
> Ah, ok.
>
>> To import a key, use softhsm2-util with the --aes parameter.
>> Using GnuTLS's p11tool for the import will not work.
>>
>
> It would be interesting if this could be tested with a real HSM, too.

I am planning on testing with a TPM via tpm2-pkcs11.

Stefano Babic

unread,
Sep 24, 2020, 5:52:17 AM9/24/20
to ba...@linutronix.de, swup...@googlegroups.com
Hi Bastian,


I have no comments for the series and I cannot find myself issues
reviewing them, but I was not able to find time to deep test them. To
avoid to delay this series, I merge this into -master and I will update
meta-swupdate to use it. I hope to win some more testers among
SWUpdate's users.

Best regards,
Stefano Babic


On 16.09.20 15:58, ba...@linutronix.de wrote:

Bastian Germann

unread,
Sep 24, 2020, 6:05:54 AM9/24/20
to Stefano Babic, swup...@googlegroups.com
Am 24.09.20 um 11:52 schrieb Stefano Babic:
> Hi Bastian,
>
>
> I have no comments for the series and I cannot find myself issues
> reviewing them, but I was not able to find time to deep test them. To
> avoid to delay this series, I merge this into -master and I will update
> meta-swupdate to use it. I hope to win some more testers among
> SWUpdate's users.
>
> Best regards,
> Stefano Babic

Hi Stefano,

In the mean time I have found an issue (not with the series but with
wolfSSL): https://github.com/wolfSSL/wolfssl/issues/3313

This makes RSA PSS behave like RSA PKCS#1.5. They are already working on it.

Regards,
Bastian
Reply all
Reply to author
Forward
0 new messages