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

This commit is contained in:
s-hadinger 2023-06-01 10:02:23 +02:00 committed by GitHub
parent 74f9973b8b
commit b9d855ef79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
@ -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"
@ -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
@ -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

View File

@ -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
*