1 /* 2 * Copyright (c) 2021, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * @brief 32 * This file includes the platform abstraction for Crypto operations. 33 */ 34 35 #ifndef OPENTHREAD_PLATFORM_CRYPTO_H_ 36 #define OPENTHREAD_PLATFORM_CRYPTO_H_ 37 38 #include <stdint.h> 39 #include <stdlib.h> 40 41 #include <openthread/error.h> 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 /** 48 * @addtogroup plat-crypto 49 * 50 * @brief 51 * This module includes the platform abstraction for Crypto. 52 * 53 * @{ 54 * 55 */ 56 57 /** 58 * This enumeration defines the key types. 59 * 60 */ 61 typedef enum 62 { 63 OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data. 64 OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES. 65 OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC. 66 } otCryptoKeyType; 67 68 /** 69 * This enumeration defines the key algorithms. 70 * 71 */ 72 typedef enum 73 { 74 OT_CRYPTO_KEY_ALG_VENDOR, ///< Key Algorithm: Vendor Defined. 75 OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB. 76 OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256. 77 } otCryptoKeyAlgorithm; 78 79 /** 80 * This enumeration defines the key usage flags. 81 * 82 */ 83 enum 84 { 85 OT_CRYPTO_KEY_USAGE_NONE = 0, ///< Key Usage: Key Usage is empty. 86 OT_CRYPTO_KEY_USAGE_EXPORT = 1 << 0, ///< Key Usage: Key can be exported. 87 OT_CRYPTO_KEY_USAGE_ENCRYPT = 1 << 1, ///< Key Usage: Encryption (vendor defined). 88 OT_CRYPTO_KEY_USAGE_DECRYPT = 1 << 2, ///< Key Usage: AES ECB. 89 OT_CRYPTO_KEY_USAGE_SIGN_HASH = 1 << 3, ///< Key Usage: HMAC SHA-256. 90 }; 91 92 /** 93 * This enumeration defines the key storage types. 94 * 95 */ 96 typedef enum 97 { 98 OT_CRYPTO_KEY_STORAGE_VOLATILE, ///< Key Persistence: Key is volatile. 99 OT_CRYPTO_KEY_STORAGE_PERSISTENT, ///< Key Persistence: Key is persistent. 100 } otCryptoKeyStorage; 101 102 /** 103 * This datatype represents the key reference. 104 * 105 */ 106 typedef uint32_t otCryptoKeyRef; 107 108 /** 109 * @struct otCryptoKey 110 * 111 * This structure represents the Key Material required for Crypto operations. 112 * 113 */ 114 typedef struct otCryptoKey 115 { 116 const uint8_t *mKey; ///< Pointer to the buffer containing key. NULL indicates to use `mKeyRef`. 117 uint16_t mKeyLength; ///< The key length in bytes (applicable when `mKey` is not NULL). 118 uint32_t mKeyRef; ///< The PSA key ref (requires `mKey` to be NULL). 119 } otCryptoKey; 120 121 /** 122 * @struct otCryptoContext 123 * 124 * This structure stores the context object for platform APIs. 125 * 126 */ 127 typedef struct otCryptoContext 128 { 129 void * mContext; ///< Pointer to the context. 130 uint16_t mContextSize; ///< The length of the context in bytes. 131 } otCryptoContext; 132 133 /** 134 * Initialize the Crypto module. 135 * 136 */ 137 void otPlatCryptoInit(void); 138 139 /** 140 * Import a key into PSA ITS. 141 * 142 * @param[in,out] aKeyRef Pointer to the key ref to be used for crypto operations. 143 * @param[in] aKeyType Key Type encoding for the key. 144 * @param[in] aKeyAlgorithm Key algorithm encoding for the key. 145 * @param[in] aKeyUsage Key Usage encoding for the key (combinations of `OT_CRYPTO_KEY_USAGE_*`). 146 * @param[in] aKeyPersistence Key Persistence for this key 147 * @param[in] aKey Actual key to be imported. 148 * @param[in] aKeyLen Length of the key to be imported. 149 * 150 * @retval OT_ERROR_NONE Successfully imported the key. 151 * @retval OT_ERROR_FAILED Failed to import the key. 152 * @retval OT_ERROR_INVALID_ARGS @p aKey was set to NULL. 153 * 154 * @note If OT_CRYPTO_KEY_STORAGE_PERSISTENT is passed for aKeyPersistence then @p aKeyRef is input and platform 155 * should use the given aKeyRef and MUST not change it. 156 * 157 * If OT_CRYPTO_KEY_STORAGE_VOLATILE is passed for aKeyPersistence then @p aKeyRef is output, the initial 158 * value does not matter and platform API MUST update it to return the new key ref. 159 * 160 * This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled. 161 * 162 */ 163 otError otPlatCryptoImportKey(otCryptoKeyRef * aKeyRef, 164 otCryptoKeyType aKeyType, 165 otCryptoKeyAlgorithm aKeyAlgorithm, 166 int aKeyUsage, 167 otCryptoKeyStorage aKeyPersistence, 168 const uint8_t * aKey, 169 size_t aKeyLen); 170 171 /** 172 * Export a key stored in PSA ITS. 173 * 174 * @param[in] aKeyRef The key ref to be used for crypto operations. 175 * @param[out] aBuffer Pointer to the buffer where key needs to be exported. 176 * @param[in] aBufferLen Length of the buffer passed to store the exported key. 177 * @param[out] aKeyLen Pointer to return the length of the exported key. 178 * 179 * @retval OT_ERROR_NONE Successfully exported @p aKeyRef. 180 * @retval OT_ERROR_FAILED Failed to export @p aKeyRef. 181 * @retval OT_ERROR_INVALID_ARGS @p aBuffer was NULL 182 * 183 * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled. 184 * 185 */ 186 otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen); 187 188 /** 189 * Destroy a key stored in PSA ITS. 190 * 191 * @param[in] aKeyRef The key ref to be destroyed 192 * 193 * @retval OT_ERROR_NONE Successfully destroyed the key. 194 * @retval OT_ERROR_FAILED Failed to destroy the key. 195 * 196 * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled. 197 * 198 */ 199 otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef); 200 201 /** 202 * Check if the key ref passed has an associated key in PSA ITS. 203 * 204 * @param[in] aKeyRef The Key Ref to check. 205 * 206 * @retval TRUE There is an associated key with @p aKeyRef. 207 * @retval FALSE There is no associated key with @p aKeyRef. 208 * 209 * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled. 210 * 211 */ 212 bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef); 213 214 /** 215 * Initialize the HMAC operation. 216 * 217 * @param[in] aContext Context for HMAC operation. 218 * 219 * @retval OT_ERROR_NONE Successfully initialized HMAC operation. 220 * @retval OT_ERROR_FAILED Failed to initialize HMAC operation. 221 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 222 * 223 * @note The platform driver shall point the context to the correct object such as psa_mac_operation_t or 224 * mbedtls_md_context_t. 225 * 226 */ 227 otError otPlatCryptoHmacSha256Init(otCryptoContext *aContext); 228 229 /** 230 * Uninitialize the HMAC operation. 231 * 232 * @param[in] aContext Context for HMAC operation. 233 * 234 * @retval OT_ERROR_NONE Successfully uninitialized HMAC operation. 235 * @retval OT_ERROR_FAILED Failed to uninitialized HMAC operation. 236 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 237 * 238 */ 239 otError otPlatCryptoHmacSha256Deinit(otCryptoContext *aContext); 240 241 /** 242 * Start HMAC operation. 243 * 244 * @param[in] aContext Context for HMAC operation. 245 * @param[in] aKey Key material to be used for for HMAC operation. 246 * 247 * @retval OT_ERROR_NONE Successfully started HMAC operation. 248 * @retval OT_ERROR_FAILED Failed to start HMAC operation. 249 * @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey was NULL 250 * 251 */ 252 otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey *aKey); 253 254 /** 255 * Update the HMAC operation with new input. 256 * 257 * @param[in] aContext Context for HMAC operation. 258 * @param[in] aBuf A pointer to the input buffer. 259 * @param[in] aBufLength The length of @p aBuf in bytes. 260 * 261 * @retval OT_ERROR_NONE Successfully updated HMAC with new input operation. 262 * @retval OT_ERROR_FAILED Failed to update HMAC operation. 263 * @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL 264 * 265 */ 266 otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength); 267 268 /** 269 * Complete the HMAC operation. 270 * 271 * @param[in] aContext Context for HMAC operation. 272 * @param[out] aBuf A pointer to the output buffer. 273 * @param[in] aBufLength The length of @p aBuf in bytes. 274 * 275 * @retval OT_ERROR_NONE Successfully completed HMAC operation. 276 * @retval OT_ERROR_FAILED Failed to complete HMAC operation. 277 * @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL 278 * 279 */ 280 otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength); 281 282 /** 283 * Initialise the AES operation. 284 * 285 * @param[in] aContext Context for AES operation. 286 * 287 * @retval OT_ERROR_NONE Successfully Initialised AES operation. 288 * @retval OT_ERROR_FAILED Failed to Initialise AES operation. 289 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 290 * @retval OT_ERROR_NO_BUFS Cannot allocate the context. 291 * 292 * @note The platform driver shall point the context to the correct object such as psa_key_id 293 * or mbedtls_aes_context_t. 294 * 295 */ 296 otError otPlatCryptoAesInit(otCryptoContext *aContext); 297 298 /** 299 * Set the key for AES operation. 300 * 301 * @param[in] aContext Context for AES operation. 302 * @param[out] aKey Key to use for AES operation. 303 * 304 * @retval OT_ERROR_NONE Successfully set the key for AES operation. 305 * @retval OT_ERROR_FAILED Failed to set the key for AES operation. 306 * @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey was NULL 307 * 308 */ 309 otError otPlatCryptoAesSetKey(otCryptoContext *aContext, const otCryptoKey *aKey); 310 311 /** 312 * Encrypt the given data. 313 * 314 * @param[in] aContext Context for AES operation. 315 * @param[in] aInput Pointer to the input buffer. 316 * @param[in] aOutput Pointer to the output buffer. 317 * 318 * @retval OT_ERROR_NONE Successfully encrypted @p aInput. 319 * @retval OT_ERROR_FAILED Failed to encrypt @p aInput. 320 * @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey or @p aOutput were NULL 321 * 322 */ 323 otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, uint8_t *aOutput); 324 325 /** 326 * Free the AES context. 327 * 328 * @param[in] aContext Context for AES operation. 329 * 330 * @retval OT_ERROR_NONE Successfully freed AES context. 331 * @retval OT_ERROR_FAILED Failed to free AES context. 332 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 333 * 334 */ 335 otError otPlatCryptoAesFree(otCryptoContext *aContext); 336 337 /** 338 * Initialise the HKDF context. 339 * 340 * @param[in] aContext Context for HKDF operation. 341 * 342 * @retval OT_ERROR_NONE Successfully Initialised AES operation. 343 * @retval OT_ERROR_FAILED Failed to Initialise AES operation. 344 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 345 * 346 * @note The platform driver shall point the context to the correct object such as psa_key_derivation_operation_t 347 * or HmacSha256::Hash 348 * 349 */ 350 otError otPlatCryptoHkdfInit(otCryptoContext *aContext); 351 352 /** 353 * Perform HKDF Expand step. 354 * 355 * @param[in] aContext Operation context for HKDF operation. 356 * @param[in] aInfo Pointer to the Info sequence. 357 * @param[in] aInfoLength Length of the Info sequence. 358 * @param[out] aOutputKey Pointer to the output Key. 359 * @param[in] aOutputKeyLength Size of the output key buffer. 360 * 361 * @retval OT_ERROR_NONE HKDF Expand was successful. 362 * @retval OT_ERROR_FAILED HKDF Expand failed. 363 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 364 * 365 */ 366 otError otPlatCryptoHkdfExpand(otCryptoContext *aContext, 367 const uint8_t * aInfo, 368 uint16_t aInfoLength, 369 uint8_t * aOutputKey, 370 uint16_t aOutputKeyLength); 371 372 /** 373 * Perform HKDF Extract step. 374 * 375 * @param[in] aContext Operation context for HKDF operation. 376 * @param[in] aSalt Pointer to the Salt for HKDF. 377 * @param[in] aSaltLength Length of Salt. 378 * @param[in] aInputKey Pointer to the input key. 379 * 380 * @retval OT_ERROR_NONE HKDF Extract was successful. 381 * @retval OT_ERROR_FAILED HKDF Extract failed. 382 * 383 */ 384 otError otPlatCryptoHkdfExtract(otCryptoContext * aContext, 385 const uint8_t * aSalt, 386 uint16_t aSaltLength, 387 const otCryptoKey *aInputKey); 388 389 /** 390 * Uninitialize the HKDF context. 391 * 392 * @param[in] aContext Context for HKDF operation. 393 * 394 * @retval OT_ERROR_NONE Successfully un-initialised HKDF operation. 395 * @retval OT_ERROR_FAILED Failed to un-initialised HKDF operation. 396 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 397 * 398 */ 399 otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext); 400 401 /** 402 * Initialise the SHA-256 operation. 403 * 404 * @param[in] aContext Context for SHA-256 operation. 405 * 406 * @retval OT_ERROR_NONE Successfully initialised SHA-256 operation. 407 * @retval OT_ERROR_FAILED Failed to initialise SHA-256 operation. 408 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 409 * 410 * 411 * @note The platform driver shall point the context to the correct object such as psa_hash_operation_t 412 * or mbedtls_sha256_context. 413 */ 414 otError otPlatCryptoSha256Init(otCryptoContext *aContext); 415 416 /** 417 * Uninitialize the SHA-256 operation. 418 * 419 * @param[in] aContext Context for SHA-256 operation. 420 * 421 * @retval OT_ERROR_NONE Successfully un-initialised SHA-256 operation. 422 * @retval OT_ERROR_FAILED Failed to un-initialised SHA-256 operation. 423 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 424 * 425 */ 426 otError otPlatCryptoSha256Deinit(otCryptoContext *aContext); 427 428 /** 429 * Start SHA-256 operation. 430 * 431 * @param[in] aContext Context for SHA-256 operation. 432 * 433 * @retval OT_ERROR_NONE Successfully started SHA-256 operation. 434 * @retval OT_ERROR_FAILED Failed to start SHA-256 operation. 435 * @retval OT_ERROR_INVALID_ARGS @p aContext was NULL 436 * 437 */ 438 otError otPlatCryptoSha256Start(otCryptoContext *aContext); 439 440 /** 441 * Update SHA-256 operation with new input. 442 * 443 * @param[in] aContext Context for SHA-256 operation. 444 * @param[in] aBuf A pointer to the input buffer. 445 * @param[in] aBufLength The length of @p aBuf in bytes. 446 * 447 * @retval OT_ERROR_NONE Successfully updated SHA-256 with new input operation. 448 * @retval OT_ERROR_FAILED Failed to update SHA-256 operation. 449 * @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL 450 * 451 */ 452 otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength); 453 454 /** 455 * Finish SHA-256 operation. 456 * 457 * @param[in] aContext Context for SHA-256 operation. 458 * @param[in] aHash A pointer to the output buffer, where hash needs to be stored. 459 * @param[in] aHashSize The length of @p aHash in bytes. 460 * 461 * @retval OT_ERROR_NONE Successfully completed the SHA-256 operation. 462 * @retval OT_ERROR_FAILED Failed to complete SHA-256 operation. 463 * @retval OT_ERROR_INVALID_ARGS @p aContext or @p aHash was NULL 464 * 465 */ 466 otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize); 467 468 /** 469 * Initialize cryptographically-secure pseudorandom number generator (CSPRNG). 470 * 471 */ 472 void otPlatCryptoRandomInit(void); 473 474 /** 475 * Deinitialize cryptographically-secure pseudorandom number generator (CSPRNG). 476 * 477 */ 478 void otPlatCryptoRandomDeinit(void); 479 480 /** 481 * Fills a given buffer with cryptographically secure random bytes. 482 * 483 * @param[out] aBuffer A pointer to a buffer to fill with the random bytes. 484 * @param[in] aSize Size of buffer (number of bytes to fill). 485 * 486 * @retval OT_ERROR_NONE Successfully filled buffer with random values. 487 * @retval OT_ERROR_FAILED Operation failed. 488 * 489 */ 490 otError otPlatCryptoRandomGet(uint8_t *aBuffer, uint16_t aSize); 491 492 /** 493 * @} 494 * 495 */ 496 497 #ifdef __cplusplus 498 } // end of extern "C" 499 #endif 500 #endif // OPENTHREAD_PLATFORM_CRYPTO_H_ 501