diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bcb5e95a..5c2943d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: [push, pull_request] env: - OPENSSL_BRANCH: openssl-3.4.2 + OPENSSL_BRANCH: openssl-3.6 USE_RPATH: yes PATCH_OPENSSL: 0 GOST_PROVIDER_ENABLE_ONLINE_TESTS: 1 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 73e59bf9..4a709caf 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,7 +1,7 @@ name: "CodeQL" env: - OPENSSL_BRANCH: openssl-3.4.2 + OPENSSL_BRANCH: openssl-3.6 #RPATH: "-Wl,-rpath=${PREFIX}/lib" #PREFIX: ${HOME}/opt #PATH: ${PREFIX}/bin:${PATH} diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 984c6e19..487c2932 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository_owner == 'gost-engine' || github.event_name == 'workflow_dispatch' }} env: - OPENSSL_BRANCH: openssl-3.4.2 + OPENSSL_BRANCH: openssl-3.6 USE_RPATH: yes PATCH_OPENSSL: 1 GOST_PROVIDER_ENABLE_ONLINE_TESTS: 0 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 728a3083..15149c68 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ jobs: with: repository: openssl/openssl path: openssl - ref: openssl-3.4.2 + ref: openssl-3.6 fetch-depth: 0 - run: echo "::set-output name=head::$(git -C openssl describe --always --long)" id: openssl @@ -49,7 +49,7 @@ jobs: - run: cmake --build . - name: Run tests run: | - $env:PATH = "$pwd\openssl\_dest\Program Files\OpenSSL\bin;$env:PATH" $env:OPENSSL_ENGINES = "$pwd\bin\Debug" $env:OPENSSL_MODULES = "$pwd\bin\Debug" + Copy-Item -Path "$pwd\openssl\_dest\Program Files\OpenSSL\bin\*.dll" -Destination "$pwd\bin\Debug" ctest -C Debug --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index 91e9377a..60552abf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,10 @@ if (ASAN) set(SKIP_PERL_TESTS 1) endif() +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(SKIP_PERL_TESTS 1) +endif() + set(CMAKE_C_STANDARD 90) CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME_C) CHECK_LIBRARY_EXISTS(rt clock_gettime "" HAVE_CLOCK_GETTIME_RT) @@ -322,6 +326,12 @@ if(TLS13_PATCHED_OPENSSL) set_tests_properties(mgm-with-provider PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") set_property(TARGET test_mgm APPEND PROPERTY COMPILE_DEFINITIONS ENGINE_DIR="${OUTPUT_DIRECTORY}") + + add_executable(test_tls13handshake test_tls13handshake.c) + target_link_libraries(test_tls13handshake OpenSSL::Crypto OpenSSL::SSL) + add_test(NAME test-tls13handshake-with-provider COMMAND test_tls13handshake) + set_tests_properties(test-tls13handshake-with-provider + PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}") endif() if(NOT SKIP_PERL_TESTS) diff --git a/gost_crypt.c b/gost_crypt.c index fdd38bbf..c1c8c478 100644 --- a/gost_crypt.c +++ b/gost_crypt.c @@ -251,7 +251,7 @@ GOST_cipher magma_ecb_cipher = { .do_cipher = magma_cipher_do_ecb, }; - GOST_cipher magma_mgm_cipher = { +GOST_cipher magma_mgm_cipher = { .nid = NID_undef, .template = &magma_template_cipher, .block_size = 1, @@ -264,7 +264,7 @@ GOST_cipher magma_ecb_cipher = { .ctrl = gost_magma_mgm_ctrl, .cleanup = gost_magma_mgm_cleanup, .ctx_size = sizeof(gost_mgm_ctx) - }; +}; static void magma_NID_callback (int nid) { @@ -1164,7 +1164,7 @@ static int gost_magma_mgm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_TLSTREE: { unsigned char newkey[32]; - if (gost_tlstree(NID_magma_mgm, + if (gost_tlstree(OBJ_sn2nid(SN_magma_mgm), (const unsigned char *)mctx->ks.g_ks.cctx.master_key, newkey, (const unsigned char *)ptr, mctx->tlstree_mode) > 0) { diff --git a/gost_eng.c b/gost_eng.c index ddb59d48..e1a036c0 100644 --- a/gost_eng.c +++ b/gost_eng.c @@ -331,33 +331,55 @@ static int gost_engine_destroy(ENGINE* e) { * Following is the glue that populates the ENGINE structure and that * binds it to OpenSSL libraries */ - static GOST_NID_JOB *missing_NIDs[] = { &kuznyechik_mgm_NID, &magma_mgm_NID, }; +static int create_new_nid_for_gost_nid_job(GOST_NID_JOB *job) { + int nid = OBJ_new_nid(1); + ASN1_OBJECT *obj = + ASN1_OBJECT_create(nid, NULL, 0, job->sn, job->ln); + + if (!obj || OBJ_add_object(obj) == NID_undef) { + OPENSSL_free(obj); + return 0; + } + + job->asn1 = obj; + job->callback(nid); + + return 1; +} + static int create_NIDs() { - int i; - int new_nid = OBJ_new_nid(OSSL_NELEM(missing_NIDs)); + int i, nid; + for (i = 0; i < OSSL_NELEM(missing_NIDs); i++) { GOST_NID_JOB *job = missing_NIDs[i]; - ASN1_OBJECT *obj = - ASN1_OBJECT_create(new_nid + i, NULL, 0, job->sn, job->ln); - job->asn1 = obj; - if (!obj || OBJ_add_object(obj) == NID_undef) { - OPENSSL_free(obj); + + nid = OBJ_sn2nid(job->sn); + if (nid != NID_undef) { + job->callback(nid); + continue; + } + + if (!create_new_nid_for_gost_nid_job(job)) { return 0; } - (*missing_NIDs[i]->callback)(new_nid + i); } return 1; } -static void free_NIDs() { +static void free_NIDs(void) { int i; + for (i = 0; i < OSSL_NELEM(missing_NIDs); i++) { - ASN1_OBJECT_free(missing_NIDs[i]->asn1); + GOST_NID_JOB *job = missing_NIDs[i]; + if (job->asn1) { + ASN1_OBJECT_free(job->asn1); + job->asn1 = NULL; + } } } diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 8f4cce60..962a5b90 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -1105,7 +1105,7 @@ static int gost_grasshopper_mgm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void case EVP_CTRL_TLSTREE: { unsigned char newkey[32]; - if (gost_tlstree(NID_kuznyechik_mgm, + if (gost_tlstree(OBJ_sn2nid(SN_kuznyechik_mgm), mctx->ks.gh_ks.master_key.k.b, newkey, (const unsigned char *)ptr, mctx->tlstree_mode) > 0) { diff --git a/gost_keyexpimp.c b/gost_keyexpimp.c index 8f66d60b..3a7be255 100644 --- a/gost_keyexpimp.c +++ b/gost_keyexpimp.c @@ -12,6 +12,8 @@ #include #include "gost_lcl.h" +#include "gost_gost2015.h" +#include "gost_grasshopper_cipher.h" #include "e_gost_err.h" static uint32_t be32(uint32_t host) @@ -267,51 +269,40 @@ int gost_tlstree(int cipher_nid, const unsigned char *in, unsigned char *out, unsigned char ko1[32], ko2[32]; int ret; - switch (cipher_nid) { - case NID_magma_cbc: + if (cipher_nid == NID_magma_cbc) { c1 = 0x00000000C0FFFFFF; c2 = 0x000000FEFFFFFFFF; c3 = 0x00F0FFFFFFFFFFFF; - break; - case NID_grasshopper_cbc: + } else if (cipher_nid == NID_grasshopper_cbc) { c1 = 0x00000000FFFFFFFF; c2 = 0x0000F8FFFFFFFFFF; c3 = 0xC0FFFFFFFFFFFFFF; - break; - case NID_magma_mgm: - switch (mode) { - case TLSTREE_MODE_S: // TLS_GOSTR341112_256_WITH_MAGMA_MGM_S + } else if (cipher_nid == magma_mgm_cipher.nid) { + if (mode == TLSTREE_MODE_S) { // TLS_GOSTR341112_256_WITH_MAGMA_MGM_S c1 = 0x000000fcffffffff; c2 = 0x00e0ffffffffffff; c3 = 0xffffffffffffffff; - break; - case TLSTREE_MODE_L: // TLS_GOSTR341112_256_WITH_MAGMA_MGM_L + } else if (mode == TLSTREE_MODE_L) { // TLS_GOSTR341112_256_WITH_MAGMA_MGM_L c1 = 0x000000000000e0ff; c2 = 0x000000c0ffffffff; c3 = 0x80ffffffffffffff; - break; - default: + } else { return 0; } - break; - case NID_kuznyechik_mgm: - switch (mode) { - case TLSTREE_MODE_S: // TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S + } else if (cipher_nid == grasshopper_mgm_cipher.nid) { + if (mode == TLSTREE_MODE_S) { // TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S c1 = 0x000000e0ffffffff; c2 = 0x0000ffffffffffff; c3 = 0xf8ffffffffffffff; - break; - case TLSTREE_MODE_L: // TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L + } else if (mode == TLSTREE_MODE_L) { // TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L c1 = 0x00000000000000f8; c2 = 0x00000000f0ffffff; c3 = 0x00e0ffffffffffff; - break; - default: + } else { return 0; } - break; - default: - return 0; + } else { + return 0; /* неизвестный cipher_nid */ } #ifndef L_ENDIAN BUF_reverse((unsigned char *)&seq, tlsseq, 8); diff --git a/gost_lcl.h b/gost_lcl.h index 44621fd3..e11f4437 100644 --- a/gost_lcl.h +++ b/gost_lcl.h @@ -37,32 +37,6 @@ EVP_CTRL_SET_TLSTREE_PARAMS definition in OpenSSL is expected." # define EVP_CTRL_SET_TLSTREE_PARAMS 0xFF # endif -# ifndef NID_magma_mgm -# if defined(_MSC_VER) -# pragma message("Gost-engine is built against not fully supported version of OpenSSL. \ -NID_magma_mgm definition in OpenSSL is expected. No magma mgm functionality is \ -guaranteed.") -# else -# warning "Gost-engine is built against not fully supported version of OpenSSL. \ -NID_magma_mgm definition in OpenSSL is expected. No magma mgm functionality is \ -guaranteed." -# endif -# define NID_magma_mgm ((int)(INT_MAX - 1)) -# endif - -# ifndef NID_kuznyechik_mgm -# if defined(_MSC_VER) -# pragma message("Gost-engine is built against not fully supported version of OpenSSL. \ -NID_kuznyechik_mgm definition in OpenSSL is expected. No magma mgm functionality is \ -guaranteed.") -# else -# warning "Gost-engine is built against not fully supported version of OpenSSL. \ -NID_kuznyechik_mgm definition in OpenSSL is expected. No kuznyechik mgm functionality is \ -guaranteed." -# endif -# define NID_kuznyechik_mgm ((int)(INT_MAX - 2)) -# endif - /* Control commands */ # define GOST_PARAM_CRYPT_PARAMS 0 # define GOST_PARAM_PBE_PARAMS 1 diff --git a/gost_prov_cipher.c b/gost_prov_cipher.c index ce688dff..9410e7a8 100644 --- a/gost_prov_cipher.c +++ b/gost_prov_cipher.c @@ -25,8 +25,8 @@ OSSL_CIPHER_PARAM_TLSTREE definition in OpenSSL is expected.") # else # warning "Gost-engine is built against not fully supported version of OpenSSL. \ -NID_kuznyechik_mgm definition in OpenSSL is expected. No kuznyechik mgm functionality is \ -guaranteed." +OSSL_CIPHER_PARAM_TLSTREE definition in OpenSSL is expected. TLSTREE is not supported by \ +the provider for cipher operations." # endif # define OSSL_CIPHER_PARAM_TLSTREE "tlstree" #endif @@ -37,8 +37,8 @@ guaranteed." OSSL_CIPHER_PARAM_TLSTREE_MODE definition in OpenSSL is expected.") # else # warning "Gost-engine is built against not fully supported version of OpenSSL. \ -NID_kuznyechik_mgm definition in OpenSSL is expected. No kuznyechik mgm functionality is \ -guaranteed." +OSSL_CIPHER_PARAM_TLSTREE_MODE definition in OpenSSL is expected. TLSTREE modes are not supported by \ +the provider for encryption/decryption operations. ." # endif # define OSSL_CIPHER_PARAM_TLSTREE_MODE "tlstree_mode" #endif diff --git a/patches/openssl-tls1.3.patch b/patches/openssl-tls1.3.patch index 95cfc4c5..4e3464ff 100644 --- a/patches/openssl-tls1.3.patch +++ b/patches/openssl-tls1.3.patch @@ -1,8 +1,47 @@ +diff --git a/openssl/crypto/asn1/charmap.h b/openssl/crypto/asn1/charmap.h +index ac1eb076cc2..e7ac77d88ce 100644 +--- a/openssl/crypto/asn1/charmap.h ++++ b/openssl/crypto/asn1/charmap.h +@@ -2,7 +2,7 @@ + * WARNING: do not edit! + * Generated by crypto/asn1/charmap.pl + * +- * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +diff --git a/openssl/crypto/bn/bn_prime.h b/openssl/crypto/bn/bn_prime.h +index 8a859ac02e2..3a59f58afb7 100644 +--- a/openssl/crypto/bn/bn_prime.h ++++ b/openssl/crypto/bn/bn_prime.h +@@ -2,7 +2,7 @@ + * WARNING: do not edit! + * Generated by crypto/bn/bn_prime.pl + * +- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy +diff --git a/openssl/crypto/conf/conf_def.h b/openssl/crypto/conf/conf_def.h +index 1f66a58e092..62d4fa2b8c4 100644 +--- a/openssl/crypto/conf/conf_def.h ++++ b/openssl/crypto/conf/conf_def.h +@@ -2,7 +2,7 @@ + * WARNING: do not edit! + * Generated by crypto/conf/keysets.pl + * +- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at diff --git a/openssl/crypto/evp/evp_enc.c b/openssl/crypto/evp/evp_enc.c -index f96d46f..1c657ce 100644 +index bcc507edfdc..cd08cee82b0 100644 --- a/openssl/crypto/evp/evp_enc.c +++ b/openssl/crypto/evp/evp_enc.c -@@ -1293,6 +1293,14 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +@@ -1614,6 +1614,14 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) params[0] = OSSL_PARAM_construct_octet_string( OSSL_CIPHER_PARAM_AEAD_MAC_KEY, ptr, sz); break; @@ -18,40 +57,154 @@ index f96d46f..1c657ce 100644 if (set_params) diff --git a/openssl/crypto/objects/obj_dat.h b/openssl/crypto/objects/obj_dat.h -index 4c61e96..8237adf 100644 +index 40d6f9ca4d1..38f1d346f35 100644 --- a/openssl/crypto/objects/obj_dat.h +++ b/openssl/crypto/objects/obj_dat.h -@@ -1187,7 +1187,7 @@ static const unsigned char so[8504] = { - 0x2B,0x06,0x01,0x04,0x01,0x82,0xE4,0x25,0x01, /* [ 8494] OBJ_id_kp_wisun_fan_device */ +@@ -10,7 +10,7 @@ + */ + + /* Serialized OID's */ +-static const unsigned char so[9571] = { ++static const unsigned char so[9589] = { + 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ +@@ -1353,9 +1353,11 @@ static const unsigned char so[9571] = { + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x1E, /* [ 9538] OBJ_HKDF_SHA512 */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x0D, /* [ 9549] OBJ_id_smime_ori */ + 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x0D,0x03, /* [ 9559] OBJ_id_smime_ori_kem */ ++ 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01,0x03, /* [ 9570] OBJ_magma_mgm */ ++ 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02,0x03, /* [ 9579] OBJ_kuznyechik_mgm */ }; --#define NUM_NID 1324 -+#define NUM_NID 1326 +-#define NUM_NID 1501 ++#define NUM_NID 1503 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, -@@ -2513,6 +2513,8 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { - {"id-on-hardwareModuleName", "Hardware Module Name", NID_id_on_hardwareModuleName, 8, &so[8486]}, - {"id-kp-wisun-fan-device", "Wi-SUN Alliance Field Area Network (FAN)", NID_id_kp_wisun_fan_device, 9, &so[8494]}, - {"NULL", "NULL", NID_ac_auditEntity}, -+ {"magma-mgm", "magma-mgm", NID_magma_mgm}, -+ {"kuznyechik-mgm", "kuznyechik-mgm", NID_kuznyechik_mgm}, +@@ -2858,9 +2860,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { + {"id-alg-hkdf-with-sha512", "HKDF-SHA512", NID_HKDF_SHA512, 11, &so[9538]}, + {"id-smime-ori", "id-smime-ori", NID_id_smime_ori, 10, &so[9549]}, + {"id-smime-ori-kem", "id-smime-ori-kem", NID_id_smime_ori_kem, 11, &so[9559]}, ++ {"magma-mgm", "magma-mgm", NID_magma_mgm, 9, &so[9570]}, ++ {"kuznyechik-mgm", "kuznyechik-mgm", NID_kuznyechik_mgm, 9, &so[9579]}, }; - #define NUM_SN 1315 +-#define NUM_SN 1492 ++#define NUM_SN 1494 + static const unsigned int sn_objs[NUM_SN] = { + 364, /* "AD_DVCS" */ + 419, /* "AES-128-CBC" */ +@@ -3823,6 +3827,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1012, /* "kuznyechik-ecb" */ + 1183, /* "kuznyechik-kexp15" */ + 1017, /* "kuznyechik-mac" */ ++ 1502, /* "kuznyechik-mgm" */ + 1014, /* "kuznyechik-ofb" */ + 477, /* "lastModifiedBy" */ + 476, /* "lastModifiedTime" */ +@@ -3836,6 +3841,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1187, /* "magma-ecb" */ + 1181, /* "magma-kexp15" */ + 1192, /* "magma-mac" */ ++ 1501, /* "magma-mgm" */ + 1189, /* "magma-ofb" */ + 460, /* "mail" */ + 493, /* "mailPreferenceOption" */ +@@ -4356,7 +4362,7 @@ static const unsigned int sn_objs[NUM_SN] = { + 1289, /* "zstd" */ + }; + +-#define NUM_LN 1492 ++#define NUM_LN 1494 + static const unsigned int ln_objs[NUM_LN] = { + 363, /* "AD Time Stamping" */ + 405, /* "ANSI X9.62" */ +@@ -5435,6 +5441,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 1012, /* "kuznyechik-ecb" */ + 1183, /* "kuznyechik-kexp15" */ + 1017, /* "kuznyechik-mac" */ ++ 1502, /* "kuznyechik-mgm" */ + 1014, /* "kuznyechik-ofb" */ + 1063, /* "kx-any" */ + 1039, /* "kx-dhe" */ +@@ -5460,6 +5467,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 1187, /* "magma-ecb" */ + 1181, /* "magma-kexp15" */ + 1192, /* "magma-mac" */ ++ 1501, /* "magma-mgm" */ + 1189, /* "magma-ofb" */ + 493, /* "mailPreferenceOption" */ + 467, /* "manager" */ +@@ -5852,7 +5860,7 @@ static const unsigned int ln_objs[NUM_LN] = { + 125, /* "zlib compression" */ + }; + +-#define NUM_OBJ 1349 ++#define NUM_OBJ 1351 + static const unsigned int obj_objs[NUM_OBJ] = { + 0, /* OBJ_undef 0 */ + 181, /* OBJ_iso 1 */ +@@ -6769,8 +6777,10 @@ static const unsigned int obj_objs[NUM_OBJ] = { + 1122, /* OBJ_aria_256_ccm 1 2 410 200046 1 1 39 */ + 1174, /* OBJ_magma_ctr_acpkm 1 2 643 7 1 1 5 1 1 */ + 1175, /* OBJ_magma_ctr_acpkm_omac 1 2 643 7 1 1 5 1 2 */ ++ 1501, /* OBJ_magma_mgm 1 2 643 7 1 1 5 1 3 */ + 1177, /* OBJ_kuznyechik_ctr_acpkm 1 2 643 7 1 1 5 2 1 */ + 1178, /* OBJ_kuznyechik_ctr_acpkm_omac 1 2 643 7 1 1 5 2 2 */ ++ 1502, /* OBJ_kuznyechik_mgm 1 2 643 7 1 1 5 2 3 */ + 1181, /* OBJ_magma_kexp15 1 2 643 7 1 1 7 1 1 */ + 1183, /* OBJ_kuznyechik_kexp15 1 2 643 7 1 1 7 2 1 */ + 1148, /* OBJ_id_tc26_gost_3410_2012_256_paramSetA 1 2 643 7 1 2 1 1 1 */ +diff --git a/openssl/crypto/objects/obj_mac.num b/openssl/crypto/objects/obj_mac.num +index b48d054d329..c4d5c1b301a 100644 +--- a/openssl/crypto/objects/obj_mac.num ++++ b/openssl/crypto/objects/obj_mac.num +@@ -1498,3 +1498,5 @@ HKDF_SHA384 1497 + HKDF_SHA512 1498 + id_smime_ori 1499 + id_smime_ori_kem 1500 ++magma_mgm 1501 ++kuznyechik_mgm 1502 +diff --git a/openssl/crypto/objects/objects.txt b/openssl/crypto/objects/objects.txt +index feed79b6738..ddc5d651a92 100644 +--- a/openssl/crypto/objects/objects.txt ++++ b/openssl/crypto/objects/objects.txt +@@ -1528,9 +1528,11 @@ id-tc26-algorithms 5 : id-tc26-cipher + id-tc26-cipher 1 : id-tc26-cipher-gostr3412-2015-magma + id-tc26-cipher-gostr3412-2015-magma 1 : magma-ctr-acpkm + id-tc26-cipher-gostr3412-2015-magma 2 : magma-ctr-acpkm-omac ++id-tc26-cipher-gostr3412-2015-magma 3 : magma-mgm + id-tc26-cipher 2 : id-tc26-cipher-gostr3412-2015-kuznyechik + id-tc26-cipher-gostr3412-2015-kuznyechik 1 : kuznyechik-ctr-acpkm + id-tc26-cipher-gostr3412-2015-kuznyechik 2 : kuznyechik-ctr-acpkm-omac ++id-tc26-cipher-gostr3412-2015-kuznyechik 3 : kuznyechik-mgm + + id-tc26-algorithms 6 : id-tc26-agreement + id-tc26-agreement 1 : id-tc26-agreement-gost-3410-2012-256 +diff --git a/openssl/fuzz/oids.txt b/openssl/fuzz/oids.txt +index b299cc2d64f..5c283a53cd0 100644 +--- a/openssl/fuzz/oids.txt ++++ b/openssl/fuzz/oids.txt +@@ -1349,3 +1349,5 @@ OBJ_HKDF_SHA384="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x1D" + OBJ_HKDF_SHA512="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x1E" + OBJ_id_smime_ori="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x0D" + OBJ_id_smime_ori_kem="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x0D\x03" ++OBJ_magma_mgm="\x2A\x85\x03\x07\x01\x01\x05\x01\x03" ++OBJ_kuznyechik_mgm="\x2A\x85\x03\x07\x01\x01\x05\x02\x03" diff --git a/openssl/include/openssl/evp.h b/openssl/include/openssl/evp.h -index 5466327..19c3b8e 100644 +index 61e50b266d6..a293e98215b 100644 --- a/openssl/include/openssl/evp.h +++ b/openssl/include/openssl/evp.h -@@ -439,6 +439,7 @@ OSSL_DEPRECATEDIN_3_0 int +@@ -460,6 +460,7 @@ OSSL_DEPRECATEDIN_3_0 int #define EVP_CTRL_GET_WRAP_CIPHER 0x29 /* TLSTREE key diversification */ #define EVP_CTRL_TLSTREE 0x2A -+#define EVP_CTRL_SET_TLSTREE_PARAMS 0x2B ++# define EVP_CTRL_SET_TLSTREE_PARAMS 0x2B /* Padding modes */ #define EVP_PADDING_PKCS7 1 -@@ -477,6 +478,10 @@ typedef struct { +@@ -498,6 +499,10 @@ typedef struct { /* Length of CCM8 tag for TLS */ # define EVP_CCM8_TLS_TAG_LEN 8 @@ -63,34 +216,36 @@ index 5466327..19c3b8e 100644 # define EVP_CHACHAPOLY_TLS_TAG_LEN 16 diff --git a/openssl/include/openssl/obj_mac.h b/openssl/include/openssl/obj_mac.h -index ea603c2..ea4af43 100644 +index 440ec10df67..262cad65d31 100644 --- a/openssl/include/openssl/obj_mac.h +++ b/openssl/include/openssl/obj_mac.h -@@ -4880,6 +4880,9 @@ - #define SN_kuznyechik_mac "kuznyechik-mac" - #define NID_kuznyechik_mac 1017 +@@ -4853,6 +4853,10 @@ + #define NID_magma_ctr_acpkm_omac 1175 + #define OBJ_magma_ctr_acpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_magma,2L -+#define SN_kuznyechik_mgm "kuznyechik-mgm" -+#define NID_kuznyechik_mgm 1325 ++#define SN_magma_mgm "magma-mgm" ++#define NID_magma_mgm 1501 ++#define OBJ_magma_mgm OBJ_id_tc26_cipher_gostr3412_2015_magma,3L + - #define SN_magma_ecb "magma-ecb" - #define NID_magma_ecb 1187 - -@@ -4898,6 +4901,9 @@ - #define SN_magma_mac "magma-mac" - #define NID_magma_mac 1192 + #define SN_id_tc26_cipher_gostr3412_2015_kuznyechik "id-tc26-cipher-gostr3412-2015-kuznyechik" + #define NID_id_tc26_cipher_gostr3412_2015_kuznyechik 1176 + #define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik OBJ_id_tc26_cipher,2L +@@ -4865,6 +4869,10 @@ + #define NID_kuznyechik_ctr_acpkm_omac 1178 + #define OBJ_kuznyechik_ctr_acpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,2L -+#define SN_magma_mgm "magma-mgm" -+#define NID_magma_mgm 1324 ++#define SN_kuznyechik_mgm "kuznyechik-mgm" ++#define NID_kuznyechik_mgm 1502 ++#define OBJ_kuznyechik_mgm OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,3L + - #define SN_camellia_128_cbc "CAMELLIA-128-CBC" - #define LN_camellia_128_cbc "camellia-128-cbc" - #define NID_camellia_128_cbc 751 + #define SN_id_tc26_agreement "id-tc26-agreement" + #define NID_id_tc26_agreement 991 + #define OBJ_id_tc26_agreement OBJ_id_tc26_algorithms,6L diff --git a/openssl/include/openssl/tls1.h b/openssl/include/openssl/tls1.h -index 8e9b110..8cadff9 100644 +index 50910d0e4c0..7fe69992f19 100644 --- a/openssl/include/openssl/tls1.h +++ b/openssl/include/openssl/tls1.h -@@ -658,6 +658,12 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb +@@ -664,6 +664,12 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb # define TLS1_CK_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06E # define TLS1_CK_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06F @@ -103,7 +258,7 @@ index 8e9b110..8cadff9 100644 /* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ # define TLS1_RFC_RSA_WITH_AES_128_SHA "TLS_RSA_WITH_AES_128_CBC_SHA" # define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" -@@ -850,6 +856,10 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb +@@ -856,6 +862,10 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb # define TLS1_RFC_DHE_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384" # define TLS1_RFC_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256" # define TLS1_RFC_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384" @@ -114,8 +269,21 @@ index 8e9b110..8cadff9 100644 /* +diff --git a/openssl/ssl/record/methods/recmethod_local.h b/openssl/ssl/record/methods/recmethod_local.h +index 364a3a01bbe..058a2c58123 100644 +--- a/openssl/ssl/record/methods/recmethod_local.h ++++ b/openssl/ssl/record/methods/recmethod_local.h +@@ -332,7 +332,7 @@ struct ossl_record_layer_st { + + /* Flags for GOST ciphers */ + int stream_mac; +- int tlstree; ++ uint32_t tlstree; + + /* TLSv1.3 fields */ + unsigned char *iv; /* static IV */ diff --git a/openssl/ssl/record/methods/tls13_meth.c b/openssl/ssl/record/methods/tls13_meth.c -index 6bbba84..40cbc0c 100644 +index c022d064a3e..8ec7d58cde0 100644 --- a/openssl/ssl/record/methods/tls13_meth.c +++ b/openssl/ssl/record/methods/tls13_meth.c @@ -78,6 +78,18 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, @@ -149,26 +317,64 @@ index 6bbba84..40cbc0c 100644 if (!tls_increment_sequence_ctr(rl)) { /* RLAYERfatal already called */ return 0; +diff --git a/openssl/ssl/record/methods/tls_common.c b/openssl/ssl/record/methods/tls_common.c +index 6ee265021c5..a15c6e06175 100644 +--- a/openssl/ssl/record/methods/tls_common.c ++++ b/openssl/ssl/record/methods/tls_common.c +@@ -1302,7 +1302,7 @@ tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, + } + } else if (strcmp(p->key, + OSSL_LIBSSL_RECORD_LAYER_PARAM_TLSTREE) == 0) { +- if (!OSSL_PARAM_get_int(p, &rl->tlstree)) { ++ if (!OSSL_PARAM_get_uint32(p, &rl->tlstree)) { + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } diff --git a/openssl/ssl/record/rec_layer_s3.c b/openssl/ssl/record/rec_layer_s3.c -index cce236b..48fedcb 100644 +index dac248fec8f..800a8d46fcd 100644 --- a/openssl/ssl/record/rec_layer_s3.c +++ b/openssl/ssl/record/rec_layer_s3.c -@@ -1310,6 +1310,10 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, +@@ -1255,7 +1255,8 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, + BIO *thisbio; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + const OSSL_RECORD_METHOD *meth; +- int use_etm, stream_mac = 0, tlstree = 0; ++ int use_etm, stream_mac = 0; ++ uint32_t algorithm2 = 0, tlstree = 0; + unsigned int maxfrag = (direction == OSSL_RECORD_DIRECTION_WRITE) + ? ssl_get_max_send_fragment(s) + : SSL3_RT_MAX_PLAIN_LENGTH; +@@ -1318,6 +1319,14 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, tlstree = 1; } -+ if (SSL_CONNECTION_IS_TLS13(s)) -+ tlstree = (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE_L) -+ | (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE_S); ++ if (s->s3.tmp.new_cipher != NULL) ++ algorithm2 = s->s3.tmp.new_cipher->algorithm2; ++ else if (s->session != NULL && s->session->cipher != NULL) ++ algorithm2 = s->session->cipher->algorithm2; ++ else if (s->psksession != NULL && s->psksession->cipher != NULL) ++ algorithm2 = s->psksession->cipher->algorithm2; ++ tlstree |= (algorithm2 & TLS1_TLSTREE_L) | (algorithm2 & TLS1_TLSTREE_S); + if (use_etm) *set++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_USE_ETM, &use_etm); +@@ -1327,8 +1336,8 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, + &stream_mac); + + if (tlstree) +- *set++ = OSSL_PARAM_construct_int(OSSL_LIBSSL_RECORD_LAYER_PARAM_TLSTREE, +- &tlstree); ++ *set++ = OSSL_PARAM_construct_uint32(OSSL_LIBSSL_RECORD_LAYER_PARAM_TLSTREE, ++ &tlstree); + + /* + * We only need to do this for the read side. The write side should already diff --git a/openssl/ssl/s3_lib.c b/openssl/ssl/s3_lib.c -index 86d8198..19edb89 100644 +index 226493a1615..55625589fd2 100644 --- a/openssl/ssl/s3_lib.c +++ b/openssl/ssl/s3_lib.c -@@ -146,6 +146,72 @@ static SSL_CIPHER tls13_ciphers[] = { +@@ -149,6 +149,72 @@ static SSL_CIPHER tls13_ciphers[] = { 384, }, #endif @@ -242,10 +448,10 @@ index 86d8198..19edb89 100644 /* diff --git a/openssl/ssl/ssl_ciph.c b/openssl/ssl/ssl_ciph.c -index e5d6237..78dd7de 100644 +index 2c35f31065c..ee22dd4d95f 100644 --- a/openssl/ssl/ssl_ciph.c +++ b/openssl/ssl/ssl_ciph.c -@@ -54,8 +54,10 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { +@@ -60,8 +60,10 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */ {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */ {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */ @@ -258,8 +464,8 @@ index e5d6237..78dd7de 100644 }; /* NB: make sure indices in this table matches values above */ -@@ -310,6 +312,23 @@ static int get_optional_pkey_id(const char *pkey_name) - +@@ -323,6 +325,23 @@ static int get_optional_pkey_id(const char *pkey_name) + } #endif +/* Checks to see if algorithms are fetchable */ @@ -282,7 +488,7 @@ index e5d6237..78dd7de 100644 int ssl_load_ciphers(SSL_CTX *ctx) { size_t i; -@@ -418,11 +437,14 @@ int ssl_load_ciphers(SSL_CTX *ctx) +@@ -431,11 +450,14 @@ int ssl_load_ciphers(SSL_CTX *ctx) else ctx->disabled_mac_mask |= SSL_KUZNYECHIKOMAC; @@ -300,7 +506,7 @@ index e5d6237..78dd7de 100644 ctx->disabled_auth_mask |= SSL_aGOST12; /* * Disable GOST key exchange if no GOST signature algs are available * -@@ -1827,9 +1849,15 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) +@@ -1840,9 +1862,15 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_MAGMA: enc = "MAGMA"; break; @@ -317,10 +523,10 @@ index e5d6237..78dd7de 100644 enc = "CHACHA20/POLY1305(256)"; break; diff --git a/openssl/ssl/ssl_local.h b/openssl/ssl/ssl_local.h -index 277be30..bf36ac7 100644 +index 104379e990b..eadb6e19cea 100644 --- a/openssl/ssl/ssl_local.h +++ b/openssl/ssl/ssl_local.h -@@ -153,6 +153,8 @@ +@@ -151,6 +151,8 @@ # define SSL_ARIA256GCM 0x00200000U # define SSL_MAGMA 0x00400000U # define SSL_KUZNYECHIK 0x00800000U @@ -329,18 +535,18 @@ index 277be30..bf36ac7 100644 # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) -@@ -235,7 +237,9 @@ +@@ -233,7 +235,9 @@ * TLSTREE cipher/mac key derivation from draft-smyshlyaev-tls12-gost-suites * (currently this also goes into algorithm2) */ -# define TLS1_TLSTREE 0x20000 +# define TLS1_TLSTREE 0x20000 -+# define TLS1_TLSTREE_S 0x40000 -+# define TLS1_TLSTREE_L 0x80000 ++# define TLS1_TLSTREE_S 0x80000 ++# define TLS1_TLSTREE_L 0x100000 /* Ciphersuite supported in QUIC */ # define SSL_QUIC 0x00040000U -@@ -335,31 +339,33 @@ +@@ -328,31 +332,33 @@ # define SSL_PKEY_ED448 8 # define SSL_PKEY_NUM 9 @@ -400,10 +606,10 @@ index 277be30..bf36ac7 100644 /*- * SSL_kRSA <- RSA_ENC diff --git a/openssl/ssl/statem/statem_lib.c b/openssl/ssl/statem/statem_lib.c -index a52b8af..6437f66 100644 +index 65530df7a43..fa6eff459c4 100644 --- a/openssl/ssl/statem/statem_lib.c +++ b/openssl/ssl/statem/statem_lib.c -@@ -501,10 +501,10 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt) +@@ -502,10 +502,10 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt) #ifndef OPENSSL_NO_GOST if (!SSL_USE_SIGALGS(s) && ((PACKET_remaining(pkt) == 64 @@ -414,10 +620,10 @@ index a52b8af..6437f66 100644 || (PACKET_remaining(pkt) == 128 - && EVP_PKEY_get_id(pkey) == NID_id_GostR3410_2012_512))) { + && EVP_PKEY_is_a(pkey, SN_id_GostR3410_2012_512)))) { - len = PACKET_remaining(pkt); + len = (unsigned int)PACKET_remaining(pkt); } else #endif -@@ -539,10 +539,9 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt) +@@ -540,10 +540,9 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt) } #ifndef OPENSSL_NO_GOST { @@ -431,7 +637,7 @@ index a52b8af..6437f66 100644 if ((gost_data = OPENSSL_malloc(len)) == NULL) goto err; BUF_reverse(gost_data, data, len); -@@ -1931,8 +1930,6 @@ static int is_tls13_capable(const SSL_CONNECTION *s) +@@ -1947,8 +1946,6 @@ static int is_tls13_capable(const SSL_CONNECTION *s) switch (i) { case SSL_PKEY_DSA_SIGN: case SSL_PKEY_GOST01: @@ -440,7 +646,7 @@ index a52b8af..6437f66 100644 continue; default: break; -@@ -1949,6 +1946,15 @@ static int is_tls13_capable(const SSL_CONNECTION *s) +@@ -1965,6 +1962,15 @@ static int is_tls13_capable(const SSL_CONNECTION *s) curve = ssl_get_EC_curve_nid(s->cert->pkeys[SSL_PKEY_ECC].privatekey); if (tls_check_sigalg_curve(s, curve)) return 1; @@ -457,10 +663,10 @@ index a52b8af..6437f66 100644 return 0; diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c -index bd85167..9b3b821 100644 +index 98fe2133817..3d5e85b22a7 100644 --- a/openssl/ssl/t1_lib.c +++ b/openssl/ssl/t1_lib.c -@@ -1565,14 +1565,19 @@ int ssl_setup_sigalgs(SSL_CTX *ctx) +@@ -2241,7 +2241,12 @@ int ssl_setup_sigalgs(SSL_CTX *ctx) /* Now complete cache and tls12_sigalgs list with provider sig information */ cache_idx = OSSL_NELEM(sigalg_lookup_tbl); for (i = 0; i < ctx->sigalg_list_len; i++) { @@ -471,17 +677,18 @@ index bd85167..9b3b821 100644 + goto err; + cache[cache_idx].name = si.name; + cache[cache_idx].name12 = si.sigalg_name; cache[cache_idx].sigalg = si.code_point; - tls12_sigalgs_list[cache_idx] = si.code_point; +@@ -2249,7 +2254,7 @@ int ssl_setup_sigalgs(SSL_CTX *ctx) cache[cache_idx].hash = si.hash_name?OBJ_txt2nid(si.hash_name):NID_undef; cache[cache_idx].hash_idx = ssl_get_md_idx(cache[cache_idx].hash); cache[cache_idx].sig = OBJ_txt2nid(si.sigalg_name); -- cache[cache_idx].sig_idx = i + SSL_PKEY_NUM; -+ cache[cache_idx].sig_idx = idx; +- cache[cache_idx].sig_idx = (int)(i + SSL_PKEY_NUM); ++ cache[cache_idx].sig_idx = (int)idx; cache[cache_idx].sigandhash = OBJ_txt2nid(si.sigalg_name); cache[cache_idx].curve = NID_undef; - /* all provided sigalgs are enabled by load */ -@@ -2601,10 +2606,8 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, + cache[cache_idx].mintls = TLS1_3_VERSION; +@@ -3359,10 +3364,8 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, if (ssl_cert_is_disabled(SSL_CONNECTION_GET_CTX(s), lu->sig_idx)) return 0; @@ -494,7 +701,7 @@ index bd85167..9b3b821 100644 if (s->server && SSL_CONNECTION_IS_TLS13(s)) return 0; if (!s->server -@@ -2640,6 +2643,18 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, +@@ -3398,6 +3401,18 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, } } @@ -513,27 +720,11 @@ index bd85167..9b3b821 100644 /* Finally see if security callback allows it */ secbits = sigalg_security_bits(SSL_CONNECTION_GET_CTX(s), lu); sigalgstr[0] = (lu->sigalg >> 8) & 0xff; -@@ -2994,9 +3009,12 @@ static int sig_cb(const char *elem, int len, void *arg) - if (sarg->ctx != NULL) { - /* Check if a provider supports the sigalg */ - for (i = 0; i < sarg->ctx->sigalg_list_len; i++) { -- if (sarg->ctx->sigalg_list[i].sigalg_name != NULL -- && strcmp(etmp, -- sarg->ctx->sigalg_list[i].sigalg_name) == 0) { -+ if ((sarg->ctx->sigalg_list[i].sigalg_name != NULL -+ && strcmp(etmp, -+ sarg->ctx->sigalg_list[i].sigalg_name) == 0) -+ || (sarg->ctx->sigalg_list[i].name != NULL -+ && strcmp(etmp, -+ sarg->ctx->sigalg_list[i].name) == 0)) { - sarg->sigalgs[sarg->sigalgcnt++] = - sarg->ctx->sigalg_list[i].code_point; - break; diff --git a/openssl/ssl/tls13_enc.c b/openssl/ssl/tls13_enc.c -index 7846c73..ca81bb3 100644 +index 489fafd5214..6ee2ab15ea3 100644 --- a/openssl/ssl/tls13_enc.c +++ b/openssl/ssl/tls13_enc.c -@@ -386,26 +386,26 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, +@@ -391,26 +391,26 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, *ivlen = *taglen = (size_t)mac_mdleni; *keylen = s->s3.tmp.new_mac_secret_size; } else { @@ -574,7 +765,7 @@ index 7846c73..ca81bb3 100644 if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) *taglen = EVP_CCM8_TLS_TAG_LEN; else -@@ -415,6 +415,12 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, +@@ -420,6 +420,12 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, if (mode == EVP_CIPH_GCM_MODE) { *taglen = EVP_GCM_TLS_TAG_LEN; @@ -588,16 +779,15 @@ index 7846c73..ca81bb3 100644 /* CHACHA20P-POLY1305 */ *taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; diff --git a/openssl/util/perl/OpenSSL/paramnames.pm b/openssl/util/perl/OpenSSL/paramnames.pm -index 163a61d..dafcf6c 100644 +index b9c53b0047f..a51afa5060a 100644 --- a/openssl/util/perl/OpenSSL/paramnames.pm +++ b/openssl/util/perl/OpenSSL/paramnames.pm -@@ -158,6 +158,9 @@ my %params = ( - 'CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN' => "tls1multi_encin", # octet_string - 'CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN' => "tls1multi_enclen", # size_t +@@ -154,6 +154,8 @@ my %params = ( + 'OSSL_CIPHER_PARAM_XTS_STANDARD' => "xts_standard",# utf8_string + 'OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC' => "encrypt-then-mac",# int, 0 or 1 + 'OSSL_CIPHER_HMAC_PARAM_MAC' => "*OSSL_CIPHER_PARAM_AEAD_TAG", ++ 'OSSL_CIPHER_PARAM_TLSTREE' => "tlstree", # octet_string ++ 'OSSL_CIPHER_PARAM_TLSTREE_MODE' => "tlstree_mode", # octet_string -+ 'CIPHER_PARAM_TLSTREE' => "tlstree", # octet_string -+ 'CIPHER_PARAM_TLSTREE_MODE' => "tlstree_mode", # octet_string -+ - # digest parameters - 'DIGEST_PARAM_XOFLEN' => "xoflen", # size_t - 'DIGEST_PARAM_SSL3_MS' => "ssl3-ms", # octet string + 'OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT' => "tls1multi_maxsndfrag",# uint + 'OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE' => "tls1multi_maxbufsz", # size_t diff --git a/tcl_tests/tls13.try b/tcl_tests/tls13.try index 7bcb105e..56fc6bca 100644 --- a/tcl_tests/tls13.try +++ b/tcl_tests/tls13.try @@ -8,13 +8,13 @@ array set protos { } array set groups { - GC256A 256 - GC256B 256 - GC256C 256 - GC256D 256 - GC512A 512 - GC512B 512 - GC512C 512 + GC256A gost2012_256 + GC256B gost2012_256 + GC256C gost2012_256 + GC256D gost2012_256 + GC512A gost2012_512 + GC512B gost2012_512 + GC512C gost2012_512 } cd $::test::dir @@ -66,9 +66,9 @@ proc sclient_auth_args {cert key ciphersuites_str groups_str {additional_args {} return [sclient_args $ciphersuites_str $groups_str [list -cert $cert -key $key {*}$additional_args]] } -proc sserver_args {cert key ciphersuites_str proto_str {additional_args {}}} { +proc sserver_args {cert key ciphersuites_str groups_str proto_str {additional_args {}}} { return [list \ - -no_dhe -www -cert $cert -key $key -ciphersuites $ciphersuites_str $proto_str {*}$additional_args] + -curves $groups_str -no_dhe -www -cert $cert -key $key -ciphersuites $ciphersuites_str $proto_str {*}$additional_args] } set run_all 0 @@ -125,10 +125,10 @@ foreach proto $proto_list { test "Handshake $group $suite $proto" { set list [client_server \ [sclient_args $suite $group {}] \ - [sserver_args $server_cert $server_key $suite $protos($proto)] \ + [sserver_args $server_cert $server_key $suite $group $protos($proto)] \ {}] if {[regexp -lineanchor \ - {^Server Temp Key: , (\d+) bits.*^\s*New,\s+(\S+),\s+Cipher\s+is\s+(\S+)\s*$} \ + {^Peer Temp Key: (\S+).*\n^New,\s+(\S+),\s+Cipher\s+is\s+(\S+)} \ [lindex $list 0] -> group_name result_proto result_cipher]} { list [lindex $list 2] $group_name $result_proto $result_cipher } else { @@ -139,7 +139,7 @@ foreach proto $proto_list { test "Get page $group $suite $proto" { set list [client_server \ [sclient_args $suite $group {-ign_eof}] \ - [sserver_args $server_cert $server_key $suite $protos($proto)] \ + [sserver_args $server_cert $server_key $suite $group $protos($proto)] \ "GET /\n\n"] grep "^New," [lindex $list 0] } 0 "New, $expected_proto, Cipher is $raw_name\nNew, $expected_proto, Cipher is $raw_name\n" @@ -147,10 +147,10 @@ foreach proto $proto_list { test "Multi-ciphersuites server $proto, $group client" { set list [client_server \ [sclient_args $suite $group] \ - [sserver_args $server_cert $server_key $suite:TLS_AES_256_GCM_SHA384 $protos($proto)] \ + [sserver_args $server_cert $server_key $suite:TLS_AES_256_GCM_SHA384 $group $protos($proto)] \ {}] if {[regexp -lineanchor \ - {^Server Temp Key: , (\d+) bits.*^\s*New,\s+(\S+),\s+Cipher\s+is\s+(\S+)\s*$} \ + {^Peer Temp Key: (\S+).*\n^New,\s+(\S+),\s+Cipher\s+is\s+(\S+)} \ [lindex $list 0] -> group_name result_proto result_cipher]} { list [lindex $list 2] $group_name $result_proto $result_cipher } else { @@ -173,7 +173,7 @@ foreach proto $proto_list { test "Server $alg, client certificate $alg_cli $proto $group" { set list [client_server \ [sclient_auth_args $user_cert $user_key $suite $group {-ign_eof}]\ - [sserver_args $server_cert $server_key $suite:TLS_AES_256_GCM_SHA384 $protos($proto) \ + [sserver_args $server_cert $server_key $suite:TLS_AES_256_GCM_SHA384 $group $protos($proto) \ {-Verify 3}] \ "GET /\n"] list [lindex $list 2] [grep "^New," [lindex $list 0]] @@ -207,7 +207,7 @@ foreach proto $proto_list { set list [client_server \ [sclient_auth_args $mm_user_cert $mm_user_key $suite $group \ [list -ign_eof -sigalgs $alg_to_rfc($alg)]] \ - [sserver_args $mm_server_cert $mm_server_key $suite:TLS_AES_256_GCM_SHA384 $protos($proto) \ + [sserver_args $mm_server_cert $mm_server_key $suite:TLS_AES_256_GCM_SHA384 $group $protos($proto) \ {-Verify 3}] \ "GET /\n"] list [lindex $list 2] [grep "^New," [lindex $list 0]] diff --git a/test_keyexpimp.c b/test_keyexpimp.c index 305b7f9f..0d201b31 100644 --- a/test_keyexpimp.c +++ b/test_keyexpimp.c @@ -20,6 +20,7 @@ #include #include #include "gost_lcl.h" +#include "gost_gost2015.h" #include "e_gost_err.h" #include "gost_grasshopper_cipher.h" @@ -70,6 +71,13 @@ static int initialize_openssl(ENGINE **eng) T(*eng = ENGINE_by_id("gost")); T(ENGINE_init(*eng)); T(ENGINE_set_default(*eng, ENGINE_METHOD_ALL)); + + /* + * The GOST_NID_JOB structs statically linked into the test start uninitialized, + * so we must assign their NIDs manually. + */ + kuznyechik_mgm_NID.callback(OBJ_sn2nid(SN_kuznyechik_mgm)); + magma_mgm_NID.callback(OBJ_sn2nid(SN_magma_mgm)); return 0; } @@ -210,19 +218,19 @@ int main(void) goto cleanup; ret = gost_tlstree(NID_grasshopper_cbc, kroot, out, tlsseq, TLSTREE_MODE_NONE); - err = expect_eq("Gost TLSTREE - grasshopper", ret, out, tlstree_gh_etalon, 32); + err = expect_eq("Gost TLSTREE_MODE_NONE - grasshopper", ret, out, tlstree_gh_etalon, 32); if (err) goto cleanup; tlsseq[7] = 7; - ret = gost_tlstree(NID_kuznyechik_mgm, kroot_kuzn_s, out, tlsseq, TLSTREE_MODE_S); - err = expect_eq("Gost TLSTREE - kuznyechik", ret, out, tlstree_kuzn_s_etalon, 32); + ret = gost_tlstree(OBJ_sn2nid(SN_kuznyechik_mgm), kroot_kuzn_s, out, tlsseq, TLSTREE_MODE_S); + err = expect_eq("Gost TLSTREE_MODE_S - grasshopper", ret, out, tlstree_kuzn_s_etalon, 32); if (err) goto cleanup; tlsseq[7] = 7; - ret = gost_tlstree(NID_magma_mgm, kroot_magma_l, out, tlsseq, TLSTREE_MODE_L); - err = expect_eq("Gost TLSTREE - magma", ret, out, tlstree_magma_l_etalon, 32); + ret = gost_tlstree(OBJ_sn2nid(SN_magma_mgm), kroot_magma_l, out, tlsseq, TLSTREE_MODE_L); + err = expect_eq("Gost TLSTREE_MODE_L - magma", ret, out, tlstree_magma_l_etalon, 32); if (err) goto cleanup; diff --git a/test_tls13handshake.c b/test_tls13handshake.c new file mode 100644 index 00000000..d83cc9c9 --- /dev/null +++ b/test_tls13handshake.c @@ -0,0 +1,279 @@ +#include +#include +#include +#include +#include +#include + +static const char test_cert_pem[] = + "-----BEGIN CERTIFICATE-----\n" + "MIIBbTCCARgCFCwPZ2ufyPD4w6L9+gIW0bxgc9VKMAwGCCqFAwcBAQMCBQAwNDES\n" + "MBAGA1UEAwwJbG9jYWxob3N0MQ0wCwYDVQQKDARUZXN0MQ8wDQYDVQQLDAZUTFMx\n" + "LjMwHhcNMjUwNDE0MTUxNDIzWhcNMjYwNDE0MTUxNDIzWjA0MRIwEAYDVQQDDAls\n" + "b2NhbGhvc3QxDTALBgNVBAoMBFRlc3QxDzANBgNVBAsMBlRMUzEuMzBmMB8GCCqF\n" + "AwcBAQEBMBMGByqFAwICIwEGCCqFAwcBAQICA0MABEBmhmqMH3rbH6kjPLR7iUwo\n" + "uJqFtsP52CSDz8gJVp1PyW6dzV8EbClmFlI0aJdyyEQ55SlAAGrOOwfSV3aDQjul\n" + "MAwGCCqFAwcBAQMCBQADQQBlxklUm4GF2/ReRw+H9HfJrTFn2lw6Ohv2+WMQKCUl\n" + "JAxWHymeIDaow5oF8Sv2iCO/dUrkab4LYgxRZFrge4mD\n" + "-----END CERTIFICATE-----"; + +static const char test_key_pem[] = + "-----BEGIN PRIVATE KEY-----\n" + "MEYCAQAwHwYIKoUDBwEBAQEwEwYHKoUDAgIjAQYIKoUDBwEBAgIEIIouOKJ+r8nY\n" + "nBM5uRJ3opU7kclTm2FzsexlIt6BPpbq\n" + "-----END PRIVATE KEY-----"; + +int load_cert_and_key_from_strings(SSL_CTX *ctx, + const char *cert_pem, + const char *key_pem) +{ + BIO *cert_bio = NULL, *key_bio = NULL; + X509 *cert = NULL; + EVP_PKEY *pkey = NULL; + int ret = 0; + + cert_bio = BIO_new_mem_buf(cert_pem, -1); + key_bio = BIO_new_mem_buf(key_pem, -1); + if (!cert_bio || !key_bio) { + fprintf(stderr, "BIO_new_mem_buf failed\n"); + goto end; + } + + cert = PEM_read_bio_X509(cert_bio, NULL, 0, NULL); + pkey = PEM_read_bio_PrivateKey(key_bio, NULL, 0, NULL); + if (!cert || !pkey) { + fprintf(stderr, "PEM_read_bio_X509/PrivateKey failed\n"); + ERR_print_errors_fp(stderr); + goto end; + } + + if (SSL_CTX_use_certificate(ctx, cert) != 1) { + fprintf(stderr, "SSL_CTX_use_certificate failed\n"); + goto end; + } + + if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) { + fprintf(stderr, "SSL_CTX_use_PrivateKey failed\n"); + goto end; + } + + if (!SSL_CTX_check_private_key(ctx)) { + fprintf(stderr, "SSL_CTX_check_private_key failed\n"); + goto end; + } + + ret = 1; /* success */ + +end: + X509_free(cert); + EVP_PKEY_free(pkey); + BIO_free(cert_bio); + BIO_free(key_bio); + return ret; +} + +static int create_ctx_pair(SSL_CTX **server_ctx, SSL_CTX **client_ctx) +{ + *server_ctx = SSL_CTX_new(TLS_server_method()); + *client_ctx = SSL_CTX_new(TLS_client_method()); + if (*server_ctx == NULL || *client_ctx == NULL) { + fprintf(stderr, "Failed to create SSL_CTX\n"); + return 0; + } + + SSL_CTX_set_min_proto_version(*server_ctx, TLS1_3_VERSION); + SSL_CTX_set_max_proto_version(*server_ctx, TLS1_3_VERSION); + SSL_CTX_set_min_proto_version(*client_ctx, TLS1_3_VERSION); + SSL_CTX_set_max_proto_version(*client_ctx, TLS1_3_VERSION); + + SSL_CTX_set_cipher_list(*server_ctx, "TLS_GOSTR341112_256_WITH_MAGMA_MGM_L"); + SSL_CTX_set_cipher_list(*client_ctx, "TLS_GOSTR341112_256_WITH_MAGMA_MGM_L"); + + SSL_CTX_set_num_tickets(*server_ctx, 1); + + if (!load_cert_and_key_from_strings(*server_ctx, test_cert_pem, test_key_pem)) + return 0; + + SSL_CTX_set_verify(*client_ctx, SSL_VERIFY_NONE, NULL); + + /* Early data */ + SSL_CTX_set_max_early_data(*server_ctx, 0xffffffff); + + return 1; +} + +static int create_ssl_connection(SSL *sssl, SSL *cssl) +{ + int s_ret, c_ret; + int max_iterations = 100; + int iterations = 0; + int s_err, c_err; + unsigned char tmpbuf[10]; + + if (!sssl || !cssl) + return 0; + + do { + s_ret = SSL_accept(sssl); + c_ret = SSL_connect(cssl); + + s_err = SSL_get_error(sssl, s_ret); + c_err = SSL_get_error(cssl, c_ret); + + if (s_ret <= 0 && s_err != SSL_ERROR_WANT_READ && s_err != SSL_ERROR_WANT_WRITE) { + fprintf(stderr, "Server handshake error: %d\n", s_err); + ERR_print_errors_fp(stderr); + return 0; + } + + if (c_ret <= 0 && c_err != SSL_ERROR_WANT_READ && c_err != SSL_ERROR_WANT_WRITE) { + fprintf(stderr, "Client handshake error: %d\n", c_err); + ERR_print_errors_fp(stderr); + return 0; + } + + iterations++; + if (iterations > max_iterations) { + fprintf(stderr, "Too many iterations in handshake\n"); + return 0; + } + + } while ((s_ret <= 0 && (s_err == SSL_ERROR_WANT_READ || s_err == SSL_ERROR_WANT_WRITE)) || + (c_ret <= 0 && (c_err == SSL_ERROR_WANT_READ || c_err == SSL_ERROR_WANT_WRITE))); + + iterations = 0; + do { + s_ret = SSL_write(sssl, "mTest", strlen("mTest")); + c_ret = SSL_read(cssl, tmpbuf, sizeof(tmpbuf)); + + s_err = SSL_get_error(sssl, s_ret); + c_err = SSL_get_error(cssl, c_ret); + + iterations++; + if (iterations > max_iterations) { + fprintf(stderr, "Too many iterations reading post-handshake data\n"); + return 0; + } + + } while ((s_err == SSL_ERROR_WANT_READ || s_err == SSL_ERROR_WANT_WRITE) || + (c_err == SSL_ERROR_WANT_READ || c_err == SSL_ERROR_WANT_WRITE)); + + if (s_err != SSL_ERROR_NONE) { + fprintf(stderr, "Server post-handshake write error: %d\n", s_err); + ERR_print_errors_fp(stderr); + return 0; + } + + if (c_err != SSL_ERROR_NONE) { + fprintf(stderr, "Client post-handshake read error: %d\n", c_err); + ERR_print_errors_fp(stderr); + return 0; + } + + return 1; +} + +static int create_ssl_pair(SSL_CTX *server_ctx, SSL_CTX *client_ctx, + SSL **server_ssl, SSL **client_ssl) +{ + SSL *s = NULL, *c = NULL; + BIO *srv_bio = NULL, *cli_bio = NULL; + int rv; + + s = SSL_new(server_ctx); + c = SSL_new(client_ctx); + if (s == NULL || c == NULL) { + fprintf(stderr, "SSL_new failed\n"); + goto err; + } + + rv = BIO_new_bio_pair(&cli_bio, 64 * 1024, &srv_bio, 64 * 1024); + if (rv != 1 || cli_bio == NULL || srv_bio == NULL) { + fprintf(stderr, "BIO_new_bio_pair failed\n"); + goto err; + } + + SSL_set_bio(c, cli_bio, cli_bio); + SSL_set_bio(s, srv_bio, srv_bio); + + *server_ssl = s; + *client_ssl = c; + return 1; + +err: + if (s) + SSL_free(s); + if (c) + SSL_free(c); + return 0; +} + +int main(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *sssl = NULL, *cssl = NULL; + SSL_SESSION *sess = NULL; + const char msg[] = "Hello early data!"; + char buf[256]; + size_t written = 0, readbytes = 0; + int ret = 1; + + SSL_library_init(); + SSL_load_error_strings(); + + if (!create_ctx_pair(&sctx, &cctx)) + goto err; + + if (!create_ssl_pair(sctx, cctx, &sssl, &cssl)) + goto err; + + if (!create_ssl_connection(sssl, cssl)) + goto err; + + sess = SSL_get1_session(cssl); + if (!sess) { + fprintf(stderr, "No session established\n"); + goto err; + } + + SSL_shutdown(cssl); + SSL_shutdown(sssl); + SSL_free(cssl); + SSL_free(sssl); + cssl = sssl = NULL; + + if (!create_ssl_pair(sctx, cctx, &sssl, &cssl)) + goto err; + + if (!SSL_set_session(cssl, sess)) { + fprintf(stderr, "SSL_set_session failed\n"); + goto err; + } + + if (!SSL_write_early_data(cssl, msg, strlen(msg), &written)) { + fprintf(stderr, "SSL_write_early_data failed\n"); + goto err; + } + + if (SSL_read_early_data(sssl, buf, sizeof(buf) - 1, &readbytes) + != SSL_READ_EARLY_DATA_SUCCESS) { + fprintf(stderr, "SSL_read_early_data failed\n"); + goto err; + } + + buf[readbytes] = '\0'; + printf("Server received early data: '%s'\n", buf); + + ret = 0; + +err: + if (ret != 0) + ERR_print_errors_fp(stderr); + + SSL_SESSION_free(sess); + SSL_free(cssl); + SSL_free(sssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return ret; +}