mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
examples: Add PSA Crypto example
This commit is contained in:
parent
2584298ade
commit
c71441d74a
116
examples/psa_crypto/Makefile
Normal file
116
examples/psa_crypto/Makefile
Normal file
@ -0,0 +1,116 @@
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
APPLICATION = example_psa_crypto
|
||||
|
||||
BOARD ?= native
|
||||
|
||||
# Necessary configurations when using Kconfig dependency resolution
|
||||
# The file `app.config.test` is always used for the build configuration.
|
||||
# The config files below are only added if needed.
|
||||
ifeq (1, $(TEST_KCONFIG))
|
||||
ifeq (1, $(SECURE_ELEMENT))
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR) # Application specific (not needed by PSA)
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.se
|
||||
else ifeq (2, $(SECURE_ELEMENT))
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DMULTIPLE_SE # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR)
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.multi_se
|
||||
else ifdef CUSTOM_BACKEND
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.base
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.custom
|
||||
else
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.base
|
||||
endif
|
||||
else
|
||||
USEMODULE += ztimer
|
||||
USEMODULE += ztimer_usec
|
||||
|
||||
USEMODULE += psa_crypto
|
||||
|
||||
# Hashes are needed for ECDSA operations (including secure elements), which
|
||||
# is why we always build them
|
||||
USEMODULE += psa_hash
|
||||
USEMODULE += psa_hash_sha_256
|
||||
|
||||
ifeq (1, $(SECURE_ELEMENT))
|
||||
# When using a secure element, the type is required.
|
||||
# Also you can specify the number of key slots required to store keys.
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR) # Application specific (not needed by PSA)
|
||||
|
||||
CFLAGS += -DCONFIG_PSA_PROTECTED_KEY_COUNT=4
|
||||
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=1
|
||||
USEMODULE += psa_secure_element
|
||||
USEMODULE += psa_secure_element_ateccx08a
|
||||
USEMODULE += psa_secure_element_ateccx08a_ecc_p256
|
||||
else ifeq (2, $(SECURE_ELEMENT))
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DMULTIPLE_SE # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR) # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCONFIG_PSA_MAX_SE_COUNT=2
|
||||
CFLAGS += -DCONFIG_PSA_PROTECTED_KEY_COUNT=8
|
||||
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=2
|
||||
USEMODULE += psa_secure_element
|
||||
USEMODULE += psa_secure_element_multiple
|
||||
USEMODULE += psa_secure_element_ateccx08a
|
||||
USEMODULE += psa_secure_element_ateccx08a_ecc_p256
|
||||
else ifdef CUSTOM_BACKEND
|
||||
# Necessary configuration when using Make dependency resolution
|
||||
# This first part chooses the operation. If nothing else es specified,
|
||||
# a default backend is built depending on the platform capabilities.
|
||||
USEMODULE += psa_cipher
|
||||
USEMODULE += psa_cipher_aes_128_cbc
|
||||
|
||||
USEMODULE += psa_mac
|
||||
USEMODULE += psa_mac_hmac_sha_256
|
||||
|
||||
USEMODULE += psa_asymmetric
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1
|
||||
|
||||
# If you want to use a custom backend, you need to do it this way.
|
||||
USEMODULE += psa_cipher_aes_128_cbc_custom_backend
|
||||
USEMODULE += psa_cipher_aes_128_cbc_backend_riot # force custom backend
|
||||
|
||||
USEMODULE += psa_mac_hmac_sha_256_custom_backend
|
||||
USEMODULE += psa_mac_hmac_sha_256_backend_riot # force custom backend
|
||||
|
||||
USEMODULE += psa_hash_sha_256_custom_backend
|
||||
USEMODULE += psa_hash_sha_256_backend_riot
|
||||
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1_custom_backend
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1_backend_microecc # force custom backend
|
||||
else
|
||||
# Necessary configuration when using Make dependency resolution
|
||||
# This part only chooses the operation. If nothing else es specified,
|
||||
# a default backend is built depending on the platform capabilities.
|
||||
USEMODULE += psa_cipher
|
||||
USEMODULE += psa_cipher_aes_128_cbc
|
||||
|
||||
USEMODULE += psa_mac
|
||||
USEMODULE += psa_mac_hmac_sha_256
|
||||
|
||||
USEMODULE += psa_asymmetric
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1
|
||||
endif
|
||||
|
||||
ifndef SECURE_ELEMENT
|
||||
CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=3
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef SECURE_ELEMENT
|
||||
# The software implementations need a larger stack, so we increase the stack size.
|
||||
CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(12*THREAD_STACKSIZE_DEFAULT\)
|
||||
endif
|
||||
|
||||
SHOULD_RUN_KCONFIG :=
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
28
examples/psa_crypto/Makefile.ci
Normal file
28
examples/psa_crypto/Makefile.ci
Normal file
@ -0,0 +1,28 @@
|
||||
BOARD_INSUFFICIENT_MEMORY := \
|
||||
arduino-duemilanove \
|
||||
arduino-leonardo \
|
||||
arduino-mega2560 \
|
||||
arduino-nano \
|
||||
arduino-uno \
|
||||
atmega328p \
|
||||
atmega328p-xplained-mini \
|
||||
atmega8 \
|
||||
bluepill-stm32f030c8 \
|
||||
i-nucleo-lrwan1 \
|
||||
nucleo-f030r8 \
|
||||
nucleo-f031k6 \
|
||||
nucleo-f042k6 \
|
||||
nucleo-f303k8 \
|
||||
nucleo-f334r8 \
|
||||
nucleo-l011k4 \
|
||||
nucleo-l031k6 \
|
||||
nucleo-l053r8 \
|
||||
samd10-xmini \
|
||||
slstk3400a \
|
||||
stk3200 \
|
||||
stm32f030f4-demo \
|
||||
stm32f0discovery \
|
||||
stm32g0316-disco \
|
||||
stm32l0538-disco \
|
||||
waspmote-pro \
|
||||
#
|
102
examples/psa_crypto/README.md
Normal file
102
examples/psa_crypto/README.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Example Applications for PSA Crypto
|
||||
This example application is supposed to show two things:
|
||||
1. How to use basic functions of the PSA Crypto API
|
||||
2. How to configure the implementation with Kconfig dependency resolution vs. Make dependency resolution
|
||||
|
||||
## Basic usage of PSA Crypto
|
||||
There are three example operations:
|
||||
- AES 128 CBC
|
||||
- HMAC SHA256
|
||||
- ECDSA with a P256 curve
|
||||
|
||||
Each comes in its own sourcefile called `example_<operation>.c`. To see which functions to call to perform each operations, please read the code.
|
||||
|
||||
The application measures the processing times of the example operations. The table below shows the expected runtime values
|
||||
for software and hardware backends as well as secure elements, measured on the nRF52840dk (this is only to show the expected difference, values will differ on other platforms).
|
||||
|
||||
| Operations | Backends | Runtime \[us\] |
|
||||
|-------------|----------------|------------------|
|
||||
| HMAC SHA256 | CryptoCell 310 | 282 |
|
||||
| | RIOT Hashes | 468 |
|
||||
| | ATECC608A | 56376 |
|
||||
| AES 128 CBC | CryptoCell 310 | 140 |
|
||||
| | RIOT Cipher | 295 |
|
||||
| | ATECC608A | 68819 |
|
||||
| ECDSA P256 | CryptoCell 310 | 60931 |
|
||||
| | Micro-ECC | 522424 |
|
||||
| | ATECC608A | 285542 |
|
||||
|
||||
|
||||
## Configuration of the API
|
||||
There are two ways to configure the API: module selection via Kconfig and module selection
|
||||
via Makefiles.
|
||||
|
||||
To see which modules should be chosen for each configuration, please read the Makefile and
|
||||
the `app.config.test.*` files.
|
||||
|
||||
### Kconfig
|
||||
> **NOTE:** In this application all the configurations are in separate app.config files
|
||||
> for demonstration purposes. You can also write all configs into one file or choose them
|
||||
> via `menuconfig`.
|
||||
> To access the GUI, run `TEST_KCONFIG=1 BOARD=<your board> make menuconfig`.
|
||||
|
||||
When building the application with the `TEST_KCONFIG=1` option, the first config file parsed by the build system is `app.config.test`. This selects the PSA Crypto module and other modules our application needs (e.g. ztimer). If you need cryptographic keys, you can specify the number of key slots needed for key storage (the default is set to 5).
|
||||
The graph below shows how the `app.config` files in this application are included.
|
||||
Selections in `app.config.test` are always applied.
|
||||
The others are only added, if you specify the corresponding build option.
|
||||
|
||||
```mermaid
|
||||
flowchart TD;
|
||||
app.config.test -- default --> app.config.test.base;
|
||||
app.config.test.base -- CUSTOM_BACKEND=1 --> app.config.test.custom;
|
||||
app.config.test -- SECURE_ELEMENT=1 --> app.config.test.se;
|
||||
app.config.test -- SECURE_ELEMENT=2 --> app.config.test.multi_se;
|
||||
```
|
||||
If you build this without specifying anything else, the symbols in `app.config.test.base`
|
||||
are added and PSA Crypto will automatically choose a default crypto backend depending on the platform you're building for.
|
||||
For example when your platform is `native`, software implementations are built.
|
||||
When you specify `BOARD=nrf52840dk`, the hardware accelerator of the board will be built.
|
||||
|
||||
If you want to force a custom backend, you can specify that in the Kconfig file. This application already contains the configuration for a custom backend (see `app.config.test.custom`), which will be added to the application build when you define `CUSTOM_BACKEND=1`.
|
||||
|
||||
Instead of or in addition to the default and custom implementations you can use a secure element as a backend (see Section [Using Secure Elements](#using-secure-elements]).
|
||||
Secure elements are independent of the other backends. In this application, when you
|
||||
choose secure elements, they are built instead of the other backends.
|
||||
|
||||
Please note that the build options `CUSTOM_BACKEND` and `SECURE_ELEMENT` only apply to this specific application and have nothing to do with the PSA implementation.
|
||||
|
||||
### Make
|
||||
All the configurations in the Kconfig files can also be applied using Make dependency resolution. The Makefile contains all the modules that must be selected when building the different configurations.
|
||||
They can all be built as described above, but *without* defining TEST_KCONFIG.
|
||||
|
||||
To prevent conflicts when building this application multiple times with different backends, it is best to remove the `bin` directory in between builds.
|
||||
|
||||
## Using Secure Elements
|
||||
> **NOTE:**
|
||||
> Currently this implementation only supports Microchip ATECCX08A devices. Those devices need to be configured and locked to be able to correctly use them.
|
||||
> This implementation assumes that you have done that and that you know your device's configuration.
|
||||
|
||||
You can build this app either with one secure element or two secure elements (`SECURE_ELEMENT=1` or `SECURE_ELEMENT=2`). To be able to use your device, make sure, you've completed the following procedure.
|
||||
|
||||
In the application folder you can find a file called `custom_atca_params.h`, which overwrites the device parameters in `atca_params.h` in the cryptoauthlib package folder.
|
||||
To use more than one secure element, you need to specify device parameters for both of them.
|
||||
This application assumes that you connect two devices with different I2C addresses on the same I2C bus.
|
||||
Alternatively you can connect two devices with the same address on separate buses.
|
||||
You can modify `custom_atca_params.h` according to your device configurations and requirements.
|
||||
|
||||
For PSA Crypto, you also need to define a location value. Here these are defined as `PSA_ATCA_LOCATION_DEV0` and `PSA_ATCA_LOCATION_DEV1`. They can be any value between `PSA_KEY_LOCATION_SE_MIN` and `PSA_KEY_LOCATION_SE_MAX`.
|
||||
A special value is `PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT`, which can be used when only one secure element is needed.
|
||||
|
||||
Below the `ATCA_PARAMS` definitions, you can see the slot configurations.
|
||||
Here you need to specify for each connected secure element what kind of key can be stored in which slot, and whether a slot is already occupied. The structure is declared in `pkg/cryptoauthlib/include/atca.h` and contains the following elements:
|
||||
1. `key_type_allowed` (takes `psa_key_type_t`)
|
||||
2. `key_persistent` (is 0, can be ignored for now, since PSA does not yet support persistent storage)
|
||||
3. `slot_occupied` (should be 0 at start up, PSA will use this to mark slots as occupied)
|
||||
|
||||
The list in `custom_atca_params.h` contains an example configuration. If your device configuration is not compatible, you'll need to change the values as necessary.
|
||||
This is required, so the implementation can allocate free key slots and can generate and import new keys. If the device configuration does not match the values in the list or if your key slots are not writeable, you will get execution errors.
|
||||
|
||||
The current implementation does not support the use of keys that are already stored on the device.
|
||||
|
||||
## Note
|
||||
If you need more information about the build options, please refer to the API documentation.
|
6
examples/psa_crypto/app.config.test
Normal file
6
examples/psa_crypto/app.config.test
Normal file
@ -0,0 +1,6 @@
|
||||
CONFIG_MODULE_PSA_CRYPTO=y
|
||||
|
||||
CONFIG_MODULE_PSA_HASH=y
|
||||
CONFIG_MODULE_PSA_HASH_SHA_256=y
|
||||
|
||||
CONFIG_ZTIMER_USEC=y
|
11
examples/psa_crypto/app.config.test.base
Normal file
11
examples/psa_crypto/app.config.test.base
Normal file
@ -0,0 +1,11 @@
|
||||
CONFIG_MODULE_PSA_CIPHER=y
|
||||
CONFIG_MODULE_PSA_CIPHER_AES_128_CBC=y
|
||||
|
||||
CONFIG_MODULE_PSA_MAC=y
|
||||
CONFIG_MODULE_PSA_MAC_HMAC_SHA_256=y
|
||||
|
||||
CONFIG_MODULE_PSA_ASYMMETRIC=y
|
||||
CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1=y
|
||||
|
||||
CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=3
|
8
examples/psa_crypto/app.config.test.custom
Normal file
8
examples/psa_crypto/app.config.test.custom
Normal file
@ -0,0 +1,8 @@
|
||||
# force software backends
|
||||
CONFIG_MODULE_PSA_CIPHER_AES_128_CBC_BACKEND_RIOT=y
|
||||
CONFIG_MODULE_PSA_HASH_SHA_256_BACKEND_RIOT=y
|
||||
CONFIG_MODULE_PSA_MAC_HMAC_SHA_256_BACKEND_RIOT=y
|
||||
CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1_BACKEND_MICROECC=y
|
||||
|
||||
CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=3
|
9
examples/psa_crypto/app.config.test.multi_se
Normal file
9
examples/psa_crypto/app.config.test.multi_se
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_MULTIPLE=y
|
||||
|
||||
CONFIG_PSA_MAX_SE_COUNT=2
|
||||
CONFIG_PSA_PROTECTED_KEY_COUNT=8
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=2
|
6
examples/psa_crypto/app.config.test.se
Normal file
6
examples/psa_crypto/app.config.test.se
Normal file
@ -0,0 +1,6 @@
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256=y
|
||||
|
||||
CONFIG_PSA_PROTECTED_KEY_COUNT=4
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=1
|
125
examples/psa_crypto/custom_atca_params.h
Normal file
125
examples/psa_crypto/custom_atca_params.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2023 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Example custom atca_params.h file to use multiple ATECC608A
|
||||
* secure elements as backends for PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
#ifndef CUSTOM_ATCA_PARAMS_H
|
||||
#define CUSTOM_ATCA_PARAMS_H
|
||||
|
||||
#include "cryptoauthlib.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PSA_ATCA_LOCATION_DEV0 (PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT)
|
||||
#define ATCA_PARAM_I2C_DEV0 (I2C_DEV(0)) /*!< Change this to the bus you want to use */
|
||||
#define ATCA_PARAM_ADDR_DEV0 (0xC0) /*!< Change this to your first device's address */
|
||||
#define ATCA_DEVTYPE_DEV0 (ATECC608A)
|
||||
#define ATCA_RX_RETRIES (20)
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
#define PSA_ATCA_LOCATION_DEV1 (PSA_KEY_LOCATION_SE_MIN)
|
||||
#define ATCA_PARAM_I2C_DEV1 (I2C_DEV(0)) /*!< Change this to the bus you want to use */
|
||||
#define ATCA_PARAM_ADDR_DEV1 (0xCC) /*!< Change this to your second device's address */
|
||||
#define ATCA_DEVTYPE_DEV1 (ATECC608A)
|
||||
|
||||
#define ATCA_PARAMS { .atca_loc = PSA_ATCA_LOCATION_DEV0,\
|
||||
.cfg = {\
|
||||
.iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE_DEV0, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR_DEV0, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C_DEV0, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES } \
|
||||
}, \
|
||||
{ .atca_loc = PSA_ATCA_LOCATION_DEV1,\
|
||||
.cfg = {\
|
||||
.iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE_DEV1, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR_DEV1, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C_DEV1, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES } \
|
||||
}
|
||||
#else
|
||||
#define ATCA_PARAMS { .atca_loc = PSA_ATCA_LOCATION_DEV0,\
|
||||
.cfg = {\
|
||||
.iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE_DEV0, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR_DEV0, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C_DEV0, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES } \
|
||||
}
|
||||
#endif /* MULTIPLE_SE */
|
||||
|
||||
#define ATCA_SLOTS_DEV0 { \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_AES, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_HMAC, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 1, 1 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ 0, 0, 0 }}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
#define ATCA_SLOTS_DEV1 { \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_AES, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_HMAC, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 1, 1 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ 0, 0, 0 }}
|
||||
#endif
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
#define ATCA_CONFIG_LIST { ATCA_SLOTS_DEV0 }, \
|
||||
{ ATCA_SLOTS_DEV1 }
|
||||
#else
|
||||
#define ATCA_CONFIG_LIST { ATCA_SLOTS_DEV0 }
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CUSTOM_ATCA_PARAMS_H */
|
||||
/** @} */
|
131
examples/psa_crypto/example_cipher_aes_128.c
Normal file
131
examples/psa_crypto/example_cipher_aes_128.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example functions for AES CBC encryption with PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#define AES_128_KEY_SIZE (16)
|
||||
#define AES_256_KEY_SIZE (32)
|
||||
|
||||
static const uint8_t KEY_128[] = {
|
||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
|
||||
};
|
||||
|
||||
static uint8_t PLAINTEXT[] = {
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51
|
||||
};
|
||||
static uint8_t PLAINTEXT_LEN = 32;
|
||||
|
||||
/**
|
||||
* @brief Example function to perform an AES-128 CBC encryption and decryption
|
||||
* with the PSA Crypto API.
|
||||
*
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t example_cipher_aes_128(void)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
|
||||
|
||||
size_t encr_output_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES,
|
||||
PSA_ALG_CBC_NO_PADDING, PLAINTEXT_LEN);
|
||||
|
||||
uint8_t cipher_out[encr_output_size];
|
||||
uint8_t plain_out[sizeof(PLAINTEXT)];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, 128);
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION
|
||||
(PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0);
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
#endif
|
||||
|
||||
status = psa_import_key(&attr, KEY_128, AES_128_KEY_SIZE, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, PLAINTEXT,
|
||||
PLAINTEXT_LEN, cipher_out, encr_output_size, &output_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_decrypt(key_id, PSA_ALG_CBC_NO_PADDING, cipher_out,
|
||||
sizeof(cipher_out), plain_out, sizeof(plain_out), &output_len);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return (memcmp(PLAINTEXT, plain_out, sizeof(plain_out)) ? -1 : 0);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
psa_status_t example_cipher_aes_128_sec_se(void)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1);
|
||||
|
||||
size_t encr_output_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES,
|
||||
PSA_ALG_CBC_NO_PADDING, PLAINTEXT_LEN);
|
||||
uint8_t cipher_out[encr_output_size];
|
||||
uint8_t plain_out[sizeof(PLAINTEXT)];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, 128);
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
|
||||
|
||||
status = psa_import_key(&attr, KEY_128, AES_128_KEY_SIZE, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, PLAINTEXT,
|
||||
PLAINTEXT_LEN, cipher_out, encr_output_size, &output_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_decrypt(key_id, PSA_ALG_CBC_NO_PADDING, cipher_out,
|
||||
sizeof(cipher_out), plain_out, sizeof(plain_out), &output_len);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return (memcmp(PLAINTEXT, plain_out, sizeof(plain_out)) ? -1 : 0);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
177
examples/psa_crypto/example_ecdsa_p256.c
Normal file
177
examples/psa_crypto/example_ecdsa_p256.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example functions for ECDSA with PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#define ECDSA_MESSAGE_SIZE (127)
|
||||
#define ECC_KEY_SIZE (256)
|
||||
|
||||
/**
|
||||
* @brief Example function to perform an ECDSA operation with a NIST P256 curve
|
||||
* with the PSA Crypto API.
|
||||
*
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t example_ecdsa_p256(void)
|
||||
{
|
||||
psa_key_id_t privkey_id;
|
||||
psa_key_attributes_t privkey_attr = psa_key_attributes_init();
|
||||
psa_key_id_t pubkey_id;
|
||||
psa_key_attributes_t pubkey_attr = psa_key_attributes_init();
|
||||
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
|
||||
psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
|
||||
psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
|
||||
psa_key_bits_t bits = ECC_KEY_SIZE;
|
||||
uint8_t bytes =
|
||||
PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), bits);
|
||||
|
||||
uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(
|
||||
PSA_ECC_FAMILY_SECP_R1),
|
||||
ECC_KEY_SIZE)] = { 0 };
|
||||
size_t pubkey_length;
|
||||
uint8_t signature[PSA_SIGN_OUTPUT_SIZE(type, bits, alg)];
|
||||
size_t sig_length;
|
||||
uint8_t msg[ECDSA_MESSAGE_SIZE] = { 0x0b };
|
||||
uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)];
|
||||
size_t hash_length;
|
||||
|
||||
psa_set_key_algorithm(&privkey_attr, alg);
|
||||
psa_set_key_usage_flags(&privkey_attr, usage);
|
||||
psa_set_key_type(&privkey_attr, type);
|
||||
psa_set_key_bits(&privkey_attr, bits);
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0);
|
||||
psa_set_key_lifetime(&privkey_attr, lifetime);
|
||||
#endif
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
|
||||
status = psa_generate_key(&privkey_attr, &privkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_export_public_key(privkey_id, public_key, sizeof(public_key), &pubkey_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_hash_compute(PSA_ALG_SHA_256, msg, sizeof(msg), hash, sizeof(hash), &hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_set_key_lifetime(&pubkey_attr, lifetime);
|
||||
#endif
|
||||
psa_set_key_algorithm(&pubkey_attr, alg);
|
||||
psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(bytes));
|
||||
psa_set_key_type(&pubkey_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
|
||||
status = psa_import_key(&pubkey_attr, public_key, pubkey_length, &pubkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_sign_hash(privkey_id, alg, hash, sizeof(hash), signature, sizeof(signature),
|
||||
&sig_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_verify_hash(pubkey_id, alg, hash, sizeof(hash), signature, sig_length);
|
||||
}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
psa_status_t example_ecdsa_p256_sec_se(void)
|
||||
{
|
||||
psa_key_id_t privkey_id;
|
||||
psa_key_attributes_t privkey_attr = psa_key_attributes_init();
|
||||
psa_key_id_t pubkey_id;
|
||||
psa_key_attributes_t pubkey_attr = psa_key_attributes_init();
|
||||
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1);
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
|
||||
psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
|
||||
psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
|
||||
psa_key_bits_t bits = 256;
|
||||
uint8_t bytes =
|
||||
PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), bits);
|
||||
|
||||
uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(
|
||||
PSA_ECC_FAMILY_SECP_R1), 256)] = { 0 };
|
||||
size_t pubkey_length;
|
||||
|
||||
uint8_t signature[PSA_SIGN_OUTPUT_SIZE(type, bits, alg)];
|
||||
size_t sig_length;
|
||||
uint8_t msg[ECDSA_MESSAGE_SIZE] = { 0x0b };
|
||||
uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)];
|
||||
size_t hash_length;
|
||||
|
||||
psa_set_key_lifetime(&privkey_attr, lifetime);
|
||||
psa_set_key_algorithm(&privkey_attr, alg);
|
||||
psa_set_key_usage_flags(&privkey_attr, usage);
|
||||
psa_set_key_type(&privkey_attr, type);
|
||||
psa_set_key_bits(&privkey_attr, bits);
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
|
||||
status = psa_generate_key(&privkey_attr, &privkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_export_public_key(privkey_id, public_key, sizeof(public_key), &pubkey_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_hash_compute(PSA_ALG_SHA_256, msg, sizeof(msg), hash, sizeof(hash), &hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_set_key_lifetime(&pubkey_attr, lifetime);
|
||||
psa_set_key_algorithm(&pubkey_attr, alg);
|
||||
psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(bytes));
|
||||
psa_set_key_type(&pubkey_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
|
||||
status = psa_import_key(&pubkey_attr, public_key, pubkey_length, &pubkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_sign_hash(privkey_id, alg, hash, sizeof(hash), signature, sizeof(signature),
|
||||
&sig_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_verify_hash(pubkey_id, alg, hash, sizeof(hash), signature, sig_length);
|
||||
}
|
||||
#endif
|
111
examples/psa_crypto/example_hmac_sha256.c
Normal file
111
examples/psa_crypto/example_hmac_sha256.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example functions for HMAC SHA256 with PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
static const uint8_t HMAC_KEY[] = {
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
|
||||
};
|
||||
static size_t HMAC_KEY_LEN = 32;
|
||||
|
||||
static const uint8_t HMAC_MSG[] = {
|
||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
|
||||
0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x73, 0x74,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72,
|
||||
0x20, 0x68, 0x6d, 0x61, 0x63, 0x32, 0x35, 0x36
|
||||
};
|
||||
static size_t HMAC_MSG_LEN = 32;
|
||||
|
||||
/**
|
||||
* @brief Example function to perform an HMAC SHA-256 computation
|
||||
* with the PSA Crypto API.
|
||||
*
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t example_hmac_sha256(void)
|
||||
{
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_MESSAGE;
|
||||
|
||||
size_t digest_size =
|
||||
PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, HMAC_KEY_LEN, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
uint8_t digest[digest_size];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(HMAC_KEY_LEN));
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0);
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
#endif
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
status = psa_import_key(&attr, HMAC_KEY, HMAC_KEY_LEN, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
HMAC_MSG, HMAC_MSG_LEN, digest, digest_size,
|
||||
&output_len);
|
||||
}
|
||||
|
||||
#if MULTIPLE_SE
|
||||
psa_status_t example_hmac_sha256_sec_se(void)
|
||||
{
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_MESSAGE;
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1);
|
||||
|
||||
size_t digest_size =
|
||||
PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, HMAC_KEY_LEN, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
uint8_t digest[digest_size];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(HMAC_KEY_LEN));
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
|
||||
status = psa_import_key(&attr, HMAC_KEY, HMAC_KEY_LEN, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
HMAC_MSG, HMAC_MSG_LEN, digest, digest_size,
|
||||
&output_len);
|
||||
}
|
||||
#endif
|
90
examples/psa_crypto/main.c
Normal file
90
examples/psa_crypto/main.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example application for PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "psa/crypto.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
extern psa_status_t example_cipher_aes_128(void);
|
||||
extern psa_status_t example_hmac_sha256(void);
|
||||
extern psa_status_t example_ecdsa_p256(void);
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
extern psa_status_t example_cipher_aes_128_sec_se(void);
|
||||
extern psa_status_t example_hmac_sha256_sec_se(void);
|
||||
extern psa_status_t example_ecdsa_p256_sec_se(void);
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
psa_crypto_init();
|
||||
|
||||
ztimer_acquire(ZTIMER_USEC);
|
||||
ztimer_now_t start = ztimer_now(ZTIMER_USEC);
|
||||
|
||||
status = example_hmac_sha256();
|
||||
printf("HMAC SHA256 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("HMAC SHA256 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_cipher_aes_128();
|
||||
printf("Cipher AES 128 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Cipher AES 128 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_ecdsa_p256();
|
||||
printf("ECDSA took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("ECDSA failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
puts("Running Examples with secondary SE:");
|
||||
status = example_hmac_sha256_sec_se();
|
||||
printf("HMAC SHA256 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("HMAC SHA256 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_cipher_aes_128_sec_se();
|
||||
printf("Cipher AES 128 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Cipher AES 128 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_ecdsa_p256_sec_se();
|
||||
printf("ECDSA took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("ECDSA failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
#endif
|
||||
|
||||
ztimer_release(ZTIMER_USEC);
|
||||
|
||||
puts("All Done");
|
||||
return 0;
|
||||
}
|
13
examples/psa_crypto/tests/01-run.py
Executable file
13
examples/psa_crypto/tests/01-run.py
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
from testrunner import run
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
child.expect_exact('All Done')
|
||||
print("[TEST PASSED]")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run(testfunc))
|
Loading…
Reference in New Issue
Block a user