1 /*
2 * Copyright 2018 Oticon A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdint.h>
7 #include <string.h>
8 #include <openssl/evp.h>
9 #include "blecrypt.h"
10
11 // Performs simple AES-128 encryption of 128-bit data.
12 // This is the security function e (BT Core v4.2 vol 3 part H section 2.2.1).
13 // This is also the HCI_LE_Encrypt command (BT Core v4.2 vol 1 part E section 7.8.22).
14 // Applications:
15 // * Generating and resolving resolvable random address (via ah function, BT Core v4.2 vol 3 part H section 2.2.2).
16 // * Generating pairing confirm value (via c1 function, BT Core v4.2 vol 3 part H section 2.2.3).
17 // * Generating short term key (via s1 function, BT Core v4.2 vol 3 part H section 2.2.4).
18 // * Generating session key.
blecrypt_aes_128(const uint8_t * key_be,const uint8_t * plaintext_data_be,uint8_t * encrypted_data_be)19 void blecrypt_aes_128(
20 // Inputs
21 const uint8_t *key_be, // Key (KEY_LEN bytes, BIG-ENDIAN)
22 const uint8_t *plaintext_data_be, // Plaintext data (KEY_LEN bytes, BIG-ENDIAN)
23 // Outputs (the pointers themselves are inputs and must point to large enough areas)
24 uint8_t *encrypted_data_be) // Encrypted data (KEY_LEN bytes, BIG-ENDIAN)
25 {
26 // Create OpenSSL cypher context
27 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
28 // Set cipher type to AES-128, mode to ECB ("Electronic Codebook": simple independent encryption of blocks),
29 // and provide encryption key
30 EVP_EncryptInit(ctx, EVP_aes_128_ecb(), key_be, NULL);
31 // Encrypt plaintext data and put result in encrypted_data_be and length in outlen
32 int outlen;
33 EVP_EncryptUpdate(ctx, encrypted_data_be, &outlen, plaintext_data_be, SKD_LEN);
34 // Free cipher context
35 EVP_CIPHER_CTX_free(ctx);
36 }
37
38 // Performs simple AES-128/192/256 encryption of 128-bit data.
blecrypt_aes_ecb(const uint8_t * key_be,size_t key_size,const uint8_t * plaintext_data_be,uint8_t * encrypted_data_be)39 void blecrypt_aes_ecb(
40 // Inputs
41 const uint8_t *key_be, // Key (KEY_LEN bytes, BIG-ENDIAN)
42 size_t key_size, // Key size in bits (only 128, 192 and 256 are supported)
43 const uint8_t *plaintext_data_be, // Plaintext data (128bits, BIG-ENDIAN)
44 // Outputs (the pointers themselves are inputs and must point to large enough areas)
45 uint8_t *encrypted_data_be) // Encrypted data (128bits, BIG-ENDIAN)
46 {
47 // Create OpenSSL cypher context
48 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
49 // Set cipher type to AES-128, mode to ECB ("Electronic Codebook": simple independent encryption of blocks),
50 // and provide encryption key
51 if (key_size == 128) {
52 EVP_EncryptInit(ctx, EVP_aes_128_ecb(), key_be, NULL);
53 } else if (key_size == 192) {
54 EVP_EncryptInit(ctx, EVP_aes_192_ecb(), key_be, NULL);
55 } else if (key_size == 256) {
56 EVP_EncryptInit(ctx, EVP_aes_256_ecb(), key_be, NULL);
57 }
58 // Encrypt plaintext data and put result in encrypted_data_be and length in outlen
59 int outlen;
60 EVP_EncryptUpdate(ctx, encrypted_data_be, &outlen, plaintext_data_be, SKD_LEN);
61 // Free cipher context
62 EVP_CIPHER_CTX_free(ctx);
63 }
64
65 // Encrypts payload of one packet and appends MIC.
66 // Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations.
blecrypt_packet_encrypt(uint8_t packet_1st_header_byte,uint8_t packet_payload_len,const uint8_t * packet_payload,const uint8_t * sk,const uint8_t * ccm_nonce,uint8_t * encrypted_packet_payload_and_mic)67 void blecrypt_packet_encrypt(
68 // Inputs
69 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)
70 uint8_t packet_payload_len, // Packet payload length (not including header and MIC)
71 const uint8_t *packet_payload, // Packet payload to be encrypted (packet_payload_len bytes)
72 const uint8_t *sk, // Session key (KEY_LEN bytes, BIG-ENDIAN)
73 const uint8_t *ccm_nonce, // CCM Nonce (NONCE_LEN bytes, little-endian)
74 // Outputs (the pointers themselves are inputs and must point to large enough areas)
75 uint8_t *encrypted_packet_payload_and_mic) // Resulting encrypted payload with MIC appended (packet_payload_len + MIC_LEN bytes)
76 {
77 // Set additional authenticated data (AAD) to first byte of packet header with NESN = SN = MD = 0
78 uint8_t aad = packet_1st_header_byte & 0xE3;
79 blecrypt_packet_encrypt_v2(aad,
80 packet_payload_len,
81 packet_payload,
82 sk,
83 ccm_nonce,
84 encrypted_packet_payload_and_mic);
85 }
86
87 // Decrypt payload of one packet and checks MIC (if present).
88 // Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations.
blecrypt_packet_decrypt(uint8_t packet_1st_header_byte,uint8_t packet_payload_len,const uint8_t * packet_payload_and_mic,const uint8_t * sk,const uint8_t * ccm_nonce,int no_mic,uint8_t * decrypted_packet_payload)89 int blecrypt_packet_decrypt( // Returns 1 if MIC is ok, else 0
90 // Inputs
91 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)
92 uint8_t packet_payload_len, // Packet payload length (not including header and MIC)
93 const uint8_t *packet_payload_and_mic, // Packet payload (with MIC if any) to be decrypted (packet_payload_len (+ MIC_LEN) bytes)
94 const uint8_t *sk, // Session key (KEY_LEN bytes, BIG-ENDIAN)
95 const uint8_t *ccm_nonce, // CCM Nonce (NONCE_LEN bytes, little-endian)
96 int no_mic, // 1 if packet to be decrypted does not include a MIC, otherwise 0
97 // Outputs (the pointers themselves are inputs and must point to large enough areas)
98 uint8_t *decrypted_packet_payload) // Resulting decrypted payload (packet_payload_len bytes)
99 {
100 // Set additional authenticated data (AAD) to first byte of packet header with NESN = SN = MD = 0
101 uint8_t aad = packet_1st_header_byte & 0xE3;
102 return blecrypt_packet_decrypt_v2(aad,
103 packet_payload_len,
104 packet_payload_and_mic,
105 sk,
106 ccm_nonce,
107 no_mic,
108 decrypted_packet_payload);
109 }
110
111 /**
112 * Encrypt a BLE packet payload and append the MIC,
113 * as per Bluetooth Core Specification Version 5.3 | Vol 6, Part E
114 *
115 * In comparison to blecrypt_packet_encrypt()
116 * this version is adapted to not apply the BT 4.2 AAD mask,
117 * but leave it to the caller, to be more transparent as to how the mask is meant to be applied
118 * for newer standard versions.
119 *
120 * \note Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations.
121 *
122 * \param[in] aad Additional Authentication Data: First byte of packet header after applying the bit mask
123 * Note: For BT 4.2 this is 0xE3. For 5.2 it depends on the packet type.
124 * \param[in] packet_payload_len Input packet payload length (i.e. not including header and MIC)
125 * \param[in] packet_payload Pointer to the packet payload to be encrypted (buffer must contain packet_payload_len bytes)
126 * \param[in] sk Session key (KEY_LEN bytes, BIG-ENDIAN)
127 * \param[in] ccm_nonce CCM Nonce (NONCE_LEN bytes, little-endian)
128 *
129 * \param[out] encrypted_packet_payload_and_mic Pointer to a buffer where the resulting encrypted payload with MIC appended will be stored
130 * (packet_payload_len + MIC_LEN bytes). The caller must allocate it.
131 */
blecrypt_packet_encrypt_v2(uint8_t aad,int packet_payload_len,const uint8_t * packet_payload,const uint8_t * sk,const uint8_t * ccm_nonce,uint8_t * encrypted_packet_payload_and_mic)132 void blecrypt_packet_encrypt_v2(
133 uint8_t aad,
134 int packet_payload_len,
135 const uint8_t *packet_payload,
136 const uint8_t *sk,
137 const uint8_t *ccm_nonce,
138 uint8_t *encrypted_packet_payload_and_mic)
139 {
140 int outlen;
141 // Set plaintext pointer to start of input packet payload
142 const uint8_t *pt = packet_payload;
143 // Set ciphertext pointer to start of encrypted packet payload
144 uint8_t *ct = encrypted_packet_payload_and_mic;
145 const int aad_len = 1; //Length of the Additional Authentication Data as per BT spec
146 // Allocate new cipher context
147 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
148 // Set cipher type to 128-bit AES, and mode to CCM (Counter with CBC-MAC)
149 EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), NULL, NULL, NULL);
150 // Set nonce length (because it is different from the 96-bit default)
151 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, NONCE_LEN, NULL);
152 // Set MIC (a.k.a MAC tag) length
153 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, MIC_LEN, NULL);
154 // Set encryption key and initialization vector (nonce)
155 EVP_EncryptInit_ex(ctx, NULL, NULL, sk, ccm_nonce);
156 // Set plaintext length (needed because AAD is used)
157 EVP_EncryptUpdate(ctx, NULL, &outlen, NULL, packet_payload_len);
158 // Provide AAD (addition authenticated data)
159 EVP_EncryptUpdate(ctx, NULL, &outlen, &aad, aad_len);
160 // Encrypt plaintext to cyphertext (and return number of encrypted bytes in outlen)
161 EVP_EncryptUpdate(ctx, ct, &outlen, pt, packet_payload_len);
162 // Get MIC and append it to encrypted data
163 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, MIC_LEN, (ct += outlen));
164 // Free cypher context
165 EVP_CIPHER_CTX_free(ctx);
166 }
167
168 /**
169 * Decrypt a BLE packet payload and check the MIC (if present)
170 * as per Bluetooth Core Specification Version 5.3 | Vol 6, Part E
171 *
172 * In comparison to blecrypt_packet_decrypt()
173 * this version is adapted to not apply the BT 4.2 AAD mask,
174 * but leave it to the caller, to be more transparent as to how the mask is meant to be applied
175 * for newer standard versions.
176 *
177 * \note Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations.
178 *
179 * \param[in] aad Additional Authentication Data: First byte of packet header after applying the bit mask
180 * Note: For BT 4.2 this is 0xE3. For 5.2 it depends on the packet type.
181 * \param[in] packet_payload_len Unencrypted packet payload length (i.e. *not* including header and MIC)
182 * \param[in] packet_payload_and mic Pointer to the packet payload (with MIC if any) to be decrypted (packet_payload_len (+ MIC_LEN) bytes)
183 * \param[in] sk Session key (KEY_LEN bytes, BIG-ENDIAN)
184 * \param[in] ccm_nonce CCM Nonce (NONCE_LEN bytes, little-endian)
185 * \param[in] no_mic Set to 1 if packet to be decrypted does not include a MIC, otherwise 0
186 *
187 * \param[out] decrypted_packet_payload Pointer to a buffer where the resulting decrypted payload will be stored
188 * (packet_payload_len bytes). The caller must allocate it.
189 *
190 * \return Returns 1 if MIC is ok, else 0
191 */
blecrypt_packet_decrypt_v2(uint8_t aad,int packet_payload_len,const uint8_t * packet_payload_and_mic,const uint8_t * sk,const uint8_t * ccm_nonce,int no_mic,uint8_t * decrypted_packet_payload)192 int blecrypt_packet_decrypt_v2(
193 uint8_t aad,
194 int packet_payload_len,
195 const uint8_t *packet_payload_and_mic,
196 const uint8_t *sk,
197 const uint8_t *ccm_nonce,
198 int no_mic,
199 uint8_t *decrypted_packet_payload)
200 {
201 int outlen, ok;
202 // Set ciphertext pointer to start of input packet payload
203 const uint8_t *ct = packet_payload_and_mic;
204 // Set plaintext pointer to start of decrypted packet payload
205 uint8_t *pt = decrypted_packet_payload;
206 const int aad_len = 1; //Length of the Additional Authentication Data as per BT spec
207 // Allocate new cipher context
208 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
209 // Set cipher type to 128-bit AES, and mode to CCM (Counter with CBC-MAC)
210 EVP_DecryptInit(ctx, EVP_aes_128_ccm(), NULL, NULL);
211 // Set nonce length (because it is different from the 96-bit default)
212 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, NONCE_LEN, NULL);
213 // Set hack flag indicating whether packet has MIC (standard BLE) or not
214 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_IGNORE_TAG, no_mic, NULL);
215
216 if (no_mic)
217 {
218 /* Set dummy MIC (a.k.a. tag) value to prevent complaints from OpenSSL */
219 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, MIC_LEN, (uint8_t[MIC_LEN]){0});
220 }
221 else
222 {
223 /* Set expected MIC (a.k.a. tag) value (located at ct + packet_payload_len) */
224 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, MIC_LEN, (uint8_t *) ct + packet_payload_len);
225 }
226 // Set decryption key and initialization vector (nonce)
227 EVP_DecryptInit(ctx, NULL, sk, ccm_nonce);
228 // Set ciphertext length (needed because AAD is used)
229 EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, packet_payload_len);
230 // Provide AAD (addition authenticated data)
231 EVP_DecryptUpdate(ctx, NULL, &outlen, &aad, aad_len);
232 // Decrypt ciphertext to plaintext and verify MIC (also return number of decrypted bytes in outlen)
233 ok = EVP_DecryptUpdate(ctx, pt, &outlen, ct, packet_payload_len);
234 // Free cipher context
235 EVP_CIPHER_CTX_free(ctx);
236 return ok;
237 }
238
239
240 /**
241 * CCM encrypt a packet payload and append the MAC/MIC,
242 *
243 * In comparison to blecrypt_packet_encrypt_v2()
244 * this version accepts variable sized AAD, and variable sized MAC/MIC
245 * to support 802.15.4 usecases.
246 * As such the "blecrypt_" prefix remains only due to the component it belongs to
247 *
248 * \note Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations.
249 *
250 * \param[in] adata Additional Authentication Data. Note, for BLE any possible bitmask must be applied by the caller
251 * \param[in] alen Length of adata
252 * \param[in] mlen Unencrypted packet payload length (i.e. *not* including header and MAC/MIC)
253 * \param[in] maclen Size of the MAC/MIC in bytes
254 * \param[in] noncelen Size of the nonce in bytes
255 * \param[in] mdata Unencrypted/input packet payload
256 * \param[in] sk Session key (KEY_LEN bytes)
257 * \param[in] ccm_nonce CCM Nonce (noncelen bytes)
258 *
259 * \param[out] encrypted_packet_payload_and_mac Pointer to a buffer where the resulting encrypted payload with MAC appended will be stored
260 * (mlen + maclen bytes). The caller must allocate it.
261 */
blecrypt_packet_encrypt_v3(uint8_t * adata,int alen,int mlen,int maclen,int noncelen,const uint8_t * mdata,const uint8_t * sk,const uint8_t * ccm_nonce,uint8_t * encrypted_packet_payload_and_mac)262 void blecrypt_packet_encrypt_v3(
263 uint8_t *adata,
264 int alen,
265 int mlen,
266 int maclen,
267 int noncelen,
268 const uint8_t *mdata,
269 const uint8_t *sk,
270 const uint8_t *ccm_nonce,
271 uint8_t *encrypted_packet_payload_and_mac)
272 {
273 int outlen;
274 // Set plaintext pointer to start of input packet payload
275 const uint8_t *pt = mdata;
276 // Set cyphertext pointer to start of encrypted packet payload
277 uint8_t *ct = encrypted_packet_payload_and_mac;
278
279 // Allocate new cypher context
280 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
281 // Set cipher type to 128-bit AES, and mode to CCM (Counter with CBC-MAC)
282 EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), NULL, NULL, NULL);
283 // Set nonce length (because it is different from the 96-bit default)
284 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, noncelen, NULL);
285 // Set MAC (a.k.a MAC tag) length
286 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, maclen, NULL);
287 // Set encryption key and initialization vector (nonce)
288 EVP_EncryptInit_ex(ctx, NULL, NULL, sk, ccm_nonce);
289 // Set plaintext length (needed because AAD is used)
290 EVP_EncryptUpdate(ctx, NULL, &outlen, NULL, mlen);
291 // Provide AAD (addition authenticated data)
292 EVP_EncryptUpdate(ctx, NULL, &outlen, adata, alen);
293 // Encrypt plaintext to cyphertext (and return number of encrypted bytes in outlen)
294 EVP_EncryptUpdate(ctx, ct, &outlen, pt, mlen);
295 // Get MAC and append it to encrypted data
296 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, maclen, (ct += outlen));
297 // Free cypher context
298 EVP_CIPHER_CTX_free(ctx);
299 }
300
301
302 /*
303 * CCM decrypt a packet payload and check the MAC/MIC (if present)
304 *
305 * In comparison to blecrypt_packet_decrypt_v2()
306 * this version accepts variable sized AAD, and variable sized MAC/MIC
307 * to support 802.15.4 usecases.
308 * As such the "blecrypt_" prefix remains only due to the component it belongs to
309 *
310 * \note Encrypted and unencrypted packet payloads must reside at different (non-overlapping) locations.
311 *
312 * \param[in] adata Additional Authentication Data. Note, for BLE any possible bitmask must be applied by the caller
313 * \param[in] alen Length of adata
314 * \param[in] mlen Unencrypted packet payload length (i.e. *not* including header and MAC/MIC)
315 * \param[in] maclen Size of the MAC/MIC in bytes
316 * \param[in] noncelen Size of the nonce in bytes
317 * \param[in] mdata_and_mac Pointer to the packet payload (with MAC if any) to be decrypted (packet_payload_len (+ MIC_LEN) bytes)
318 * \param[in] sk Session key (KEY_LEN bytes)
319 * \param[in] ccm_nonce CCM Nonce (noncelen bytes)
320 * \param[in] no_mac Set to 1 if packet to be decrypted does not include a MAC, otherwise 0
321 *
322 * \param[out] decrypted_packet_payload Pointer to a buffer where the resulting decrypted payload will be stored
323 * (mlen bytes). The caller must allocate it.
324 *
325 * \return Returns 1 if MIC is ok, else 0
326 */
blecrypt_packet_decrypt_v3(uint8_t * adata,int alen,int mlen,int maclen,int noncelen,const uint8_t * mdata_and_mac,const uint8_t * sk,const uint8_t * ccm_nonce,int no_mac,uint8_t * decrypted_packet_payload)327 int blecrypt_packet_decrypt_v3(
328 uint8_t *adata,
329 int alen,
330 int mlen,
331 int maclen,
332 int noncelen,
333 const uint8_t *mdata_and_mac,
334 const uint8_t *sk,
335 const uint8_t *ccm_nonce,
336 int no_mac,
337 uint8_t *decrypted_packet_payload)
338 {
339 int outlen, ok;
340 // Set cyphertext pointer to start of input packet payload
341 const uint8_t *ct = mdata_and_mac;
342 // Set plaintext pointer to start of decrypted packet payload
343 uint8_t *pt = decrypted_packet_payload;
344 // Allocate new cypher context
345 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
346 // Set cipher type to 128-bit AES, and mode to CCM (Counter with CBC-MAC)
347 EVP_DecryptInit(ctx, EVP_aes_128_ccm(), NULL, NULL);
348 // Set nonce length (because it is different from the 96-bit default)
349 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, noncelen, NULL);
350 // Set hack flag indicating whether packet has MAC or not
351 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_IGNORE_TAG, no_mac, NULL);
352
353 if (no_mac) {
354 #define DUMMY_MAC_LEN 4
355 /* Set dummy MAC (a.k.a. tag) value to prevent complaints from OpenSSL */
356 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, DUMMY_MAC_LEN, (uint8_t[DUMMY_MAC_LEN]){0});
357 } else {
358 /* Set expected MAC (a.k.a. tag) value (located at ct + mlen) */
359 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, maclen, (uint8_t *)ct + mlen);
360 }
361 // Set decryption key and initialization vector (nonce)
362 EVP_DecryptInit(ctx, NULL, sk, ccm_nonce);
363 // Set cyphertext length (needed because AAD is used)
364 EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, mlen);
365 // Provide AAD (addition authenticated data)
366 // Mask the first byte of adata
367 EVP_DecryptUpdate(ctx, NULL, &outlen, adata, alen);
368 // Decrypt cyphertext to plaintext and verify MAC (also return number of decrypted bytes in outlen)
369 ok = EVP_DecryptUpdate(ctx, pt, &outlen, ct, mlen);
370 // Free cypher context
371 EVP_CIPHER_CTX_free(ctx);
372 return ok;
373 }
374
375 // Reverses byte order of data
blecrypt_reverse_byte_order(const uint8_t * in_data,uint8_t * out_data,int len)376 void blecrypt_reverse_byte_order(const uint8_t *in_data, uint8_t *out_data, int len)
377 {
378 int i;
379 in_data += len - 1;
380 for (i = 0; i < len; i++)
381 {
382 *out_data++ = *in_data--;
383 }
384 }
385