MastersThesis/PQ_TIIGER_TLS/lib/tls_sal.cpp

1730 lines
52 KiB
C++
Raw Permalink Normal View History

2024-05-12 16:20:02 +00:00
/*
* JS update 18.04.2024
* Pridana instrukcia _rdtsc() na meranie casu pri overovani certifikatov
*/
2024-04-15 09:53:30 +00:00
/*
* 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"
2024-05-12 16:20:02 +00:00
#include <intrin.h>
#pragma intrinsic(__rdtsc)
2024-04-15 09:53:30 +00:00
#if CRYPTO_SETTING>=POST_QUANTUM
// JS post-kvantove algoritmy pridane z kniznice liboqs
#include <oqs/oqs.h>
#include <oqs/oqsconfig.h>
2024-05-12 16:20:02 +00:00
2024-04-15 09:53:30 +00:00
#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
2024-05-12 16:20:02 +00:00
#if CRYPTO_SETTING>=POST_QUANTUM
2024-04-15 09:53:30 +00:00
OQS_randombytes(RNGseed, 64);
2024-05-12 16:20:02 +00:00
#else
char raw[64];
for (int i = 0; i < 64; i++) raw[i] = i; // *** should be from output of true random number generator ****
#endif
2024-04-15 09:53:30 +00:00
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();
2024-05-12 16:20:02 +00:00
uint64_t start, end;
start = _rdtsc();
2024-04-15 09:53:30 +00:00
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);
2024-05-12 16:20:02 +00:00
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));
2024-04-15 09:53:30 +00:00
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);
}