xref: /btstack/src/btstack_crypto.h (revision 3c4cc6427fe05577c00b7d2593f58c7abcf9eab7)
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 
50 #if defined __cplusplus
51 extern "C" {
52 #endif
53 
54 #define CMAC_TEMP_API
55 
56 typedef enum {
57 	BTSTACK_CRYPTO_RANDOM,
58 	BTSTACK_CRYPTO_AES128,
59 	BTSTACK_CRYPTO_CMAC_GENERATOR,
60 	BTSTACK_CRYPTO_CMAC_MESSAGE,
61 	BTSTACK_CRYPTO_ECC_P256_GENERATE_KEY,
62 	BTSTACK_CRYPTO_ECC_P256_CALCULATE_DHKEY,
63 	BTSTACK_CRYPTO_CCM_DIGEST_BLOCK,
64 	BTSTACK_CRYPTO_CCM_ENCRYPT_BLOCK,
65 	BTSTACK_CRYPTO_CCM_DECRYPT_BLOCK,
66 } btstack_crypto_operation_t;
67 
68 typedef struct {
69 	btstack_context_callback_registration_t context_callback;
70 	btstack_crypto_operation_t              operation;
71 } btstack_crypto_t;
72 
73 typedef struct {
74 	btstack_crypto_t btstack_crypto;
75 	uint8_t  * buffer;
76 	uint16_t   size;
77 } btstack_crypto_random_t;
78 
79 typedef struct {
80 	btstack_crypto_t btstack_crypto;
81 	const uint8_t  * key;
82 	const uint8_t  * plaintext;
83 	uint8_t  * ciphertext;
84 } btstack_crypto_aes128_t;
85 
86 typedef struct {
87 	btstack_crypto_t btstack_crypto;
88 	const uint8_t  * key;
89 	uint16_t         size;
90 	union {
91 		uint8_t (*get_byte_callback)(uint16_t pos);
92 		const uint8_t * message;
93 	} data;
94 	uint8_t  * hash;
95 } btstack_crypto_aes128_cmac_t;
96 
97 typedef struct {
98 	btstack_crypto_t btstack_crypto;
99 	uint8_t * public_key;
100     uint8_t * dhkey;
101 } btstack_crypto_ecc_p256_t;
102 
103 typedef enum {
104     CCM_CALCULATE_X1,
105     CCM_W4_X1,
106     CCM_CALCULATE_AAD_XN,
107     CCM_W4_AAD_XN,
108     CCM_CALCULATE_XN,
109     CCM_W4_XN,
110     CCM_CALCULATE_S0,
111     CCM_W4_S0,
112     CCM_CALCULATE_SN,
113     CCM_W4_SN,
114 } btstack_crypto_ccm_state_t;
115 
116 typedef struct {
117 	btstack_crypto_t btstack_crypto;
118 	btstack_crypto_ccm_state_t state;
119 	const uint8_t * key;
120 	const uint8_t * nonce;
121 	const uint8_t * input;
122 	uint8_t       * output;
123 	uint8_t         x_i[16];
124 	uint16_t        aad_offset;
125 	uint16_t        aad_len;
126 	uint16_t        message_len;
127 	uint16_t        counter;
128 	uint16_t        block_len;
129 	uint8_t         auth_len;
130 	uint8_t         aad_remainder_len;
131 } btstack_crypto_ccm_t;
132 
133 /**
134  * Initialize crypto functions
135  */
136 void btstack_crypto_init(void);
137 
138 /**
139  * Generate random data
140  * @param request
141  * @param buffer for output
142  * @param size of requested random data
143  * @param callback
144  * @param callback_arg
145  * @note request needs to stay avaliable until callback (i.e. not provided on stack)
146  */
147 void btstack_crypto_random_generate(btstack_crypto_random_t * request, uint8_t * buffer, uint16_t size, void (* callback)(void * arg), void * callback_arg);
148 
149 /**
150  * Encrypt plaintext using AES128
151  * @param request
152  * @param key (16 bytes)
153  * @param plaintext (16 bytes)
154  * @param ciphertext (16 bytes)
155  * @param callback
156  * @param callback_arg
157  * @note request needs to stay avaliable until callback (i.e. not provided on stack)
158  */
159 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);
160 
161 /**
162  * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and a generator function to provide data
163  * @param request
164  * @param key (16 bytes)
165  * @param size of message
166  * @param generator provides byte at requested position
167  * @param callback
168  * @param callback_arg
169  */
170 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);
171 
172 /**
173  * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and complete message
174  * @param request
175  * @param key (16 bytes)
176  * @param len of message
177  * @param message
178  * @param hash result
179  * @param callback
180  * @param callback_arg
181  */
182 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);
183 
184 /**
185  * Calculate AES128-CMAC with key ZERO and complete message
186  * @param request
187  * @param len of message
188  * @param message
189  * @param hash
190  * @param callback
191  * @param callback_arg
192  */
193 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);
194 
195 /**
196  * Generate Elliptic Curve Public/Private Key Pair (FIPS P-256)
197  * @note BTstack uses a single ECC key pair per reset.
198  * @note If LE Controller is used for ECC, private key cannot be read or managed
199  * @param request
200  * @param public_key (64 bytes)
201  * @param callback
202  * @param callback_arg
203  */
204 void btstack_crypto_ecc_p256_generate_key(btstack_crypto_ecc_p256_t * request, uint8_t * public_key, void (* callback)(void * arg), void * callback_arg);
205 
206 /**
207  * Calculate Diffie-Hellman Key based on local private key and remote public key
208  * @param request
209  * @param public_key (64 bytes)
210  * @param dhkey (32 bytes)
211  * @param callback
212  * @param callback_arg
213  */
214 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);
215 
216 /*
217  * Validate public key (not implemented for LE Controller ECC)
218  * @param public_key (64 bytes)
219  * @result 0 == valid
220  */
221 int btstack_crypto_ecc_p256_validate_public_key(const uint8_t * public_key);
222 
223 /**
224  * Initialize Counter with CBC-MAC for Bluetooth Mesh (L=2)
225  * @param request
226  * @param nonce
227  * @param key
228  * @param message_len
229  * @param additional_authenticated_data_len must be smaller than 0xff00
230  * @param auth_len
231  */
232 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);
233 
234 /**
235  * Get authentication value after encrypt or decrypt operation
236  * @param request
237  * @param authentication_value
238  */
239 void btstack_crypto_ccm_get_authentication_value(btstack_crypto_ccm_t * request, uint8_t * authentication_value);
240 
241 /**
242  * Digest Additional Authentication Data - can be called multipled times up to total additional_authenticated_data_len specified in btstack_crypto_ccm_init
243  * @param request
244  * @param additional_authenticated_data
245  * @param additional_authenticated_data_len
246  * @param callback
247  * @param callback_arg
248  */
249 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);
250 
251 /**
252  * Encrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call
253  * @param request
254  * @param len (16 bytes for all but the last block)
255  * @param plaintext  (16 bytes)
256  * @param ciphertext (16 bytes)
257  * @param callback
258  * @param callback_arg
259  */
260 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);
261 
262 /**
263  * Decrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call
264  * @param request
265  * @param len (16 for all but last block)
266  * @param ciphertext (16 bytes)
267  * @param plaintext  (16 bytes)
268  * @param callback
269  * @param callback_arg
270  */
271 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);
272 
273 // PTS testing only - not possible when using Buetooth Controller for ECC operations
274 void btstack_crypto_ecc_p256_set_key(const uint8_t * public_key, const uint8_t * private_key);
275 
276 // Unit testing
277 int btstack_crypto_idle(void);
278 void btstack_crypto_reset(void);
279 
280 #if defined __cplusplus
281 }
282 #endif
283 
284 #endif /* BTSTACK_CTRYPTO_H */
285