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