Commit 0e0f3acf authored by manastasova's avatar manastasova
Browse files

Add all tests for randomized qhkex

parent 3bf56800
Loading
Loading
Loading
Loading
+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.
 
@@ -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 ###     
+212 −0
Original line number Diff line number Diff line
@@ -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
+4 −0
Original line number Diff line number Diff line
@@ -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_*/
+882 −140

File changed.

Preview size limit exceeded, changes collapsed.

+19 −19
Original line number Diff line number Diff line
@@ -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                                      */
@@ -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                                                              */
@@ -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)
{
@@ -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)
{
@@ -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)
@@ -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 */
@@ -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 */
@@ -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    */
@@ -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    */
@@ -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    */
@@ -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    */
@@ -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    */
@@ -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    */