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