mirror of https://github.com/arendst/Tasmota.git
add AES_CBC to crypto module (#19964)
This commit is contained in:
parent
9b5945a117
commit
cf6de0ce31
|
@ -1,9 +1,9 @@
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Berry module `webserver`
|
* Berry module `crypto`
|
||||||
*
|
*
|
||||||
* To use: `import webserver`
|
* To use: `import crypto`
|
||||||
*
|
*
|
||||||
* Allows to respond to HTTP request
|
* Allows to use crypto functions
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
#include "be_constobj.h"
|
#include "be_constobj.h"
|
||||||
#include "be_mapping.h"
|
#include "be_mapping.h"
|
||||||
|
@ -29,6 +29,9 @@ extern int m_aes_ctr_init(bvm *vm);
|
||||||
extern int m_aes_ctr_run(bvm *vm);
|
extern int m_aes_ctr_run(bvm *vm);
|
||||||
extern int m_aes_ctr_tag(bvm *vm);
|
extern int m_aes_ctr_tag(bvm *vm);
|
||||||
|
|
||||||
|
extern int m_aes_cbc_encrypt1(bvm *vm);
|
||||||
|
extern int m_aes_cbc_decrypt1(bvm *vm);
|
||||||
|
|
||||||
extern int m_ec_p256_pubkey(bvm *vm);
|
extern int m_ec_p256_pubkey(bvm *vm);
|
||||||
extern int m_ec_p256_sharedkey(bvm *vm);
|
extern int m_ec_p256_sharedkey(bvm *vm);
|
||||||
extern int m_ec_p256_ecdsa_sign_sha256(bvm *vm);
|
extern int m_ec_p256_ecdsa_sign_sha256(bvm *vm);
|
||||||
|
@ -64,6 +67,7 @@ extern const bclass be_class_md5;
|
||||||
#include "be_fixed_be_class_aes_ccm.h"
|
#include "be_fixed_be_class_aes_ccm.h"
|
||||||
#include "be_fixed_be_class_aes_gcm.h"
|
#include "be_fixed_be_class_aes_gcm.h"
|
||||||
#include "be_fixed_be_class_aes_ctr.h"
|
#include "be_fixed_be_class_aes_ctr.h"
|
||||||
|
#include "be_fixed_be_class_aes_cbc.h"
|
||||||
#include "be_fixed_be_class_ec_p256.h"
|
#include "be_fixed_be_class_ec_p256.h"
|
||||||
#include "be_fixed_be_class_ec_c25519.h"
|
#include "be_fixed_be_class_ec_c25519.h"
|
||||||
#include "be_fixed_be_class_sha256.h"
|
#include "be_fixed_be_class_sha256.h"
|
||||||
|
@ -87,6 +91,10 @@ const be_const_member_t be_crypto_members[] = {
|
||||||
{ "/AES_GCM", (intptr_t) &be_class_aes_gcm },
|
{ "/AES_GCM", (intptr_t) &be_class_aes_gcm },
|
||||||
#endif // USE_BERRY_CRYPTO_AES_GCM
|
#endif // USE_BERRY_CRYPTO_AES_GCM
|
||||||
|
|
||||||
|
#ifdef USE_BERRY_CRYPTO_AES_CBC
|
||||||
|
{ "/AES_CBC", (intptr_t) &be_class_aes_cbc },
|
||||||
|
#endif // USE_BERRY_CRYPTO_AES_CBC
|
||||||
|
|
||||||
#ifdef USE_BERRY_CRYPTO_EC_C25519
|
#ifdef USE_BERRY_CRYPTO_EC_C25519
|
||||||
{ "/EC_C25519", (intptr_t) &be_class_ec_c25519 },
|
{ "/EC_C25519", (intptr_t) &be_class_ec_c25519 },
|
||||||
#endif // USE_BERRY_CRYPTO_EC_C25519
|
#endif // USE_BERRY_CRYPTO_EC_C25519
|
||||||
|
@ -162,6 +170,11 @@ class be_class_aes_ctr (scope: global, name: AES_CTR) {
|
||||||
decrypt, func(m_aes_ctr_run)
|
decrypt, func(m_aes_ctr_run)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class be_class_aes_cbc (scope: global, name: AES_CBC) {
|
||||||
|
decrypt1, static_func(m_aes_cbc_decrypt1)
|
||||||
|
encrypt1, static_func(m_aes_cbc_encrypt1)
|
||||||
|
}
|
||||||
|
|
||||||
class be_class_ec_p256 (scope: global, name: EC_P256) {
|
class be_class_ec_p256 (scope: global, name: EC_P256) {
|
||||||
public_key, static_func(m_ec_p256_pubkey)
|
public_key, static_func(m_ec_p256_pubkey)
|
||||||
shared_key, static_func(m_ec_p256_sharedkey)
|
shared_key, static_func(m_ec_p256_sharedkey)
|
||||||
|
@ -211,4 +224,4 @@ module crypto (scope: global) {
|
||||||
random, func(m_crypto_random)
|
random, func(m_crypto_random)
|
||||||
}
|
}
|
||||||
|
|
||||||
@const_object_info_end */
|
@const_object_info_end */
|
|
@ -533,6 +533,89 @@ extern "C" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* AES_CBC class
|
||||||
|
*
|
||||||
|
\*********************************************************************************************/
|
||||||
|
extern "C" {
|
||||||
|
// `AES_CBC.encrypt1(secret_key:bytes(16),iv:bytes(16),data:bytes(n*16))-> bool (true)
|
||||||
|
int32_t m_aes_cbc_encrypt1(bvm *vm);
|
||||||
|
int32_t m_aes_cbc_encrypt1(bvm *vm) {
|
||||||
|
int32_t argc = be_top(vm); // Get the number of arguments
|
||||||
|
if (argc >= 3 && be_isbytes(vm, 1) // secret_key - 16 bytes
|
||||||
|
&& be_isbytes(vm, 2) // iv - 16 bytes
|
||||||
|
&& be_isbytes(vm, 3) // data/cipher - multiple 16 bytes
|
||||||
|
) {
|
||||||
|
|
||||||
|
size_t key_len = 0;
|
||||||
|
const void * key = be_tobytes(vm, 1, &key_len);
|
||||||
|
if (key_len != 16) {
|
||||||
|
be_raise(vm, "value_error", "Key size must be 16 bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t iv_len = 0;
|
||||||
|
void * iv = (void *) be_tobytes(vm, 2, &iv_len);
|
||||||
|
if (iv_len != 16) {
|
||||||
|
be_raise(vm, "value_error", "IV size must be 16");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t data_len = 0;
|
||||||
|
void * data = (void *) be_tobytes(vm, 3, &data_len);
|
||||||
|
if (data_len%16 != 0) {
|
||||||
|
be_raise(vm, "value_error", "Data size must be multiple of 16");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize an AES CBC encryption structure with the secret key, then run with IV and data
|
||||||
|
br_aes_small_cbcenc_keys cbc_ctx;
|
||||||
|
br_aes_small_cbcenc_init(&cbc_ctx, key, 16);
|
||||||
|
br_aes_small_cbcenc_run( &cbc_ctx, iv, data, data_len );
|
||||||
|
|
||||||
|
// (unchecked )success
|
||||||
|
be_pushbool(vm, btrue);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
be_raise(vm, kTypeError, nullptr);
|
||||||
|
}
|
||||||
|
// `AES_CBC.decrypt1(secret_key:bytes(16),iv:bytes(16),cipher:bytes(n*16))-> bool (true)
|
||||||
|
int32_t m_aes_cbc_decrypt1(bvm *vm);
|
||||||
|
int32_t m_aes_cbc_decrypt1(bvm *vm) {
|
||||||
|
int32_t argc = be_top(vm); // Get the number of arguments
|
||||||
|
if (argc >= 3 && be_isbytes(vm, 1) // secret_key - 16 bytes
|
||||||
|
&& be_isbytes(vm, 2) // iv - 16 bytes
|
||||||
|
&& be_isbytes(vm, 3) // cipher/data - multiple 16 bytes
|
||||||
|
) {
|
||||||
|
|
||||||
|
size_t key_len = 0;
|
||||||
|
const void * key = be_tobytes(vm, 1, &key_len);
|
||||||
|
if (key_len != 16) {
|
||||||
|
be_raise(vm, "value_error", "Key size must be 16 bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t iv_len = 0;
|
||||||
|
void * iv = (void *) be_tobytes(vm, 2, &iv_len);
|
||||||
|
if (iv_len != 16) {
|
||||||
|
be_raise(vm, "value_error", "IV size must be 16");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t data_len = 0;
|
||||||
|
void * data = (void *) be_tobytes(vm, 3, &data_len);
|
||||||
|
if (data_len%16 != 0) {
|
||||||
|
be_raise(vm, "value_error", "Cipher size must be multiple of 16");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize an AES CBC decryption structure with the secret key, then run with IV and data
|
||||||
|
br_aes_small_cbcdec_keys cbc_ctx;
|
||||||
|
br_aes_small_cbcdec_init(&cbc_ctx, key, 16);
|
||||||
|
br_aes_small_cbcdec_run( &cbc_ctx, iv, data, data_len );
|
||||||
|
|
||||||
|
// (unchecked )success
|
||||||
|
be_pushbool(vm, btrue);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
be_raise(vm, kTypeError, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* SHA256 class
|
* SHA256 class
|
||||||
*
|
*
|
||||||
|
@ -1212,4 +1295,4 @@ extern "C" {
|
||||||
be_raise(vm, kTypeError, nullptr);
|
be_raise(vm, kTypeError, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_BERRY
|
#endif // USE_BERRY
|
Loading…
Reference in New Issue