blob: 7cadc8e793fbac70a9e363139a349e53027ea156 [file] [log] [blame]
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file includes the platform abstraction for Crypto operations.
*/
#ifndef OPENTHREAD_PLATFORM_CRYPTO_H_
#define OPENTHREAD_PLATFORM_CRYPTO_H_
#include <stdint.h>
#include <stdlib.h>
#include <openthread/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup plat-crypto
*
* @brief
* This module includes the platform abstraction for Crypto.
*
* @{
*
*/
/**
* This enumeration defines the key types.
*
*/
typedef enum
{
OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data.
OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES.
OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
} otCryptoKeyType;
/**
* This enumeration defines the key algorithms.
*
*/
typedef enum
{
OT_CRYPTO_KEY_ALG_VENDOR, ///< Key Algorithm: Vendor Defined.
OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB.
OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
} otCryptoKeyAlgorithm;
/**
* This enumeration defines the key usage flags.
*
*/
enum
{
OT_CRYPTO_KEY_USAGE_NONE = 0, ///< Key Usage: Key Usage is empty.
OT_CRYPTO_KEY_USAGE_EXPORT = 1 << 0, ///< Key Usage: Key can be exported.
OT_CRYPTO_KEY_USAGE_ENCRYPT = 1 << 1, ///< Key Usage: Encryption (vendor defined).
OT_CRYPTO_KEY_USAGE_DECRYPT = 1 << 2, ///< Key Usage: AES ECB.
OT_CRYPTO_KEY_USAGE_SIGN_HASH = 1 << 3, ///< Key Usage: HMAC SHA-256.
};
/**
* This enumeration defines the key storage types.
*
*/
typedef enum
{
OT_CRYPTO_KEY_STORAGE_VOLATILE, ///< Key Persistence: Key is volatile.
OT_CRYPTO_KEY_STORAGE_PERSISTENT, ///< Key Persistence: Key is persistent.
} otCryptoKeyStorage;
/**
* This datatype represents the key reference.
*
*/
typedef uint32_t otCryptoKeyRef;
/**
* @struct otCryptoKey
*
* This structure represents the Key Material required for Crypto operations.
*
*/
typedef struct otCryptoKey
{
const uint8_t *mKey; ///< Pointer to the buffer containing key. NULL indicates to use `mKeyRef`.
uint16_t mKeyLength; ///< The key length in bytes (applicable when `mKey` is not NULL).
uint32_t mKeyRef; ///< The PSA key ref (requires `mKey` to be NULL).
} otCryptoKey;
/**
* @struct otCryptoContext
*
* This structure stores the context object for platform APIs.
*
*/
typedef struct otCryptoContext
{
void * mContext; ///< Pointer to the context.
uint16_t mContextSize; ///< The length of the context in bytes.
} otCryptoContext;
/**
* Initialize the Crypto module.
*
*/
void otPlatCryptoInit(void);
/**
* Import a key into PSA ITS.
*
* @param[in,out] aKeyRef Pointer to the key ref to be used for crypto operations.
* @param[in] aKeyType Key Type encoding for the key.
* @param[in] aKeyAlgorithm Key algorithm encoding for the key.
* @param[in] aKeyUsage Key Usage encoding for the key (combinations of `OT_CRYPTO_KEY_USAGE_*`).
* @param[in] aKeyPersistence Key Persistence for this key
* @param[in] aKey Actual key to be imported.
* @param[in] aKeyLen Length of the key to be imported.
*
* @retval OT_ERROR_NONE Successfully imported the key.
* @retval OT_ERROR_FAILED Failed to import the key.
* @retval OT_ERROR_INVALID_ARGS @p aKey was set to NULL.
*
* @note If OT_CRYPTO_KEY_STORAGE_PERSISTENT is passed for aKeyPersistence then @p aKeyRef is input and platform
* should use the given aKeyRef and MUST not change it.
*
* If OT_CRYPTO_KEY_STORAGE_VOLATILE is passed for aKeyPersistence then @p aKeyRef is output, the initial
* value does not matter and platform API MUST update it to return the new key ref.
*
* This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
otError otPlatCryptoImportKey(otCryptoKeyRef * aKeyRef,
otCryptoKeyType aKeyType,
otCryptoKeyAlgorithm aKeyAlgorithm,
int aKeyUsage,
otCryptoKeyStorage aKeyPersistence,
const uint8_t * aKey,
size_t aKeyLen);
/**
* Export a key stored in PSA ITS.
*
* @param[in] aKeyRef The key ref to be used for crypto operations.
* @param[out] aBuffer Pointer to the buffer where key needs to be exported.
* @param[in] aBufferLen Length of the buffer passed to store the exported key.
* @param[out] aKeyLen Pointer to return the length of the exported key.
*
* @retval OT_ERROR_NONE Successfully exported @p aKeyRef.
* @retval OT_ERROR_FAILED Failed to export @p aKeyRef.
* @retval OT_ERROR_INVALID_ARGS @p aBuffer was NULL
*
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen);
/**
* Destroy a key stored in PSA ITS.
*
* @param[in] aKeyRef The key ref to be destroyed
*
* @retval OT_ERROR_NONE Successfully destroyed the key.
* @retval OT_ERROR_FAILED Failed to destroy the key.
*
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef);
/**
* Check if the key ref passed has an associated key in PSA ITS.
*
* @param[in] aKeyRef The Key Ref to check.
*
* @retval TRUE There is an associated key with @p aKeyRef.
* @retval FALSE There is no associated key with @p aKeyRef.
*
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef);
/**
* Initialize the HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
*
* @retval OT_ERROR_NONE Successfully initialized HMAC operation.
* @retval OT_ERROR_FAILED Failed to initialize HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note The platform driver shall point the context to the correct object such as psa_mac_operation_t or
* mbedtls_md_context_t.
*
*/
otError otPlatCryptoHmacSha256Init(otCryptoContext *aContext);
/**
* Uninitialize the HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
*
* @retval OT_ERROR_NONE Successfully uninitialized HMAC operation.
* @retval OT_ERROR_FAILED Failed to uninitialized HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
*/
otError otPlatCryptoHmacSha256Deinit(otCryptoContext *aContext);
/**
* Start HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
* @param[in] aKey Key material to be used for for HMAC operation.
*
* @retval OT_ERROR_NONE Successfully started HMAC operation.
* @retval OT_ERROR_FAILED Failed to start HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey was NULL
*
*/
otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey *aKey);
/**
* Update the HMAC operation with new input.
*
* @param[in] aContext Context for HMAC operation.
* @param[in] aBuf A pointer to the input buffer.
* @param[in] aBufLength The length of @p aBuf in bytes.
*
* @retval OT_ERROR_NONE Successfully updated HMAC with new input operation.
* @retval OT_ERROR_FAILED Failed to update HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL
*
*/
otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength);
/**
* Complete the HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
* @param[out] aBuf A pointer to the output buffer.
* @param[in] aBufLength The length of @p aBuf in bytes.
*
* @retval OT_ERROR_NONE Successfully completed HMAC operation.
* @retval OT_ERROR_FAILED Failed to complete HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL
*
*/
otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength);
/**
* Initialise the AES operation.
*
* @param[in] aContext Context for AES operation.
*
* @retval OT_ERROR_NONE Successfully Initialised AES operation.
* @retval OT_ERROR_FAILED Failed to Initialise AES operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
* @retval OT_ERROR_NO_BUFS Cannot allocate the context.
*
* @note The platform driver shall point the context to the correct object such as psa_key_id
* or mbedtls_aes_context_t.
*
*/
otError otPlatCryptoAesInit(otCryptoContext *aContext);
/**
* Set the key for AES operation.
*
* @param[in] aContext Context for AES operation.
* @param[out] aKey Key to use for AES operation.
*
* @retval OT_ERROR_NONE Successfully set the key for AES operation.
* @retval OT_ERROR_FAILED Failed to set the key for AES operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey was NULL
*
*/
otError otPlatCryptoAesSetKey(otCryptoContext *aContext, const otCryptoKey *aKey);
/**
* Encrypt the given data.
*
* @param[in] aContext Context for AES operation.
* @param[in] aInput Pointer to the input buffer.
* @param[in] aOutput Pointer to the output buffer.
*
* @retval OT_ERROR_NONE Successfully encrypted @p aInput.
* @retval OT_ERROR_FAILED Failed to encrypt @p aInput.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey or @p aOutput were NULL
*
*/
otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, uint8_t *aOutput);
/**
* Free the AES context.
*
* @param[in] aContext Context for AES operation.
*
* @retval OT_ERROR_NONE Successfully freed AES context.
* @retval OT_ERROR_FAILED Failed to free AES context.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
*/
otError otPlatCryptoAesFree(otCryptoContext *aContext);
/**
* Initialise the HKDF context.
*
* @param[in] aContext Context for HKDF operation.
*
* @retval OT_ERROR_NONE Successfully Initialised AES operation.
* @retval OT_ERROR_FAILED Failed to Initialise AES operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note The platform driver shall point the context to the correct object such as psa_key_derivation_operation_t
* or HmacSha256::Hash
*
*/
otError otPlatCryptoHkdfInit(otCryptoContext *aContext);
/**
* Perform HKDF Expand step.
*
* @param[in] aContext Operation context for HKDF operation.
* @param[in] aInfo Pointer to the Info sequence.
* @param[in] aInfoLength Length of the Info sequence.
* @param[out] aOutputKey Pointer to the output Key.
* @param[in] aOutputKeyLength Size of the output key buffer.
*
* @retval OT_ERROR_NONE HKDF Expand was successful.
* @retval OT_ERROR_FAILED HKDF Expand failed.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
*/
otError otPlatCryptoHkdfExpand(otCryptoContext *aContext,
const uint8_t * aInfo,
uint16_t aInfoLength,
uint8_t * aOutputKey,
uint16_t aOutputKeyLength);
/**
* Perform HKDF Extract step.
*
* @param[in] aContext Operation context for HKDF operation.
* @param[in] aSalt Pointer to the Salt for HKDF.
* @param[in] aSaltLength Length of Salt.
* @param[in] aInputKey Pointer to the input key.
*
* @retval OT_ERROR_NONE HKDF Extract was successful.
* @retval OT_ERROR_FAILED HKDF Extract failed.
*
*/
otError otPlatCryptoHkdfExtract(otCryptoContext * aContext,
const uint8_t * aSalt,
uint16_t aSaltLength,
const otCryptoKey *aInputKey);
/**
* Uninitialize the HKDF context.
*
* @param[in] aContext Context for HKDF operation.
*
* @retval OT_ERROR_NONE Successfully un-initialised HKDF operation.
* @retval OT_ERROR_FAILED Failed to un-initialised HKDF operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
*/
otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext);
/**
* Initialise the SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
*
* @retval OT_ERROR_NONE Successfully initialised SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to initialise SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
*
* @note The platform driver shall point the context to the correct object such as psa_hash_operation_t
* or mbedtls_sha256_context.
*/
otError otPlatCryptoSha256Init(otCryptoContext *aContext);
/**
* Uninitialize the SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
*
* @retval OT_ERROR_NONE Successfully un-initialised SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to un-initialised SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
*/
otError otPlatCryptoSha256Deinit(otCryptoContext *aContext);
/**
* Start SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
*
* @retval OT_ERROR_NONE Successfully started SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to start SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
*/
otError otPlatCryptoSha256Start(otCryptoContext *aContext);
/**
* Update SHA-256 operation with new input.
*
* @param[in] aContext Context for SHA-256 operation.
* @param[in] aBuf A pointer to the input buffer.
* @param[in] aBufLength The length of @p aBuf in bytes.
*
* @retval OT_ERROR_NONE Successfully updated SHA-256 with new input operation.
* @retval OT_ERROR_FAILED Failed to update SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL
*
*/
otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength);
/**
* Finish SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
* @param[in] aHash A pointer to the output buffer, where hash needs to be stored.
* @param[in] aHashSize The length of @p aHash in bytes.
*
* @retval OT_ERROR_NONE Successfully completed the SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to complete SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aHash was NULL
*
*/
otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize);
/**
* Initialize cryptographically-secure pseudorandom number generator (CSPRNG).
*
*/
void otPlatCryptoRandomInit(void);
/**
* Deinitialize cryptographically-secure pseudorandom number generator (CSPRNG).
*
*/
void otPlatCryptoRandomDeinit(void);
/**
* Fills a given buffer with cryptographically secure random bytes.
*
* @param[out] aBuffer A pointer to a buffer to fill with the random bytes.
* @param[in] aSize Size of buffer (number of bytes to fill).
*
* @retval OT_ERROR_NONE Successfully filled buffer with random values.
* @retval OT_ERROR_FAILED Operation failed.
*
*/
otError otPlatCryptoRandomGet(uint8_t *aBuffer, uint16_t aSize);
/**
* @}
*
*/
#ifdef __cplusplus
} // end of extern "C"
#endif
#endif // OPENTHREAD_PLATFORM_CRYPTO_H_