mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/psa_crypto: chacha20 oneshot gluecode
This commit is contained in:
parent
4612cc2348
commit
b9396c4739
@ -20,6 +20,7 @@ ifneq (,$(filter nrf52840xxaa,$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += periph_hash_sha_512
|
||||
FEATURES_PROVIDED += periph_hmac_sha_256
|
||||
FEATURES_PROVIDED += periph_cipher_aes_128_cbc
|
||||
FEATURES_PROVIDED += periph_cipher_chacha20
|
||||
FEATURES_PROVIDED += periph_ecc_p192r1
|
||||
FEATURES_PROVIDED += periph_ecc_p256r1
|
||||
FEATURES_PROVIDED += periph_ecc_ed25519
|
||||
|
@ -38,6 +38,11 @@ ifneq (,$(filter periph_cipher_aes_128_cbc,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_aes_cbc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_cipher_chacha20,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_cipher_chacha20
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_hmac_sha_256,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_hmac
|
||||
|
@ -851,6 +851,8 @@ groups:
|
||||
help: A Hardware Random Number Generator (HWRNG) peripheral is present.
|
||||
- name: periph_cipher_aes_128_cbc
|
||||
help: AES 128 CBC hardware acceleration present
|
||||
- name: periph_cipher_chacha20
|
||||
help: ChaCha20 hardware acceleration present
|
||||
- name: periph_ecc_p192r1
|
||||
help: ECC P192R1 hardware acceleration peripheral present.
|
||||
- name: periph_ecc_p256r1
|
||||
|
@ -139,6 +139,7 @@ FEATURES_EXISTING := \
|
||||
periph_adc_continuous \
|
||||
periph_can \
|
||||
periph_cipher_aes_128_cbc \
|
||||
periph_cipher_chacha20 \
|
||||
periph_clic \
|
||||
periph_coretimer \
|
||||
periph_cpuid \
|
||||
|
@ -12,6 +12,7 @@ USEMODULE += $(PERIPH_FEATURES)
|
||||
# Add all USED periph_% init modules unless they are blacklisted
|
||||
PERIPH_IGNORE_MODULES := \
|
||||
periph_cipher_aes_128_cbc \
|
||||
periph_cipher_chacha20 \
|
||||
periph_clic \
|
||||
periph_common \
|
||||
periph_coretimer \
|
||||
|
@ -357,6 +357,7 @@ PSEUDOMODULES += psa_riot_cipher_aes_128_ecb
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_128_cbc
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_192_cbc
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_256_cbc
|
||||
PSEUDOMODULES += psa_riot_cipher_chacha20
|
||||
PSEUDOMODULES += psa_riot_hashes_md5
|
||||
PSEUDOMODULES += psa_riot_hashes_sha_1
|
||||
PSEUDOMODULES += psa_riot_hashes_sha_224
|
||||
|
@ -13,6 +13,7 @@ CFLAGS += -Wno-cast-align
|
||||
|
||||
PSEUDOMODULES += psa_cryptocell_310_aes_cbc
|
||||
PSEUDOMODULES += psa_cryptocell_310_aes_common
|
||||
PSEUDOMODULES += psa_cryptocell_310_cipher_chacha20
|
||||
PSEUDOMODULES += psa_cryptocell_310_ecc_common
|
||||
PSEUDOMODULES += psa_cryptocell_310_ecc_p192
|
||||
PSEUDOMODULES += psa_cryptocell_310_ecc_p256
|
||||
|
@ -23,6 +23,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CPU_NRF52
|
||||
#define CHECK_POINTER_DMA_ACCESS(p) ((unsigned int)p >= 0x20000000 ? (unsigned int)p < 0x40000000 : 0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable CryptoCell module and IRQs.
|
||||
*
|
||||
|
@ -28,6 +28,7 @@ extern "C" {
|
||||
#include "crys_ec_mont_edw_error.h"
|
||||
#include "crys_hash_error.h"
|
||||
#include "ssi_aes_error.h"
|
||||
#include "crys_chacha_error.h"
|
||||
|
||||
/**
|
||||
* @brief Convert CryptoCell CRYS errors to PSA status values
|
||||
|
135
pkg/driver_cryptocell_310/psa_cryptocell_310/cipher_chacha20.c
Normal file
135
pkg/driver_cryptocell_310/psa_cryptocell_310/cipher_chacha20.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2024 TU Dresden
|
||||
*
|
||||
* 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 pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief PSA Crypto wrapper for the CryptoCell 310 ChaCha API.
|
||||
*
|
||||
* @author Lennard Melling <lennard.melling@msx.tu-dresden.de>
|
||||
*
|
||||
*/
|
||||
#ifndef PSA_CRYPTOCELL_310_CHACHA_H
|
||||
#define PSA_CRYPTOCELL_310_CHACHA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crys_chacha.h"
|
||||
#include "cryptocell_310_util.h"
|
||||
#include "psa_error.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
psa_status_t psa_cipher_chacha20_encrypt(uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
DEBUG("Peripheral ChaCha20 Cipher encryption");
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (!CHECK_POINTER_DMA_ACCESS(key_buffer) ||
|
||||
!CHECK_POINTER_DMA_ACCESS(input) ||
|
||||
!CHECK_POINTER_DMA_ACCESS(output)) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
if (output_size < (input_length + CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (key_buffer_size != CRYS_CHACHA_KEY_MAX_SIZE_IN_BYTES) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
uint8_t *nonce = &output[0];
|
||||
uint8_t *data_out = &output[CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES];
|
||||
status = psa_generate_random(nonce, CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
cryptocell_310_enable();
|
||||
CRYSError_t periph_status = CRYS_CHACHA(nonce, CRYS_CHACHA_Nonce96BitSize,
|
||||
key_buffer, 0UL,
|
||||
CRYS_CHACHA_Encrypt,
|
||||
(uint8_t *) input,
|
||||
input_length,
|
||||
data_out);
|
||||
cryptocell_310_disable();
|
||||
status = CRYS_to_psa_error(periph_status);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*output_length = input_length + CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_cipher_chacha20_decrypt(uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
DEBUG("Peripheral ChaCha20 Cipher decryption");
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (!CHECK_POINTER_DMA_ACCESS(key_buffer) ||
|
||||
!CHECK_POINTER_DMA_ACCESS(input) ||
|
||||
!CHECK_POINTER_DMA_ACCESS(output)) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
if ((key_buffer_size != CRYS_CHACHA_KEY_MAX_SIZE_IN_BYTES) ||
|
||||
(input_length < CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (output_size < (input_length - CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const uint8_t *nonce = &input[0];
|
||||
const uint8_t *data_in = &input[CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES];
|
||||
size_t data_size = input_length - CRYS_CHACHA_NONCE_MAX_SIZE_IN_BYTES;
|
||||
|
||||
cryptocell_310_enable();
|
||||
CRYSError_t periph_status = CRYS_CHACHA((uint8_t *)nonce, CRYS_CHACHA_Nonce96BitSize,
|
||||
key_buffer, 0UL,
|
||||
CRYS_CHACHA_Decrypt,
|
||||
(uint8_t *)data_in,
|
||||
data_size,
|
||||
output);
|
||||
cryptocell_310_disable();
|
||||
status = CRYS_to_psa_error(periph_status);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*output_length = data_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTOCELL_310_CHACHA_H */
|
||||
/** @} */
|
@ -27,12 +27,23 @@ psa_status_t CRYS_to_psa_error(CRYSError_t error)
|
||||
return PSA_SUCCESS;
|
||||
case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR:
|
||||
case CRYS_HASH_IS_NOT_SUPPORTED:
|
||||
case CRYS_CHACHA_IS_NOT_SUPPORTED:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
|
||||
case CRYS_ECEDW_SIGN_VERIFY_FAILED_ERROR:
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
case CRYS_CHACHA_CTX_SIZES_ERROR:
|
||||
case CRYS_CHACHA_DATA_IN_POINTER_INVALID_ERROR:
|
||||
case CRYS_CHACHA_DATA_IN_SIZE_ILLEGAL:
|
||||
case CRYS_CHACHA_DATA_OUT_POINTER_INVALID_ERROR:
|
||||
case CRYS_CHACHA_ILLEGAL_KEY_SIZE_ERROR:
|
||||
case CRYS_CHACHA_INVALID_ENCRYPT_MODE_ERROR:
|
||||
case CRYS_CHACHA_INVALID_KEY_POINTER_ERROR:
|
||||
case CRYS_CHACHA_INVALID_NONCE_ERROR:
|
||||
case CRYS_CHACHA_INVALID_NONCE_PTR_ERROR:
|
||||
case CRYS_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR:
|
||||
case CRYS_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
@ -453,6 +464,28 @@ const char *cryptocell310_status_to_humanly_readable(uint32_t status)
|
||||
return "CRYS_ECMONT_IS_NOT_SUPPORTED";
|
||||
case CRYS_ECEDW_IS_NOT_SUPPORTED:
|
||||
return "CRYS_ECEDW_IS_NOT_SUPPORTED";
|
||||
case CRYS_CHACHA_CTX_SIZES_ERROR:
|
||||
return "CRYS_CHACHA_CTX_SIZES_ERROR";
|
||||
case CRYS_CHACHA_DATA_IN_POINTER_INVALID_ERROR:
|
||||
return "CRYS_CHACHA_DATA_IN_POINTER_INVALID_ERROR";
|
||||
case CRYS_CHACHA_DATA_IN_SIZE_ILLEGAL:
|
||||
return "CRYS_CHACHA_DATA_IN_SIZE_ILLEGAL";
|
||||
case CRYS_CHACHA_DATA_OUT_POINTER_INVALID_ERROR:
|
||||
return "CRYS_CHACHA_DATA_OUT_POINTER_INVALID_ERROR";
|
||||
case CRYS_CHACHA_ILLEGAL_KEY_SIZE_ERROR:
|
||||
return "CRYS_CHACHA_ILLEGAL_KEY_SIZE_ERROR";
|
||||
case CRYS_CHACHA_INVALID_ENCRYPT_MODE_ERROR:
|
||||
return "CRYS_CHACHA_INVALID_ENCRYPT_MODE_ERROR";
|
||||
case CRYS_CHACHA_INVALID_KEY_POINTER_ERROR:
|
||||
return "CRYS_CHACHA_INVALID_KEY_POINTER_ERROR";
|
||||
case CRYS_CHACHA_INVALID_NONCE_ERROR:
|
||||
return "CRYS_CHACHA_INVALID_NONCE_ERROR";
|
||||
case CRYS_CHACHA_INVALID_NONCE_PTR_ERROR:
|
||||
return "CRYS_CHACHA_INVALID_NONCE_PTR_ERROR";
|
||||
case CRYS_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR:
|
||||
return "CRYS_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR";
|
||||
case CRYS_CHACHA_IS_NOT_SUPPORTED:
|
||||
return "CRYS_CHACHA_IS_NOT_SUPPORTED";
|
||||
default:
|
||||
return "Error value not recognized";
|
||||
}
|
||||
|
@ -89,21 +89,22 @@ static void _keystream(chacha20poly1305_ctx_t *ctx, const uint8_t *key,
|
||||
}
|
||||
|
||||
static void _xcrypt(chacha20poly1305_ctx_t *ctx, const uint8_t *key,
|
||||
const uint8_t *nonce, const uint8_t *in, uint8_t *out, size_t len)
|
||||
const uint8_t *nonce, const uint8_t *in, uint8_t *out,
|
||||
size_t len, size_t counter)
|
||||
{
|
||||
/* Number of full 64 byte blocks */
|
||||
const size_t num_blocks = len >> 6;
|
||||
size_t pos = 0;
|
||||
/* xcrypt full blocks */
|
||||
for (size_t i = 0; i < num_blocks; i++, pos += 64) {
|
||||
_keystream(ctx, key, nonce, i+1);
|
||||
_keystream(ctx, key, nonce, i + counter);
|
||||
for (size_t j = 0; j < 64; j++) {
|
||||
out[pos+j] = in[pos+j] ^ ((uint8_t*)ctx->state)[j];
|
||||
}
|
||||
}
|
||||
/* xcrypt remaining bytes */
|
||||
if (len - pos) {
|
||||
_keystream(ctx, key, nonce, num_blocks+1);
|
||||
_keystream(ctx, key, nonce, num_blocks + counter);
|
||||
for (size_t j = 0; j < len - pos; j++) {
|
||||
out[pos+j] = in[pos+j] ^ ((uint8_t*)ctx->state)[j];
|
||||
}
|
||||
@ -142,7 +143,7 @@ void chacha20poly1305_encrypt(uint8_t *cipher, const uint8_t *msg,
|
||||
const uint8_t *key, const uint8_t *nonce)
|
||||
{
|
||||
chacha20poly1305_ctx_t ctx;
|
||||
_xcrypt(&ctx, key, nonce, msg, cipher, msglen);
|
||||
_xcrypt(&ctx, key, nonce, msg, cipher, msglen, 1);
|
||||
crypto_secure_wipe(&ctx, sizeof(ctx));
|
||||
/* Generate tag */
|
||||
_poly1305_gentag(&cipher[msglen], key, nonce,
|
||||
@ -164,6 +165,14 @@ int chacha20poly1305_decrypt(const uint8_t *cipher, size_t cipherlen,
|
||||
}
|
||||
chacha20poly1305_ctx_t ctx;
|
||||
/* Number of full blocks */
|
||||
_xcrypt(&ctx, key, nonce, cipher, msg, *msglen);
|
||||
_xcrypt(&ctx, key, nonce, cipher, msg, *msglen, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void chacha20_encrypt_decrypt(const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key, const uint8_t *nonce,
|
||||
size_t inputlen)
|
||||
{
|
||||
chacha20poly1305_ctx_t ctx;
|
||||
_xcrypt(&ctx, key, nonce, input, output, inputlen, 0);
|
||||
}
|
||||
|
84
sys/crypto/psa_riot_cipher/chacha20.c
Normal file
84
sys/crypto/psa_riot_cipher/chacha20.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2024 TU Dresden
|
||||
*
|
||||
* 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 sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT ChaCha20 Cipher from the ChaCha20-Poly1305 Cipher module
|
||||
*
|
||||
* @author Lennard Melling <lennard.melling@msx.tu-dresden.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crypto/chacha20poly1305.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
psa_status_t psa_cipher_chacha20_encrypt(uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
DEBUG("RIOT ChaCha20 Cipher encryption");
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (output_size < (input_length + CHACHA20POLY1305_NONCE_BYTES)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (key_buffer_size != CHACHA20POLY1305_KEY_BYTES) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
uint8_t *nonce = &output[0];
|
||||
uint8_t *data_out = &output[CHACHA20POLY1305_NONCE_BYTES];
|
||||
status = psa_generate_random(nonce, CHACHA20POLY1305_NONCE_BYTES);
|
||||
if (status != PSA_SUCCESS)
|
||||
return status;
|
||||
|
||||
chacha20_encrypt_decrypt(input, data_out, key_buffer, nonce, input_length);
|
||||
|
||||
*output_length = input_length + CHACHA20POLY1305_NONCE_BYTES;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_cipher_chacha20_decrypt(uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
DEBUG("RIOT ChaCha20 Cipher decryption");
|
||||
|
||||
if ((key_buffer_size != CHACHA20POLY1305_KEY_BYTES) ||
|
||||
(input_length < CHACHA20POLY1305_NONCE_BYTES)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
||||
if (output_size < (input_length - CHACHA20POLY1305_NONCE_BYTES)) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
const uint8_t *nonce = &input[0];
|
||||
const uint8_t *data_in = &input[CHACHA20POLY1305_NONCE_BYTES];
|
||||
|
||||
chacha20_encrypt_decrypt(data_in, output, key_buffer, nonce, input_length - CHACHA20POLY1305_NONCE_BYTES);
|
||||
*output_length = input_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
@ -96,6 +96,21 @@ int chacha20poly1305_decrypt(const uint8_t *cipher, size_t cipherlen,
|
||||
const uint8_t *aad, size_t aadlen,
|
||||
const uint8_t *key, const uint8_t *nonce);
|
||||
|
||||
/**
|
||||
* @brief Encrypt a plaintext to ciphertext with the ChaCha20 algorithm.
|
||||
*
|
||||
* @param[in] input Input for the encryption/decryption.
|
||||
* @param[out] output The resulting encrypted cipher/decrypted message.
|
||||
* @param[in] key Key to encrypt/decrypt with, must be
|
||||
* @ref CHACHA20POLY1305_KEY_BYTES long.
|
||||
* @param[in] nonce Nonce to use. Must be CHACHA20POLY1305_NONCE_BYTES
|
||||
* long.
|
||||
* @param[in] inputlen Length of the input byte array.
|
||||
*/
|
||||
void chacha20_encrypt_decrypt(const uint8_t *input, uint8_t *output,
|
||||
const uint8_t *key, const uint8_t *nonce,
|
||||
size_t inputlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -61,7 +61,8 @@ extern "C" {
|
||||
IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) || \
|
||||
IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || \
|
||||
IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \
|
||||
IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256))
|
||||
IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256) || \
|
||||
IS_USED(MODULE_PSA_CIPHER_CHACHA20))
|
||||
#define CONFIG_PSA_MAX_KEY_SIZE 32
|
||||
#elif (IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || \
|
||||
IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1))
|
||||
@ -591,8 +592,9 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
#define PSA_CIPHER_IV_LENGTH(key_type, alg) \
|
||||
(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \
|
||||
((alg) == PSA_ALG_CBC_NO_PADDING) ? 16 : 0)
|
||||
((PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \
|
||||
((alg) == PSA_ALG_CBC_NO_PADDING)) ? 16 : \
|
||||
(key_type == PSA_KEY_TYPE_CHACHA20) ? 12 : 0)
|
||||
|
||||
/**
|
||||
* @brief A sufficient buffer size for storing the IV generated by @ref psa_cipher_generate_iv(),
|
||||
|
@ -143,6 +143,30 @@ ifneq (,$(filter psa_cipher_aes_192_cbc_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += psa_riot_cipher_aes_192_cbc
|
||||
endif
|
||||
|
||||
## ChaCha20
|
||||
ifneq (,$(filter psa_cipher_chacha20,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_cipher_chacha20_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_cipher_chacha20
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_cipher_chacha20,$(FEATURES_USED)))
|
||||
USEMODULE += psa_cipher_chacha20_backend_periph
|
||||
else
|
||||
USEMODULE += psa_cipher_chacha20_backend_riot
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cipher_chacha20_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_cipher_chacha20
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cipher_chacha20_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += crypto
|
||||
USEMODULE += psa_riot_cipher
|
||||
USEMODULE += psa_riot_cipher_chacha20
|
||||
endif
|
||||
|
||||
# Hash
|
||||
|
||||
## MD5
|
||||
|
@ -85,6 +85,18 @@ ifneq (,$(filter psa_cipher_aes_256_cbc,$(USEMODULE)))
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_cipher_chacha20
|
||||
PSEUDOMODULES += psa_cipher_chacha20_backend_periph
|
||||
PSEUDOMODULES += psa_cipher_chacha20_backend_riot
|
||||
PSEUDOMODULES += psa_cipher_chacha20_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_cipher_chacha20,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_cipher_chacha20))
|
||||
$(error "One (and only one) backend should be selected for psa_cipher_chacha20")
|
||||
endif
|
||||
endif
|
||||
|
||||
## Hash
|
||||
PSEUDOMODULES += psa_hash
|
||||
PSEUDOMODULES += psa_hash_md5
|
||||
|
@ -286,6 +286,12 @@
|
||||
* - psa_cipher_aes_256_cbc_custom_backend
|
||||
* - psa_cipher_aes_256_cbc_backend_riot
|
||||
*
|
||||
* #### CHACHA20
|
||||
* - psa_cipher_chacha20
|
||||
* - psa_cipher_chacha20_backend_periph
|
||||
* - psa_cipher_chacha20_custom_backend
|
||||
* - psa_cipher_chacha20_backend_riot
|
||||
*
|
||||
* ### Hashes
|
||||
* - Base: psa_hash
|
||||
*
|
||||
|
@ -28,6 +28,7 @@ extern "C" {
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_contexts.h"
|
||||
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_128_CBC) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an AES 128 CBC encryption.
|
||||
* See @ref psa_cipher_encrypt()
|
||||
@ -77,7 +78,9 @@ psa_status_t psa_cipher_cbc_aes_128_decrypt(const psa_key_attributes_t *attribut
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
#endif /* MODULE_PSA_CIPHER_AES_128_CBC */
|
||||
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an AES 192 CBC encryption.
|
||||
* See @ref psa_cipher_encrypt()
|
||||
@ -102,7 +105,9 @@ psa_status_t psa_cipher_cbc_aes_192_encrypt(const psa_key_attributes_t *attribut
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
#endif /* MODULE_PSA_CIPHER_AES_192_CBC */
|
||||
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an AES 256 CBC encryption.
|
||||
* See @ref psa_cipher_encrypt()
|
||||
@ -127,7 +132,53 @@ psa_status_t psa_cipher_cbc_aes_256_encrypt(const psa_key_attributes_t *attribut
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
#endif /* MODULE_PSA_CIPHER_AES_256_CBC */
|
||||
|
||||
#if IS_USED(MODULE_PSA_CIPHER_CHACHA20) || defined(DOXYGEN)
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for ChaCha20 encryption/decryption.
|
||||
* See @ref psa_cipher_encrypt().
|
||||
* @param key_buffer Buffer containing the Key.
|
||||
* @param key_buffer_size Size of the key in bytes. Must be 32 bytes.
|
||||
* @param input Input Buffer containing the message to be encrypted.
|
||||
* @param input_length Size of input buffer.
|
||||
* @param output Output buffer containing the generated 12 byte nonce
|
||||
* followed by the cipher of the input.
|
||||
* @param output_size Size of output buffer. Must be at least
|
||||
* (input_length + 12) bytes long.
|
||||
* @param output_length Actual size of the output (including nonce).
|
||||
*/
|
||||
psa_status_t psa_cipher_chacha20_encrypt(uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for ChaCha20 decryption.
|
||||
* See @ref psa_cipher_decrypt().
|
||||
* @param key_buffer Buffer containing the Key.
|
||||
* @param key_buffer_size Size of the key in bytes. Must be 32 bytes long.
|
||||
* @param input Input buffer containing the 12 byte nonce used in the
|
||||
* encryption followed by the cipher to be decrypted.
|
||||
* @param input_length Size of input buffer (including 12 byte nonce).
|
||||
* @param output Output buffer.
|
||||
* @param output_size Size of output buffer. Must be at least
|
||||
* (input_length - 12) bytes long.
|
||||
* @param output_length Actual size of the output.
|
||||
*/
|
||||
psa_status_t psa_cipher_chacha20_decrypt(uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
#endif /* MODULE_PSA_CIPHER_CHACHA20 */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -45,7 +45,8 @@ typedef enum {
|
||||
PSA_CBC_NO_PAD_AES_128,
|
||||
PSA_CBC_NO_PAD_AES_192,
|
||||
PSA_CBC_NO_PAD_AES_256,
|
||||
PSA_CBC_PKCS7_AES_256
|
||||
PSA_CBC_PKCS7_AES_256,
|
||||
PSA_STREAM_CIPHER_CHACHA20
|
||||
} psa_cipher_op_t;
|
||||
|
||||
/**
|
||||
@ -109,59 +110,127 @@ typedef enum {
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine algorithm, and key type with a key size of 128 bits.
|
||||
* @brief Combine key type and size with a PSA_ALG_CBC_NO_PADDING algorithm
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, and @c type are incompatible with the key size
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_CIPHER_OPERATION_128(alg, type) \
|
||||
(((alg == PSA_ALG_CBC_NO_PADDING) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_NO_PAD_AES_128 : \
|
||||
#define GET_CBC_NO_PADDING_OPERATION(type, bits) \
|
||||
((type == PSA_KEY_TYPE_AES) ? \
|
||||
((bits == 128) ? PSA_CBC_NO_PAD_AES_128 : \
|
||||
(bits == 192) ? PSA_CBC_NO_PAD_AES_192 : \
|
||||
(bits == 256) ? PSA_CBC_NO_PAD_AES_256 : \
|
||||
PSA_INVALID_OPERATION) : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine algorithm, and key type with a key size of 192 bits.
|
||||
* @brief Combine key type and size with a PSA_ALG_CBC_PKCS7 algorithm
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, and @c type are incompatible with the key size
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_CIPHER_OPERATION_192(alg, type) \
|
||||
(((alg == PSA_ALG_CBC_NO_PADDING) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_NO_PAD_AES_192 : \
|
||||
#define GET_CBC_PKCS7_OPERATION(type, bits) \
|
||||
(((alg == PSA_ALG_CBC_PKCS7) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_PKCS7_AES_256 : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine algorithm, and key type with a key size of 256 bits.
|
||||
* @brief Combine key type and size with a PSA_ALG_CFB algorithm
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, and @c type are incompatible with the key size
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_CIPHER_OPERATION_256(alg, type) \
|
||||
(((alg == PSA_ALG_CBC_NO_PADDING) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_NO_PAD_AES_256 : \
|
||||
((alg == PSA_ALG_CBC_PKCS7) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_PKCS7_AES_256 : \
|
||||
#define GET_CFB_OPERATION(type, bits) \
|
||||
(PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine key type and size with a PSA_ALG_CTR algorithm
|
||||
*
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_CTR_OPERATION(type, bits) \
|
||||
(PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine key type and size with a PSA_ALG_ECB_NO_PADDING algorithm
|
||||
*
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_ECB_NO_PADDING_OPERATION(type, bits) \
|
||||
(PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine key type and size with a PSA_ALG_OFB algorithm
|
||||
*
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_OFB_OPERATION(type, bits) \
|
||||
(PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine key type and size with a PSA_ALG_STREAM_CIPHER algorithm
|
||||
*
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_STREAM_CIPHER_OPERATION(type, bits) \
|
||||
(((type == PSA_KEY_TYPE_CHACHA20) && (bits == 256)) ? PSA_STREAM_CIPHER_CHACHA20 : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine key type and size with a PSA_ALG_XTS algorithm
|
||||
*
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define GET_XTS_OPERATION(type, bits) \
|
||||
(PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Map algorithm, key size and type to a specific operation.
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define PSA_ENCODE_CIPHER_OPERATION(alg, bits, type) \
|
||||
((bits == 128) ? GET_CIPHER_OPERATION_128(alg, type) : \
|
||||
(bits == 192) ? GET_CIPHER_OPERATION_192(alg, type) : \
|
||||
(bits == 256) ? GET_CIPHER_OPERATION_256(alg, type) : \
|
||||
#define PSA_ENCODE_CIPHER_OPERATION(alg, type, bits) \
|
||||
((alg == PSA_ALG_CBC_NO_PADDING) ? GET_CBC_NO_PADDING_OPERATION(type, bits) : \
|
||||
(alg == PSA_ALG_CBC_PKCS7) ? GET_CBC_PKCS7_OPERATION(type, bits) : \
|
||||
(alg == PSA_ALG_CFB) ? GET_CFB_OPERATION(type, bits) : \
|
||||
(alg == PSA_ALG_CTR) ? GET_CTR_OPERATION(type, bits) : \
|
||||
(alg == PSA_ALG_ECB_NO_PADDING) ? GET_ECB_NO_PADDING_OPERATION(type, bits) : \
|
||||
(alg == PSA_ALG_OFB) ? GET_OFB_OPERATION(type, bits) : \
|
||||
(alg == PSA_ALG_STREAM_CIPHER) ? GET_STREAM_CIPHER_OPERATION(type, bits) : \
|
||||
(alg == PSA_ALG_XTS) ? GET_XTS_OPERATION(type, bits) : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1019,6 +1019,11 @@ static psa_status_t psa_validate_unstructured_key_size(psa_key_type_t type, size
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
break;
|
||||
case PSA_KEY_TYPE_CHACHA20:
|
||||
if (bits != 256) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(void)bits;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
@ -1539,7 +1544,6 @@ psa_status_t psa_builtin_import_key(const psa_key_attributes_t *attributes,
|
||||
|
||||
if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
|
||||
*bits = PSA_BYTES_TO_BITS(data_length);
|
||||
|
||||
status = psa_validate_unstructured_key_size(type, *bits);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
|
@ -602,7 +602,8 @@ psa_status_t psa_algorithm_dispatch_cipher_encrypt( const psa_key_attributes_t *
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_cipher_op_t op = PSA_ENCODE_CIPHER_OPERATION(alg, attributes->bits, attributes->type);
|
||||
psa_cipher_op_t op = PSA_ENCODE_CIPHER_OPERATION(alg, attributes->type, attributes->bits);
|
||||
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
|
||||
@ -628,6 +629,13 @@ psa_status_t psa_algorithm_dispatch_cipher_encrypt( const psa_key_attributes_t *
|
||||
return psa_cipher_cbc_aes_256_encrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_CHACHA20)
|
||||
case PSA_STREAM_CIPHER_CHACHA20:
|
||||
return psa_cipher_chacha20_encrypt(key_data, *key_bytes,
|
||||
input, input_length,
|
||||
output, output_size,
|
||||
output_length);
|
||||
#endif
|
||||
default:
|
||||
(void)slot;
|
||||
(void)input;
|
||||
@ -648,7 +656,8 @@ psa_status_t psa_algorithm_dispatch_cipher_decrypt( const psa_key_attributes_t *
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_cipher_op_t op = PSA_ENCODE_CIPHER_OPERATION(alg, attributes->bits, attributes->type);
|
||||
psa_cipher_op_t op = PSA_ENCODE_CIPHER_OPERATION(alg, attributes->type, attributes->bits);
|
||||
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
|
||||
@ -674,6 +683,13 @@ psa_status_t psa_algorithm_dispatch_cipher_decrypt( const psa_key_attributes_t *
|
||||
return psa_cipher_cbc_aes_256_decrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_CHACHA20)
|
||||
case PSA_STREAM_CIPHER_CHACHA20:
|
||||
return psa_cipher_chacha20_decrypt(key_data, *key_bytes,
|
||||
input, input_length,
|
||||
output, output_size,
|
||||
output_length);
|
||||
#endif
|
||||
default:
|
||||
(void)slot;
|
||||
(void)input;
|
||||
|
@ -6,6 +6,7 @@ USEMODULE += ztimer_usec
|
||||
USEMODULE += psa_crypto
|
||||
|
||||
USEMODULE += psa_cipher
|
||||
USEMODULE += psa_cipher_chacha20
|
||||
USEMODULE += psa_cipher_aes_128_cbc
|
||||
|
||||
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=1
|
||||
|
@ -67,17 +67,20 @@ psa_status_t example_cipher_aes_128(void)
|
||||
|
||||
status = psa_import_key(&attr, KEY_128, AES_128_KEY_SIZE, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_destroy_key(key_id);
|
||||
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) {
|
||||
psa_destroy_key(key_id);
|
||||
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);
|
||||
psa_destroy_key(key_id);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return (memcmp(PLAINTEXT, plain_out, sizeof(plain_out)) ? -1 : 0);
|
||||
}
|
||||
|
83
tests/sys/psa_crypto_cipher/example_cipher_chacha20.c
Normal file
83
tests/sys/psa_crypto_cipher/example_cipher_chacha20.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2024 TU-Dresden
|
||||
*
|
||||
* 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 tests
|
||||
* @{
|
||||
*
|
||||
* @brief Tests the PSA cipher configurations
|
||||
* Contents have been copied from `examples/psa_crypto`
|
||||
*
|
||||
* @author Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
static const uint8_t KEY_CHACHA20[] = {
|
||||
0x90, 0x6f, 0xdc, 0xf1, 0x72, 0xe6, 0x8a, 0xd1, 0xbb, 0xd0, 0xa3, 0x24,
|
||||
0x2a, 0xda, 0x91, 0xdb, 0x3a, 0x8d, 0xb8, 0xd4, 0x9a, 0x75, 0xc7, 0x14,
|
||||
0x00, 0x08, 0x9a, 0x8b, 0x86, 0x55, 0x2e, 0x9a
|
||||
};
|
||||
|
||||
/* This cannot be const, as the Cryptocell hardware implementation does not have
|
||||
DMA access to flash storage, which contains the global const values */
|
||||
static uint8_t PLAINTEXT[] = {
|
||||
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x52, 0x49, 0x4F, 0x54, 0x21, 0x20,
|
||||
0x54, 0x68, 0x65, 0x20, 0x41, 0x6E, 0x73, 0x77, 0x65, 0x72, 0x20, 0x69,
|
||||
0x73, 0x20, 0x34, 0x32, 0x2E
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Example function to perform an CHACHA20 encryption and decryption
|
||||
* with the PSA Crypto API.
|
||||
*
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t example_cipher_chacha20(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 cipher_output_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_CHACHA20,
|
||||
PSA_ALG_STREAM_CIPHER, sizeof(PLAINTEXT));
|
||||
|
||||
uint8_t cipher_out[cipher_output_size];
|
||||
uint8_t plain_out[sizeof(PLAINTEXT)];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_STREAM_CIPHER);
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, 256);
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_CHACHA20);
|
||||
|
||||
status = psa_import_key(&attr, KEY_CHACHA20, sizeof(KEY_CHACHA20), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_destroy_key(key_id);
|
||||
return status;
|
||||
}
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_STREAM_CIPHER, PLAINTEXT,
|
||||
sizeof(PLAINTEXT), cipher_out, cipher_output_size, &output_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_destroy_key(key_id);
|
||||
return status;
|
||||
}
|
||||
status = psa_cipher_decrypt(key_id, PSA_ALG_STREAM_CIPHER, cipher_out,
|
||||
sizeof(cipher_out), plain_out, sizeof(plain_out), &output_len);
|
||||
psa_destroy_key(key_id);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return (memcmp(PLAINTEXT, plain_out, sizeof(plain_out)) ? -1 : 0);
|
||||
}
|
||||
return status;
|
||||
}
|
@ -23,6 +23,7 @@
|
||||
#include "ztimer.h"
|
||||
|
||||
extern psa_status_t example_cipher_aes_128(void);
|
||||
extern psa_status_t example_cipher_chacha20(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@ -42,6 +43,14 @@ int main(void)
|
||||
printf("Cipher AES 128 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_cipher_chacha20();
|
||||
printf("Cipher CHACHA20 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
failed = true;
|
||||
printf("Cipher CHACHA20 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
ztimer_release(ZTIMER_USEC);
|
||||
|
||||
if (failed) {
|
||||
|
Loading…
Reference in New Issue
Block a user