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 232fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 242fca4dadSMilanka Ringwald * GMBH 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 38fe5a6c4eSMilanka Ringwald /** 39fe5a6c4eSMilanka Ringwald * Crypto-related functions 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 4580e33422SMatthias Ringwald #ifndef BTSTACK_CTRYPTO_H 4680e33422SMatthias Ringwald #define BTSTACK_CTRYPTO_H 47d1a1f6a4SMatthias Ringwald 48d1a1f6a4SMatthias Ringwald #include "btstack_defines.h" 49d8fc648cSMatthias Ringwald #include "btstack_config.h" 50d1a1f6a4SMatthias Ringwald 51d1a1f6a4SMatthias Ringwald #if defined __cplusplus 52d1a1f6a4SMatthias Ringwald extern "C" { 53d1a1f6a4SMatthias Ringwald #endif 54d1a1f6a4SMatthias Ringwald 55d1a1f6a4SMatthias Ringwald #define CMAC_TEMP_API 56d1a1f6a4SMatthias Ringwald 57d1a1f6a4SMatthias Ringwald typedef enum { 58d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_RANDOM, 59d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_AES128, 60d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_CMAC_GENERATOR, 61d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_CMAC_MESSAGE, 62d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_ECC_P256_GENERATE_KEY, 63d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_ECC_P256_CALCULATE_DHKEY, 64f88ad41fSMatthias Ringwald BTSTACK_CRYPTO_CCM_DIGEST_BLOCK, 65d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_CCM_ENCRYPT_BLOCK, 66d1a1f6a4SMatthias Ringwald BTSTACK_CRYPTO_CCM_DECRYPT_BLOCK, 67d1a1f6a4SMatthias Ringwald } btstack_crypto_operation_t; 68d1a1f6a4SMatthias Ringwald 69d1a1f6a4SMatthias Ringwald typedef struct { 70d1a1f6a4SMatthias Ringwald btstack_context_callback_registration_t context_callback; 71d1a1f6a4SMatthias Ringwald btstack_crypto_operation_t operation; 72d1a1f6a4SMatthias Ringwald } btstack_crypto_t; 73d1a1f6a4SMatthias Ringwald 74d1a1f6a4SMatthias Ringwald typedef struct { 75d1a1f6a4SMatthias Ringwald btstack_crypto_t btstack_crypto; 76d1a1f6a4SMatthias Ringwald uint8_t * buffer; 77d1a1f6a4SMatthias Ringwald uint16_t size; 78d1a1f6a4SMatthias Ringwald } btstack_crypto_random_t; 79d1a1f6a4SMatthias Ringwald 80d1a1f6a4SMatthias Ringwald typedef struct { 81d1a1f6a4SMatthias Ringwald btstack_crypto_t btstack_crypto; 82d1a1f6a4SMatthias Ringwald const uint8_t * key; 83d1a1f6a4SMatthias Ringwald const uint8_t * plaintext; 84d1a1f6a4SMatthias Ringwald uint8_t * ciphertext; 85d1a1f6a4SMatthias Ringwald } btstack_crypto_aes128_t; 86d1a1f6a4SMatthias Ringwald 87d1a1f6a4SMatthias Ringwald typedef struct { 88d1a1f6a4SMatthias Ringwald btstack_crypto_t btstack_crypto; 89d1a1f6a4SMatthias Ringwald const uint8_t * key; 90d1a1f6a4SMatthias Ringwald uint16_t size; 91d1a1f6a4SMatthias Ringwald union { 92d1a1f6a4SMatthias Ringwald uint8_t (*get_byte_callback)(uint16_t pos); 93d1a1f6a4SMatthias Ringwald const uint8_t * message; 9459ab1655SMatthias Ringwald } data; 95d1a1f6a4SMatthias Ringwald uint8_t * hash; 96d1a1f6a4SMatthias Ringwald } btstack_crypto_aes128_cmac_t; 97d1a1f6a4SMatthias Ringwald 98d1a1f6a4SMatthias Ringwald typedef struct { 99d1a1f6a4SMatthias Ringwald btstack_crypto_t btstack_crypto; 100d1a1f6a4SMatthias Ringwald uint8_t * public_key; 101d1a1f6a4SMatthias Ringwald uint8_t * dhkey; 102d1a1f6a4SMatthias Ringwald } btstack_crypto_ecc_p256_t; 103d1a1f6a4SMatthias Ringwald 104d1a1f6a4SMatthias Ringwald typedef enum { 105d1a1f6a4SMatthias Ringwald CCM_CALCULATE_X1, 106d1a1f6a4SMatthias Ringwald CCM_W4_X1, 107f88ad41fSMatthias Ringwald CCM_CALCULATE_AAD_XN, 108f88ad41fSMatthias Ringwald CCM_W4_AAD_XN, 109d1a1f6a4SMatthias Ringwald CCM_CALCULATE_XN, 110d1a1f6a4SMatthias Ringwald CCM_W4_XN, 111d1a1f6a4SMatthias Ringwald CCM_CALCULATE_S0, 112d1a1f6a4SMatthias Ringwald CCM_W4_S0, 113d1a1f6a4SMatthias Ringwald CCM_CALCULATE_SN, 114d1a1f6a4SMatthias Ringwald CCM_W4_SN, 115d1a1f6a4SMatthias Ringwald } btstack_crypto_ccm_state_t; 116d1a1f6a4SMatthias Ringwald 117d1a1f6a4SMatthias Ringwald typedef struct { 118d1a1f6a4SMatthias Ringwald btstack_crypto_t btstack_crypto; 119d1a1f6a4SMatthias Ringwald btstack_crypto_ccm_state_t state; 120d1a1f6a4SMatthias Ringwald const uint8_t * key; 121d1a1f6a4SMatthias Ringwald const uint8_t * nonce; 122d1a1f6a4SMatthias Ringwald const uint8_t * input; 123d1a1f6a4SMatthias Ringwald uint8_t * output; 124d1a1f6a4SMatthias Ringwald uint8_t x_i[16]; 125f88ad41fSMatthias Ringwald uint16_t aad_offset; 126f88ad41fSMatthias Ringwald uint16_t aad_len; 127d1a1f6a4SMatthias Ringwald uint16_t message_len; 128d1a1f6a4SMatthias Ringwald uint16_t counter; 129f88ad41fSMatthias Ringwald uint16_t block_len; 1306015e1edSMatthias Ringwald uint8_t auth_len; 131f88ad41fSMatthias Ringwald uint8_t aad_remainder_len; 132d1a1f6a4SMatthias Ringwald } btstack_crypto_ccm_t; 133d1a1f6a4SMatthias Ringwald 134d1a1f6a4SMatthias Ringwald /** 135d1a1f6a4SMatthias Ringwald * Initialize crypto functions 136d1a1f6a4SMatthias Ringwald */ 137d1a1f6a4SMatthias Ringwald void btstack_crypto_init(void); 138d1a1f6a4SMatthias Ringwald 139d1a1f6a4SMatthias Ringwald /** 140d1a1f6a4SMatthias Ringwald * Generate random data 141d1a1f6a4SMatthias Ringwald * @param request 142d1a1f6a4SMatthias Ringwald * @param buffer for output 143d1a1f6a4SMatthias Ringwald * @param size of requested random data 144d1a1f6a4SMatthias Ringwald * @param callback 145d1a1f6a4SMatthias Ringwald * @param callback_arg 146d1a1f6a4SMatthias Ringwald * @note request needs to stay avaliable until callback (i.e. not provided on stack) 147d1a1f6a4SMatthias Ringwald */ 148d1a1f6a4SMatthias Ringwald void btstack_crypto_random_generate(btstack_crypto_random_t * request, uint8_t * buffer, uint16_t size, void (* callback)(void * arg), void * callback_arg); 149d1a1f6a4SMatthias Ringwald 150d1a1f6a4SMatthias Ringwald /** 151d1a1f6a4SMatthias Ringwald * Encrypt plaintext using AES128 152d1a1f6a4SMatthias Ringwald * @param request 153d1a1f6a4SMatthias Ringwald * @param key (16 bytes) 154d1a1f6a4SMatthias Ringwald * @param plaintext (16 bytes) 155d1a1f6a4SMatthias Ringwald * @param ciphertext (16 bytes) 156d1a1f6a4SMatthias Ringwald * @param callback 157d1a1f6a4SMatthias Ringwald * @param callback_arg 158d1a1f6a4SMatthias Ringwald * @note request needs to stay avaliable until callback (i.e. not provided on stack) 159d1a1f6a4SMatthias Ringwald */ 160d1a1f6a4SMatthias 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); 161d1a1f6a4SMatthias Ringwald 162d1a1f6a4SMatthias Ringwald /** 163d1a1f6a4SMatthias Ringwald * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and a generator function to provide data 164d1a1f6a4SMatthias Ringwald * @param request 165d1a1f6a4SMatthias Ringwald * @param key (16 bytes) 166d1a1f6a4SMatthias Ringwald * @param size of message 167d1a1f6a4SMatthias Ringwald * @param generator provides byte at requested position 168d1a1f6a4SMatthias Ringwald * @param callback 169d1a1f6a4SMatthias Ringwald * @param callback_arg 170d1a1f6a4SMatthias Ringwald */ 171d1a1f6a4SMatthias 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); 172d1a1f6a4SMatthias Ringwald 173d1a1f6a4SMatthias Ringwald /** 174d1a1f6a4SMatthias Ringwald * Calculate Cipher-based Message Authentication Code (CMAC) using AES128 and complete message 175d1a1f6a4SMatthias Ringwald * @param request 176d1a1f6a4SMatthias Ringwald * @param key (16 bytes) 177b45b7749SMilanka Ringwald * @param size of message 178d1a1f6a4SMatthias Ringwald * @param message 179d1a1f6a4SMatthias Ringwald * @param hash result 180d1a1f6a4SMatthias Ringwald * @param callback 181d1a1f6a4SMatthias Ringwald * @param callback_arg 182d1a1f6a4SMatthias Ringwald */ 183b45b7749SMilanka Ringwald void btstack_crypto_aes128_cmac_message(btstack_crypto_aes128_cmac_t * request, const uint8_t * key, uint16_t size, const uint8_t * message, uint8_t * hash, void (* callback)(void * arg), void * callback_arg); 184d1a1f6a4SMatthias Ringwald 185d1a1f6a4SMatthias Ringwald /** 186d1a1f6a4SMatthias Ringwald * Calculate AES128-CMAC with key ZERO and complete message 187d1a1f6a4SMatthias Ringwald * @param request 188b45b7749SMilanka Ringwald * @param size of message 189d1a1f6a4SMatthias Ringwald * @param message 190d1a1f6a4SMatthias Ringwald * @param hash 191d1a1f6a4SMatthias Ringwald * @param callback 192d1a1f6a4SMatthias Ringwald * @param callback_arg 193d1a1f6a4SMatthias Ringwald */ 194b45b7749SMilanka Ringwald void btstack_crypto_aes128_cmac_zero(btstack_crypto_aes128_cmac_t * request, uint16_t size, const uint8_t * message, uint8_t * hash, void (* callback)(void * arg), void * callback_arg); 195d1a1f6a4SMatthias Ringwald 196d1a1f6a4SMatthias Ringwald /** 197d1a1f6a4SMatthias Ringwald * Generate Elliptic Curve Public/Private Key Pair (FIPS P-256) 198d1a1f6a4SMatthias Ringwald * @note BTstack uses a single ECC key pair per reset. 199d1a1f6a4SMatthias Ringwald * @note If LE Controller is used for ECC, private key cannot be read or managed 200d1a1f6a4SMatthias Ringwald * @param request 201d1a1f6a4SMatthias Ringwald * @param public_key (64 bytes) 202d1a1f6a4SMatthias Ringwald * @param callback 203d1a1f6a4SMatthias Ringwald * @param callback_arg 204d1a1f6a4SMatthias Ringwald */ 205d1a1f6a4SMatthias 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); 206d1a1f6a4SMatthias Ringwald 207d1a1f6a4SMatthias Ringwald /** 208d1a1f6a4SMatthias Ringwald * Calculate Diffie-Hellman Key based on local private key and remote public key 209*9edc3991SMatthias Ringwald * @note Bluetooth Core v5.1+ requires the Controller to return an error if the public key is invalid 210*9edc3991SMatthias Ringwald * In this case, dhkey will be set to 0xff..ff 211d1a1f6a4SMatthias Ringwald * @param request 212d1a1f6a4SMatthias Ringwald * @param public_key (64 bytes) 213d1a1f6a4SMatthias Ringwald * @param dhkey (32 bytes) 214d1a1f6a4SMatthias Ringwald * @param callback 215d1a1f6a4SMatthias Ringwald * @param callback_arg 216d1a1f6a4SMatthias Ringwald */ 217d1a1f6a4SMatthias 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); 218d1a1f6a4SMatthias Ringwald 219d1a1f6a4SMatthias Ringwald /* 220*9edc3991SMatthias Ringwald * Validate public key 221*9edc3991SMatthias Ringwald * @note Not implemented for ECC in Controller. @see btstack_crypto_ecc_p256_calculate_dhkey 222d1a1f6a4SMatthias Ringwald * @param public_key (64 bytes) 223d1a1f6a4SMatthias Ringwald * @result 0 == valid 224d1a1f6a4SMatthias Ringwald */ 225d1a1f6a4SMatthias Ringwald int btstack_crypto_ecc_p256_validate_public_key(const uint8_t * public_key); 226d1a1f6a4SMatthias Ringwald 227d1a1f6a4SMatthias Ringwald /** 22810e0e23cSMatthias Ringwald * Initialize Counter with CBC-MAC for Bluetooth Mesh (L=2) 229d1a1f6a4SMatthias Ringwald * @param request 230d1a1f6a4SMatthias Ringwald * @param nonce 231d1a1f6a4SMatthias Ringwald * @param key 232d1a1f6a4SMatthias Ringwald * @param message_len 233f88ad41fSMatthias Ringwald * @param additional_authenticated_data_len must be smaller than 0xff00 2346015e1edSMatthias Ringwald * @param auth_len 235d1a1f6a4SMatthias Ringwald */ 23603843d74SMatthias 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); 237d1a1f6a4SMatthias Ringwald 238d1a1f6a4SMatthias Ringwald /** 23910e0e23cSMatthias Ringwald * Get authentication value after encrypt or decrypt operation 240d1a1f6a4SMatthias Ringwald * @param request 241d1a1f6a4SMatthias Ringwald * @param authentication_value 242d1a1f6a4SMatthias Ringwald */ 24303843d74SMatthias Ringwald void btstack_crypto_ccm_get_authentication_value(btstack_crypto_ccm_t * request, uint8_t * authentication_value); 244d1a1f6a4SMatthias Ringwald 245d1a1f6a4SMatthias Ringwald /** 24603843d74SMatthias Ringwald * Digest Additional Authentication Data - can be called multipled times up to total additional_authenticated_data_len specified in btstack_crypto_ccm_init 247f88ad41fSMatthias Ringwald * @param request 248f88ad41fSMatthias Ringwald * @param additional_authenticated_data 249f88ad41fSMatthias Ringwald * @param additional_authenticated_data_len 250f88ad41fSMatthias Ringwald * @param callback 251f88ad41fSMatthias Ringwald * @param callback_arg 252f88ad41fSMatthias Ringwald */ 25303843d74SMatthias 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); 254f88ad41fSMatthias Ringwald 255f88ad41fSMatthias Ringwald /** 256d1a1f6a4SMatthias Ringwald * Encrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call 257d1a1f6a4SMatthias Ringwald * @param request 258d1a1f6a4SMatthias Ringwald * @param len (16 bytes for all but the last block) 259d1a1f6a4SMatthias Ringwald * @param plaintext (16 bytes) 260d1a1f6a4SMatthias Ringwald * @param ciphertext (16 bytes) 261d1a1f6a4SMatthias Ringwald * @param callback 262d1a1f6a4SMatthias Ringwald * @param callback_arg 263d1a1f6a4SMatthias Ringwald */ 264d1a1f6a4SMatthias 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); 265d1a1f6a4SMatthias Ringwald 266d1a1f6a4SMatthias Ringwald /** 267d1a1f6a4SMatthias Ringwald * Decrypt block - can be called multiple times. len must be a multiply of 16 for all but the last call 268d1a1f6a4SMatthias Ringwald * @param request 269d1a1f6a4SMatthias Ringwald * @param len (16 for all but last block) 270d1a1f6a4SMatthias Ringwald * @param ciphertext (16 bytes) 271d1a1f6a4SMatthias Ringwald * @param plaintext (16 bytes) 272d1a1f6a4SMatthias Ringwald * @param callback 273d1a1f6a4SMatthias Ringwald * @param callback_arg 274d1a1f6a4SMatthias Ringwald */ 275d1a1f6a4SMatthias 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); 276d1a1f6a4SMatthias Ringwald 277d8fc648cSMatthias Ringwald #if defined(ENABLE_SOFTWARE_AES128) || defined (HAVE_AES128) 278cfbd0db4SMatthias Ringwald /** 279cfbd0db4SMatthias Ringwald * Encrypt plaintext using AES128 280cfbd0db4SMatthias Ringwald * @note Prototype for custom AES128 implementation 281cfbd0db4SMatthias Ringwald * @param key (16 bytes) 282cfbd0db4SMatthias Ringwald * @param plaintext (16 bytes) 283cfbd0db4SMatthias Ringwald * @param ciphertext (16 bytes) 284cfbd0db4SMatthias Ringwald */ 285cfbd0db4SMatthias Ringwald void btstack_aes128_calc(const uint8_t * key, const uint8_t * plaintext, uint8_t * ciphertext); 286cfbd0db4SMatthias Ringwald #endif 287cfbd0db4SMatthias Ringwald 288172c13e7SMatthias Ringwald /** 289172c13e7SMatthias Ringwald * @brief De-Init BTstack Crypto 290172c13e7SMatthias Ringwald */ 291172c13e7SMatthias Ringwald void btstack_crypto_deinit(void); 292172c13e7SMatthias Ringwald 2931fbe4564SMatthias Ringwald // PTS testing only - not possible when using Buetooth Controller for ECC operations 2941fbe4564SMatthias Ringwald void btstack_crypto_ecc_p256_set_key(const uint8_t * public_key, const uint8_t * private_key); 2951fbe4564SMatthias Ringwald 29680665fb7SMatthias Ringwald // Unit testing 29780665fb7SMatthias Ringwald int btstack_crypto_idle(void); 298fde19096SMatthias Ringwald void btstack_crypto_reset(void); 29980665fb7SMatthias Ringwald 300d1a1f6a4SMatthias Ringwald #if defined __cplusplus 301d1a1f6a4SMatthias Ringwald } 302d1a1f6a4SMatthias Ringwald #endif 303d1a1f6a4SMatthias Ringwald 30480e33422SMatthias Ringwald #endif /* BTSTACK_CTRYPTO_H */ 305