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