Loading README.md +14 −5 Original line number Diff line number Diff line ## TS 103 744 Quantum-safe Hybrid Key Exchanges ## Informative reference implementation as reported in Annex D of ETSI TS 103 744, Informative reference implementation as reported in Annex C of ETSI TS 103 744, "CYBER; Quantum-safe Hybrid Key Exchanges. The code is not intended for production use. It is intended to be a reference implementation for test. Loading @@ -14,11 +14,20 @@ This is not intended for production use. It is intended to be a reference implementation for test vectors for the specification. git clone ssh://git.amazon.com/pkg/Etsi-hkex-test git checkout ### Build instructions ### This library requires OpenSSL version 3.x.x libcrypto. This library requires OpenSSL version 3.2.4-dev libcrypto. gcc -Wall -o etsi-hkex-test main.c qshkex.c -lcrypto To clone and build dependencies (openssl, liboqs, and oqs-provider), run: make To build and run etsi-hkex-test: make run Or: gcc -Wall -o etsi-hkex-test main.c crypto.c qshkex.c -lcrypto -loqs ./etsi-hkex-test ### License ### Loading crypto.c +212 −0 Original line number Diff line number Diff line Loading @@ -208,3 +208,215 @@ int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2len } return rval; } int test_qhkex_rand_ecdh(int curve, uint8_t *pubA, size_t *PA1length, uint8_t *pubB, size_t *PB1length, uint8_t *ss, uint32_t *ss_len) { int rval = FAILURE; EVP_PKEY_CTX *ctxA = NULL, *ctxB = NULL; EVP_PKEY *pkeyA = NULL, *pkeyB = NULL; uint8_t ssB[MAX_KEY_BYTE_LEN]; size_t secret_lenA = 0, secret_lenB = 0; size_t pubA_len = 0, pubB_len = 0; do { // Create entity A keys if (curve == EVP_PKEY_X25519 || curve == EVP_PKEY_X448) { if (!(ctxA = EVP_PKEY_CTX_new_id(curve, NULL))) { break; } } else { if (!(ctxA = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) { break; } } if (EVP_PKEY_keygen_init(ctxA) <= 0) { break; } if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctxA, curve) <= 0) { break; } } if (EVP_PKEY_keygen(ctxA, &pkeyA) <= 0) { break; } if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { if (EVP_PKEY_get_octet_string_param(pkeyA, "pub", pubA, MAX_KEY_BYTE_LEN, &pubA_len) <=0 ) { break; } } else { if (EVP_PKEY_get_raw_public_key(pkeyA, pubA, &pubA_len) <= 0) { break; } } *PA1length = pubA_len; // Create entity B keys if (curve == EVP_PKEY_X25519 || curve == EVP_PKEY_X448) { if (!(ctxB = EVP_PKEY_CTX_new_id(curve, NULL))) { break; } } else { if (!(ctxB = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) { break; } } if (EVP_PKEY_keygen_init(ctxB) <= 0) { break; } if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctxB, curve) <= 0) { break; } if (EVP_PKEY_keygen(ctxB, &pkeyB) <= 0) { break; } if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { if (EVP_PKEY_get_octet_string_param(pkeyB, "pub", pubB, MAX_KEY_BYTE_LEN, &pubB_len) <= 0) { break; } } else { if (EVP_PKEY_get_raw_public_key(pkeyB, pubB, &pubB_len) <= 0) { break; } } *PB1length = pubB_len; // Derive entity A shared secret ctxA = EVP_PKEY_CTX_new(pkeyA, NULL); if (!ctxA) { break; } if (EVP_PKEY_derive_init(ctxA) <= 0) { break; } if (EVP_PKEY_derive_set_peer(ctxA, pkeyB) <= 0) { break; } if (EVP_PKEY_derive(ctxA, NULL, &secret_lenA) <= 0) { break; } if (EVP_PKEY_derive(ctxA, ss, &secret_lenA) <= 0) { break; } // Derive entity B shared secret ctxB = EVP_PKEY_CTX_new(pkeyB, NULL); if (!ctxB) { break; } if (EVP_PKEY_derive_init(ctxB) <= 0) { break; } if (EVP_PKEY_derive_set_peer(ctxB, pkeyA) <= 0) { break; } if (EVP_PKEY_derive(ctxB, NULL, &secret_lenB) <= 0) { break; } if (EVP_PKEY_derive(ctxB, ssB, &secret_lenB) <= 0) { break; } // Check if entities shared secrets match if (memcmp(ss, ssB, secret_lenB) != 0 || (secret_lenA != secret_lenB)) { break; } *ss_len = secret_lenA; rval = SUCCESS; } while (0); if (ctxA) { EVP_PKEY_CTX_free(ctxA); } if (ctxB) { EVP_PKEY_CTX_free(ctxB); } if (pkeyA) { EVP_PKEY_free(pkeyA); } if (pkeyB) { EVP_PKEY_free(pkeyB); } return rval; } int test_qhkex_rand_mlkem(const char * kem, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len) { int rval = FAILURE; size_t pubA_len = OQS_KEM_ml_kem_1024_length_public_key; size_t ss_out_len = OQS_KEM_ml_kem_1024_length_shared_secret; size_t ciphertext_len = OQS_KEM_ml_kem_1024_length_ciphertext; uint8_t shared_secretB[OQS_KEM_ml_kem_1024_length_shared_secret]; EVP_PKEY_CTX *pkey_ctx = NULL, *encaps_ctx = NULL, *decaps_ctx = NULL; EVP_PKEY *keypair = NULL; OSSL_PROVIDER *oqs_provider = NULL; OSSL_LIB_CTX *libctx = NULL; do { if (!(libctx = OSSL_LIB_CTX_new())) { break; } if (!(oqs_provider = OSSL_PROVIDER_load(libctx, "oqsprovider"))) { break; } if (!(pkey_ctx = EVP_PKEY_CTX_new_from_name(libctx, kem, NULL))) { break; } if (EVP_PKEY_keygen_init(pkey_ctx) <= 0) { break; } if (EVP_PKEY_keygen(pkey_ctx, &keypair) <= 0) { break; } if (EVP_PKEY_get_octet_string_param(keypair, "pub", pubA, OQS_KEM_ml_kem_1024_length_public_key, &pubA_len) <= 0) { break; } *PA2length = pubA_len; if (!(encaps_ctx = EVP_PKEY_CTX_new(keypair, NULL))) { break; } if (EVP_PKEY_encapsulate_init(encaps_ctx, NULL) <= 0) { break; } if (EVP_PKEY_encapsulate(encaps_ctx, NULL, &ciphertext_len, NULL, &ss_out_len) <= 0) { break; } *CTB2length = ciphertext_len; if (EVP_PKEY_encapsulate(encaps_ctx, ctB, &ciphertext_len, ss, &ss_out_len) <= 0) { break; } if (!(decaps_ctx = EVP_PKEY_CTX_new(keypair, NULL))) { break; } if (EVP_PKEY_decapsulate_init(decaps_ctx, NULL) <= 0) { break; } if (EVP_PKEY_decapsulate(decaps_ctx, shared_secretB, &ss_out_len, ctB, ciphertext_len) <= 0) { break; } if (memcmp(ss, shared_secretB, ss_out_len) != 0) { break; } *ss_len = ss_out_len; rval = SUCCESS; } while (0); if (pkey_ctx) { EVP_PKEY_CTX_free(pkey_ctx); } if (encaps_ctx) { EVP_PKEY_CTX_free(encaps_ctx); } if (decaps_ctx) { EVP_PKEY_CTX_free(decaps_ctx); } if (keypair) { EVP_PKEY_free(keypair); } if (oqs_provider) { OSSL_PROVIDER_unload(oqs_provider); } if (libctx) { OSSL_LIB_CTX_free(libctx); } return rval; } No newline at end of file crypto.h +4 −0 Original line number Diff line number Diff line Loading @@ -32,4 +32,8 @@ int test_qhkex_derand_ecdh(const int curve, const char *priv_dataA, const char * uint8_t *ss, uint32_t *ss_len); int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len); int test_qhkex_rand_ecdh(int curve, uint8_t *pubA, size_t *PA1length, uint8_t *pubB, size_t *PB1length, uint8_t *ss, uint32_t *ss_len); int test_qhkex_rand_mlkem(const char * kem, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len); #endif /*_QS_H_CRYPTO_KEX_H_*/ main.c +882 −140 File changed.Preview size limit exceeded, changes collapsed. Show changes qshkex.c +19 −19 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ void *my_memcpy(void *dst, const void *src, size_t byte_len) } return memcpy(dst, src, byte_len); } /* Implements the kdf concatenate-based formatting function, see Section 7.2.2 */ /* Implements KDF concatenate-based formatting function, see Section 7.2.2 */ /* Input: const uint8_t * arg1, arg2, arg3 */ /* Input: const uint32_t a1length, a2length, a3length */ /* Output: uint8_t *kdf_context, uint32_t *clength */ Loading Loading @@ -62,7 +62,7 @@ int cb_f(uint8_t *kdf_context, uint32_t *clength, const uint8_t *arg1, } while (0); return rval; } /* Implements the kdf concatenate-and-hash-based formatting function, see Section 7.2.3 */ /* Implements KDF concatenate-and-hash-based formatting function, see Section 7.2.3 */ /* Input: const uint8_t * arg1, arg2, arg3 */ /* Input: const uint32_t a1length, a2length, a3length */ /* Input: const EVP_MD *md_type */ Loading Loading @@ -121,12 +121,12 @@ int cahb_f(const EVP_MD *md_type, uint8_t *kdf_context, uint32_t *clength, const } return rval; } /* Implements the HMAC KDF function from Section 7.4.2 */ /* Implements HKDF KDF function from Section 7.4.2 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ /* Functionality: key_material = HMAC(secret, label, context, length) */ /* Functionality: key_material = HKDF(secret, label, context, length) */ int kdf_hkdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) { Loading Loading @@ -171,12 +171,12 @@ int kdf_hkdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, co } return rval; } /* Implements the HMAC KDF function from Section 7.4.2 */ /* Implements HMAC KDF function from Section 7.4.3 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ /* Functionality: key_material = HMAC(secret, label, context, length) */ /* Functionality: key_material = HMAC(label, secret || context) */ int kdf_hmac(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) { Loading Loading @@ -220,12 +220,12 @@ int kdf_hmac(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, co } return rval; } /* Implements the KMAC KDF function from Section 7.4.3 */ /* Implements KMAC KDF function from Section 7.4.4 */ /* Input: const char *kmac */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ /* Functionality: key_material = KMAC#(label, counter || secret || context, length, "KDF") */ /* Functionality: key_material = KMAC#(label, counter || secret || context, length * 8, "KDF") */ /* Functionality: key_material = SSKDF_kmac(secret, label, context, length) */ int kdf_kmac(const char *kmac, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) Loading Loading @@ -268,7 +268,7 @@ int kdf_kmac(const char *kmac, uint8_t *key_material, uint32_t *klength, const u } return rval; } /* Implements the HMAC prf function from Section 7.3.2 */ /* Implements HMAC PRF function from Section 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *ki, *MAi, *MBi */ /* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ Loading Loading @@ -330,7 +330,7 @@ int prf_hmac(const EVP_MD *md_type, uint8_t *output, uint32_t *olength, const ui } return rval; } /* Implements the KMAC PRF function from Section 7.3.3 */ /* Implements KMAC PRF function from Section 7.3.3 */ /* Input: const char *kmac */ /* Input: const uint8_t *secret, *ki, *MAi, *MBi */ /* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ Loading Loading @@ -388,7 +388,7 @@ int prf_kmac(const char *kmac, uint8_t *output, uint32_t *olength, const uint8_t } return rval; } /* Implements the function Concatenation HKDF KDF from Section 8.2 */ /* Implements function CatKDF from Section 8.2 using HKDF KDF as described in Section 7.4.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ Loading Loading @@ -433,7 +433,7 @@ int hkex_concat_hkdf(const EVP_MD *md_type, uint8_t *key_material, const uint32_ } while (0); return rval; } /* Implements the function Concatenation HMAC KDF from Section 8.2 */ /* Implements function CatKDF from Section 8.2 using HMAC KDF as described in Section 7.4.3 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ Loading Loading @@ -478,7 +478,7 @@ int hkex_concat_hmac(const EVP_MD *md_type, uint8_t *key_material, const uint32_ } while (0); return rval; } /* Implements the function Concatenation KMAC KDF from Section 8.2 */ /* Implements function CatKDF from Section 8.2 using KMAC KDF as described in Section 7.4.4 */ /* Input: const char *kmac */ /* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, ilength, llength */ Loading Loading @@ -521,7 +521,7 @@ int hkex_concat_kmac(const char *kmac, uint8_t *key_material, const uint32_t kle } while (0); return rval; } /* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ /* Implements function CasKDF from Section 8.3 using HKDF KDF and HMAC PRF as described in Sections 7.4.2 and 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ Loading Loading @@ -572,7 +572,7 @@ int hkex_cascade_hkdf(const EVP_MD *md_type, uint8_t *chain_secret, const uint32 } while (0); return rval; } /* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ /* Implements function CasKDF from Section 8.3 using HMAC KDF and HMAC PRF as described in Sections 7.4.3 and 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ Loading Loading @@ -623,7 +623,7 @@ int hkex_cascade_hmac(const EVP_MD *md_type, uint8_t *chain_secret, const uint32 } while (0); return rval; } /* Implements the function Cascade KMAC KDF from Section 8.3 */ /* Implements function CasKDF from Section 8.3 using KMAC KDF and KMAC PRF as described in Sections 7.4.4 and 7.3.3 */ /* Input: const char *kmac */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ Loading Loading
README.md +14 −5 Original line number Diff line number Diff line ## TS 103 744 Quantum-safe Hybrid Key Exchanges ## Informative reference implementation as reported in Annex D of ETSI TS 103 744, Informative reference implementation as reported in Annex C of ETSI TS 103 744, "CYBER; Quantum-safe Hybrid Key Exchanges. The code is not intended for production use. It is intended to be a reference implementation for test. Loading @@ -14,11 +14,20 @@ This is not intended for production use. It is intended to be a reference implementation for test vectors for the specification. git clone ssh://git.amazon.com/pkg/Etsi-hkex-test git checkout ### Build instructions ### This library requires OpenSSL version 3.x.x libcrypto. This library requires OpenSSL version 3.2.4-dev libcrypto. gcc -Wall -o etsi-hkex-test main.c qshkex.c -lcrypto To clone and build dependencies (openssl, liboqs, and oqs-provider), run: make To build and run etsi-hkex-test: make run Or: gcc -Wall -o etsi-hkex-test main.c crypto.c qshkex.c -lcrypto -loqs ./etsi-hkex-test ### License ### Loading
crypto.c +212 −0 Original line number Diff line number Diff line Loading @@ -208,3 +208,215 @@ int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2len } return rval; } int test_qhkex_rand_ecdh(int curve, uint8_t *pubA, size_t *PA1length, uint8_t *pubB, size_t *PB1length, uint8_t *ss, uint32_t *ss_len) { int rval = FAILURE; EVP_PKEY_CTX *ctxA = NULL, *ctxB = NULL; EVP_PKEY *pkeyA = NULL, *pkeyB = NULL; uint8_t ssB[MAX_KEY_BYTE_LEN]; size_t secret_lenA = 0, secret_lenB = 0; size_t pubA_len = 0, pubB_len = 0; do { // Create entity A keys if (curve == EVP_PKEY_X25519 || curve == EVP_PKEY_X448) { if (!(ctxA = EVP_PKEY_CTX_new_id(curve, NULL))) { break; } } else { if (!(ctxA = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) { break; } } if (EVP_PKEY_keygen_init(ctxA) <= 0) { break; } if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctxA, curve) <= 0) { break; } } if (EVP_PKEY_keygen(ctxA, &pkeyA) <= 0) { break; } if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { if (EVP_PKEY_get_octet_string_param(pkeyA, "pub", pubA, MAX_KEY_BYTE_LEN, &pubA_len) <=0 ) { break; } } else { if (EVP_PKEY_get_raw_public_key(pkeyA, pubA, &pubA_len) <= 0) { break; } } *PA1length = pubA_len; // Create entity B keys if (curve == EVP_PKEY_X25519 || curve == EVP_PKEY_X448) { if (!(ctxB = EVP_PKEY_CTX_new_id(curve, NULL))) { break; } } else { if (!(ctxB = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) { break; } } if (EVP_PKEY_keygen_init(ctxB) <= 0) { break; } if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctxB, curve) <= 0) { break; } if (EVP_PKEY_keygen(ctxB, &pkeyB) <= 0) { break; } if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { if (EVP_PKEY_get_octet_string_param(pkeyB, "pub", pubB, MAX_KEY_BYTE_LEN, &pubB_len) <= 0) { break; } } else { if (EVP_PKEY_get_raw_public_key(pkeyB, pubB, &pubB_len) <= 0) { break; } } *PB1length = pubB_len; // Derive entity A shared secret ctxA = EVP_PKEY_CTX_new(pkeyA, NULL); if (!ctxA) { break; } if (EVP_PKEY_derive_init(ctxA) <= 0) { break; } if (EVP_PKEY_derive_set_peer(ctxA, pkeyB) <= 0) { break; } if (EVP_PKEY_derive(ctxA, NULL, &secret_lenA) <= 0) { break; } if (EVP_PKEY_derive(ctxA, ss, &secret_lenA) <= 0) { break; } // Derive entity B shared secret ctxB = EVP_PKEY_CTX_new(pkeyB, NULL); if (!ctxB) { break; } if (EVP_PKEY_derive_init(ctxB) <= 0) { break; } if (EVP_PKEY_derive_set_peer(ctxB, pkeyA) <= 0) { break; } if (EVP_PKEY_derive(ctxB, NULL, &secret_lenB) <= 0) { break; } if (EVP_PKEY_derive(ctxB, ssB, &secret_lenB) <= 0) { break; } // Check if entities shared secrets match if (memcmp(ss, ssB, secret_lenB) != 0 || (secret_lenA != secret_lenB)) { break; } *ss_len = secret_lenA; rval = SUCCESS; } while (0); if (ctxA) { EVP_PKEY_CTX_free(ctxA); } if (ctxB) { EVP_PKEY_CTX_free(ctxB); } if (pkeyA) { EVP_PKEY_free(pkeyA); } if (pkeyB) { EVP_PKEY_free(pkeyB); } return rval; } int test_qhkex_rand_mlkem(const char * kem, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len) { int rval = FAILURE; size_t pubA_len = OQS_KEM_ml_kem_1024_length_public_key; size_t ss_out_len = OQS_KEM_ml_kem_1024_length_shared_secret; size_t ciphertext_len = OQS_KEM_ml_kem_1024_length_ciphertext; uint8_t shared_secretB[OQS_KEM_ml_kem_1024_length_shared_secret]; EVP_PKEY_CTX *pkey_ctx = NULL, *encaps_ctx = NULL, *decaps_ctx = NULL; EVP_PKEY *keypair = NULL; OSSL_PROVIDER *oqs_provider = NULL; OSSL_LIB_CTX *libctx = NULL; do { if (!(libctx = OSSL_LIB_CTX_new())) { break; } if (!(oqs_provider = OSSL_PROVIDER_load(libctx, "oqsprovider"))) { break; } if (!(pkey_ctx = EVP_PKEY_CTX_new_from_name(libctx, kem, NULL))) { break; } if (EVP_PKEY_keygen_init(pkey_ctx) <= 0) { break; } if (EVP_PKEY_keygen(pkey_ctx, &keypair) <= 0) { break; } if (EVP_PKEY_get_octet_string_param(keypair, "pub", pubA, OQS_KEM_ml_kem_1024_length_public_key, &pubA_len) <= 0) { break; } *PA2length = pubA_len; if (!(encaps_ctx = EVP_PKEY_CTX_new(keypair, NULL))) { break; } if (EVP_PKEY_encapsulate_init(encaps_ctx, NULL) <= 0) { break; } if (EVP_PKEY_encapsulate(encaps_ctx, NULL, &ciphertext_len, NULL, &ss_out_len) <= 0) { break; } *CTB2length = ciphertext_len; if (EVP_PKEY_encapsulate(encaps_ctx, ctB, &ciphertext_len, ss, &ss_out_len) <= 0) { break; } if (!(decaps_ctx = EVP_PKEY_CTX_new(keypair, NULL))) { break; } if (EVP_PKEY_decapsulate_init(decaps_ctx, NULL) <= 0) { break; } if (EVP_PKEY_decapsulate(decaps_ctx, shared_secretB, &ss_out_len, ctB, ciphertext_len) <= 0) { break; } if (memcmp(ss, shared_secretB, ss_out_len) != 0) { break; } *ss_len = ss_out_len; rval = SUCCESS; } while (0); if (pkey_ctx) { EVP_PKEY_CTX_free(pkey_ctx); } if (encaps_ctx) { EVP_PKEY_CTX_free(encaps_ctx); } if (decaps_ctx) { EVP_PKEY_CTX_free(decaps_ctx); } if (keypair) { EVP_PKEY_free(keypair); } if (oqs_provider) { OSSL_PROVIDER_unload(oqs_provider); } if (libctx) { OSSL_LIB_CTX_free(libctx); } return rval; } No newline at end of file
crypto.h +4 −0 Original line number Diff line number Diff line Loading @@ -32,4 +32,8 @@ int test_qhkex_derand_ecdh(const int curve, const char *priv_dataA, const char * uint8_t *ss, uint32_t *ss_len); int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len); int test_qhkex_rand_ecdh(int curve, uint8_t *pubA, size_t *PA1length, uint8_t *pubB, size_t *PB1length, uint8_t *ss, uint32_t *ss_len); int test_qhkex_rand_mlkem(const char * kem, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len); #endif /*_QS_H_CRYPTO_KEX_H_*/
qshkex.c +19 −19 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ void *my_memcpy(void *dst, const void *src, size_t byte_len) } return memcpy(dst, src, byte_len); } /* Implements the kdf concatenate-based formatting function, see Section 7.2.2 */ /* Implements KDF concatenate-based formatting function, see Section 7.2.2 */ /* Input: const uint8_t * arg1, arg2, arg3 */ /* Input: const uint32_t a1length, a2length, a3length */ /* Output: uint8_t *kdf_context, uint32_t *clength */ Loading Loading @@ -62,7 +62,7 @@ int cb_f(uint8_t *kdf_context, uint32_t *clength, const uint8_t *arg1, } while (0); return rval; } /* Implements the kdf concatenate-and-hash-based formatting function, see Section 7.2.3 */ /* Implements KDF concatenate-and-hash-based formatting function, see Section 7.2.3 */ /* Input: const uint8_t * arg1, arg2, arg3 */ /* Input: const uint32_t a1length, a2length, a3length */ /* Input: const EVP_MD *md_type */ Loading Loading @@ -121,12 +121,12 @@ int cahb_f(const EVP_MD *md_type, uint8_t *kdf_context, uint32_t *clength, const } return rval; } /* Implements the HMAC KDF function from Section 7.4.2 */ /* Implements HKDF KDF function from Section 7.4.2 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ /* Functionality: key_material = HMAC(secret, label, context, length) */ /* Functionality: key_material = HKDF(secret, label, context, length) */ int kdf_hkdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) { Loading Loading @@ -171,12 +171,12 @@ int kdf_hkdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, co } return rval; } /* Implements the HMAC KDF function from Section 7.4.2 */ /* Implements HMAC KDF function from Section 7.4.3 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ /* Functionality: key_material = HMAC(secret, label, context, length) */ /* Functionality: key_material = HMAC(label, secret || context) */ int kdf_hmac(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) { Loading Loading @@ -220,12 +220,12 @@ int kdf_hmac(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, co } return rval; } /* Implements the KMAC KDF function from Section 7.4.3 */ /* Implements KMAC KDF function from Section 7.4.4 */ /* Input: const char *kmac */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ /* Functionality: key_material = KMAC#(label, counter || secret || context, length, "KDF") */ /* Functionality: key_material = KMAC#(label, counter || secret || context, length * 8, "KDF") */ /* Functionality: key_material = SSKDF_kmac(secret, label, context, length) */ int kdf_kmac(const char *kmac, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) Loading Loading @@ -268,7 +268,7 @@ int kdf_kmac(const char *kmac, uint8_t *key_material, uint32_t *klength, const u } return rval; } /* Implements the HMAC prf function from Section 7.3.2 */ /* Implements HMAC PRF function from Section 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *ki, *MAi, *MBi */ /* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ Loading Loading @@ -330,7 +330,7 @@ int prf_hmac(const EVP_MD *md_type, uint8_t *output, uint32_t *olength, const ui } return rval; } /* Implements the KMAC PRF function from Section 7.3.3 */ /* Implements KMAC PRF function from Section 7.3.3 */ /* Input: const char *kmac */ /* Input: const uint8_t *secret, *ki, *MAi, *MBi */ /* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ Loading Loading @@ -388,7 +388,7 @@ int prf_kmac(const char *kmac, uint8_t *output, uint32_t *olength, const uint8_t } return rval; } /* Implements the function Concatenation HKDF KDF from Section 8.2 */ /* Implements function CatKDF from Section 8.2 using HKDF KDF as described in Section 7.4.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ Loading Loading @@ -433,7 +433,7 @@ int hkex_concat_hkdf(const EVP_MD *md_type, uint8_t *key_material, const uint32_ } while (0); return rval; } /* Implements the function Concatenation HMAC KDF from Section 8.2 */ /* Implements function CatKDF from Section 8.2 using HMAC KDF as described in Section 7.4.3 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ Loading Loading @@ -478,7 +478,7 @@ int hkex_concat_hmac(const EVP_MD *md_type, uint8_t *key_material, const uint32_ } while (0); return rval; } /* Implements the function Concatenation KMAC KDF from Section 8.2 */ /* Implements function CatKDF from Section 8.2 using KMAC KDF as described in Section 7.4.4 */ /* Input: const char *kmac */ /* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, ilength, llength */ Loading Loading @@ -521,7 +521,7 @@ int hkex_concat_kmac(const char *kmac, uint8_t *key_material, const uint32_t kle } while (0); return rval; } /* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ /* Implements function CasKDF from Section 8.3 using HKDF KDF and HMAC PRF as described in Sections 7.4.2 and 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ Loading Loading @@ -572,7 +572,7 @@ int hkex_cascade_hkdf(const EVP_MD *md_type, uint8_t *chain_secret, const uint32 } while (0); return rval; } /* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ /* Implements function CasKDF from Section 8.3 using HMAC KDF and HMAC PRF as described in Sections 7.4.3 and 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ Loading Loading @@ -623,7 +623,7 @@ int hkex_cascade_hmac(const EVP_MD *md_type, uint8_t *chain_secret, const uint32 } while (0); return rval; } /* Implements the function Cascade KMAC KDF from Section 8.3 */ /* Implements function CasKDF from Section 8.3 using KMAC KDF and KMAC PRF as described in Sections 7.4.4 and 7.3.3 */ /* Input: const char *kmac */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ Loading