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