1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
30
31
35
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
63
64
65
66
67
68
73
74
75
76
77
82
83
84
98
99
104
105
110
111
112
113
114
119
120
121
122
123
124
129
130
131
136
137
138
139
140
141
142
147
148
149
150
155
156
157
158
159
160
161
162
163
164
165
167
169
171
172
173
174
175
176
177
178
179
180
183
184
185
186
187
188
191
192
193
194
195
196
197
198
199
200
201
204
205
206
207
208
209
212
213
214
215
216
221
222
223
224
225
228
229
230
231
232
233
234
235
236
237
238
239
240
243
247
248
249
250
251
252
253
254
/* ... */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_random.h"12 includes
#if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED
#include "esp_bt.h"
#endif
#include "esp_blufi_api.h"
#include "blufi_example.h"
#include "mbedtls/aes.h"
#include "mbedtls/dhm.h"
#include "mbedtls/md5.h"
#include "esp_crc.h"6 includes
/* ... */
#define SEC_TYPE_DH_PARAM_LEN 0x00
#define SEC_TYPE_DH_PARAM_DATA 0x01
#define SEC_TYPE_DH_P 0x02
#define SEC_TYPE_DH_G 0x03
#define SEC_TYPE_DH_PUBLIC 0x045 defines
struct blufi_security {
#define DH_SELF_PUB_KEY_LEN 128
uint8_t self_public_key[DH_SELF_PUB_KEY_LEN];
#define SHARE_KEY_LEN 128
uint8_t share_key[SHARE_KEY_LEN];
size_t share_len;
#define PSK_LEN 16
uint8_t psk[PSK_LEN];
uint8_t *dh_param;
int dh_param_len;
uint8_t iv[16];
mbedtls_dhm_context dhm;
mbedtls_aes_context aes;
}{ ... };
static struct blufi_security *blufi_sec;
static int myrand( void *rng_state, unsigned char *output, size_t len )
{
esp_fill_random(output, len);
return( 0 );
}{ ... }
extern void btc_blufi_report_error(esp_blufi_error_state_t state);
void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
{
if (data == NULL || len < 3) {
BLUFI_ERROR("BLUFI Invalid data format");
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
return;
}{...}
int ret;
uint8_t type = data[0];
if (blufi_sec == NULL) {
BLUFI_ERROR("BLUFI Security is not initialized");
btc_blufi_report_error(ESP_BLUFI_INIT_SECURITY_ERROR);
return;
}{...}
switch (type) {
case SEC_TYPE_DH_PARAM_LEN:
blufi_sec->dh_param_len = ((data[1]<<8)|data[2]);
if (blufi_sec->dh_param) {
free(blufi_sec->dh_param);
blufi_sec->dh_param = NULL;
}{...}
blufi_sec->dh_param = (uint8_t *)malloc(blufi_sec->dh_param_len);
if (blufi_sec->dh_param == NULL) {
blufi_sec->dh_param_len = 0;
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR);
BLUFI_ERROR("%s, malloc failed\n", __func__);
return;
}{...}
break;...
case SEC_TYPE_DH_PARAM_DATA:{
if (blufi_sec->dh_param == NULL) {
BLUFI_ERROR("%s, blufi_sec->dh_param == NULL\n", __func__);
btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR);
return;
}{...}
if (len < (blufi_sec->dh_param_len + 1)) {
BLUFI_ERROR("%s, invalid dh param len\n", __func__);
btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR);
return;
}{...}
uint8_t *param = blufi_sec->dh_param;
memcpy(blufi_sec->dh_param, &data[1], blufi_sec->dh_param_len);
ret = mbedtls_dhm_read_params(&blufi_sec->dhm, ¶m, ¶m[blufi_sec->dh_param_len]);
if (ret) {
BLUFI_ERROR("%s read param failed %d\n", __func__, ret);
btc_blufi_report_error(ESP_BLUFI_READ_PARAM_ERROR);
return;
}{...}
free(blufi_sec->dh_param);
blufi_sec->dh_param = NULL;
const int dhm_len = mbedtls_dhm_get_len(&blufi_sec->dhm);
if (dhm_len > DH_SELF_PUB_KEY_LEN) {
BLUFI_ERROR("%s dhm len not support %d\n", __func__, dhm_len);
btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR);
return;
}{...}
ret = mbedtls_dhm_make_public(&blufi_sec->dhm, dhm_len, blufi_sec->self_public_key, DH_SELF_PUB_KEY_LEN, myrand, NULL);
if (ret) {
BLUFI_ERROR("%s make public failed %d\n", __func__, ret);
btc_blufi_report_error(ESP_BLUFI_MAKE_PUBLIC_ERROR);
return;
}{...}
ret = mbedtls_dhm_calc_secret( &blufi_sec->dhm,
blufi_sec->share_key,
SHARE_KEY_LEN,
&blufi_sec->share_len,
myrand, NULL);
if (ret) {
BLUFI_ERROR("%s mbedtls_dhm_calc_secret failed %d\n", __func__, ret);
btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR);
return;
}{...}
ret = mbedtls_md5(blufi_sec->share_key, blufi_sec->share_len, blufi_sec->psk);
if (ret) {
BLUFI_ERROR("%s mbedtls_md5 failed %d\n", __func__, ret);
btc_blufi_report_error(ESP_BLUFI_CALC_MD5_ERROR);
return;
}{...}
mbedtls_aes_setkey_enc(&blufi_sec->aes, blufi_sec->psk, PSK_LEN * 8);
*output_data = &blufi_sec->self_public_key[0];
*output_len = dhm_len;
*need_free = false;
}{...}
break;...
case SEC_TYPE_DH_P:
break;...
case SEC_TYPE_DH_G:
break;...
case SEC_TYPE_DH_PUBLIC:
break;...
}{...}
}{ ... }
int blufi_aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
{
int ret;
size_t iv_offset = 0;
uint8_t iv0[16];
if (!blufi_sec) {
return -1;
}{...}
memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv));
iv0[0] = iv8;
ret = mbedtls_aes_crypt_cfb128(&blufi_sec->aes, MBEDTLS_AES_ENCRYPT, crypt_len, &iv_offset, iv0, crypt_data, crypt_data);
if (ret) {
return -1;
}{...}
return crypt_len;
}{ ... }
int blufi_aes_decrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
{
int ret;
size_t iv_offset = 0;
uint8_t iv0[16];
if (!blufi_sec) {
return -1;
}{...}
memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv));
iv0[0] = iv8;
ret = mbedtls_aes_crypt_cfb128(&blufi_sec->aes, MBEDTLS_AES_DECRYPT, crypt_len, &iv_offset, iv0, crypt_data, crypt_data);
if (ret) {
return -1;
}{...}
return crypt_len;
}{ ... }
uint16_t blufi_crc_checksum(uint8_t iv8, uint8_t *data, int len)
{
return esp_crc16_be(0, data, len);
}{ ... }
esp_err_t blufi_security_init(void)
{
blufi_sec = (struct blufi_security *)malloc(sizeof(struct blufi_security));
if (blufi_sec == NULL) {
return ESP_FAIL;
}{...}
memset(blufi_sec, 0x0, sizeof(struct blufi_security));
mbedtls_dhm_init(&blufi_sec->dhm);
mbedtls_aes_init(&blufi_sec->aes);
memset(blufi_sec->iv, 0x0, sizeof(blufi_sec->iv));
return 0;
}{ ... }
void blufi_security_deinit(void)
{
if (blufi_sec == NULL) {
return;
}{...}
if (blufi_sec->dh_param){
free(blufi_sec->dh_param);
blufi_sec->dh_param = NULL;
}{...}
mbedtls_dhm_free(&blufi_sec->dhm);
mbedtls_aes_free(&blufi_sec->aes);
memset(blufi_sec, 0x0, sizeof(struct blufi_security));
free(blufi_sec);
blufi_sec = NULL;
}{ ... }