430 lines
22 KiB
C
430 lines
22 KiB
C
/***************************************************************************//**
|
|
* @file
|
|
* @brief This file implements abstracting the PSA CRYPTO interface.
|
|
*******************************************************************************
|
|
* # License
|
|
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
|
*******************************************************************************
|
|
*
|
|
* The licensor of this software is Silicon Laboratories Inc. Your use of this
|
|
* software is governed by the terms of Silicon Labs Master Software License
|
|
* Agreement (MSLA) available at
|
|
* www.silabs.com/about-us/legal/master-software-license-agreement. This
|
|
* software is distributed to you in Source Code format and is governed by the
|
|
* sections of the MSLA applicable to Source Code.
|
|
*
|
|
******************************************************************************/
|
|
|
|
#ifndef SECURITY_MANAGER_H_
|
|
#define SECURITY_MANAGER_H_
|
|
|
|
#include <psa/crypto_types.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include "psa/crypto.h"
|
|
#include "psa/crypto_values.h"
|
|
|
|
/**
|
|
* Import a key into PSA ITS.
|
|
*
|
|
* The caller must Provide a valid key.
|
|
*
|
|
* Based on the parameters passed, the security manager will choose the storage location.
|
|
* For persistent keys, key_id is managed by the application, and for volatiles keys,
|
|
* PSA will create a key_id and returns the same to the application. All the keys will be wrapped
|
|
* before storage and the key_id is further used for all the security operations.
|
|
*
|
|
* @param[out] sl_psa_key_id Pointer to Key Id to be used for persistent keys. If the key is stored
|
|
* in RAM, PSA will allocate the key ID and pass it to the application. For
|
|
* non-volatile keys, key ID provided by application will be assigned as the reference.
|
|
* @param[in] sl_psa_key_type Key type encoding for the key.
|
|
* @param[in] sl_psa_key_algorithm Key algorithm encoding for the key.
|
|
* @param[in] sl_psa_key_usage Key Usage encoding for the key.
|
|
* @param[in] sl_psa_key_persistence What persistence level needs to be applied to the key.
|
|
* @param[in] sl_psa_key_literal Pointer to the actual key.
|
|
* @param[in] sl_key_literal_len Length of the key.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_import_key(psa_key_id_t * sl_psa_key_id,
|
|
psa_key_type_t sl_psa_key_type,
|
|
psa_algorithm_t sl_psa_key_algorithm,
|
|
psa_key_usage_t sl_psa_key_usage,
|
|
psa_key_persistence_t sl_psa_key_persistence,
|
|
const uint8_t * sl_psa_key_literal,
|
|
size_t sl_key_literal_len);
|
|
|
|
/**
|
|
* Generates a key and stores the same in PSA.
|
|
*
|
|
* Based on the parameters passed, the security manager will choose the storage location.
|
|
* For persistent keys, key_id is managed by the application, and for volatiles keys,
|
|
* PSA will create a key_id and returns the same to the application. All the keys will be wrapped
|
|
* before storage and the key_id is further used for all the security operations.
|
|
*
|
|
* @param[out] sl_psa_key_id Pointer to Key Id to be used for persistent keys. If the key is stored
|
|
* in RAM, PSA will allocate the key ID and pass it to the application. For
|
|
* non-volatile keys, key ID provided by application will be assigned as the reference.
|
|
* @param[in] sl_psa_key_type Key type encoding for the key.
|
|
* @param[in] sl_psa_key_algorithm Key algorithm encoding for the key.
|
|
* @param[in] sl_psa_key_usage Key Usage encoding for the key.
|
|
* @param[in] sl_psa_key_persistence What persistence level needs to be applied to the key.
|
|
* @param[in] sl_psa_key_len Length of the key.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_generate_key(psa_key_id_t * sl_psa_key_id,
|
|
psa_key_type_t sl_psa_key_type,
|
|
psa_algorithm_t sl_psa_key_algorithm,
|
|
psa_key_usage_t sl_psa_key_usage,
|
|
psa_key_persistence_t sl_psa_key_persistence,
|
|
size_t sl_psa_key_len);
|
|
|
|
/**
|
|
* Export a key from PSA ITS.
|
|
*
|
|
* This API can be used to export the key stored in the PSA. Only keys marked as exportable can be
|
|
* read back from the storage as plaintext.
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key. This is either passed to import key,
|
|
* for persistent keys, or returned to the application in the key context, for
|
|
* volatile keys.
|
|
* @param[in] sl_psa_key_buffer Pointer to the buffer to store the key.
|
|
* @param[in] sl_psa_key_buffer_len Length of the buffer.
|
|
* @param[out] sl_psa_key_len Length of the exported key.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_export_key(psa_key_id_t sl_psa_key_id,
|
|
uint8_t * sl_psa_key_buffer,
|
|
size_t sl_psa_key_buffer_len,
|
|
size_t * sl_psa_key_len);
|
|
|
|
/**
|
|
* Get attributes for a key stored in PSA ITS.
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key.
|
|
* @param[out] sl_psa_key_attributes output pointer for key attributes.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_get_key_attributes(psa_key_id_t sl_psa_key_id,
|
|
psa_key_attributes_t *sl_psa_key_attributes);
|
|
|
|
/**
|
|
* Destroy a key stored in PSA ITS.
|
|
*
|
|
* This API can be used to dispose a stored key from PSA.
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_destroy_key(psa_key_id_t sl_psa_key_id);
|
|
|
|
/**
|
|
* Make a copy a key stored in the ITS.
|
|
*
|
|
* This API can be used to make copies of a key in ITS.
|
|
* This API can also be used to change the key attributes of a existing key.
|
|
*
|
|
* If the source and destination key ids are the same, a copy of the original
|
|
* key will be made with new additional attributes.
|
|
*
|
|
* If the source and destination keyids are different, a copy of source key is
|
|
* made, and new attributes additional attributes, and the keyId of new key will
|
|
* be returned.
|
|
*
|
|
* @note /ref psa_copy_key() only supports unwrapped source keys.
|
|
* This API will fail if the sl_psa_source_key_id is wrapped.
|
|
* @note There are restrictions on what attributes can be changed. Refer to /ref psa_copy_key()
|
|
*
|
|
* @param[in] sl_psa_source_key_id Key ID of the source key.
|
|
* @param[in] sl_psa_key_attributes New key attributes to be added.
|
|
* @param[inout] sl_psa_dest_key_id KeyId for new key.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_copy_key(psa_key_id_t sl_psa_source_key_id,
|
|
psa_key_attributes_t *sl_psa_key_attributes,
|
|
psa_key_id_t *sl_psa_dest_key_id);
|
|
|
|
/**
|
|
* API to encrypt or decrypt data using AES ECB.
|
|
*
|
|
* This API can be used to perform AES ECB on given data. The user will have to
|
|
* pass a valid key reference in the form of a key_id to the API.
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key.
|
|
* @param[in] sl_psa_aes_alg AES Algorithm to use.
|
|
* @param[in] sl_psa_aes_input Pointer to the data to be encrypted or decrypted.
|
|
* @param[out] sl_psa_aes_output Pointer to buffer to hold the output data.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_aes_encrypt(psa_key_id_t sl_psa_key_id,
|
|
psa_algorithm_t sl_psa_aes_alg,
|
|
const uint8_t* sl_psa_aes_input,
|
|
uint8_t* sl_psa_aes_output);
|
|
|
|
psa_status_t sl_sec_man_aes_decrypt(psa_key_id_t sl_psa_key_id,
|
|
psa_algorithm_t sl_psa_aes_alg,
|
|
const uint8_t* sl_psa_aes_input,
|
|
uint8_t* sl_psa_aes_output);
|
|
|
|
/**
|
|
* API to encrypt data using AES-CCM*.
|
|
*
|
|
* This API can be used to perform AES-CCM* operations on given data which is in packet format.
|
|
* (Authentication data is followed by the data to be encrypted/decrypted, with a MIC
|
|
* located after the encryption data)
|
|
* @note returns an error if given invalid psa key id
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key.
|
|
* @param[in] nonce Nonce value to use in the CCM* operation.
|
|
* @param[in] encrypt Function mode. False for authenticated decryption,
|
|
true otherwise.
|
|
* @param[in] input Pointer to the packet to be encrypted.
|
|
* @param[in] encryption_start_index Index where the data to be encrypted begins, equal to
|
|
* the length of the authenticated data.
|
|
* @param[in] length Total combined length of authenticated and encrypted data.
|
|
* @param[in] mic_length Length of the MIC to be output after the encrypted data.
|
|
* This must be consistent with what the referenced key
|
|
* permits for its encryption algorithm.
|
|
* @param[out] output Pointer to buffer to hold the output packet.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_aes_ccm_crypt(psa_key_id_t sl_psa_key_id,
|
|
uint8_t* nonce,
|
|
bool encrypt,
|
|
const uint8_t* input,
|
|
uint8_t encryption_start_index,
|
|
uint8_t length,
|
|
uint8_t mic_length,
|
|
uint8_t* output);
|
|
|
|
/**
|
|
* Start the HMAC operation.
|
|
*
|
|
* @param[in] sl_psa_hmac_ctx Operation Context for HMAC operation.
|
|
* @param[out] sl_psa_key_id Reference to the key to be used for HMAC operation.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_hmac_start(psa_mac_operation_t *sl_psa_hmac_ctx, psa_key_id_t sl_psa_key_id);
|
|
|
|
/**
|
|
* Update the HMAC operation with new input.
|
|
*
|
|
* @param[in] sl_psa_hmac_ctx Operation Context for HMAC operation.
|
|
* @param[out] sl_psa_hmac_buffer A pointer to the input buffer.
|
|
* @param[in] sl_psa_hmac_buffer_len The length of @p sl_psa_hmac_buffer in bytes.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_hmac_update(psa_mac_operation_t *sl_psa_hmac_ctx,
|
|
const uint8_t * sl_psa_hmac_buffer,
|
|
size_t sl_psa_hmac_buffer_len);
|
|
|
|
/**
|
|
* Complete the HMAC operation.
|
|
*
|
|
* @param[in] sl_psa_hmac_ctx Operation Context for HMAC operation.
|
|
* @param[out] sl_psa_hmac_buffer A pointer to the output buffer.
|
|
* @param[in] sl_psa_hmac_buffer_len The length of @p sl_psa_hmac_buffer in bytes.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_hmac_finish(psa_mac_operation_t *sl_psa_hmac_ctx,
|
|
const uint8_t * sl_psa_hmac_buffer,
|
|
size_t sl_psa_hmac_buffer_len);
|
|
|
|
/**
|
|
* Uninitialize the HMAC operation.
|
|
*
|
|
* @param[in] sl_psa_hmac_ctx Operation Context for HMAC operation.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_hmac_deinit(psa_mac_operation_t *sl_psa_hmac_ctx);
|
|
|
|
/**
|
|
* Perform HKDF Extract step.
|
|
*
|
|
* @param[in] sl_psa_key_derivation_ctx Operation context for key derivation operation.
|
|
* @param[in] sl_psa_key_derivation_algorithm Algorithm being used for key derivation.
|
|
* @param[in] sl_psa_key_id Reference to key stored in PSA ITS.
|
|
* @param[in] sl_psa_key_derivation_salt Pointer to the Salt for key derivation.
|
|
* @param[in] sl_psa_key_derivation_salt_length Length of Salt.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_key_derivation_extract(psa_key_derivation_operation_t *sl_psa_key_derivation_ctx,
|
|
psa_algorithm_t sl_psa_key_derivation_algorithm,
|
|
psa_key_id_t sl_psa_key_id,
|
|
const uint8_t * sl_psa_key_derivation_salt,
|
|
uint16_t sl_psa_key_derivation_salt_length);
|
|
|
|
/**
|
|
* Perform HKDF Expand step.
|
|
*
|
|
* @param[in] sl_psa_key_derivation_ctx Operation context for HKDF operation.
|
|
* @param[in] sl_psa_key_derivation_info Pointer to the Info sequence.
|
|
* @param[in] sl_psa_key_derivation_info_length Length of the Info sequence.
|
|
* @param[out] sl_psa_key_derivation_output_key Pointer to the output Key.
|
|
* @param[in] sl_psa_key_derivation_output_key_len Size of the output key buffer.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_key_derivation_expand(psa_key_derivation_operation_t *sl_psa_key_derivation_ctx,
|
|
const uint8_t * sl_psa_key_derivation_info,
|
|
uint16_t sl_psa_key_derivation_info_length,
|
|
uint8_t * sl_psa_key_derivation_output_key,
|
|
uint16_t sl_psa_key_derivation_output_key_len);
|
|
|
|
/**
|
|
* Initialise the hashing operation.
|
|
*
|
|
* @param[in] sl_psa_hash_ctx Context for hashing operation.
|
|
*
|
|
* @retval Initial value for a hash operation object.
|
|
*/
|
|
psa_hash_operation_t sl_sec_man_hash_init(void);
|
|
|
|
/**
|
|
* De-Initialise the hashing operation.
|
|
*
|
|
* @param[in] sl_psa_hash_ctx Context for hashing operation.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*/
|
|
psa_status_t sl_sec_man_hash_deinit(psa_hash_operation_t *sl_psa_hash_ctx);
|
|
|
|
/**
|
|
* Start SHA-256 operation.
|
|
*
|
|
* @param[in] sl_psa_hash_ctx Context for hashing operation.
|
|
* @param[in] sl_psa_hash_alg Hashing algorithm to use.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_hash_start(psa_hash_operation_t *sl_psa_hash_ctx, psa_algorithm_t sl_psa_hash_alg);
|
|
|
|
/**
|
|
* Update hashing operation with new input.
|
|
*
|
|
* @param[in] sl_psa_hash_ctx Context for hashing operation.
|
|
* @param[out] sl_psa_hash_buffer A pointer to the input buffer.
|
|
* @param[in] sl_psa_hash_buffer_len The length of @p sl_psa_hash_buffer in bytes.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*/
|
|
psa_status_t sl_sec_man_hash_update(psa_hash_operation_t *sl_psa_hash_ctx,
|
|
uint8_t * sl_psa_hash_buffer,
|
|
uint16_t sl_psa_hash_buffer_len);
|
|
|
|
/**
|
|
* Finish hashing operation.
|
|
*
|
|
* @param[in] sl_psa_hash_ctx Context for hashing operation.
|
|
* @param[in] sl_psa_hash_hash A pointer to the output buffer, where hash needs to be stored.
|
|
* @param[in] sl_psa_hash_hash_size The length of @p sl_psa_hash_hash in bytes.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*/
|
|
psa_status_t sl_sec_man_hash_finish(psa_hash_operation_t *sl_psa_hash_ctx,
|
|
uint8_t * sl_psa_hash,
|
|
uint16_t sl_psa_hash_size,
|
|
size_t * sl_psa_hash_len);
|
|
|
|
/**
|
|
* Generate Entropy.
|
|
*
|
|
* @param[in] sl_psa_output_buffer Buffer to store the generated entropy.
|
|
* @param[in] sl_psa_output_size Amount of entropy needed in bytes.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_get_random(uint8_t *sl_psa_output_buffer,
|
|
uint16_t sl_psa_output_size);
|
|
|
|
/**
|
|
* Export the public key from the key pair.
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key.
|
|
* @param[out] sl_psa_output_buffer A pointer to the output buffer to store the public key.
|
|
* @param[in] sl_output_buffer_size The length of @p sl_psa_output_buffer in bytes.
|
|
* @param[out] sl_public_key_len A pointer to a variable to store length of the exported public key.
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_export_public_key(psa_key_id_t sl_psa_key_id,
|
|
uint8_t *sl_psa_output_buffer,
|
|
size_t sl_output_buffer_size,
|
|
size_t *sl_public_key_len);
|
|
|
|
/**
|
|
* Sign the given input buffer using the algorithm specified.
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key.
|
|
* @param[in] sl_dsa_algorithm DSA Algorithm to use to perform ECDSA sign operation.
|
|
* @param[in] sl_dsa_input_buf A pointer to the input buffer.
|
|
* @param[in] sl_dsa_input_size The length of @p sl_dsa_input_buf in bytes.
|
|
* @param[out] sl_dsa_signature_buf A pointer to the output buffer to store the signature.
|
|
* @param[in] sl_dsa_signature_size The length of @p sl_dsa_signature_buf in bytes.
|
|
* @param[out] sl_dsa_signature_len A pointer to a variable to store length of the generated signature.
|
|
* @param[in] sl_is_hash Is the input a message hash?
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*
|
|
*/
|
|
psa_status_t sl_sec_man_sign(psa_key_id_t sl_psa_key_id,
|
|
psa_algorithm_t sl_dsa_algorithm,
|
|
const uint8_t *sl_dsa_input_buf,
|
|
size_t sl_dsa_input_size,
|
|
uint8_t *sl_dsa_signature_buf,
|
|
size_t sl_dsa_signature_size,
|
|
size_t *sl_dsa_signature_len,
|
|
bool sl_is_hash);
|
|
|
|
/**
|
|
* Verify the given signature using the algorithm specified.
|
|
*
|
|
* @param[in] sl_psa_key_id Key ID used as a reference to the key.
|
|
* @param[in] sl_dsa_algorithm DSA Algorithm to use to perform ECDSA verify operation.
|
|
* @param[in] sl_dsa_input_buf A pointer to the input buffer.
|
|
* @param[in] sl_dsa_input_size The length of @p sl_dsa_input_buf in bytes.
|
|
* @param[in] sl_dsa_signature_buf A pointer to the input buffer to store the signature.
|
|
* @param[in] sl_dsa_signature_size The length of @p sl_dsa_signature_buf in bytes.
|
|
* @param[in] sl_is_hash Is the input a message hash?
|
|
*
|
|
* @retval A psa_status_t status code. Refer to /ref psa_status_t.
|
|
*/
|
|
psa_status_t sl_sec_man_verify(psa_key_id_t sl_psa_key_id,
|
|
psa_algorithm_t sl_dsa_algorithm,
|
|
const uint8_t *sl_dsa_input_buf,
|
|
size_t sl_dsa_input_size,
|
|
const uint8_t *sl_dsa_signature_buf,
|
|
size_t sl_dsa_signature_size,
|
|
bool sl_is_hash);
|
|
|
|
#endif /* SECURITY_MANAGER_H_ */
|