177 lines
5.7 KiB
C++
177 lines
5.7 KiB
C++
/********************************************************************************
|
|
*
|
|
* Copyright 2015-2019 BES.
|
|
* All rights reserved. All unpublished rights reserved.
|
|
*
|
|
* No part of this work may be used or reproduced in any form or by any
|
|
* means, or stored in a database or retrieval system, without prior written
|
|
* permission of BES.
|
|
*
|
|
* Use of this work is governed by a license granted by BES.
|
|
* This work contains confidential and proprietary information of
|
|
* BES. which is protected by copyright, trade secret,
|
|
* trademark and other intellectual property rights.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#include "app_tota_conn.h"
|
|
#include "app_tota.h"
|
|
#include "app_tota_cmd_code.h"
|
|
#include "app_tota_cmd_handler.h"
|
|
#include "sha256.h"
|
|
#include "stdlib.h"
|
|
#include "string.h"
|
|
|
|
static bool _is_tota_initiate = false;
|
|
|
|
typedef struct {
|
|
uint8_t length;
|
|
uint8_t random_key[MAX_RANDOM_KEY_SIZE];
|
|
} TOTA_CONN_STRUCT_T;
|
|
|
|
typedef TOTA_CONN_STRUCT_T random_key_t;
|
|
|
|
typedef struct {
|
|
/* local & peer random list */
|
|
random_key_t random_a;
|
|
random_key_t random_b;
|
|
/* hash key generate from (random_a, random_b) */
|
|
uint8_t hash_key[HASH_KEY_SIZE];
|
|
/* encrypt key generate from hash key */
|
|
uint8_t encrypt_key[ENCRYPT_KEY_SIZE];
|
|
} TOTA_CONN_PARAMETER_T;
|
|
|
|
static TOTA_CONN_PARAMETER_T keyManager;
|
|
|
|
/*
|
|
** @
|
|
*/
|
|
static void _tota_conn_and_update_key_handle(APP_TOTA_CMD_CODE_E funcCode,
|
|
uint8_t *ptrParam,
|
|
uint32_t paramLen);
|
|
|
|
static uint8_t _generate_random_algorithm(uint8_t id, uint8_t a, uint8_t b);
|
|
|
|
/* generate key */
|
|
static void _generate_random_key();
|
|
|
|
/* calculate key */
|
|
static void _calculate_encrypt_key();
|
|
|
|
static uint8_t _generate_random_algorithm(uint8_t id, uint8_t a, uint8_t b) {
|
|
uint8_t op = id % 6;
|
|
switch (op) {
|
|
case 0:
|
|
return a + b;
|
|
case 1:
|
|
return a * b;
|
|
case 2:
|
|
return a & b;
|
|
case 3:
|
|
return a | b;
|
|
case 4:
|
|
return a ^ b;
|
|
case 5:
|
|
return a * a + b * b;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static void _generate_random_key() {
|
|
uint8_t random_length = rand() % (MAX_RANDOM_KEY_SIZE + 1);
|
|
if (random_length < 16) {
|
|
random_length += 16;
|
|
}
|
|
keyManager.random_a.length = random_length;
|
|
uint32_t *prandom = (uint32_t *)keyManager.random_a.random_key;
|
|
for (uint8_t i = 0; i < (random_length + 3) / 4; i++) {
|
|
prandom[i] = rand();
|
|
}
|
|
TOTA_LOG_DBG(1, "generate random : 0x%x", random_length);
|
|
TOTA_LOG_DUMP("%02x ", keyManager.random_a.random_key, random_length);
|
|
}
|
|
|
|
static void _calculate_encrypt_key() {
|
|
uint8_t random_key[MAX_RANDOM_KEY_SIZE];
|
|
random_key_t *prandom_a = &keyManager.random_a;
|
|
random_key_t *prandom_b = &keyManager.random_b;
|
|
|
|
/* align random list */
|
|
if (prandom_a->length > prandom_b->length) {
|
|
memset(prandom_b->random_key + prandom_b->length, 0,
|
|
prandom_a->length - prandom_b->length);
|
|
prandom_b->length = prandom_a->length;
|
|
} else if (prandom_a->length < prandom_b->length) {
|
|
memset(prandom_a->random_key + prandom_a->length, 0,
|
|
prandom_b->length - prandom_a->length);
|
|
prandom_a->length = prandom_b->length;
|
|
} else {
|
|
TOTA_LOG_DBG(0, "random list is the same size");
|
|
}
|
|
TOTA_LOG_DBG(1, "random list a : 0x%x", prandom_a->length);
|
|
TOTA_LOG_DUMP("%02x ", keyManager.random_a.random_key, prandom_a->length);
|
|
TOTA_LOG_DBG(1, "random list b : 0x%x", prandom_b->length);
|
|
TOTA_LOG_DUMP("%02x ", keyManager.random_b.random_key, prandom_b->length);
|
|
|
|
/* calculate random_key */
|
|
for (uint8_t i = 0; i < prandom_a->length; i++) {
|
|
random_key[i] = _generate_random_algorithm(i, prandom_a->random_key[i],
|
|
prandom_b->random_key[i]);
|
|
}
|
|
|
|
TOTA_LOG_DBG(0, "generate random key:");
|
|
TOTA_LOG_DUMP("%02x ", random_key, prandom_a->length);
|
|
#if defined(TOTA)
|
|
SHA256_hash(random_key, prandom_a->length, keyManager.hash_key);
|
|
#endif
|
|
TOTA_LOG_DBG(0, "generate hash key:");
|
|
TOTA_LOG_DUMP("\\x%02x", keyManager.hash_key, HASH_KEY_SIZE);
|
|
}
|
|
|
|
static void _tota_conn_and_update_key_handle(APP_TOTA_CMD_CODE_E funcCode,
|
|
uint8_t *ptrParam,
|
|
uint32_t paramLen) {
|
|
TOTA_CONN_STRUCT_T *pConn = (TOTA_CONN_STRUCT_T *)ptrParam;
|
|
|
|
switch (funcCode) {
|
|
case OP_TOTA_STRING:
|
|
TOTA_LOG_DBG(0, "not willing to receive this CMD");
|
|
break;
|
|
case OP_TOTA_CONN_RESPONSE:
|
|
TOTA_LOG_DBG(0, "not willing to receive this CMD");
|
|
break;
|
|
case OP_TOTA_CONN_INITIATE:
|
|
_is_tota_initiate = true;
|
|
keyManager.random_b = *pConn;
|
|
_generate_random_key();
|
|
app_tota_send_command(
|
|
OP_TOTA_CONN_RESPONSE, (uint8_t *)&keyManager.random_a,
|
|
keyManager.random_a.length + 1, app_tota_get_datapath());
|
|
_calculate_encrypt_key();
|
|
break;
|
|
case OP_TOTA_CONN_CONFIRM:
|
|
if (_is_tota_initiate) {
|
|
_is_tota_initiate = false;
|
|
if (memcmp(keyManager.hash_key, pConn->random_key, HASH_KEY_SIZE) == 0) {
|
|
tota_set_encrypt_key_from_hash_key(keyManager.hash_key);
|
|
tota_connected_handle();
|
|
TOTA_LOG_DBG(0, "tota connect success");
|
|
tota_printf("connect success.");
|
|
} else {
|
|
TOTA_LOG_DBG(0, "tota connect failed");
|
|
tota_printf("connect failed.");
|
|
}
|
|
}
|
|
default:;
|
|
}
|
|
}
|
|
|
|
TOTA_COMMAND_TO_ADD(OP_TOTA_CONN_INITIATE, _tota_conn_and_update_key_handle,
|
|
false, 0, NULL);
|
|
TOTA_COMMAND_TO_ADD(OP_TOTA_CONN_RESPONSE, _tota_conn_and_update_key_handle,
|
|
false, 0, NULL);
|
|
TOTA_COMMAND_TO_ADD(OP_TOTA_CONN_CONFIRM, _tota_conn_and_update_key_handle,
|
|
false, 0, NULL);
|
|
TOTA_COMMAND_TO_ADD(OP_TOTA_STRING, _tota_conn_and_update_key_handle, false, 0,
|
|
NULL); |