xref: /btstack/src/btstack_crypto.h (revision cd5f23a3250874824c01a2b3326a9522fea3f99f)
1 /*
2  * Copyright (C) 2017 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 /*
39  * btstack_crypto.h
40  *
41  * Central place for all crypto-related functions with completion callbacks to allow
42  * using of MCU crypto peripherals or the Bluetooth controller
43  */
44 
45 #ifndef BTSTACK_CTRYPTO_H
46 #define BTSTACK_CTRYPTO_H
47 
48 #include "btstack_defines.h"
49 #include "btstack_config.h"
50 
51 #if defined __cplusplus
52 extern "C" {
53 #endif
54 
55 #define CMAC_TEMP_API
56 
57 typedef enum {
58 	BTSTACK_CRYPTO_RANDOM,
59 	BTSTACK_CRYPTO_AES128,
60 	BTSTACK_CRYPTO_CMAC_GENERATOR,
61 	BTSTACK_CRYPTO_CMAC_MESSAGE,
62 	BTSTACK_CRYPTO_ECC_P256_GENERATE_KEY,
63 	BTSTACK_CRYPTO_ECC_P256_CALCULATE_DHKEY,
64 	BTSTACK_CRYPTO_CCM_DIGEST_BLOCK,
65 	BTSTACK_CRYPTO_CCM_ENCRYPT_BLOCK,
66 	BTSTACK_CRYPTO_CCM_DECRYPT_BLOCK,
67 } btstack_crypto_operation_t;
68 
69 typedef struct {
70 	btstack_context_callback_registration_t context_callback;
71 	btstack_crypto_operation_t              operation;
72 } btstack_crypto_t;
73 
74 typedef struct {
75 	btstack_crypto_t btstack_crypto;
76 	uint8_t  * buffer;
77 	uint16_t   size;
78 } btstack_crypto_random_t;
79 
80 typedef struct {
81 	btstack_crypto_t btstack_crypto;
82 	const uint8_t  * key;
83 	const uint8_t  * plaintext;
84 	uint8_t  * ciphertext;
85 } btstack_crypto_aes128_t;
86 
87 typedef struct {
88 	btstack_crypto_t btstack_crypto;
89 	const uint8_t  * key;
90 	uint16_t         size;
91 	union {
92 		uint8_t (*get_byte_callback)(uint16_t pos);
93 		const uint8_t * message;
94 	} data;
95 	uint8_t  * hash;
96 } btstack_crypto_aes128_cmac_t;
97 
98 typedef struct {
99 	btstack_crypto_t btstack_crypto;
100 	uint8_t * public_key;
101     uint8_t * dhkey;
102 } btstack_crypto_ecc_p256_t;
103 
104 typedef enum {
105     CCM_CALCULATE_X1,
106     CCM_W4_X1,
107     CCM_CALCULATE_AAD_XN,
108     CCM_W4_AAD_XN,
109     CCM_CALCULATE_XN,
110     CCM_W4_XN,
111     CCM_CALCULATE_S0,
112     CCM_W4_S0,
113     CCM_CALCULATE_SN,
114     CCM_W4_SN,
115 } btstack_crypto_ccm_state_t;
116 
117 typedef struct {
118 	btstack_crypto_t btstack_crypto;
119 	btstack_crypto_ccm_state_t state;
120 	const uint8_t * key;
121 	const uint8_t * nonce;
122 	const uint8_t * input;
123 	uint8_t       * output;
124 	uint8_t         x_i[16];
125 	uint16_t        aad_offset;
126 	uint16_t        aad_len;
127 	uint16_t        message_len;
128 	uint16_t        counter;
129 	uint16_t        block_len;
130 	uint8_t         auth_len;
131 	uint8_t         aad_remainder_len;
132 } btstack_crypto_ccm_t;
133 
134 /**
135  * Initialize crypto functions
136  */
137 void btstack_crypto_init(void);
138 
139 /**
140  * Generate random data
141  * @param request
142  * @param buffer for output
143  * @param size of requested random data
144  * @param callback
145  * @param callback_arg
146  * @note request needs to stay avaliable until callback (i.e. not provided on stack)
147  */
148 void btstack_crypto_random_generate(btstack_crypto_random_t * request, uint8_t * buffer, uint16_t size, void (* callback)(void * arg), void * callback_arg);
149 
150 /**
151  * Encrypt plaintext using AES128
152  * @param request
153  * @param key (16 bytes)
154  * @param plaintext (16 bytes)
155  * @param ciphertext (16 bytes)
156  * @param callback
157  * @param callback_arg
158  * @note request needs to stay avaliable until callback (i.e. not provided on stack)
159  */
160 void btstack_crypto_aes128_encrypt(btstack_crypto_aes128_t * request, const uint8_t * key, const uint8_t * plaintext, uint8_t * ciphertext, void (* callback)(void * arg), void * callback_arg);
161 
162 /**
163  * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and a generator function to provide data
164  * @param request
165  * @param key (16 bytes)
166  * @param size of message
167  * @param generator provides byte at requested position
168  * @param callback
169  * @param callback_arg
170  */
171 void btstack_crypto_aes128_cmac_generator(btstack_crypto_aes128_cmac_t * request, const uint8_t * key, uint16_t size, uint8_t (*get_byte_callback)(uint16_t pos), uint8_t * hash, void (* callback)(void * arg), void * callback_arg);
172 
173 /**
174  * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and complete message
175  * @param request
176  * @param key (16 bytes)
177  * @param len of message
178  * @param message
179  * @param hash result
180  * @param callback
181  * @param callback_arg
182  */
183 void btstack_crypto_aes128_cmac_message(btstack_crypto_aes128_cmac_t * request, const uint8_t * key, uint16_t len, const uint8_t * message,  uint8_t * hash, void (* callback)(void * arg), void * callback_arg);
184 
185 /**
186  * Calculate AES128-CMAC with key ZERO and complete message
187  * @param request
188  * @param len of message
189  * @param message
190  * @param hash
191  * @param callback
192  * @param callback_arg
193  */
194 void btstack_crypto_aes128_cmac_zero(btstack_crypto_aes128_cmac_t * request, uint16_t len, const uint8_t * message,  uint8_t * hash, void (* callback)(void * arg), void * callback_arg);
195 
196 /**
197  * Generate Elliptic Curve Public/Private Key Pair (FIPS P-256)
198  * @note BTstack uses a single ECC key pair per reset.
199  * @note If LE Controller is used for ECC, private key cannot be read or managed
200  * @param request
201  * @param public_key (64 bytes)
202  * @param callback
203  * @param callback_arg
204  */
205 void btstack_crypto_ecc_p256_generate_key(btstack_crypto_ecc_p256_t * request, uint8_t * public_key, void (* callback)(void * arg), void * callback_arg);
206 
207 /**
208  * Calculate Diffie-Hellman Key based on local private key and remote public key
209  * @param request
210  * @param public_key (64 bytes)
211  * @param dhkey (32 bytes)
212  * @param callback
213  * @param callback_arg
214  */
215 void btstack_crypto_ecc_p256_calculate_dhkey(btstack_crypto_ecc_p256_t * request, const uint8_t * public_key, uint8_t * dhkey, void (* callback)(void * arg), void * callback_arg);
216 
217 /*
218  * Validate public key (not implemented for LE Controller ECC)
219  * @param public_key (64 bytes)
220  * @result 0 == valid
221  */
222 int btstack_crypto_ecc_p256_validate_public_key(const uint8_t * public_key);
223 
224 /**
225  * Initialize Counter with CBC-MAC for Bluetooth Mesh (L=2)
226  * @param request
227  * @param nonce
228  * @param key
229  * @param message_len
230  * @param additional_authenticated_data_len must be smaller than 0xff00
231  * @param auth_len
232  */
233 void btstack_crypto_ccm_init(btstack_crypto_ccm_t * request, const uint8_t * key, const uint8_t * nonce, uint16_t message_len, uint16_t additional_authenticated_data_len, uint8_t auth_len);
234 
235 /**
236  * Get authentication value after encrypt or decrypt operation
237  * @param request
238  * @param authentication_value
239  */
240 void btstack_crypto_ccm_get_authentication_value(btstack_crypto_ccm_t * request, uint8_t * authentication_value);
241 
242 /**
243  * Digest Additional Authentication Data - can be called multipled times up to total additional_authenticated_data_len specified in btstack_crypto_ccm_init
244  * @param request
245  * @param additional_authenticated_data
246  * @param additional_authenticated_data_len
247  * @param callback
248  * @param callback_arg
249  */
250 void btstack_crypto_ccm_digest(btstack_crypto_ccm_t * request, uint8_t * additional_authenticated_data, uint16_t additional_authenticated_data_len, void (* callback)(void * arg), void * callback_arg);
251 
252 /**
253  * Encrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call
254  * @param request
255  * @param len (16 bytes for all but the last block)
256  * @param plaintext  (16 bytes)
257  * @param ciphertext (16 bytes)
258  * @param callback
259  * @param callback_arg
260  */
261 void btstack_crypto_ccm_encrypt_block(btstack_crypto_ccm_t * request, uint16_t len, const uint8_t * plaintext, uint8_t * ciphertext, void (* callback)(void * arg), void * callback_arg);
262 
263 /**
264  * Decrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call
265  * @param request
266  * @param len (16 for all but last block)
267  * @param ciphertext (16 bytes)
268  * @param plaintext  (16 bytes)
269  * @param callback
270  * @param callback_arg
271  */
272 void btstack_crypto_ccm_decrypt_block(btstack_crypto_ccm_t * request, uint16_t len, const uint8_t * ciphertext, uint8_t * plaintext, void (* callback)(void * arg), void * callback_arg);
273 
274 #if defined(ENABLE_SOFTWARE_AES128) || defined (HAVE_AES128)
275 /**
276  * Encrypt plaintext using AES128
277  * @note Prototype for custom AES128 implementation
278  * @param key (16 bytes)
279  * @param plaintext (16 bytes)
280  * @param ciphertext (16 bytes)
281  */
282 void btstack_aes128_calc(const uint8_t * key, const uint8_t * plaintext, uint8_t * ciphertext);
283 #endif
284 
285 /**
286  * @brief De-Init BTstack Crypto
287  */
288 void btstack_crypto_deinit(void);
289 
290 // PTS testing only - not possible when using Buetooth Controller for ECC operations
291 void btstack_crypto_ecc_p256_set_key(const uint8_t * public_key, const uint8_t * private_key);
292 
293 // Unit testing
294 int btstack_crypto_idle(void);
295 void btstack_crypto_reset(void);
296 
297 #if defined __cplusplus
298 }
299 #endif
300 
301 #endif /* BTSTACK_CTRYPTO_H */
302