1730 lines
52 KiB
Plaintext
1730 lines
52 KiB
Plaintext
/*
|
|
* JS update 18.04.2024
|
|
* Pridana instrukcia _rdtsc() na meranie casu pri overovani certifikatov
|
|
*/
|
|
|
|
/*
|
|
* JS update 14.04.2024
|
|
* Pridana podpora pre algoritmy ML-KEM a ML-DSA
|
|
* Testovane s novou verziou liboqs 0.10.0
|
|
*/
|
|
|
|
/*
|
|
* JS update 29.02.2024
|
|
* Pridanie kniznice liboqs, nahradenie funkcii z miracl core
|
|
* Pouzitie generatoru (pseudo)nahodnych cisel z kniznice liboqs
|
|
* Uprava funkcii, ktore priamo vyuzivaju pole s vygenerovanymi cislami
|
|
* Definovanie novych PQ KEM algoritmov do zoznamu
|
|
* Pridane nove PQ algoritmy pre certifikaty a podpis
|
|
* Pridane funkcie pre generovanie sukromneho a verejneho kluca pre KEM protokoly
|
|
* Pridane funkcie na decapsulaciu pre KEM protokoly
|
|
* Pridane funkcii na overenie a podpis novymi PQ algoritmami
|
|
*/
|
|
|
|
// JS update
|
|
// Cryptographic Security Abstraction Layer API - this version uses MIRACL core & liboqs functions
|
|
//
|
|
|
|
#include "tls_sal.h"
|
|
|
|
// Pull in MIRACL core code
|
|
|
|
#include "core.h"
|
|
#include "ecdh_NIST256.h"
|
|
#include "ecdh_NIST384.h"
|
|
#include "ecdh_C25519.h"
|
|
#include "rsa_RSA2048.h"
|
|
#include "rsa_RSA4096.h"
|
|
#include "eddsa_Ed25519.h"
|
|
#include "eddsa_Ed448.h"
|
|
#include <intrin.h>
|
|
#pragma intrinsic(__rdtsc)
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
// JS post-kvantove algoritmy pridane z kniznice liboqs
|
|
#include <oqs/oqs.h>
|
|
#include <oqs/oqsconfig.h>
|
|
|
|
#endif
|
|
|
|
using namespace core;
|
|
|
|
csprng RNG; // Global miracl core Crypto Strong RNG - could be a hardware source
|
|
|
|
// JS definovanie pola pre vygenerovanie 64 nahodnych cisel pouzitych ako seed pre RNG
|
|
uint8_t RNGseed[64];
|
|
|
|
// JS pridanie liboqs do vypisu
|
|
char* SAL_name()
|
|
{
|
|
return (char *)"MIRACL Core + liboqs";
|
|
}
|
|
|
|
// JS pole naplnene nahodne vygenerovanymi cislami a pouzite ako seed pre RNG generator
|
|
bool SAL_initLib()
|
|
{ // Initialise library
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
OQS_randombytes(RNGseed, 64);
|
|
|
|
#else
|
|
char raw[64];
|
|
for (int i = 0; i < 64; i++) raw[i] = i; // *** should be from output of true random number generator ****
|
|
#endif
|
|
RAND_seed(&RNG, 64, (char*) RNGseed);
|
|
return true;
|
|
}
|
|
|
|
void SAL_endLib()
|
|
{
|
|
}
|
|
|
|
int SAL_ciphers(int *ciphers)
|
|
{
|
|
int n=2;
|
|
ciphers[0]=TLS_AES_128_GCM_SHA256;
|
|
ciphers[1]=TLS_AES_256_GCM_SHA384;
|
|
return n;
|
|
}
|
|
|
|
// IMPORTANT - Favourite group (as used in client Hello) must be placed first in list
|
|
int SAL_groups(int *groups)
|
|
{
|
|
int n=0;
|
|
|
|
#if CRYPTO_SETTING==TINY_ECC || CRYPTO_SETTING==EDDSA
|
|
n=3;
|
|
groups[0]=X25519;
|
|
groups[1]=SECP256R1;
|
|
groups[2]=SECP384R1;
|
|
#endif
|
|
|
|
#if CRYPTO_SETTING==TYPICAL
|
|
n=3;
|
|
groups[0]=X25519;
|
|
groups[1]=SECP256R1;
|
|
groups[2]=SECP384R1;
|
|
#endif
|
|
|
|
// JS doplnene PQ KEM algoritmy
|
|
// BIKE nefunguje na Windowse, preto je jeho pridanie do zoznamu podmienene linuxovym prostredim
|
|
#if CRYPTO_SETTING==POST_QUANTUM
|
|
n=0;
|
|
groups[n]=KYBER512; n++;
|
|
groups[n]=KYBER768; n++;
|
|
groups[n]=KYBER1024; n++;
|
|
groups[n]=MLKEM512; n++;
|
|
groups[n]=MLKEM768; n++;
|
|
groups[n]=MLKEM1024; n++;
|
|
groups[n]=HQC128; n++;
|
|
groups[n]=HQC192; n++;
|
|
groups[n]=HQC256; n++;
|
|
groups[n]=FRODO640AES; n++;
|
|
groups[n]=FRODO640SHAKE; n++;
|
|
groups[n]=FRODO976AES; n++;
|
|
groups[n]=FRODO976SHAKE; n++;
|
|
groups[n]=FRODO1344AES; n++;
|
|
groups[n]=FRODO1344SHAKE; n++;
|
|
#ifdef __linux__
|
|
groups[n]=BIKEL1; n++;
|
|
groups[n]=BIKEL3; n++;
|
|
groups[n]=BIKEL5; n++;
|
|
#endif
|
|
|
|
#endif
|
|
|
|
return n;
|
|
}
|
|
|
|
int SAL_sigs(int *sigAlgs)
|
|
{
|
|
int n=4;
|
|
sigAlgs[0]=ECDSA_SECP256R1_SHA256;
|
|
sigAlgs[1]=ECDSA_SECP384R1_SHA384;
|
|
sigAlgs[2]=ED25519;
|
|
sigAlgs[3]=ED448;
|
|
#if CRYPTO_SETTING>TINY_ECC
|
|
sigAlgs[n]=RSA_PSS_RSAE_SHA256; n++;
|
|
#endif
|
|
|
|
// JS doplnene PQ algoritmy
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
sigAlgs[n]=DILITHIUM2; n++;
|
|
sigAlgs[n]=DILITHIUM3; n++;
|
|
sigAlgs[n]=DILITHIUM5; n++;
|
|
sigAlgs[n]=MLDSA44; n++;
|
|
sigAlgs[n]=MLDSA65; n++;
|
|
sigAlgs[n]=MLDSA87; n++;
|
|
sigAlgs[n]=FALCON512; n++;
|
|
sigAlgs[n]=FALCON1024; n++;
|
|
sigAlgs[n]=SPHINCSSHA2128FSIMPLE; n++;
|
|
sigAlgs[n]=SPHINCSSHA2128SSIMPLE; n++;
|
|
sigAlgs[n]=SPHINCSSHAKE128FSIMPLE; n++;
|
|
//sigAlgs[n]=SPHINCSSHA2192FSIMPLE; n++;
|
|
#endif
|
|
return n;
|
|
}
|
|
|
|
int SAL_sigCerts(int *sigAlgsCert)
|
|
{
|
|
int n=4;
|
|
sigAlgsCert[0]=ECDSA_SECP256R1_SHA256;
|
|
sigAlgsCert[1]=ECDSA_SECP384R1_SHA384;
|
|
sigAlgsCert[2]=ED25519;
|
|
sigAlgsCert[3]=ED448;
|
|
#if CRYPTO_SETTING>TINY_ECC
|
|
sigAlgsCert[n]=RSA_PKCS1_SHA256; n++;
|
|
sigAlgsCert[n]=RSA_PKCS1_SHA384; n++;
|
|
sigAlgsCert[n]=RSA_PKCS1_SHA512; n++;
|
|
#endif
|
|
|
|
// JS doplnene PQ algoritmy
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
sigAlgsCert[n]=DILITHIUM2; n++;
|
|
sigAlgsCert[n]=DILITHIUM3; n++;
|
|
sigAlgsCert[n]=DILITHIUM5; n++;
|
|
sigAlgsCert[n]=MLDSA44; n++;
|
|
sigAlgsCert[n]=MLDSA65; n++;
|
|
sigAlgsCert[n]=MLDSA87; n++;
|
|
sigAlgsCert[n]=FALCON512; n++;
|
|
sigAlgsCert[n]=FALCON1024; n++;
|
|
sigAlgsCert[n]=SPHINCSSHA2128FSIMPLE; n++;
|
|
sigAlgsCert[n]=SPHINCSSHA2128SSIMPLE; n++;
|
|
sigAlgsCert[n]=SPHINCSSHAKE128FSIMPLE; n++;
|
|
//sigAlgsCert[n]=SPHINCSSHA2192FSIMPLE; n++;
|
|
#endif
|
|
return n;
|
|
}
|
|
|
|
// return hashtype from cipher_suite
|
|
int SAL_hashType(int cipher_suite)
|
|
{
|
|
int htype=0;
|
|
if (cipher_suite==TLS_AES_128_GCM_SHA256) htype=TLS_SHA256_T;
|
|
if (cipher_suite==TLS_AES_256_GCM_SHA384) htype=TLS_SHA384_T;
|
|
if (cipher_suite==TLS_CHACHA20_POLY1305_SHA256) htype=TLS_SHA256_T;
|
|
return htype;
|
|
}
|
|
|
|
/*
|
|
// return hashtype from signature algorithm
|
|
int SAL_hashTypeSig(int sigAlg)
|
|
{
|
|
int htype=0;
|
|
if (sigAlg==ECDSA_SECP256R1_SHA256) htype=TLS_SHA256_T;
|
|
if (sigAlg==ECDSA_SECP384R1_SHA384) htype=TLS_SHA384_T;
|
|
if (sigAlg==RSA_PSS_RSAE_SHA256) htype=TLS_SHA256_T;
|
|
if (sigAlg==RSA_PSS_RSAE_SHA384) htype=TLS_SHA384_T;
|
|
if (sigAlg==RSA_PSS_RSAE_SHA512) htype=TLS_SHA512_T;
|
|
if (sigAlg==RSA_PKCS1_SHA256) htype=TLS_SHA256_T;
|
|
if (sigAlg==RSA_PKCS1_SHA384) htype=TLS_SHA384_T;
|
|
if (sigAlg==RSA_PKCS1_SHA512) htype=TLS_SHA512_T;
|
|
return htype;
|
|
}
|
|
*/
|
|
// return hash length from hash type
|
|
int SAL_hashLen(int hash_type)
|
|
{
|
|
int hlen=0;
|
|
if (hash_type==TLS_SHA256_T) hlen=32;
|
|
if (hash_type==TLS_SHA384_T) hlen=48;
|
|
if (hash_type==TLS_SHA512_T) hlen=64;
|
|
return hlen;
|
|
}
|
|
|
|
int SAL_aeadKeylen(int cipher_suite)
|
|
{
|
|
int klen=0;
|
|
if (cipher_suite==TLS_AES_128_GCM_SHA256) klen=16;
|
|
if (cipher_suite==TLS_AES_256_GCM_SHA384) klen=32;
|
|
if (cipher_suite==TLS_CHACHA20_POLY1305_SHA256) klen=32;
|
|
return klen;
|
|
}
|
|
|
|
int SAL_aeadTaglen(int cipher_suite)
|
|
{
|
|
int tlen=0;
|
|
if (cipher_suite==TLS_AES_128_GCM_SHA256) tlen=16;
|
|
if (cipher_suite==TLS_AES_256_GCM_SHA384) tlen=16;
|
|
if (cipher_suite==TLS_CHACHA20_POLY1305_SHA256) tlen=16;
|
|
return tlen;
|
|
}
|
|
|
|
// convert TLS octad to MIRACL core octet
|
|
static octet octad_to_octet(octad *x)
|
|
{
|
|
octet y;
|
|
if (x!=NULL) {
|
|
y.len=x->len;
|
|
y.max=x->max;
|
|
y.val=x->val;
|
|
} else {
|
|
y.len=y.max=0;
|
|
y.val=NULL;
|
|
}
|
|
return y;
|
|
}
|
|
|
|
// Return a random byte
|
|
int SAL_randomByte()
|
|
{
|
|
return RAND_byte(&RNG);
|
|
}
|
|
|
|
// Fill an octad with random values
|
|
void SAL_randomOctad(int len,octad *R)
|
|
{
|
|
for (int i=0;i<len;i++)
|
|
R->val[i]=SAL_randomByte();
|
|
R->len=len;
|
|
}
|
|
|
|
// HKDF - Extract secret from raw input
|
|
void SAL_hkdfExtract(int htype,octad *PRK,octad *SALT,octad *IKM)
|
|
{
|
|
int hlen=SAL_hashLen(htype);
|
|
octet MC_PRK=octad_to_octet(PRK); // Make it MIRACL core compatible
|
|
octet MC_SALT=octad_to_octet(SALT);
|
|
octet MC_IKM=octad_to_octet(IKM);
|
|
|
|
HKDF_Extract(MC_SHA2,hlen,&MC_PRK,&MC_SALT,&MC_IKM);
|
|
|
|
IKM->len=MC_IKM.len; // restore length
|
|
SALT->len=MC_SALT.len;
|
|
PRK->len=MC_PRK.len;
|
|
}
|
|
|
|
void SAL_hkdfExpand(int htype, int olen, octad *OKM,octad *PRK, octad *INFO)
|
|
{
|
|
int hlen=SAL_hashLen(htype);
|
|
octet MC_OKM=octad_to_octet(OKM);
|
|
octet MC_INFO=octad_to_octet(INFO);
|
|
octet MC_PRK=octad_to_octet(PRK);
|
|
|
|
HKDF_Expand(MC_SHA2,hlen,&MC_OKM,olen,&MC_PRK,&MC_INFO);
|
|
|
|
OKM->len=MC_OKM.len;
|
|
INFO->len=MC_INFO.len;
|
|
PRK->len=MC_PRK.len;
|
|
}
|
|
|
|
// HMAC
|
|
void SAL_hmac(int htype,octad *T,octad *K,octad *M)
|
|
{
|
|
int hlen=SAL_hashLen(htype);
|
|
octet MC_T=octad_to_octet(T);
|
|
octet MC_K=octad_to_octet(K);
|
|
octet MC_M=octad_to_octet(M);
|
|
|
|
HMAC(MC_SHA2,hlen,&MC_T,hlen,&MC_K,&MC_M);
|
|
|
|
T->len=MC_T.len;
|
|
K->len=MC_K.len;
|
|
M->len=MC_M.len;
|
|
}
|
|
|
|
// HASH of NULL
|
|
void SAL_hashNull(int htype,octad *H)
|
|
{
|
|
if (htype==TLS_SHA256_T)
|
|
{
|
|
core::hash256 sh;
|
|
HASH256_init(&sh);
|
|
HASH256_hash(&sh,H->val);
|
|
}
|
|
if (htype==TLS_SHA384_T)
|
|
{
|
|
core::hash384 sh;
|
|
HASH384_init(&sh);
|
|
HASH384_hash(&sh,H->val);
|
|
}
|
|
if (htype==TLS_SHA512_T)
|
|
{
|
|
core::hash512 sh;
|
|
HASH512_init(&sh);
|
|
HASH512_hash(&sh,H->val);
|
|
|
|
}
|
|
H->len=SAL_hashLen(htype);
|
|
return;
|
|
}
|
|
|
|
// Unified hashing. Hash type type indicate by htype.
|
|
void SAL_hashInit(int htype,unihash *h)
|
|
{
|
|
if (htype==TLS_SHA256_T)
|
|
HASH256_init((core::hash256*)&(h->state));
|
|
if (htype==TLS_SHA384_T)
|
|
HASH384_init((core::hash512*)&(h->state));
|
|
if (htype==TLS_SHA512_T)
|
|
HASH512_init((core::hash512*)&(h->state));
|
|
h->htype=htype;
|
|
}
|
|
|
|
// Process a byte array
|
|
void SAL_hashProcessArray(unihash *h,char *b,int len)
|
|
{
|
|
int i;
|
|
if (h->htype==TLS_SHA256_T)
|
|
{
|
|
for (i=0;i<len;i++)
|
|
HASH256_process((core::hash256*)&(h->state),b[i]);
|
|
}
|
|
if (h->htype==TLS_SHA384_T)
|
|
{
|
|
for (i=0;i<len;i++)
|
|
HASH384_process((core::hash512*)&(h->state),b[i]);
|
|
}
|
|
if (h->htype==TLS_SHA512_T)
|
|
{
|
|
for (i=0;i<len;i++)
|
|
HASH512_process((core::hash512*)&(h->state),b[i]);
|
|
}
|
|
}
|
|
|
|
// output digest
|
|
int SAL_hashOutput(unihash *h,char *d)
|
|
{
|
|
int hlen=SAL_hashLen(h->htype);
|
|
if (h->htype==TLS_SHA256_T)
|
|
HASH256_continuing_hash((core::hash256*)&(h->state),d);
|
|
if (h->htype==TLS_SHA384_T)
|
|
HASH384_continuing_hash((core::hash384*)&(h->state),d);
|
|
if (h->htype==TLS_SHA512_T)
|
|
HASH512_continuing_hash((core::hash512*)&(h->state),d);
|
|
return hlen;
|
|
}
|
|
|
|
void SAL_aeadEncrypt(crypto *send,int hdrlen,char *hdr,int ptlen,char *pt,octad *TAG)
|
|
{ // AEAD encryption
|
|
// its AES-GCM
|
|
gcm g;
|
|
GCM_init(&g,send->K.len,send->K.val,12,send->IV.val); // Encrypt with Key and IV
|
|
GCM_add_header(&g,hdr,hdrlen);
|
|
GCM_add_plain(&g,pt,pt,ptlen);
|
|
//create and append TA
|
|
GCM_finish(&g,TAG->val);
|
|
TAG->len=16;
|
|
}
|
|
|
|
bool SAL_aeadDecrypt(crypto *recv,int hdrlen,char *hdr,int ctlen,char *ct,octad *TAG)
|
|
{ // AEAD decryption
|
|
// its AES-GCM
|
|
char ctag[TLS_MAX_TAG_SIZE]; // calculated TAG
|
|
octad CTAG={0,sizeof(ctag),ctag};
|
|
gcm g;
|
|
GCM_init(&g,recv->K.len,recv->K.val,12,recv->IV.val); // Decrypt with Key and IV
|
|
GCM_add_header(&g,hdr,hdrlen);
|
|
GCM_add_cipher(&g,ct,ct,ctlen);
|
|
//create and append TA
|
|
GCM_finish(&g,CTAG.val); CTAG.len=16;
|
|
if (!OCT_compare(TAG,&CTAG))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
// generate a public/private key pair in an approved group for a key exchange
|
|
void SAL_generateKeyPair(int group,octad *SK,octad *PK)
|
|
{
|
|
octet MC_SK=octad_to_octet(SK);
|
|
octet MC_PK=octad_to_octet(PK);
|
|
|
|
if (group==X25519)
|
|
{ // Note that this program maintains the private key in big-endian format
|
|
// But X25519 assumes private and public keys are all in little-endian form (and are transmitted/received in that form)
|
|
SAL_randomOctad(32,SK);
|
|
SK->val[31]&=248;
|
|
SK->val[0]&=127;
|
|
SK->val[0]|=64;
|
|
C25519::ECP_KEY_PAIR_GENERATE(NULL, &MC_SK, &MC_PK);
|
|
OCT_reverse(&MC_PK); // public key must be transmitted in little-endian form
|
|
}
|
|
if (group==SECP256R1)
|
|
{
|
|
SAL_randomOctad(32,SK);
|
|
NIST256::ECP_KEY_PAIR_GENERATE(NULL, &MC_SK, &MC_PK);
|
|
}
|
|
if (group==SECP384R1)
|
|
{
|
|
SAL_randomOctad(48,SK);
|
|
NIST384::ECP_KEY_PAIR_GENERATE(NULL, &MC_SK, &MC_PK);
|
|
}
|
|
SK->len=MC_SK.len;
|
|
PK->len=MC_PK.len;
|
|
|
|
//--------------------------------------------------------------------------
|
|
// JS doplnene PQ KEM algoritmy
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
if (group==KYBER768){
|
|
OQS_STATUS rc = OQS_KEM_kyber_768_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_kyber_768_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_kyber_768_length_secret_key;
|
|
PK->len=OQS_KEM_kyber_768_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==KYBER512){
|
|
OQS_STATUS rc = OQS_KEM_kyber_512_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_kyber_512_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_kyber_512_length_secret_key;
|
|
PK->len=OQS_KEM_kyber_512_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==KYBER1024){
|
|
OQS_STATUS rc = OQS_KEM_kyber_1024_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_kyber_1024_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_kyber_1024_length_secret_key;
|
|
PK->len=OQS_KEM_kyber_1024_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==MLKEM512){
|
|
OQS_STATUS rc = OQS_KEM_ml_kem_512_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_ml_kem_512_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_ml_kem_512_length_secret_key;
|
|
PK->len=OQS_KEM_ml_kem_512_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==MLKEM768){
|
|
OQS_STATUS rc = OQS_KEM_ml_kem_768_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_ml_kem_768_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_ml_kem_768_length_secret_key;
|
|
PK->len=OQS_KEM_ml_kem_768_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==MLKEM1024){
|
|
OQS_STATUS rc = OQS_KEM_ml_kem_1024_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_ml_kem_1024_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_ml_kem_1024_length_secret_key;
|
|
PK->len=OQS_KEM_ml_kem_1024_length_public_key;
|
|
}
|
|
}
|
|
|
|
// JS Protokol BIKE nie je podporovany na Windowse, preto je definovany len pre linuxove prostredie
|
|
// Bez podmienky aplikacia na Windowse padne, pretoze liboqs na Windowse neobsahuje funkcie pre BIKE
|
|
#ifdef __linux__
|
|
if (group==BIKEL1){
|
|
OQS_STATUS rc = OQS_KEM_bike_l1_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_bike_l1_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_bike_l1_length_secret_key;
|
|
PK->len=OQS_KEM_bike_l1_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==BIKEL3){
|
|
OQS_STATUS rc = OQS_KEM_bike_l3_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_bike_l3_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_bike_l3_length_secret_key;
|
|
PK->len=OQS_KEM_bike_l3_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==BIKEL5){
|
|
OQS_STATUS rc = OQS_KEM_bike_l5_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_bike_l5_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_bike_l5_length_secret_key;
|
|
PK->len=OQS_KEM_bike_l5_length_public_key;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (group==HQC128){
|
|
OQS_STATUS rc = OQS_KEM_hqc_128_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_hqc_128_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_hqc_128_length_secret_key;
|
|
PK->len=OQS_KEM_hqc_128_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==HQC192){
|
|
OQS_STATUS rc = OQS_KEM_hqc_192_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_hqc_192_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_hqc_192_length_secret_key;
|
|
PK->len=OQS_KEM_hqc_192_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==HQC256){
|
|
OQS_STATUS rc = OQS_KEM_hqc_256_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_hqc_256_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_hqc_256_length_secret_key;
|
|
PK->len=OQS_KEM_hqc_256_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO640AES){
|
|
OQS_STATUS rc = OQS_KEM_frodokem_640_aes_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_640_aes_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_640_aes_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_640_aes_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO976AES){
|
|
OQS_STATUS rc = OQS_KEM_frodokem_976_aes_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_976_aes_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_976_aes_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_976_aes_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO1344AES){
|
|
OQS_STATUS rc = OQS_KEM_frodokem_1344_aes_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_1344_aes_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_1344_aes_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_1344_aes_length_public_key;
|
|
}
|
|
}
|
|
|
|
|
|
if (group==FRODO640SHAKE){
|
|
OQS_STATUS rc = OQS_KEM_frodokem_640_shake_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_640_shake_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_640_shake_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_640_shake_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO976SHAKE){
|
|
OQS_STATUS rc = OQS_KEM_frodokem_976_shake_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_976_shake_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_976_shake_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_976_shake_length_public_key;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO1344SHAKE){
|
|
OQS_STATUS rc = OQS_KEM_frodokem_1344_shake_keypair((uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_1344_shake_keypair failed!\n");
|
|
SK->len=0;
|
|
PK->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_1344_shake_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_1344_shake_length_public_key;
|
|
}
|
|
}
|
|
//--------------------------------------------------------------------------
|
|
|
|
#endif
|
|
}
|
|
|
|
// generate shared secret SS from secret key SK and public key PK
|
|
bool SAL_generateSharedSecret(int group,octad *SK,octad *PK,octad *SS)
|
|
{
|
|
octet MC_SK=octad_to_octet(SK);
|
|
octet MC_PK=octad_to_octet(PK);
|
|
octet MC_SS=octad_to_octet(SS);
|
|
int res=0;
|
|
|
|
if (group==X25519) {
|
|
OCT_reverse(&MC_PK); // to big endian
|
|
res=C25519::ECP_SVDP_DH(&MC_SK, &MC_PK, &MC_SS,0);
|
|
OCT_reverse(&MC_PK); // back again
|
|
OCT_reverse(&MC_SS);
|
|
}
|
|
if (group==SECP256R1) {
|
|
res=NIST256::ECP_SVDP_DH(&MC_SK, &MC_PK, &MC_SS,0);
|
|
}
|
|
if (group==SECP384R1) {
|
|
res=NIST384::ECP_SVDP_DH(&MC_SK, &MC_PK, &MC_SS,0);
|
|
}
|
|
SK->len=MC_SK.len;
|
|
PK->len=MC_PK.len;
|
|
SS->len=MC_SS.len;
|
|
|
|
//--------------------------------------------------------------------------
|
|
// JS doplnene PQ KEM algoritmy
|
|
// Zo strany klienta je pri KEM protokole realizovana len decapsulacia
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
if (group==KYBER768) {
|
|
OQS_STATUS rc = OQS_KEM_kyber_768_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_kyber_768_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_kyber_768_length_secret_key;
|
|
PK->len=OQS_KEM_kyber_768_length_ciphertext;
|
|
SS->len=OQS_KEM_kyber_768_length_shared_secret;
|
|
}
|
|
}
|
|
if (group==KYBER512) {
|
|
OQS_STATUS rc = OQS_KEM_kyber_512_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_kyber_512_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_kyber_512_length_secret_key;
|
|
PK->len=OQS_KEM_kyber_512_length_ciphertext;
|
|
SS->len=OQS_KEM_kyber_512_length_shared_secret;
|
|
}
|
|
}
|
|
if (group==KYBER1024) {
|
|
OQS_STATUS rc = OQS_KEM_kyber_1024_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_kyber_1024_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_kyber_1024_length_secret_key;
|
|
PK->len=OQS_KEM_kyber_1024_length_ciphertext;
|
|
SS->len=OQS_KEM_kyber_1024_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==MLKEM512) {
|
|
OQS_STATUS rc = OQS_KEM_ml_kem_512_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_ml_kem_512_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_ml_kem_512_length_secret_key;
|
|
PK->len=OQS_KEM_ml_kem_512_length_ciphertext;
|
|
SS->len=OQS_KEM_ml_kem_512_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==MLKEM768) {
|
|
OQS_STATUS rc = OQS_KEM_ml_kem_768_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_ml_kem_768_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_ml_kem_768_length_secret_key;
|
|
PK->len=OQS_KEM_ml_kem_768_length_ciphertext;
|
|
SS->len=OQS_KEM_ml_kem_768_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==MLKEM1024) {
|
|
OQS_STATUS rc = OQS_KEM_ml_kem_1024_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_ml_kem_1024_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_ml_kem_1024_length_secret_key;
|
|
PK->len=OQS_KEM_ml_kem_1024_length_ciphertext;
|
|
SS->len=OQS_KEM_ml_kem_1024_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
// JS Protokol BIKE nie je podporovany na Windowse, preto je definovany len pre linuxove prostredie
|
|
// Bez podmienky aplikacia na Windowse padne, pretoze liboqs na Windowse neobsahuje funkcie pre BIKE
|
|
#ifdef __linux__
|
|
if (group==BIKEL1) {
|
|
OQS_STATUS rc = OQS_KEM_bike_l1_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_bike_l1_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_bike_l1_length_secret_key;
|
|
PK->len=OQS_KEM_bike_l1_length_ciphertext;
|
|
SS->len=OQS_KEM_bike_l1_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==BIKEL3) {
|
|
OQS_STATUS rc = OQS_KEM_bike_l3_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_bike_l3_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_bike_l3_length_secret_key;
|
|
PK->len=OQS_KEM_bike_l3_length_ciphertext;
|
|
SS->len=OQS_KEM_bike_l3_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==BIKEL5) {
|
|
OQS_STATUS rc = OQS_KEM_bike_l5_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_bike_l5_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_bike_l5_length_secret_key;
|
|
PK->len=OQS_KEM_bike_l5_length_ciphertext;
|
|
SS->len=OQS_KEM_bike_l5_length_shared_secret;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (group==HQC128) {
|
|
OQS_STATUS rc = OQS_KEM_hqc_128_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_hqc_128_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_hqc_128_length_secret_key;
|
|
PK->len=OQS_KEM_hqc_128_length_ciphertext;
|
|
SS->len=OQS_KEM_hqc_128_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==HQC192) {
|
|
OQS_STATUS rc = OQS_KEM_hqc_192_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_hqc_192_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_hqc_192_length_secret_key;
|
|
PK->len=OQS_KEM_hqc_192_length_ciphertext;
|
|
SS->len=OQS_KEM_hqc_192_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==HQC256) {
|
|
OQS_STATUS rc = OQS_KEM_hqc_256_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_hqc_256_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_hqc_256_length_secret_key;
|
|
PK->len=OQS_KEM_hqc_256_length_ciphertext;
|
|
SS->len=OQS_KEM_hqc_256_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO640AES) {
|
|
OQS_STATUS rc = OQS_KEM_frodokem_640_aes_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_640_aes_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_640_aes_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_640_aes_length_ciphertext;
|
|
SS->len=OQS_KEM_frodokem_640_aes_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO976AES) {
|
|
OQS_STATUS rc = OQS_KEM_frodokem_976_aes_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_976_aes_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_976_aes_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_976_aes_length_ciphertext;
|
|
SS->len=OQS_KEM_frodokem_976_aes_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO1344AES) {
|
|
OQS_STATUS rc = OQS_KEM_frodokem_1344_aes_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_1344_aes_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_1344_aes_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_1344_aes_length_ciphertext;
|
|
SS->len=OQS_KEM_frodokem_1344_aes_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO640SHAKE) {
|
|
OQS_STATUS rc = OQS_KEM_frodokem_640_shake_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_640_shake_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_640_shake_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_640_shake_length_ciphertext;
|
|
SS->len=OQS_KEM_frodokem_640_shake_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO976SHAKE) {
|
|
OQS_STATUS rc = OQS_KEM_frodokem_976_shake_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_976_shake_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_976_shake_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_976_shake_length_ciphertext;
|
|
SS->len=OQS_KEM_frodokem_976_shake_length_shared_secret;
|
|
}
|
|
}
|
|
|
|
if (group==FRODO1344SHAKE) {
|
|
OQS_STATUS rc = OQS_KEM_frodokem_1344_shake_decaps( (uint8_t*) SS->val, (uint8_t*) PK->val, (uint8_t*) SK->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_KEM_frodokem_1344_shake_decaps failed!\n");
|
|
SS->len=0;
|
|
}
|
|
else{
|
|
SK->len=OQS_KEM_frodokem_1344_shake_length_secret_key;
|
|
PK->len=OQS_KEM_frodokem_1344_shake_length_ciphertext;
|
|
SS->len=OQS_KEM_frodokem_1344_shake_length_shared_secret;
|
|
}
|
|
}
|
|
//--------------------------------------------------------------------------
|
|
#endif
|
|
|
|
// all zeros is suspect...
|
|
char ors=0;
|
|
for (int i=0;i<SS->len;i++) ors|=SS->val[i];
|
|
if (ors==0 || res!=0) return false;
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// JS funkcie pre nove PQ algoritmy
|
|
// Najprv funkcia pre overenie, potom funkcia pre podpis
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
static bool DILITHIUM3_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_dilithium_3_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_dilithium_3_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void DILITHIUM3_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_dilithium_3_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_dilithium_3_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_dilithium_3_length_signature;
|
|
}
|
|
}
|
|
|
|
static bool DILITHIUM2_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_dilithium_2_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_dilithium_2_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void DILITHIUM2_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_dilithium_2_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_dilithium_2_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_dilithium_2_length_signature;
|
|
}
|
|
}
|
|
|
|
|
|
static bool DILITHIUM5_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_dilithium_5_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_dilithium_5_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void DILITHIUM5_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_dilithium_5_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_dilithium_5_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_dilithium_5_length_signature;
|
|
}
|
|
}
|
|
|
|
//-----
|
|
|
|
static bool MLDSA44_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_ml_dsa_44_ipd_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_ml_dsa_44_ipd_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void MLDSA44_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_ml_dsa_44_ipd_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_ml_dsa_44_ipd_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_ml_dsa_44_ipd_length_signature;
|
|
}
|
|
}
|
|
|
|
static bool MLDSA65_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_ml_dsa_65_ipd_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_ml_dsa_65_ipd_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void MLDSA65_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_ml_dsa_65_ipd_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_ml_dsa_65_ipd_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_ml_dsa_65_ipd_length_signature;
|
|
}
|
|
}
|
|
|
|
static bool MLDSA87_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_ml_dsa_87_ipd_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_ml_dsa_87_ipd_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void MLDSA87_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_ml_dsa_87_ipd_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_ml_dsa_87_ipd_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_ml_dsa_87_ipd_length_signature;
|
|
}
|
|
}
|
|
|
|
|
|
// ------
|
|
static bool FALCON512_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_falcon_512_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_falcon_512_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void FALCON512_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_falcon_512_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_falcon_512_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_falcon_512_length_signature;
|
|
}
|
|
}
|
|
|
|
static bool FALCON1024_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_falcon_1024_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_falcon_1024_verify failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void FALCON1024_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_falcon_1024_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
fprintf(stderr, "ERROR: OQS_SIG_falcon_1024_sign failed!\n");
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_falcon_1024_length_signature;
|
|
}
|
|
}
|
|
|
|
static bool SPHINCSSHA2128FSIMPLE_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_sha2_128f_simple_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void SPHINCSSHA2128FSIMPLE_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_sha2_128f_simple_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_sphincs_sha2_128f_simple_length_signature;
|
|
}
|
|
}
|
|
|
|
static bool SPHINCSSHA2128SSIMPLE_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_sha2_128s_simple_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void SPHINCSSHA2128SSIMPLE_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_sha2_128s_simple_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_sphincs_sha2_128s_simple_length_signature;
|
|
}
|
|
}
|
|
|
|
static bool SPHINCSSHAKE128FSIMPLE_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_shake_128f_simple_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void SPHINCSSHAKE128FSIMPLE_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_shake_128f_simple_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_sphincs_shake_128f_simple_length_signature;
|
|
}
|
|
}
|
|
/*
|
|
static bool SPHINCSSHA2192FSIMPLE_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_sha2_192f_simple_verify((uint8_t*) CERT->val, CERT->len, (uint8_t*) SIG->val, SIG->len, (uint8_t*) PUBKEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void SPHINCSSHA2192FSIMPLE_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
OQS_STATUS rc = OQS_SIG_sphincs_sha2_192f_simple_sign( (uint8_t*) SIG->val, (size_t*) SIG->len, (uint8_t*) MESS->val, (size_t) MESS->len, (uint8_t*) KEY->val);
|
|
if (rc != OQS_SUCCESS) {
|
|
SIG->len=0;
|
|
}
|
|
else{
|
|
SIG->len=OQS_SIG_sphincs_sha2_192s_simple_length_signature;
|
|
}
|
|
}
|
|
*/
|
|
//--------------------------------------------------------------------------
|
|
#endif
|
|
|
|
// RSA 2048-bit PKCS1.5 signature verification
|
|
static bool RSA_2048_PKCS15_VERIFY(int sha,octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
bool res;
|
|
char p1[RFS_RSA2048];
|
|
octet P1={0,sizeof(p1),p1};
|
|
char p2[RFS_RSA2048];
|
|
octet P2={0,sizeof(p2),p2};
|
|
|
|
octet MC_CERT=octad_to_octet(CERT);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
|
|
RSA2048::rsa_public_key PK;
|
|
PK.e = 65537; // assuming this!
|
|
RSA2048::RSA_fromOctet(PK.n, &MC_PUBKEY);
|
|
RSA2048::RSA_ENCRYPT(&PK, &MC_SIG, &P2);
|
|
PKCS15(sha, &MC_CERT, &P1);
|
|
res=OCT_comp(&P1, &P2);
|
|
if (!res)
|
|
{ // check alternate PKCS1.5 encoding
|
|
PKCS15b(sha, &MC_CERT, &P1);
|
|
res=OCT_comp(&P1, &P2);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// RSA 4096-bit PKCS1.5 signature verification
|
|
static bool RSA_4096_PKCS15_VERIFY(int sha,octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
bool res;
|
|
char p1[RFS_RSA4096];
|
|
octet P1={0,sizeof(p1),p1};
|
|
char p2[RFS_RSA4096];
|
|
octet P2={0,sizeof(p2),p2};
|
|
|
|
octet MC_CERT=octad_to_octet(CERT);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
|
|
RSA4096::rsa_public_key PK;
|
|
PK.e = 65537; // assuming this!
|
|
RSA4096::RSA_fromOctet(PK.n, &MC_PUBKEY);
|
|
RSA4096::RSA_ENCRYPT(&PK, &MC_SIG, &P2);
|
|
PKCS15(sha, &MC_CERT, &P1);
|
|
res=OCT_comp(&P1, &P2);
|
|
if (!res)
|
|
{ // check alternate PKCS1.5 encoding
|
|
PKCS15b(sha, &MC_CERT, &P1);
|
|
res=OCT_comp(&P1, &P2);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static bool RSA_PKCS15_VERIFY(int sha,octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
if (PUBKEY->len==RFS_RSA2048)
|
|
return RSA_2048_PKCS15_VERIFY(sha,CERT,SIG,PUBKEY);
|
|
if (PUBKEY->len==RFS_RSA4096)
|
|
return RSA_4096_PKCS15_VERIFY(sha,CERT,SIG,PUBKEY);
|
|
return false;
|
|
}
|
|
|
|
// RSA 2048-bit PSS-RSAE signature verification
|
|
static bool RSA_2048_PSS_RSAE_VERIFY(int sha,octad *MESS,octad *SIG,octad *PUBKEY)
|
|
{
|
|
char p[RFS_RSA2048];
|
|
octet P={0,sizeof(p),p};
|
|
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
|
|
RSA2048::rsa_public_key PK;
|
|
PK.e = 65537;
|
|
RSA2048::RSA_fromOctet(PK.n, &MC_PUBKEY);
|
|
RSA2048::RSA_ENCRYPT(&PK, &MC_SIG, &P);
|
|
if (PSS_VERIFY(sha,&MC_MESS,&P))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
// RSA 4096-bit PSS-RSAE signature verification
|
|
static bool RSA_4096_PSS_RSAE_VERIFY(int sha,octad *MESS,octad *SIG,octad *PUBKEY)
|
|
{
|
|
char p[RFS_RSA4096];
|
|
octet P={0,sizeof(p),p};
|
|
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
|
|
RSA4096::rsa_public_key PK;
|
|
PK.e = 65537;
|
|
RSA4096::RSA_fromOctet(PK.n, &MC_PUBKEY);
|
|
RSA4096::RSA_ENCRYPT(&PK, &MC_SIG, &P);
|
|
if (PSS_VERIFY(sha,&MC_MESS,&P))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
static bool RSA_PSS_RSAE_VERIFY(int sha,octad *MESS,octad *SIG,octad *PUBKEY)
|
|
{
|
|
if (PUBKEY->len==RFS_RSA2048)
|
|
return RSA_2048_PSS_RSAE_VERIFY(sha,MESS,SIG,PUBKEY);
|
|
if (PUBKEY->len==RFS_RSA4096)
|
|
return RSA_4096_PSS_RSAE_VERIFY(sha,MESS,SIG,PUBKEY);
|
|
return false;
|
|
}
|
|
|
|
// Curve SECP256R1 elliptic curve ECDSA verification
|
|
static bool SECP256R1_ECDSA_VERIFY(int sha,octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
int res;
|
|
|
|
octet MC_CERT=octad_to_octet(CERT);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
|
|
res=NIST256::ECP_PUBLIC_KEY_VALIDATE(&MC_PUBKEY);
|
|
if (res!=0) return false;
|
|
|
|
char r[32];
|
|
octet R={0,sizeof(r),r};
|
|
char s[32];
|
|
octet S={0,sizeof(s),s};
|
|
int siglen=SIG->len/2;
|
|
for (int i=0;i<siglen;i++)
|
|
{
|
|
OCT_jbyte(&R,MC_SIG.val[i],1);
|
|
OCT_jbyte(&S,MC_SIG.val[i+siglen],1);
|
|
}
|
|
|
|
res=NIST256::ECP_VP_DSA(sha, &MC_PUBKEY, &MC_CERT, &R, &S);
|
|
if (res!=0) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Curve SECP384R1 elliptic curve ECDSA verification
|
|
|
|
static bool SECP384R1_ECDSA_VERIFY(int sha,octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
int res;
|
|
|
|
octet MC_CERT=octad_to_octet(CERT);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
|
|
res=NIST384::ECP_PUBLIC_KEY_VALIDATE(&MC_PUBKEY);
|
|
if (res!=0) return false;
|
|
|
|
char r[48];
|
|
octet R={0,sizeof(r),r};
|
|
char s[48];
|
|
octet S={0,sizeof(s),s};
|
|
int siglen=SIG->len/2;
|
|
for (int i=0;i<siglen;i++)
|
|
{
|
|
OCT_jbyte(&R,MC_SIG.val[i],1);
|
|
OCT_jbyte(&S,MC_SIG.val[i+siglen],1);
|
|
}
|
|
|
|
res=NIST384::ECP_VP_DSA(sha, &MC_PUBKEY, &MC_CERT, &R, &S);
|
|
if (res!=0) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool Ed25519_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
octet MC_CERT=octad_to_octet(CERT);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
return Ed25519::EDDSA_VERIFY(false,&MC_PUBKEY,NULL,&MC_CERT,&MC_SIG);
|
|
}
|
|
|
|
static bool Ed448_VERIFY(octad *CERT,octad *SIG,octad *PUBKEY)
|
|
{
|
|
octet MC_CERT=octad_to_octet(CERT);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
octet MC_PUBKEY=octad_to_octet(PUBKEY);
|
|
return Ed448::EDDSA_VERIFY(false,&MC_PUBKEY,NULL,&MC_CERT,&MC_SIG);
|
|
}
|
|
|
|
// Use Curve SECP256R1 ECDSA to digitally sign a message using a private key
|
|
static void SECP256R1_ECDSA_SIGN(int sha,octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_KEY=octad_to_octet(KEY);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
|
|
char r[32];
|
|
octet R={0,sizeof(r),r};
|
|
char s[32];
|
|
octet S={0,sizeof(s),s};
|
|
|
|
NIST256::ECP_SP_DSA(sha, &RNG, NULL, &MC_KEY, &MC_MESS, &R, &S);
|
|
|
|
OCT_copy(&MC_SIG,&R);
|
|
OCT_joctet(&MC_SIG,&S);
|
|
|
|
SIG->len=MC_SIG.len;
|
|
}
|
|
|
|
// Use Curve SECP384R1 ECDSA to digitally sign a message using a private key
|
|
static void SECP384R1_ECDSA_SIGN(int sha,octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_KEY=octad_to_octet(KEY);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
|
|
char r[48];
|
|
octet R={0,sizeof(r),r};
|
|
char s[48];
|
|
octet S={0,sizeof(s),s};
|
|
|
|
NIST384::ECP_SP_DSA(sha, &RNG, NULL, &MC_KEY, &MC_MESS, &R, &S);
|
|
|
|
OCT_copy(&MC_SIG,&R);
|
|
OCT_joctet(&MC_SIG,&S);
|
|
|
|
SIG->len=MC_SIG.len;
|
|
}
|
|
|
|
static void Ed25519_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_KEY=octad_to_octet(KEY);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
Ed25519::EDDSA_SIGNATURE(false,&MC_KEY,NULL,&MC_MESS,&MC_SIG);
|
|
SIG->len=MC_SIG.len;
|
|
}
|
|
|
|
static void Ed448_SIGN(octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_KEY=octad_to_octet(KEY);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
Ed448::EDDSA_SIGNATURE(false,&MC_KEY,NULL,&MC_MESS,&MC_SIG);
|
|
SIG->len=MC_SIG.len;
|
|
}
|
|
|
|
// Use RSA-2048 PSS-RSAE to digitally sign a message using a private key
|
|
static void RSA_2048_PSS_RSAE_SIGN(int sha,octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
int len=KEY->len/5; // length of p and q
|
|
if (len!=128) return;
|
|
char p[128];
|
|
octet P={len,sizeof(p),p};
|
|
char q[128];
|
|
octet Q={len,sizeof(q),q};
|
|
char dp[128];
|
|
octet DP={len,sizeof(dp),dp};
|
|
char dq[128];
|
|
octet DQ={len,sizeof(dq),dq};
|
|
char c[128];
|
|
octet C={len,sizeof(c),c};
|
|
for (int i=0;i<len;i++)
|
|
{
|
|
p[i]=KEY->val[i];
|
|
q[i]=KEY->val[i+len];
|
|
dp[i]=KEY->val[i+2*len];
|
|
dq[i]=KEY->val[i+3*len];
|
|
c[i]=KEY->val[i+4*len];
|
|
}
|
|
RSA2048::rsa_private_key SK;
|
|
char enc[256];
|
|
octet ENC={0,sizeof(enc),enc};
|
|
RSA2048::RSA_PRIVATE_KEY_FROM_OPENSSL(&P,&Q,&DP,&DQ,&C,&SK);
|
|
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
|
|
PSS_ENCODE(sha, &MC_MESS, &RNG, &ENC);
|
|
RSA2048::RSA_DECRYPT(&SK,&ENC,&MC_SIG);
|
|
SIG->len=MC_SIG.len;
|
|
}
|
|
|
|
// Use RSA-4096 PSS-RSAE to digitally sign a message using a private key
|
|
static void RSA_4096_PSS_RSAE_SIGN(int sha,octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
int len=KEY->len/5; // length of p and q
|
|
if (len!=256) return;
|
|
char p[256];
|
|
octet P={len,sizeof(p),p};
|
|
char q[256];
|
|
octet Q={len,sizeof(q),q};
|
|
char dp[256];
|
|
octet DP={len,sizeof(dp),dp};
|
|
char dq[256];
|
|
octet DQ={len,sizeof(dq),dq};
|
|
char c[256];
|
|
octet C={len,sizeof(c),c};
|
|
for (int i=0;i<len;i++)
|
|
{
|
|
p[i]=KEY->val[i];
|
|
q[i]=KEY->val[i+len];
|
|
dp[i]=KEY->val[i+2*len];
|
|
dq[i]=KEY->val[i+3*len];
|
|
c[i]=KEY->val[i+4*len];
|
|
}
|
|
RSA4096::rsa_private_key SK;
|
|
char enc[512];
|
|
octet ENC={0,sizeof(enc),enc};
|
|
|
|
octet MC_MESS=octad_to_octet(MESS);
|
|
octet MC_SIG=octad_to_octet(SIG);
|
|
|
|
RSA4096::RSA_PRIVATE_KEY_FROM_OPENSSL(&P,&Q,&DP,&DQ,&C,&SK);
|
|
|
|
PSS_ENCODE(sha, &MC_MESS, &RNG, &ENC);
|
|
RSA4096::RSA_DECRYPT(&SK,&ENC,&MC_SIG);
|
|
SIG->len=MC_SIG.len;
|
|
}
|
|
|
|
static void RSA_PSS_RSAE_SIGN(int sha,octad *KEY,octad *MESS,octad *SIG)
|
|
{
|
|
int len=KEY->len/5;
|
|
if (len==128) RSA_2048_PSS_RSAE_SIGN(sha,KEY,MESS,SIG);
|
|
if (len==256) RSA_4096_PSS_RSAE_SIGN(sha,KEY,MESS,SIG);
|
|
}
|
|
|
|
// RFC8446: "A TLS-compliant application MUST support digital signatures with
|
|
// rsa_pkcs1_sha256 (for certificates), rsa_pss_rsae_sha256 (for
|
|
// CertificateVerify and certificates), and ecdsa_secp256r1_sha256."
|
|
|
|
// SAL signature verification
|
|
bool SAL_tlsSignatureVerify(int sigAlg,octad *BUFF,octad *SIG,octad *PUBKEY)
|
|
{
|
|
bool result;
|
|
//double start,elapsed;
|
|
//start = millis();
|
|
uint64_t start, end;
|
|
start = _rdtsc();
|
|
switch (sigAlg) {
|
|
case RSA_PKCS1_SHA256 :
|
|
result= RSA_PKCS15_VERIFY(32,BUFF,SIG,PUBKEY);
|
|
break;
|
|
case ECDSA_SECP256R1_SHA256 :
|
|
result= SECP256R1_ECDSA_VERIFY(32,BUFF,SIG,PUBKEY);
|
|
break;
|
|
case ECDSA_SECP256R1_SHA384 :
|
|
result= SECP256R1_ECDSA_VERIFY(48,BUFF,SIG,PUBKEY);
|
|
break;
|
|
case RSA_PKCS1_SHA384 :
|
|
result= RSA_PKCS15_VERIFY(48,BUFF,SIG,PUBKEY);
|
|
break;
|
|
case ECDSA_SECP384R1_SHA384 :
|
|
result= SECP384R1_ECDSA_VERIFY(48,BUFF,SIG,PUBKEY);
|
|
break;
|
|
case RSA_PKCS1_SHA512 :
|
|
result= RSA_PKCS15_VERIFY(64,BUFF,SIG,PUBKEY);
|
|
break;
|
|
case RSA_PSS_RSAE_SHA256:
|
|
result= RSA_PSS_RSAE_VERIFY(32,BUFF,SIG,PUBKEY);
|
|
break;
|
|
case ED25519:
|
|
result= Ed25519_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case ED448:
|
|
result= Ed448_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
|
|
// JS doplnenie novych PQ algoritmov
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
case DILITHIUM2:
|
|
result= DILITHIUM2_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case DILITHIUM3:
|
|
result= DILITHIUM3_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case DILITHIUM5:
|
|
result= DILITHIUM5_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case MLDSA44:
|
|
result= MLDSA44_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case MLDSA65:
|
|
result= MLDSA65_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case MLDSA87:
|
|
result= MLDSA87_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case FALCON512:
|
|
result= FALCON512_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case FALCON1024:
|
|
result= FALCON1024_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case SPHINCSSHA2128FSIMPLE:
|
|
result= SPHINCSSHA2128FSIMPLE_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case SPHINCSSHA2128SSIMPLE:
|
|
result= SPHINCSSHA2128SSIMPLE_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
case SPHINCSSHAKE128FSIMPLE:
|
|
result= SPHINCSSHAKE128FSIMPLE_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
/*
|
|
case SPHINCSSHA2192FSIMPLE:
|
|
result= SPHINCSSHA2192FSIMPLE_VERIFY(BUFF,SIG,PUBKEY);
|
|
break;
|
|
*/
|
|
#endif
|
|
default:
|
|
result=false;
|
|
}
|
|
//elapsed=(millis()-start);
|
|
//printf(" Verification= %.2lf ms\n", elapsed);
|
|
|
|
end = _rdtsc();
|
|
uint64_t elapsed_ticks = end - start;
|
|
double elapsed_miliseconds = (double)elapsed_ticks;
|
|
|
|
// JS 3.8 je frekvencia pouziteho CPU, 1e6 transformuje hodnotu citacu na ms
|
|
printf("Elapsed time: %.2f ms\n", elapsed_miliseconds / (3.8 * 1e6));
|
|
return result;
|
|
}
|
|
|
|
// Form Transcript Signature
|
|
void SAL_tlsSignature(int sigAlg,octad *KEY,octad *TRANS,octad *SIG)
|
|
{ // probably need to support more cases
|
|
//int start,elapsed;
|
|
//start = millis();
|
|
switch (sigAlg)
|
|
{
|
|
case RSA_PSS_RSAE_SHA256:
|
|
RSA_PSS_RSAE_SIGN(32,KEY,TRANS,SIG);
|
|
break;
|
|
case ED25519:
|
|
Ed25519_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case ED448:
|
|
Ed448_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case ECDSA_SECP256R1_SHA256:
|
|
SECP256R1_ECDSA_SIGN(32,KEY,TRANS,SIG);
|
|
break;
|
|
case ECDSA_SECP256R1_SHA384:
|
|
SECP256R1_ECDSA_SIGN(48,KEY,TRANS,SIG);
|
|
break;
|
|
case ECDSA_SECP384R1_SHA384:
|
|
SECP384R1_ECDSA_SIGN(48,KEY,TRANS,SIG);
|
|
break;
|
|
|
|
// JS doplnenie novych PQ algoritmov
|
|
#if CRYPTO_SETTING>=POST_QUANTUM
|
|
case DILITHIUM2:
|
|
DILITHIUM2_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case DILITHIUM3:
|
|
DILITHIUM3_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case DILITHIUM5:
|
|
DILITHIUM5_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case MLDSA44:
|
|
MLDSA44_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case MLDSA65:
|
|
MLDSA65_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case MLDSA87:
|
|
MLDSA87_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case FALCON512:
|
|
FALCON512_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case FALCON1024:
|
|
FALCON1024_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case SPHINCSSHA2128FSIMPLE:
|
|
SPHINCSSHA2128FSIMPLE_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case SPHINCSSHA2128SSIMPLE:
|
|
SPHINCSSHA2128SSIMPLE_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
case SPHINCSSHAKE128FSIMPLE:
|
|
SPHINCSSHAKE128FSIMPLE_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
/*
|
|
case SPHINCSSHA2192FSIMPLE:
|
|
SPHINCSSHA2192FSIMPLE_SIGN(KEY,TRANS,SIG);
|
|
break;
|
|
*/
|
|
#endif
|
|
}
|
|
//elapsed=(millis()-start);
|
|
//printf(" Signature= %d\n", elapsed);
|
|
} |