1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #20854 from netd-tud/psa-headers

Various PSA Crypto fixes
This commit is contained in:
mguetschow 2024-09-18 08:10:44 +00:00 committed by GitHub
commit 5d958957be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 342 additions and 124 deletions

View File

@ -367,7 +367,24 @@ extern "C" {
* recognized, return 0. An implementation can return either 0 or the correct size for a
* hash algorithm that it recognizes, but does not support.
*/
#define PSA_HASH_BLOCK_LENGTH(alg) /* implementation-defined value */
#define PSA_HASH_BLOCK_LENGTH(alg) \
( \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72 : \
0)
/**
* @brief The size of the output of @ref psa_hash_compute() and @ref psa_hash_finish(), in bytes.
@ -439,7 +456,30 @@ extern "C" {
*
* See also @ref PSA_MAC_LENGTH().
*/
#define PSA_MAC_MAX_SIZE (PSA_HASH_MAX_SIZE)
#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA_512) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_512))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_512)) /* 64 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_384) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_384))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_384)) /* 48 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_256) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_256))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_256)) /* 32 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_224) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA3_224))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_224)) /* 28 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_RIPEMD160) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_1))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA_1)) /* 20 */
#elif (IS_USED(MODULE_PSA_MAC_HMAC_MD2) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD4) || \
IS_USED(MODULE_PSA_MAC_HMAC_MD5))
#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_MD5)) /* 16 */
#else
#define PSA_MAC_MAX_SIZE 0
#endif
/**
* @brief The block size of a block cipher.

View File

@ -26,6 +26,8 @@ extern "C" {
#include <stdint.h>
#include "psa/error.h"
/**
* @brief For encrypt-decrypt functions, whether the operation is an encryption
* or a decryption.
@ -319,15 +321,6 @@ typedef struct psa_aead_operation_s psa_aead_operation_t;
*/
typedef struct psa_mac_operation_s psa_mac_operation_t;
/**
* @brief Function return status.
*
* @details This is either @ref PSA_SUCCESS, which is zero, indicating success; or a small
* negative value indicating that an error occurred. Errors are encoded as one of
* the @c PSA_ERROR_xxx values defined here.
*/
typedef int32_t psa_status_t;
/**
* @brief The type of the state data structure for multipart hash operations.
*

View File

@ -3354,118 +3354,6 @@ extern "C" {
*/
#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE /* implementation-defined value */
/**
* @brief The action was completed successfully.
*/
#define PSA_SUCCESS ((psa_status_t)0)
/**
* @brief An error occurred that does not correspond to any defined failure cause.
*/
#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
/**
* @brief The requested operation or a parameter is not supported by this implementation.
*/
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
/**
* @brief The requested action is denied by a policy.
*/
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
/**
* @brief An output buffer is too small.
*/
#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
/**
* @brief Asking for an item that already exists.
*/
#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
/**
* @brief Asking for an item that doesnt exist.
*/
#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
/**
* @brief The requested action cannot be performed in the current state.
*/
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
/**
* @brief The parameters passed to the function are invalid.
*/
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
/**
* @brief There is not enough runtime memory.
*/
#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
/**
* @brief There is not enough persistent storage.
*/
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
/**
* @brief There was a communication failure inside the implementation.
*/
#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
/**
* @brief There was a storage failure that might have led to data loss.
*/
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
/**
* @brief Stored data has been corrupted.
*/
#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
/**
* @brief Data read from storage is not valid for the implementation.
*/
#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153)
/**
* @brief A hardware failure was detected.
*/
#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
/**
* @brief A tampering attempt was detected.
*/
#define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151)
/**
* @brief There is not enough entropy to generate random data needed
* for the requested action.
*/
#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)-148)
/**
* @brief The signature, MAC or hash is incorrect.
*/
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
/**
* @brief The decrypted padding is incorrect.
*/
#define PSA_ERROR_INVALID_PADDING ((psa_status_t)-150)
/**
* @brief Return this error when theres insufficient data when
* attempting to read from a resource.
*/
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
/**
* @brief The key identifier is not valid.
*/
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,216 @@
/*
* Copyright (C) 2024 TU Dresden
* Copyright (C) 2021 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 sys_psa_crypto
* @{
*
* @file error.h
* @brief Error definitions for the PSA Crypto API
*
* @details This header file is also compatible with the PSA Certified Status code API.
*
* @author Armin Wolf <wolf.armin@mailbox.tu-dresden.de>
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
*/
#ifndef PSA_CRYPTO_PSA_ERROR_H
#define PSA_CRYPTO_PSA_ERROR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @brief Status code type used for all PSA Certified APIs.
*
* @details This is either @ref PSA_SUCCESS, which is zero, indicating success; or a small
* negative value indicating that an error occurred. Errors are encoded as one of
* the @c PSA_ERROR_xxx values defined here.
*/
#ifndef PSA_SUCCESS
typedef int32_t psa_status_t;
#endif
/**
* @brief Status code to indicate general success.
*/
#define PSA_SUCCESS ((psa_status_t)0)
/**
* @brief Status code that indicates a programmer error in the client.
*/
#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t)-129)
/**
* @brief Status code that indicates that the caller is not permitted to connect to a Service.
*/
#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t)-130)
/**
* @brief Status code that indicates that the caller cannot connect to a service.
*/
#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t)-131)
/**
* @brief Status code that indicates an error that does not correspond to any defined
* failure cause.
*/
#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
/**
* @brief Status code that indicates that the requested action is denied by a policy.
*/
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
/**
* @brief Status code that indicates that the requested operation or a parameter is not supported.
*/
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
/**
* @brief Status code that indicates that the parameters passed to the function are invalid.
*/
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
/**
* @brief Status code that indicates that a handle parameter is not valid.
*
* @details Usually means that a key identifier does not refer to an existing key.
*/
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
/**
* @brief Status code that indicates that the requested action cannot be performed in the
* current state.
*
* @details Multi-part operations return this error when one of the functions is called out
* of sequence. We also return this error if the caller has not initialized the library
* by a call to @ref psa_crypto_init().
*/
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
/**
* @brief Status code that indicates that an output buffer parameter is too small.
*
* @details Applications can call the @c PSA_xxx_SIZE macros listed in the function description to
* determine a sufficient buffer size.
*/
#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
/**
* @brief Status code that indicates that an identifier or index is already in use.
*/
#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
/**
* @brief Status code that indicates that an identified resource does not exist.
*/
#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
/**
* @brief Status code that indicates that there is not enough runtime memory.
*/
#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
/**
* @brief Status code that indicates that there is not enough persistent storage.
*/
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
/**
* @brief Status code that indicates that a data source has insufficient capacity left.
*/
#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
/**
* @brief Status code that indicates an error within the service.
*/
#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144)
/**
* @brief Status code that indicates a communication failure between the function and another
* service or component.
*/
#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
/**
* @brief Status code that indicates a storage failure that may have led to data loss.
*
* @details When a storage failure occurs, it is no longer possible to ensure the global
* integrity of the keystore. Access to other data might fail even if the data
* is still readable but its integrity cannot be guaranteed.
*/
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
/**
* @brief Status code that indicates that a hardware failure was detected.
*/
#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
/**
* @brief Status code that indicates that there is not enough entropy to generate random data
* needed for the requested action.
*/
#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)-148)
/**
* @brief Status code that indicates that a signature, MAC or hash is incorrect.
*/
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
/**
* @brief Status code that indicates that the decrypted padding is incorrect.
*/
#define PSA_ERROR_INVALID_PADDING ((psa_status_t)-150)
/**
* @brief Status code that indicates that internal data has been tampered with.
*
* @details This error code is intended as a last resort when a security breach is detected
* and it is unsure whether the keystore data is still protected. Only return this
* error code to report an alarm from a tampering detector, to indicate that the
* confidentiality of stored data can no longer be guaranteed, or to indicate that
* the integrity of previously returned data is now considered compromised.
*/
#define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151)
/**
* @brief Status code that indicates that stored data has been corrupted.
*
* @details When a storage failure occurs, it is no longer possible to ensure the global integrity
* of the keystore. Depending on the global integrity guarantees, access to other data
* might fail even if the data is still readable but its integrity cannot be guaranteed.
*/
#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
/**
* @brief Status code that indicates that data read from storage is not valid for the
* implementation.
*/
#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153)
/**
* @brief Status code that indicates that the requested operation is interruptible, and still
* has work to do.
*
* @details This status code does not mean that the operation has failed or that it has succeeded.
* The operation must be repeated until it completes with either success or failure.
*/
#define PSA_OPERATION_INCOMPLETE ((psa_status_t)-248)
#ifdef __cplusplus
}
#endif
#endif /* PSA_CRYPTO_PSA_ERROR_H */
/** @} */

View File

@ -12,7 +12,8 @@
* About {#About}
* =====
* This module implements the PSA Cryptography API Version 1.1 as specified
* [here](https://armmbed.github.io/mbed-crypto/html/).
* [here](https://armmbed.github.io/mbed-crypto/html/) and the PSA Status code API Version 1.0
* as specified [here](https://arm-software.github.io/psa-api/status-code/1.0/).
* It provides an OS level access to cryptographic operations and supports software and hardware
* backends as well as the use of secure elements.
* The API automatically builds a hardware backend for an operation, if there's one available,

View File

@ -1133,6 +1133,15 @@ static psa_status_t psa_start_key_creation(psa_key_creation_method_t method,
slot = *p_slot;
slot->attr = *attributes;
/* See 9.5.2. Key usage flags */
if (slot->attr.policy.usage & PSA_KEY_USAGE_SIGN_HASH) {
slot->attr.policy.usage |= PSA_KEY_USAGE_SIGN_MESSAGE;
}
if (slot->attr.policy.usage & PSA_KEY_USAGE_VERIFY_HASH) {
slot->attr.policy.usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
}
if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
slot->attr.id = key_id;
}

View File

@ -111,6 +111,75 @@ cleanup:
TEST_ASSERT_PSA_CONTINUE(psa_hash_abort(&op2));
}
/**
* Importing keys with the usage flags PSA_KEY_USAGE_SIGN_HASH/PSA_KEY_USAGE_VERIFY_HASH
* should automatically set the usage flags PSA_KEY_USAGE_SIGN_MESSAGE/PSA_KEY_USAGE_VERIFY_MESSAGE
* on the key.
*/
static void test_key_import_usage_flags(void)
{
psa_key_attributes_t attributes = psa_key_attributes_init();
psa_key_attributes_t key_attrs;
const uint8_t key[32] = { 0 };
psa_key_usage_t key_usage;
psa_key_id_t key_id;
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_512));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(sizeof(key)));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
TEST_ASSERT_PSA_RETURN(psa_crypto_init());
TEST_ASSERT_PSA_RETURN(psa_import_key(&attributes, key, sizeof(key), &key_id));
TEST_ASSERT_PSA_CLEANUP(psa_get_key_attributes(key_id, &key_attrs));
key_usage = psa_get_key_usage_flags(&key_attrs);
TEST_ASSERT_PSA_RETURN(psa_destroy_key(key_id));
TEST_ASSERT(key_usage & PSA_KEY_USAGE_SIGN_MESSAGE);
TEST_ASSERT(key_usage & PSA_KEY_USAGE_VERIFY_MESSAGE);
return;
cleanup:
TEST_ASSERT_PSA_CONTINUE(psa_destroy_key(key_id));
}
/**
* Generating keys with the usage flags PSA_KEY_USAGE_SIGN_HASH/PSA_KEY_USAGE_VERIFY_HASH
* should automatically set the usage flags PSA_KEY_USAGE_SIGN_MESSAGE/PSA_KEY_USAGE_VERIFY_MESSAGE
* on the key.
*/
static void test_key_generate_usage_flags(void)
{
psa_key_attributes_t attributes = psa_key_attributes_init();
psa_key_attributes_t key_attrs;
psa_key_usage_t key_usage;
psa_key_id_t key_id;
psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_512));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(32));
psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
TEST_ASSERT_PSA_RETURN(psa_crypto_init());
TEST_ASSERT_PSA_RETURN(psa_generate_key(&attributes, &key_id));
TEST_ASSERT_PSA_CLEANUP(psa_get_key_attributes(key_id, &key_attrs));
key_usage = psa_get_key_usage_flags(&key_attrs);
TEST_ASSERT_PSA_RETURN(psa_destroy_key(key_id));
TEST_ASSERT(key_usage & PSA_KEY_USAGE_SIGN_MESSAGE);
TEST_ASSERT(key_usage & PSA_KEY_USAGE_VERIFY_MESSAGE);
return;
cleanup:
TEST_ASSERT_PSA_CONTINUE(psa_destroy_key(key_id));
}
/**
* Exporting and re-importing a private Ed25519 key should result in the same public key and signature.
*/
@ -227,6 +296,8 @@ static Test *tests_psa_crypto(void)
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_init_twice),
new_TestFixture(test_hash_interleaved),
new_TestFixture(test_key_import_usage_flags),
new_TestFixture(test_key_generate_usage_flags),
new_TestFixture(test_exported_key_is_identical_when_imported_again_ed25519),
new_TestFixture(test_export_public_key_ed25519),
};