补充上个问题的信息:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libubox/md5.h>
#include "common.h"
#include "ubus.h"
#include "worker.h"
#include "relay.h"
#include "minor_stream.h"
#include "double_talk.h"
#include "chime_ctrl.h"
#include "alarm.h"
#include "preview.h"
#include "cookie.h"
#include "device.h"
#include "iot_info.h"
#include "snapshot.h"
#include "tapocare.h"
#include "ring.h"
#include "storage.h"
#ifdef HARDDISK_STORAGE
#include "face_control.h"
#endif
#ifdef HUB_WEBRTC
#include "webrtc.h"
#endif
#ifdef AI_ENHANCE
#include "image_transmit.h"
#endif
#ifdef SDCARD_VIDEO_DOWNLOAD_SUPPORT
#include "storage_local_download.h"
#endif
#ifdef PROTOCOL_SECURE
#define HTTP_DIGEST_PWD_MD5 "1"
#define HTTP_DIGEST_PWD_RSA "2"
#define HTTP_DIGEST_PWD_SHA "3"
#endif
char tapo_user[128] = {0};
char tapo_passwd[128] = {0};
char tapo_nonce[128] = {0};
const int RELAY_CONSUMER_MAX_NUM[] = {0, 34, 26, 18, 20};
int relay_consumer_cur_max_num = 0;
int relay_consumer_cur_left_num = 0;
static unsigned char tapo_key[16] = {0};
static unsigned char tapo_iv[16] = {0};
static struct tpsocket_aes_key tapo_aes_key = {{0}};
static struct tpsocket_aes_key tapo_aes_dec_key = {{0}};
#ifdef HTTP_HMAC_HKDF_SUPPORT
unsigned char tapo_key_hkdf[16] = {0};
unsigned char tapo_key_hkdf_hmac[16] = {0};
char tapo_salt[32 + 1] = {0};
struct tpsocket_aes_key tapo_aes_key_hkdf = {{0}};
struct tpsocket_aes_key tapo_aes_dec_key_hkdf = {{0}};
char *tapo_vod_get_salt()
{
return tapo_salt;
}
void generate_iv_nonce(unsigned char *nonce, int len)
{
int i = 0;
for (i = 0; i < len; ++i)
{
nonce[i] = (unsigned char)(rand() % 256);
}
}
int tapo_vod_hkdf_hamc_verify_decrypt(unsigned char *in, int inputlen, unsigned char *out, int *outputlen, unsigned char *iv_nonce, char *XHmac)
{
unsigned char hmac[32] = {0};
char base64_hmac[32*2] = {0};
int ret = 0;
tpsocket_sha256_hmac(tapo_key_hkdf_hmac, 16, in, inputlen, hmac);
tpsocket_base64_encode(hmac, sizeof(hmac), (unsigned char *)base64_hmac);
if (!strncmp(base64_hmac, XHmac, strlen(base64_hmac))) {
ret = tpsocket_aes_cbc_encrypt(in, out, inputlen, &tapo_aes_dec_key_hkdf, iv_nonce, 0);
if (ret != 0) {
DBG_ERR("tpsocket_aes_cbc_encrypt failed\n");
*outputlen = 0;
goto exit;
}
*outputlen = inputlen;
} else {
DBG_ERR("Hmac verification failed\n");
*outputlen = 0;
goto exit;
}
exit:
return ret;
}
int tapo_vod_hkdf_hamc_encrypt(unsigned char *in, unsigned char *out, unsigned int len, unsigned char *iv_str, unsigned char *base64_hmac)
{
unsigned char iv_nonce[16] = {0};
unsigned char hmac[32] = {0};
int ret = 0;
generate_iv_nonce(iv_nonce, 16);
tpsocket_hex_encode(iv_nonce, 16, iv_str, 0);
ret = tpsocket_aes_cbc_encrypt(in, out, len, &tapo_aes_key_hkdf, iv_nonce, 1);
if (ret != 0) {
DBG_ERR("Error happens on encrypting.\n");
ret = 0 ;
goto exit;
}
tpsocket_sha256_hmac(tapo_key_hkdf_hmac, 16, out, len, hmac);
tpsocket_base64_encode(hmac, sizeof(hmac), base64_hmac);
exit:
return len;
}
bool tapo_vod_get_hkdf_hamc(struct list_head *buf, char *XHmac, unsigned char *iv_nonce)
{
char *XHmac_tmp = NULL;
char *XNonce = NULL;
if ((XHmac_tmp = common_find_key_from_buf(buf, "X-Data-Hmac")) != NULL) {
memset(XHmac, 0, HKDF_HMAC_LEN);
memcpy(XHmac, XHmac_tmp, HKDF_HMAC_LEN);
//DBG_ERR("X-Data-Hmac:%s\n", XHmac);
free(XHmac_tmp);
if ((XNonce = common_find_key_from_buf(buf, "X-Nonce")) != NULL) {
tpsocket_hex_decode((const unsigned char *)XNonce, HKDF_IV_LEN * 2, iv_nonce);
//DBG_ERR("X-Nonce:%s\n", XNonce);
free(XNonce);
return true;
}
}
return false;
}
#endif
static void _ubus_get_result(
struct ubus_app *app, struct blob_attr *msg, int ret, void *priv)
{
if (msg && priv) {
struct blob_buf *bBuf = (struct blob_buf *)priv;
struct blob_attr *cur = NULL;
int rem;
blob_for_each_attr(cur, msg, rem) {
blobmsg_add_blob(bBuf, cur);
}
}
}
#ifdef TAPO_CAMERA
static MEDIA_ENCRYPT_STATUS gEncryptStatus = MEDIA_ENCRYPT_INVALID; //Note: indicate validation of encrypt key
void set_media_encrypt_status(MEDIA_ENCRYPT_STATUS ENCRYPT_STATUS)
{
if (gEncryptStatus != ENCRYPT_STATUS) {
gEncryptStatus = ENCRYPT_STATUS;
}
}
MEDIA_ENCRYPT_STATUS get_media_encrypt_status()
{
return gEncryptStatus;
}
int get_media_encrypt_key(char *aes_key, char *aes_iv, int size)
{
if (!aes_key || !aes_iv || size < (2*MD5_HEX_LEN+1)) {
return -1;
}
if (get_media_encrypt_status() != MEDIA_ENCRYPT_VALID) {
return -1;
}
tpsocket_hex_encode(tapo_key, MD5_HEX_LEN, (unsigned char *)aes_key, 0);
tpsocket_hex_encode(tapo_iv, MD5_HEX_LEN, (unsigned char *)aes_iv, 0);
return 0;
}
#endif
static void send_clip_start_event(ALARM_PRODUCER *producer)
{
struct blob_buf b = {0};
blobmsg_buf_init(&b);
if (producer)
{
DEV_INFO *dev_info = get_dev_info((MEDIACENTER_CTX *)get_top_ctx(), producer->dev_id, producer->dev_ip);
if (dev_info) {
blobmsg_add_string(&b, "deviceId", dev_info->dev_id);
ubus_app_event((struct ubus_app *)ubus_get_ubus_app(), "clip_start_timing", b.head);
}
}
blob_buf_free(&b);
}
static inline void work_tapo_refresh_encrypt_key(void)
{
md5_ctx_t md5_ctx;
char tmp[64] = {0};
//DBG_DBG("tapo_nonce: %s\n", tapo_nonce);
//DBG_DBG("tapo_passwd: %s\n", tapo_passwd);
md5_begin(&md5_ctx);
md5_hash(tapo_nonce, strlen(tapo_nonce), &md5_ctx);
md5_hash(":", strlen(":"), &md5_ctx);
md5_hash(tapo_passwd, strlen(tapo_passwd), &md5_ctx);
md5_end(tapo_key, &md5_ctx);
md5_begin(&md5_ctx);
md5_hash(tapo_user, strlen(tapo_user), &md5_ctx);
md5_hash(":", strlen(":"), &md5_ctx);
md5_hash(tapo_nonce, strlen(tapo_nonce), &md5_ctx);
md5_end(tapo_iv, &md5_ctx);
tpsocket_hex_encode(tapo_key, sizeof(tapo_key), (unsigned char *)tmp, 0);
//DBG_DBG("tapo_key: %s\n", tmp);
tpsocket_hex_encode(tapo_iv, sizeof(tapo_iv), (unsigned char *)tmp, 0);
//DBG_DBG("tapo_iv: %s\n", tmp);
tpsocket_aes_set_encrypt_key((unsigned char *)tapo_key, 128, &tapo_aes_key);
tpsocket_aes_set_decrypt_key((unsigned char *)tapo_key, 128, &tapo_aes_dec_key);
}
void work_tapo_aec_encrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
unsigned char tmpiv[16];
memcpy(tmpiv, tapo_iv, sizeof(tapo_iv));
if (tpsocket_aes_cbc_encrypt(inputbuf, outbuf, inputlen, &tapo_aes_key, tmpiv, 1) == 0)
*outputlen = inputlen;
else
*outputlen = 0;
}
static inline void work_tapo_aec_decrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
unsigned char tmpiv[16];
memcpy(tmpiv, tapo_iv, sizeof(tapo_iv));
if (tpsocket_aes_cbc_encrypt(inputbuf, outbuf, inputlen, &tapo_aes_dec_key, tmpiv, 0) == 0)
*outputlen = inputlen;
else
*outputlen = 0;
}
#ifdef TAPO_CAMERA
void work_tapo_refresh_nonce()
{
tpsocket_hex_random((unsigned char *)tapo_nonce, 32, 0);
work_tapo_refresh_encrypt_key();
set_media_encrypt_status(MEDIA_ENCRYPT_VALID);
}
#endif
char *tapo_vod_get_user()
{
return tapo_user;
}
char *tapo_vod_get_nonce()
{
return tapo_nonce;
}
void tapo_vod_aec_encrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
if(!inputbuf || inputlen <= 0 || !outbuf || !outputlen) {
DBG_ERR("tapo_vod_aec_encrypt param error\n");
return;
}
return work_tapo_aec_encrypt(inputbuf, inputlen, outbuf, outputlen);
}
void tapo_vod_aec_decrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
if(!inputbuf || inputlen <= 0 || !outbuf || !outputlen) {
DBG_ERR("tapo_vod_aec_decrypt param error\n");
return;
}
return work_tapo_aec_decrypt(inputbuf, inputlen, outbuf, outputlen);
}
void tapo_talk_aec_decrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
if(!inputbuf || inputlen <= 0 || !outbuf || !outputlen) {
DBG_ERR("tapo_talk_aec_decrypt param error\n");
return;
}
return work_tapo_aec_decrypt(inputbuf, inputlen, outbuf, outputlen);
}
void tapo_img_trans_aec_encrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
if(!inputbuf || inputlen <= 0 || !outbuf || !outputlen) {
DBG_ERR("tapo_img_trans_aec_encrypt param error, inputlen: %d, inbuf: %p, outbuf: %p, outlen: %p\n", inputlen, inputbuf, outbuf, outputlen);
return;
}
return work_tapo_aec_encrypt(inputbuf, inputlen, outbuf, outputlen);
}
void tapo_img_trans_aec_decrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
if(!inputbuf || inputlen <= 0 || !outbuf || !outputlen) {
DBG_ERR("tapo_img_trans_aec_decrypt param error\n");
return;
}
return work_tapo_aec_decrypt(inputbuf, inputlen, outbuf, outputlen);
}
void tapo_log_aec_decrypt(unsigned char *inputbuf, int inputlen, unsigned char *outbuf, int *outputlen)
{
if(!inputbuf || inputlen <= 0 || !outbuf || !outputlen) {
DBG_ERR("tapo_log_aec_decrypt param error\n");
return;
}
return work_tapo_aec_decrypt(inputbuf, inputlen, outbuf, outputlen);
}
最新发布