1 /***************************************************************************//**
2  * @file
3  * @brief Accelerated cryptographic primitives using the CRYPTO and RADIOAES
4  *        peripherals, for series-1 and series-2 respectively.
5  *******************************************************************************
6  * # License
7  * <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
8  *******************************************************************************
9  *
10  * SPDX-License-Identifier: Zlib
11  *
12  * The licensor of this software is Silicon Laboratories Inc.
13  *
14  * This software is provided 'as-is', without any express or implied
15  * warranty. In no event will the authors be held liable for any damages
16  * arising from the use of this software.
17  *
18  * Permission is granted to anyone to use this software for any purpose,
19  * including commercial applications, and to alter it and redistribute it
20  * freely, subject to the following restrictions:
21  *
22  * 1. The origin of this software must not be misrepresented; you must not
23  *    claim that you wrote the original software. If you use this software
24  *    in a product, an acknowledgment in the product documentation would be
25  *    appreciated but is not required.
26  * 2. Altered source versions must be plainly marked as such, and must not be
27  *    misrepresented as being the original software.
28  * 3. This notice may not be removed or altered from any source distribution.
29  *
30  ******************************************************************************/
31 #ifndef SLI_PROTOCOL_CRYPTO_H
32 #define SLI_PROTOCOL_CRYPTO_H
33 
34 /// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
35 
36 /***************************************************************************//**
37  * @addtogroup sli_protocol_crypto
38  * @brief Accelerated cryptographic primitives using the CRYPTO and RADIOAES
39  *        peripherals, for series-1 and series-2 respectively.
40  * @{
41  ******************************************************************************/
42 
43 #include "sl_status.h"
44 #include "em_device.h"
45 #include <stddef.h>
46 #include <stdint.h>
47 #include <stdbool.h>
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 
53 /***************************************************************************//**
54  * @brief          Initialise Silabs internal protocol crypto library
55  *
56  * @return         SL_STATUS_OK if successful, relevant status code on error
57  ******************************************************************************/
58 sl_status_t sli_protocol_crypto_init(void);
59 
60 /***************************************************************************//**
61  * @brief          AES-CTR block encryption/decryption optimized for radio
62  *
63  * @param key      AES key
64  * @param keybits  must be 128 or 256
65  * @param input    16-byte input block
66  * @param iv_in    16-byte counter/IV starting value
67  * @param iv_out   16-byte counter/IV output after block round
68  * @param output   16-byte output block
69  *
70  * @return         SL_STATUS_OK if successful, relevant status code on error
71  ******************************************************************************/
72 sl_status_t sli_aes_crypt_ctr_radio(const unsigned char    *key,
73                                     unsigned int           keybits,
74                                     const unsigned char    input[16],
75                                     const unsigned char    iv_in[16],
76                                     volatile unsigned char iv_out[16],
77                                     volatile unsigned char output[16]);
78 
79 /***************************************************************************//**
80  * @brief          AES-ECB block encryption/decryption optimized for radio
81  *
82  * @param encrypt  true for encryption, false for decryption
83  * @param key      AES key
84  * @param keybits  must be 128 or 256
85  * @param input    16-byte input block
86  * @param output   16-byte output block
87  *
88  * @return         SL_STATUS_OK if successful, relevant status code on error
89  ******************************************************************************/
90 sl_status_t sli_aes_crypt_ecb_radio(bool                   encrypt,
91                                     const unsigned char    *key,
92                                     unsigned int           keybits,
93                                     const unsigned char    input[16],
94                                     volatile unsigned char output[16]);
95 
96 #if defined(RADIOAES_PRESENT)
97 /***************************************************************************//**
98  * @brief          AES-CMAC calculation optimized for radio
99  *
100  * @param key      AES key
101  * @param keybits  Must be 128 or 256
102  * @param input    Input buffer containing the message to be signed
103  * @param length   Amount of bytes in the input buffer
104  * @param output   16-byte output block for calculated CMAC
105  *
106  * @return         SL_STATUS_OK if successful, relevant status code on error
107  ******************************************************************************/
108 sl_status_t sli_aes_cmac_radio(const unsigned char    *key,
109                                unsigned int           keybits,
110                                const unsigned char    *input,
111                                unsigned int           length,
112                                volatile unsigned char output[16]);
113 
114 /***************************************************************************//**
115  * @brief         Seeds the AES mask. It is recommended to call this function
116                   during initialization in order to avoid taking the potential
117                   hit of requesting RNG output in an IRQ context.
118  ******************************************************************************/
119 void sli_aes_seed_mask(void);
120 #endif
121 
122 /***************************************************************************//**
123  * @brief          CCM buffer authenticated decryption optimized for BLE
124  *
125  * @param data     Input/output buffer of payload data of BLE packet
126  * @param length   length of input data
127  * @param iv       nonce (initialization vector)
128  *                 must be 13 bytes
129  * @param header   header of BLE packet (1 byte)
130  * @param tag      authentication tag of BLE packet (4 bytes)
131  *
132  * @return         SL_STATUS_OK if successful and authenticated,
133  *                 SL_STATUS_INVALID_SIGNATURE if tag does not match payload,
134  *                 relevant status code on other error
135  ******************************************************************************/
136 sl_status_t sli_ccm_auth_decrypt_ble(unsigned char       *data,
137                                      size_t              length,
138                                      const unsigned char *key,
139                                      const unsigned char *iv,
140                                      unsigned char       header,
141                                      unsigned char       *tag);
142 
143 /***************************************************************************//**
144  * @brief          CCM buffer encryption optimized for BLE
145  *
146  * @param data     Input/output buffer of payload data of BLE packet
147  * @param length   length of input data
148  * @param iv       nonce (initialization vector)
149  *                 must be 13 bytes
150  * @param header   header of BLE packet (1 byte)
151  * @param tag      buffer where the BLE packet tag (4 bytes) will be written
152  *
153  * @return         SL_STATUS_OK if successful, relevant status code on error
154  ******************************************************************************/
155 sl_status_t sli_ccm_encrypt_and_tag_ble(unsigned char       *data,
156                                         size_t              length,
157                                         const unsigned char *key,
158                                         const unsigned char *iv,
159                                         unsigned char       header,
160                                         unsigned char       *tag);
161 
162 /***************************************************************************//**
163  * @brief          CCM buffer authenticated decryption optimized for Zigbee
164  *
165  * @param data     Input/output buffer of payload data (decrypt-in-place)
166  * @param length   length of input data
167  * @param iv       nonce (initialization vector)
168  *                 must be 13 bytes
169  * @param aad      Input buffer of Additional Authenticated Data
170  * @param aad_len  Length of buffer @p aad
171  * @param tag      authentication tag
172  * @param tag_len  Length of authentication tag
173  *
174  * @return         SL_STATUS_OK if successful and authenticated,
175  *                 SL_STATUS_INVALID_SIGNATURE if tag does not match payload,
176  *                 relevant status code on other error
177  ******************************************************************************/
178 sl_status_t sli_ccm_zigbee(bool encrypt,
179                            const unsigned char *data_in,
180                            unsigned char       *data_out,
181                            size_t              length,
182                            const unsigned char *key,
183                            const unsigned char *iv,
184                            const unsigned char *aad,
185                            size_t              aad_len,
186                            unsigned char       *tag,
187                            size_t              tag_len);
188 
189 /***************************************************************************//**
190  * @brief          Process a table of BLE RPA device keys and look for a
191  *                 match against the supplied hash
192  *
193  * @param keytable Pointer to an array of AES-128 keys, corresponding to the
194  *                 per-device key in the BLE RPA process
195  * @param keymask  Bitmask indicating with key indices in keytable are valid
196  * @param prand    24-bit BLE nonce to encrypt with each key and match against hash
197  * @param hash     BLE RPA hash to match against (last 24 bits of AES result)
198  *
199  * @return         0-based index of matching key if a match is found, -1 for no match.
200  ******************************************************************************/
201 int sli_process_ble_rpa(const unsigned char keytable[],
202                         uint32_t            keymask,
203                         uint32_t            prand,
204                         uint32_t            hash);
205 
206 #ifdef __cplusplus
207 }
208 #endif
209 
210 /// @} (end addtogroup sli_protocol_crypto)
211 /// @endcond
212 #endif // SLI_PROTOCOL_CRYPTO_H
213