xref: /btstack/src/btstack_crypto.h (revision 6015e1edc2e003d8108b1cab8d122222067a4ee9)
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;
9259ab1655SMatthias 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;
124*6015e1edSMatthias Ringwald 	uint8_t         auth_len;
125d1a1f6a4SMatthias Ringwald } btstack_crypto_ccm_t;
126d1a1f6a4SMatthias Ringwald 
127d1a1f6a4SMatthias Ringwald /**
128d1a1f6a4SMatthias Ringwald  * Initialize crypto functions
129d1a1f6a4SMatthias Ringwald  */
130d1a1f6a4SMatthias Ringwald void btstack_crypto_init(void);
131d1a1f6a4SMatthias Ringwald 
132d1a1f6a4SMatthias Ringwald /**
133d1a1f6a4SMatthias Ringwald  * Generate random data
134d1a1f6a4SMatthias Ringwald  * @param request
135d1a1f6a4SMatthias Ringwald  * @param buffer for output
136d1a1f6a4SMatthias Ringwald  * @param size of requested random data
137d1a1f6a4SMatthias Ringwald  * @param callback
138d1a1f6a4SMatthias Ringwald  * @param callback_arg
139d1a1f6a4SMatthias Ringwald  * @note request needs to stay avaliable until callback (i.e. not provided on stack)
140d1a1f6a4SMatthias Ringwald  */
141d1a1f6a4SMatthias Ringwald void btstack_crypto_random_generate(btstack_crypto_random_t * request, uint8_t * buffer, uint16_t size, void (* callback)(void * arg), void * callback_arg);
142d1a1f6a4SMatthias Ringwald 
143d1a1f6a4SMatthias Ringwald /**
144d1a1f6a4SMatthias Ringwald  * Encrypt plaintext using AES128
145d1a1f6a4SMatthias Ringwald  * @param request
146d1a1f6a4SMatthias Ringwald  * @param key (16 bytes)
147d1a1f6a4SMatthias Ringwald  * @param plaintext (16 bytes)
148d1a1f6a4SMatthias Ringwald  * @param ciphertext (16 bytes)
149d1a1f6a4SMatthias Ringwald  * @param callback
150d1a1f6a4SMatthias Ringwald  * @param callback_arg
151d1a1f6a4SMatthias Ringwald  * @note request needs to stay avaliable until callback (i.e. not provided on stack)
152d1a1f6a4SMatthias Ringwald  */
153d1a1f6a4SMatthias 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);
154d1a1f6a4SMatthias Ringwald 
155d1a1f6a4SMatthias Ringwald /**
156d1a1f6a4SMatthias Ringwald  * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and a generator function to provide data
157d1a1f6a4SMatthias Ringwald  * @param request
158d1a1f6a4SMatthias Ringwald  * @param key (16 bytes)
159d1a1f6a4SMatthias Ringwald  * @param size of message
160d1a1f6a4SMatthias Ringwald  * @param generator provides byte at requested position
161d1a1f6a4SMatthias Ringwald  * @param callback
162d1a1f6a4SMatthias Ringwald  * @param callback_arg
163d1a1f6a4SMatthias Ringwald  */
164d1a1f6a4SMatthias 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);
165d1a1f6a4SMatthias Ringwald 
166d1a1f6a4SMatthias Ringwald /**
167d1a1f6a4SMatthias Ringwald  * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and complete message
168d1a1f6a4SMatthias Ringwald  * @param request
169d1a1f6a4SMatthias Ringwald  * @param key (16 bytes)
170d1a1f6a4SMatthias Ringwald  * @param len of message
171d1a1f6a4SMatthias Ringwald  * @param message
172d1a1f6a4SMatthias Ringwald  * @param hash result
173d1a1f6a4SMatthias Ringwald  * @param callback
174d1a1f6a4SMatthias Ringwald  * @param callback_arg
175d1a1f6a4SMatthias Ringwald  */
176d1a1f6a4SMatthias 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);
177d1a1f6a4SMatthias Ringwald 
178d1a1f6a4SMatthias Ringwald /**
179d1a1f6a4SMatthias Ringwald  * Calculate AES128-CMAC with key ZERO and complete message
180d1a1f6a4SMatthias Ringwald  * @param request
181d1a1f6a4SMatthias Ringwald  * @param len of message
182d1a1f6a4SMatthias Ringwald  * @param message
183d1a1f6a4SMatthias Ringwald  * @param hash
184d1a1f6a4SMatthias Ringwald  * @param callback
185d1a1f6a4SMatthias Ringwald  * @param callback_arg
186d1a1f6a4SMatthias Ringwald  */
187d1a1f6a4SMatthias 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);
188d1a1f6a4SMatthias Ringwald 
189d1a1f6a4SMatthias Ringwald /**
190d1a1f6a4SMatthias Ringwald  * Generate Elliptic Curve Public/Private Key Pair (FIPS P-256)
191d1a1f6a4SMatthias Ringwald  * @note BTstack uses a single ECC key pair per reset.
192d1a1f6a4SMatthias Ringwald  * @note If LE Controller is used for ECC, private key cannot be read or managed
193d1a1f6a4SMatthias Ringwald  * @param request
194d1a1f6a4SMatthias Ringwald  * @param public_key (64 bytes)
195d1a1f6a4SMatthias Ringwald  * @param callback
196d1a1f6a4SMatthias Ringwald  * @param callback_arg
197d1a1f6a4SMatthias Ringwald  */
198d1a1f6a4SMatthias 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);
199d1a1f6a4SMatthias Ringwald 
200d1a1f6a4SMatthias Ringwald /**
201d1a1f6a4SMatthias Ringwald  * Calculate Diffie-Hellman Key based on local private key and remote public key
202d1a1f6a4SMatthias Ringwald  * @param request
203d1a1f6a4SMatthias Ringwald  * @param public_key (64 bytes)
204d1a1f6a4SMatthias Ringwald  * @param dhkey (32 bytes)
205d1a1f6a4SMatthias Ringwald  * @param callback
206d1a1f6a4SMatthias Ringwald  * @param callback_arg
207d1a1f6a4SMatthias Ringwald  */
208d1a1f6a4SMatthias 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);
209d1a1f6a4SMatthias Ringwald 
210d1a1f6a4SMatthias Ringwald /*
211d1a1f6a4SMatthias Ringwald  * Validate public key (not implemented for LE Controller ECC)
212d1a1f6a4SMatthias Ringwald  * @param public_key (64 bytes)
213d1a1f6a4SMatthias Ringwald  * @result 0 == valid
214d1a1f6a4SMatthias Ringwald  */
215d1a1f6a4SMatthias Ringwald int btstack_crypto_ecc_p256_validate_public_key(const uint8_t * public_key);
216d1a1f6a4SMatthias Ringwald 
217d1a1f6a4SMatthias Ringwald /**
218d1a1f6a4SMatthias Ringwald  * Initialize Counter with CBC-MAC for Bluetooth Mesh (L=2,M=8)
219d1a1f6a4SMatthias Ringwald  * @param request
220d1a1f6a4SMatthias Ringwald  * @param nonce
221d1a1f6a4SMatthias Ringwald  * @param key
222d1a1f6a4SMatthias Ringwald  * @param message_len
223*6015e1edSMatthias Ringwald  * @param auth_len
224d1a1f6a4SMatthias Ringwald  */
225*6015e1edSMatthias Ringwald void btstack_crypo_ccm_init(btstack_crypto_ccm_t * request, const uint8_t * key, const uint8_t * nonce, uint16_t message_len, uint8_t auth_len);
226d1a1f6a4SMatthias Ringwald 
227d1a1f6a4SMatthias Ringwald /**
228d1a1f6a4SMatthias Ringwald  * Get authentication value (M=8) after encrypt or decrypt operation
229d1a1f6a4SMatthias Ringwald  * @param request
230d1a1f6a4SMatthias Ringwald  * @param authentication_value
231d1a1f6a4SMatthias Ringwald  */
232d1a1f6a4SMatthias Ringwald void btstack_crypo_ccm_get_authentication_value(btstack_crypto_ccm_t * request, uint8_t * authentication_value);
233d1a1f6a4SMatthias Ringwald 
234d1a1f6a4SMatthias Ringwald /**
235d1a1f6a4SMatthias Ringwald  * Encrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call
236d1a1f6a4SMatthias Ringwald  * @param request
237d1a1f6a4SMatthias Ringwald  * @param len (16 bytes for all but the last block)
238d1a1f6a4SMatthias Ringwald  * @param plaintext  (16 bytes)
239d1a1f6a4SMatthias Ringwald  * @param ciphertext (16 bytes)
240d1a1f6a4SMatthias Ringwald  * @param callback
241d1a1f6a4SMatthias Ringwald  * @param callback_arg
242d1a1f6a4SMatthias Ringwald  */
243d1a1f6a4SMatthias 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);
244d1a1f6a4SMatthias Ringwald 
245d1a1f6a4SMatthias Ringwald /**
246d1a1f6a4SMatthias Ringwald  * Decrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call
247d1a1f6a4SMatthias Ringwald  * @param request
248d1a1f6a4SMatthias Ringwald  * @param len (16 for all but last block)
249d1a1f6a4SMatthias Ringwald  * @param ciphertext (16 bytes)
250d1a1f6a4SMatthias Ringwald  * @param plaintext  (16 bytes)
251d1a1f6a4SMatthias Ringwald  * @param callback
252d1a1f6a4SMatthias Ringwald  * @param callback_arg
253d1a1f6a4SMatthias Ringwald  */
254d1a1f6a4SMatthias 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);
255d1a1f6a4SMatthias Ringwald 
256d1a1f6a4SMatthias Ringwald #if defined __cplusplus
257d1a1f6a4SMatthias Ringwald }
258d1a1f6a4SMatthias Ringwald #endif
259d1a1f6a4SMatthias Ringwald 
260d1a1f6a4SMatthias Ringwald #endif /* __BTSTACK_CTRYPTO_H */
261