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