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

sys: Add PSA Crypto module #18578

Closed
wants to merge 6 commits into from

Conversation

Einhornhool
Copy link
Contributor

@Einhornhool Einhornhool commented Sep 12, 2022

Contribution description

This adds an implementation of the ARM PSA Crypto API specification to RIOT.

It is a cryptographic API that supports software and hardware backends as well as the use of multiple secure elements, which can be configured with Kconfig.
It integrates indirect, identifier based key management to support persistent storage of key material in local memory and devices with protected key storage.

A description of the implementation design and an evaluation of the processing time and memory overhead in RIOT has been published here: Usable Security for an IoT OS: Integrating the Zoo of Embedded Crypto Components Below a Common API
Implementation status

So far this implementation supports the following operations:

  • Volatile key storage
  • AES in CBC mode
  • Hashes (MD5, SHA1, SHA224, SHA256)
  • HMAC SHA256
  • ECDSA with NIST P192 and P256 curves

Issues/PRs references

Split up PR #18547

Related:
#18583
#18582
#18581
#18580
#18579

@aabadie
Copy link
Contributor

aabadie commented Sep 12, 2022

Why not keep the example application from #18547 ? It was providing a way for Murdock to build (and test) the code of this PR.

@Einhornhool
Copy link
Contributor Author

Einhornhool commented Sep 12, 2022

I removed it, because this branch only provides the PSA Module without backend support. I submitted the code for the wrappers for the RIOT cipher module, etc, in separate PRs, to reduce the size of the PR, but this will mean that the example won't build.

@github-actions github-actions bot added the Area: examples Area: Example Applications label Sep 13, 2022
@Einhornhool
Copy link
Contributor Author

Einhornhool commented Sep 13, 2022

Why not keep the example application from #18547 ? It was providing a way for Murdock to build (and test) the code of this PR.

I added a minimal example application that works on this branch. It only executes key management operations and random number generation. It can be extended by more operations when other backends are included.

Copy link
Contributor

@kfessel kfessel left a comment

Choose a reason for hiding this comment

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

the static tests found some empty lines and some long lines https://github.com/RIOT-OS/RIOT/actions/runs/3045866373 please check if they are fixable

psa_key_slot_number_t slot_number;
#if IS_ACTIVE(CONFIG_PSA_SECURE_ELEMENT_ASYMMETRIC)
uint8_t pubkey_data[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
size_t pubkey_bytes;
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason you use pubkey_bytes here to refer to the size of the buffer ? This is kind of confusing to me since I relate bytes to being data. pubkey_data_len or pubkey_data_length would make more sense in my opinion.

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 agree, I changed the names

{
lib_initialized = 1;

#if IS_ACTIVE(CONFIG_MODULE_PSA_KEY_SLOT_MGMT)
Copy link
Contributor

Choose a reason for hiding this comment

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

I learned that one should use if (IS_ACTIVE(...)) wherever possible because this will cause the code to be compiled normally even if the specific FLAGS are not enabled and therefore enable syntax checks. If the code chunks are not used they will be optimized out afterwards.

No idea how much work changing this would be but you should keep this in mind. Especially looking at e.g. psa_crypto_location_dispatch this could increase code coverage by a lot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for telling me, I didn't know. I changed this on this branch.

}

operation->iv_set = 1;
*iv_length = operation->default_iv_length;
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be *iv_length = iv_size ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, my bad. Fixed.


uint8_t actual_hash_length = PSA_HASH_LENGTH(operation->alg);

if (hash_size < actual_hash_length) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this check a little late ? I would think that for e.g. psa_hash_compute checking if the output buffer is big enough should happen before any computation is done

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We actually need the check in psa_hash_finish, in case it is called outside of psa_hash_compute.
I do agree that it would be good to abort before computing anything, but checking in both places would result in redundant code. I'm not sure what's preferable here.

@@ -0,0 +1,13 @@
#!/usr/bin/env python3
Copy link
Contributor

Choose a reason for hiding this comment

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

please change the mode

sudo chmod 0775 examples/psa_crypto/tests/01-run.py

Copy link
Contributor

@MrKevinWeiss MrKevinWeiss left a comment

Choose a reason for hiding this comment

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

I was able to get the make build and test (vs kconfig).

There is some cleanup needed in the kconfig model. Normally we don't have configuration values select modules.

diff --git a/examples/psa_crypto/Makefile b/examples/psa_crypto/Makefile
diff --git a/examples/psa_crypto/Makefile b/examples/psa_crypto/Makefile
index 7c5d438aab..791374bf9b 100644
--- a/examples/psa_crypto/Makefile
+++ b/examples/psa_crypto/Makefile
@@ -1,10 +1,12 @@
 # This has to be the absolute path to the RIOT base directory:
 RIOTBASE ?= $(CURDIR)/../..
 
+USEMODULE += psa_crypto
+USEMODULE += random
+USEMODULE += psa_key_slot_mgmt
+
 APPLICATION = example_psa_crypto
 
 BOARD ?= native
 
-export TEST_KCONFIG ?= 1
-
 include $(RIOTBASE)/Makefile.include
diff --git a/sys/psa_crypto/Kconfig b/sys/psa_crypto/Kconfig
index 4bdda0b10e..e3332e85fc 100644
--- a/sys/psa_crypto/Kconfig
+++ b/sys/psa_crypto/Kconfig
@@ -13,12 +13,13 @@ menuconfig MODULE_PSA_CRYPTO
 if MODULE_PSA_CRYPTO
 
 rsource "Kconfig.asymmetric"
-rsource "Kconfig.ciphers"
 rsource "Kconfig.hashes"
 rsource "Kconfig.mac"
-rsource "Kconfig.keys"
 
 rsource "psa_se_mgmt/Kconfig"
 rsource "psa_key_slot_mgmt/Kconfig"
 
 endif # MODULE_PSA_CRYPTO
+
+rsource "Kconfig.ciphers"
+rsource "Kconfig.keys"
diff --git a/sys/psa_crypto/Kconfig.ciphers b/sys/psa_crypto/Kconfig.ciphers
index 7cb282ff77..aac8d5570f 100644
--- a/sys/psa_crypto/Kconfig.ciphers
+++ b/sys/psa_crypto/Kconfig.ciphers
@@ -8,7 +8,7 @@
 menuconfig PSA_CIPHERS
     bool "PSA Cipher"
     select PSA_KEY_CONFIG
-    select MODULE_PSA_KEY_SLOT_MGMT
+    select MODULE_PSA_KEY_SLOT_MGMT if TEST_KCONFIG
 
 if PSA_CIPHERS
 
@@ -27,9 +27,9 @@ choice CIPHER_AES_128_ECB_IMPLEMENTATION
 
 config RIOT_CIPHER_AES_128_ECB
     bool "RIOT Cipher Module"
-    select MODULE_CRYPTO
-    select MODULE_CRYPTO_AES_128
-    select MODULE_PSA_RIOT_CIPHER_AES_ECB
+    select MODULE_CRYPTO if TEST_KCONFIG
+    select MODULE_CRYPTO_AES_128 if TEST_KCONFIG
+    select MODULE_PSA_RIOT_CIPHER_AES_ECB if TEST_KCONFIG
 
 endchoice
 
@@ -51,7 +51,7 @@ choice CIPHER_AES_128_CBC_IMPLEMENTATION
 
 config RIOT_CIPHER_AES_128_CBC
     bool "RIOT Cipher Module"
-    select MODULE_PSA_RIOT_CIPHER_AES_128_CBC
+    select MODULE_PSA_RIOT_CIPHER_AES_128_CBC if TEST_KCONFIG
 
 config HARDWARE_CIPHER_AES_128_CBC
     bool "Hardware Accelerated"
@@ -61,7 +61,7 @@ config HARDWARE_CIPHER_AES_128_CBC
 config PSA_TINYCRYPT_CIPHER_AES_128_CBC
     bool "TinyCrypt Library"
     select PACKAGE_TINYCRYPT
-    select MODULE_PSA_TINYCRYPT_CIPHER_AES_CBC
+    select MODULE_PSA_TINYCRYPT_CIPHER_AES_CBC if TEST_KCONFIG
 
 endchoice
 
@@ -82,9 +82,9 @@ choice CIPHER_AES_192_CBC_IMPLEMENTATION
 
 config RIOT_CIPHER_AES_192_CBC
     bool "RIOT Cipher Module"
-    select MODULE_CRYPTO
-    select MODULE_CRYPTO_AES_192
-    select MODULE_PSA_RIOT_CIPHER_AES_CBC
+    select MODULE_CRYPTO if TEST_KCONFIG
+    select MODULE_CRYPTO_AES_192 if TEST_KCONFIG
+    select MODULE_PSA_RIOT_CIPHER_AES_CBC if TEST_KCONFIG
 
 endchoice
 
@@ -105,9 +105,9 @@ choice CIPHER_AES_256_CBC_IMPLEMENTATION
 
 config RIOT_CIPHER_AES_256_CBC
     bool "RIOT Cipher Module"
-    select MODULE_CRYPTO
-    select MODULE_CRYPTO_AES_256
-    select MODULE_PSA_RIOT_CIPHER_AES_CBC
+    select MODULE_CRYPTO if TEST_KCONFIG
+    select MODULE_CRYPTO_AES_256 if TEST_KCONFIG
+    select MODULE_PSA_RIOT_CIPHER_AES_CBC if TEST_KCONFIG
 
 endchoice
 
@@ -143,4 +143,4 @@ config PSA_CIPHER_AES_192
 config PSA_CIPHER_AES_256
     bool
     help
-        Indicates that an 256 bit AES key is used
\ No newline at end of file
+        Indicates that an 256 bit AES key is used

Copy link
Contributor

@MrKevinWeiss MrKevinWeiss left a comment

Choose a reason for hiding this comment

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

A few meta-review things from the Kconfig/dependency modelling aspect:

  1. Many of the symbols that are used in code (ie #if IS_ACTIVE(CONFIG_*)) should probably be changed into modules so that they can be modelled in the Makefile.deps and exposed with info-modules.
  2. Anything that is used as values such as CONFIG_PSA_MAX_KEY_SIZE should be first modelled in the header file:
#ifndef CONFIG_PSA_MAX_KEY_SIZE
#if (IS_ACTIVE(MODULE_PSA_KEY_SIZE_256_R1) || \
     IS_ACTIVE(MODULE_PSA_CIPHER_AES_256_CBC) || \
     IS_ACTIVE(MODULE_PSA_MAC_HMAC_SHA_256) || \
     IS_ACTIVE(MODULE_PSA_SE_ATECCX08A_ECC))
#define CONFIG_PSA_MAX_KEY_SIZE 32
#elif (IS_ACTIVE(MODULE_PSA_CIPHER_AES_192_CBC) || \
       IS_ACTIVE(MODULE_PSA_ECC_P192_R1))
#define CONFIG_PSA_MAX_KEY_SIZE 24
#elif (IS_ACTIVE(MODULE_PSA_CIPHER_AES_128_CBC)) || \
      (IS_ACTIVE(MODULE_PSA_CIPHER_AES_128_ECB))
#define CONFIG_PSA_MAX_KEY_SIZE 16
#else
#define CONFIG_PSA_MAX_KEY_SIZE 0
#endif
#endif

Same goes for things like the

#ifndef CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT
#if IS_ACTIVE(MODULE_PSA_ASYMMETRIC)
#define CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT  5
#else
#define CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT  0
#endif
  1. Generally all modules should be namespaced, many things (eg HASHES_MD5 should be namespaced with PSA_
  2. I know that you were asked to split the PR but, at least in this state, there are a lot of things included that will be used but not here making it odd to have. There are two paths to move, either reduce and rework this PR to only have the bare minimum which you know will require more work later (eg. menuconfig with many options will only be config then in a follow-up change it back to menuconfig). Since hardware acceleration is not in this PR, all hardware based symbols should be removed from the module selection. OR go back to the initial, big PR, and split the commits to make it semi-reviewable. This would mean that not every step would need a passing test and things can be added with the future in mind.
  3. Obviously the make resolution needs to be implemented, but it would be a lot easier if the first 2 points are followed.

@Einhornhool
Copy link
Contributor Author

Thank you, Kevin.
I think from that perspective it makes more sense to keep everything in one PR with separate commits. I will apply all the changes I made on this branch and the other PSA subbranches to the original PR and reopen it, so we can work on that.
I'll also address numbers 1-3.

@Einhornhool
Copy link
Contributor Author

To make this easier to test and work on are going to keep working on the original branch: #18547

@Einhornhool Einhornhool closed this Nov 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: doc Area: Documentation Area: examples Area: Example Applications Area: Kconfig Area: Kconfig integration Area: sys Area: System
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants