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