pinebuds/services/tota/app_tota_conn.cpp

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);