/* * 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 #pragma intrinsic(__rdtsc) #if CRYPTO_SETTING>=POST_QUANTUM // JS post-kvantove algoritmy pridane z kniznice liboqs #include #include #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;ival[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;istate),b[i]); } if (h->htype==TLS_SHA384_T) { for (i=0;istate),b[i]); } if (h->htype==TLS_SHA512_T) { for (i=0;istate),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;ilen;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;ilen/2; for (int i=0;ilen=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;ival[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;ival[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_microseconds = (double)elapsed_ticks; // JS 3.8 je frekvencia pouziteho CPU, 1e6 transformuje hodnotu citacu na ms printf("Elapsed time: %.2f microseconds\n", elapsed_microseconds / (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); }