Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Berry RS256 crypto algorithm (RSASSA-PCKS1_v1-5 with SHA256) used for JWT #18763

Merged
merged 1 commit into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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