1 /*
2 * Copyright (c) 2017 Intel Corporation
3 * Copyright (c) 2022 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <string.h>
9 #include <stdbool.h>
10 #include <errno.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/bluetooth/mesh.h>
13
14 #include "common/bt_str.h"
15
16 #include "mesh.h"
17 #include "crypto.h"
18
19 #define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL
20 #include <zephyr/logging/log.h>
21 LOG_MODULE_REGISTER(bt_mesh_crypto);
22
23 #define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4)
24 #define APP_MIC_LEN(aszmic) ((aszmic) ? 8 : 4)
25
bt_mesh_aes_cmac_one(const uint8_t key[16],const void * m,size_t len,uint8_t mac[16])26 static int bt_mesh_aes_cmac_one(const uint8_t key[16], const void *m, size_t len, uint8_t mac[16])
27 {
28 struct bt_mesh_sg sg = {m, len};
29
30 return bt_mesh_aes_cmac(key, &sg, 1, mac);
31 }
32
bt_mesh_sha256_hmac_one(const uint8_t key[32],const void * m,size_t len,uint8_t mac[32])33 static int bt_mesh_sha256_hmac_one(const uint8_t key[32], const void *m, size_t len,
34 uint8_t mac[32])
35 {
36 struct bt_mesh_sg sg = {m, len};
37
38 return bt_mesh_sha256_hmac(key, &sg, 1, mac);
39 }
40
bt_mesh_s1(const char * m,size_t m_len,uint8_t salt[16])41 int bt_mesh_s1(const char *m, size_t m_len, uint8_t salt[16])
42 {
43 const uint8_t zero[16] = { 0 };
44
45 return bt_mesh_aes_cmac_one(zero, m, m_len, salt);
46 }
47
bt_mesh_s2(const char * m,size_t m_len,uint8_t salt[32])48 int bt_mesh_s2(const char *m, size_t m_len, uint8_t salt[32])
49 {
50 const uint8_t zero[32] = { 0 };
51
52 return bt_mesh_sha256_hmac_one(zero, m, m_len, salt);
53 }
54
bt_mesh_k1(const uint8_t * ikm,size_t ikm_len,const uint8_t salt[16],const char * info,uint8_t okm[16])55 int bt_mesh_k1(const uint8_t *ikm, size_t ikm_len, const uint8_t salt[16],
56 const char *info, uint8_t okm[16])
57 {
58 int err;
59
60 err = bt_mesh_aes_cmac_one(salt, ikm, ikm_len, okm);
61 if (err < 0) {
62 return err;
63 }
64
65 return bt_mesh_aes_cmac_one(okm, info, strlen(info), okm);
66 }
67
bt_mesh_k2(const uint8_t n[16],const uint8_t * p,size_t p_len,uint8_t net_id[1],uint8_t enc_key[16],uint8_t priv_key[16])68 int bt_mesh_k2(const uint8_t n[16], const uint8_t *p, size_t p_len,
69 uint8_t net_id[1], uint8_t enc_key[16], uint8_t priv_key[16])
70 {
71 struct bt_mesh_sg sg[3];
72 uint8_t salt[16];
73 uint8_t out[16];
74 uint8_t t[16];
75 uint8_t pad;
76 int err;
77
78 LOG_DBG("n %s", bt_hex(n, 16));
79 LOG_DBG("p %s", bt_hex(p, p_len));
80
81 err = bt_mesh_s1_str("smk2", salt);
82 if (err) {
83 return err;
84 }
85
86 err = bt_mesh_aes_cmac_one(salt, n, 16, t);
87 if (err) {
88 return err;
89 }
90
91 pad = 0x01;
92
93 sg[0].data = NULL;
94 sg[0].len = 0;
95 sg[1].data = p;
96 sg[1].len = p_len;
97 sg[2].data = &pad;
98 sg[2].len = sizeof(pad);
99
100 err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
101 if (err) {
102 return err;
103 }
104
105 net_id[0] = out[15] & 0x7f;
106
107 sg[0].data = out;
108 sg[0].len = sizeof(out);
109 pad = 0x02;
110
111 err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
112 if (err) {
113 return err;
114 }
115
116 memcpy(enc_key, out, 16);
117
118 pad = 0x03;
119
120 err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
121 if (err) {
122 return err;
123 }
124
125 memcpy(priv_key, out, 16);
126
127 LOG_DBG("NID 0x%02x enc_key %s", net_id[0], bt_hex(enc_key, 16));
128 LOG_DBG("priv_key %s", bt_hex(priv_key, 16));
129
130 return 0;
131 }
132
bt_mesh_k3(const uint8_t n[16],uint8_t out[8])133 int bt_mesh_k3(const uint8_t n[16], uint8_t out[8])
134 {
135 uint8_t id64[] = { 'i', 'd', '6', '4', 0x01 };
136 uint8_t tmp[16];
137 uint8_t t[16];
138 int err;
139
140 err = bt_mesh_s1_str("smk3", tmp);
141 if (err) {
142 return err;
143 }
144
145 err = bt_mesh_aes_cmac_one(tmp, n, 16, t);
146 if (err) {
147 return err;
148 }
149
150 err = bt_mesh_aes_cmac_one(t, id64, sizeof(id64), tmp);
151 if (err) {
152 return err;
153 }
154
155 memcpy(out, tmp + 8, 8);
156
157 return 0;
158 }
159
bt_mesh_k4(const uint8_t n[16],uint8_t out[1])160 int bt_mesh_k4(const uint8_t n[16], uint8_t out[1])
161 {
162 uint8_t id6[] = { 'i', 'd', '6', 0x01 };
163 uint8_t tmp[16];
164 uint8_t t[16];
165 int err;
166
167 err = bt_mesh_s1_str("smk4", tmp);
168 if (err) {
169 return err;
170 }
171
172 err = bt_mesh_aes_cmac_one(tmp, n, 16, t);
173 if (err) {
174 return err;
175 }
176
177 err = bt_mesh_aes_cmac_one(t, id6, sizeof(id6), tmp);
178 if (err) {
179 return err;
180 }
181
182 out[0] = tmp[15] & BIT_MASK(6);
183
184 return 0;
185 }
186
bt_mesh_k5(const uint8_t * n,size_t n_len,const uint8_t salt[32],uint8_t * p,uint8_t out[32])187 int bt_mesh_k5(const uint8_t *n, size_t n_len, const uint8_t salt[32],
188 uint8_t *p, uint8_t out[32])
189 {
190 uint8_t t[32];
191 int err;
192
193 err = bt_mesh_sha256_hmac_one(salt, n, n_len, t);
194 if (err) {
195 return err;
196 }
197
198 err = bt_mesh_sha256_hmac_one(t, p, strlen(p), out);
199 if (err) {
200 return err;
201 }
202
203 return 0;
204 }
205
bt_mesh_id128(const uint8_t n[16],const char * s,uint8_t out[16])206 int bt_mesh_id128(const uint8_t n[16], const char *s, uint8_t out[16])
207 {
208 const char *id128 = "id128\x01";
209 uint8_t salt[16];
210 int err;
211
212 err = bt_mesh_s1_str(s, salt);
213 if (err) {
214 return err;
215 }
216
217 return bt_mesh_k1(n, 16, salt, id128, out);
218 }
219
bt_mesh_prov_nonce(const uint8_t dhkey[32],const uint8_t prov_salt[16],uint8_t nonce[13])220 int bt_mesh_prov_nonce(const uint8_t dhkey[32], const uint8_t prov_salt[16], uint8_t nonce[13])
221 {
222 uint8_t tmp[16];
223 int err;
224
225 err = bt_mesh_k1(dhkey, 32, prov_salt, "prsn", tmp);
226 if (!err) {
227 memcpy(nonce, tmp + 3, 13);
228 }
229
230 return err;
231 }
232
bt_mesh_session_key(const uint8_t dhkey[32],const uint8_t prov_salt[16],uint8_t session_key[16])233 int bt_mesh_session_key(const uint8_t dhkey[32], const uint8_t prov_salt[16],
234 uint8_t session_key[16])
235 {
236 return bt_mesh_k1(dhkey, 32, prov_salt, "prsk", session_key);
237 }
238
bt_mesh_dev_key(const uint8_t dhkey[32],const uint8_t prov_salt[16],uint8_t dev_key[16])239 int bt_mesh_dev_key(const uint8_t dhkey[32], const uint8_t prov_salt[16], uint8_t dev_key[16])
240 {
241 return bt_mesh_k1(dhkey, 32, prov_salt, "prdk", dev_key);
242 }
243
create_proxy_nonce(uint8_t nonce[13],const uint8_t * pdu,uint32_t iv_index)244 static void create_proxy_nonce(uint8_t nonce[13], const uint8_t *pdu,
245 uint32_t iv_index)
246 {
247 memset(nonce, 0, 13);
248
249 /* Nonce Type */
250 nonce[0] = 0x03;
251
252 /* Sequence Number */
253 nonce[2] = pdu[2];
254 nonce[3] = pdu[3];
255 nonce[4] = pdu[4];
256
257 /* Source Address */
258 nonce[5] = pdu[5];
259 nonce[6] = pdu[6];
260
261 /* IV Index */
262 sys_put_be32(iv_index, &nonce[9]);
263 }
264
create_proxy_sol_nonce(uint8_t nonce[13],const uint8_t * pdu)265 static void create_proxy_sol_nonce(uint8_t nonce[13], const uint8_t *pdu)
266 {
267 memset(nonce, 0, 13);
268
269 /* Nonce Type */
270 nonce[0] = 0x04;
271
272 /* Sequence Number */
273 nonce[2] = pdu[2];
274 nonce[3] = pdu[3];
275 nonce[4] = pdu[4];
276
277 /* Source Address */
278 nonce[5] = pdu[5];
279 nonce[6] = pdu[6];
280 }
281
create_net_nonce(uint8_t nonce[13],const uint8_t * pdu,uint32_t iv_index)282 static void create_net_nonce(uint8_t nonce[13], const uint8_t *pdu,
283 uint32_t iv_index)
284 {
285 /* Nonce Type */
286 nonce[0] = 0x00;
287
288 /* FRND + TTL */
289 nonce[1] = pdu[1];
290
291 /* Sequence Number */
292 nonce[2] = pdu[2];
293 nonce[3] = pdu[3];
294 nonce[4] = pdu[4];
295
296 /* Source Address */
297 nonce[5] = pdu[5];
298 nonce[6] = pdu[6];
299
300 /* Pad */
301 nonce[7] = 0U;
302 nonce[8] = 0U;
303
304 /* IV Index */
305 sys_put_be32(iv_index, &nonce[9]);
306 }
307
bt_mesh_net_obfuscate(uint8_t * pdu,uint32_t iv_index,const uint8_t privacy_key[16])308 int bt_mesh_net_obfuscate(uint8_t *pdu, uint32_t iv_index,
309 const uint8_t privacy_key[16])
310 {
311 uint8_t priv_rand[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
312 uint8_t tmp[16];
313 int err, i;
314
315 LOG_DBG("IVIndex %u, PrivacyKey %s", iv_index, bt_hex(privacy_key, 16));
316
317 sys_put_be32(iv_index, &priv_rand[5]);
318 memcpy(&priv_rand[9], &pdu[7], 7);
319
320 LOG_DBG("PrivacyRandom %s", bt_hex(priv_rand, 16));
321
322 err = bt_mesh_encrypt(privacy_key, priv_rand, tmp);
323 if (err) {
324 return err;
325 }
326
327 for (i = 0; i < 6; i++) {
328 pdu[1 + i] ^= tmp[i];
329 }
330
331 return 0;
332 }
333
bt_mesh_net_encrypt(const uint8_t key[16],struct net_buf_simple * buf,uint32_t iv_index,enum bt_mesh_nonce_type type)334 int bt_mesh_net_encrypt(const uint8_t key[16], struct net_buf_simple *buf,
335 uint32_t iv_index, enum bt_mesh_nonce_type type)
336 {
337 uint8_t mic_len = NET_MIC_LEN(buf->data);
338 uint8_t nonce[13];
339 int err;
340
341 LOG_DBG("IVIndex %u EncKey %s mic_len %u", iv_index, bt_hex(key, 16), mic_len);
342 LOG_DBG("PDU (len %u) %s", buf->len, bt_hex(buf->data, buf->len));
343
344 if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && type == BT_MESH_NONCE_PROXY) {
345 create_proxy_nonce(nonce, buf->data, iv_index);
346 } else if (IS_ENABLED(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) &&
347 type == BT_MESH_NONCE_SOLICITATION) {
348 create_proxy_sol_nonce(nonce, buf->data);
349 } else {
350 create_net_nonce(nonce, buf->data, iv_index);
351 }
352
353 LOG_DBG("Nonce %s", bt_hex(nonce, 13));
354
355 err = bt_mesh_ccm_encrypt(key, nonce, &buf->data[7], buf->len - 7, NULL, 0,
356 &buf->data[7], mic_len);
357 if (!err) {
358 net_buf_simple_add(buf, mic_len);
359 }
360
361 return err;
362 }
363
bt_mesh_net_decrypt(const uint8_t key[16],struct net_buf_simple * buf,uint32_t iv_index,enum bt_mesh_nonce_type type)364 int bt_mesh_net_decrypt(const uint8_t key[16], struct net_buf_simple *buf,
365 uint32_t iv_index, enum bt_mesh_nonce_type type)
366 {
367 uint8_t mic_len = NET_MIC_LEN(buf->data);
368 uint8_t nonce[13];
369
370 LOG_DBG("PDU (%u bytes) %s", buf->len, bt_hex(buf->data, buf->len));
371 LOG_DBG("iv_index %u, key %s mic_len %u", iv_index, bt_hex(key, 16), mic_len);
372
373 if (IS_ENABLED(CONFIG_BT_MESH_PROXY) && type == BT_MESH_NONCE_PROXY) {
374 create_proxy_nonce(nonce, buf->data, iv_index);
375 } else if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) &&
376 type == BT_MESH_NONCE_SOLICITATION) {
377 create_proxy_sol_nonce(nonce, buf->data);
378 } else {
379 create_net_nonce(nonce, buf->data, iv_index);
380 }
381
382 LOG_DBG("Nonce %s", bt_hex(nonce, 13));
383
384 buf->len -= mic_len;
385
386 return bt_mesh_ccm_decrypt(key, nonce, &buf->data[7], buf->len - 7, NULL, 0,
387 &buf->data[7], mic_len);
388 }
389
create_app_nonce(uint8_t nonce[13],const struct bt_mesh_app_crypto_ctx * ctx)390 static void create_app_nonce(uint8_t nonce[13],
391 const struct bt_mesh_app_crypto_ctx *ctx)
392 {
393 if (ctx->dev_key) {
394 nonce[0] = 0x02;
395 } else {
396 nonce[0] = 0x01;
397 }
398
399 sys_put_be32((ctx->seq_num | ((uint32_t)ctx->aszmic << 31)), &nonce[1]);
400
401 sys_put_be16(ctx->src, &nonce[5]);
402 sys_put_be16(ctx->dst, &nonce[7]);
403
404 sys_put_be32(ctx->iv_index, &nonce[9]);
405 }
406
bt_mesh_app_encrypt(const uint8_t key[16],const struct bt_mesh_app_crypto_ctx * ctx,struct net_buf_simple * buf)407 int bt_mesh_app_encrypt(const uint8_t key[16],
408 const struct bt_mesh_app_crypto_ctx *ctx,
409 struct net_buf_simple *buf)
410 {
411 uint8_t nonce[13];
412 int err;
413
414 LOG_DBG("AppKey %s", bt_hex(key, 16));
415 LOG_DBG("dev_key %u src 0x%04x dst 0x%04x", ctx->dev_key, ctx->src, ctx->dst);
416 LOG_DBG("seq_num 0x%08x iv_index 0x%08x", ctx->seq_num, ctx->iv_index);
417 LOG_DBG("Clear: %s", bt_hex(buf->data, buf->len));
418
419 create_app_nonce(nonce, ctx);
420
421 LOG_DBG("Nonce %s", bt_hex(nonce, 13));
422
423 err = bt_mesh_ccm_encrypt(key, nonce, buf->data, buf->len, ctx->ad,
424 ctx->ad ? 16 : 0, buf->data,
425 APP_MIC_LEN(ctx->aszmic));
426 if (!err) {
427 net_buf_simple_add(buf, APP_MIC_LEN(ctx->aszmic));
428 LOG_DBG("Encr: %s", bt_hex(buf->data, buf->len));
429 }
430
431 return err;
432 }
433
bt_mesh_app_decrypt(const uint8_t key[16],const struct bt_mesh_app_crypto_ctx * ctx,struct net_buf_simple * buf,struct net_buf_simple * out)434 int bt_mesh_app_decrypt(const uint8_t key[16],
435 const struct bt_mesh_app_crypto_ctx *ctx,
436 struct net_buf_simple *buf, struct net_buf_simple *out)
437 {
438 uint8_t nonce[13];
439 int err;
440
441 LOG_DBG("EncData (len %u) %s", buf->len, bt_hex(buf->data, buf->len));
442
443 create_app_nonce(nonce, ctx);
444
445 LOG_DBG("AppKey %s", bt_hex(key, 16));
446 LOG_DBG("Nonce %s", bt_hex(nonce, 13));
447
448 err = bt_mesh_ccm_decrypt(key, nonce, buf->data, buf->len, ctx->ad,
449 ctx->ad ? 16 : 0, out->data,
450 APP_MIC_LEN(ctx->aszmic));
451 if (!err) {
452 net_buf_simple_add(out, buf->len);
453 }
454
455 return err;
456 }
457
458 /* reversed, 8-bit, poly=0x07 */
459 static const uint8_t crc_table[256] = {
460 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
461 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
462 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
463 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
464
465 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
466 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
467 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
468 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
469
470 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
471 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
472 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
473 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
474
475 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
476 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
477 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
478 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
479
480 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
481 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
482 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
483 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
484
485 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
486 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
487 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
488 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
489
490 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
491 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
492 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
493 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
494
495 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
496 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
497 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
498 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
499 };
500
bt_mesh_fcs_calc(const uint8_t * data,uint8_t data_len)501 uint8_t bt_mesh_fcs_calc(const uint8_t *data, uint8_t data_len)
502 {
503 uint8_t fcs = 0xff;
504
505 while (data_len--) {
506 fcs = crc_table[fcs ^ *data++];
507 }
508
509 LOG_DBG("fcs 0x%02x", 0xff - fcs);
510
511 return 0xff - fcs;
512 }
513
bt_mesh_fcs_check(struct net_buf_simple * buf,uint8_t received_fcs)514 bool bt_mesh_fcs_check(struct net_buf_simple *buf, uint8_t received_fcs)
515 {
516 const uint8_t *data = buf->data;
517 uint16_t data_len = buf->len;
518 uint8_t fcs = 0xff;
519
520 while (data_len--) {
521 fcs = crc_table[fcs ^ *data++];
522 }
523
524 return crc_table[fcs ^ received_fcs] == 0xcf;
525 }
526
bt_mesh_virtual_addr(const uint8_t virtual_label[16],uint16_t * addr)527 int bt_mesh_virtual_addr(const uint8_t virtual_label[16], uint16_t *addr)
528 {
529 uint8_t salt[16];
530 uint8_t tmp[16];
531 int err;
532
533 err = bt_mesh_s1_str("vtad", salt);
534 if (err) {
535 return err;
536 }
537
538 err = bt_mesh_aes_cmac_one(salt, virtual_label, 16, tmp);
539 if (err) {
540 return err;
541 }
542
543 *addr = (sys_get_be16(&tmp[14]) & 0x3fff) | 0x8000;
544
545 return 0;
546 }
547
bt_mesh_prov_salt(uint8_t algorithm,const uint8_t * conf_salt,const uint8_t * prov_rand,const uint8_t * dev_rand,uint8_t * prov_salt)548 int bt_mesh_prov_salt(uint8_t algorithm,
549 const uint8_t *conf_salt,
550 const uint8_t *prov_rand,
551 const uint8_t *dev_rand,
552 uint8_t *prov_salt)
553 {
554 uint8_t size = algorithm ? 32 : 16;
555 const uint8_t prov_salt_key[16] = { 0 };
556 struct bt_mesh_sg sg[] = {
557 { conf_salt, size },
558 { prov_rand, size },
559 { dev_rand, size },
560 };
561
562 return bt_mesh_aes_cmac(prov_salt_key, sg, ARRAY_SIZE(sg), prov_salt);
563 }
564
bt_mesh_prov_conf_salt(uint8_t algorithm,const uint8_t conf_inputs[145],uint8_t * salt)565 int bt_mesh_prov_conf_salt(uint8_t algorithm, const uint8_t conf_inputs[145],
566 uint8_t *salt)
567 {
568 if (algorithm == BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM &&
569 IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM)) {
570
571 return bt_mesh_s2(conf_inputs, 145, salt);
572 }
573
574 if (algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM &&
575 IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM)) {
576
577 return bt_mesh_s1(conf_inputs, 145, salt);
578 }
579
580 return -EINVAL;
581 }
582
bt_mesh_prov_conf_key(uint8_t algorithm,const uint8_t * k_input,const uint8_t * conf_salt,uint8_t * conf_key)583 int bt_mesh_prov_conf_key(uint8_t algorithm, const uint8_t *k_input,
584 const uint8_t *conf_salt, uint8_t *conf_key)
585 {
586 if (algorithm == BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM &&
587 IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM)) {
588
589 return bt_mesh_k5(k_input, 64, conf_salt, "prck256", conf_key);
590 }
591
592 if (algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM &&
593 IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM)) {
594
595 return bt_mesh_k1(k_input, 32, conf_salt, "prck", conf_key);
596 }
597
598 return -EINVAL;
599 }
600
bt_mesh_prov_conf(uint8_t algorithm,const uint8_t * conf_key,const uint8_t * prov_rand,const uint8_t * auth,uint8_t * conf)601 int bt_mesh_prov_conf(uint8_t algorithm, const uint8_t *conf_key,
602 const uint8_t *prov_rand, const uint8_t *auth, uint8_t *conf)
603 {
604 uint8_t auth_size = algorithm ? 32 : 16;
605
606 LOG_DBG("ConfirmationKey %s", bt_hex(conf_key, auth_size));
607 LOG_DBG("RandomDevice %s", bt_hex(prov_rand, auth_size));
608 LOG_DBG("AuthValue %s", bt_hex(auth, auth_size));
609
610 if (algorithm == BT_MESH_PROV_AUTH_HMAC_SHA256_AES_CCM &&
611 IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM)) {
612
613 return bt_mesh_sha256_hmac_one(conf_key, prov_rand, 32, conf);
614 }
615
616 if (algorithm == BT_MESH_PROV_AUTH_CMAC_AES128_AES_CCM &&
617 IS_ENABLED(CONFIG_BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM)) {
618 struct bt_mesh_sg sg[] = { { prov_rand, 16 }, { auth, 16 } };
619
620 return bt_mesh_aes_cmac(conf_key, sg, ARRAY_SIZE(sg), conf);
621 }
622
623 return -EINVAL;
624 }
625
bt_mesh_prov_decrypt(const uint8_t key[16],uint8_t nonce[13],const uint8_t data[25+8],uint8_t out[25])626 int bt_mesh_prov_decrypt(const uint8_t key[16], uint8_t nonce[13],
627 const uint8_t data[25 + 8], uint8_t out[25])
628 {
629 return bt_mesh_ccm_decrypt(key, nonce, data, 25, NULL, 0, out, 8);
630 }
631
bt_mesh_prov_encrypt(const uint8_t key[16],uint8_t nonce[13],const uint8_t data[25],uint8_t out[25+8])632 int bt_mesh_prov_encrypt(const uint8_t key[16], uint8_t nonce[13],
633 const uint8_t data[25], uint8_t out[25 + 8])
634 {
635 return bt_mesh_ccm_encrypt(key, nonce, data, 25, NULL, 0, out, 8);
636 }
637
bt_mesh_beacon_auth(const uint8_t beacon_key[16],uint8_t flags,const uint8_t net_id[8],uint32_t iv_index,uint8_t auth[8])638 int bt_mesh_beacon_auth(const uint8_t beacon_key[16], uint8_t flags,
639 const uint8_t net_id[8], uint32_t iv_index,
640 uint8_t auth[8])
641 {
642 uint8_t msg[13], tmp[16];
643 int err;
644
645 LOG_DBG("BeaconKey %s", bt_hex(beacon_key, 16));
646 LOG_DBG("NetId %s", bt_hex(net_id, 8));
647 LOG_DBG("IV Index 0x%08x", iv_index);
648
649 msg[0] = flags;
650 memcpy(&msg[1], net_id, 8);
651 sys_put_be32(iv_index, &msg[9]);
652
653 LOG_DBG("BeaconMsg %s", bt_hex(msg, sizeof(msg)));
654
655 err = bt_mesh_aes_cmac_one(beacon_key, msg, sizeof(msg), tmp);
656 if (!err) {
657 memcpy(auth, tmp, 8);
658 }
659
660 return err;
661 }
662
private_beacon_obf(const uint8_t pbk[16],const uint8_t data[5],const uint8_t random[13],uint8_t out[5])663 static int private_beacon_obf(const uint8_t pbk[16], const uint8_t data[5],
664 const uint8_t random[13], uint8_t out[5])
665 {
666 uint8_t salt[16];
667 int i, err;
668
669 /* C1 = 0x01 | random | 0x0001 */
670 salt[0] = 0x01;
671 memcpy(&salt[1], random, 13);
672 sys_put_be16(0x0001, &salt[14]);
673
674 /* ObfData = e(pbk, C1) ^ (flags | iv_index) */
675 err = bt_mesh_encrypt(pbk, salt, salt);
676 if (err) {
677 return err;
678 }
679
680 for (i = 0; i < 5; i++) {
681 out[i] = data[i] ^ salt[i];
682 }
683
684
685 return 0;
686 }
687
private_beacon_auth(const uint8_t pbk[16],const uint8_t beacon_data[5],const uint8_t random[13],uint8_t auth[8])688 static int private_beacon_auth(const uint8_t pbk[16],
689 const uint8_t beacon_data[5],
690 const uint8_t random[13], uint8_t auth[8])
691 {
692 uint8_t salt[16], tmp[16];
693 int i, err;
694
695 /* B0 = 0x19 | random | 0x0005 */
696 salt[0] = 0x19;
697 memcpy(&salt[1], random, 13);
698 sys_put_be16(0x0005, &salt[14]);
699
700 /* T0 = e(PBK, b0) */
701 err = bt_mesh_encrypt(pbk, salt, tmp);
702 if (err) {
703 return err;
704 }
705
706 /* P = flags | iv_index | 000 */
707 /* T1 = e(PBK, P ^ T0) */
708 for (i = 0; i < 5; i++) {
709 tmp[i] ^= beacon_data[i];
710 }
711
712 err = bt_mesh_encrypt(pbk, tmp, tmp);
713 if (err) {
714 return err;
715 }
716
717 /* C0 = 0x01 | random | 0x0000 */
718 salt[0] = 0x01;
719 sys_put_be16(0x0000, &salt[14]);
720
721 /* T2 = T1 ^ e(PBK, C0) */
722 memcpy(auth, tmp, 8);
723
724 err = bt_mesh_encrypt(pbk, salt, tmp);
725 if (err) {
726 return err;
727 }
728
729 /* Auth = T2[0..7] */
730 for (i = 0; i < 8; i++) {
731 auth[i] ^= tmp[i];
732 }
733
734 return 0;
735 }
736
bt_mesh_beacon_decrypt(const uint8_t pbk[16],const uint8_t random[13],const uint8_t data[5],const uint8_t expected_auth[8],uint8_t out[5])737 int bt_mesh_beacon_decrypt(const uint8_t pbk[16], const uint8_t random[13],
738 const uint8_t data[5],
739 const uint8_t expected_auth[8], uint8_t out[5])
740 {
741 uint8_t auth[8];
742 int err;
743
744 LOG_DBG("");
745
746 err = private_beacon_obf(pbk, data, random, out);
747 if (err) {
748 return err;
749 }
750
751 err = private_beacon_auth(pbk, out, random, auth);
752 if (err) {
753 return err;
754 }
755
756 LOG_DBG("0x%02x, 0x%08x", out[0], sys_get_be32(&out[1]));
757
758 if (memcmp(auth, expected_auth, 8)) {
759 LOG_DBG("Invalid auth: %s expected %s", bt_hex(auth, 8),
760 bt_hex(expected_auth, 8));
761 return -EBADMSG;
762 }
763
764 return 0;
765 }
766
bt_mesh_beacon_encrypt(const uint8_t pbk[16],uint8_t flags,uint32_t iv_index,const uint8_t random[13],uint8_t data[5],uint8_t auth[8])767 int bt_mesh_beacon_encrypt(const uint8_t pbk[16], uint8_t flags,
768 uint32_t iv_index, const uint8_t random[13],
769 uint8_t data[5], uint8_t auth[8])
770 {
771 int err;
772
773 LOG_WRN("Enc beacon: 0x%02x, 0x%08x", flags, iv_index);
774
775 data[0] = flags;
776 sys_put_be32(iv_index, &data[1]);
777
778 err = private_beacon_auth(pbk, data, random, auth);
779 if (err) {
780 return err;
781 }
782
783 return private_beacon_obf(pbk, data, random, data);
784 }
785