108 lines
4.6 KiB
C
108 lines
4.6 KiB
C
#pragma once
|
|
#include "tlibc/collections/Array.h"
|
|
#include "tlibc/errors.h"
|
|
#include "bearssl_rsa.h"
|
|
#include "cryptography.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// RSA.c //
|
|
// //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define RSA_DEFAULT_KEY_SIZE 3072
|
|
|
|
/// @brief generate random key pair
|
|
/// @param key_size size of public key in bits (2048/3072/4096)
|
|
/// @param sk key for decryption
|
|
/// @param pk key for encryption
|
|
/// @param rng_vtable_ptr pointer to vtable field in prng context. The context must be initialized
|
|
Result(void) RSA_generateKeyPair(u32 key_size,
|
|
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
|
const br_prng_class** rng_vtable_ptr);
|
|
|
|
/// @brief generate random key pair using system crypto-rng provider
|
|
Result(void) RSA_generateKeyPairFromSystemRandom(u32 key_size,
|
|
br_rsa_private_key* sk, br_rsa_public_key* pk);
|
|
|
|
Result(void) RSA_generateKeyPairFromPassword(u32 key_size,
|
|
br_rsa_private_key* sk, br_rsa_public_key* pk, str password);
|
|
|
|
static inline void RSA_destroyPrivateKey(br_rsa_private_key* sk){
|
|
free(sk->p);
|
|
}
|
|
|
|
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(const br_rsa_private_key* sk, br_rsa_public_key* pk);
|
|
|
|
/// @brief Encode key data in human-readable format
|
|
/// @param src some data
|
|
/// @return heap-allocated string
|
|
str RSA_serializePrivateKey_base64(const br_rsa_private_key* sk);
|
|
|
|
/// @param src serialized private key format "RSA-Private-%SIZE%:%DATA_BASE64%"
|
|
/// @param sk out private key. WARNING: .p is allocated on heap
|
|
Result(void) RSA_parsePrivateKey_base64(const str src, br_rsa_private_key* sk);
|
|
|
|
/// @brief Encode key data in human-readable format
|
|
/// @param src some data
|
|
/// @return heap-allocated string
|
|
str RSA_serializePublicKey_base64(const br_rsa_public_key* sk);
|
|
|
|
/// @param src serialized public key format "RSA-Public-%SIZE%:%DATA_BASE64%"
|
|
/// @param sk out public key. WARNING: .p is allocated on heap
|
|
Result(void) RSA_parsePublicKey_base64(const str src, br_rsa_public_key* sk);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// RSAEncryptor //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct RSAEncryptor {
|
|
const br_rsa_public_key* pk;
|
|
br_hmac_drbg_context rng;
|
|
} RSAEncryptor;
|
|
|
|
/// RSA OAEP encryption with SHA256 hashing algorithm
|
|
void RSAEncryptor_construct(RSAEncryptor* ptr, const br_rsa_public_key* pk);
|
|
|
|
/*
|
|
https://crypto.stackexchange.com/a/42100
|
|
+---------+----------+-------------------------------------------+
|
|
| | overhead | max message size (bytes) |
|
|
| Hash | (bytes) | RSA-1024 | RSA-2048 | RSA-3072 | RSA-4096 |
|
|
+---------+----------+----------+----------+----------+----------+
|
|
| SHA-1 | 42 | 86 | 214 | 342 | 470 |
|
|
| SHA-224 | 58 | 70 | 198 | 326 | 454 |
|
|
| SHA-256 | 66 | 62 | 190 | 318 | 446 |
|
|
| SHA-384 | 98 | 30 | 158 | 286 | 414 |
|
|
| SHA-512 | 130 | N/A | 126 | 254 | 382 |
|
|
+---------+----------+----------+----------+----------+----------+
|
|
*/
|
|
#define RSAEncryptor_calcMaxSrcSize(KEY_LEN_BITS, HASH_LEN_BITS) (KEY_LEN_BITS / 8 - 2 * HASH_LEN_BITS / 8 - 2)
|
|
|
|
/// @param src buffer with size <= `RSAEncryptor_calcMaxSrcSize(key_size_bits, 256)`
|
|
/// @param dst buffer with size >= key size in bytes
|
|
/// @return size of encrypted data
|
|
Result(u32) RSAEncryptor_encrypt(RSAEncryptor* ptr, Array(u8) src, Array(u8) dst);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// RSADecryptor //
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct RSADecryptor {
|
|
const br_rsa_private_key* sk;
|
|
} RSADecryptor;
|
|
|
|
/// RSA OAEP encryption with SHA256 hashing algorithm
|
|
void RSADecryptor_construct(RSADecryptor* ptr, const br_rsa_private_key* sk);
|
|
|
|
/// @param src buffer with size == key size in bytes
|
|
/// @param dst buffer with size >= `RSAEncryptor_calcMaxSrcSize(key_size_bits, 256)`
|
|
/// @return size of decrypted data
|
|
Result(u32) RSADecryptor_decrypt(RSADecryptor* ptr, Array(u8) src, Array(u8) dst);
|