int tpsocket_aes_cbc_encrypt(const unsigned char *in, unsigned char *out,
unsigned int len, const struct tpsocket_aes_key *key, unsigned char *iv, int forward)
{
unsigned char tmp[16];
int i;
if (forward) { while (len >= sizeof(tmp)) { for (i = 0; i < sizeof(tmp); i++) tmp[i] = in[i] ^ iv[i]; tpsocket_aes_encrypt(tmp, out, key); memcpy(iv, out, sizeof(tmp)); len -= sizeof(tmp); in += sizeof(tmp); out += sizeof(tmp); } if (len) { for (i = 0; i < len; i++)tmp[i] = in[i] ^ iv[i]; for (i = len; i < sizeof(tmp); i++) tmp[i] = iv[i]; tpsocket_aes_encrypt(tmp, out, key); memcpy(iv, out, sizeof(tmp)); } } else { while (len >= sizeof(tmp)) { memcpy(tmp, in, sizeof(tmp)); tpsocket_aes_decrypt(tmp, out, key); for (i = 0; i < sizeof(tmp); i++) out[i] ^= iv[i]; memcpy(iv, tmp, sizeof(tmp)); len -= sizeof(tmp); in += sizeof(tmp); out += sizeof(tmp); } if (len) { memcpy(tmp, in, sizeof(tmp)); tpsocket_aes_decrypt(tmp, out, key); for (i = 0; i < len; i++) out[i] ^= iv[i]; memcpy(iv, tmp, sizeof(tmp)); } } return 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;
}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);
#ifdef HTTP_HMAC_HKDF_SUPPORT
#define HKDF_SHA256_INFO_AES_KEY “stream_hkdf_aes_key”
#define HKDF_SHA256_INFO_HMAC_KEY “stream_hkdf_hmac_key”
int iRet = 0; for (int i = 0; i < 32; i++) { iRet = rand() % 16; tapo_salt[i] = iRet < 10 ? ('0' + iRet) : ('a' + iRet - 10); } char hkdf_ikm_key[512] = {0}; memset(hkdf_ikm_key, 0, 512); snprintf(hkdf_ikm_key, sizeof(hkdf_ikm_key), "%s:%s", tapo_nonce, tapo_passwd); tpsocket_sha256_hkdf((unsigned char *)tapo_salt, strlen(tapo_salt), (unsigned char *)hkdf_ikm_key, strlen(hkdf_ikm_key), (unsigned char *)HKDF_SHA256_INFO_AES_KEY, strlen(HKDF_SHA256_INFO_AES_KEY), tapo_key_hkdf, sizeof(tapo_key_hkdf)); tpsocket_sha256_hkdf((unsigned char *)tapo_salt, strlen(tapo_salt), (unsigned char *)hkdf_ikm_key, strlen(hkdf_ikm_key), (unsigned char *)HKDF_SHA256_INFO_HMAC_KEY, strlen(HKDF_SHA256_INFO_HMAC_KEY), tapo_key_hkdf_hmac, sizeof(tapo_key_hkdf_hmac)); tpsocket_aes_set_encrypt_key((unsigned char *)tapo_key_hkdf, 128, &tapo_aes_key_hkdf); tpsocket_aes_set_decrypt_key((unsigned char *)tapo_key_hkdf, 128, &tapo_aes_dec_key_hkdf);
#endif
}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);
}这段代码中,如果为加密的情况,把nbuf先进行HEX解码,再进行后续操作。