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  * 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     OT_CRYPTO_KEY_TYPE_ECDSA, ///< Key Type: ECDSA.
67 } otCryptoKeyType;
68 
69 /**
70  * Defines the key algorithms.
71  *
72  */
73 typedef enum
74 {
75     OT_CRYPTO_KEY_ALG_VENDOR,       ///< Key Algorithm: Vendor Defined.
76     OT_CRYPTO_KEY_ALG_AES_ECB,      ///< Key Algorithm: AES ECB.
77     OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
78     OT_CRYPTO_KEY_ALG_ECDSA,        ///< Key Algorithm: ECDSA.
79 } otCryptoKeyAlgorithm;
80 
81 /**
82  * Defines the key usage flags.
83  *
84  */
85 enum
86 {
87     OT_CRYPTO_KEY_USAGE_NONE        = 0,      ///< Key Usage: Key Usage is empty.
88     OT_CRYPTO_KEY_USAGE_EXPORT      = 1 << 0, ///< Key Usage: Key can be exported.
89     OT_CRYPTO_KEY_USAGE_ENCRYPT     = 1 << 1, ///< Key Usage: Encryption (vendor defined).
90     OT_CRYPTO_KEY_USAGE_DECRYPT     = 1 << 2, ///< Key Usage: AES ECB.
91     OT_CRYPTO_KEY_USAGE_SIGN_HASH   = 1 << 3, ///< Key Usage: Sign Hash.
92     OT_CRYPTO_KEY_USAGE_VERIFY_HASH = 1 << 4, ///< Key Usage: Verify Hash.
93 };
94 
95 /**
96  * Defines the key storage types.
97  *
98  */
99 typedef enum
100 {
101     OT_CRYPTO_KEY_STORAGE_VOLATILE,   ///< Key Persistence: Key is volatile.
102     OT_CRYPTO_KEY_STORAGE_PERSISTENT, ///< Key Persistence: Key is persistent.
103 } otCryptoKeyStorage;
104 
105 /**
106  * This datatype represents the key reference.
107  *
108  */
109 typedef uint32_t otCryptoKeyRef;
110 
111 /**
112  * @struct otCryptoKey
113  *
114  * Represents the Key Material required for Crypto operations.
115  *
116  */
117 typedef struct otCryptoKey
118 {
119     const uint8_t *mKey;       ///< Pointer to the buffer containing key. NULL indicates to use `mKeyRef`.
120     uint16_t       mKeyLength; ///< The key length in bytes (applicable when `mKey` is not NULL).
121     uint32_t       mKeyRef;    ///< The PSA key ref (requires `mKey` to be NULL).
122 } otCryptoKey;
123 
124 /**
125  * @struct otCryptoContext
126  *
127  * Stores the context object for platform APIs.
128  *
129  */
130 typedef struct otCryptoContext
131 {
132     void    *mContext;     ///< Pointer to the context.
133     uint16_t mContextSize; ///< The length of the context in bytes.
134 } otCryptoContext;
135 
136 /**
137  * Length of SHA256 hash (in bytes).
138  *
139  */
140 #define OT_CRYPTO_SHA256_HASH_SIZE 32
141 
142 /**
143  * @struct otPlatCryptoSha256Hash
144  *
145  * Represents a SHA-256 hash.
146  *
147  */
148 OT_TOOL_PACKED_BEGIN
149 struct otPlatCryptoSha256Hash
150 {
151     uint8_t m8[OT_CRYPTO_SHA256_HASH_SIZE]; ///< Hash bytes.
152 } OT_TOOL_PACKED_END;
153 
154 /**
155  * Represents a SHA-256 hash.
156  *
157  */
158 typedef struct otPlatCryptoSha256Hash otPlatCryptoSha256Hash;
159 
160 /**
161  * Max buffer size (in bytes) for representing the EDCSA key-pair in DER format.
162  *
163  */
164 #define OT_CRYPTO_ECDSA_MAX_DER_SIZE 125
165 
166 /**
167  * @struct otPlatCryptoEcdsaKeyPair
168  *
169  * Represents an ECDSA key pair (public and private keys).
170  *
171  * The key pair is stored using Distinguished Encoding Rules (DER) format (per RFC 5915).
172  *
173  */
174 typedef struct otPlatCryptoEcdsaKeyPair
175 {
176     uint8_t mDerBytes[OT_CRYPTO_ECDSA_MAX_DER_SIZE];
177     uint8_t mDerLength;
178 } otPlatCryptoEcdsaKeyPair;
179 
180 /**
181  * Buffer size (in bytes) for representing the EDCSA public key.
182  *
183  */
184 #define OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE 64
185 
186 /**
187  * @struct otPlatCryptoEcdsaPublicKey
188  *
189  * Represents a ECDSA public key.
190  *
191  * The public key is stored as a byte sequence representation of an uncompressed curve point (RFC 6605 - sec 4).
192  *
193  */
194 OT_TOOL_PACKED_BEGIN
195 struct otPlatCryptoEcdsaPublicKey
196 {
197     uint8_t m8[OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE];
198 } OT_TOOL_PACKED_END;
199 
200 typedef struct otPlatCryptoEcdsaPublicKey otPlatCryptoEcdsaPublicKey;
201 
202 /**
203  * Buffer size (in bytes) for representing the EDCSA signature.
204  *
205  */
206 #define OT_CRYPTO_ECDSA_SIGNATURE_SIZE 64
207 
208 /**
209  * @struct otPlatCryptoEcdsaSignature
210  *
211  * Represents an ECDSA signature.
212  *
213  * The signature is encoded as the concatenated binary representation of two MPIs `r` and `s` which are calculated
214  * during signing (RFC 6605 - section 4).
215  *
216  */
217 OT_TOOL_PACKED_BEGIN
218 struct otPlatCryptoEcdsaSignature
219 {
220     uint8_t m8[OT_CRYPTO_ECDSA_SIGNATURE_SIZE];
221 } OT_TOOL_PACKED_END;
222 
223 typedef struct otPlatCryptoEcdsaSignature otPlatCryptoEcdsaSignature;
224 
225 /**
226  * Max PBKDF2 SALT length: salt prefix (6) + extended panid (8) + network name (16)
227  *
228  */
229 #define OT_CRYPTO_PBDKF2_MAX_SALT_SIZE 30
230 
231 /**
232  * Initialize the Crypto module.
233  *
234  */
235 void otPlatCryptoInit(void);
236 
237 /**
238  * Import a key into PSA ITS.
239  *
240  * @param[in,out] aKeyRef           Pointer to the key ref to be used for crypto operations.
241  * @param[in]     aKeyType          Key Type encoding for the key.
242  * @param[in]     aKeyAlgorithm     Key algorithm encoding for the key.
243  * @param[in]     aKeyUsage         Key Usage encoding for the key (combinations of `OT_CRYPTO_KEY_USAGE_*`).
244  * @param[in]     aKeyPersistence   Key Persistence for this key
245  * @param[in]     aKey              Actual key to be imported.
246  * @param[in]     aKeyLen           Length of the key to be imported.
247  *
248  * @retval OT_ERROR_NONE          Successfully imported the key.
249  * @retval OT_ERROR_FAILED        Failed to import the key.
250  * @retval OT_ERROR_INVALID_ARGS  @p aKey was set to NULL.
251  *
252  * @note If OT_CRYPTO_KEY_STORAGE_PERSISTENT is passed for aKeyPersistence then @p aKeyRef is input and platform
253  *       should use the given aKeyRef and MUST not change it.
254  *
255  *       If OT_CRYPTO_KEY_STORAGE_VOLATILE is passed for aKeyPersistence then @p aKeyRef is output, the initial
256  *       value does not matter and platform API MUST update it to return the new key ref.
257  *
258  *       This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
259  *
260  */
261 otError otPlatCryptoImportKey(otCryptoKeyRef      *aKeyRef,
262                               otCryptoKeyType      aKeyType,
263                               otCryptoKeyAlgorithm aKeyAlgorithm,
264                               int                  aKeyUsage,
265                               otCryptoKeyStorage   aKeyPersistence,
266                               const uint8_t       *aKey,
267                               size_t               aKeyLen);
268 
269 /**
270  * Export a key stored in PSA ITS.
271  *
272  * @param[in]   aKeyRef           The key ref to be used for crypto operations.
273  * @param[out]  aBuffer           Pointer to the buffer where key needs to be exported.
274  * @param[in]   aBufferLen        Length of the buffer passed to store the exported key.
275  * @param[out]  aKeyLen           Pointer to return the length of the exported key.
276  *
277  * @retval OT_ERROR_NONE          Successfully exported  @p aKeyRef.
278  * @retval OT_ERROR_FAILED        Failed to export @p aKeyRef.
279  * @retval OT_ERROR_INVALID_ARGS  @p aBuffer was NULL
280  *
281  * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
282  *
283  */
284 otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen);
285 
286 /**
287  * Destroy a key stored in PSA ITS.
288  *
289  * @param[in]   aKeyRef          The key ref to be destroyed
290  *
291  * @retval OT_ERROR_NONE          Successfully destroyed the key.
292  * @retval OT_ERROR_FAILED        Failed to destroy the key.
293  *
294  * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
295  *
296  */
297 otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef);
298 
299 /**
300  * Check if the key ref passed has an associated key in PSA ITS.
301  *
302  * @param[in]  aKeyRef          The Key Ref to check.
303  *
304  * @retval TRUE                 There is an associated key with @p aKeyRef.
305  * @retval FALSE                There is no associated key with @p aKeyRef.
306  *
307  * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
308  *
309  */
310 bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef);
311 
312 /**
313  * Initialize the HMAC operation.
314  *
315  * @param[in]  aContext          Context for HMAC operation.
316  *
317  * @retval OT_ERROR_NONE          Successfully initialized HMAC operation.
318  * @retval OT_ERROR_FAILED        Failed to initialize HMAC operation.
319  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
320  *
321  * @note The platform driver shall point the context to the correct object such as psa_mac_operation_t or
322  *       mbedtls_md_context_t.
323  *
324  */
325 otError otPlatCryptoHmacSha256Init(otCryptoContext *aContext);
326 
327 /**
328  * Uninitialize the HMAC operation.
329  *
330  * @param[in]  aContext          Context for HMAC operation.
331  *
332  * @retval OT_ERROR_NONE          Successfully uninitialized HMAC operation.
333  * @retval OT_ERROR_FAILED        Failed to uninitialized HMAC operation.
334  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
335  *
336  */
337 otError otPlatCryptoHmacSha256Deinit(otCryptoContext *aContext);
338 
339 /**
340  * Start HMAC operation.
341  *
342  * @param[in]  aContext           Context for HMAC operation.
343  * @param[in]  aKey               Key material to be used for HMAC operation.
344  *
345  * @retval OT_ERROR_NONE          Successfully started HMAC operation.
346  * @retval OT_ERROR_FAILED        Failed to start HMAC operation.
347  * @retval OT_ERROR_INVALID_ARGS  @p aContext or @p aKey was NULL
348  *
349  */
350 otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey *aKey);
351 
352 /**
353  * Update the HMAC operation with new input.
354  *
355  * @param[in]  aContext           Context for HMAC operation.
356  * @param[in]  aBuf               A pointer to the input buffer.
357  * @param[in]  aBufLength         The length of @p aBuf in bytes.
358  *
359  * @retval OT_ERROR_NONE          Successfully updated HMAC with new input operation.
360  * @retval OT_ERROR_FAILED        Failed to update HMAC operation.
361  * @retval OT_ERROR_INVALID_ARGS  @p aContext or @p aBuf was NULL
362  *
363  */
364 otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength);
365 
366 /**
367  * Complete the HMAC operation.
368  *
369  * @param[in]  aContext           Context for HMAC operation.
370  * @param[out] aBuf               A pointer to the output buffer.
371  * @param[in]  aBufLength         The length of @p aBuf in bytes.
372  *
373  * @retval OT_ERROR_NONE          Successfully completed HMAC operation.
374  * @retval OT_ERROR_FAILED        Failed to complete HMAC operation.
375  * @retval OT_ERROR_INVALID_ARGS  @p aContext or @p aBuf was NULL
376  *
377  */
378 otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength);
379 
380 /**
381  * Initialise the AES operation.
382  *
383  * @param[in]  aContext           Context for AES operation.
384  *
385  * @retval OT_ERROR_NONE          Successfully Initialised AES operation.
386  * @retval OT_ERROR_FAILED        Failed to Initialise AES operation.
387  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
388  * @retval OT_ERROR_NO_BUFS       Cannot allocate the context.
389  *
390  * @note The platform driver shall point the context to the correct object such as psa_key_id
391  *       or mbedtls_aes_context_t.
392  *
393  */
394 otError otPlatCryptoAesInit(otCryptoContext *aContext);
395 
396 /**
397  * Set the key for AES operation.
398  *
399  * @param[in]  aContext           Context for AES operation.
400  * @param[out] aKey               Key to use for AES operation.
401  *
402  * @retval OT_ERROR_NONE          Successfully set the key for AES operation.
403  * @retval OT_ERROR_FAILED        Failed to set the key for AES operation.
404  * @retval OT_ERROR_INVALID_ARGS  @p aContext or @p aKey was NULL
405  *
406  */
407 otError otPlatCryptoAesSetKey(otCryptoContext *aContext, const otCryptoKey *aKey);
408 
409 /**
410  * Encrypt the given data.
411  *
412  * @param[in]  aContext           Context for AES operation.
413  * @param[in]  aInput             Pointer to the input buffer.
414  * @param[in]  aOutput            Pointer to the output buffer.
415  *
416  * @retval OT_ERROR_NONE          Successfully encrypted @p aInput.
417  * @retval OT_ERROR_FAILED        Failed to encrypt @p aInput.
418  * @retval OT_ERROR_INVALID_ARGS  @p aContext or @p aKey or @p aOutput were NULL
419  *
420  */
421 otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, uint8_t *aOutput);
422 
423 /**
424  * Free the AES context.
425  *
426  * @param[in]  aContext           Context for AES operation.
427  *
428  * @retval OT_ERROR_NONE          Successfully freed AES context.
429  * @retval OT_ERROR_FAILED        Failed to free AES context.
430  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
431  *
432  */
433 otError otPlatCryptoAesFree(otCryptoContext *aContext);
434 
435 /**
436  * Initialise the HKDF context.
437  *
438  * @param[in]  aContext           Context for HKDF operation.
439  *
440  * @retval OT_ERROR_NONE          Successfully Initialised AES operation.
441  * @retval OT_ERROR_FAILED        Failed to Initialise AES operation.
442  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
443  *
444  * @note The platform driver shall point the context to the correct object such as psa_key_derivation_operation_t
445  *       or HmacSha256::Hash
446  *
447  */
448 otError otPlatCryptoHkdfInit(otCryptoContext *aContext);
449 
450 /**
451  * Perform HKDF Expand step.
452  *
453  * @param[in]  aContext           Operation context for HKDF operation.
454  * @param[in]  aInfo              Pointer to the Info sequence.
455  * @param[in]  aInfoLength        Length of the Info sequence.
456  * @param[out] aOutputKey         Pointer to the output Key.
457  * @param[in]  aOutputKeyLength   Size of the output key buffer.
458  *
459  * @retval OT_ERROR_NONE          HKDF Expand was successful.
460  * @retval OT_ERROR_FAILED        HKDF Expand failed.
461  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
462  *
463  */
464 otError otPlatCryptoHkdfExpand(otCryptoContext *aContext,
465                                const uint8_t   *aInfo,
466                                uint16_t         aInfoLength,
467                                uint8_t         *aOutputKey,
468                                uint16_t         aOutputKeyLength);
469 
470 /**
471  * Perform HKDF Extract step.
472  *
473  * @param[in]  aContext           Operation context for HKDF operation.
474  * @param[in]  aSalt              Pointer to the Salt for HKDF.
475  * @param[in]  aSaltLength        Length of Salt.
476  * @param[in]  aInputKey          Pointer to the input key.
477  *
478  * @retval OT_ERROR_NONE          HKDF Extract was successful.
479  * @retval OT_ERROR_FAILED        HKDF Extract failed.
480  *
481  */
482 otError otPlatCryptoHkdfExtract(otCryptoContext   *aContext,
483                                 const uint8_t     *aSalt,
484                                 uint16_t           aSaltLength,
485                                 const otCryptoKey *aInputKey);
486 
487 /**
488  * Uninitialize the HKDF context.
489  *
490  * @param[in]  aContext           Context for HKDF operation.
491  *
492  * @retval OT_ERROR_NONE          Successfully un-initialised HKDF operation.
493  * @retval OT_ERROR_FAILED        Failed to un-initialised HKDF operation.
494  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
495  *
496  */
497 otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext);
498 
499 /**
500  * Initialise the SHA-256 operation.
501  *
502  * @param[in]  aContext           Context for SHA-256 operation.
503  *
504  * @retval OT_ERROR_NONE          Successfully initialised SHA-256 operation.
505  * @retval OT_ERROR_FAILED        Failed to initialise SHA-256 operation.
506  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
507  *
508  *
509  * @note The platform driver shall point the context to the correct object such as psa_hash_operation_t
510  *       or mbedtls_sha256_context.
511  */
512 otError otPlatCryptoSha256Init(otCryptoContext *aContext);
513 
514 /**
515  * Uninitialize the SHA-256 operation.
516  *
517  * @param[in]  aContext           Context for SHA-256 operation.
518  *
519  * @retval OT_ERROR_NONE          Successfully un-initialised SHA-256 operation.
520  * @retval OT_ERROR_FAILED        Failed to un-initialised SHA-256 operation.
521  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
522  *
523  */
524 otError otPlatCryptoSha256Deinit(otCryptoContext *aContext);
525 
526 /**
527  * Start SHA-256 operation.
528  *
529  * @param[in]  aContext           Context for SHA-256 operation.
530  *
531  * @retval OT_ERROR_NONE          Successfully started SHA-256 operation.
532  * @retval OT_ERROR_FAILED        Failed to start SHA-256 operation.
533  * @retval OT_ERROR_INVALID_ARGS  @p aContext was NULL
534  *
535  */
536 otError otPlatCryptoSha256Start(otCryptoContext *aContext);
537 
538 /**
539  * Update SHA-256 operation with new input.
540  *
541  * @param[in]  aContext           Context for SHA-256 operation.
542  * @param[in]  aBuf               A pointer to the input buffer.
543  * @param[in]  aBufLength         The length of @p aBuf in bytes.
544  *
545  * @retval OT_ERROR_NONE          Successfully updated SHA-256 with new input operation.
546  * @retval OT_ERROR_FAILED        Failed to update SHA-256 operation.
547  * @retval OT_ERROR_INVALID_ARGS  @p aContext or @p aBuf was NULL
548  *
549  */
550 otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength);
551 
552 /**
553  * Finish SHA-256 operation.
554  *
555  * @param[in]  aContext           Context for SHA-256 operation.
556  * @param[in]  aHash              A pointer to the output buffer, where hash needs to be stored.
557  * @param[in]  aHashSize          The length of @p aHash in bytes.
558  *
559  * @retval OT_ERROR_NONE          Successfully completed the SHA-256 operation.
560  * @retval OT_ERROR_FAILED        Failed to complete SHA-256 operation.
561  * @retval OT_ERROR_INVALID_ARGS  @p aContext or @p aHash was NULL
562  *
563  */
564 otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize);
565 
566 /**
567  * Initialize cryptographically-secure pseudorandom number generator (CSPRNG).
568  *
569  */
570 void otPlatCryptoRandomInit(void);
571 
572 /**
573  * Deinitialize cryptographically-secure pseudorandom number generator (CSPRNG).
574  *
575  */
576 void otPlatCryptoRandomDeinit(void);
577 
578 /**
579  * Fills a given buffer with cryptographically secure random bytes.
580  *
581  * @param[out] aBuffer            A pointer to a buffer to fill with the random bytes.
582  * @param[in]  aSize              Size of buffer (number of bytes to fill).
583  *
584  * @retval OT_ERROR_NONE          Successfully filled buffer with random values.
585  * @retval OT_ERROR_FAILED        Operation failed.
586  *
587  */
588 otError otPlatCryptoRandomGet(uint8_t *aBuffer, uint16_t aSize);
589 
590 /**
591  * Generate and populate the output buffer with a new ECDSA key-pair.
592  *
593  * @param[out] aKeyPair           A pointer to an ECDSA key-pair structure to store the generated key-pair.
594  *
595  * @retval OT_ERROR_NONE          A new key-pair was generated successfully.
596  * @retval OT_ERROR_NO_BUFS       Failed to allocate buffer for key generation.
597  * @retval OT_ERROR_NOT_CAPABLE   Feature not supported.
598  * @retval OT_ERROR_FAILED        Failed to generate key-pair.
599  *
600  */
601 otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair);
602 
603 /**
604  * Get the associated public key from the input context.
605  *
606  * @param[in]  aKeyPair           A pointer to an ECDSA key-pair structure where the key-pair is stored.
607  * @param[out] aPublicKey         A pointer to an ECDSA public key structure to store the public key.
608  *
609  * @retval OT_ERROR_NONE          Public key was retrieved successfully, and @p aBuffer is updated.
610  * @retval OT_ERROR_PARSE         The key-pair DER format could not be parsed (invalid format).
611  * @retval OT_ERROR_INVALID_ARGS  The @p aContext is NULL.
612  *
613  */
614 otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair, otPlatCryptoEcdsaPublicKey *aPublicKey);
615 
616 /**
617  * Calculate the ECDSA signature for a hashed message using the private key from the input context.
618  *
619  * Uses the deterministic digital signature generation procedure from RFC 6979.
620  *
621  * @param[in]  aKeyPair           A pointer to an ECDSA key-pair structure where the key-pair is stored.
622  * @param[in]  aHash              A pointer to a SHA-256 hash structure where the hash value for signature calculation
623  *                                is stored.
624  * @param[out] aSignature         A pointer to an ECDSA signature structure to output the calculated signature.
625  *
626  * @retval OT_ERROR_NONE          The signature was calculated successfully, @p aSignature was updated.
627  * @retval OT_ERROR_PARSE         The key-pair DER format could not be parsed (invalid format).
628  * @retval OT_ERROR_NO_BUFS       Failed to allocate buffer for signature calculation.
629  * @retval OT_ERROR_INVALID_ARGS  The @p aContext is NULL.
630  *
631  */
632 otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair,
633                               const otPlatCryptoSha256Hash   *aHash,
634                               otPlatCryptoEcdsaSignature     *aSignature);
635 
636 /**
637  * Use the key from the input context to verify the ECDSA signature of a hashed message.
638  *
639  * @param[in]  aPublicKey         A pointer to an ECDSA public key structure where the public key for signature
640  *                                verification is stored.
641  * @param[in]  aHash              A pointer to a SHA-256 hash structure where the hash value for signature verification
642  *                                is stored.
643  * @param[in]  aSignature         A pointer to an ECDSA signature structure where the signature value to be verified is
644  *                                stored.
645  *
646  * @retval OT_ERROR_NONE          The signature was verified successfully.
647  * @retval OT_ERROR_SECURITY      The signature is invalid.
648  * @retval OT_ERROR_INVALID_ARGS  The key or hash is invalid.
649  * @retval OT_ERROR_NO_BUFS       Failed to allocate buffer for signature verification.
650  *
651  */
652 otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
653                                 const otPlatCryptoSha256Hash     *aHash,
654                                 const otPlatCryptoEcdsaSignature *aSignature);
655 
656 /**
657  * Calculate the ECDSA signature for a hashed message using the Key reference passed.
658  *
659  * Uses the deterministic digital signature generation procedure from RFC 6979.
660  *
661  * @param[in]  aKeyRef            Key Reference to the slot where the key-pair is stored.
662  * @param[in]  aHash              A pointer to a SHA-256 hash structure where the hash value for signature calculation
663  *                                is stored.
664  * @param[out] aSignature         A pointer to an ECDSA signature structure to output the calculated signature.
665  *
666  * @retval OT_ERROR_NONE          The signature was calculated successfully, @p aSignature was updated.
667  * @retval OT_ERROR_PARSE         The key-pair DER format could not be parsed (invalid format).
668  * @retval OT_ERROR_NO_BUFS       Failed to allocate buffer for signature calculation.
669  * @retval OT_ERROR_INVALID_ARGS  The @p aContext is NULL.
670  *
671  * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
672  *
673  */
674 otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef                aKeyRef,
675                                          const otPlatCryptoSha256Hash *aHash,
676                                          otPlatCryptoEcdsaSignature   *aSignature);
677 
678 /**
679  * Get the associated public key from the key reference passed.
680  *
681  * The public key is stored differently depending on the crypto backend library being used
682  * (OPENTHREAD_CONFIG_CRYPTO_LIB).
683  *
684  * This API must make sure to return the public key as a byte sequence representation of an
685  * uncompressed curve point (RFC 6605 - sec 4)
686  *
687  * @param[in]  aKeyRef            Key Reference to the slot where the key-pair is stored.
688  * @param[out] aPublicKey         A pointer to an ECDSA public key structure to store the public key.
689  *
690  * @retval OT_ERROR_NONE          Public key was retrieved successfully, and @p aBuffer is updated.
691  * @retval OT_ERROR_PARSE         The key-pair DER format could not be parsed (invalid format).
692  * @retval OT_ERROR_INVALID_ARGS  The @p aContext is NULL.
693  *
694  * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
695  *
696  */
697 otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, otPlatCryptoEcdsaPublicKey *aPublicKey);
698 
699 /**
700  * Generate and import a new ECDSA key-pair at reference passed.
701  *
702  * @param[in]  aKeyRef            Key Reference to the slot where the key-pair is stored.
703  *
704  * @retval OT_ERROR_NONE          A new key-pair was generated successfully.
705  * @retval OT_ERROR_NO_BUFS       Failed to allocate buffer for key generation.
706  * @retval OT_ERROR_NOT_CAPABLE   Feature not supported.
707  * @retval OT_ERROR_FAILED        Failed to generate key-pair.
708  *
709  * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
710  *
711  */
712 otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef);
713 
714 /**
715  * Use the keyref to verify the ECDSA signature of a hashed message.
716  *
717  * @param[in]  aKeyRef            Key Reference to the slot where the key-pair is stored.
718  * @param[in]  aHash              A pointer to a SHA-256 hash structure where the hash value for signature verification
719  *                                is stored.
720  * @param[in]  aSignature         A pointer to an ECDSA signature structure where the signature value to be verified is
721  *                                stored.
722  *
723  * @retval OT_ERROR_NONE          The signature was verified successfully.
724  * @retval OT_ERROR_SECURITY      The signature is invalid.
725  * @retval OT_ERROR_INVALID_ARGS  The key or hash is invalid.
726  * @retval OT_ERROR_NO_BUFS       Failed to allocate buffer for signature verification.
727  *
728  * @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
729  *
730  */
731 otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef                    aKeyRef,
732                                            const otPlatCryptoSha256Hash     *aHash,
733                                            const otPlatCryptoEcdsaSignature *aSignature);
734 
735 /**
736  * Perform PKCS#5 PBKDF2 using CMAC (AES-CMAC-PRF-128).
737  *
738  * @param[in]     aPassword          Password to use when generating key.
739  * @param[in]     aPasswordLen       Length of password.
740  * @param[in]     aSalt              Salt to use when generating key.
741  * @param[in]     aSaltLen           Length of salt.
742  * @param[in]     aIterationCounter  Iteration count.
743  * @param[in]     aKeyLen            Length of generated key in bytes.
744  * @param[out]    aKey               A pointer to the generated key.
745  *
746  */
747 void otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
748                                    uint16_t       aPasswordLen,
749                                    const uint8_t *aSalt,
750                                    uint16_t       aSaltLen,
751                                    uint32_t       aIterationCounter,
752                                    uint16_t       aKeyLen,
753                                    uint8_t       *aKey);
754 
755 /**
756  * @}
757  *
758  */
759 
760 #ifdef __cplusplus
761 } // end of extern "C"
762 #endif
763 #endif // OPENTHREAD_PLATFORM_CRYPTO_H_
764