rsa encryption and decryption

This commit is contained in:
Timerix 2025-09-25 01:11:22 +05:00
parent 7ef2eb31ee
commit 37f38feec7
3 changed files with 51 additions and 57 deletions

View File

@ -1,6 +1,7 @@
#include "cryptography.h"
#include <assert.h>
#include "bearssl_x509.h"
#include "bearssl_pem.h"
// https://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537
#define DEFAULT_PUBLIC_EXPONENT 65537
@ -15,7 +16,7 @@ bool RSA_generateKeyPair(u32 key_size, br_rsa_private_key* sk, br_rsa_public_key
return r;
}
Result(void) RSA_computePublicKey(br_rsa_private_key* sk, br_rsa_public_key* pk){
Result(void) RSA_computePublicKey(const br_rsa_private_key* sk, br_rsa_public_key* pk){
Deferral(16);
br_rsa_compute_modulus compute_modulus = br_rsa_i31_compute_modulus;
br_rsa_compute_pubexp compute_pubexp = br_rsa_i31_compute_pubexp;
@ -53,16 +54,18 @@ Result(void) RSA_computePublicKey(br_rsa_private_key* sk, br_rsa_public_key* pk)
}
Result(void) RSA_serializePrivateKey_RawDER(
br_rsa_private_key* sk,
NULLABLE(br_rsa_public_key*) pk,
const br_rsa_private_key* sk,
NULLABLE(const br_rsa_public_key*) pk,
Array(u8)* out_der)
{
Deferral(32);
br_rsa_compute_pubexp compute_pubexp = br_rsa_i31_compute_pubexp;
br_rsa_compute_privexp compute_privexp = br_rsa_i31_compute_privexp;
br_rsa_public_key pk_computed;
if(pk == NULL){
try_void(RSA_computePublicKey(sk, pk));
pk = &pk_computed;
try_void(RSA_computePublicKey(sk, &pk_computed));
Defer(free(pk->n));
}
@ -157,7 +160,32 @@ Result(void) RSA_parsePrivateKey_DER(Array(u8) _src, br_rsa_private_key* sk){
Return RESULT_VOID;
}
void EncryptorRSA_init(EncryptorRSA* ptr, Array(u8) key){
void EncryptorRSA_construct(EncryptorRSA* ptr, const br_rsa_public_key* pk){
ptr->pk = pk;
rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, &ptr->rng.vtable);
}
void EncryptorRSA_encrypt(EncryptorRSA* ptr, Array(u8) src, Array(u8) dst, u32* encrypted_size){
size_t sz = br_rsa_i31_oaep_encrypt(
&ptr->rng.vtable, &br_sha256_vtable,
NULL, 0,
ptr->pk,
dst.data, dst.size,
src.data, src.size);
*encrypted_size = sz;
}
void DecryptorRSA_construct(DecryptorRSA* ptr, const br_rsa_private_key* sk){
ptr->sk = sk;
}
void DecryptorRSA_decrypt(DecryptorRSA* ptr, Array(u8) buf, u32* decrypted_size){
size_t sz = buf.size;
br_rsa_i31_oaep_decrypt(
&br_sha256_vtable,
NULL, 0,
ptr->sk,
buf.data, &sz);
*decrypted_size = sz;
}

View File

@ -6,7 +6,6 @@
#include "bearssl_block.h"
#include "bearssl_rand.h"
#include "bearssl_rsa.h"
#include "bearssl_pem.h"
//////////////////////////////////////////////////////////////////////////////
// hash.c //
@ -88,27 +87,32 @@ void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32*
// RSA.c //
//////////////////////////////////////////////////////////////////////////////
/// @brief generate random key pair based on system time
/// @param key_size size of public key in bits (2048/3072/4096)
/// @param sk key for decryption
/// @param pk key for encryption
/// @return true on success
bool RSA_generateKeyPair(u32 key_size, br_rsa_private_key* sk, br_rsa_public_key* pk);
static inline void RSA_freePrivateKey(br_rsa_private_key* sk){
static inline void RSA_destroyPrivateKey(br_rsa_private_key* sk){
free(sk->p);
}
static inline void RSA_freePublicKey(br_rsa_public_key* sk){
static inline void RSA_destroyPublicKey(br_rsa_public_key* sk){
free(sk->n);
}
/// @param sk some private key
/// @param pk out public key. WARNING: .n is allocated on heap
Result(void) RSA_computePublicKey(br_rsa_private_key* sk, br_rsa_public_key* pk);
Result(void) RSA_computePublicKey(const br_rsa_private_key* sk, br_rsa_public_key* pk);
/// @brief Serialize key in raw DER binary format
/// @param sk the private key
/// @param pk set to NULL to calculate automatically
/// @param out_der out array. WARNING: .data is allocated on heap
Result(void) RSA_serializePrivateKey_RawDER(
br_rsa_private_key* sk,
NULLABLE(br_rsa_public_key*) pk,
const br_rsa_private_key* sk,
NULLABLE(const br_rsa_public_key*) pk,
Array(u8)* out_der);
/// @brief Encode key data in human-readable format
@ -122,15 +126,15 @@ void PEM_encode(Array(u8) src, Array(u8)* dst, cstr label);
Result(void) RSA_parsePrivateKey_DER(Array(u8) src, br_rsa_private_key* sk);
typedef struct EncryptorRSA {
br_rsa_public_key public_key;
const br_rsa_public_key* pk;
br_hmac_drbg_context rng;
} EncryptorRSA;
/// @param key Array<u8, 16 | 24 | 32>
void EncryptorRSA_init(EncryptorRSA* ptr, Array(u8) key);
void EncryptorRSA_construct(EncryptorRSA* ptr, const br_rsa_public_key* pk);
void EncryptorRSA_encrypt(EncryptorRSA* ptr, Array(u8) src, Array(u8) dst, u32* encrypted_size);
typedef struct DecryptorRSA {
br_rsa_private_key private_key;
const br_rsa_private_key* sk;
} DecryptorRSA;
/// @param key Array<u8, 16 | 24 | 32>
void DecryptorRSA_init(DecryptorRSA* ptr, Array(u8) key);
void DecryptorRSA_construct(DecryptorRSA* ptr, const br_rsa_private_key* sk);
void DecryptorRSA_decrypt(DecryptorRSA* ptr, Array(u8) buf, u32* decrypted_size);

View File

@ -12,44 +12,6 @@ typedef enum ProgramMode {
int main(const int argc, cstr const* argv){
Deferral(32);
const u32 key_size = 2048;
br_rsa_private_key sk;
br_rsa_public_key pk;
if(!RSA_generateKeyPair(key_size, &sk, &pk)){
printfe("ERROR: can't generate RSA key pair\n");
Return 1;
}
br_rsa_public_key pk2;
try_fatal_void(RSA_computePublicKey(&sk, &pk2));
Defer(free(pk2.n));
if(memcmp(pk2.n, pk.n, pk.nlen) != 0){
printfe("public key computation failed\n");
Return 1;
}
Array(u8) der;
try_fatal_void(RSA_serializePrivateKey_RawDER(&sk, &pk, &der));
Defer(free(der.data));
Array(u8) pem;
Defer(free(pem.data));
PEM_encode(der, &pem, "RSA PRIVATE KEY");
printf("\nserialized key:\n%s\n\n", (char*)pem.data);
br_rsa_private_key sk2;
try_fatal_void(RSA_parsePrivateKey_DER(der, &sk2));
Defer(free(sk2.p));
free(der.data);
try_fatal_void(RSA_serializePrivateKey_RawDER(&sk2, &pk, &der));
free(pem.data);
PEM_encode(der, &pem, "RSA PRIVATE KEY");
printf("\nparsed key:\n%s\n\n", (char*)pem.data);
Return 0;
ProgramMode mode = Client;
cstr server_endpoint_cstr;