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