1 /*
2 * Copyright (c) 2017 Intel Corporation
3 * Copyright (c) 2023 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <errno.h>
9
10 #include <tinycrypt/constants.h>
11 #include <tinycrypt/utils.h>
12 #include <tinycrypt/aes.h>
13 #include <tinycrypt/cmac_mode.h>
14 #include <tinycrypt/ccm_mode.h>
15 #include <tinycrypt/ecc.h>
16 #include <tinycrypt/ecc_dh.h>
17 #include <tinycrypt/hmac.h>
18
19 #include <zephyr/bluetooth/mesh.h>
20 #include <zephyr/bluetooth/crypto.h>
21
22 #define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL
23 #include <zephyr/logging/log.h>
24 LOG_MODULE_REGISTER(bt_mesh_crypto_tc);
25
26 #include "mesh.h"
27 #include "crypto.h"
28 #include "prov.h"
29
30 static struct {
31 bool is_ready;
32 uint8_t private_key_be[PRIV_KEY_SIZE];
33 uint8_t public_key_be[PUB_KEY_SIZE];
34 } dh_pair;
35
bt_mesh_encrypt(const struct bt_mesh_key * key,const uint8_t plaintext[16],uint8_t enc_data[16])36 int bt_mesh_encrypt(const struct bt_mesh_key *key, const uint8_t plaintext[16],
37 uint8_t enc_data[16])
38 {
39 return bt_encrypt_be(key->key, plaintext, enc_data);
40 }
41
bt_mesh_ccm_encrypt(const struct bt_mesh_key * key,uint8_t nonce[13],const uint8_t * plaintext,size_t len,const uint8_t * aad,size_t aad_len,uint8_t * enc_data,size_t mic_size)42 int bt_mesh_ccm_encrypt(const struct bt_mesh_key *key, uint8_t nonce[13], const uint8_t *plaintext,
43 size_t len, const uint8_t *aad, size_t aad_len, uint8_t *enc_data,
44 size_t mic_size)
45 {
46 return bt_ccm_encrypt(key->key, nonce, plaintext, len, aad, aad_len, enc_data, mic_size);
47 }
48
bt_mesh_ccm_decrypt(const struct bt_mesh_key * key,uint8_t nonce[13],const uint8_t * enc_data,size_t len,const uint8_t * aad,size_t aad_len,uint8_t * plaintext,size_t mic_size)49 int bt_mesh_ccm_decrypt(const struct bt_mesh_key *key, uint8_t nonce[13], const uint8_t *enc_data,
50 size_t len, const uint8_t *aad, size_t aad_len, uint8_t *plaintext,
51 size_t mic_size)
52 {
53 return bt_ccm_decrypt(key->key, nonce, enc_data, len, aad, aad_len, plaintext, mic_size);
54 }
55
bt_mesh_aes_cmac_raw_key(const uint8_t key[16],struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[16])56 int bt_mesh_aes_cmac_raw_key(const uint8_t key[16], struct bt_mesh_sg *sg, size_t sg_len,
57 uint8_t mac[16])
58 {
59 struct tc_aes_key_sched_struct sched;
60 struct tc_cmac_struct state;
61
62 if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) {
63 return -EIO;
64 }
65
66 for (; sg_len; sg_len--, sg++) {
67 if (tc_cmac_update(&state, sg->data, sg->len) == TC_CRYPTO_FAIL) {
68 return -EIO;
69 }
70 }
71
72 if (tc_cmac_final(mac, &state) == TC_CRYPTO_FAIL) {
73 return -EIO;
74 }
75
76 return 0;
77 }
78
bt_mesh_aes_cmac_mesh_key(const struct bt_mesh_key * key,struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[16])79 int bt_mesh_aes_cmac_mesh_key(const struct bt_mesh_key *key, struct bt_mesh_sg *sg,
80 size_t sg_len, uint8_t mac[16])
81 {
82 return bt_mesh_aes_cmac_raw_key(key->key, sg, sg_len, mac);
83 }
84
bt_mesh_sha256_hmac_raw_key(const uint8_t key[32],struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[32])85 int bt_mesh_sha256_hmac_raw_key(const uint8_t key[32], struct bt_mesh_sg *sg, size_t sg_len,
86 uint8_t mac[32])
87 {
88 struct tc_hmac_state_struct h;
89
90 if (tc_hmac_set_key(&h, key, 32) == TC_CRYPTO_FAIL) {
91 return -EIO;
92 }
93
94 if (tc_hmac_init(&h) == TC_CRYPTO_FAIL) {
95 return -EIO;
96 }
97
98 for (; sg_len; sg_len--, sg++) {
99 if (tc_hmac_update(&h, sg->data, sg->len) == TC_CRYPTO_FAIL) {
100 return -EIO;
101 }
102 }
103
104 if (tc_hmac_final(mac, 32, &h) == TC_CRYPTO_FAIL) {
105 return -EIO;
106 }
107
108 return 0;
109 }
110
bt_mesh_pub_key_gen(void)111 int bt_mesh_pub_key_gen(void)
112 {
113 int rc = uECC_make_key(dh_pair.public_key_be,
114 dh_pair.private_key_be,
115 &curve_secp256r1);
116
117 if (rc == TC_CRYPTO_FAIL) {
118 dh_pair.is_ready = false;
119 LOG_ERR("Failed to create public/private pair");
120 return -EIO;
121 }
122
123 dh_pair.is_ready = true;
124
125 return 0;
126 }
127
bt_mesh_pub_key_get(void)128 const uint8_t *bt_mesh_pub_key_get(void)
129 {
130 return dh_pair.is_ready ? dh_pair.public_key_be : NULL;
131 }
132
bt_mesh_dhkey_gen(const uint8_t * pub_key,const uint8_t * priv_key,uint8_t * dhkey)133 int bt_mesh_dhkey_gen(const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *dhkey)
134 {
135 if (uECC_valid_public_key(pub_key, &curve_secp256r1)) {
136 LOG_ERR("Public key is not valid");
137 return -EIO;
138 } else if (uECC_shared_secret(pub_key, priv_key ? priv_key :
139 dh_pair.private_key_be,
140 dhkey, &curve_secp256r1) != TC_CRYPTO_SUCCESS) {
141 LOG_ERR("DHKey generation failed");
142 return -EIO;
143 }
144
145 return 0;
146 }
147
default_CSPRNG(uint8_t * dst,unsigned int len)148 __weak int default_CSPRNG(uint8_t *dst, unsigned int len)
149 {
150 return !bt_rand(dst, len);
151 }
152
bt_mesh_crypto_init(void)153 int bt_mesh_crypto_init(void)
154 {
155 return 0;
156 }
157