1 /***************************************************************************//**
2  * @file
3  * @brief Silicon Labs Secure Engine Manager API.
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 #ifndef SL_SE_MANAGER_CIPHER_H
31 #define SL_SE_MANAGER_CIPHER_H
32 
33 #include "em_device.h"
34 
35 #if defined(SEMAILBOX_PRESENT) || defined(DOXYGEN)
36 
37 /// @addtogroup sl_se_manager
38 /// @{
39 
40 /***************************************************************************//**
41  * @addtogroup sl_se_manager_cipher Cipher
42  *
43  * @brief
44  *   Symmetric encryption, AEAD and MAC.
45  *
46  * @details
47  *   API for performing symmetric encryption, Authenticated Encryption and
48  *   Additional Data (AEAD) operations, and computing Message Authentication
49  *   Codes (MACs) using the Secure Engine.
50  *
51  * @{
52  ******************************************************************************/
53 
54 #include "sl_se_manager_key_handling.h"
55 #include "sl_se_manager_types.h"
56 #include "em_se.h"
57 #include "sl_status.h"
58 #include <stdint.h>
59 #include <stdbool.h>
60 #include <stddef.h>
61 
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65 
66 // -----------------------------------------------------------------------------
67 // Prototypes
68 
69 /***************************************************************************//**
70  * @brief
71  *   AES-ECB block encryption/decryption.
72  *
73  * @param[in] cmd_ctx
74  *   Pointer to an SE command context object.
75  *
76  * @param[in] key
77  *   Pointer to sl_se_key_descriptor_t structure.
78  *
79  * @param[in] mode
80  *   Crypto operation type (encryption or decryption).
81  *
82  * @param[in] length
83  *   Length of the input data.
84  *
85  * @param[in] input
86  *   Buffer holding the input data.
87  *
88  * @param[out] output
89  *   Buffer holding the output data.
90  *
91  * @return
92  *   Status code, @ref sl_status.h.
93  ******************************************************************************/
94 sl_status_t sl_se_aes_crypt_ecb(sl_se_command_context_t *cmd_ctx,
95                                 const sl_se_key_descriptor_t *key,
96                                 sl_se_cipher_operation_t mode,
97                                 size_t length,
98                                 const unsigned char *input,
99                                 unsigned char *output);
100 
101 /***************************************************************************//**
102  * @brief
103  *   AES-CBC buffer encryption/decryption.
104  *
105  * @note
106  *   Length should be a multiple of the block size (16 bytes).
107  *
108  * @param[in] cmd_ctx
109  *   Pointer to an SE command context object.
110  *
111  * @param[in] key
112  *   Pointer to sl_se_key_descriptor_t structure.
113  *
114  * @param[in] mode
115  *   Crypto operation type (encryption or decryption).
116  *
117  * @param[in] length
118  *   Length of the input data.
119  *
120  * @param[in,out] iv
121  *   Initialization vector (updated after use).
122  *
123  * @param[in] input
124  *   Buffer holding the input data.
125  *
126  * @param[out] output
127  *   Buffer holding the output data.
128  *
129  * @return
130  *   Status code, @ref sl_status.h.
131  ******************************************************************************/
132 sl_status_t sl_se_aes_crypt_cbc(sl_se_command_context_t *cmd_ctx,
133                                 const sl_se_key_descriptor_t *key,
134                                 sl_se_cipher_operation_t mode,
135                                 size_t length,
136                                 unsigned char iv[16],
137                                 const unsigned char *input,
138                                 unsigned char *output);
139 
140 /***************************************************************************//**
141  * @brief
142  *   AES-CFB128 buffer encryption/decryption.
143  *
144  * @param[in] cmd_ctx
145  *   Pointer to an SE command context object.
146  *
147  * @param[in] key
148  *   Pointer to sl_se_key_descriptor_t structure.
149  *
150  * @param[in] mode
151  *   Crypto operation type (encryption or decryption).
152  *
153  * @param[in] length
154  *   Length of the input data.
155  *
156  * @param[in,out] iv_off
157  *   Offset in IV (updated after use).
158  *
159  * @param[in,out] iv
160  *   Initialization vector (updated after use).
161  *
162  * @param[in] input
163  *   Buffer holding the input data.
164  *
165  * @param[out] output
166  *   Buffer holding the output data.
167  *
168  * @return
169  *   Status code, @ref sl_status.h.
170  ******************************************************************************/
171 sl_status_t sl_se_aes_crypt_cfb128(sl_se_command_context_t *cmd_ctx,
172                                    const sl_se_key_descriptor_t *key,
173                                    sl_se_cipher_operation_t mode,
174                                    size_t length,
175                                    uint32_t *iv_off,
176                                    unsigned char iv[16],
177                                    const unsigned char *input,
178                                    unsigned char *output);
179 
180 /***************************************************************************//**
181  * @brief
182  *   AES-CFB8 buffer encryption/decryption.
183  *
184  * @param[in] cmd_ctx
185  *   Pointer to an SE command context object.
186  *
187  * @param[in] key
188  *   Pointer to sl_se_key_descriptor_t structure.
189  *
190  * @param[in] mode
191  *   Crypto operation type (encryption or decryption).
192  *
193  * @param[in] length
194  *   Length of the input data.
195  *
196  * @param[in,out] iv
197  *   Initialization vector (updated after use).
198  *
199  * @param[in] input
200  *   Buffer holding the input data.
201  *
202  * @param[out] output
203  *   Buffer holding the output data.
204  *
205  * @return
206  *   Status code, @ref sl_status.h.
207  ******************************************************************************/
208 sl_status_t sl_se_aes_crypt_cfb8(sl_se_command_context_t *cmd_ctx,
209                                  const sl_se_key_descriptor_t *key,
210                                  sl_se_cipher_operation_t mode,
211                                  size_t length,
212                                  unsigned char iv[16],
213                                  const unsigned char *input,
214                                  unsigned char *output);
215 
216 /***************************************************************************//**
217  * @brief
218  *   AES-CTR buffer encryption/decryption.
219  *
220  * @param[in] cmd_ctx
221  *   Pointer to an SE command context object.
222  *
223  * @param[in] key
224  *   Pointer to sl_se_key_descriptor_t structure.
225  *
226  * @param[in] length
227  *   Length of the input data.
228  *
229  * @param[in] nc_off
230  *   The offset in the current stream_block (for resuming
231  *   within current cipher stream). The offset pointer to
232  *   should be 0 at the start of a stream.
233  *
234  * @param[in,out] nonce_counter
235  *   The 128-bit nonce and counter.
236  *
237  * @param[in,out] stream_block
238  *   The saved stream-block for resuming (updated after use).
239  *
240  * @param[in] input
241  *   Buffer holding the input data.
242  *
243  * @param[out] output
244  *   Buffer holding the output data.
245  *
246  * @return
247  *   Status code, @ref sl_status.h.
248  ******************************************************************************/
249 sl_status_t sl_se_aes_crypt_ctr(sl_se_command_context_t *cmd_ctx,
250                                 const sl_se_key_descriptor_t *key,
251                                 size_t length,
252                                 uint32_t *nc_off,
253                                 unsigned char nonce_counter[16],
254                                 unsigned char stream_block[16],
255                                 const unsigned char *input,
256                                 unsigned char *output);
257 
258 /***************************************************************************//**
259  * @brief
260  *   AES-CCM buffer encryption.
261  *
262  * @param[in] cmd_ctx
263  *   Pointer to an SE command context object.
264  *
265  * @param[in] key
266  *   Pointer to sl_se_key_descriptor_t structure.
267  *
268  * @param[in] length
269  *   The length of the input data in Bytes.
270  *
271  * @param[in] iv
272  *   Initialization vector (nonce).
273  *
274  * @param[in] iv_len
275  *   The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
276  *
277  * @param[in] add
278  *   The additional data field.
279  *
280  * @param[in] add_len
281  *   The length of additional data in Bytes.
282  *
283  * @param[in] input
284  *   The buffer holding the input data.
285  *
286  * @param[out] output
287  *   The buffer holding the output data. Must be at least @p length Bytes wide.
288  *
289  * @param[in,out] tag
290  *   The buffer holding the tag.
291  *
292  * @param[in] tag_len
293  *   The length of the tag to generate in Bytes: 4, 6, 8, 10, 12, 14 or 16.
294  *
295  * @return
296  *   Status code, @ref sl_status.h.
297  ******************************************************************************/
298 sl_status_t sl_se_ccm_encrypt_and_tag(sl_se_command_context_t *cmd_ctx,
299                                       const sl_se_key_descriptor_t *key,
300                                       size_t length,
301                                       const unsigned char *iv, size_t iv_len,
302                                       const unsigned char *add, size_t add_len,
303                                       const unsigned char *input,
304                                       unsigned char *output,
305                                       unsigned char *tag, size_t tag_len);
306 
307 /***************************************************************************//**
308  * @brief
309  *   AES-CCM buffer decryption.
310  *
311  * @param[in] cmd_ctx
312  *   Pointer to an SE command context object.
313  *
314  * @param[in] key
315  *   Pointer to sl_se_key_descriptor_t structure.
316  *
317  * @param[in] length
318  *   The length of the input data in Bytes.
319  *
320  * @param[in] iv
321  *   Initialization vector.
322  *
323  * @param[in] iv_len
324  *   The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13.
325  *
326  * @param[in] add
327  *   The additional data field.
328  *
329  * @param[in] add_len
330  *   The length of additional data in Bytes.
331  *
332  * @param[in] input
333  *   The buffer holding the input data.
334  *
335  * @param[out] output
336  *   The buffer holding the output data. Must be at least @p length Bytes wide.
337  *
338  * @param[in] tag
339  *   The buffer holding the tag.
340  *
341  * @param[in] tag_len
342  *   The length of the tag in Bytes. Must be 4, 6, 8, 10, 12, 14 or 16.
343  *
344  * @return
345  *   Status code, @ref sl_status.h.
346  ******************************************************************************/
347 sl_status_t sl_se_ccm_auth_decrypt(sl_se_command_context_t *cmd_ctx,
348                                    const sl_se_key_descriptor_t *key,
349                                    size_t length,
350                                    const unsigned char *iv, size_t iv_len,
351                                    const unsigned char *add, size_t add_len,
352                                    const unsigned char *input,
353                                    unsigned char *output,
354                                    const unsigned char *tag, size_t tag_len);
355 
356 /***************************************************************************//**
357  * @brief
358  *   Prepare a CCM streaming command context object.
359  *
360  * @details
361  *   Prepare a CCM streaming command context object to be used in subsequent
362  *   CCM streaming function calls.
363  *
364  * @param[in] ccm_ctx
365  *   Pointer to a CCM streaming context object.
366  *
367  * @param[in] cmd_ctx
368  *   Pointer to a SE command context object.
369  *
370  * @param[in] key
371  *   Pointer to sl_se_key_descriptor_t structure.
372  *
373  * @param[in] mode
374  *   The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
375  *
376  * @param[in] total_message_length
377  *   The total length of the text to encrypt/decrypt
378  *
379  * @param[in] iv
380  *   The initialization vector (commonly referred to as nonce for CCM).
381  *
382  * @param[in] iv_len
383  *   The length of the IV.
384  *
385  * @param[in] add
386  *   The buffer holding the additional data.
387  *
388  * @param[in] add_len
389  *   The length of the additional data.
390  *
391  * @param[in] tag_len
392  *   Encryption: The length of the tag to generate. Must be 0, 4, 6, 8, 10, 12, 14 or 16.
393  *   Decryption: The length of the tag to authenticate. Must be 0, 4, 6, 8, 10, 12, 14 or 16.
394  *
395  * @return
396  *   Status code, @ref sl_status.h.
397  ******************************************************************************/
398 sl_status_t sl_se_ccm_multipart_starts(sl_se_ccm_multipart_context_t *ccm_ctx,
399                                        sl_se_command_context_t *cmd_ctx,
400                                        const sl_se_key_descriptor_t *key,
401                                        sl_se_cipher_operation_t mode,
402                                        uint32_t total_message_length,
403                                        const uint8_t *iv,
404                                        size_t iv_len,
405                                        const uint8_t *add,
406                                        size_t add_len,
407                                        size_t tag_len);
408 
409 /***************************************************************************//**
410  * @brief
411  *   This function feeds an input buffer into an ongoing CCM computation.
412  *
413  *   It is called between sl_se_ccm_multipart_starts() and sl_se_ccm_multipart_finish().
414  *   Can be called repeatedly.
415  *
416  * @param[in] ccm_ctx
417  *   Pointer to a CCM streaming context object.
418  *
419  * @param[in] cmd_ctx
420  *   Pointer to a SE command context object.
421  *
422  * @param[in] key
423  *   Pointer to sl_se_key_descriptor_t structure.
424  *
425  * @param[in] length
426  *   The length of the input data. This must be a multiple of 16 except in
427  *   the last call before sl_se_ccm_multipart_finish().
428  *
429  * @param[in] input
430  *   Buffer holding the input data, must be at least @p length bytes wide.
431  *
432  * @param[out] output
433  *   Buffer for holding the output data, must be at least @p length bytes wide.
434  *
435  * @param[out] output_length
436  *   Length of data that has been encrypted/decrypted.
437  *
438  * @return
439  *   Status code, @ref sl_status.h.
440  ******************************************************************************/
441 
442 sl_status_t sl_se_ccm_multipart_update(sl_se_ccm_multipart_context_t *ccm_ctx,
443                                        sl_se_command_context_t *cmd_ctx,
444                                        const sl_se_key_descriptor_t *key,
445                                        size_t length,
446                                        const uint8_t *input,
447                                        uint8_t *output,
448                                        size_t *output_length);
449 
450 /***************************************************************************//**
451  * @brief
452  *   Finish a CCM streaming operation and return the resulting CCM tag.
453  *
454  *   It is called after sl_se_ccm_multipart_update().
455  *
456  * @param[in] ccm_ctx
457  *   Pointer to a CCM streaming context object.
458  *
459  * @param[in] cmd_ctx
460  *   Pointer to an SE command context object.
461  *
462  * @param[in] key
463  *   Pointer to sl_se_key_descriptor_t structure.
464  *
465  * @param[in, out] tag
466  *   Encryption: The buffer for holding the tag.
467  *   Decryption: The tag to authenticate.
468  *
469  * @param[in]  tag_size
470  *   The size of the tag buffer. Must be equal or greater to the length of the expected tag.
471  *
472  * @param[out] output
473  *   Buffer for holding the output data.
474  *
475  * @param[in] output_size
476  *   Output buffer size. Must be equal or greater to the stored data from
477  *   sl_se_ccm_multipart_update (maximum 16 bytes).
478  *
479  * @param[out] output_length
480  *   Length of data that has been encrypted/decrypted.
481  *
482  * @return
483  *   Returns SL_SE_INVALID_SIGNATURE if authentication step fails.
484  *   Status code, @ref sl_status.h.
485  ******************************************************************************/
486 sl_status_t sl_se_ccm_multipart_finish(sl_se_ccm_multipart_context_t *ccm_ctx,
487                                        sl_se_command_context_t *cmd_ctx,
488                                        const sl_se_key_descriptor_t *key,
489                                        uint8_t *tag,
490                                        uint8_t  tag_size,
491                                        uint8_t *output,
492                                        uint8_t output_size,
493                                        uint8_t *output_length);
494 
495 /***************************************************************************//**
496  * @brief
497  *   This function performs GCM encryption or decryption of a buffer.
498  *
499  * @note
500  *   For encryption, the output buffer can be the same as the input buffer.
501  *   For decryption, the output buffer cannot be the same as input buffer.
502  *   If the buffers overlap, the output buffer must trail at least 8 bytes
503  *   behind the input buffer.
504  *
505  * @warning
506  *   When this function performs a decryption, it outputs the authentication
507  *   tag and does not verify that the data is authentic. You should use this
508  *   function to perform encryption only. For decryption, use
509  *   sl_se_gcm_auth_decrypt() instead.
510  *
511  * @param[in] cmd_ctx
512  *   Pointer to an SE command context object.
513  *
514  * @param[in] key
515  *   Pointer to sl_se_key_descriptor_t structure.
516  *
517  * @param[in] mode
518  *   Crypto operation type (encryption or decryption).
519  *     - SL_SE_ENCRYPT: The ciphertext is written to @p output and the
520  *                      authentication tag is written to @p tag.
521  *     - SL_SE_DECRYPT: The plaintext is written to @p output and the
522  *                      authentication tag is written to @p tag.
523  *                      Note that this mode is not recommended, because it does
524  *                      not verify the authenticity of the data. For this
525  *                      reason, you should use sl_se_gcm_auth_decrypt() instead.
526  *
527  * @param[in] length
528  *   The length of the input data, which is equal to the length of the output
529  *   data.
530  *
531  * @param[in] iv
532  *   The initialization vector.
533  *
534  * @param[in] iv_len
535  *   The length of the iv. Must be @b 12 bytes.
536  *
537  * @param[in] add
538  *   The buffer holding the additional data.
539  *
540  * @param[in] add_len
541  *   The length of the additional data in bytes.
542  *
543  * @param[in] input
544  *   The buffer holding the input data. Its size is @b length bytes.
545  *
546  * @param[out] output
547  *   The buffer for holding the output data. It must have room for @b length
548  *   bytes.
549  *
550  * @param[in] tag_len
551  *   The length of the tag to generate (in bytes).
552  *
553  * @param[out] tag
554  *   The buffer for holding the tag.
555  *
556  * @return
557  *   SL_STATUS_OK when the command was executed successfully, otherwise an
558  *   appropriate error code (@ref sl_status.h).
559  ******************************************************************************/
560 sl_status_t sl_se_gcm_crypt_and_tag(sl_se_command_context_t *cmd_ctx,
561                                     const sl_se_key_descriptor_t *key,
562                                     sl_se_cipher_operation_t mode,
563                                     size_t length,
564                                     const unsigned char *iv,
565                                     size_t iv_len,
566                                     const unsigned char *add,
567                                     size_t add_len,
568                                     const unsigned char *input,
569                                     unsigned char *output,
570                                     size_t tag_len,
571                                     unsigned char *tag);
572 
573 /***************************************************************************//**
574  * @brief
575  *   This function performs a GCM authenticated decryption of a buffer.
576  *
577  * @note
578  *   The output buffer cannot be the same as input buffer. If the buffers
579  *   overlap, the output buffer must trail at least 8 bytes behind the input
580  *   buffer.
581  *
582  * @param[in] cmd_ctx
583  *   Pointer to an SE command context object.
584  *
585  * @param[in] key
586  *   Pointer to sl_se_key_descriptor_t structure.
587  *
588  * @param[in] length
589  *   The length of the ciphertext to decrypt, which is also the length of the
590  *   decrypted plaintext.
591  *
592  * @param[in] iv
593  *   The initialization vector.
594  *
595  * @param[in] iv_len
596  *   The length of the iv. Must be @b 12 bytes.
597  *
598  * @param[in] add
599  *   The buffer holding the additional data.
600  *
601  * @param[in] add_len
602  *   The length of the additional data in bytes.
603  *
604  * @param[in] tag
605  *   The buffer holding the tag to verify.
606  *
607  * @param[in] tag_len
608  *   The length of the tag to verify (in bytes).
609  *
610  * @param[in] input
611  *   The buffer holding the ciphertext. Its size is @b length bytes.
612  *
613  * @param[out] output
614  *   The buffer for holding the decrypted plaintext. It must have room for
615  *   @b length bytes.
616  *
617  * @return
618  *   SL_STATUS_OK when the command was executed successfully, otherwise an
619  *   appropriate error code (@ref sl_status.h).
620  ******************************************************************************/
621 sl_status_t sl_se_gcm_auth_decrypt(sl_se_command_context_t *cmd_ctx,
622                                    const sl_se_key_descriptor_t *key,
623                                    size_t length,
624                                    const unsigned char *iv,
625                                    size_t iv_len,
626                                    const unsigned char *add,
627                                    size_t add_len,
628                                    const unsigned char *input,
629                                    unsigned char *output,
630                                    size_t tag_len,
631                                    const unsigned char *tag);
632 
633 /***************************************************************************//**
634  * @brief
635  *   This function calculates the full generic CMAC on the input buffer with
636  *   the provided key.
637  *
638  * @param[in] cmd_ctx
639  *   Pointer to an SE command context object.
640  *
641  * @param[in] key
642  *   Pointer to sl_se_key_descriptor_t structure.
643  *
644  * @param[in] input
645  *   Buffer holding the input data, must be at least @p input_len bytes wide.
646  *
647  * @param[in] input_len
648  *   The length of the input data in bytes.
649  *
650  * @param[out] output
651  *   Buffer holding the 16-byte output data, must be at least 16 bytes wide.
652  *
653  * @return
654  *   Status code, @ref sl_status.h.
655  ******************************************************************************/
656 sl_status_t sl_se_cmac(sl_se_command_context_t *cmd_ctx,
657                        const sl_se_key_descriptor_t *key,
658                        const unsigned char *input,
659                        size_t input_len,
660                        unsigned char *output);
661 
662 /***************************************************************************//**
663  * @brief
664  *   Prepare a CMAC streaming command context object.
665  *
666  * @details
667  *   Prepare a CMAC streaming command context object to be used in subsequent
668  *   CMAC streaming function calls.
669  *
670  * @param[in] cmac_ctx
671  *   Pointer to a CMAC streaming context object.
672  *
673  * @param[in] cmd_ctx
674  *   Pointer to an SE command context object.
675  *
676  * @param[in] key
677  *   Pointer to sl_se_key_descriptor_t structure.
678  *
679  * @return
680  *   Status code, @ref sl_status.h.
681  ******************************************************************************/
682 sl_status_t sl_se_cmac_multipart_starts(sl_se_cmac_multipart_context_t *cmac_ctx,
683                                         sl_se_command_context_t *cmd_ctx,
684                                         const sl_se_key_descriptor_t *key);
685 
686 /***************************************************************************//**
687  * @brief
688  *   Deprecated, please switch to using \ref sl_se_cmac_multipart_starts().
689  *
690  *   Prepare a CMAC streaming command context object.
691  *
692  * @details
693  *   Prepare a CMAC streaming command context object to be used in subsequent
694  *   CMAC streaming function calls.
695  *
696  * @param[in] cmac_ctx
697  *   Pointer to a CMAC streaming context object.
698  *
699  * @param[in] cmd_ctx
700  *   Pointer to an SE command context object.
701  *
702  * @param[in] key
703  *   Pointer to sl_se_key_descriptor_t structure.
704  *
705  * @return
706  *   Status code, @ref sl_status.h.
707  ******************************************************************************/
708 sl_status_t sl_se_cmac_starts(sl_se_cmac_streaming_context_t *cmac_ctx,
709                               sl_se_command_context_t *cmd_ctx,
710                               const sl_se_key_descriptor_t *key) SL_DEPRECATED_API_SDK_3_3;
711 
712 /***************************************************************************//**
713  * @brief
714  *   This function feeds an input buffer into an ongoing CMAC computation.
715  *
716  * @details
717  *   It is called between sl_se_cmac_multipart_starts() and sl_se_cmac_multipart_finish().
718  *   Can be called repeatedly.
719  *
720  * @param[in,out] cmac_ctx
721  *   Pointer to a CMAC streaming context object.
722  *
723  * @param[in] cmd_ctx
724  *   Pointer to an SE command context object.
725  *
726  * @param[in] key
727  *   Pointer to sl_se_key_descriptor_t structure.
728  *
729  * @param[in] input
730  *   Buffer holding the input data, must be at least @p input_len bytes wide.
731  *
732  * @param[in] input_len
733  *   The length of the input data in bytes.
734  *
735  * @return
736  *   Status code, @ref sl_status.h.
737  ******************************************************************************/
738 sl_status_t sl_se_cmac_multipart_update(sl_se_cmac_multipart_context_t *cmac_ctx,
739                                         sl_se_command_context_t *cmd_ctx,
740                                         const sl_se_key_descriptor_t *key,
741                                         const uint8_t *input,
742                                         size_t input_len);
743 
744 /***************************************************************************//**
745  * @brief
746  *   Deprecated, please switch to using \ref sl_se_cmac_multipart_update().
747  *
748  *   This function feeds an input buffer into an ongoing CMAC computation.
749  *
750  * @details
751  *   It is called between sl_se_cmac_multipart_starts() and sl_se_cmac_multipart_finish().
752  *   Can be called repeatedly.
753  *
754  * @param[in,out] cmac_ctx
755  *   Pointer to a CMAC streaming context object.
756  *
757  * @param[in] input
758  *   Buffer holding the input data, must be at least @p input_len bytes wide.
759  *
760  * @param[in] input_len
761  *   The length of the input data in bytes.
762  *
763  * @return
764  *   Status code, @ref sl_status.h.
765  ******************************************************************************/
766 
767 sl_status_t sl_se_cmac_update(sl_se_cmac_streaming_context_t *cmac_ctx,
768                               const uint8_t *input,
769                               size_t input_len) SL_DEPRECATED_API_SDK_3_3;
770 
771 /***************************************************************************//**
772  * @brief
773  *   Finish a CMAC streaming operation and return the resulting CMAC tag.
774  *
775  * @details
776  *   It is called after sl_se_cmac_multipart_update().
777  *
778  * @param[in,out] cmac_ctx
779  *   Pointer to a CMAC streaming context object.
780  *
781  * @param[in] cmd_ctx
782  *   Pointer to an SE command context object.
783  *
784  * @param[in] key
785  *   Pointer to sl_se_key_descriptor_t structure.
786  *
787  * @param[out] output
788  *   Buffer holding the 16-byte CMAC tag, must be at least 16 bytes wide.
789  *
790  * @return
791  *   Status code, @ref sl_status.h.
792  ******************************************************************************/
793 sl_status_t sl_se_cmac_multipart_finish(sl_se_cmac_multipart_context_t *cmac_ctx,
794                                         sl_se_command_context_t *cmd_ctx,
795                                         const sl_se_key_descriptor_t *key,
796                                         uint8_t *output);
797 
798 /***************************************************************************//**
799  * @brief
800  *   Deprecated, please switch to using \ref sl_se_cmac_multipart_finish().
801  *
802  *   Finish a CMAC streaming operation and return the resulting CMAC tag.
803  *
804  * @details
805  *   It is called after sl_se_cmac_update().
806  *
807  * @param[in,out] cmac_ctx
808  *   Pointer to a CMAC streaming context object.
809  *
810  * @param[out] output
811  *   Buffer holding the 16-byte CMAC tag, must be at least 16 bytes wide.
812  *
813  * @return
814  *   Status code, @ref sl_status.h.
815  ******************************************************************************/
816 sl_status_t sl_se_cmac_finish(sl_se_cmac_streaming_context_t *cmac_ctx,
817                               uint8_t *output) SL_DEPRECATED_API_SDK_3_3;
818 
819 /***************************************************************************//**
820  * @brief
821  *   Deprecated, please switch to using \ref sl_se_gcm_multipart_starts().
822  *
823  *   Prepare a GCM streaming command context object.
824  * @details
825  *   Prepare a GCM streaming command context object to be used in subsequent
826  *   GCM streaming function calls.
827  *
828  * @param[in] gcm_ctx
829  *   Pointer to a GCM streaming context object.
830  *
831  * @param[in] cmd_ctx
832  *   Pointer to an SE command context object.
833  *
834  * @param[in] key
835  *   Pointer to sl_se_key_descriptor_t structure.
836  *
837  * @param mode
838  *   The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
839  *
840  * @param iv
841  *   The initialization vector.
842  *
843  * @param iv_len
844  *   The length of the IV.
845  *
846  * @param add
847  *   The buffer holding the additional data, or NULL if @p add_len is 0.
848  *
849  * @param add_len
850  *   The length of the additional data. If 0, @p  add is NULL.
851  *
852  * @return
853  *   Status code, @ref sl_status.h.
854  ******************************************************************************/
855 sl_status_t sl_se_gcm_starts(sl_se_gcm_streaming_context_t *gcm_ctx,
856                              sl_se_command_context_t *cmd_ctx,
857                              const sl_se_key_descriptor_t *key,
858                              sl_se_cipher_operation_t mode,
859                              const uint8_t *iv,
860                              size_t iv_len,
861                              const uint8_t *add,
862                              size_t add_len) SL_DEPRECATED_API_SDK_3_3;
863 
864 /***************************************************************************//**
865  * @brief
866  *   Prepare a GCM streaming command context object.
867  *
868  * @details
869  *   Prepare a GCM streaming command context object to be used in subsequent
870  *   GCM streaming function calls.
871  *
872  * @param[in, out] gcm_ctx
873  *   Pointer to a GCM streaming context object.
874  *
875  * @param[in] cmd_ctx
876  *   Pointer to an SE command context object.
877  *
878  * @param[in] key
879  *   Pointer to sl_se_key_descriptor_t structure.
880  *
881  * @param[in] mode
882  *   The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
883  *
884  * @param[in] iv
885  *   The initialization vector.
886  *
887  * @param[in] iv_len
888  *   The length of the IV.
889  *
890  * @param[in] add
891  *   The buffer holding the additional data, or NULL if @p add_len is 0.
892  *
893  * @param[in] add_len
894  *   The length of the additional data. If 0, @p  add is NULL.
895  *
896  * @return
897  *   Status code, @ref sl_status.h.
898  ******************************************************************************/
899 sl_status_t sl_se_gcm_multipart_starts(sl_se_gcm_multipart_context_t *gcm_ctx,
900                                        sl_se_command_context_t *cmd_ctx,
901                                        const sl_se_key_descriptor_t *key,
902                                        sl_se_cipher_operation_t mode,
903                                        const uint8_t *iv,
904                                        size_t iv_len,
905                                        const uint8_t *add,
906                                        size_t add_len);
907 
908 /***************************************************************************//**
909  * @brief
910  *  Deprecated, please switch to using \ref sl_se_gcm_multipart_update().
911  *
912  *   This function feeds an input buffer into an ongoing GCM computation.
913  *
914  *   It is called between sl_se_gcm_starts() and sl_se_gcm_finish().
915  *   Can be called repeatedly.
916  *
917  * @param[in] gcm_ctx
918  *   Pointer to a GCM streaming context object.
919  *
920  * @param[in] length
921  *   The length of the input data. This must be a multiple of 16 except in
922  *   the last call before sl_se_gcm_finish().
923  *
924  * @param[in] input
925  *   Buffer holding the input data, must be at least @p length bytes wide.
926  *
927  * @param[out] output
928  *   Buffer for holding the output data, must be at least @p length bytes wide.
929  *
930  * @return
931  *   Status code, @ref sl_status.h.
932  ******************************************************************************/
933 sl_status_t sl_se_gcm_update(sl_se_gcm_streaming_context_t *gcm_ctx,
934                              size_t length,
935                              const uint8_t *input,
936                              uint8_t *output) SL_DEPRECATED_API_SDK_3_3;
937 
938 /***************************************************************************//**
939  * @brief
940  *   This function feeds an input buffer into an ongoing GCM computation.
941  *
942  *   It is called between sl_se_gcm_multipart_starts() and sl_se_gcm_multiapart_finish().
943  *   Can be called repeatedly.
944  *
945  * @param[in, out] gcm_ctx
946  *   Pointer to a GCM streaming context object.
947  *
948  * @param[in] length
949  *   The length of the input data.
950  *
951  * @param[in] input
952  *   Buffer holding the input data, must be at least @p length bytes wide.
953  *
954  * @param[out] output
955  *   Buffer for holding the output data, must be at least @p length bytes wide.
956  *
957  * @param[out] output_length
958  *   Length of data that has been encrypted/decrypted.
959  *
960  * @return
961  *   Status code, @ref sl_status.h.
962  ******************************************************************************/
963 sl_status_t sl_se_gcm_multipart_update(sl_se_gcm_multipart_context_t *gcm_ctx,
964                                        sl_se_command_context_t *cmd_ctx,
965                                        const sl_se_key_descriptor_t *key,
966                                        size_t length,
967                                        const uint8_t *input,
968                                        uint8_t *output,
969                                        size_t *output_length);
970 
971 /***************************************************************************//**
972  * @brief
973  *   Deprecated, please switch to using \ref sl_se_gcm_multipart_finish().
974  *
975  *   Finish a GCM streaming operation and return the resulting GCM tag.
976  *
977  *   It is called after sl_se_gcm_update().
978  *
979  * @param[in] gcm_ctx
980  *   Pointer to a GCM streaming context object.
981  *
982  * @param[out] tag
983  *   The buffer for holding the tag.
984  *
985  * @param[in]  tag_len
986  *   The length of the tag to generate. Must be at least four.
987  *
988  * @return
989  *   Status code, @ref sl_status.h.
990  ******************************************************************************/
991 sl_status_t sl_se_gcm_finish(sl_se_gcm_streaming_context_t *gcm_ctx,
992                              uint8_t *tag,
993                              size_t   tag_len) SL_DEPRECATED_API_SDK_3_3;
994 
995 /***************************************************************************//**
996  * @brief
997  *   Finish a GCM streaming operation and return the resulting GCM tag.
998  *
999  *   It is called after sl_se_gcm_multipart_update().
1000  *
1001  * @param[in, out] gcm_ctx
1002  *   Pointer to a GCM streaming context object.
1003  *
1004  * @param[in, out] tag
1005  *   Encryption: The buffer for holding the tag.
1006  *   Decryption: The tag to authenticate.
1007  *
1008  * @param[in]  tag_length
1009  *   Encryption: Length of the output tag.
1010  *   Decryption: Length of tag to verify
1011  *
1012  * @param[out] output
1013  *   Buffer for holding the output data.
1014  *
1015  * @param[in] output_size
1016  *   Output buffer size. Must be equal or greater to the stored data from
1017  *   sl_se_gcm_multipart_update (stored data is maximum 16 bytes).
1018  *
1019  * @param[out] output_length
1020  *   Length of data that has been encrypted/decrypted.
1021  *
1022  * @return
1023  *   Returns SL_SE_INVALID_SIGNATURE if authentication step fails.
1024  *   Status code, @ref sl_status.h.
1025  ******************************************************************************/
1026 sl_status_t sl_se_gcm_multipart_finish(sl_se_gcm_multipart_context_t *gcm_ctx,
1027                                        sl_se_command_context_t *cmd_ctx,
1028                                        const sl_se_key_descriptor_t *key,
1029                                        uint8_t *tag,
1030                                        uint8_t tag_length,
1031                                        uint8_t *output,
1032                                        uint8_t output_size,
1033                                        uint8_t *output_length);
1034 
1035 /***************************************************************************//**
1036  * @brief
1037  *   Compute a HMAC on a full message.
1038  *
1039  * @details
1040  *   This function computes a Keyed-Hashed Message Authentication Code (HMAC)
1041  *   for the given input message. HMAC can be used with any iterative
1042  *   cryptographic hash function, e.g., SHA-1 in combination with a
1043  *   secret shared key.  The cryptographic strength of HMAC depends on the
1044  *   properties of the underlying hash function. For instance, if the algorithm
1045  *   is chosen to be SHA-256, it will generate a 32 bytes HMAC.
1046  *   This function supports SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512.
1047  *   The key can be of any length. If the key is shorter than the block size
1048  *   of the hash function the SE will append zeros to the key so the key size
1049  *   matches the block size of the hash function. If the key is longer than the
1050  *   block size of the hash function the key will be hashed to
1051  *   produce a key digest, then append zeros so the resulting 'hashed' key size
1052  *   matches the block size of the hash function. In any case the minimal
1053  *   recommended key length is the digest size of the hash function.
1054  *
1055  * @param[in] cmd_ctx
1056  *   Pointer to an SE command context object.
1057  *
1058  * @param[in] key
1059  *   Pointer to sl_se_key_descriptor_t structure specifying the key to use in
1060  *   the HMAC computation.
1061  *
1062  * @param[in] hash_type
1063  *   Which hashing algorithm to use.
1064  *
1065  * @param[in] message
1066  *   Pointer to the message buffer to compute the hash/digest from.
1067  *
1068  * @param[in] message_len
1069  *   Number of bytes in message.
1070  *
1071  * @param[out] output
1072  *   Pointer to memory buffer to store the final HMAC output.
1073  *
1074  * @param[in]  output_len
1075  *   The length of the HMAC output memory buffer, must be at least the size
1076  *   of the corresponding hash type.
1077  *
1078  * @return Status code, @ref sl_status.h.
1079  ******************************************************************************/
1080 sl_status_t sl_se_hmac(sl_se_command_context_t *cmd_ctx,
1081                        const sl_se_key_descriptor_t *key,
1082                        sl_se_hash_type_t hash_type,
1083                        const uint8_t *message,
1084                        size_t message_len,
1085                        uint8_t *output,
1086                        size_t output_len);
1087 
1088 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
1089 /***************************************************************************//**
1090  * @brief
1091  *   ChaCha20 buffer encryption/decryption, as defined by RFC8439 section 2.4.
1092  *
1093  * @param[in] cmd_ctx
1094  *   Pointer to an SE command context object.
1095  *
1096  * @param[in] mode
1097  *   Crypto operation type (encryption or decryption).
1098  *
1099  * @param[in] key
1100  *   Pointer to sl_se_key_descriptor_t structure.
1101  *
1102  * @param[in] length
1103  *   Length of the input data.
1104  *
1105  * @param[in] initial_counter
1106  *   The initial counter value as defined in RFC8439 section 2.4.
1107  *
1108  * @param[in] nonce
1109  *   The nonce, also called initialisation vector, as defined in RFC8439 section
1110  *   2.4.
1111  *
1112  * @param[in] input
1113  *   Buffer holding the input data.
1114  *
1115  * @param[out] output
1116  *   Buffer holding the output data.
1117  *
1118  * @return
1119  *   Status code, @ref sl_status.h.
1120  ******************************************************************************/
1121 sl_status_t sl_se_chacha20_crypt(sl_se_command_context_t *cmd_ctx,
1122                                  sl_se_cipher_operation_t mode,
1123                                  const sl_se_key_descriptor_t *key,
1124                                  size_t length,
1125                                  const unsigned char initial_counter[4],
1126                                  const unsigned char nonce[12],
1127                                  const unsigned char *input,
1128                                  unsigned char *output);
1129 
1130 /***************************************************************************//**
1131  * @brief
1132  *   ChaCha20-Poly1305 authenticated encryption with additional data, as defined
1133  *   by RFC8439 section 2.8.
1134  *
1135  * @param[in] cmd_ctx
1136  *   Pointer to an SE command context object.
1137  *
1138  * @param[in] key
1139  *   Pointer to sl_se_key_descriptor_t structure.
1140  *
1141  * @param[in] length
1142  *   The length of the input data in bytes.
1143  *
1144  * @param[in] nonce
1145  *   The nonce, also called initialisation vector, as defined in RFC8439 section
1146  *   2.8.
1147  *
1148  * @param[in] add
1149  *   The buffer holding additional authenticated data. Can be NULL if @p add_len
1150  *   equals 0.
1151  *
1152  * @param[in] add_len
1153  *   The length of the additional authenticated data in bytes.
1154  *
1155  * @param[in] input
1156  *   The buffer holding the plaintext input.
1157  *
1158  * @param[out] output
1159  *   The buffer holding the ciphertext output. Can be NULL, in which case the
1160  *   generated ciphertext will be discarded. Must be at least @p length bytes
1161  *   wide.
1162  *
1163  * @param[out] tag
1164  *   The buffer holding the tag. This function will produce a 128-bit tag, so
1165  *   this buffer must be at least 16 bytes wide. Can be NULL, in which case the
1166  *   generated tag will be discarded.
1167  *
1168  * @return
1169  *   Status code, @ref sl_status.h.
1170  ******************************************************************************/
1171 sl_status_t sl_se_chacha20_poly1305_encrypt_and_tag(sl_se_command_context_t *cmd_ctx,
1172                                                     const sl_se_key_descriptor_t *key,
1173                                                     size_t length,
1174                                                     const unsigned char nonce[12],
1175                                                     const unsigned char *add, size_t add_len,
1176                                                     const unsigned char *input,
1177                                                     unsigned char *output,
1178                                                     unsigned char *tag);
1179 
1180 /***************************************************************************//**
1181  * @brief
1182  *   ChaCha20-Poly1305 authenticated decryption with additional data, as defined
1183  *   by RFC8439 section 2.8.
1184  *
1185  * @param[in] cmd_ctx
1186  *   Pointer to an SE command context object.
1187  *
1188  * @param[in] key
1189  *   Pointer to sl_se_key_descriptor_t structure.
1190  *
1191  * @param[in] length
1192  *   The length of the input data in Bytes.
1193  *
1194  * @param[in] nonce
1195  *   The nonce, also called initialisation vector, as defined in RFC8439 section
1196  *   2.8.
1197  *
1198  * @param[in] add
1199  *   The buffer holding additional authenticated data. Can be NULL if @p add_len
1200  *   equals 0.
1201  *
1202  * @param[in] add_len
1203  *   The length of the additional authenticated data in bytes.
1204  *
1205  * @param[in] input
1206  *   The buffer holding the ciphertext to decrypt. Can be NULL if @p length
1207  *   equals 0.
1208  *
1209  * @param[out] output
1210  *   The buffer holding the plaintext output. Can be NULL, in which case the
1211  *   decrypted plaintext will be discarded, or when @p length equals 0. Must be
1212  *   at least @p length bytes wide.
1213  *
1214  * @param[in] tag
1215  *   The buffer holding the tag to verify.
1216  *
1217  * @return
1218  *   Status code, @ref sl_status.h.
1219  ******************************************************************************/
1220 sl_status_t sl_se_chacha20_poly1305_auth_decrypt(sl_se_command_context_t *cmd_ctx,
1221                                                  const sl_se_key_descriptor_t *key,
1222                                                  size_t length,
1223                                                  const unsigned char nonce[12],
1224                                                  const unsigned char *add, size_t add_len,
1225                                                  const unsigned char *input,
1226                                                  unsigned char *output,
1227                                                  const unsigned char tag[16]);
1228 
1229 /***************************************************************************//**
1230  * @brief
1231  *   Generate a Poly1305 MAC (message authentication code) for a given message
1232  *   using an ephemeral key derived using ChaCha20.
1233  *
1234  * @note
1235  *   This function first derives a Poly1305 key based on a ChaCha20 key and
1236  *   nonce, which are input to this function. The key derivation adheres to
1237  *   RFC8439 section 2.6. The derived key is then used to calculate a MAC of the
1238  *   input data, according to RFC8439 section 2.5.
1239  *
1240  * @param[in] cmd_ctx
1241  *   Pointer to an SE command context object.
1242  *
1243  * @param[in] key
1244  *   Pointer to sl_se_key_descriptor_t structure containing a ChaCha20 key.
1245  *
1246  * @param[in] length
1247  *   The length of the input data in Bytes.
1248  *
1249  * @param[in] nonce
1250  *   The nonce, also called initialisation vector, as defined in RFC8439 section
1251  *   2.6.
1252  *
1253  * @param[in] input
1254  *   The buffer holding the input data.
1255  *
1256  * @param[out] tag
1257  *   The buffer holding the tag. This function will produce a 128-bit tag, so
1258  *   this buffer must be at least 16 bytes wide.
1259  *
1260  * @return
1261  *   Status code, @ref sl_status.h.
1262  ******************************************************************************/
1263 sl_status_t sl_se_poly1305_genkey_tag(sl_se_command_context_t *cmd_ctx,
1264                                       const sl_se_key_descriptor_t *key,
1265                                       size_t length,
1266                                       const unsigned char nonce[12],
1267                                       const unsigned char *input,
1268                                       unsigned char *tag);
1269 
1270 #endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
1271 
1272 #ifdef __cplusplus
1273 }
1274 #endif
1275 
1276 /// @} (end addtogroup sl_se_manager_cipher)
1277 /// @} (end addtogroup sl_se_manager)
1278 
1279 #endif // defined(SEMAILBOX_PRESENT)
1280 
1281 #endif // SL_SE_MANAGER_CIPHER_H
1282