diff --git a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c index 5cb5d7f10f71..26ebed27562c 100644 --- a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c @@ -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_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_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_sharedkey(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_gcm.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_c25519.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 }, #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 { "/EC_C25519", (intptr_t) &be_class_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) } +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) { public_key, static_func(m_ec_p256_pubkey) shared_key, static_func(m_ec_p256_sharedkey) @@ -211,4 +224,4 @@ module crypto (scope: global) { random, func(m_crypto_random) } -@const_object_info_end */ +@const_object_info_end */ \ No newline at end of file diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino index 6ac2b6ae40f9..63d7b750fe00 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino @@ -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 * @@ -1212,4 +1295,4 @@ extern "C" { be_raise(vm, kTypeError, nullptr); } } -#endif // USE_BERRY +#endif // USE_BERRY \ No newline at end of file