From 30ace5a3f39fa2a463b29eab329fd8de55a92bbb Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sat, 17 Dec 2022 23:38:57 +0100 Subject: [PATCH] Berry support for `crypto.SHA256` (#17430) --- CHANGELOG.md | 1 + .../berry_tasmota/src/be_crypto_lib.c | 14 ++++ tasmota/my_user_config.h | 1 + .../xdrv_52_3_berry_crypto.ino | 77 +++++++++++++++++++ 4 files changed, 93 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4981bc39..b7736a4eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ## [12.3.1.1] 20221216 ### Added - Support for IPv6 DNS records (AAAA) and IPv6 ``Ping`` for ESP32 and ESP8266 +- Berry support for ``crypto.SHA256`` ### Breaking Changed diff --git a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c index 5e6818a00..3889e750c 100644 --- a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c @@ -15,8 +15,13 @@ extern int m_aes_gcm_tag(bvm *vm); extern int m_ec_c25519_pubkey(bvm *vm); extern int m_ec_c25519_sharedkey(bvm *vm); +extern int m_hash_sha256_init(bvm *vm); +extern int m_hash_sha256_update(bvm *vm); +extern int m_hash_sha256_out(bvm *vm); + #include "be_fixed_be_class_aes_gcm.h" #include "be_fixed_be_class_ec_c25519.h" +#include "be_fixed_be_class_sha256.h" #include "be_fixed_crypto.h" /* @const_object_info_begin @@ -36,9 +41,18 @@ class be_class_ec_c25519 (scope: global, name: EC_C25519) { shared_key, func(m_ec_c25519_sharedkey) } +class be_class_sha256 (scope: global, name: SHA256) { + .p, var + + init, func(m_hash_sha256_init) + update, func(m_hash_sha256_update) + out, func(m_hash_sha256_out) +} + module crypto (scope: global) { AES_GCM, class(be_class_aes_gcm) EC_C25519, class(be_class_ec_c25519) + SHA256, class(be_class_sha256) } @const_object_info_end */ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 6ca0fa850..f00cc476a 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -1107,6 +1107,7 @@ // Berry crypto extensions below: #define USE_BERRY_CRYPTO_AES_GCM // enable AES GCM 256 bits // #define USE_BERRY_CRYPTO_EC_C25519 // enable Elliptic Curve C C25519 + #define USE_BERRY_CRYPTO_SHA256 // enable SHA256 hash function #define USE_CSE7761 // Add support for CSE7761 Energy monitor as used in Sonoff Dual R3 // -- LVGL Graphics Library --------------------------------- 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 2c89fb30a..83094ff5d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino @@ -158,6 +158,83 @@ extern "C" { #endif // USE_BERRY_CRYPTO_AES_GCM } } +/*********************************************************************************************\ + * SHA256 class + * +\*********************************************************************************************/ +extern "C" { + + // `SHA256.init() -> nil` + int32_t m_hash_sha256_init(struct bvm *vm); + int32_t m_hash_sha256_init(struct bvm *vm) { +#ifdef USE_BERRY_CRYPTO_SHA256 + // Initialize a SHA256 context + br_sha256_context * ctx = (br_sha256_context *) be_os_malloc(sizeof(br_sha256_context)); + if (!ctx) { + be_throw(vm, BE_MALLOC_FAIL); + } + br_sha256_init(ctx); + + be_newcomobj(vm, ctx, &be_commonobj_destroy_generic); + be_setmember(vm, 1, ".p"); + be_return_nil(vm); +#else // USE_BERRY_CRYPTO_SHA256 + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_SHA256 + } + + // `.update(content:bytes()) -> nil` + // + // Add raw bytes to the hash calculation + int32_t m_hash_sha256_update(struct bvm *vm); + int32_t m_hash_sha256_update(struct bvm *vm) { +#ifdef USE_BERRY_CRYPTO_SHA256 + int32_t argc = be_top(vm); // Get the number of arguments + if (argc >= 2 && be_isinstance(vm, 2)) { + do { + be_getglobal(vm, "bytes"); /* get the bytes class */ /* TODO eventually replace with be_getbuiltin */ + if (!be_isderived(vm, 2)) break; + size_t length = 0; + const void * bytes = be_tobytes(vm, 2, &length); + if (!bytes) break; + + be_getmember(vm, 1, ".p"); + br_sha256_context * ctx; + ctx = (br_sha256_context *) be_tocomptr(vm, -1); + if (!ctx) break; + + if (length > 0) { + br_sha256_update(ctx, bytes, length); + } + be_return_nil(vm); + // success + } while (0); + } + be_raise(vm, "value_error", NULL); +#else // USE_BERRY_CRYPTO_SHA256 + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_SHA256 + } + + // `.finish() -> bytes()` + // + // Add raw bytes to the MD5 calculation + int32_t m_hash_sha256_out(struct bvm *vm); + int32_t m_hash_sha256_out(struct bvm *vm) { +#ifdef USE_BERRY_CRYPTO_SHA256 + be_getmember(vm, 1, ".p"); + br_sha256_context * ctx; + ctx = (br_sha256_context *) be_tocomptr(vm, -1); + + uint8_t output[32]; + br_sha256_out(ctx, output); + be_pushbytes(vm, output, sizeof(output)); + be_return(vm); +#else // USE_BERRY_CRYPTO_SHA256 + be_raise(vm, "Not implemented", nullptr); +#endif // USE_BERRY_CRYPTO_SHA256 + } +} /*********************************************************************************************\ * EC C25519 class