Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PSA implementation of ed25519 image verification and x25519 random key encryption/decryption #323

Merged
merged 14 commits into from
Sep 27, 2024

Conversation

de-nordic
Copy link
Contributor

@de-nordic de-nordic commented Jul 24, 2024

The PSA encryption is quite complete.
The mbedTLS configuration is rather dodgy.
There are few requirements from upstream and mcuboot upmerge would be nice.

The TODO for reviewers:

  • check licenses on [noups]

config BOOT_ED25519_PSA_DEPENDENCIES
bool
default n
select PSA_WANT_ALG_SHA_256
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PSA_WANT_ALG_SHA_256 is stranger there - won't be there once we will introduce corrected signature right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would be with #325 and mcu-tools/mcuboot#2029

return 0;
}

status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, message_len,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the place where psa_verify_hash() will be used instead for full sha512 based signature check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Exactly. In the following PR 33a7ec4 there is already that part done.

The difference is that instead of the sha256, which is the messge here, we will get sha512, and therefore we do not rely on the internal sha512 calculation of psa_verify_message, but rather just verify the hash.

Copy link

@valeriosetti valeriosetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just had a quick look to the last 2 commits of this PR and I added some minor comments. I'll take a deeper look ASAP

boot/zephyr/Kconfig Outdated Show resolved Hide resolved
boot/zephyr/Kconfig Outdated Show resolved Hide resolved
default BOOT_ED25519_TINYCRYPT
config BOOT_ED25519_TINYCRYPT
bool "Use tinycrypt"
select BOOT_USE_TINYCRYPT
depends on !NRF_SECURITY

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: isn't this a bit redundant with line 184? I mean we already have default BOOT_ED25519_PSA if NRF_SECURITY there, so I don't know if it's worth to add depends on !NRF_SECURITY here and on line 194 for Mbed TLS. Wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just makes these options inaccessible.

@@ -15,7 +15,7 @@
#include "mcuboot_config/mcuboot_config.h"

#if (defined(MCUBOOT_USE_MBED_TLS) + \
defined(MCUBOOT_USE_TINYCRYPT)) != 1
defined(MCUBOOT_USE_TINYCRYPT) + defined(MCUBOOT_USE_PSA_CRYPTO)) != 1
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT or PSA"

@@ -9,6 +9,11 @@

#include "mcuboot_config/mcuboot_config.h"

#if defined(CONFIG_NRF_SECURITY)
/* We are not really using the MBEDTLS but need the ASN.1 parsing funcitons */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor detail, but I don't agree much with this comment. You are not using Mbed TLS for crypto, but you are using its ASN1 parse capabilities. So I would rephrase it as:

/* Enable ASN1 parse functions from Mbed TLS */

Wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I can replace that. btw:#326

Copy link

@valeriosetti valeriosetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completed the 2nd pass I mentioned this morning and I left some new comments.

psa_ret = psa_crypto_init();
if (psa_ret != PSA_SUCCESS) {
BOOT_LOG_ERR("AES crypto init failed %d", psa_ret);
return -1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you might add memset(private_key, 0, sizeof(private_key)); here as well just in case psa_crypto_init fails.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will re-order operations so that the private key is not loaded before crypto init happens.

psa_ret = psa_key_derivation_setup(&key_do, key_do_alg);
if (psa_ret != PSA_SUCCESS) {
BOOT_LOG_ERR("Key derivation setup failed %d", psa_ret);
return -1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you might add psa_destroy_key(kid); just in case psa_key_derivation_setup fails.
From a practical point of view this might not matter much because the device won't boot in this case and the key is volatile (so it will be lost on power cycle), but it might be nice for cleanliness.

@@ -415,7 +387,7 @@ static int fake_rng(void *p_rng, unsigned char *output, size_t len)
* @param enckey An AES-128 or AES-256 key sized buffer to store to plain key.
*/
int
boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey)
boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not moving these functions out of encrypted.c for better code organization? In this case you would have 2 source files implementing these functions, i.e. encrypted_psa.c and the new one, without a huge #if !defined(CONFIG_BOOT_ED25519_PSA) in encrypted.c...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not want to do that within this PR, that is something I would like to do, but that has to be done upstream.
Because we are trying to do things with [nrf noups] till we are able to push the changes upstream, I do not want to divert from the upstream code too much.

Comment on lines 38 to 40
target_include_directories(MCUBOOT_BOOTUTIL INTERFACE
${ZEPHYR_MBEDTLS_MODULE_DIR}/include
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 space indent for cmake. Is this going to be submitted upstream?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a look below, wouldn't be keeping the existing one and adding a new one for psa crypto work better since you're not changing a piece of the upstream code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general idea is to, at some point, bring this upstream.
I am keeping the PSA code separate because the change is significant and the code is already badly ifdefed in the verification/encryption calls.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved

Comment on lines 55 to 57
zephyr_library_include_directories(
${ZEPHYR_MBEDTLS_MODULE_DIR}/include
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved

Comment on lines 14 to 24
# Within sdk-nrf NRF security is default
config NRF_SECURITY
bool
default y
select NRF_OBERON
select BOOT_USE_PSA_CRYPTO

# NRF_SECURITY enforces PSA crypt
config MBEDTLS
bool
default n if NRF_SECURITY
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NRF_SECURITY already exists, it should not be getting defined here again, likewise with MBEDTLS. Default should go in a Kconfig.defconfig file

@@ -27,6 +40,15 @@ config BOOT_USE_MBEDTLS
help
Use mbedTLS for crypto primitives.

config BOOT_USE_PSA_CRYPTO
bool
# Hidden option
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Hidden option

There should not be a comment for this, put hidden option in the help text only

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved

Comment on lines 124 to 133
config MBEDTLS_HEAP_SIZE
int
default 2048
help
The PSA internals need to be able to allocate memory for operation
and it uses mbedTLS heap for that.

config MBEDTLS_ENABLE_HEAP
bool
default y
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with these

Comment on lines 163 to 164
default BOOT_IMG_HASH_ALG_SHA256 if BOOT_IMG_HASH_ALG_SHA256_ALLOW
default BOOT_IMG_HASH_ALG_SHA384 if BOOT_IMG_HASH_ALG_SHA384_ALLOW
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

help text always goes last

boot/zephyr/Kconfig Show resolved Hide resolved
boot/zephyr/Kconfig Show resolved Hide resolved
boot/bootutil/include/bootutil/crypto/aes_ctr.h Outdated Show resolved Hide resolved
Comment on lines 81 to 82
/* Fixme: Fix needed here, as ed25519 should only use sha512 */
if (!(hlen == 64 || hlen == 32) || slen != 64) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be using defines for these sizes

@de-nordic de-nordic force-pushed the x25519_enc branch 2 times, most recently from de6a34d to dd4e39f Compare September 18, 2024 07:23
@nvlsianpu
Copy link
Contributor

@nordicjm Please revisit.

Comment on lines 38 to 40
target_include_directories(MCUBOOT_BOOTUTIL INTERFACE
${ZEPHYR_MBEDTLS_MODULE_DIR}/include
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved

Comment on lines 55 to 57
zephyr_library_include_directories(
${ZEPHYR_MBEDTLS_MODULE_DIR}/include
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved

boot/zephyr/CMakeLists.txt Show resolved Hide resolved
@@ -27,6 +40,15 @@ config BOOT_USE_MBEDTLS
help
Use mbedTLS for crypto primitives.

config BOOT_USE_PSA_CRYPTO
bool
# Hidden option
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not resolved

@nordicjm
Copy link
Contributor

@nordicjm Please revisit.

None of the comments have been resolved and issues remain

Copy link
Contributor

@nordicjm nordicjm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor Kconfig nit.

config BOOT_USE_PSA_CRYPTO
bool
default y if NRF_SECURITY
default n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
default n

default n not needed


config BOOT_ED25519_PSA_DEPENDENCIES
bool
default n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above

if BOOT_ENCRYPT_IMAGE
config BOOT_X25519_PSA_DEPENDENCIES
bool
default n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above

if MBEDTLS_ENABLE_HEAP

config MBEDTLS_HEAP_SIZE
int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int

This is an existing symbol already https://github.com/zephyrproject-rtos/zephyr/blob/main/modules/mbedtls/Kconfig#L191

@de-nordic de-nordic force-pushed the x25519_enc branch 2 times, most recently from e78edce to 329814d Compare September 26, 2024 15:58
d3zd3z and others added 14 commits September 26, 2024 16:59
In Mbed TLS 3.1, the private fields in the ASN.1 structure were made private.
This breaks code that accesses these private macros.

Fix this by changing the ASN.1 specific code to use a new field accessor
`ASN1_CONTEXT_MEMBER` that will be conditionally defined based on the version of
Mbed TLS that is present.

Signed-off-by: David Brown <david.brown@linaro.org>
(cherry picked from commit 1d79ef3)
Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
Currently, when swap using scratch is used with encrypted images,
MCUboot is decrypting the images during the copy from the secondary slot
to the scratch area. This means the scratch area contains plaintext
image data and therefore that the scratch area must be placed in the
MCU's internal flash memory. This commit makes the necessary changes to
perform the decryption when copying from the scratch area to the primary
slot instead, making possible to place the scratch area in an external
flash memory since the scratch area is now encrypted.

Note that BOOT_SWAP_SAVE_ENCTLV must be enabled if the scratch area is
placed in external flash memory.

Signed-off-by: Thomas Altenbach <thomas.altenbach@legrand.com>
(cherry picked from commit 08d2d94)
Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
In the boot_image_validate_encrypted there was call to
flash_area_id_to_multi_image_slot, which tries to figure out
slot index from flash area and image index, and the result of the
call was not used for anything as slot index is hardcoded in the
next call to be 1 (secondary).

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit 4da4a72)
All of boot_enc_ function follow the same pattern where
they take encryption context as the first parameter, and the
boot_enc_decrypt stands out here as it does not work around
the encryption context, but is rather single-part decryption
function only used for decrypting of the image encryption
key.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit 2371c0a)
…_drop.

The enc_key_data.valid had been set to true when key has been added
to the encryption context, but in case when boot_enc_drop was called,
on the same context, the flag remained true, even though the context
may no longer hold any valid context nor key.
The commit moves the enc_key_data invalidation to enc_key_drop.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit 3355735)
… of image

In all cases where boot_enc_load is called it is known what slot
is addressed, so it is better to just pass the slot number
instead of making the boot_enc_load figure out slot number from
image index and provided flash area object.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit 7f9ac97)
…mage_to_sram

There was not really needed repetition of code in if-else
block; common code has been moved out and the block has been
reduced.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit d09112a)
Convert tab to spaces; fix opening brace position.

Signed-off-by: Fabio Utzig <utzig@apache.org>
(cherry picked from commit d5e0e89)
boot_encrypt required the image_index paired with flash area pointer
to be able to figure out which slot it will operate on.
Since in most calls the slot is known in advance it can be just
passed to the function directly.
The commit replaces both parameters with slot number.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit 3f11286)
Move checking of conditions, which remain the same for the whole
loop run, outside of the loop.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit 6fe259b)
…ndex

There is no point for boot_enc_valid to take image index and
flash area and use these to figure out slot number.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit 956311d)
…t_enc_decrypt

To be able to implement encryption with API that requires different
calls for encryption and encryption, the boot_encrypt
needs to be replaced with encryption/decryption specific functions.

Upstream PR: mcu-tools/mcuboot#2017

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
Set of changes to Kconfig, CMakeLists.txt and some of headers
that are required for the PSA support to compile.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
The commit provides implementation of image verification with
ed25519 and encryption/decryption support where random key
is encrypted using x25519.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
@nvlsianpu nvlsianpu merged commit 5f95fec into nrfconnect:main Sep 27, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants