Skip to content

Commit

Permalink
Berry RS256 crypto algorithm (RSASSA-MCKS1_v1-5 with SHA256) used for…
Browse files Browse the repository at this point in the history
… JWT (#18763)
  • Loading branch information
s-hadinger authored Jun 1, 2023
1 parent 74f9973 commit b9d855e
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Matter bridge for ESP8266 remote endpoints (experimental)
- Display descriptor for ST7735 128x160 display
- Matter support for Occupancy via Switch (experimental)
- Berry RS256 crypto algorithm (RSASSA-MCKS1_v1-5 with SHA256) used for JWT

### Breaking Changed
- Matter relay number starts at 1 instead of 0 to match Tasmota numbering
Expand Down
6 changes: 5 additions & 1 deletion lib/lib_ssl/bearssl-esp8266/src/t_inner.h
Original file line number Diff line number Diff line change
Expand Up @@ -2597,7 +2597,11 @@ br_cpuid(uint32_t mask_eax, uint32_t mask_ebx,
#endif

#define _debugBearSSL (0)
extern void optimistic_yield(uint32_t);
#ifdef ESP8266
extern void optimistic_yield(uint32_t);
#else
#define optimistic_yield(ignored)
#endif
#ifdef __cplusplus
}
#endif
Expand Down
11 changes: 11 additions & 0 deletions lib/libesp32/berry_tasmota/src/be_crypto_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
extern int be_class_crypto_member(bvm *vm);
extern int m_crypto_random(bvm *vm);

extern int m_rsa_rsassa_pkcs1_v1_5(bvm *vm);

extern int m_aes_ccm_init(bvm *vm);
extern int m_aes_ccm_encryt(bvm *vm);
extern int m_aes_ccm_decryt(bvm *vm);
Expand Down Expand Up @@ -56,6 +58,7 @@ extern const bclass be_class_md5;
#include "solidify/solidified_crypto_pbkdf2_hmac_sha256.h"
#include "solidify/solidified_crypto_spake2p_matter.h"

#include "be_fixed_be_class_rsa.h"
#include "be_fixed_be_class_aes_ccm.h"
#include "be_fixed_be_class_aes_gcm.h"
#include "be_fixed_be_class_aes_ctr.h"
Expand Down Expand Up @@ -104,6 +107,10 @@ const be_const_member_t be_crypto_members[] = {
{ "/PBKDF2_HMAC_SHA256", (intptr_t) &be_class_pbkdf2_hmac_sha256 },
#endif // USE_BERRY_CRYPTO_PBKDF2_HMAC_SHA256

#ifdef USE_BERRY_CRYPTO_RSA
{ "/RSA", (intptr_t) &be_class_rsa },
#endif // USE_BERRY_CRYPTO_PBKDF2_HMAC_SHA256

#ifdef USE_BERRY_CRYPTO_SHA256
{ "/SHA256", (intptr_t) &be_class_sha256 },
#endif // USE_BERRY_CRYPTO_SHA256
Expand All @@ -118,6 +125,10 @@ const size_t be_crypto_members_size = sizeof(be_crypto_members)/sizeof(be_crypto

/* @const_object_info_begin
class be_class_rsa (scope: global, name: RSA) {
rs256, static_func(m_rsa_rsassa_pkcs1_v1_5)
}
class be_class_aes_ccm (scope: global, name: AES_CCM) {
.p1, var
.p2, var
Expand Down
50 changes: 50 additions & 0 deletions tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_crypto.ino
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,56 @@ extern "C" {
}
}

/*********************************************************************************************\
* RSA class
*
\*********************************************************************************************/
extern "C" {
// crypto.RSA.rsassa_pkcs1_v1_5(private_key:bytes(), msg:bytes()) -> bytes()
// Parses RSA private key from DER binary
int32_t m_rsa_rsassa_pkcs1_v1_5(bvm *vm);
int32_t m_rsa_rsassa_pkcs1_v1_5(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isbytes(vm, 1)) {
size_t sk_len = 0;
uint8_t * sk_der = (uint8_t*) be_tobytes(vm, 1, &sk_len);

// 1. decode the DER private key
br_skey_decoder_context sdc;
br_skey_decoder_init(&sdc);
br_skey_decoder_push(&sdc, sk_der, sk_len);
if (int ret = br_skey_decoder_last_error(&sdc)) {
be_raisef(vm, "value_error", "invalid private key %i", ret);
}
if (br_skey_decoder_key_type(&sdc) != BR_KEYTYPE_RSA) {
be_raise(vm, "value_error", "key is not RSA");
}
const br_rsa_private_key *sk = br_skey_decoder_get_rsa(&sdc);

// 2. Hash the message with SHA
size_t msg_len = 0;
uint8_t * msg = (uint8_t*) be_tobytes(vm, 2, &msg_len);
uint8_t hash[32];
br_sha256_context ctx;
br_sha256_init(&ctx);
br_sha256_update(&ctx, msg, msg_len);
br_sha256_out(&ctx, hash);

// 3. sign the message
size_t sign_len = (sk->n_bitlen + 7) / 8;
uint8_t x[sign_len] = {};
int err = br_rsa_i15_pkcs1_sign(BR_HASH_OID_SHA256, hash, sizeof(hash), sk, x);
if (err != 1) {
be_raisef(vm, "value_error", "signature failed %i", err);
}

be_pushbytes(vm, x, sign_len);
be_return(vm);
}
be_raise(vm, kTypeError, nullptr);
}
}

/*********************************************************************************************\
* AES_GCM class
*
Expand Down

0 comments on commit b9d855e

Please sign in to comment.