1 /* 2 * Copyright 2018 Oticon A/S 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #ifndef BLECRYPT_H 7 #define BLECRYPT_H 8 9 // This file provides an API for BLE packet encryption/decryption using the 10 // OpenSSL library. 11 12 #include <stdint.h> 13 14 // CCM size parameters specified in BT Core v4.2 vol 6 part E section 1 15 #define BLE_CCM_M 4 // Number of bytes in MIC (a.k.a. MAC) field 16 #define BLE_CCM_L 2 // Number of bytes in Length field (in counter mode blocks) 17 18 // Various BLE specific lengths 19 #define KEY_LEN 16 20 #define SKD_LEN KEY_LEN 21 #define IV_LEN 8 22 23 // Various derived lengths 24 #define MIC_LEN BLE_CCM_M 25 26 // Nonce length depends on CCM parameter L 27 #define NONCE_LEN (15 - BLE_CCM_L) 28 29 // Packet direction 30 typedef enum { 31 SLAVE_TO_MASTER_DIRECTION, 32 MASTER_TO_SLAVE_DIRECTION 33 } blecrypt_packet_direction_t; 34 35 // Performs simple AES-128 encryption of 128-bit data. 36 // This is the security function e (BT Core v4.2 vol 3 part H section 2.2.1) - except for parameter endianness. 37 // This is also the HCI_LE_Encrypt command (BT Core v4.2 vol 1 part E section 7.8.22). 38 // Applications: 39 // * Generating and resolving resolvable random address (via ah function, BT Core v4.2 vol 3 part H section 2.2.2). 40 // * Generating pairing confirm value (via c1 function, BT Core v4.2 vol 3 part H section 2.2.3). 41 // * Generating short term key (via s1 function, BT Core v4.2 vol 3 part H section 2.2.4). 42 // * Generating session key. 43 void blecrypt_aes_128( 44 // Inputs 45 const uint8_t *key_be, // Key (KEY_LEN bytes, big-endian) 46 const uint8_t *plaintext_data_be, // Plaintext data (KEY_LEN bytes, big-endian) 47 // Outputs (the pointers themselves are inputs and must point to large enough areas) 48 uint8_t *encrypted_data_be); // Plaintext data (KEY_LEN bytes, big-endian) 49 50 // Encrypts payload of one packet and appends MIC. 51 // Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations. 52 void blecrypt_packet_encrypt( 53 // Inputs 54 uint8_t packet_1st_header_byte, // First byte of packet header (or just LLID and RFU (RFU=0 for BLE v4.x) - other bits are ignored) 55 uint8_t packet_payload_len, // Packet payload length (not including header and MIC) 56 const uint8_t *packet_payload, // Packet payload to be encrypted (packet_payload_len bytes) 57 const uint8_t *sk, // Session key (KEY_LEN bytes, BIG-ENDIAN) 58 const uint8_t *ccm_nonce, // CCM Nonce (NONCE_LEN bytes, little-endian) 59 // Outputs (the pointers themselves are inputs and must point to large enough areas) 60 uint8_t *encrypted_packet_payload_and_mic); // Resulting encrypted payload with MIC appended (packet_payload_len + MIC_LEN bytes) 61 62 // Decrypts payload of one packet and checks MIC (if present). 63 // Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations. 64 int blecrypt_packet_decrypt( // Returns 1 if MIC is ok, else 0 65 // Inputs 66 uint8_t packet_1st_header_byte, // First byte of packet header (or just LLID and RFU (RFU=0 for BLE v4.x) - other bits are ignored) 67 uint8_t packet_payload_len, // Packet payload length (not including header and MIC) 68 const uint8_t *packet_payload_and_mic, // Packet payload (with MIC if any) to be decrypted (packet_payload_len (+ MIC_LEN) bytes) 69 const uint8_t *sk, // Session key (KEY_LEN bytes, BIG-ENDIAN) 70 const uint8_t *ccm_nonce, // CCM Nonce (NONCE_LEN bytes, little-endian) 71 int no_mic, // 1 if packet to be decrypted does not include a MIC, otherwise 0 72 // Outputs (the pointers themselves are inputs and must point to large enough areas) 73 uint8_t *decrypted_packet_payload); // Resulting decrypted payload (packet_payload_len bytes) 74 75 void blecrypt_packet_encrypt_v2( 76 uint8_t aad, 77 int packet_payload_len, 78 const uint8_t *packet_payload, 79 const uint8_t *sk, 80 const uint8_t *ccm_nonce, 81 uint8_t *encrypted_packet_payload_and_mic); 82 83 int blecrypt_packet_decrypt_v2( 84 uint8_t aad, 85 int packet_payload_len, 86 const uint8_t *packet_payload_and_mic, 87 const uint8_t *sk, 88 const uint8_t *ccm_nonce, 89 int no_mic, 90 uint8_t *decrypted_packet_payload); 91 92 // Reverses byte order of data 93 void blecrypt_reverse_byte_order(const uint8_t *in_data, uint8_t *out_data, int len); 94 95 #endif // #ifndef BLECRYPT_H 96