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 } key;
35 
bt_mesh_encrypt(const uint8_t key[16],const uint8_t plaintext[16],uint8_t enc_data[16])36 int bt_mesh_encrypt(const uint8_t key[16], const uint8_t plaintext[16], uint8_t enc_data[16])
37 {
38 	return bt_encrypt_be(key, plaintext, enc_data);
39 }
40 
bt_mesh_ccm_encrypt(const uint8_t key[16],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)41 int bt_mesh_ccm_encrypt(const uint8_t key[16], uint8_t nonce[13], const uint8_t *plaintext,
42 			size_t len, const uint8_t *aad, size_t aad_len, uint8_t *enc_data,
43 			size_t mic_size)
44 {
45 	return bt_ccm_encrypt(key, nonce, plaintext, len, aad, aad_len, enc_data, mic_size);
46 }
47 
bt_mesh_ccm_decrypt(const uint8_t key[16],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)48 int bt_mesh_ccm_decrypt(const uint8_t key[16], uint8_t nonce[13], const uint8_t *enc_data,
49 			size_t len, const uint8_t *aad, size_t aad_len, uint8_t *plaintext,
50 			size_t mic_size)
51 {
52 	return bt_ccm_decrypt(key, nonce, enc_data, len, aad, aad_len, plaintext, mic_size);
53 }
54 
bt_mesh_aes_cmac(const uint8_t key[16],struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[16])55 int bt_mesh_aes_cmac(const uint8_t key[16], struct bt_mesh_sg *sg, size_t sg_len, uint8_t mac[16])
56 {
57 	struct tc_aes_key_sched_struct sched;
58 	struct tc_cmac_struct state;
59 
60 	if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) {
61 		return -EIO;
62 	}
63 
64 	for (; sg_len; sg_len--, sg++) {
65 		if (tc_cmac_update(&state, sg->data, sg->len) == TC_CRYPTO_FAIL) {
66 			return -EIO;
67 		}
68 	}
69 
70 	if (tc_cmac_final(mac, &state) == TC_CRYPTO_FAIL) {
71 		return -EIO;
72 	}
73 
74 	return 0;
75 }
76 
bt_mesh_sha256_hmac(const uint8_t key[32],struct bt_mesh_sg * sg,size_t sg_len,uint8_t mac[32])77 int bt_mesh_sha256_hmac(const uint8_t key[32], struct bt_mesh_sg *sg, size_t sg_len,
78 			uint8_t mac[32])
79 {
80 	struct tc_hmac_state_struct h;
81 
82 	if (tc_hmac_set_key(&h, key, 32) == TC_CRYPTO_FAIL) {
83 		return -EIO;
84 	}
85 
86 	if (tc_hmac_init(&h) == TC_CRYPTO_FAIL) {
87 		return -EIO;
88 	}
89 
90 	for (; sg_len; sg_len--, sg++) {
91 		if (tc_hmac_update(&h, sg->data, sg->len) == TC_CRYPTO_FAIL) {
92 			return -EIO;
93 		}
94 	}
95 
96 	if (tc_hmac_final(mac, 32, &h) == TC_CRYPTO_FAIL) {
97 		return -EIO;
98 	}
99 
100 	return 0;
101 }
102 
bt_mesh_pub_key_gen(void)103 int bt_mesh_pub_key_gen(void)
104 {
105 	int rc = uECC_make_key(key.public_key_be, key.private_key_be, &curve_secp256r1);
106 
107 	if (rc == TC_CRYPTO_FAIL) {
108 		key.is_ready = false;
109 		LOG_ERR("Failed to create public/private pair");
110 		return -EIO;
111 	}
112 
113 	key.is_ready = true;
114 
115 	return 0;
116 }
117 
bt_mesh_pub_key_get(void)118 const uint8_t *bt_mesh_pub_key_get(void)
119 {
120 	return key.is_ready ? key.public_key_be : NULL;
121 }
122 
bt_mesh_dhkey_gen(const uint8_t * pub_key,const uint8_t * priv_key,uint8_t * dhkey)123 int bt_mesh_dhkey_gen(const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *dhkey)
124 {
125 	if (uECC_valid_public_key(pub_key, &curve_secp256r1)) {
126 		LOG_ERR("Public key is not valid");
127 		return -EIO;
128 	} else if (uECC_shared_secret(pub_key, priv_key ? priv_key : key.private_key_be, dhkey,
129 				      &curve_secp256r1) != TC_CRYPTO_SUCCESS) {
130 		LOG_ERR("DHKey generation failed");
131 		return -EIO;
132 	}
133 
134 	return 0;
135 }
136 
default_CSPRNG(uint8_t * dst,unsigned int len)137 __weak int default_CSPRNG(uint8_t *dst, unsigned int len)
138 {
139 	return !bt_rand(dst, len);
140 }
141 
bt_mesh_crypto_init(void)142 int bt_mesh_crypto_init(void)
143 {
144 	return 0;
145 }
146