From 8484db4abd494eba17f343ea2b61bd788d1c2e42 Mon Sep 17 00:00:00 2001 From: igrkir Date: Wed, 29 Dec 2021 14:45:06 +0300 Subject: [PATCH] change OpenSSL version up to OpenSSL_1_1_1m add new 'tls13' openssl patch CI: .cirrus, GitHub Actions --- .cirrus.yml | 7 +- .github/before_script.sh | 5 +- .github/workflows/ci.yml | 12 +- .github/workflows/codeql-analysis.yml | 7 +- README.md | 2 +- .../{openssl_111g.diff => openssl_111m.diff} | 4048 ++++++++--------- ...sl_111g_obj.diff => openssl_111m_obj.diff} | 22 +- patches/openssl_111m_tls13.diff | 83 + 8 files changed, 2115 insertions(+), 2071 deletions(-) rename patches/{openssl_111g.diff => openssl_111m.diff} (85%) rename patches/{openssl_111g_obj.diff => openssl_111m_obj.diff} (97%) create mode 100644 patches/openssl_111m_tls13.diff diff --git a/.cirrus.yml b/.cirrus.yml index 936ecd1..01018b4 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -4,15 +4,16 @@ FreeBSD_task: env: PREFIX: ${HOME}/opt PATH: ${PREFIX}/bin:${PATH} - OPENSSL_BRANCH: OpenSSL_1_1_1g + OPENSSL_BRANCH: OpenSSL_1_1_1m install_script: - pkg install -y git cmake p5-App-cpanminus gdb pkgconf - sudo cpanm --notest Test2::V0 script: - git clone --depth 1 -b ${OPENSSL_BRANCH} https://github.com/openssl/openssl.git - cd openssl - - patch -p0 < ../patches/openssl_111g.diff - - patch -p0 < ../patches/openssl_111g_obj.diff + - patch -p0 < ../patches/openssl_111m.diff + - patch -p0 < ../patches/openssl_111m_obj.diff + - patch -p0 < ../patches/openssl_111m_tls13.diff - ./config shared -d --prefix=${PREFIX} --openssldir=${PREFIX} -Wl,-rpath=${PREFIX}/lib && make all install_sw > build.log 2>&1 || (cat build.log && exit 1) - cd .. - mkdir build diff --git a/.github/before_script.sh b/.github/before_script.sh index 388a8ae..50c4fc8 100755 --- a/.github/before_script.sh +++ b/.github/before_script.sh @@ -9,8 +9,9 @@ fi git clone --depth 1 -b $OPENSSL_BRANCH https://github.com/openssl/openssl.git cd openssl -patch -p0 < ../patches/openssl_111g.diff -patch -p0 < ../patches/openssl_111g_obj.diff +patch -p0 < ../patches/openssl_111m.diff +patch -p0 < ../patches/openssl_111m_obj.diff +patch -p0 < ../patches/openssl_111m_tls13.diff git describe --always --long PREFIX=$HOME/opt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e039bac..29f9169 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,17 +2,17 @@ name: CI on: [push, pull_request] env: - OPENSSL_BRANCH: OpenSSL_1_1_1g + OPENSSL_BRANCH: OpenSSL_1_1_1m jobs: - gcc-openssl-111g: + gcc-openssl-111m: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - run: .github/before_script.sh - run: .github/script.sh - clang-openssl-111g: + clang-openssl-111m: runs-on: ubuntu-20.04 env: CC: clang @@ -21,17 +21,17 @@ jobs: - run: .github/before_script.sh - run: .github/script.sh - gcc-asan-openssl-111g: + gcc-asan-openssl-111m: runs-on: ubuntu-20.04 env: - OPENSSL_BRANCH: OpenSSL_1_1_1g + OPENSSL_BRANCH: OpenSSL_1_1_1m ASAN: -DASAN=1 steps: - uses: actions/checkout@v2 - run: .github/before_script.sh - run: .github/script.sh - gcc-openssl-111g-x86: + gcc-openssl-111m-x86: runs-on: ubuntu-20.04 env: CFLAGS: -m32 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1eea4f7..f2b3a99 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,7 +1,7 @@ name: "CodeQL" env: - OPENSSL_BRANCH: OpenSSL_1_1_1g + OPENSSL_BRANCH: OpenSSL_1_1_1m #RPATH: "-Wl,-rpath=${PREFIX}/lib" #PREFIX: ${HOME}/opt #PATH: ${PREFIX}/bin:${PATH} @@ -60,8 +60,9 @@ jobs: export PREFIX=`pwd`/opt export RPATH="-Wl,-rpath=${PREFIX}/lib" cd openssl - patch -p0 < ../patches/openssl_111g.diff - patch -p0 < ../patches/openssl_111g_obj.diff + patch -p0 < ../patches/openssl_111m.diff + patch -p0 < ../patches/openssl_111m_obj.diff + patch -p0 < ../patches/openssl_111m_tls13.diff git describe --always --long ./config shared -d --prefix=${PREFIX} --openssldir=${PREFIX} ${RPATH} make -s build_libs diff --git a/README.md b/README.md index fde70cb..1fa4acd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A reference implementation of the Russian GOST crypto algorithms for OpenSSL Compatibility: OpenSSL 1.1.1 (needs patches) *This branch should not compile with vanilla OpenSSL 1.1.1! -It requires patching OpenSSL using the patches/openssl_111g.diff* +It requires patching OpenSSL using the patches/openssl_111m.diff* License: same as the corresponding version of OpenSSL. diff --git a/patches/openssl_111g.diff b/patches/openssl_111m.diff similarity index 85% rename from patches/openssl_111g.diff rename to patches/openssl_111m.diff index fa3dd56..ef65818 100644 --- a/patches/openssl_111g.diff +++ b/patches/openssl_111m.diff @@ -1,8 +1,20 @@ -Index: apps/cms.c -=================================================================== ---- apps/cms.c (revision 14523) -+++ apps/cms.c (working copy) -@@ -75,15 +75,16 @@ +diff --git Configurations/unix-Makefile.tmpl Configurations/unix-Makefile.tmpl +index 66617d6f..0a46a241 100644 +--- Configurations/unix-Makefile.tmpl ++++ Configurations/unix-Makefile.tmpl +@@ -887,6 +887,7 @@ generate_crypto_objects: + crypto/objects/obj_mac.num \ + crypto/objects/obj_xref.txt \ + > crypto/objects/obj_xref.h ) ++ ( cd $(SRCDIR); cat crypto/objects/obj_compat.h >> include/openssl/obj_mac.h ) + + generate_crypto_conf: + ( cd $(SRCDIR); $(PERL) crypto/conf/keysets.pl \ +diff --git apps/cms.c apps/cms.c +index 71554037..7fe22a90 100644 +--- apps/cms.c ++++ apps/cms.c +@@ -75,15 +75,16 @@ typedef enum OPTION_choice { OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF, OPT_NOINDEF, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT, OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE, @@ -22,7 +34,7 @@ Index: apps/cms.c } OPTION_CHOICE; const OPTIONS cms_options[] = { -@@ -150,6 +151,8 @@ +@@ -150,6 +151,8 @@ const OPTIONS cms_options[] = { "Supply or override content for detached signature"}, {"print", OPT_PRINT, '-', "For the -cmsout operation print out all fields of the CMS structure"}, @@ -31,7 +43,7 @@ Index: apps/cms.c {"secretkey", OPT_SECRETKEY, 's'}, {"secretkeyid", OPT_SECRETKEYID, 's'}, {"pwri_password", OPT_PWRI_PASSWORD, 's'}, -@@ -159,6 +162,7 @@ +@@ -159,6 +162,7 @@ const OPTIONS cms_options[] = { {"from", OPT_FROM, 's', "From address"}, {"subject", OPT_SUBJECT, 's', "Subject"}, {"signer", OPT_SIGNER, 's', "Signer certificate file"}, @@ -39,7 +51,7 @@ Index: apps/cms.c {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"}, {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, -@@ -177,6 +181,7 @@ +@@ -177,6 +181,7 @@ const OPTIONS cms_options[] = { # ifndef OPENSSL_NO_DES {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, # endif @@ -47,7 +59,7 @@ Index: apps/cms.c # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, # endif -@@ -196,7 +201,7 @@ +@@ -196,7 +201,7 @@ int cms_main(int argc, char **argv) STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; @@ -56,7 +68,7 @@ Index: apps/cms.c X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; -@@ -204,7 +209,7 @@ +@@ -204,7 +209,7 @@ int cms_main(int argc, char **argv) char *certsoutfile = NULL; int noCAfile = 0, noCApath = 0; char *infile = NULL, *outfile = NULL, *rctfile = NULL; @@ -65,7 +77,7 @@ Index: apps/cms.c char *to = NULL, *from = NULL, *subject = NULL, *prog; cms_key_param *key_first = NULL, *key_param = NULL; int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0; -@@ -406,6 +411,10 @@ +@@ -406,6 +411,10 @@ int cms_main(int argc, char **argv) case OPT_PRINT: noout = print = 1; break; @@ -76,7 +88,7 @@ Index: apps/cms.c case OPT_SECRETKEY: if (secret_key != NULL) { BIO_printf(bio_err, "Invalid key (supplied twice) %s\n", -@@ -486,6 +495,9 @@ +@@ -486,6 +495,9 @@ int cms_main(int argc, char **argv) } signerfile = opt_arg(); break; @@ -86,7 +98,7 @@ Index: apps/cms.c case OPT_INKEY: /* If previous -inkey argument add signer to list */ if (keyfile != NULL) { -@@ -580,6 +592,10 @@ +@@ -582,6 +594,10 @@ int cms_main(int argc, char **argv) case OPT_AES256_WRAP: wrap_cipher = EVP_aes_256_wrap(); break; @@ -97,7 +109,7 @@ Index: apps/cms.c } } argc = opt_num_rest(); -@@ -687,11 +703,11 @@ +@@ -689,11 +705,11 @@ int cms_main(int argc, char **argv) } if (certfile != NULL) { @@ -114,7 +126,7 @@ Index: apps/cms.c } if (recipfile != NULL && (operation == SMIME_DECRYPT)) { -@@ -702,6 +718,15 @@ +@@ -704,6 +720,15 @@ int cms_main(int argc, char **argv) } } @@ -130,7 +142,7 @@ Index: apps/cms.c if (operation == SMIME_SIGN_RECEIPT) { if ((signer = load_cert(signerfile, FORMAT_PEM, "receipt signer certificate file")) == NULL) { -@@ -710,7 +735,8 @@ +@@ -712,7 +737,8 @@ int cms_main(int argc, char **argv) } } @@ -140,7 +152,7 @@ Index: apps/cms.c if (keyfile == NULL) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { -@@ -819,23 +845,31 @@ +@@ -821,23 +847,31 @@ int cms_main(int argc, char **argv) for (i = 0; i < sk_X509_num(encerts); i++) { CMS_RecipientInfo *ri; cms_key_param *kparam; @@ -177,7 +189,7 @@ Index: apps/cms.c if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE && wrap_cipher) { EVP_CIPHER_CTX *wctx; -@@ -981,7 +1015,7 @@ +@@ -983,7 +1017,7 @@ int cms_main(int argc, char **argv) } if (key != NULL) { @@ -186,7 +198,7 @@ Index: apps/cms.c BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } -@@ -1047,8 +1081,19 @@ +@@ -1049,8 +1083,19 @@ int cms_main(int argc, char **argv) } } else { if (noout) { @@ -208,11 +220,11 @@ Index: apps/cms.c } else if (outformat == FORMAT_SMIME) { if (to) BIO_printf(out, "To: %s%s", to, mime_eol); -Index: apps/s_cb.c -=================================================================== ---- apps/s_cb.c (revision 14523) -+++ apps/s_cb.c (working copy) -@@ -684,7 +684,7 @@ +diff --git apps/s_cb.c apps/s_cb.c +index d066a423..23575ed1 100644 +--- apps/s_cb.c ++++ apps/s_cb.c +@@ -684,7 +684,7 @@ static STRINT_PAIR tlsext_types[] = { {NULL} }; @@ -221,7 +233,7 @@ Index: apps/s_cb.c static STRINT_PAIR signature_tls13_scheme_list[] = { {"rsa_pkcs1_sha1", 0x0201 /* TLSEXT_SIGALG_rsa_pkcs1_sha1 */}, {"ecdsa_sha1", 0x0203 /* TLSEXT_SIGALG_ecdsa_sha1 */}, -@@ -696,6 +696,13 @@ +@@ -696,6 +696,13 @@ static STRINT_PAIR signature_tls13_scheme_list[] = { {"ecdsa_secp384r1_sha384", 0x0503 /* TLSEXT_SIGALG_ecdsa_secp384r1_sha384 */}, {"rsa_pkcs1_sha512", 0x0601 /* TLSEXT_SIGALG_rsa_pkcs1_sha512 */}, {"ecdsa_secp521r1_sha512", 0x0603 /* TLSEXT_SIGALG_ecdsa_secp521r1_sha512 */}, @@ -235,7 +247,7 @@ Index: apps/s_cb.c {"rsa_pss_rsae_sha256", 0x0804 /* TLSEXT_SIGALG_rsa_pss_rsae_sha256 */}, {"rsa_pss_rsae_sha384", 0x0805 /* TLSEXT_SIGALG_rsa_pss_rsae_sha384 */}, {"rsa_pss_rsae_sha512", 0x0806 /* TLSEXT_SIGALG_rsa_pss_rsae_sha512 */}, -@@ -704,9 +711,6 @@ +@@ -704,9 +711,6 @@ static STRINT_PAIR signature_tls13_scheme_list[] = { {"rsa_pss_pss_sha256", 0x0809 /* TLSEXT_SIGALG_rsa_pss_pss_sha256 */}, {"rsa_pss_pss_sha384", 0x080a /* TLSEXT_SIGALG_rsa_pss_pss_sha384 */}, {"rsa_pss_pss_sha512", 0x080b /* TLSEXT_SIGALG_rsa_pss_pss_sha512 */}, @@ -245,244 +257,325 @@ Index: apps/s_cb.c {NULL} }; -Index: crypto/objects/objects.txt -=================================================================== ---- crypto/objects/objects.txt (revision 14523) -+++ crypto/objects/objects.txt (working copy) -@@ -1321,6 +1321,14 @@ +diff --git crypto/asn1/p8_pkey.c crypto/asn1/p8_pkey.c +index ab509b1a..e90b3022 100644 +--- crypto/asn1/p8_pkey.c ++++ crypto/asn1/p8_pkey.c +@@ -78,3 +78,18 @@ int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + return 1; + return 0; + } ++ ++int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, int type, ++ const unsigned char *bytes, int len) ++{ ++ if (X509at_add1_attr_by_OBJ(&p8->attributes, obj, type, bytes, len) != NULL) ++ return 1; ++ return 0; ++} ++ ++int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr) ++{ ++ if (X509at_add1_attr(&p8->attributes, attr) != NULL) ++ return 1; ++ return 0; ++} +diff --git crypto/cms/cms_env.c crypto/cms/cms_env.c +index 962a0137..249e4753 100644 +--- crypto/cms/cms_env.c ++++ crypto/cms/cms_env.c +@@ -20,6 +20,8 @@ - # TC26 GOST OIDs + /* CMS EnvelopedData Utilities */ -+id-tc26 0 : id-tc26-modules: GOST TC26 ASN.1 modules ++static void cms_env_set_version(CMS_EnvelopedData *env); + -+id-tc26-modules 6 : id-tc26-cms: GOST TC26 SMS + CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) + { + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { +@@ -121,6 +123,39 @@ CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) + return NULL; + } + ++int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) ++{ ++ CMS_EnvelopedData *env = NULL; ++ EVP_CIPHER_CTX *ctx = NULL; ++ BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER); + -+id-tc26-cms 1 : id-tc26-cms-attrs: GOST TC26 SMS attributes ++ env = cms_get0_enveloped(cms); ++ if (!env) ++ return 0; + -+id-tc26-cms-attrs 1 : id-tc26-mac-attr: GOST TC26 SMS content-mac attribute ++ if (!mbio) { ++ CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CONTENT_NOT_FOUND); ++ return 0; ++ } + - id-tc26 1 : id-tc26-algorithms - id-tc26-algorithms 1 : id-tc26-sign - !Cname id-GostR3410-2012-256 -@@ -1344,11 +1352,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 : id-tc26-cipher-gostr3412-2015-magma-ctracpkm --id-tc26-cipher-gostr3412-2015-magma 2 : id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac -+id-tc26-cipher-gostr3412-2015-magma 1 : magma-ctr-acpkm -+id-tc26-cipher-gostr3412-2015-magma 2 : magma-ctr-acpkm-omac - id-tc26-cipher 2 : id-tc26-cipher-gostr3412-2015-kuznyechik --id-tc26-cipher-gostr3412-2015-kuznyechik 1 : id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm --id-tc26-cipher-gostr3412-2015-kuznyechik 2 : id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac -+id-tc26-cipher-gostr3412-2015-kuznyechik 1 : kuznyechik-ctr-acpkm -+id-tc26-cipher-gostr3412-2015-kuznyechik 2 : kuznyechik-ctr-acpkm-omac - - id-tc26-algorithms 6 : id-tc26-agreement - id-tc26-agreement 1 : id-tc26-agreement-gost-3410-2012-256 -@@ -1356,9 +1364,9 @@ - - id-tc26-algorithms 7 : id-tc26-wrap - id-tc26-wrap 1 : id-tc26-wrap-gostr3412-2015-magma --id-tc26-wrap-gostr3412-2015-magma 1 : id-tc26-wrap-gostr3412-2015-magma-kexp15 -+id-tc26-wrap-gostr3412-2015-magma 1 : magma-kexp15 - id-tc26-wrap 2 : id-tc26-wrap-gostr3412-2015-kuznyechik --id-tc26-wrap-gostr3412-2015-kuznyechik 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15 -+id-tc26-wrap-gostr3412-2015-kuznyechik 1 : kuznyechik-kexp15 ++ BIO_get_cipher_ctx(mbio, &ctx); ++ ++ /* ++ * If the selected cipher supports unprotected attributes, ++ * deal with it using special ctrl function ++ */ ++ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) { ++ cms->d.envelopedData->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null(); ++ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 1, env->unprotectedAttrs) <= 0) { ++ CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CTRL_FAILURE); ++ return 0; ++ } ++ } ++ cms_env_set_version(cms->d.envelopedData); ++ ++ return 1; ++} ++ + /* Key Transport Recipient Info (KTRI) routines */ - id-tc26 2 : id-tc26-constants + /* Initialise a ktri based on passed certificate and key */ +@@ -175,8 +210,8 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, + * Add a recipient certificate using appropriate type of RecipientInfo + */ -@@ -1382,16 +1390,25 @@ - member-body 643 3 131 1 1 : INN : INN - member-body 643 100 1 : OGRN : OGRN - member-body 643 100 3 : SNILS : SNILS -+member-body 643 100 5 : OGRNIP : OGRNIP - member-body 643 100 111 : subjectSignTool : Signing Tool of Subject - member-body 643 100 112 : issuerSignTool : Signing Tool of Issuer -+member-body 643 100 113 : classSignTool : Class of Signing Tool -+member-body 643 100 113 1 : classSignToolKC1 : Class of Signing Tool KC1 -+member-body 643 100 113 2 : classSignToolKC2 : Class of Signing Tool KC2 -+member-body 643 100 113 3 : classSignToolKC3 : Class of Signing Tool KC3 -+member-body 643 100 113 4 : classSignToolKB1 : Class of Signing Tool KB1 -+member-body 643 100 113 5 : classSignToolKB2 : Class of Signing Tool KB2 -+member-body 643 100 113 6 : classSignToolKA1 : Class of Signing Tool KA1 +-CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, +- X509 *recip, unsigned int flags) ++CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, ++ EVP_PKEY *originatorPrivKey, X509 * originator, unsigned int flags) + { + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; +@@ -192,7 +227,7 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, - #GOST R34.13-2015 Grasshopper "Kuznechik" -- : grasshopper-ecb -- : grasshopper-ctr -- : grasshopper-ofb -- : grasshopper-cbc -- : grasshopper-cfb -- : grasshopper-mac -+ : kuznyechik-ecb -+ : kuznyechik-ctr -+ : kuznyechik-ofb -+ : kuznyechik-cbc -+ : kuznyechik-cfb -+ : kuznyechik-mac -+ : kuznyechik-mgm + pk = X509_get0_pubkey(recip); + if (!pk) { +- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); ++ CMSerr(CMS_F_CMS_ADD1_RECIPIENT, CMS_R_ERROR_GETTING_PUBLIC_KEY); + goto err; + } - #GOST R34.13-2015 Magma - : magma-ecb -@@ -1400,6 +1417,7 @@ - : magma-cbc - : magma-cfb - : magma-mac -+ : magma-mgm +@@ -204,12 +239,12 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + break; - # Definitions for Camellia cipher - CBC MODE + case CMS_RECIPINFO_AGREE: +- if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) ++ if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator, originatorPrivKey, flags)) + goto err; + break; -Index: crypto/cms/cms_local.h -=================================================================== ---- crypto/cms/cms_local.h (revision 14523) -+++ crypto/cms/cms_local.h (working copy) -@@ -403,12 +403,13 @@ - ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); + default: +- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ++ CMSerr(CMS_F_CMS_ADD1_RECIPIENT, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; - BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); -+int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain); - CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); - int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); - int cms_pkey_get_ri_type(EVP_PKEY *pk); -+int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type); - /* KARI routines */ --int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, -- EVP_PKEY *pk, unsigned int flags); -+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *recipPubKey, X509 * originator, EVP_PKEY *originatorPrivKey, unsigned int flags); - int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri); +@@ -221,13 +256,19 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + return ri; -Index: crypto/cms/cms_lib.c -=================================================================== ---- crypto/cms/cms_lib.c (revision 14523) -+++ crypto/cms/cms_lib.c (working copy) -@@ -130,12 +130,14 @@ - switch (OBJ_obj2nid(cms->contentType)) { + merr: +- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); ++ CMSerr(CMS_F_CMS_ADD1_RECIPIENT, ERR_R_MALLOC_FAILURE); + err: + M_ASN1_free_of(ri, CMS_RecipientInfo); + return NULL; - case NID_pkcs7_data: -- case NID_pkcs7_enveloped: - case NID_pkcs7_encrypted: - case NID_id_smime_ct_compressedData: - /* Nothing to do */ - return 1; + } -+ case NID_pkcs7_enveloped: -+ return cms_EnvelopedData_final(cms, cmsbio); ++CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, ++ X509 *recip, unsigned int flags) ++{ ++ return CMS_add1_recipient(cms, recip, NULL, NULL, flags); ++} + - case NID_pkcs7_signed: - return cms_SignedData_final(cms, cmsbio); - -Index: crypto/cms/cms_smime.c -=================================================================== ---- crypto/cms/cms_smime.c (revision 14523) -+++ crypto/cms/cms_smime.c (working copy) -@@ -576,8 +576,8 @@ - return NULL; + int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg) +@@ -857,50 +898,88 @@ static void cms_env_set_version(CMS_EnvelopedData *env) + env->version = 0; } --static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, -- EVP_PKEY *pk, X509 *cert) -+static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, -+ EVP_PKEY *pk, X509 *cert, X509 *peer) +-BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) ++static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms) { - int i; - STACK_OF(CMS_RecipientEncryptedKey) *reks; -@@ -588,7 +588,7 @@ - rek = sk_CMS_RecipientEncryptedKey_value(reks, i); - if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) - continue; -- CMS_RecipientInfo_kari_set0_pkey(ri, pk); -+ CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, peer); - rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); - CMS_RecipientInfo_kari_set0_pkey(ri, NULL); - if (rv > 0) -@@ -600,27 +600,35 @@ +- CMS_EncryptedContentInfo *ec; +- STACK_OF(CMS_RecipientInfo) *rinfos; +- CMS_RecipientInfo *ri; +- int i, ok = 0; +- BIO *ret; ++ CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo; ++ BIO *contentBio = cms_EncryptedContent_init_bio(ec); ++ EVP_CIPHER_CTX *ctx = NULL; - int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) - { -+ return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL); +- /* Get BIO first to set up key */ ++ if (!contentBio) ++ return NULL; + +- ec = cms->d.envelopedData->encryptedContentInfo; +- ret = cms_EncryptedContent_init_bio(ec); ++ BIO_get_cipher_ctx(contentBio, &ctx); ++ if (ctx == NULL) { ++ BIO_free(contentBio); ++ return NULL; ++ } ++/* ++ * If the selected cipher supports unprotected attributes, ++ * deal with it using special ctrl function ++ */ ++ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC && ++ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 0, cms->d.envelopedData->unprotectedAttrs) <= 0) { ++ BIO_free(contentBio); ++ return NULL; ++ } ++ return contentBio; +} -+ -+int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer) + +- /* If error or no cipher end of processing */ ++static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms) +{ - STACK_OF(CMS_RecipientInfo) *ris; - CMS_RecipientInfo *ri; -- int i, r, ri_type; -+ int i, r, cms_pkey_ri_type; - int debug = 0, match_ri = 0; - ris = CMS_get0_RecipientInfos(cms); - if (ris) - debug = cms->d.envelopedData->encryptedContentInfo->debug; -- ri_type = cms_pkey_get_ri_type(pk); -- if (ri_type == CMS_RECIPINFO_NONE) { -- CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, -- CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); -- return 0; -+ -+ cms_pkey_ri_type = cms_pkey_get_ri_type(pk); -+ if (cms_pkey_ri_type == CMS_RECIPINFO_NONE) { -+ CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, -+ CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); -+ return 0; - } ++ CMS_EncryptedContentInfo *ec; ++ STACK_OF(CMS_RecipientInfo) *rinfos; ++ CMS_RecipientInfo *ri; ++ int i, ok = 0; ++ BIO *ret; - for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { -+ int ri_type; - ri = sk_CMS_RecipientInfo_value(ris, i); -- if (CMS_RecipientInfo_type(ri) != ri_type) -- continue; -+ ri_type = CMS_RecipientInfo_type(ri); -+/* if (!cms_pkey_is_ri_type_supported(pk, ri_type)) -+ continue; */ - match_ri = 1; - if (ri_type == CMS_RECIPINFO_AGREE) { -- r = cms_kari_set1_pkey(cms, ri, pk, cert); -+ r = cms_kari_set1_pkey_and_peer(cms, ri, pk, cert, peer); - if (r > 0) - return 1; - if (r < 0) -@@ -640,13 +648,13 @@ - * If not debugging clear any error and return success to - * avoid leaking of information useful to MMA - */ -- if (!debug) { -+ if (!debug && cms_pkey_ri_type == CMS_RECIPINFO_TRANS) { - ERR_clear_error(); - return 1; - } - if (r > 0) - return 1; -- CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); -+ CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, CMS_R_DECRYPT_ERROR); - return 0; - } - /* -@@ -654,17 +662,17 @@ - * successful decrypt. Always attempt to decrypt all recipients - * to avoid leaking timing of a successful decrypt. - */ -- else if (r > 0 && debug) -+ else if (r > 0 && (debug || cms_pkey_ri_type != CMS_RECIPINFO_TRANS)) - return 1; - } - } - /* If no cert, key transport and not debugging always return success */ -- if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { -+ if (cert == NULL && cms_pkey_ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { - ERR_clear_error(); - return 1; - } +- if (!ret || !ec->cipher) +- return ret; ++ /* Get BIO first to set up key */ -- CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); -+ CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, CMS_R_NO_MATCHING_RECIPIENT); - return 0; +- /* Now encrypt content key according to each RecipientInfo type */ ++ ec = cms->d.envelopedData->encryptedContentInfo; ++ ret = cms_EncryptedContent_init_bio(ec); + +- rinfos = cms->d.envelopedData->recipientInfos; ++ /* If error or no cipher end of processing */ + +- for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { +- ri = sk_CMS_RecipientInfo_value(rinfos, i); +- if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { +- CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, +- CMS_R_ERROR_SETTING_RECIPIENTINFO); +- goto err; +- } +- } +- cms_env_set_version(cms->d.envelopedData); ++ if (!ret) ++ return ret; + +- ok = 1; ++ /* Now encrypt content key according to each RecipientInfo type */ + +- err: +- ec->cipher = NULL; +- OPENSSL_clear_free(ec->key, ec->keylen); +- ec->key = NULL; +- ec->keylen = 0; +- if (ok) +- return ret; +- BIO_free(ret); +- return NULL; ++ rinfos = cms->d.envelopedData->recipientInfos; + ++ for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { ++ ri = sk_CMS_RecipientInfo_value(rinfos, i); ++ if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { ++ CMSerr(CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO, ++ CMS_R_ERROR_SETTING_RECIPIENTINFO); ++ goto err; ++ } ++ } ++ cms_env_set_version(cms->d.envelopedData); /* FIXME move lower? */ ++ ++ ok = 1; ++ ++err: ++ ec->cipher = NULL; ++ OPENSSL_clear_free(ec->key, ec->keylen); ++ ec->key = NULL; ++ ec->keylen = 0; ++ if (ok) ++ return ret; ++ BIO_free(ret); ++ return NULL; ++ ++} ++ ++BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) ++{ ++ if (cms->d.envelopedData->encryptedContentInfo->cipher) ++ { ++ //If cipher is set it's encrypting ++ return cms_EnvelopedData_Encryption_init_bio(cms); ++ } ++ ++ //If cipher is not set it's decrypting ++ return cms_EnvelopedData_Decryption_init_bio(cms); + } + /* +@@ -918,3 +997,25 @@ int cms_pkey_get_ri_type(EVP_PKEY *pk) + } + return CMS_RECIPINFO_TRANS; } -Index: crypto/cms/cms_kari.c -=================================================================== ---- crypto/cms/cms_kari.c (revision 14523) -+++ crypto/cms/cms_kari.c (working copy) -@@ -152,7 +152,7 @@ ++ ++int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type) ++{ ++ if (pk->ameth && pk->ameth->pkey_ctrl) ++ { ++ int i, r; ++ i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, ri_type, &r); ++ if (i > 0) ++ return r; ++ } ++ ++ //if ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED not supported ++ ++ int supportedRiType = cms_pkey_get_ri_type(pk); ++ ++ if (supportedRiType < 0) ++ { ++ return 0; ++ } ++ ++ return (supportedRiType == ri_type); ++} +diff --git crypto/cms/cms_err.c crypto/cms/cms_err.c +index a211f495..6bc8a3af 100644 +--- crypto/cms/cms_err.c ++++ crypto/cms/cms_err.c +@@ -22,6 +22,7 @@ static const ERR_STRING_DATA CMS_str_functs[] = { + "CMS_add0_recipient_password"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECEIPTREQUEST, 0), + "CMS_add1_ReceiptRequest"}, ++ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECIPIENT, 0), "CMS_add1_recipient"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECIPIENT_CERT, 0), + "CMS_add1_recipient_cert"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNER, 0), "CMS_add1_signer"}, +@@ -45,6 +46,8 @@ static const ERR_STRING_DATA CMS_str_functs[] = { + "CMS_decrypt_set1_password"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PKEY, 0), + "CMS_decrypt_set1_pkey"}, ++ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, 0), ++ "CMS_decrypt_set1_pkey_and_peer"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, 0), + "cms_DigestAlgorithm_find_ctx"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, 0), +@@ -66,6 +69,12 @@ static const ERR_STRING_DATA CMS_str_functs[] = { + "CMS_EncryptedData_set1_key"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_CREATE, 0), + "CMS_EnvelopedData_create"}, ++ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_DECRYPTION_INIT_BIO, 0), ++ "cms_EnvelopedData_Decryption_init_bio"}, ++ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO, 0), ++ "cms_EnvelopedData_Encryption_init_bio"}, ++ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_FINAL, 0), ++ "cms_EnvelopedData_final"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 0), + "cms_EnvelopedData_init_bio"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPED_DATA_INIT, 0), +diff --git crypto/cms/cms_kari.c crypto/cms/cms_kari.c +index cafc3040..eb11e428 100644 +--- crypto/cms/cms_kari.c ++++ crypto/cms/cms_kari.c +@@ -152,7 +152,7 @@ int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, return -1; } @@ -491,7 +584,7 @@ Index: crypto/cms/cms_kari.c { EVP_PKEY_CTX *pctx; CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; -@@ -164,6 +164,16 @@ +@@ -164,6 +164,16 @@ int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) pctx = EVP_PKEY_CTX_new(pk, NULL); if (!pctx || EVP_PKEY_derive_init(pctx) <= 0) goto err; @@ -508,7 +601,7 @@ Index: crypto/cms/cms_kari.c kari->pctx = pctx; return 1; err: -@@ -171,6 +181,11 @@ +@@ -171,6 +181,11 @@ int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) return 0; } @@ -520,7 +613,7 @@ Index: crypto/cms/cms_kari.c EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) { if (ri->type == CMS_RECIPINFO_AGREE) -@@ -282,10 +297,27 @@ +@@ -282,10 +297,27 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, return rv; } @@ -550,7 +643,7 @@ Index: crypto/cms/cms_kari.c { CMS_KeyAgreeRecipientInfo *kari; CMS_RecipientEncryptedKey *rek = NULL; -@@ -320,12 +352,45 @@ +@@ -320,12 +352,45 @@ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, return 0; } @@ -567,9 +660,7 @@ Index: crypto/cms/cms_kari.c + { + /* Use originator key */ + CMS_OriginatorIdentifierOrKey *oik = ri->d.kari->originator; - -- EVP_PKEY_up_ref(pk); -- rek->pkey = pk; ++ + if (!originatorPrivKey && !originator) + { + return 0; @@ -595,13 +686,15 @@ Index: crypto/cms/cms_kari.c + return 0; + } + } -+ + +- EVP_PKEY_up_ref(pk); +- rek->pkey = pk; + EVP_PKEY_up_ref(recipPubKey); + rek->pkey = recipPubKey; return 1; } -@@ -335,14 +400,35 @@ +@@ -335,14 +400,35 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, EVP_CIPHER_CTX *ctx = kari->ctx; const EVP_CIPHER *kekcipher; int keylen = EVP_CIPHER_key_length(cipher); @@ -641,305 +734,339 @@ Index: crypto/cms/cms_kari.c /* * Pick a cipher based on content encryption cipher. If it is DES3 use * DES3 wrap otherwise use AES wrap similar to key size. -Index: crypto/cms/cms_env.c -=================================================================== ---- crypto/cms/cms_env.c (revision 14523) -+++ crypto/cms/cms_env.c (working copy) -@@ -20,6 +20,8 @@ +diff --git crypto/cms/cms_lib.c crypto/cms/cms_lib.c +index be4c2c70..8cce75ea 100644 +--- crypto/cms/cms_lib.c ++++ crypto/cms/cms_lib.c +@@ -131,12 +131,14 @@ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) + switch (OBJ_obj2nid(cms->contentType)) { - /* CMS EnvelopedData Utilities */ + case NID_pkcs7_data: +- case NID_pkcs7_enveloped: + case NID_pkcs7_encrypted: + case NID_id_smime_ct_compressedData: + /* Nothing to do */ + return 1; -+static void cms_env_set_version(CMS_EnvelopedData *env); ++ case NID_pkcs7_enveloped: ++ return cms_EnvelopedData_final(cms, cmsbio); + - CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) - { - if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { -@@ -121,6 +123,39 @@ + case NID_pkcs7_signed: + return cms_SignedData_final(cms, cmsbio); + +diff --git crypto/cms/cms_local.h crypto/cms/cms_local.h +index a0ce4448..27261b77 100644 +--- crypto/cms/cms_local.h ++++ crypto/cms/cms_local.h +@@ -403,12 +403,13 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); + ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); + + BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); ++int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain); + CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); + int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); + int cms_pkey_get_ri_type(EVP_PKEY *pk); ++int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type); + /* KARI routines */ +-int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, +- EVP_PKEY *pk, unsigned int flags); ++int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *recipPubKey, X509 * originator, EVP_PKEY *originatorPrivKey, unsigned int flags); + int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri); + +diff --git crypto/cms/cms_smime.c crypto/cms/cms_smime.c +index 6e7dbc4d..b7d457d3 100644 +--- crypto/cms/cms_smime.c ++++ crypto/cms/cms_smime.c +@@ -576,8 +576,8 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, return NULL; } -+int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) +-static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, +- EVP_PKEY *pk, X509 *cert) ++static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, ++ EVP_PKEY *pk, X509 *cert, X509 *peer) + { + int i; + STACK_OF(CMS_RecipientEncryptedKey) *reks; +@@ -588,7 +588,7 @@ static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + rek = sk_CMS_RecipientEncryptedKey_value(reks, i); + if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) + continue; +- CMS_RecipientInfo_kari_set0_pkey(ri, pk); ++ CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, peer); + rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); + CMS_RecipientInfo_kari_set0_pkey(ri, NULL); + if (rv > 0) +@@ -599,28 +599,36 @@ static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + } + + int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) +{ -+ CMS_EnvelopedData *env = NULL; -+ EVP_CIPHER_CTX *ctx = NULL; -+ BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER); ++ return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL); ++} + -+ env = cms_get0_enveloped(cms); -+ if (!env) -+ return 0; ++int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer) + { + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; +- int i, r, ri_type; ++ int i, r, cms_pkey_ri_type; + int debug = 0, match_ri = 0; + ris = CMS_get0_RecipientInfos(cms); + if (ris) + debug = cms->d.envelopedData->encryptedContentInfo->debug; +- ri_type = cms_pkey_get_ri_type(pk); +- if (ri_type == CMS_RECIPINFO_NONE) { +- CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, +- CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); +- return 0; + -+ if (!mbio) { -+ CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CONTENT_NOT_FOUND); -+ return 0; -+ } ++ cms_pkey_ri_type = cms_pkey_get_ri_type(pk); ++ if (cms_pkey_ri_type == CMS_RECIPINFO_NONE) { ++ CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, ++ CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); ++ return 0; + } + + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { ++ int ri_type; + ri = sk_CMS_RecipientInfo_value(ris, i); +- if (CMS_RecipientInfo_type(ri) != ri_type) +- continue; ++ ri_type = CMS_RecipientInfo_type(ri); ++/* if (!cms_pkey_is_ri_type_supported(pk, ri_type)) ++ continue; */ + match_ri = 1; + if (ri_type == CMS_RECIPINFO_AGREE) { +- r = cms_kari_set1_pkey(cms, ri, pk, cert); ++ r = cms_kari_set1_pkey_and_peer(cms, ri, pk, cert, peer); + if (r > 0) + return 1; + if (r < 0) +@@ -640,13 +648,13 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) + * If not debugging clear any error and return success to + * avoid leaking of information useful to MMA + */ +- if (!debug) { ++ if (!debug && cms_pkey_ri_type == CMS_RECIPINFO_TRANS) { + ERR_clear_error(); + return 1; + } + if (r > 0) + return 1; +- CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); ++ CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, CMS_R_DECRYPT_ERROR); + return 0; + } + /* +@@ -654,17 +662,17 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) + * successful decrypt. Always attempt to decrypt all recipients + * to avoid leaking timing of a successful decrypt. + */ +- else if (r > 0 && debug) ++ else if (r > 0 && (debug || cms_pkey_ri_type != CMS_RECIPINFO_TRANS)) + return 1; + } + } + /* If no cert, key transport and not debugging always return success */ +- if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { ++ if (cert == NULL && cms_pkey_ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { + ERR_clear_error(); + return 1; + } + +- CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); ++ CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + + } +diff --git crypto/err/openssl.txt crypto/err/openssl.txt +index 902e97b8..7fef6807 100644 +--- crypto/err/openssl.txt ++++ crypto/err/openssl.txt +@@ -240,6 +240,7 @@ CMS_F_CMS_ADD0_CERT:164:CMS_add0_cert + CMS_F_CMS_ADD0_RECIPIENT_KEY:100:CMS_add0_recipient_key + CMS_F_CMS_ADD0_RECIPIENT_PASSWORD:165:CMS_add0_recipient_password + CMS_F_CMS_ADD1_RECEIPTREQUEST:158:CMS_add1_ReceiptRequest ++CMS_F_CMS_ADD1_RECIPIENT:181:CMS_add1_recipient + CMS_F_CMS_ADD1_RECIPIENT_CERT:101:CMS_add1_recipient_cert + CMS_F_CMS_ADD1_SIGNER:102:CMS_add1_signer + CMS_F_CMS_ADD1_SIGNINGTIME:103:cms_add1_signingTime +@@ -255,6 +256,7 @@ CMS_F_CMS_DECRYPT:112:CMS_decrypt + CMS_F_CMS_DECRYPT_SET1_KEY:113:CMS_decrypt_set1_key + CMS_F_CMS_DECRYPT_SET1_PASSWORD:166:CMS_decrypt_set1_password + CMS_F_CMS_DECRYPT_SET1_PKEY:114:CMS_decrypt_set1_pkey ++CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER:182:CMS_decrypt_set1_pkey_and_peer + CMS_F_CMS_DIGESTALGORITHM_FIND_CTX:115:cms_DigestAlgorithm_find_ctx + CMS_F_CMS_DIGESTALGORITHM_INIT_BIO:116:cms_DigestAlgorithm_init_bio + CMS_F_CMS_DIGESTEDDATA_DO_FINAL:117:cms_DigestedData_do_final +@@ -267,6 +269,11 @@ CMS_F_CMS_ENCRYPTEDDATA_DECRYPT:121:CMS_EncryptedData_decrypt + CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT:122:CMS_EncryptedData_encrypt + CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY:123:CMS_EncryptedData_set1_key + CMS_F_CMS_ENVELOPEDDATA_CREATE:124:CMS_EnvelopedData_create ++CMS_F_CMS_ENVELOPEDDATA_DECRYPTION_INIT_BIO:184:\ ++ cms_EnvelopedData_Decryption_init_bio ++CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO:185:\ ++ cms_EnvelopedData_Encryption_init_bio ++CMS_F_CMS_ENVELOPEDDATA_FINAL:186:cms_EnvelopedData_final + CMS_F_CMS_ENVELOPEDDATA_INIT_BIO:125:cms_EnvelopedData_init_bio + CMS_F_CMS_ENVELOPED_DATA_INIT:126:cms_enveloped_data_init + CMS_F_CMS_ENV_ASN1_CTRL:171:cms_env_asn1_ctrl +@@ -1184,7 +1191,7 @@ SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE:431:* + SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE:601:\ + ossl_statem_server_post_process_message + SSL_F_OSSL_STATEM_SERVER_POST_WORK:602:ossl_statem_server_post_work +-SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640: ++SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640:ossl_statem_server_pre_work + SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE:603:ossl_statem_server_process_message + SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION:418:ossl_statem_server_read_transition + SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION:604:\ +@@ -1399,6 +1406,7 @@ SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC:427:tls_construct_change_cipher_spec + SSL_F_TLS_CONSTRUCT_CKE_DHE:404:tls_construct_cke_dhe + SSL_F_TLS_CONSTRUCT_CKE_ECDHE:405:tls_construct_cke_ecdhe + SSL_F_TLS_CONSTRUCT_CKE_GOST:406:tls_construct_cke_gost ++SSL_F_TLS_CONSTRUCT_CKE_GOST18:642:tls_construct_cke_gost18 + SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE:407:tls_construct_cke_psk_preamble + SSL_F_TLS_CONSTRUCT_CKE_RSA:409:tls_construct_cke_rsa + SSL_F_TLS_CONSTRUCT_CKE_SRP:410:tls_construct_cke_srp +@@ -1530,6 +1538,7 @@ SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC:363:tls_process_change_cipher_spec + SSL_F_TLS_PROCESS_CKE_DHE:411:tls_process_cke_dhe + SSL_F_TLS_PROCESS_CKE_ECDHE:412:tls_process_cke_ecdhe + SSL_F_TLS_PROCESS_CKE_GOST:413:tls_process_cke_gost ++SSL_F_TLS_PROCESS_CKE_GOST18:641:tls_process_cke_gost18 + SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE:414:tls_process_cke_psk_preamble + SSL_F_TLS_PROCESS_CKE_RSA:415:tls_process_cke_rsa + SSL_F_TLS_PROCESS_CKE_SRP:416:tls_process_cke_srp +@@ -1652,6 +1661,7 @@ X509V3_F_GNAMES_FROM_SECTNAME:156:gnames_from_sectname + X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED + X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING + X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER ++X509V3_F_I2S_ASN1_UTF8STRING:175:i2s_ASN1_UTF8STRING + X509V3_F_I2V_AUTHORITY_INFO_ACCESS:138:i2v_AUTHORITY_INFO_ACCESS + X509V3_F_I2V_AUTHORITY_KEYID:173:i2v_AUTHORITY_KEYID + X509V3_F_LEVEL_ADD_NODE:168:level_add_node +@@ -1667,6 +1677,7 @@ X509V3_F_R2I_PCI:155:r2i_pci + X509V3_F_S2I_ASN1_IA5STRING:100:s2i_ASN1_IA5STRING + X509V3_F_S2I_ASN1_INTEGER:108:s2i_ASN1_INTEGER + X509V3_F_S2I_ASN1_OCTET_STRING:112:s2i_ASN1_OCTET_STRING ++X509V3_F_S2I_ASN1_UTF8STRING:176:s2i_ASN1_UTF8STRING + X509V3_F_S2I_SKEY_ID:115:s2i_skey_id + X509V3_F_SET_DIST_POINT_NAME:158:set_dist_point_name + X509V3_F_SXNET_ADD_ID_ASC:125:SXNET_add_id_asc +diff --git crypto/objects/objects.txt crypto/objects/objects.txt +index c49d4c56..00444c40 100644 +--- crypto/objects/objects.txt ++++ crypto/objects/objects.txt +@@ -1321,6 +1321,14 @@ cryptocom 1 8 1 : id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Se + + # TC26 GOST OIDs + ++id-tc26 0 : id-tc26-modules: GOST TC26 ASN.1 modules + -+ BIO_get_cipher_ctx(mbio, &ctx); ++id-tc26-modules 6 : id-tc26-cms: GOST TC26 SMS + -+ /* -+ * If the selected cipher supports unprotected attributes, -+ * deal with it using special ctrl function -+ */ -+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) { -+ cms->d.envelopedData->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null(); -+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 1, env->unprotectedAttrs) <= 0) { -+ CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CTRL_FAILURE); -+ return 0; -+ } -+ } -+ cms_env_set_version(cms->d.envelopedData); ++id-tc26-cms 1 : id-tc26-cms-attrs: GOST TC26 SMS attributes + -+ return 1; -+} ++id-tc26-cms-attrs 1 : id-tc26-mac-attr: GOST TC26 SMS content-mac attribute + - /* Key Transport Recipient Info (KTRI) routines */ - - /* Initialise a ktri based on passed certificate and key */ -@@ -175,8 +210,8 @@ - * Add a recipient certificate using appropriate type of RecipientInfo - */ + id-tc26 1 : id-tc26-algorithms + id-tc26-algorithms 1 : id-tc26-sign + !Cname id-GostR3410-2012-256 +@@ -1344,11 +1352,11 @@ id-tc26-mac 2 : id-tc26-hmac-gost-3411-2012-512 : HMAC GOST 34.11-2012 512 bit --CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, -- X509 *recip, unsigned int flags) -+CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, -+ EVP_PKEY *originatorPrivKey, X509 * originator, unsigned int flags) - { - CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; -@@ -192,7 +227,7 @@ + id-tc26-algorithms 5 : id-tc26-cipher + id-tc26-cipher 1 : id-tc26-cipher-gostr3412-2015-magma +-id-tc26-cipher-gostr3412-2015-magma 1 : id-tc26-cipher-gostr3412-2015-magma-ctracpkm +-id-tc26-cipher-gostr3412-2015-magma 2 : id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac ++id-tc26-cipher-gostr3412-2015-magma 1 : magma-ctr-acpkm ++id-tc26-cipher-gostr3412-2015-magma 2 : magma-ctr-acpkm-omac + id-tc26-cipher 2 : id-tc26-cipher-gostr3412-2015-kuznyechik +-id-tc26-cipher-gostr3412-2015-kuznyechik 1 : id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm +-id-tc26-cipher-gostr3412-2015-kuznyechik 2 : id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac ++id-tc26-cipher-gostr3412-2015-kuznyechik 1 : kuznyechik-ctr-acpkm ++id-tc26-cipher-gostr3412-2015-kuznyechik 2 : kuznyechik-ctr-acpkm-omac - pk = X509_get0_pubkey(recip); - if (!pk) { -- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); -+ CMSerr(CMS_F_CMS_ADD1_RECIPIENT, CMS_R_ERROR_GETTING_PUBLIC_KEY); - goto err; - } + id-tc26-algorithms 6 : id-tc26-agreement + id-tc26-agreement 1 : id-tc26-agreement-gost-3410-2012-256 +@@ -1356,9 +1364,9 @@ id-tc26-agreement 2 : id-tc26-agreement-gost-3410-2012-512 -@@ -204,12 +239,12 @@ - break; + id-tc26-algorithms 7 : id-tc26-wrap + id-tc26-wrap 1 : id-tc26-wrap-gostr3412-2015-magma +-id-tc26-wrap-gostr3412-2015-magma 1 : id-tc26-wrap-gostr3412-2015-magma-kexp15 ++id-tc26-wrap-gostr3412-2015-magma 1 : magma-kexp15 + id-tc26-wrap 2 : id-tc26-wrap-gostr3412-2015-kuznyechik +-id-tc26-wrap-gostr3412-2015-kuznyechik 1 : id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15 ++id-tc26-wrap-gostr3412-2015-kuznyechik 1 : kuznyechik-kexp15 - case CMS_RECIPINFO_AGREE: -- if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) -+ if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator, originatorPrivKey, flags)) - goto err; - break; + id-tc26 2 : id-tc26-constants - default: -- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, -+ CMSerr(CMS_F_CMS_ADD1_RECIPIENT, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; +@@ -1382,16 +1390,25 @@ id-tc26-gost-28147-constants 1 : id-tc26-gost-28147-param-Z : GOST 28147-89 TC26 + member-body 643 3 131 1 1 : INN : INN + member-body 643 100 1 : OGRN : OGRN + member-body 643 100 3 : SNILS : SNILS ++member-body 643 100 5 : OGRNIP : OGRNIP + member-body 643 100 111 : subjectSignTool : Signing Tool of Subject + member-body 643 100 112 : issuerSignTool : Signing Tool of Issuer ++member-body 643 100 113 : classSignTool : Class of Signing Tool ++member-body 643 100 113 1 : classSignToolKC1 : Class of Signing Tool KC1 ++member-body 643 100 113 2 : classSignToolKC2 : Class of Signing Tool KC2 ++member-body 643 100 113 3 : classSignToolKC3 : Class of Signing Tool KC3 ++member-body 643 100 113 4 : classSignToolKB1 : Class of Signing Tool KB1 ++member-body 643 100 113 5 : classSignToolKB2 : Class of Signing Tool KB2 ++member-body 643 100 113 6 : classSignToolKA1 : Class of Signing Tool KA1 -@@ -221,7 +256,7 @@ - return ri; + #GOST R34.13-2015 Grasshopper "Kuznechik" +- : grasshopper-ecb +- : grasshopper-ctr +- : grasshopper-ofb +- : grasshopper-cbc +- : grasshopper-cfb +- : grasshopper-mac ++ : kuznyechik-ecb ++ : kuznyechik-ctr ++ : kuznyechik-ofb ++ : kuznyechik-cbc ++ : kuznyechik-cfb ++ : kuznyechik-mac ++ : kuznyechik-mgm - merr: -- CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); -+ CMSerr(CMS_F_CMS_ADD1_RECIPIENT, ERR_R_MALLOC_FAILURE); - err: - M_ASN1_free_of(ri, CMS_RecipientInfo); - return NULL; -@@ -228,6 +263,12 @@ + #GOST R34.13-2015 Magma + : magma-ecb +@@ -1400,6 +1417,7 @@ member-body 643 100 112 : issuerSignTool : Signing Tool of Issuer + : magma-cbc + : magma-cfb + : magma-mac ++ : magma-mgm - } + # Definitions for Camellia cipher - CBC MODE -+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, -+ X509 *recip, unsigned int flags) -+{ -+ return CMS_add1_recipient(cms, recip, NULL, NULL, flags); -+} -+ - int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, - EVP_PKEY **pk, X509 **recip, - X509_ALGOR **palg) -@@ -856,52 +897,90 @@ - env->version = 0; - } - --BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) -+static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms) - { -- CMS_EncryptedContentInfo *ec; -- STACK_OF(CMS_RecipientInfo) *rinfos; -- CMS_RecipientInfo *ri; -- int i, ok = 0; -- BIO *ret; -+ CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo; -+ BIO *contentBio = cms_EncryptedContent_init_bio(ec); -+ EVP_CIPHER_CTX *ctx = NULL; - -- /* Get BIO first to set up key */ -+ if (!contentBio) -+ return NULL; - -- ec = cms->d.envelopedData->encryptedContentInfo; -- ret = cms_EncryptedContent_init_bio(ec); -+ BIO_get_cipher_ctx(contentBio, &ctx); -+ if (ctx == NULL) { -+ BIO_free(contentBio); -+ return NULL; -+ } -+/* -+ * If the selected cipher supports unprotected attributes, -+ * deal with it using special ctrl function -+ */ -+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC && -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 0, cms->d.envelopedData->unprotectedAttrs) <= 0) { -+ BIO_free(contentBio); -+ return NULL; -+ } -+ return contentBio; -+} - -- /* If error or no cipher end of processing */ -+static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms) -+{ -+ CMS_EncryptedContentInfo *ec; -+ STACK_OF(CMS_RecipientInfo) *rinfos; -+ CMS_RecipientInfo *ri; -+ int i, ok = 0; -+ BIO *ret; - -- if (!ret || !ec->cipher) -- return ret; -+ /* Get BIO first to set up key */ - -- /* Now encrypt content key according to each RecipientInfo type */ -+ ec = cms->d.envelopedData->encryptedContentInfo; -+ ret = cms_EncryptedContent_init_bio(ec); - -- rinfos = cms->d.envelopedData->recipientInfos; -+ /* If error or no cipher end of processing */ - -- for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { -- ri = sk_CMS_RecipientInfo_value(rinfos, i); -- if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { -- CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, -- CMS_R_ERROR_SETTING_RECIPIENTINFO); -- goto err; -- } -- } -- cms_env_set_version(cms->d.envelopedData); -+ if (!ret) -+ return ret; - -- ok = 1; -+ /* Now encrypt content key according to each RecipientInfo type */ - -- err: -- ec->cipher = NULL; -- OPENSSL_clear_free(ec->key, ec->keylen); -- ec->key = NULL; -- ec->keylen = 0; -- if (ok) -- return ret; -- BIO_free(ret); -- return NULL; -+ rinfos = cms->d.envelopedData->recipientInfos; - -+ for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { -+ ri = sk_CMS_RecipientInfo_value(rinfos, i); -+ if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { -+ CMSerr(CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO, -+ CMS_R_ERROR_SETTING_RECIPIENTINFO); -+ goto err; -+ } -+ } -+ cms_env_set_version(cms->d.envelopedData); /* FIXME move lower? */ -+ -+ ok = 1; -+ -+err: -+ ec->cipher = NULL; -+ OPENSSL_clear_free(ec->key, ec->keylen); -+ ec->key = NULL; -+ ec->keylen = 0; -+ if (ok) -+ return ret; -+ BIO_free(ret); -+ return NULL; -+ - } - -+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) -+{ -+ if (cms->d.envelopedData->encryptedContentInfo->cipher) -+ { -+ //If cipher is set it's encrypting -+ return cms_EnvelopedData_Encryption_init_bio(cms); -+ } -+ -+ //If cipher is not set it's decrypting -+ return cms_EnvelopedData_Decryption_init_bio(cms); -+} -+ - /* - * Get RecipientInfo type (if any) supported by a key (public or private). To - * retain compatibility with previous behaviour if the ctrl value isn't -@@ -917,3 +996,25 @@ - } - return CMS_RECIPINFO_TRANS; - } -+ -+int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type) -+{ -+ if (pk->ameth && pk->ameth->pkey_ctrl) -+ { -+ int i, r; -+ i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, ri_type, &r); -+ if (i > 0) -+ return r; -+ } -+ -+ //if ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED not supported -+ -+ int supportedRiType = cms_pkey_get_ri_type(pk); -+ -+ if (supportedRiType < 0) -+ { -+ return 0; -+ } -+ -+ return (supportedRiType == ri_type); -+} -Index: crypto/cms/cms_err.c -=================================================================== ---- crypto/cms/cms_err.c (revision 14523) -+++ crypto/cms/cms_err.c (working copy) -@@ -22,6 +22,7 @@ - "CMS_add0_recipient_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECEIPTREQUEST, 0), - "CMS_add1_ReceiptRequest"}, -+ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECIPIENT, 0), "CMS_add1_recipient"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECIPIENT_CERT, 0), - "CMS_add1_recipient_cert"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNER, 0), "CMS_add1_signer"}, -@@ -45,6 +46,8 @@ - "CMS_decrypt_set1_password"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PKEY, 0), - "CMS_decrypt_set1_pkey"}, -+ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER, 0), -+ "CMS_decrypt_set1_pkey_and_peer"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, 0), - "cms_DigestAlgorithm_find_ctx"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, 0), -@@ -66,6 +69,12 @@ - "CMS_EncryptedData_set1_key"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_CREATE, 0), - "CMS_EnvelopedData_create"}, -+ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_DECRYPTION_INIT_BIO, 0), -+ "cms_EnvelopedData_Decryption_init_bio"}, -+ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO, 0), -+ "cms_EnvelopedData_Encryption_init_bio"}, -+ {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_FINAL, 0), -+ "cms_EnvelopedData_final"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 0), - "cms_EnvelopedData_init_bio"}, - {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPED_DATA_INIT, 0), -Index: crypto/x509v3/standard_exts.h -=================================================================== ---- crypto/x509v3/standard_exts.h (revision 14523) -+++ crypto/x509v3/standard_exts.h (working copy) -@@ -68,6 +68,8 @@ +diff --git crypto/x509v3/build.info crypto/x509v3/build.info +index 4ab64884..322a1212 100644 +--- crypto/x509v3/build.info ++++ crypto/x509v3/build.info +@@ -5,4 +5,4 @@ SOURCE[../../libcrypto]=\ + v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \ + v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \ + pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ +- v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c ++ v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c v3_rus.c +diff --git crypto/x509v3/ext_dat.h crypto/x509v3/ext_dat.h +index 762e264b..022816e2 100644 +--- crypto/x509v3/ext_dat.h ++++ crypto/x509v3/ext_dat.h +@@ -21,5 +21,6 @@ extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; + extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; + extern const X509V3_EXT_METHOD v3_addr, v3_asid; + extern const X509V3_EXT_METHOD v3_ct_scts[3]; ++extern const X509V3_EXT_METHOD v3_subject_sign_tool, v3_issuer_sign_tool; + extern const X509V3_EXT_METHOD v3_tls_feature; + extern const X509V3_EXT_METHOD v3_ext_admission; +diff --git crypto/x509v3/standard_exts.h crypto/x509v3/standard_exts.h +index 944f4de0..536b3d25 100644 +--- crypto/x509v3/standard_exts.h ++++ crypto/x509v3/standard_exts.h +@@ -68,6 +68,8 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &v3_ct_scts[1], &v3_ct_scts[2], #endif @@ -948,51 +1075,11 @@ Index: crypto/x509v3/standard_exts.h &v3_tls_feature, &v3_ext_admission }; -Index: crypto/x509v3/v3err.c -=================================================================== ---- crypto/x509v3/v3err.c (revision 14523) -+++ crypto/x509v3/v3err.c (working copy) -@@ -1,6 +1,6 @@ - /* - * Generated by util/mkerr.pl DO NOT EDIT -- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy -@@ -37,6 +37,8 @@ - "i2s_ASN1_IA5STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_INTEGER, 0), - "i2s_ASN1_INTEGER"}, -+ {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_UTF8STRING, 0), -+ "i2s_ASN1_UTF8STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2V_AUTHORITY_INFO_ACCESS, 0), - "i2v_AUTHORITY_INFO_ACCESS"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_LEVEL_ADD_NODE, 0), "level_add_node"}, -@@ -58,6 +60,8 @@ - "s2i_ASN1_INTEGER"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_OCTET_STRING, 0), - "s2i_ASN1_OCTET_STRING"}, -+ {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_UTF8STRING, 0), -+ "s2i_ASN1_UTF8STRING"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_SKEY_ID, 0), "s2i_skey_id"}, - {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SET_DIST_POINT_NAME, 0), - "set_dist_point_name"}, -Index: crypto/x509v3/build.info -=================================================================== ---- crypto/x509v3/build.info (revision 14523) -+++ crypto/x509v3/build.info (working copy) -@@ -5,4 +5,4 @@ - v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \ - v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \ - pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ -- v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c -+ v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c v3_rus.c -Index: crypto/x509v3/v3_alt.c -=================================================================== ---- crypto/x509v3/v3_alt.c (revision 14523) -+++ crypto/x509v3/v3_alt.c (working copy) -@@ -24,13 +24,46 @@ +diff --git crypto/x509v3/v3_alt.c crypto/x509v3/v3_alt.c +index 7c32d403..91846eb3 100644 +--- crypto/x509v3/v3_alt.c ++++ crypto/x509v3/v3_alt.c +@@ -25,26 +25,59 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); @@ -1041,7 +1128,6 @@ Index: crypto/x509v3/v3_alt.c {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, -@@ -37,13 +70,13 @@ 0, 0, (X509V3_EXT_I2V) i2v_GENERAL_NAMES, (X509V3_EXT_V2I)v2i_issuer_alt, @@ -1057,7 +1143,7 @@ Index: crypto/x509v3/v3_alt.c }; STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, -@@ -79,7 +112,7 @@ +@@ -80,7 +113,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, STACK_OF(CONF_VALUE) *ret) { unsigned char *p; @@ -1066,7 +1152,7 @@ Index: crypto/x509v3/v3_alt.c int i; switch (gen->type) { -@@ -114,7 +147,7 @@ +@@ -118,7 +151,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, break; case GEN_DIRNAME: @@ -1075,7 +1161,7 @@ Index: crypto/x509v3/v3_alt.c || !X509V3_add_value("DirName", oline, &ret)) return NULL; break; -@@ -151,6 +184,96 @@ +@@ -155,6 +188,96 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, return ret; } @@ -1172,21 +1258,11 @@ Index: crypto/x509v3/v3_alt.c int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { unsigned char *p; -Index: crypto/x509v3/ext_dat.h -=================================================================== ---- crypto/x509v3/ext_dat.h (revision 14523) -+++ crypto/x509v3/ext_dat.h (working copy) -@@ -21,5 +21,6 @@ - extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; - extern const X509V3_EXT_METHOD v3_addr, v3_asid; - extern const X509V3_EXT_METHOD v3_ct_scts[3]; -+extern const X509V3_EXT_METHOD v3_subject_sign_tool, v3_issuer_sign_tool; - extern const X509V3_EXT_METHOD v3_tls_feature; - extern const X509V3_EXT_METHOD v3_ext_admission; -Index: crypto/x509v3/v3_rus.c -=================================================================== ---- crypto/x509v3/v3_rus.c (nonexistent) -+++ crypto/x509v3/v3_rus.c (revision 14744) +diff --git crypto/x509v3/v3_rus.c crypto/x509v3/v3_rus.c +new file mode 100644 +index 00000000..415c9165 +--- /dev/null ++++ crypto/x509v3/v3_rus.c @@ -0,0 +1,168 @@ +/* v3_rus.c */ +/* @@ -1356,154 +1432,33 @@ Index: crypto/x509v3/v3_rus.c + 0, + (X509V3_EXT_I2R)i2r_ISSUER_SIGN_TOOL, 0, NULL +}; -Index: crypto/err/openssl.txt -=================================================================== ---- crypto/err/openssl.txt (revision 14523) -+++ crypto/err/openssl.txt (working copy) -@@ -239,6 +239,7 @@ - CMS_F_CMS_ADD0_RECIPIENT_KEY:100:CMS_add0_recipient_key - CMS_F_CMS_ADD0_RECIPIENT_PASSWORD:165:CMS_add0_recipient_password - CMS_F_CMS_ADD1_RECEIPTREQUEST:158:CMS_add1_ReceiptRequest -+CMS_F_CMS_ADD1_RECIPIENT:181:CMS_add1_recipient - CMS_F_CMS_ADD1_RECIPIENT_CERT:101:CMS_add1_recipient_cert - CMS_F_CMS_ADD1_SIGNER:102:CMS_add1_signer - CMS_F_CMS_ADD1_SIGNINGTIME:103:cms_add1_signingTime -@@ -254,6 +255,7 @@ - CMS_F_CMS_DECRYPT_SET1_KEY:113:CMS_decrypt_set1_key - CMS_F_CMS_DECRYPT_SET1_PASSWORD:166:CMS_decrypt_set1_password - CMS_F_CMS_DECRYPT_SET1_PKEY:114:CMS_decrypt_set1_pkey -+CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER:182:CMS_decrypt_set1_pkey_and_peer - CMS_F_CMS_DIGESTALGORITHM_FIND_CTX:115:cms_DigestAlgorithm_find_ctx - CMS_F_CMS_DIGESTALGORITHM_INIT_BIO:116:cms_DigestAlgorithm_init_bio - CMS_F_CMS_DIGESTEDDATA_DO_FINAL:117:cms_DigestedData_do_final -@@ -266,6 +268,11 @@ - CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT:122:CMS_EncryptedData_encrypt - CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY:123:CMS_EncryptedData_set1_key - CMS_F_CMS_ENVELOPEDDATA_CREATE:124:CMS_EnvelopedData_create -+CMS_F_CMS_ENVELOPEDDATA_DECRYPTION_INIT_BIO:184:\ -+ cms_EnvelopedData_Decryption_init_bio -+CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO:185:\ -+ cms_EnvelopedData_Encryption_init_bio -+CMS_F_CMS_ENVELOPEDDATA_FINAL:186:cms_EnvelopedData_final - CMS_F_CMS_ENVELOPEDDATA_INIT_BIO:125:cms_EnvelopedData_init_bio - CMS_F_CMS_ENVELOPED_DATA_INIT:126:cms_enveloped_data_init - CMS_F_CMS_ENV_ASN1_CTRL:171:cms_env_asn1_ctrl -@@ -1180,7 +1187,7 @@ - SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE:601:\ - ossl_statem_server_post_process_message - SSL_F_OSSL_STATEM_SERVER_POST_WORK:602:ossl_statem_server_post_work --SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640: -+SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640:ossl_statem_server_pre_work - SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE:603:ossl_statem_server_process_message - SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION:418:ossl_statem_server_read_transition - SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION:604:\ -@@ -1395,6 +1402,7 @@ - SSL_F_TLS_CONSTRUCT_CKE_DHE:404:tls_construct_cke_dhe - SSL_F_TLS_CONSTRUCT_CKE_ECDHE:405:tls_construct_cke_ecdhe - SSL_F_TLS_CONSTRUCT_CKE_GOST:406:tls_construct_cke_gost -+SSL_F_TLS_CONSTRUCT_CKE_GOST18:639:tls_construct_cke_gost18 - SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE:407:tls_construct_cke_psk_preamble - SSL_F_TLS_CONSTRUCT_CKE_RSA:409:tls_construct_cke_rsa - SSL_F_TLS_CONSTRUCT_CKE_SRP:410:tls_construct_cke_srp -@@ -1526,6 +1534,7 @@ - SSL_F_TLS_PROCESS_CKE_DHE:411:tls_process_cke_dhe - SSL_F_TLS_PROCESS_CKE_ECDHE:412:tls_process_cke_ecdhe - SSL_F_TLS_PROCESS_CKE_GOST:413:tls_process_cke_gost -+SSL_F_TLS_PROCESS_CKE_GOST18:641:tls_process_cke_gost18 - SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE:414:tls_process_cke_psk_preamble - SSL_F_TLS_PROCESS_CKE_RSA:415:tls_process_cke_rsa - SSL_F_TLS_PROCESS_CKE_SRP:416:tls_process_cke_srp -@@ -1648,6 +1657,7 @@ - X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED - X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING - X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER -+X509V3_F_I2S_ASN1_UTF8STRING:173:i2s_ASN1_UTF8STRING - X509V3_F_I2V_AUTHORITY_INFO_ACCESS:138:i2v_AUTHORITY_INFO_ACCESS - X509V3_F_LEVEL_ADD_NODE:168:level_add_node - X509V3_F_NOTICE_SECTION:132:notice_section -@@ -1662,6 +1672,7 @@ - X509V3_F_S2I_ASN1_IA5STRING:100:s2i_ASN1_IA5STRING - X509V3_F_S2I_ASN1_INTEGER:108:s2i_ASN1_INTEGER - X509V3_F_S2I_ASN1_OCTET_STRING:112:s2i_ASN1_OCTET_STRING -+X509V3_F_S2I_ASN1_UTF8STRING:174:s2i_ASN1_UTF8STRING - X509V3_F_S2I_SKEY_ID:115:s2i_skey_id - X509V3_F_SET_DIST_POINT_NAME:158:set_dist_point_name - X509V3_F_SXNET_ADD_ID_ASC:125:SXNET_add_id_asc -Index: crypto/asn1/p8_pkey.c -=================================================================== ---- crypto/asn1/p8_pkey.c (revision 14523) -+++ crypto/asn1/p8_pkey.c (working copy) -@@ -78,3 +78,18 @@ - return 1; - return 0; - } -+ -+int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, int type, -+ const unsigned char *bytes, int len) -+{ -+ if (X509at_add1_attr_by_OBJ(&p8->attributes, obj, type, bytes, len) != NULL) -+ return 1; -+ return 0; -+} -+ -+int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr) -+{ -+ if (X509at_add1_attr(&p8->attributes, attr) != NULL) -+ return 1; -+ return 0; -+} -Index: include/openssl/sslerr.h -=================================================================== ---- include/openssl/sslerr.h (revision 14523) -+++ include/openssl/sslerr.h (working copy) -@@ -11,9 +11,7 @@ - #ifndef HEADER_SSLERR_H - # define HEADER_SSLERR_H - --# ifndef HEADER_SYMHACKS_H --# include --# endif -+# include - - # ifdef __cplusplus - extern "C" -@@ -296,6 +294,7 @@ - # define SSL_F_TLS_CONSTRUCT_CKE_DHE 404 - # define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 405 - # define SSL_F_TLS_CONSTRUCT_CKE_GOST 406 -+# define SSL_F_TLS_CONSTRUCT_CKE_GOST18 639 - # define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 407 - # define SSL_F_TLS_CONSTRUCT_CKE_RSA 409 - # define SSL_F_TLS_CONSTRUCT_CKE_SRP 410 -@@ -420,6 +419,7 @@ - # define SSL_F_TLS_PROCESS_CKE_DHE 411 - # define SSL_F_TLS_PROCESS_CKE_ECDHE 412 - # define SSL_F_TLS_PROCESS_CKE_GOST 413 -+# define SSL_F_TLS_PROCESS_CKE_GOST18 641 - # define SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE 414 - # define SSL_F_TLS_PROCESS_CKE_RSA 415 - # define SSL_F_TLS_PROCESS_CKE_SRP 416 -Index: include/openssl/x509.h -=================================================================== ---- include/openssl/x509.h (revision 14523) -+++ include/openssl/x509.h (working copy) -@@ -1020,8 +1020,11 @@ - - const STACK_OF(X509_ATTRIBUTE) * - PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); -+int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr); - int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, - const unsigned char *bytes, int len); -+int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, -+ int type, const unsigned char *bytes, int len); - - int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, - int ptype, void *pval, -Index: include/openssl/cms.h -=================================================================== ---- include/openssl/cms.h (revision 14523) -+++ include/openssl/cms.h (working copy) -@@ -73,6 +73,7 @@ +diff --git crypto/x509v3/v3err.c crypto/x509v3/v3err.c +index 8b2918a6..3c9f2332 100644 +--- crypto/x509v3/v3err.c ++++ crypto/x509v3/v3err.c +@@ -37,6 +37,8 @@ static const ERR_STRING_DATA X509V3_str_functs[] = { + "i2s_ASN1_IA5STRING"}, + {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_INTEGER, 0), + "i2s_ASN1_INTEGER"}, ++ {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2S_ASN1_UTF8STRING, 0), ++ "i2s_ASN1_UTF8STRING"}, + {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2V_AUTHORITY_INFO_ACCESS, 0), + "i2v_AUTHORITY_INFO_ACCESS"}, + {ERR_PACK(ERR_LIB_X509V3, X509V3_F_I2V_AUTHORITY_KEYID, 0), +@@ -60,6 +62,8 @@ static const ERR_STRING_DATA X509V3_str_functs[] = { + "s2i_ASN1_INTEGER"}, + {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_OCTET_STRING, 0), + "s2i_ASN1_OCTET_STRING"}, ++ {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_ASN1_UTF8STRING, 0), ++ "s2i_ASN1_UTF8STRING"}, + {ERR_PACK(ERR_LIB_X509V3, X509V3_F_S2I_SKEY_ID, 0), "s2i_skey_id"}, + {ERR_PACK(ERR_LIB_X509V3, X509V3_F_SET_DIST_POINT_NAME, 0), + "set_dist_point_name"}, +diff --git include/openssl/cms.h include/openssl/cms.h +index c7627968..c90a01fa 100644 +--- include/openssl/cms.h ++++ include/openssl/cms.h +@@ -73,6 +73,7 @@ DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) # define CMS_DEBUG_DECRYPT 0x20000 # define CMS_KEY_PARAM 0x40000 # define CMS_ASCIICRLF 0x80000 @@ -1511,7 +1466,7 @@ Index: include/openssl/cms.h const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms); -@@ -143,6 +144,7 @@ +@@ -143,6 +144,7 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *dcont, BIO *out, unsigned int flags); int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); @@ -1519,7 +1474,7 @@ Index: include/openssl/cms.h int CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key, size_t keylen, const unsigned char *id, size_t idlen); -@@ -155,6 +157,8 @@ +@@ -155,6 +157,8 @@ EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags); @@ -1528,7 +1483,7 @@ Index: include/openssl/cms.h int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, -@@ -319,6 +323,7 @@ +@@ -319,6 +323,7 @@ int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, X509 *cert); int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); @@ -1536,61 +1491,128 @@ Index: include/openssl/cms.h EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, -Index: include/openssl/tls1.h -=================================================================== ---- include/openssl/tls1.h (revision 14523) -+++ include/openssl/tls1.h (working copy) -@@ -613,6 +613,12 @@ - # define TLS1_3_CK_AES_128_CCM_SHA256 0x03001304 - # define TLS1_3_CK_AES_128_CCM_8_SHA256 0x03001305 +diff --git include/openssl/cmserr.h include/openssl/cmserr.h +index 7dbc13dc..9131e075 100644 +--- include/openssl/cmserr.h ++++ include/openssl/cmserr.h +@@ -11,9 +11,7 @@ + #ifndef HEADER_CMSERR_H + # define HEADER_CMSERR_H -+/* https://tools.ietf.org/html/draft-smyshlyaev-tls13-gost-suites */ -+# define TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L 0x0300C103 -+# define TLS_GOSTR341112_256_WITH_MAGMA_MGM_L 0x0300C104 -+# define TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S 0x0300C105 -+# define TLS_GOSTR341112_256_WITH_MAGMA_MGM_S 0x0300C106 +-# ifndef HEADER_SYMHACKS_H +-# include +-# endif ++# include + + # include + +@@ -32,6 +30,7 @@ int ERR_load_CMS_strings(void); + # define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 + # define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 + # define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 ++# define CMS_F_CMS_ADD1_RECIPIENT 181 + # define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 + # define CMS_F_CMS_ADD1_SIGNER 102 + # define CMS_F_CMS_ADD1_SIGNINGTIME 103 +@@ -47,6 +46,7 @@ int ERR_load_CMS_strings(void); + # define CMS_F_CMS_DECRYPT_SET1_KEY 113 + # define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 + # define CMS_F_CMS_DECRYPT_SET1_PKEY 114 ++# define CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER 182 + # define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 + # define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 + # define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +@@ -59,6 +59,9 @@ int ERR_load_CMS_strings(void); + # define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 + # define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 + # define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 ++# define CMS_F_CMS_ENVELOPEDDATA_DECRYPTION_INIT_BIO 184 ++# define CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO 185 ++# define CMS_F_CMS_ENVELOPEDDATA_FINAL 186 + # define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 + # define CMS_F_CMS_ENVELOPED_DATA_INIT 126 + # define CMS_F_CMS_ENV_ASN1_CTRL 171 +diff --git include/openssl/evp.h include/openssl/evp.h +index a411f3f2..8172316e 100644 +--- include/openssl/evp.h ++++ include/openssl/evp.h +@@ -20,6 +20,9 @@ + # define EVP_MAX_KEY_LENGTH 64 + # define EVP_MAX_IV_LENGTH 16 + # define EVP_MAX_BLOCK_LENGTH 32 ++# define EVP_MAX_AEAD_TAG_LEN 16/* longest known AEAD tag size */ + - /* Aria ciphersuites from RFC6209 */ - # define TLS1_CK_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C050 - # define TLS1_CK_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C051 -@@ -1135,8 +1141,10 @@ - # define TLS_CT_RSA_FIXED_ECDH 65 - # define TLS_CT_ECDSA_FIXED_ECDH 66 - # define TLS_CT_GOST01_SIGN 22 --# define TLS_CT_GOST12_SIGN 238 --# define TLS_CT_GOST12_512_SIGN 239 -+# define TLS_CT_GOST12_SIGN 67 -+# define TLS_CT_GOST12_512_SIGN 68 -+# define TLS_CT_GOST12_SIGN_LEGACY 238 -+# define TLS_CT_GOST12_512_SIGN_LEGACY 239 ++#define EVP_MAX_MAC_SIZE EVP_MAX_AEAD_TAG_LEN + + # define PKCS5_SALT_LEN 8 + /* Default PKCS#5 iteration count */ +@@ -139,6 +142,7 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, + # define EVP_MD_CTRL_DIGALGID 0x1 + # define EVP_MD_CTRL_MICALG 0x2 + # define EVP_MD_CTRL_XOF_LEN 0x3 ++# define EVP_MD_CTRL_TLSTREE 0x4 + /* Minimum Algorithm specific ctrl value */ + +@@ -277,8 +281,9 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + # define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 + # define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 + /* Cipher can handle pipeline operations */ +-# define EVP_CIPH_FLAG_PIPELINE 0X800000 +- ++# define EVP_CIPH_FLAG_PIPELINE 0x800000 ++# define EVP_CIPH_FLAG_CIPHER_WITH_MAC 0x1000000 ++# define EVP_CIPH_FLAG_GET_WRAP_CIPHER 0X4000000 /* - * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see -Index: include/openssl/ssl.h -=================================================================== ---- include/openssl/ssl.h (revision 14523) -+++ include/openssl/ssl.h (working copy) -@@ -81,6 +81,7 @@ - # define SSL_TXT_kECDHEPSK "kECDHEPSK" - # define SSL_TXT_kDHEPSK "kDHEPSK" - # define SSL_TXT_kGOST "kGOST" -+# define SSL_TXT_kGOST18 "kGOST18" - # define SSL_TXT_kSRP "kSRP" + * Cipher context flag to indicate we can handle wrap mode: if allowed in + * older applications it could overflow buffers. +@@ -352,6 +357,20 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + # define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24 - # define SSL_TXT_aRSA "aRSA" -@@ -908,6 +909,8 @@ + # define EVP_CTRL_GET_IVLEN 0x25 ++/* Indicates TLSTREE key diversification during TLS processing */ ++# define EVP_CTRL_TLSTREE 0x26 ++ ++#define EVP_CTRL_AEAD_MAX_TAG_LEN 0x27 ++# define EVP_CTRL_GET_WRAP_CIPHER 0X28 ++ ++# define EVP_CTRL_GET_MAC_LEN EVP_CTRL_AEAD_MAX_TAG_LEN ++# define EVP_CTRL_GET_MAC EVP_CTRL_AEAD_GET_TAG ++# define EVP_CTRL_SET_EXPECTED_MAC EVP_CTRL_AEAD_SET_TAG ++/* GOST CMS requires processing unprotected attributes in some cases*/ ++# define EVP_CTRL_PROCESS_UNPROTECTED 0x29 ++/* Set GOST TLSTREE params */ ++# define EVP_CTRL_SET_TLSTREE_PARAMS 0x2A ++ - # define SSL_MAC_FLAG_READ_MAC_STREAM 1 - # define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 -+# define SSL_MAC_FLAG_READ_MAC_TLSTREE 4 -+# define SSL_MAC_FLAG_WRITE_MAC_TLSTREE 8 + /* Padding modes */ + #define EVP_PADDING_PKCS7 1 +@@ -390,6 +409,10 @@ typedef struct { + /* Length of CCM8 tag for TLS */ + # define EVP_CCM8_TLS_TAG_LEN 8 - /* - * A callback for logging out TLS key material. This callback should log out -Index: include/openssl/obj_mac.h -=================================================================== ---- include/openssl/obj_mac.h (revision 14523) -+++ include/openssl/obj_mac.h (working copy) ++/* GOST TLS 1.3 tag lengths */ ++# define EVP_MAGMA_TLS_TAG_LEN 8 ++# define EVP_KUZNYECHIK_TLS_TAG_LEN 16 ++ + /* Length of tag for TLS */ + # define EVP_CHACHAPOLY_TLS_TAG_LEN 16 + +@@ -1142,6 +1165,10 @@ int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num); + # define ASN1_PKEY_CTRL_SET1_TLS_ENCPT 0x9 + # define ASN1_PKEY_CTRL_GET1_TLS_ENCPT 0xa + ++// This control use for decryption ++// when algorithm support multiple ri types ++# define ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED 0xb ++ + int EVP_PKEY_asn1_get_count(void); + const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); + const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +diff --git include/openssl/obj_mac.h include/openssl/obj_mac.h +index eb812ed1..260357b1 100644 +--- include/openssl/obj_mac.h ++++ include/openssl/obj_mac.h @@ -4162,6 +4162,26 @@ #define NID_id_GostR3410_2001_ParamSet_cc 854 #define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L @@ -1692,7 +1714,7 @@ Index: include/openssl/obj_mac.h #define SN_subjectSignTool "subjectSignTool" #define LN_subjectSignTool "Signing Tool of Subject" #define NID_subjectSignTool 1007 -@@ -4380,24 +4405,62 @@ +@@ -4380,23 +4405,61 @@ #define NID_issuerSignTool 1008 #define OBJ_issuerSignTool OBJ_member_body,643L,100L,112L @@ -1702,56 +1724,56 @@ Index: include/openssl/obj_mac.h +#define LN_classSignTool "Class of Signing Tool" +#define NID_classSignTool 1196 +#define OBJ_classSignTool OBJ_member_body,643L,100L,113L - --#define SN_grasshopper_ctr "grasshopper-ctr" --#define NID_grasshopper_ctr 1013 ++ +#define SN_classSignToolKC1 "classSignToolKC1" +#define LN_classSignToolKC1 "Class of Signing Tool KC1" +#define NID_classSignToolKC1 1197 +#define OBJ_classSignToolKC1 OBJ_member_body,643L,100L,113L,1L - --#define SN_grasshopper_ofb "grasshopper-ofb" --#define NID_grasshopper_ofb 1014 ++ +#define SN_classSignToolKC2 "classSignToolKC2" +#define LN_classSignToolKC2 "Class of Signing Tool KC2" +#define NID_classSignToolKC2 1198 +#define OBJ_classSignToolKC2 OBJ_member_body,643L,100L,113L,2L - --#define SN_grasshopper_cbc "grasshopper-cbc" --#define NID_grasshopper_cbc 1015 ++ +#define SN_classSignToolKC3 "classSignToolKC3" +#define LN_classSignToolKC3 "Class of Signing Tool KC3" +#define NID_classSignToolKC3 1199 +#define OBJ_classSignToolKC3 OBJ_member_body,643L,100L,113L,3L - --#define SN_grasshopper_cfb "grasshopper-cfb" --#define NID_grasshopper_cfb 1016 ++ +#define SN_classSignToolKB1 "classSignToolKB1" +#define LN_classSignToolKB1 "Class of Signing Tool KB1" +#define NID_classSignToolKB1 1200 +#define OBJ_classSignToolKB1 OBJ_member_body,643L,100L,113L,4L - --#define SN_grasshopper_mac "grasshopper-mac" --#define NID_grasshopper_mac 1017 ++ +#define SN_classSignToolKB2 "classSignToolKB2" +#define LN_classSignToolKB2 "Class of Signing Tool KB2" +#define NID_classSignToolKB2 1201 +#define OBJ_classSignToolKB2 OBJ_member_body,643L,100L,113L,5L +-#define SN_grasshopper_ctr "grasshopper-ctr" +-#define NID_grasshopper_ctr 1013 +#define SN_classSignToolKA1 "classSignToolKA1" +#define LN_classSignToolKA1 "Class of Signing Tool KA1" +#define NID_classSignToolKA1 1202 +#define OBJ_classSignToolKA1 OBJ_member_body,643L,100L,113L,6L -+ + +-#define SN_grasshopper_ofb "grasshopper-ofb" +-#define NID_grasshopper_ofb 1014 +#define SN_kuznyechik_ecb "kuznyechik-ecb" +#define NID_kuznyechik_ecb 1012 -+ + +-#define SN_grasshopper_cbc "grasshopper-cbc" +-#define NID_grasshopper_cbc 1015 +#define SN_kuznyechik_ctr "kuznyechik-ctr" +#define NID_kuznyechik_ctr 1013 -+ + +-#define SN_grasshopper_cfb "grasshopper-cfb" +-#define NID_grasshopper_cfb 1016 +#define SN_kuznyechik_ofb "kuznyechik-ofb" +#define NID_kuznyechik_ofb 1014 -+ + +-#define SN_grasshopper_mac "grasshopper-mac" +-#define NID_grasshopper_mac 1017 +#define SN_kuznyechik_cbc "kuznyechik-cbc" +#define NID_kuznyechik_cbc 1015 + @@ -1763,10 +1785,9 @@ Index: include/openssl/obj_mac.h + +#define SN_kuznyechik_mgm "kuznyechik-mgm" +#define NID_kuznyechik_mgm 1207 -+ + #define SN_magma_ecb "magma-ecb" #define NID_magma_ecb 1187 - @@ -4416,6 +4479,9 @@ #define SN_magma_mac "magma-mac" #define NID_magma_mac 1192 @@ -1827,765 +1848,516 @@ Index: include/openssl/obj_mac.h +#define NID_grasshopper_mac NID_kuznyechik_mac + +#endif -Index: include/openssl/evp.h -=================================================================== ---- include/openssl/evp.h (revision 14523) -+++ include/openssl/evp.h (working copy) -@@ -20,7 +20,10 @@ - # define EVP_MAX_KEY_LENGTH 64 - # define EVP_MAX_IV_LENGTH 16 - # define EVP_MAX_BLOCK_LENGTH 32 -+# define EVP_MAX_AEAD_TAG_LEN 16/* longest known AEAD tag size */ +diff --git include/openssl/ssl.h include/openssl/ssl.h +index fd0c5a99..5ec06487 100644 +--- include/openssl/ssl.h ++++ include/openssl/ssl.h +@@ -81,6 +81,7 @@ extern "C" { + # define SSL_TXT_kECDHEPSK "kECDHEPSK" + # define SSL_TXT_kDHEPSK "kDHEPSK" + # define SSL_TXT_kGOST "kGOST" ++# define SSL_TXT_kGOST18 "kGOST18" + # define SSL_TXT_kSRP "kSRP" -+#define EVP_MAX_MAC_SIZE EVP_MAX_AEAD_TAG_LEN -+ - # define PKCS5_SALT_LEN 8 - /* Default PKCS#5 iteration count */ - # define PKCS5_DEFAULT_ITER 2048 -@@ -139,6 +142,7 @@ - # define EVP_MD_CTRL_DIGALGID 0x1 - # define EVP_MD_CTRL_MICALG 0x2 - # define EVP_MD_CTRL_XOF_LEN 0x3 -+# define EVP_MD_CTRL_TLSTREE 0x4 + # define SSL_TXT_aRSA "aRSA" +@@ -908,6 +909,8 @@ __owur int SSL_extension_supported(unsigned int ext_type); - /* Minimum Algorithm specific ctrl value */ + # define SSL_MAC_FLAG_READ_MAC_STREAM 1 + # define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 ++# define SSL_MAC_FLAG_READ_MAC_TLSTREE 4 ++# define SSL_MAC_FLAG_WRITE_MAC_TLSTREE 8 -@@ -277,8 +281,9 @@ - # define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 - # define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 - /* Cipher can handle pipeline operations */ --# define EVP_CIPH_FLAG_PIPELINE 0X800000 -- -+# define EVP_CIPH_FLAG_PIPELINE 0x800000 -+# define EVP_CIPH_FLAG_CIPHER_WITH_MAC 0x1000000 -+# define EVP_CIPH_FLAG_GET_WRAP_CIPHER 0X4000000 /* - * Cipher context flag to indicate we can handle wrap mode: if allowed in - * older applications it could overflow buffers. -@@ -352,7 +357,21 @@ - # define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24 - - # define EVP_CTRL_GET_IVLEN 0x25 -+/* Indicates TLSTREE key diversification during TLS processing */ -+# define EVP_CTRL_TLSTREE 0x26 - -+#define EVP_CTRL_AEAD_MAX_TAG_LEN 0x27 -+# define EVP_CTRL_GET_WRAP_CIPHER 0X28 -+ -+# define EVP_CTRL_GET_MAC_LEN EVP_CTRL_AEAD_MAX_TAG_LEN -+# define EVP_CTRL_GET_MAC EVP_CTRL_AEAD_GET_TAG -+# define EVP_CTRL_SET_EXPECTED_MAC EVP_CTRL_AEAD_SET_TAG -+/* GOST CMS requires processing unprotected attributes in some cases*/ -+# define EVP_CTRL_PROCESS_UNPROTECTED 0x29 -+/* Set GOST TLSTREE params */ -+# define EVP_CTRL_SET_TLSTREE_PARAMS 0x2A -+ -+ - /* Padding modes */ - #define EVP_PADDING_PKCS7 1 - #define EVP_PADDING_ISO7816_4 2 -@@ -390,6 +409,10 @@ - /* Length of CCM8 tag for TLS */ - # define EVP_CCM8_TLS_TAG_LEN 8 - -+/* GOST TLS 1.3 tag lengths */ -+# define EVP_MAGMA_TLS_TAG_LEN 8 -+# define EVP_KUZNYECHIK_TLS_TAG_LEN 16 -+ - /* Length of tag for TLS */ - # define EVP_CHACHAPOLY_TLS_TAG_LEN 16 - -@@ -1142,6 +1165,10 @@ - # define ASN1_PKEY_CTRL_SET1_TLS_ENCPT 0x9 - # define ASN1_PKEY_CTRL_GET1_TLS_ENCPT 0xa - -+// This control use for decryption -+// when algorithm support multiple ri types -+# define ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED 0xb -+ - int EVP_PKEY_asn1_get_count(void); - const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); - const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); -Index: include/openssl/cmserr.h -=================================================================== ---- include/openssl/cmserr.h (revision 14523) -+++ include/openssl/cmserr.h (working copy) + * A callback for logging out TLS key material. This callback should log out +diff --git include/openssl/sslerr.h include/openssl/sslerr.h +index 701d61c6..36cacab3 100644 +--- include/openssl/sslerr.h ++++ include/openssl/sslerr.h @@ -11,9 +11,7 @@ - #ifndef HEADER_CMSERR_H - # define HEADER_CMSERR_H + #ifndef HEADER_SSLERR_H + # define HEADER_SSLERR_H -# ifndef HEADER_SYMHACKS_H -# include -# endif +# include - # include + # ifdef __cplusplus + extern "C" +@@ -297,6 +295,7 @@ int ERR_load_SSL_strings(void); + # define SSL_F_TLS_CONSTRUCT_CKE_DHE 404 + # define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 405 + # define SSL_F_TLS_CONSTRUCT_CKE_GOST 406 ++# define SSL_F_TLS_CONSTRUCT_CKE_GOST18 642 + # define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 407 + # define SSL_F_TLS_CONSTRUCT_CKE_RSA 409 + # define SSL_F_TLS_CONSTRUCT_CKE_SRP 410 +@@ -421,6 +420,7 @@ int ERR_load_SSL_strings(void); + # define SSL_F_TLS_PROCESS_CKE_DHE 411 + # define SSL_F_TLS_PROCESS_CKE_ECDHE 412 + # define SSL_F_TLS_PROCESS_CKE_GOST 413 ++# define SSL_F_TLS_PROCESS_CKE_GOST18 641 + # define SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE 414 + # define SSL_F_TLS_PROCESS_CKE_RSA 415 + # define SSL_F_TLS_PROCESS_CKE_SRP 416 +diff --git include/openssl/tls1.h include/openssl/tls1.h +index 76d9fda4..6b6442f3 100644 +--- include/openssl/tls1.h ++++ include/openssl/tls1.h +@@ -613,6 +613,12 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) + # define TLS1_3_CK_AES_128_CCM_SHA256 0x03001304 + # define TLS1_3_CK_AES_128_CCM_8_SHA256 0x03001305 -@@ -32,6 +30,7 @@ - # define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 - # define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 - # define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 -+# define CMS_F_CMS_ADD1_RECIPIENT 181 - # define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 - # define CMS_F_CMS_ADD1_SIGNER 102 - # define CMS_F_CMS_ADD1_SIGNINGTIME 103 -@@ -47,6 +46,7 @@ - # define CMS_F_CMS_DECRYPT_SET1_KEY 113 - # define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 - # define CMS_F_CMS_DECRYPT_SET1_PKEY 114 -+# define CMS_F_CMS_DECRYPT_SET1_PKEY_AND_PEER 182 - # define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 - # define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 - # define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 -@@ -59,6 +59,9 @@ - # define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 - # define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 - # define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 -+# define CMS_F_CMS_ENVELOPEDDATA_DECRYPTION_INIT_BIO 184 -+# define CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO 185 -+# define CMS_F_CMS_ENVELOPEDDATA_FINAL 186 - # define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 - # define CMS_F_CMS_ENVELOPED_DATA_INIT 126 - # define CMS_F_CMS_ENV_ASN1_CTRL 171 -Index: include/openssl/x509v3err.h -=================================================================== ---- include/openssl/x509v3err.h (revision 14523) -+++ include/openssl/x509v3err.h (working copy) -@@ -37,6 +37,7 @@ ++/* https://tools.ietf.org/html/draft-smyshlyaev-tls13-gost-suites */ ++# define TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L 0x0300C103 ++# define TLS_GOSTR341112_256_WITH_MAGMA_MGM_L 0x0300C104 ++# define TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S 0x0300C105 ++# define TLS_GOSTR341112_256_WITH_MAGMA_MGM_S 0x0300C106 ++ + /* Aria ciphersuites from RFC6209 */ + # define TLS1_CK_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C050 + # define TLS1_CK_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C051 +@@ -1135,8 +1141,10 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) + # define TLS_CT_RSA_FIXED_ECDH 65 + # define TLS_CT_ECDSA_FIXED_ECDH 66 + # define TLS_CT_GOST01_SIGN 22 +-# define TLS_CT_GOST12_SIGN 238 +-# define TLS_CT_GOST12_512_SIGN 239 ++# define TLS_CT_GOST12_SIGN 67 ++# define TLS_CT_GOST12_512_SIGN 68 ++# define TLS_CT_GOST12_SIGN_LEGACY 238 ++# define TLS_CT_GOST12_512_SIGN_LEGACY 239 + + /* + * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see +diff --git include/openssl/x509.h include/openssl/x509.h +index 3ff86ec7..cdca4f5f 100644 +--- include/openssl/x509.h ++++ include/openssl/x509.h +@@ -1023,8 +1023,11 @@ int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, + + const STACK_OF(X509_ATTRIBUTE) * + PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); ++int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr); + int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len); ++int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, ++ int type, const unsigned char *bytes, int len); + + int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, +diff --git include/openssl/x509v3err.h include/openssl/x509v3err.h +index 3b9f7139..48f7a558 100644 +--- include/openssl/x509v3err.h ++++ include/openssl/x509v3err.h +@@ -37,6 +37,7 @@ int ERR_load_X509V3_strings(void); # define X509V3_F_I2S_ASN1_ENUMERATED 121 # define X509V3_F_I2S_ASN1_IA5STRING 149 # define X509V3_F_I2S_ASN1_INTEGER 120 -+# define X509V3_F_I2S_ASN1_UTF8STRING 173 ++# define X509V3_F_I2S_ASN1_UTF8STRING 175 # define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 + # define X509V3_F_I2V_AUTHORITY_KEYID 173 # define X509V3_F_LEVEL_ADD_NODE 168 - # define X509V3_F_NOTICE_SECTION 132 -@@ -51,6 +52,7 @@ +@@ -52,6 +53,7 @@ int ERR_load_X509V3_strings(void); # define X509V3_F_S2I_ASN1_IA5STRING 100 # define X509V3_F_S2I_ASN1_INTEGER 108 # define X509V3_F_S2I_ASN1_OCTET_STRING 112 -+# define X509V3_F_S2I_ASN1_UTF8STRING 174 ++# define X509V3_F_S2I_ASN1_UTF8STRING 176 # define X509V3_F_S2I_SKEY_ID 115 # define X509V3_F_SET_DIST_POINT_NAME 158 # define X509V3_F_SXNET_ADD_ID_ASC 125 -Index: Configurations/unix-Makefile.tmpl -=================================================================== ---- Configurations/unix-Makefile.tmpl (revision 14523) -+++ Configurations/unix-Makefile.tmpl (working copy) -@@ -888,6 +888,7 @@ - crypto/objects/obj_mac.num \ - crypto/objects/obj_xref.txt \ - > crypto/objects/obj_xref.h ) -+ ( cd $(SRCDIR); cat crypto/objects/obj_compat.h >> include/openssl/obj_mac.h ) +diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c +index f1585447..b4ed24fd 100644 +--- ssl/record/ssl3_record.c ++++ ssl/record/ssl3_record.c +@@ -944,6 +944,8 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) + unsigned char padval; + int imac_size; + const EVP_CIPHER *enc; ++ int tlstree_enc = (sending ? (s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) ++ : (s->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE)); - generate_crypto_conf: - ( cd $(SRCDIR); $(PERL) crypto/conf/keysets.pl \ -Index: ssl/t1_trce.c -=================================================================== ---- ssl/t1_trce.c (revision 14523) -+++ ssl/t1_trce.c (working copy) -@@ -443,6 +443,9 @@ - {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, - {0xFF85, "GOST2012-GOST8912-GOST8912"}, - {0xFF87, "GOST2012-NULL-GOST12"}, -+ {0xC100, "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC"}, -+ {0xC101, "GOST2012-MAGMA-MAGMAOMAC"}, -+ {0xC102, "GOST2012-GOST8912-IANA"}, - }; + if (n_recs == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, +@@ -1036,7 +1038,6 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) - /* Compression methods */ -@@ -522,6 +525,13 @@ - {28, "brainpoolP512r1"}, - {29, "ecdh_x25519"}, - {30, "ecdh_x448"}, -+ {34, "GC256A"}, -+ {35, "GC256B"}, -+ {36, "GC256C"}, -+ {37, "GC256D"}, -+ {38, "GC512A"}, -+ {39, "GC512B"}, -+ {40, "GC512C"}, - {256, "ffdhe2048"}, - {257, "ffdhe3072"}, - {258, "ffdhe4096"}, -@@ -571,6 +581,8 @@ - {TLSEXT_SIGALG_dsa_sha1, "dsa_sha1"}, - {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, "gost2012_256"}, - {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, "gost2012_512"}, -+ {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy, "gost2012_256"}, -+ {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy, "gost2012_512"}, - {TLSEXT_SIGALG_gostr34102001_gostr3411, "gost2001_gost94"}, - }; + seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) + : RECORD_LAYER_get_read_sequence(&s->rlayer); +- + if (SSL_IS_DTLS(s)) { + /* DTLS does not support pipelining */ + unsigned char dtlsseq[8], *p = dtlsseq; +@@ -1122,6 +1123,27 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) + } + } -@@ -584,7 +596,9 @@ - {20, "fortezza_dms"}, - {64, "ecdsa_sign"}, - {65, "rsa_fixed_ecdh"}, -- {66, "ecdsa_fixed_ecdh"} -+ {66, "ecdsa_fixed_ecdh"}, -+ {67, "gost_sign256"}, -+ {68, "gost_sign512"}, - }; ++ if (!SSL_IS_DTLS(s) && tlstree_enc) { ++ unsigned char *seq; ++ int decrement_seq = 0; ++ /* ++ * When sending, seq is incremented after MAC calculation. ++ * So if we are in ETM mode, we use seq 'as is' in the ctrl-function. ++ * Otherwise we have to decrease it in the implementation ++ */ ++ if (sending && !SSL_WRITE_ETM(s)) ++ decrement_seq = 1; ++ ++ seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) ++ : RECORD_LAYER_get_read_sequence(&s->rlayer); ++ if(EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, seq) <= 0) ++ { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, ++ ERR_R_INTERNAL_ERROR); ++ return -1; ++ } ++ } ++ + /* TODO(size_t): Convert this call */ + tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input, + (unsigned int)reclen[0]); +@@ -1287,6 +1309,8 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) + unsigned char header[13]; + int stream_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) + : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); ++ int tlstree_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) ++ : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE)); + int t; - static const ssl_trace_tbl ssl_psk_kex_modes_tbl[] = { -@@ -1072,6 +1086,10 @@ - *pname = "GOST"; - return SSL_kGOST; + if (sending) { +@@ -1314,6 +1338,11 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) + mac_ctx = hmac; } -+ if (alg_k & SSL_kGOST18) { -+ *pname = "GOST18"; -+ return SSL_kGOST18; + ++ if (!SSL_IS_DTLS(ssl) && tlstree_mac && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) { ++ EVP_MD_CTX_free(hmac); ++ return 0; + } - *pname = "UNKNOWN"; - return 0; - } -@@ -1114,7 +1132,16 @@ - if (!ssl_print_hexbuf(bio, indent + 2, "ecdh_Yc", 1, &msg, &msglen)) - return 0; - break; -- -+#ifndef OPENSSL_NO_GOST -+ case SSL_kGOST: -+ ssl_print_hex(bio, indent + 2, "GOST-wrapped PreMasterSecret", msg, msglen); -+ break; -+ case SSL_kGOST18: -+ ssl_print_hex(bio, indent + 2, -+ "GOST-wrapped PreMasterSecret", msg, msglen); -+ return 0; -+ break; -+#endif - } ++ + if (SSL_IS_DTLS(ssl)) { + unsigned char dtlsseq[8], *p = dtlsseq; - return !msglen; -Index: ssl/ssl_err.c -=================================================================== ---- ssl/ssl_err.c (revision 14523) -+++ ssl/ssl_err.c (working copy) -@@ -1,6 +1,6 @@ - /* - * Generated by util/mkerr.pl DO NOT EDIT -- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy -@@ -112,6 +112,8 @@ - "ossl_statem_server_post_process_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_POST_WORK, 0), - "ossl_statem_server_post_work"}, -+ {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PRE_WORK, 0), -+ "ossl_statem_server_pre_work"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE, 0), - "ossl_statem_server_process_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, 0), -@@ -437,6 +439,8 @@ - "tls_construct_cke_ecdhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_GOST, 0), - "tls_construct_cke_gost"}, -+ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_GOST18, 0), -+ "tls_construct_cke_gost18"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, 0), - "tls_construct_cke_psk_preamble"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_RSA, 0), -@@ -664,6 +668,8 @@ - "tls_process_cke_ecdhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_GOST, 0), - "tls_process_cke_gost"}, -+ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_GOST18, 0), -+ "tls_process_cke_gost18"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, 0), - "tls_process_cke_psk_preamble"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_RSA, 0), -Index: ssl/t1_lib.c -=================================================================== ---- ssl/t1_lib.c (revision 14523) -+++ ssl/t1_lib.c (working copy) -@@ -169,6 +169,18 @@ - {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ - {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ - {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ -+#ifndef OPENSSL_NO_GOST -+ {NID_undef, 0, TLS_CURVE_CUSTOM}, /* 31 */ -+ {NID_undef, 0, TLS_CURVE_CUSTOM}, /* 32 */ -+ {NID_undef, 0, TLS_CURVE_CUSTOM}, /* 33 */ -+ {NID_id_tc26_gost_3410_2012_256_paramSetA, 128, TLS_CURVE_GOST}, -+ {NID_id_tc26_gost_3410_2012_256_paramSetB, 128, TLS_CURVE_GOST}, -+ {NID_id_tc26_gost_3410_2012_256_paramSetC, 128, TLS_CURVE_GOST}, -+ {NID_id_tc26_gost_3410_2012_256_paramSetD, 128, TLS_CURVE_GOST}, -+ {NID_id_tc26_gost_3410_2012_512_paramSetA, 256, TLS_CURVE_GOST}, -+ {NID_id_tc26_gost_3410_2012_512_paramSetB, 256, TLS_CURVE_GOST}, -+ {NID_id_tc26_gost_3410_2012_512_paramSetC, 256, TLS_CURVE_GOST}, -+#endif - }; +diff --git ssl/record/ssl3_record_tls13.c ssl/record/ssl3_record_tls13.c +index ab50e376..4f78474e 100644 +--- ssl/record/ssl3_record_tls13.c ++++ ssl/record/ssl3_record_tls13.c +@@ -107,6 +107,10 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) + taglen = EVP_GCM_TLS_TAG_LEN; + } else if (alg_enc & SSL_CHACHA20) { + taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; ++ } else if (alg_enc & SSL_MAGMA_MGM) { ++ taglen = EVP_MAGMA_TLS_TAG_LEN; ++ } else if (alg_enc & SSL_KUZNYECHIK_MGM) { ++ taglen = EVP_KUZNYECHIK_TLS_TAG_LEN; + } else { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, + ERR_R_INTERNAL_ERROR); +@@ -135,6 +139,15 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) + for (loop = 0; loop < SEQ_NUM_SIZE; loop++) + iv[offset + loop] = staticiv[offset + loop] ^ seq[loop]; - static const unsigned char ecformats_default[] = { -@@ -184,6 +196,15 @@ - 30, /* X448 (30) */ - 25, /* secp521r1 (25) */ - 24, /* secp384r1 (24) */ ++ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) { ++ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLSTREE, ++ 0, seq) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, ++ ERR_R_INTERNAL_ERROR); ++ return -1; ++ } ++ } ++ + /* Increment the sequence counter */ + for (loop = SEQ_NUM_SIZE; loop > 0; loop--) { + ++seq[loop - 1]; +diff --git ssl/s3_lib.c ssl/s3_lib.c +index b256a4b9..bc9ba357 100644 +--- ssl/s3_lib.c ++++ ssl/s3_lib.c +@@ -111,7 +111,74 @@ static SSL_CIPHER tls13_ciphers[] = { + SSL_HANDSHAKE_MAC_SHA256, + 128, + 128, +- } ++ }, +#ifndef OPENSSL_NO_GOST -+ 34, -+ 35, -+ 36, -+ 37, -+ 38, -+ 39, -+ 40, ++/* https://tools.ietf.org/html/draft-smyshlyaev-tls13-gost-suites */ ++ { ++ 1, ++ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L", /* FIXME */ ++ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L", /* FIXME */ ++ TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L, ++ SSL_kANY, ++ SSL_aANY, ++ SSL_KUZNYECHIK_MGM, ++ SSL_AEAD, ++ TLS1_3_VERSION, TLS1_3_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_L, ++ 256, ++ 256, ++ }, ++ { ++ 1, ++ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_L", /* FIXME */ ++ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_L", /* FIXME */ ++ TLS_GOSTR341112_256_WITH_MAGMA_MGM_L, ++ SSL_kANY, ++ SSL_aANY, ++ SSL_MAGMA_MGM, ++ SSL_AEAD, ++ TLS1_3_VERSION, TLS1_3_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_L, ++ 256, ++ 256, ++ }, ++ { ++ 1, ++ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S", /* FIXME */ ++ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S", /* FIXME */ ++ TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S, ++ SSL_kANY, ++ SSL_aANY, ++ SSL_KUZNYECHIK_MGM, ++ SSL_AEAD, ++ TLS1_3_VERSION, TLS1_3_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_S, ++ 256, ++ 256, ++ }, ++ { ++ 1, ++ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_S", /* FIXME */ ++ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_S", /* FIXME */ ++ TLS_GOSTR341112_256_WITH_MAGMA_MGM_S, ++ SSL_kANY, ++ SSL_aANY, ++ SSL_MAGMA_MGM, ++ SSL_AEAD, ++ TLS1_3_VERSION, TLS1_3_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_S, ++ 256, ++ 256, ++ }, +#endif }; - static const uint16_t suiteb_curves[] = { -@@ -196,6 +217,8 @@ - /* ECC curves from RFC 4492 and RFC 7027 */ - if (group_id < 1 || group_id > OSSL_NELEM(nid_list)) - return NULL; -+ if (nid_list[group_id - 1].nid == NID_undef) -+ return NULL; - return &nid_list[group_id - 1]; - } + /* +@@ -2665,6 +2732,54 @@ static SSL_CIPHER ssl3_ciphers[] = { + 0, + 0, + }, ++ { ++ 1, ++ "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC", ++ NULL, ++ 0x0300C100, ++ SSL_kGOST18, ++ SSL_aGOST12, ++ SSL_KUZNYECHIK, ++ SSL_KUZNYECHIKOMAC, ++ TLS1_2_VERSION, TLS1_2_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, ++ 256, ++ 256, ++ }, ++ { ++ 1, ++ "GOST2012-MAGMA-MAGMAOMAC", ++ NULL, ++ 0x0300C101, ++ SSL_kGOST18, ++ SSL_aGOST12, ++ SSL_MAGMA, ++ SSL_MAGMAOMAC, ++ TLS1_2_VERSION, TLS1_2_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, ++ 256, ++ 256, ++ }, ++ { ++ 1, ++ "GOST2012-GOST8912-IANA", ++ NULL, ++ 0x0300C102, ++ SSL_kGOST, ++ SSL_aGOST12 | SSL_aGOST01, ++ SSL_eGOST2814789CNT12, ++ SSL_GOST89MAC12, ++ TLS1_VERSION, TLS1_2_VERSION, ++ 0, 0, ++ SSL_HIGH, ++ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_STREAM_MAC, ++ 256, ++ 256, ++ }, + #endif /* OPENSSL_NO_GOST */ -@@ -380,6 +403,33 @@ - int nid_arr[MAX_CURVELIST]; - } nid_cb_st; + #ifndef OPENSSL_NO_IDEA +@@ -4339,6 +4454,11 @@ int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt) + if (s->version >= TLS1_VERSION && (alg_k & SSL_kGOST)) + return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN) + && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN) ++ && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN) ++ && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN_LEGACY) ++ && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN_LEGACY); ++ if (s->version >= TLS1_2_VERSION && (alg_k & SSL_kGOST18)) ++ return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN) + && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN); + #endif +@@ -4689,6 +4809,52 @@ EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm) + return pkey; + } + #ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_GOST -+typedef struct { -+ const char *name; /* Name of GOST curve */ -+ int nid; /* Curve NID */ -+} EC_GOST_NAME; + -+static EC_GOST_NAME gost_curves[] = { -+ {"GC256A", NID_id_tc26_gost_3410_2012_256_paramSetA}, -+ {"GC256B", NID_id_tc26_gost_3410_2012_256_paramSetB}, -+ {"GC256C", NID_id_tc26_gost_3410_2012_256_paramSetC}, -+ {"GC256D", NID_id_tc26_gost_3410_2012_256_paramSetD}, -+ {"GC512A", NID_id_tc26_gost_3410_2012_512_paramSetA}, -+ {"GC512B", NID_id_tc26_gost_3410_2012_512_paramSetB}, -+ {"GC512C", NID_id_tc26_gost_3410_2012_512_paramSetC}, -+}; ++typedef struct tls_gost_group_param_st { ++ int nid; /* Curve params NID */ ++ int alg_nid; /* GOST algorithm nid */ ++ const char *params; /* GOST paramset mnemonics */ ++} TLS_GOST_GROUP_PARAM; + -+int GOST_curve2nid(const char *name) ++TLS_GOST_GROUP_PARAM gost_param[] = { ++ {NID_id_tc26_gost_3410_2012_256_paramSetA, NID_id_GostR3410_2012_256, "TCA"}, ++ {NID_id_tc26_gost_3410_2012_256_paramSetB, NID_id_GostR3410_2012_256, "TCB"}, ++ {NID_id_tc26_gost_3410_2012_256_paramSetC, NID_id_GostR3410_2012_256, "TCC"}, ++ {NID_id_tc26_gost_3410_2012_256_paramSetD, NID_id_GostR3410_2012_256, "TCD"}, ++ {NID_id_tc26_gost_3410_2012_512_paramSetA, NID_id_GostR3410_2012_512, "A"}, ++ {NID_id_tc26_gost_3410_2012_512_paramSetB, NID_id_GostR3410_2012_512, "B"}, ++ {NID_id_tc26_gost_3410_2012_512_paramSetC, NID_id_GostR3410_2012_512, "C"}, ++}; ++ ++static EVP_PKEY_CTX *gost_pkey_nid2ctx(int nid) +{ -+ size_t i; -+ for (i = 0; i < OSSL_NELEM(gost_curves); i++) { -+ if (strcmp(gost_curves[i].name, name) == 0) -+ return gost_curves[i].nid; -+ } -+ return NID_undef; ++ int i = 0; ++ TLS_GOST_GROUP_PARAM *pGostParam = NULL; ++ EVP_PKEY_CTX *pctx = NULL; ++ ++ for (i = 0; i < OSSL_NELEM(gost_param); i++) { ++ if (gost_param[i].nid == nid) { ++ pGostParam = gost_param + i; ++ break; ++ } ++ } ++ ++ if (pGostParam == NULL) { ++ return NULL; ++ } ++ ++ pctx = EVP_PKEY_CTX_new_id(pGostParam->alg_nid, NULL); ++ if (pctx == NULL ++ || EVP_PKEY_CTX_ctrl_str(pctx, "paramset", pGostParam->params) <= 0) { ++ EVP_PKEY_CTX_free(pctx); ++ return NULL; ++ } ++ ++ return pctx; +} -+#endif + - static int nid_cb(const char *elem, int len, void *arg) ++#endif + /* Generate a private key from a group ID */ + EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) { - nid_cb_st *narg = arg; -@@ -395,7 +445,12 @@ - memcpy(etmp, elem, len); - etmp[len] = 0; - nid = EC_curve_nist2nid(etmp); +@@ -4705,8 +4871,13 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) + gtype = ginf->flags & TLS_CURVE_TYPE; + if (gtype == TLS_CURVE_CUSTOM) + pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); +#ifndef OPENSSL_NO_GOST -+ /* FIXME beldmit */ - if (nid == NID_undef) -+ nid = GOST_curve2nid(etmp); ++ else if (gtype == TLS_CURVE_GOST) ++ pctx = gost_pkey_nid2ctx(ginf->nid); +#endif -+ if (nid == NID_undef) - nid = OBJ_sn2nid(etmp); - if (nid == NID_undef) - nid = OBJ_ln2nid(etmp); -@@ -670,8 +725,17 @@ - TLSEXT_SIGALG_dsa_sha512, - #endif - #ifndef OPENSSL_NO_GOST -+ TLSEXT_SIGALG_gostr34102012_256a, -+ TLSEXT_SIGALG_gostr34102012_256b, -+ TLSEXT_SIGALG_gostr34102012_256c, -+ TLSEXT_SIGALG_gostr34102012_256d, -+ TLSEXT_SIGALG_gostr34102012_512a, -+ TLSEXT_SIGALG_gostr34102012_512b, -+ TLSEXT_SIGALG_gostr34102012_512c, - TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, - TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, -+ TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy, -+ TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy, - TLSEXT_SIGALG_gostr34102001_gostr3411, - #endif - }; -@@ -758,6 +822,34 @@ - NID_dsaWithSHA1, NID_undef}, - #endif - #ifndef OPENSSL_NO_GOST -+ {"gostr34102012_256a", TLSEXT_SIGALG_gostr34102012_256a, -+ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, -+ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, -+ NID_undef, NID_undef}, -+ {"gostr34102012_256b", TLSEXT_SIGALG_gostr34102012_256b, -+ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, -+ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, -+ NID_undef, NID_undef}, -+ {"gostr34102012_256c", TLSEXT_SIGALG_gostr34102012_256c, -+ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, -+ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, -+ NID_undef, NID_undef}, -+ {"gostr34102012_256d", TLSEXT_SIGALG_gostr34102012_256d, -+ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, -+ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, -+ NID_undef, NID_undef}, -+ {"gostr34102012_512a", TLSEXT_SIGALG_gostr34102012_512a, -+ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, -+ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, -+ NID_undef, NID_undef}, -+ {"gostr34102012_512b", TLSEXT_SIGALG_gostr34102012_512b, -+ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, -+ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, -+ NID_undef, NID_undef}, -+ {"gostr34102012_512c", TLSEXT_SIGALG_gostr34102012_512c, -+ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, -+ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, -+ NID_undef, NID_undef}, - {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, - NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, - NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, -@@ -766,6 +858,14 @@ - NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, - NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, - NID_undef, NID_undef}, -+ {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy, -+ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, -+ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, -+ NID_undef, NID_undef}, -+ {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy, -+ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, -+ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, -+ NID_undef, NID_undef}, - {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411, - NID_id_GostR3411_94, SSL_MD_GOST94_IDX, - NID_id_GostR3410_2001, SSL_PKEY_GOST01, -@@ -886,6 +986,24 @@ - } - } - } -+ /* -+ * Here is another fallback: when broken implementations did not sent -+ * proper signature_algorithm extension, we try to use this function. -+ * -+ * As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used -+ * with new (aGOST12-only) ciphersuites, we should find out which one is available really. -+ * */ -+ else if (idx == SSL_PKEY_GOST12_256) { -+ int real_idx; + else + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + -+ for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256; -+ real_idx--) { -+ if (s->cert->pkeys[real_idx].privatekey != NULL) { -+ idx = real_idx; -+ break; -+ } -+ } -+ } - } else { - idx = s->cert->key - s->cert->pkeys; - } -@@ -1612,10 +1730,8 @@ - if (ssl_cert_is_disabled(lu->sig_idx)) - return 0; + if (pctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, + ERR_R_MALLOC_FAILURE); +@@ -4717,7 +4888,7 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) + ERR_R_EVP_LIB); + goto err; + } +- if (gtype != TLS_CURVE_CUSTOM ++ if (gtype != TLS_CURVE_CUSTOM && gtype != TLS_CURVE_GOST + && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, + ERR_R_EVP_LIB); +@@ -4755,13 +4926,21 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) + return NULL; + } -- if (lu->sig == NID_id_GostR3410_2012_256 -- || lu->sig == NID_id_GostR3410_2012_512 -- || lu->sig == NID_id_GostR3410_2001) { -- /* We never allow GOST sig algs on the server with TLSv1.3 */ -+ if (lu->sig == NID_id_GostR3410_2001) { -+ /* GOST sig algs on the server with TLSv1.3 are allowed for GOST2012 */ - if (s->server && SSL_IS_TLS13(s)) - return 0; - if (!s->server -@@ -1643,7 +1759,7 @@ - if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) - continue; ++#ifndef OPENSSL_NO_GOST ++ if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_GOST) ++ pctx = gost_pkey_nid2ctx(ginf->nid); ++ else ++#endif + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); ++ + if (pctx == NULL) + goto err; + if (EVP_PKEY_paramgen_init(pctx) <= 0) + goto err; +- if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) ++ if ((ginf->flags & TLS_CURVE_TYPE) != TLS_CURVE_GOST) { ++ if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) + goto err; ++ } + if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) { + EVP_PKEY_free(pkey); + pkey = NULL; +diff --git ssl/ssl_ciph.c ssl/ssl_ciph.c +index 55f919fc..87a41b15 100644 +--- ssl/ssl_ciph.c ++++ ssl/ssl_ciph.c +@@ -43,7 +43,11 @@ + #define SSL_ENC_CHACHA_IDX 19 + #define SSL_ENC_ARIA128GCM_IDX 20 + #define SSL_ENC_ARIA256GCM_IDX 21 +-#define SSL_ENC_NUM_IDX 22 ++#define SSL_ENC_MAGMA_IDX 22 ++#define SSL_ENC_KUZNYECHIK_IDX 23 ++#define SSL_ENC_MAGMA_MGM_IDX 24 ++#define SSL_ENC_KUZNYECHIK_MGM_IDX 25 ++#define SSL_ENC_NUM_IDX 26 -- if ((c->algorithm_mkey & SSL_kGOST) != 0) -+ if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0) - break; - } - if (i == num) -Index: ssl/ssl_local.h -=================================================================== ---- ssl/ssl_local.h (revision 14523) -+++ ssl/ssl_local.h (working copy) -@@ -176,6 +176,8 @@ - # define SSL_kRSAPSK 0x00000040U - # define SSL_kECDHEPSK 0x00000080U - # define SSL_kDHEPSK 0x00000100U -+/* GOST KDF key exchange, draft-smyshlyaev-tls12-gost-suites */ -+# define SSL_kGOST18 0x00000200U + /* NB: make sure indices in these tables match values above */ - /* all PSK */ +@@ -76,6 +80,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 */ ++ {SSL_MAGMA, NID_magma_ctr_acpkm}, /* SSL_ENC_MAGMA_IDX */ ++ {SSL_KUZNYECHIK, NID_kuznyechik_ctr_acpkm}, /* SSL_ENC_KUZNYECHIK_IDX */ ++ {SSL_MAGMA_MGM, NID_magma_mgm}, /* SSL_ENC_MAGMA_MGM_IDX */ ++ {SSL_KUZNYECHIK_MGM, NID_kuznyechik_mgm}, /* SSL_ENC_KUZNYECHIK_MGM_IDX */ + }; -@@ -230,6 +232,10 @@ - # define SSL_CHACHA20POLY1305 0x00080000U - # define SSL_ARIA128GCM 0x00100000U - # define SSL_ARIA256GCM 0x00200000U -+# define SSL_MAGMA 0x00400000U -+# define SSL_KUZNYECHIK 0x00800000U -+# define SSL_MAGMA_MGM 0x01000000U -+# define SSL_KUZNYECHIK_MGM 0x02000000U + static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; +@@ -110,11 +118,13 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = { + {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */ + {0, NID_md5_sha1}, /* SSL_MD_MD5_SHA1_IDX 9 */ + {0, NID_sha224}, /* SSL_MD_SHA224_IDX 10 */ +- {0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */ ++ {0, NID_sha512}, /* SSL_MD_SHA512_IDX 11 */ ++ {SSL_MAGMAOMAC, NID_magma_mac}, /* SSL_MD_MAGMAOMAC_IDX */ ++ {SSL_KUZNYECHIKOMAC, NID_kuznyechik_mac}, /* SSL_MD_KUZNYECHIKOMAC_IDX */ + }; - # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) - # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) -@@ -252,6 +258,8 @@ - # define SSL_GOST12_256 0x00000080U - # define SSL_GOST89MAC12 0x00000100U - # define SSL_GOST12_512 0x00000200U -+# define SSL_MAGMAOMAC 0x00000400U -+# define SSL_KUZNYECHIKOMAC 0x00000800U - - /* - * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make -@@ -270,7 +278,9 @@ - # define SSL_MD_MD5_SHA1_IDX 9 - # define SSL_MD_SHA224_IDX 10 - # define SSL_MD_SHA512_IDX 11 --# define SSL_MAX_DIGEST 12 -+# define SSL_MD_MAGMAOMAC_IDX 12 -+# define SSL_MD_KUZNYECHIKOMAC_IDX 13 -+# define SSL_MAX_DIGEST 14 - - /* Bits for algorithm2 (handshake digests and other extra flags) */ - -@@ -299,6 +309,13 @@ - * goes into algorithm2) - */ - # define TLS1_STREAM_MAC 0x10000 -+/* -+ * TLSTREE cipher/mac key derivation used for GOST TLS 1.2/1.3 ciphersuites -+ * (currently this also goes into algorithm2) -+ */ -+# define TLS1_TLSTREE 0x20000 -+# define TLS1_TLSTREE_S 0x40000 -+# define TLS1_TLSTREE_L 0x80000 - - # define SSL_STRONG_MASK 0x0000001FU - # define SSL_DEFAULT_MASK 0X00000020U -@@ -1512,10 +1529,11 @@ - } TLS_GROUP_INFO; - - /* flags values */ --# define TLS_CURVE_TYPE 0x3 /* Mask for group type */ -+# define TLS_CURVE_TYPE 0x7 /* Mask for group type */ - # define TLS_CURVE_PRIME 0x0 - # define TLS_CURVE_CHAR2 0x1 - # define TLS_CURVE_CUSTOM 0x2 -+# define TLS_CURVE_GOST 0x4 - - typedef struct cert_pkey_st CERT_PKEY; - -@@ -2043,8 +2061,17 @@ - #define TLSEXT_SIGALG_dsa_sha512 0x0602 - #define TLSEXT_SIGALG_dsa_sha224 0x0302 - #define TLSEXT_SIGALG_dsa_sha1 0x0202 --#define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256 0xeeee --#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 0xefef -+#define TLSEXT_SIGALG_gostr34102012_256a 0x0709 -+#define TLSEXT_SIGALG_gostr34102012_256b 0x070A -+#define TLSEXT_SIGALG_gostr34102012_256c 0x070B -+#define TLSEXT_SIGALG_gostr34102012_256d 0x070C -+#define TLSEXT_SIGALG_gostr34102012_512a 0x070D -+#define TLSEXT_SIGALG_gostr34102012_512b 0x070E -+#define TLSEXT_SIGALG_gostr34102012_512c 0x070F -+#define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256 0x0840 -+#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 0x0841 -+#define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy 0xeeee -+#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy 0xefef - #define TLSEXT_SIGALG_gostr34102001_gostr3411 0xeded - - #define TLSEXT_SIGALG_ed25519 0x0807 -Index: ssl/ssl_lib.c -=================================================================== ---- ssl/ssl_lib.c (revision 14523) -+++ ssl/ssl_lib.c (working copy) -@@ -3327,11 +3327,11 @@ - - #ifndef OPENSSL_NO_GOST - if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) { -- mask_k |= SSL_kGOST; -+ mask_k |= SSL_kGOST | SSL_kGOST18; - mask_a |= SSL_aGOST12; - } - if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) { -- mask_k |= SSL_kGOST; -+ mask_k |= SSL_kGOST | SSL_kGOST18; - mask_a |= SSL_aGOST12; - } - if (ssl_has_cert(s, SSL_PKEY_GOST01)) { -Index: ssl/tls13_enc.c -=================================================================== ---- ssl/tls13_enc.c (revision 14523) -+++ ssl/tls13_enc.c (working copy) -@@ -421,6 +421,21 @@ - goto err; - } - -+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) { -+ int res = 0; -+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE_S) { -+ res = EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_SET_TLSTREE_PARAMS, 0, "short"); -+ } else if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE_L) { -+ res = EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_SET_TLSTREE_PARAMS, 0, "long"); -+ } -+ -+ if (res <= 0) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, -+ ERR_R_EVP_LIB); -+ goto err; -+ } -+ } -+ - return 1; - err: - OPENSSL_cleanse(key, sizeof(key)); -Index: ssl/record/ssl3_record.c -=================================================================== ---- ssl/record/ssl3_record.c (revision 14523) -+++ ssl/record/ssl3_record.c (working copy) -@@ -944,6 +944,8 @@ - unsigned char padval; - int imac_size; - const EVP_CIPHER *enc; -+ int tlstree_enc = (sending ? (s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) -+ : (s->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE)); - - if (n_recs == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, -@@ -1036,7 +1038,6 @@ - - seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) - : RECORD_LAYER_get_read_sequence(&s->rlayer); -- - if (SSL_IS_DTLS(s)) { - /* DTLS does not support pipelining */ - unsigned char dtlsseq[9], *p = dtlsseq; -@@ -1122,6 +1123,27 @@ - } - } - -+ if (!SSL_IS_DTLS(s) && tlstree_enc) { -+ unsigned char *seq; -+ int decrement_seq = 0; -+ /* -+ * When sending, seq is incremented after MAC calculation. -+ * So if we are in ETM mode, we use seq 'as is' in the ctrl-function. -+ * Otherwise we have to decrease it in the implementation -+ */ -+ if (sending && !SSL_WRITE_ETM(s)) -+ decrement_seq = 1; -+ -+ seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) -+ : RECORD_LAYER_get_read_sequence(&s->rlayer); -+ if(EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, seq) <= 0) -+ { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, -+ ERR_R_INTERNAL_ERROR); -+ return -1; -+ } -+ } -+ - /* TODO(size_t): Convert this call */ - tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input, - (unsigned int)reclen[0]); -@@ -1287,6 +1309,8 @@ - unsigned char header[13]; - int stream_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) - : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); -+ int tlstree_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) -+ : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE)); - int t; - - if (sending) { -@@ -1314,6 +1338,11 @@ - mac_ctx = hmac; - } - -+ if (!SSL_IS_DTLS(ssl) && tlstree_mac && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) { -+ EVP_MD_CTX_free(hmac); -+ return 0; -+ } -+ - if (SSL_IS_DTLS(ssl)) { - unsigned char dtlsseq[8], *p = dtlsseq; - -Index: ssl/record/ssl3_record_tls13.c -=================================================================== ---- ssl/record/ssl3_record_tls13.c (revision 14523) -+++ ssl/record/ssl3_record_tls13.c (working copy) -@@ -107,6 +107,10 @@ - taglen = EVP_GCM_TLS_TAG_LEN; - } else if (alg_enc & SSL_CHACHA20) { - taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; -+ } else if (alg_enc & SSL_MAGMA_MGM) { -+ taglen = EVP_MAGMA_TLS_TAG_LEN; -+ } else if (alg_enc & SSL_KUZNYECHIK_MGM) { -+ taglen = EVP_KUZNYECHIK_TLS_TAG_LEN; - } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); -@@ -135,6 +139,15 @@ - for (loop = 0; loop < SEQ_NUM_SIZE; loop++) - iv[offset + loop] = staticiv[offset + loop] ^ seq[loop]; - -+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) { -+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLSTREE, -+ 0, seq) <= 0) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, -+ ERR_R_INTERNAL_ERROR); -+ return -1; -+ } -+ } -+ - /* Increment the sequence counter */ - for (loop = SEQ_NUM_SIZE; loop > 0; loop--) { - ++seq[loop - 1]; -Index: ssl/ssl_ciph.c -=================================================================== ---- ssl/ssl_ciph.c (revision 14523) -+++ ssl/ssl_ciph.c (working copy) -@@ -43,7 +43,11 @@ - #define SSL_ENC_CHACHA_IDX 19 - #define SSL_ENC_ARIA128GCM_IDX 20 - #define SSL_ENC_ARIA256GCM_IDX 21 --#define SSL_ENC_NUM_IDX 22 -+#define SSL_ENC_MAGMA_IDX 22 -+#define SSL_ENC_KUZNYECHIK_IDX 23 -+#define SSL_ENC_MAGMA_MGM_IDX 24 -+#define SSL_ENC_KUZNYECHIK_MGM_IDX 25 -+#define SSL_ENC_NUM_IDX 26 - - /* NB: make sure indices in these tables match values above */ - -@@ -76,6 +80,10 @@ - {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 */ -+ {SSL_MAGMA, NID_magma_ctr_acpkm}, /* SSL_ENC_MAGMA_IDX */ -+ {SSL_KUZNYECHIK, NID_kuznyechik_ctr_acpkm}, /* SSL_ENC_KUZNYECHIK_IDX */ -+ {SSL_MAGMA_MGM, NID_magma_mgm}, /* SSL_ENC_MAGMA_MGM_IDX */ -+ {SSL_KUZNYECHIK_MGM, NID_kuznyechik_mgm}, /* SSL_ENC_KUZNYECHIK_MGM_IDX */ - }; - - static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; -@@ -110,11 +118,13 @@ - {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */ - {0, NID_md5_sha1}, /* SSL_MD_MD5_SHA1_IDX 9 */ - {0, NID_sha224}, /* SSL_MD_SHA224_IDX 10 */ -- {0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */ -+ {0, NID_sha512}, /* SSL_MD_SHA512_IDX 11 */ -+ {SSL_MAGMAOMAC, NID_magma_mac}, /* SSL_MD_MAGMAOMAC_IDX */ -+ {SSL_KUZNYECHIKOMAC, NID_kuznyechik_mac}, /* SSL_MD_KUZNYECHIKOMAC_IDX */ - }; - - static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { -- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }; + static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { +- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; /* *INDENT-OFF* */ -@@ -128,6 +138,7 @@ +@@ -128,6 +138,7 @@ static const ssl_cipher_table ssl_cipher_table_kx[] = { {SSL_kPSK, NID_kx_psk}, {SSL_kSRP, NID_kx_srp}, {SSL_kGOST, NID_kx_gost}, @@ -2593,7 +2365,7 @@ Index: ssl/ssl_ciph.c {SSL_kANY, NID_kx_any} }; -@@ -171,8 +182,8 @@ +@@ -171,8 +182,8 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, /* GOST2012_512 */ EVP_PKEY_HMAC, @@ -2604,7 +2376,7 @@ Index: ssl/ssl_ciph.c }; static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX]; -@@ -228,6 +239,7 @@ +@@ -228,6 +239,7 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_kDHEPSK, NULL, 0, SSL_kDHEPSK}, {0, SSL_TXT_kSRP, NULL, 0, SSL_kSRP}, {0, SSL_TXT_kGOST, NULL, 0, SSL_kGOST}, @@ -2612,7 +2384,7 @@ Index: ssl/ssl_ciph.c /* server authentication aliases */ {0, SSL_TXT_aRSA, NULL, 0, 0, SSL_aRSA}, -@@ -261,7 +273,7 @@ +@@ -261,7 +273,7 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_IDEA, NULL, 0, 0, 0, SSL_IDEA}, {0, SSL_TXT_SEED, NULL, 0, 0, 0, SSL_SEED}, {0, SSL_TXT_eNULL, NULL, 0, 0, 0, SSL_eNULL}, @@ -2621,7 +2393,7 @@ Index: ssl/ssl_ciph.c {0, SSL_TXT_AES128, NULL, 0, 0, 0, SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8}, {0, SSL_TXT_AES256, NULL, 0, 0, 0, -@@ -419,7 +431,7 @@ +@@ -419,24 +431,38 @@ int ssl_load_ciphers(void) * Check for presence of GOST 34.10 algorithms, and if they are not * present, disable appropriate auth and key exchange */ @@ -2630,7 +2402,6 @@ Index: ssl/ssl_ciph.c if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; else -@@ -426,17 +438,31 @@ disabled_mac_mask |= SSL_GOST89MAC; ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] = @@ -2666,7 +2437,7 @@ Index: ssl/ssl_ciph.c disabled_auth_mask |= SSL_aGOST12; /* * Disable GOST key exchange if no GOST signature algs are available * -@@ -445,6 +471,9 @@ +@@ -445,6 +471,9 @@ int ssl_load_ciphers(void) (SSL_aGOST01 | SSL_aGOST12)) disabled_mkey_mask |= SSL_kGOST; @@ -2676,7 +2447,7 @@ Index: ssl/ssl_ciph.c return 1; } -@@ -1686,6 +1715,9 @@ +@@ -1687,6 +1716,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kGOST: kx = "GOST"; break; @@ -2686,7 +2457,7 @@ Index: ssl/ssl_ciph.c case SSL_kANY: kx = "any"; break; -@@ -1789,6 +1821,14 @@ +@@ -1790,6 +1822,14 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_eGOST2814789CNT12: enc = "GOST89(256)"; break; @@ -2701,329 +2472,342 @@ Index: ssl/ssl_ciph.c case SSL_CHACHA20POLY1305: enc = "CHACHA20/POLY1305(256)"; break; -Index: ssl/t1_enc.c -=================================================================== ---- ssl/t1_enc.c (revision 14523) -+++ ssl/t1_enc.c (working copy) -@@ -113,6 +113,11 @@ - else - s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; +diff --git ssl/ssl_err.c ssl/ssl_err.c +index 324f2ccb..df16a616 100644 +--- ssl/ssl_err.c ++++ ssl/ssl_err.c +@@ -113,6 +113,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "ossl_statem_server_post_process_message"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_POST_WORK, 0), + "ossl_statem_server_post_work"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PRE_WORK, 0), ++ "ossl_statem_server_pre_work"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE, 0), + "ossl_statem_server_process_message"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, 0), +@@ -438,6 +440,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "tls_construct_cke_ecdhe"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_GOST, 0), + "tls_construct_cke_gost"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_GOST18, 0), ++ "tls_construct_cke_gost18"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, 0), + "tls_construct_cke_psk_preamble"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_RSA, 0), +@@ -665,6 +669,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = { + "tls_process_cke_ecdhe"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_GOST, 0), + "tls_process_cke_gost"}, ++ {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_GOST18, 0), ++ "tls_process_cke_gost18"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, 0), + "tls_process_cke_psk_preamble"}, + {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_RSA, 0), +diff --git ssl/ssl_lib.c ssl/ssl_lib.c +index 9c411a32..51bd2d3a 100644 +--- ssl/ssl_lib.c ++++ ssl/ssl_lib.c +@@ -3382,11 +3382,11 @@ void ssl_set_masks(SSL *s) -+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) -+ s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE; -+ else -+ s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE; -+ - if (s->enc_read_ctx != NULL) { - reuse_dd = 1; - } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { -@@ -160,6 +165,11 @@ - s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; - else - s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; -+ -+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) -+ s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE; -+ else -+ s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE; - if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) { - reuse_dd = 1; - } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { -@@ -298,11 +308,11 @@ - goto err; - } - } else { -- if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { -- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, -- ERR_R_INTERNAL_ERROR); -- goto err; -- } -+ if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, -+ ERR_R_INTERNAL_ERROR); -+ goto err; -+ } + #ifndef OPENSSL_NO_GOST + if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) { +- mask_k |= SSL_kGOST; ++ mask_k |= SSL_kGOST | SSL_kGOST18; + mask_a |= SSL_aGOST12; } - /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ - if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size -@@ -438,7 +448,11 @@ - { - size_t hashlen; - unsigned char hash[EVP_MAX_MD_SIZE]; -+ size_t finished_size = TLS1_FINISH_MAC_LENGTH; + if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) { +- mask_k |= SSL_kGOST; ++ mask_k |= SSL_kGOST | SSL_kGOST18; + mask_a |= SSL_aGOST12; + } + if (ssl_has_cert(s, SSL_PKEY_GOST01)) { +diff --git ssl/ssl_local.h ssl/ssl_local.h +index 9f346e30..b23d3433 100644 +--- ssl/ssl_local.h ++++ ssl/ssl_local.h +@@ -176,6 +176,8 @@ + # define SSL_kRSAPSK 0x00000040U + # define SSL_kECDHEPSK 0x00000080U + # define SSL_kDHEPSK 0x00000100U ++/* GOST KDF key exchange, draft-smyshlyaev-tls12-gost-suites */ ++# define SSL_kGOST18 0x00000200U -+ if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kGOST18) -+ finished_size = 32; -+ - if (!ssl3_digest_cached_records(s, 0)) { - /* SSLfatal() already called */ - return 0; -@@ -451,12 +465,12 @@ + /* all PSK */ - if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, - s->session->master_key, s->session->master_key_length, -- out, TLS1_FINISH_MAC_LENGTH, 1)) { -+ out, finished_size, 1)) { - /* SSLfatal() already called */ - return 0; - } - OPENSSL_cleanse(hash, hashlen); -- return TLS1_FINISH_MAC_LENGTH; -+ return finished_size; - } +@@ -230,6 +232,10 @@ + # define SSL_CHACHA20POLY1305 0x00080000U + # define SSL_ARIA128GCM 0x00100000U + # define SSL_ARIA256GCM 0x00200000U ++# define SSL_MAGMA 0x00400000U ++# define SSL_KUZNYECHIK 0x00800000U ++# define SSL_MAGMA_MGM 0x01000000U ++# define SSL_KUZNYECHIK_MGM 0x02000000U - int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, -Index: ssl/s3_lib.c -=================================================================== ---- ssl/s3_lib.c (revision 14523) -+++ ssl/s3_lib.c (working copy) -@@ -111,7 +111,74 @@ - SSL_HANDSHAKE_MAC_SHA256, - 128, - 128, -- } -+ }, -+#ifndef OPENSSL_NO_GOST -+/* https://tools.ietf.org/html/draft-smyshlyaev-tls13-gost-suites */ -+ { -+ 1, -+ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L", /* FIXME */ -+ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L", /* FIXME */ -+ TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_L, -+ SSL_kANY, -+ SSL_aANY, -+ SSL_KUZNYECHIK_MGM, -+ SSL_AEAD, -+ TLS1_3_VERSION, TLS1_3_VERSION, -+ 0, 0, -+ SSL_HIGH, -+ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_L, -+ 256, -+ 256, -+ }, -+ { -+ 1, -+ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_L", /* FIXME */ -+ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_L", /* FIXME */ -+ TLS_GOSTR341112_256_WITH_MAGMA_MGM_L, -+ SSL_kANY, -+ SSL_aANY, -+ SSL_MAGMA_MGM, -+ SSL_AEAD, -+ TLS1_3_VERSION, TLS1_3_VERSION, -+ 0, 0, -+ SSL_HIGH, -+ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_L, -+ 256, -+ 256, -+ }, -+ { -+ 1, -+ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S", /* FIXME */ -+ "TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S", /* FIXME */ -+ TLS_GOSTR341112_256_WITH_KUZNYECHIK_MGM_S, -+ SSL_kANY, -+ SSL_aANY, -+ SSL_KUZNYECHIK_MGM, -+ SSL_AEAD, -+ TLS1_3_VERSION, TLS1_3_VERSION, -+ 0, 0, -+ SSL_HIGH, -+ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_S, -+ 256, -+ 256, -+ }, -+ { -+ 1, -+ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_S", /* FIXME */ -+ "TLS_GOSTR341112_256_WITH_MAGMA_MGM_S", /* FIXME */ -+ TLS_GOSTR341112_256_WITH_MAGMA_MGM_S, -+ SSL_kANY, -+ SSL_aANY, -+ SSL_MAGMA_MGM, -+ SSL_AEAD, -+ TLS1_3_VERSION, TLS1_3_VERSION, -+ 0, 0, -+ SSL_HIGH, -+ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_TLSTREE | TLS1_TLSTREE_S, -+ 256, -+ 256, -+ }, -+#endif - }; + # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) + # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) +@@ -252,6 +258,8 @@ + # define SSL_GOST12_256 0x00000080U + # define SSL_GOST89MAC12 0x00000100U + # define SSL_GOST12_512 0x00000200U ++# define SSL_MAGMAOMAC 0x00000400U ++# define SSL_KUZNYECHIKOMAC 0x00000800U /* -@@ -2665,6 +2732,54 @@ - 0, - 0, - }, -+ { -+ 1, -+ "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC", -+ NULL, -+ 0x0300C100, -+ SSL_kGOST18, -+ SSL_aGOST12, -+ SSL_KUZNYECHIK, -+ SSL_KUZNYECHIKOMAC, -+ TLS1_2_VERSION, TLS1_2_VERSION, -+ 0, 0, -+ SSL_HIGH, -+ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, -+ 256, -+ 256, -+ }, -+ { -+ 1, -+ "GOST2012-MAGMA-MAGMAOMAC", -+ NULL, -+ 0x0300C101, -+ SSL_kGOST18, -+ SSL_aGOST12, -+ SSL_MAGMA, -+ SSL_MAGMAOMAC, -+ TLS1_2_VERSION, TLS1_2_VERSION, -+ 0, 0, -+ SSL_HIGH, -+ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, -+ 256, -+ 256, -+ }, -+ { -+ 1, -+ "GOST2012-GOST8912-IANA", -+ NULL, -+ 0x0300C102, -+ SSL_kGOST, -+ SSL_aGOST12 | SSL_aGOST01, -+ SSL_eGOST2814789CNT12, -+ SSL_GOST89MAC12, -+ TLS1_VERSION, TLS1_2_VERSION, -+ 0, 0, -+ SSL_HIGH, -+ SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_STREAM_MAC, -+ 256, -+ 256, -+ }, - #endif /* OPENSSL_NO_GOST */ + * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make +@@ -270,7 +278,9 @@ + # define SSL_MD_MD5_SHA1_IDX 9 + # define SSL_MD_SHA224_IDX 10 + # define SSL_MD_SHA512_IDX 11 +-# define SSL_MAX_DIGEST 12 ++# define SSL_MD_MAGMAOMAC_IDX 12 ++# define SSL_MD_KUZNYECHIKOMAC_IDX 13 ++# define SSL_MAX_DIGEST 14 - #ifndef OPENSSL_NO_IDEA -@@ -4348,6 +4463,11 @@ - if (s->version >= TLS1_VERSION && (alg_k & SSL_kGOST)) - return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN) -+ && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN) -+ && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN_LEGACY) -+ && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN_LEGACY); -+ if (s->version >= TLS1_2_VERSION && (alg_k & SSL_kGOST18)) -+ return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN); - #endif + /* Bits for algorithm2 (handshake digests and other extra flags) */ + +@@ -299,6 +309,13 @@ + * goes into algorithm2) + */ + # define TLS1_STREAM_MAC 0x10000 ++/* ++ * TLSTREE cipher/mac key derivation used for GOST TLS 1.2/1.3 ciphersuites ++ * (currently this also goes into algorithm2) ++ */ ++# define TLS1_TLSTREE 0x20000 ++# define TLS1_TLSTREE_S 0x40000 ++# define TLS1_TLSTREE_L 0x80000 + + # define SSL_STRONG_MASK 0x0000001FU + # define SSL_DEFAULT_MASK 0X00000020U +@@ -1511,10 +1528,11 @@ typedef struct tls_group_info_st { + } TLS_GROUP_INFO; + + /* flags values */ +-# define TLS_CURVE_TYPE 0x3 /* Mask for group type */ ++# define TLS_CURVE_TYPE 0x7 /* Mask for group type */ + # define TLS_CURVE_PRIME 0x0 + # define TLS_CURVE_CHAR2 0x1 + # define TLS_CURVE_CUSTOM 0x2 ++# define TLS_CURVE_GOST 0x4 + + typedef struct cert_pkey_st CERT_PKEY; + +@@ -2042,8 +2060,17 @@ typedef enum downgrade_en { + #define TLSEXT_SIGALG_dsa_sha512 0x0602 + #define TLSEXT_SIGALG_dsa_sha224 0x0302 + #define TLSEXT_SIGALG_dsa_sha1 0x0202 +-#define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256 0xeeee +-#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 0xefef ++#define TLSEXT_SIGALG_gostr34102012_256a 0x0709 ++#define TLSEXT_SIGALG_gostr34102012_256b 0x070A ++#define TLSEXT_SIGALG_gostr34102012_256c 0x070B ++#define TLSEXT_SIGALG_gostr34102012_256d 0x070C ++#define TLSEXT_SIGALG_gostr34102012_512a 0x070D ++#define TLSEXT_SIGALG_gostr34102012_512b 0x070E ++#define TLSEXT_SIGALG_gostr34102012_512c 0x070F ++#define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256 0x0840 ++#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 0x0841 ++#define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy 0xeeee ++#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy 0xefef + #define TLSEXT_SIGALG_gostr34102001_gostr3411 0xeded -@@ -4695,6 +4815,52 @@ - return pkey; + #define TLSEXT_SIGALG_ed25519 0x0807 +diff --git ssl/statem/extensions_srvr.c ssl/statem/extensions_srvr.c +index 04f64f81..25e4e8ec 100644 +--- ssl/statem/extensions_srvr.c ++++ ssl/statem/extensions_srvr.c +@@ -624,7 +624,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, + + if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) + return 1; +- ++/* FIXME beldmit GOST */ + /* Sanity check */ + if (s->s3->peer_tmp != NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, +@@ -1623,7 +1623,9 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, + if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD + || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4 + || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT +- || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) { ++ || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12 ++ || s->s3->tmp.new_cipher->algorithm_enc == SSL_MAGMA ++ || s->s3->tmp.new_cipher->algorithm_enc == SSL_KUZNYECHIK) { + s->ext.use_etm = 0; + return EXT_RETURN_NOT_SENT; + } +@@ -1682,6 +1684,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx) + { ++/* FIXME beldmit GOST */ + #ifndef OPENSSL_NO_TLS1_3 + unsigned char *encodedPoint; + size_t encoded_pt_len = 0; +diff --git ssl/statem/statem_clnt.c ssl/statem/statem_clnt.c +index d1a39698..428536b8 100644 +--- ssl/statem/statem_clnt.c ++++ ssl/statem/statem_clnt.c +@@ -3285,6 +3285,144 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) + #endif } - #ifndef OPENSSL_NO_EC + +#ifndef OPENSSL_NO_GOST ++int gost18_cke_cipher_nid(const SSL *s) ++{ ++ if ((s->s3->tmp.new_cipher->algorithm_enc & SSL_MAGMA) != 0) ++ return NID_magma_ctr; ++ else if ((s->s3->tmp.new_cipher->algorithm_enc & SSL_KUZNYECHIK) != 0) ++ return NID_kuznyechik_ctr; + -+typedef struct tls_gost_group_param_st { -+ int nid; /* Curve params NID */ -+ int alg_nid; /* GOST algorithm nid */ -+ const char *params; /* GOST paramset mnemonics */ -+} TLS_GOST_GROUP_PARAM; ++ return NID_undef; ++} + -+TLS_GOST_GROUP_PARAM gost_param[] = { -+ {NID_id_tc26_gost_3410_2012_256_paramSetA, NID_id_GostR3410_2012_256, "TCA"}, -+ {NID_id_tc26_gost_3410_2012_256_paramSetB, NID_id_GostR3410_2012_256, "TCB"}, -+ {NID_id_tc26_gost_3410_2012_256_paramSetC, NID_id_GostR3410_2012_256, "TCC"}, -+ {NID_id_tc26_gost_3410_2012_256_paramSetD, NID_id_GostR3410_2012_256, "TCD"}, -+ {NID_id_tc26_gost_3410_2012_512_paramSetA, NID_id_GostR3410_2012_512, "A"}, -+ {NID_id_tc26_gost_3410_2012_512_paramSetB, NID_id_GostR3410_2012_512, "B"}, -+ {NID_id_tc26_gost_3410_2012_512_paramSetC, NID_id_GostR3410_2012_512, "C"}, -+}; ++int gost_ukm(const SSL *s, unsigned char *dgst_buf) ++{ ++ EVP_MD_CTX * hash = NULL; ++ unsigned int md_len; + -+static EVP_PKEY_CTX *gost_pkey_nid2ctx(int nid) ++ hash = EVP_MD_CTX_new(); ++ if (hash == NULL ++ || EVP_DigestInit(hash, EVP_get_digestbynid(NID_id_GostR3411_2012_256)) <= 0 ++ || EVP_DigestUpdate(hash, s->s3->client_random, SSL3_RANDOM_SIZE) <= 0 ++ || EVP_DigestUpdate(hash, s->s3->server_random, SSL3_RANDOM_SIZE) <= 0 ++ || EVP_DigestFinal_ex(hash, dgst_buf, &md_len) <= 0) { ++ EVP_MD_CTX_free(hash); ++ return 0; ++ } else { ++ EVP_MD_CTX_free(hash); ++ return 1; ++ } ++} ++#endif ++ ++static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) +{ -+ int i = 0; -+ TLS_GOST_GROUP_PARAM *pGostParam = NULL; -+ EVP_PKEY_CTX *pctx = NULL; ++#ifndef OPENSSL_NO_GOST ++ /* GOST 2018 key exchange message creation */ ++ unsigned char rnd_dgst[32], tmp[255]; ++ EVP_PKEY_CTX *pkey_ctx = NULL; ++ X509 *peer_cert; ++ unsigned char *pms = NULL; ++ size_t pmslen = 0; ++ size_t msglen; ++ int cipher_nid = gost18_cke_cipher_nid(s); + -+ for (i = 0; i < OSSL_NELEM(gost_param); i++) { -+ if (gost_param[i].nid == nid) { -+ pGostParam = gost_param + i; -+ break; -+ } -+ } ++ if (cipher_nid == NID_undef) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } + -+ if (pGostParam == NULL) { -+ return NULL; -+ } ++ if (gost_ukm(s, rnd_dgst) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } + -+ pctx = EVP_PKEY_CTX_new_id(pGostParam->alg_nid, NULL); -+ if (pctx == NULL -+ || EVP_PKEY_CTX_ctrl_str(pctx, "paramset", pGostParam->params) <= 0) { -+ EVP_PKEY_CTX_free(pctx); -+ return NULL; -+ } ++ /* Pre-master secret - random bytes */ ++ pmslen = 32; ++ pms = OPENSSL_malloc(pmslen); ++ if (pms == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_MALLOC_FAILURE); ++ goto err; ++ } + -+ return pctx; -+} ++ if (RAND_bytes(pms, (int)pmslen) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } + -+#endif - /* Generate a private key from a group ID */ - EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) - { -@@ -4711,8 +4877,13 @@ - gtype = ginf->flags & TLS_CURVE_TYPE; - if (gtype == TLS_CURVE_CUSTOM) - pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); -+#ifndef OPENSSL_NO_GOST -+ else if (gtype == TLS_CURVE_GOST) -+ pctx = gost_pkey_nid2ctx(ginf->nid); -+#endif - else - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); ++ /* ++ * Get server certificate PKEY and create ctx from it ++ */ ++ peer_cert = s->session->peer; ++ if (!peer_cert) { ++ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); ++ return 0; ++ } + - if (pctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_MALLOC_FAILURE); -@@ -4723,7 +4894,7 @@ - ERR_R_EVP_LIB); - goto err; - } -- if (gtype != TLS_CURVE_CUSTOM -+ if (gtype != TLS_CURVE_CUSTOM && gtype != TLS_CURVE_GOST - && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_EVP_LIB); -@@ -4761,13 +4932,21 @@ - return NULL; - } - -+#ifndef OPENSSL_NO_GOST -+ if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_GOST) -+ pctx = gost_pkey_nid2ctx(ginf->nid); -+ else -+#endif - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); ++ pkey_ctx = EVP_PKEY_CTX_new(X509_get0_pubkey(peer_cert), NULL); ++ if (pkey_ctx == NULL) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_MALLOC_FAILURE); ++ return 0; ++ } + - if (pctx == NULL) - goto err; - if (EVP_PKEY_paramgen_init(pctx) <= 0) - goto err; -- if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) -+ if ((ginf->flags & TLS_CURVE_TYPE) != TLS_CURVE_GOST) { -+ if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) - goto err; ++ if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 ) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ }; ++ ++ /* ++ * Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code ++ * */ ++ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, ++ EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) < 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ SSL_R_LIBRARY_BUG); ++ goto err; + } - if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) { - EVP_PKEY_free(pkey); - pkey = NULL; -Index: ssl/statem/statem_lib.c -=================================================================== ---- ssl/statem/statem_lib.c (revision 14523) -+++ ssl/statem/statem_lib.c (working copy) -@@ -410,7 +410,6 @@ ++ ++ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, ++ EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) < 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ SSL_R_LIBRARY_BUG); ++ goto err; ++ } ++ ++ msglen = 255; ++ if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ SSL_R_LIBRARY_BUG); ++ goto err; ++ } ++ ++ if (!WPACKET_memcpy(pkt, tmp, msglen)) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ ++ EVP_PKEY_CTX_free(pkey_ctx); ++ s->s3->tmp.pms = pms; ++ s->s3->tmp.pmslen = pmslen; ++ return 1; ++ err: ++ EVP_PKEY_CTX_free(pkey_ctx); ++ OPENSSL_clear_free(pms, pmslen); ++ return 0; ++#else ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++#endif ++} ++ + static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) + { + #ifndef OPENSSL_NO_SRP +@@ -3341,6 +3479,9 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) + } else if (alg_k & SSL_kGOST) { + if (!tls_construct_cke_gost(s, pkt)) + goto err; ++ } else if (alg_k & SSL_kGOST18) { ++ if (!tls_construct_cke_gost18(s, pkt)) ++ goto err; + } else if (alg_k & SSL_kSRP) { + if (!tls_construct_cke_srp(s, pkt)) + goto err; +diff --git ssl/statem/statem_lib.c ssl/statem/statem_lib.c +index 695caab3..004b452b 100644 +--- ssl/statem/statem_lib.c ++++ ssl/statem/statem_lib.c +@@ -410,7 +410,6 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) md == NULL ? "n/a" : EVP_MD_name(md)); #endif @@ -3031,7 +2815,7 @@ Index: ssl/statem/statem_lib.c /* * If key is GOST and len is exactly 64 or 128, it is signature without * length field (CryptoPro implementations at least till TLS 1.2) -@@ -1527,8 +1526,6 @@ +@@ -1539,8 +1538,6 @@ static int is_tls13_capable(const SSL *s) switch (i) { case SSL_PKEY_DSA_SIGN: case SSL_PKEY_GOST01: @@ -3040,11 +2824,27 @@ Index: ssl/statem/statem_lib.c continue; default: break; -Index: ssl/statem/statem_srvr.c -=================================================================== ---- ssl/statem/statem_srvr.c (revision 14523) -+++ ssl/statem/statem_srvr.c (working copy) -@@ -3446,6 +3446,93 @@ +diff --git ssl/statem/statem_local.h ssl/statem/statem_local.h +index eae88053..50f6bfe4 100644 +--- ssl/statem/statem_local.h ++++ ssl/statem/statem_local.h +@@ -155,6 +155,11 @@ __owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt); + __owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt); + MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt); + ++#ifndef OPENSSL_NO_GOST ++/* These functions are used in GOST18 CKE, both for client and server */ ++int gost18_cke_cipher_nid(const SSL *s); ++int gost_ukm(const SSL *s, unsigned char *dgst_buf); ++#endif + + /* Extension processing */ + +diff --git ssl/statem/statem_srvr.c ssl/statem/statem_srvr.c +index d701c46b..5765c279 100644 +--- ssl/statem/statem_srvr.c ++++ ssl/statem/statem_srvr.c +@@ -3455,6 +3455,93 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) #endif } @@ -3138,7 +2938,7 @@ Index: ssl/statem/statem_srvr.c MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) { unsigned long alg_k; -@@ -3496,6 +3583,11 @@ +@@ -3505,6 +3592,11 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) /* SSLfatal() already called */ goto err; } @@ -3150,223 +2950,399 @@ Index: ssl/statem/statem_srvr.c } else { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, -Index: ssl/statem/extensions_srvr.c -=================================================================== ---- ssl/statem/extensions_srvr.c (revision 14523) -+++ ssl/statem/extensions_srvr.c (working copy) -@@ -624,7 +624,7 @@ +diff --git ssl/t1_enc.c ssl/t1_enc.c +index c85c0b03..eb366883 100644 +--- ssl/t1_enc.c ++++ ssl/t1_enc.c +@@ -113,6 +113,11 @@ int tls1_change_cipher_state(SSL *s, int which) + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; - if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) - return 1; -- -+/* FIXME beldmit GOST */ - /* Sanity check */ - if (s->s3->peer_tmp != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, -@@ -1623,7 +1623,9 @@ - if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD - || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4 - || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT -- || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) { -+ || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12 -+ || s->s3->tmp.new_cipher->algorithm_enc == SSL_MAGMA -+ || s->s3->tmp.new_cipher->algorithm_enc == SSL_KUZNYECHIK) { - s->ext.use_etm = 0; - return EXT_RETURN_NOT_SENT; ++ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) ++ s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE; ++ else ++ s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE; ++ + if (s->enc_read_ctx != NULL) { + reuse_dd = 1; + } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { +@@ -160,6 +165,11 @@ int tls1_change_cipher_state(SSL *s, int which) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; ++ ++ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) ++ s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE; ++ else ++ s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE; + if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) { + reuse_dd = 1; + } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { +@@ -298,11 +308,11 @@ int tls1_change_cipher_state(SSL *s, int which) + goto err; + } + } else { +- if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { +- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, +- ERR_R_INTERNAL_ERROR); +- goto err; +- } ++ if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, ++ ERR_R_INTERNAL_ERROR); ++ goto err; ++ } } -@@ -1682,6 +1684,7 @@ - unsigned int context, X509 *x, - size_t chainidx) + /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ + if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size +@@ -438,6 +448,10 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, { -+/* FIXME beldmit GOST */ - #ifndef OPENSSL_NO_TLS1_3 - unsigned char *encodedPoint; - size_t encoded_pt_len = 0; -Index: ssl/statem/statem_local.h -=================================================================== ---- ssl/statem/statem_local.h (revision 14523) -+++ ssl/statem/statem_local.h (working copy) -@@ -153,6 +153,11 @@ - __owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt); - MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt); + size_t hashlen; + unsigned char hash[EVP_MAX_MD_SIZE]; ++ size_t finished_size = TLS1_FINISH_MAC_LENGTH; ++ ++ if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kGOST18) ++ finished_size = 32; + + if (!ssl3_digest_cached_records(s, 0)) { + /* SSLfatal() already called */ +@@ -451,12 +465,12 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, + + if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, + s->session->master_key, s->session->master_key_length, +- out, TLS1_FINISH_MAC_LENGTH, 1)) { ++ out, finished_size, 1)) { + /* SSLfatal() already called */ + return 0; + } + OPENSSL_cleanse(hash, hashlen); +- return TLS1_FINISH_MAC_LENGTH; ++ return finished_size; + } + + int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, +diff --git ssl/t1_lib.c ssl/t1_lib.c +index b1d3add1..72cfc450 100644 +--- ssl/t1_lib.c ++++ ssl/t1_lib.c +@@ -169,6 +169,18 @@ static const TLS_GROUP_INFO nid_list[] = { + {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ + {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ + {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ ++#ifndef OPENSSL_NO_GOST ++ {NID_undef, 0, TLS_CURVE_CUSTOM}, /* 31 */ ++ {NID_undef, 0, TLS_CURVE_CUSTOM}, /* 32 */ ++ {NID_undef, 0, TLS_CURVE_CUSTOM}, /* 33 */ ++ {NID_id_tc26_gost_3410_2012_256_paramSetA, 128, TLS_CURVE_GOST}, ++ {NID_id_tc26_gost_3410_2012_256_paramSetB, 128, TLS_CURVE_GOST}, ++ {NID_id_tc26_gost_3410_2012_256_paramSetC, 128, TLS_CURVE_GOST}, ++ {NID_id_tc26_gost_3410_2012_256_paramSetD, 128, TLS_CURVE_GOST}, ++ {NID_id_tc26_gost_3410_2012_512_paramSetA, 256, TLS_CURVE_GOST}, ++ {NID_id_tc26_gost_3410_2012_512_paramSetB, 256, TLS_CURVE_GOST}, ++ {NID_id_tc26_gost_3410_2012_512_paramSetC, 256, TLS_CURVE_GOST}, ++#endif + }; + + static const unsigned char ecformats_default[] = { +@@ -184,6 +196,15 @@ static const uint16_t eccurves_default[] = { + 30, /* X448 (30) */ + 25, /* secp521r1 (25) */ + 24, /* secp384r1 (24) */ ++#ifndef OPENSSL_NO_GOST ++ 34, ++ 35, ++ 36, ++ 37, ++ 38, ++ 39, ++ 40, ++#endif + }; + + static const uint16_t suiteb_curves[] = { +@@ -196,6 +217,8 @@ const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t group_id) + /* ECC curves from RFC 4492 and RFC 7027 */ + if (group_id < 1 || group_id > OSSL_NELEM(nid_list)) + return NULL; ++ if (nid_list[group_id - 1].nid == NID_undef) ++ return NULL; + return &nid_list[group_id - 1]; + } + +@@ -380,6 +403,33 @@ typedef struct { + int nid_arr[MAX_CURVELIST]; + } nid_cb_st; + ++#ifndef OPENSSL_NO_GOST ++typedef struct { ++ const char *name; /* Name of GOST curve */ ++ int nid; /* Curve NID */ ++} EC_GOST_NAME; ++ ++static EC_GOST_NAME gost_curves[] = { ++ {"GC256A", NID_id_tc26_gost_3410_2012_256_paramSetA}, ++ {"GC256B", NID_id_tc26_gost_3410_2012_256_paramSetB}, ++ {"GC256C", NID_id_tc26_gost_3410_2012_256_paramSetC}, ++ {"GC256D", NID_id_tc26_gost_3410_2012_256_paramSetD}, ++ {"GC512A", NID_id_tc26_gost_3410_2012_512_paramSetA}, ++ {"GC512B", NID_id_tc26_gost_3410_2012_512_paramSetB}, ++ {"GC512C", NID_id_tc26_gost_3410_2012_512_paramSetC}, ++}; ++ ++int GOST_curve2nid(const char *name) ++{ ++ size_t i; ++ for (i = 0; i < OSSL_NELEM(gost_curves); i++) { ++ if (strcmp(gost_curves[i].name, name) == 0) ++ return gost_curves[i].nid; ++ } ++ return NID_undef; ++} ++#endif ++ + static int nid_cb(const char *elem, int len, void *arg) + { + nid_cb_st *narg = arg; +@@ -395,6 +445,11 @@ static int nid_cb(const char *elem, int len, void *arg) + memcpy(etmp, elem, len); + etmp[len] = 0; + nid = EC_curve_nist2nid(etmp); ++#ifndef OPENSSL_NO_GOST ++ /* FIXME beldmit */ ++ if (nid == NID_undef) ++ nid = GOST_curve2nid(etmp); ++#endif + if (nid == NID_undef) + nid = OBJ_sn2nid(etmp); + if (nid == NID_undef) +@@ -670,8 +725,17 @@ static const uint16_t tls12_sigalgs[] = { + TLSEXT_SIGALG_dsa_sha512, + #endif + #ifndef OPENSSL_NO_GOST ++ TLSEXT_SIGALG_gostr34102012_256a, ++ TLSEXT_SIGALG_gostr34102012_256b, ++ TLSEXT_SIGALG_gostr34102012_256c, ++ TLSEXT_SIGALG_gostr34102012_256d, ++ TLSEXT_SIGALG_gostr34102012_512a, ++ TLSEXT_SIGALG_gostr34102012_512b, ++ TLSEXT_SIGALG_gostr34102012_512c, + TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, + TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, ++ TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy, ++ TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy, + TLSEXT_SIGALG_gostr34102001_gostr3411, + #endif + }; +@@ -758,6 +822,34 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { + NID_dsaWithSHA1, NID_undef}, + #endif + #ifndef OPENSSL_NO_GOST ++ {"gostr34102012_256a", TLSEXT_SIGALG_gostr34102012_256a, ++ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, ++ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, ++ NID_undef, NID_undef}, ++ {"gostr34102012_256b", TLSEXT_SIGALG_gostr34102012_256b, ++ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, ++ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, ++ NID_undef, NID_undef}, ++ {"gostr34102012_256c", TLSEXT_SIGALG_gostr34102012_256c, ++ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, ++ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, ++ NID_undef, NID_undef}, ++ {"gostr34102012_256d", TLSEXT_SIGALG_gostr34102012_256d, ++ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, ++ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, ++ NID_undef, NID_undef}, ++ {"gostr34102012_512a", TLSEXT_SIGALG_gostr34102012_512a, ++ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, ++ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, ++ NID_undef, NID_undef}, ++ {"gostr34102012_512b", TLSEXT_SIGALG_gostr34102012_512b, ++ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, ++ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, ++ NID_undef, NID_undef}, ++ {"gostr34102012_512c", TLSEXT_SIGALG_gostr34102012_512c, ++ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, ++ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, ++ NID_undef, NID_undef}, + {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, +@@ -766,6 +858,14 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { + NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, + NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, + NID_undef, NID_undef}, ++ {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy, ++ NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, ++ NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, ++ NID_undef, NID_undef}, ++ {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy, ++ NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, ++ NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, ++ NID_undef, NID_undef}, + {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411, + NID_id_GostR3411_94, SSL_MD_GOST94_IDX, + NID_id_GostR3410_2001, SSL_PKEY_GOST01, +@@ -886,6 +986,24 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) + } + } + } ++ /* ++ * Here is another fallback: when broken implementations did not sent ++ * proper signature_algorithm extension, we try to use this function. ++ * ++ * As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used ++ * with new (aGOST12-only) ciphersuites, we should find out which one is available really. ++ * */ ++ else if (idx == SSL_PKEY_GOST12_256) { ++ int real_idx; ++ ++ for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256; ++ real_idx--) { ++ if (s->cert->pkeys[real_idx].privatekey != NULL) { ++ idx = real_idx; ++ break; ++ } ++ } ++ } + } else { + idx = s->cert->key - s->cert->pkeys; + } +@@ -1612,10 +1730,8 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) + if (ssl_cert_is_disabled(lu->sig_idx)) + return 0; -+#ifndef OPENSSL_NO_GOST -+/* These functions are used in GOST18 CKE, both for client and server */ -+int gost18_cke_cipher_nid(const SSL *s); -+int gost_ukm(const SSL *s, unsigned char *dgst_buf); -+#endif +- if (lu->sig == NID_id_GostR3410_2012_256 +- || lu->sig == NID_id_GostR3410_2012_512 +- || lu->sig == NID_id_GostR3410_2001) { +- /* We never allow GOST sig algs on the server with TLSv1.3 */ ++ if (lu->sig == NID_id_GostR3410_2001) { ++ /* GOST sig algs on the server with TLSv1.3 are allowed for GOST2012 */ + if (s->server && SSL_IS_TLS13(s)) + return 0; + if (!s->server +@@ -1643,7 +1759,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) + if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) + continue; - /* Extension processing */ +- if ((c->algorithm_mkey & SSL_kGOST) != 0) ++ if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0) + break; + } + if (i == num) +diff --git ssl/t1_trce.c ssl/t1_trce.c +index e2c397b7..9d7341da 100644 +--- ssl/t1_trce.c ++++ ssl/t1_trce.c +@@ -443,6 +443,9 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = { + {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, + {0xFF85, "GOST2012-GOST8912-GOST8912"}, + {0xFF87, "GOST2012-NULL-GOST12"}, ++ {0xC100, "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC"}, ++ {0xC101, "GOST2012-MAGMA-MAGMAOMAC"}, ++ {0xC102, "GOST2012-GOST8912-IANA"}, + }; -Index: ssl/statem/statem_clnt.c -=================================================================== ---- ssl/statem/statem_clnt.c (revision 14523) -+++ ssl/statem/statem_clnt.c (working copy) -@@ -3280,6 +3280,144 @@ - #endif - } + /* Compression methods */ +@@ -522,6 +525,13 @@ static const ssl_trace_tbl ssl_groups_tbl[] = { + {28, "brainpoolP512r1"}, + {29, "ecdh_x25519"}, + {30, "ecdh_x448"}, ++ {34, "GC256A"}, ++ {35, "GC256B"}, ++ {36, "GC256C"}, ++ {37, "GC256D"}, ++ {38, "GC512A"}, ++ {39, "GC512B"}, ++ {40, "GC512C"}, + {256, "ffdhe2048"}, + {257, "ffdhe3072"}, + {258, "ffdhe4096"}, +@@ -571,6 +581,8 @@ static const ssl_trace_tbl ssl_sigalg_tbl[] = { + {TLSEXT_SIGALG_dsa_sha1, "dsa_sha1"}, + {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, "gost2012_256"}, + {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, "gost2012_512"}, ++ {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256_legacy, "gost2012_256"}, ++ {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512_legacy, "gost2012_512"}, + {TLSEXT_SIGALG_gostr34102001_gostr3411, "gost2001_gost94"}, + }; -+#ifndef OPENSSL_NO_GOST -+int gost18_cke_cipher_nid(const SSL *s) -+{ -+ if ((s->s3->tmp.new_cipher->algorithm_enc & SSL_MAGMA) != 0) -+ return NID_magma_ctr; -+ else if ((s->s3->tmp.new_cipher->algorithm_enc & SSL_KUZNYECHIK) != 0) -+ return NID_kuznyechik_ctr; -+ -+ return NID_undef; -+} -+ -+int gost_ukm(const SSL *s, unsigned char *dgst_buf) -+{ -+ EVP_MD_CTX * hash = NULL; -+ unsigned int md_len; -+ -+ hash = EVP_MD_CTX_new(); -+ if (hash == NULL -+ || EVP_DigestInit(hash, EVP_get_digestbynid(NID_id_GostR3411_2012_256)) <= 0 -+ || EVP_DigestUpdate(hash, s->s3->client_random, SSL3_RANDOM_SIZE) <= 0 -+ || EVP_DigestUpdate(hash, s->s3->server_random, SSL3_RANDOM_SIZE) <= 0 -+ || EVP_DigestFinal_ex(hash, dgst_buf, &md_len) <= 0) { -+ EVP_MD_CTX_free(hash); -+ return 0; -+ } else { -+ EVP_MD_CTX_free(hash); -+ return 1; +@@ -584,7 +596,9 @@ static const ssl_trace_tbl ssl_ctype_tbl[] = { + {20, "fortezza_dms"}, + {64, "ecdsa_sign"}, + {65, "rsa_fixed_ecdh"}, +- {66, "ecdsa_fixed_ecdh"} ++ {66, "ecdsa_fixed_ecdh"}, ++ {67, "gost_sign256"}, ++ {68, "gost_sign512"}, + }; + + static const ssl_trace_tbl ssl_psk_kex_modes_tbl[] = { +@@ -1077,6 +1091,10 @@ static int ssl_get_keyex(const char **pname, const SSL *ssl) + *pname = "GOST"; + return SSL_kGOST; + } ++ if (alg_k & SSL_kGOST18) { ++ *pname = "GOST18"; ++ return SSL_kGOST18; + } -+} -+#endif -+ -+static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) -+{ + *pname = "UNKNOWN"; + return 0; + } +@@ -1119,7 +1137,16 @@ static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl, + if (!ssl_print_hexbuf(bio, indent + 2, "ecdh_Yc", 1, &msg, &msglen)) + return 0; + break; +- +#ifndef OPENSSL_NO_GOST -+ /* GOST 2018 key exchange message creation */ -+ unsigned char rnd_dgst[32], tmp[255]; -+ EVP_PKEY_CTX *pkey_ctx = NULL; -+ X509 *peer_cert; -+ unsigned char *pms = NULL; -+ size_t pmslen = 0; -+ size_t msglen; -+ int cipher_nid = gost18_cke_cipher_nid(s); -+ -+ if (cipher_nid == NID_undef) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_INTERNAL_ERROR); -+ return 0; -+ } -+ -+ if (gost_ukm(s, rnd_dgst) <= 0) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ /* Pre-master secret - random bytes */ -+ pmslen = 32; -+ pms = OPENSSL_malloc(pmslen); -+ if (pms == NULL) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (RAND_bytes(pms, (int)pmslen) <= 0) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ /* -+ * Get server certificate PKEY and create ctx from it -+ */ -+ peer_cert = s->session->peer; -+ if (!peer_cert) { -+ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); -+ return 0; -+ } -+ -+ pkey_ctx = EVP_PKEY_CTX_new(X509_get0_pubkey(peer_cert), NULL); -+ if (pkey_ctx == NULL) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ -+ if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 ) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_INTERNAL_ERROR); -+ goto err; -+ }; -+ -+ /* -+ * Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code -+ * */ -+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, -+ EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) < 0) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ SSL_R_LIBRARY_BUG); -+ goto err; -+ } -+ -+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, -+ EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) < 0) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ SSL_R_LIBRARY_BUG); -+ goto err; -+ } -+ -+ msglen = 255; -+ if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ SSL_R_LIBRARY_BUG); -+ goto err; -+ } ++ case SSL_kGOST: ++ ssl_print_hex(bio, indent + 2, "GOST-wrapped PreMasterSecret", msg, msglen); ++ break; ++ case SSL_kGOST18: ++ ssl_print_hex(bio, indent + 2, ++ "GOST-wrapped PreMasterSecret", msg, msglen); ++ return 0; ++ break; ++#endif + } + + return !msglen; +diff --git ssl/tls13_enc.c ssl/tls13_enc.c +index b8fb07f2..50e9aa3a 100644 +--- ssl/tls13_enc.c ++++ ssl/tls13_enc.c +@@ -428,6 +428,21 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, + goto err; + } + ++ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE) { ++ int res = 0; ++ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE_S) { ++ res = EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_SET_TLSTREE_PARAMS, 0, "short"); ++ } else if (s->s3->tmp.new_cipher->algorithm2 & TLS1_TLSTREE_L) { ++ res = EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_SET_TLSTREE_PARAMS, 0, "long"); ++ } + -+ if (!WPACKET_memcpy(pkt, tmp, msglen)) { -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_INTERNAL_ERROR); -+ goto err; ++ if (res <= 0) { ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, ++ ERR_R_EVP_LIB); ++ goto err; ++ } + } + -+ EVP_PKEY_CTX_free(pkey_ctx); -+ s->s3->tmp.pms = pms; -+ s->s3->tmp.pmslen = pmslen; -+ return 1; -+ err: -+ EVP_PKEY_CTX_free(pkey_ctx); -+ OPENSSL_clear_free(pms, pmslen); -+ return 0; -+#else -+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, -+ ERR_R_INTERNAL_ERROR); -+ return 0; -+#endif -+} -+ - static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) - { - #ifndef OPENSSL_NO_SRP -@@ -3336,6 +3474,9 @@ - } else if (alg_k & SSL_kGOST) { - if (!tls_construct_cke_gost(s, pkt)) - goto err; -+ } else if (alg_k & SSL_kGOST18) { -+ if (!tls_construct_cke_gost18(s, pkt)) -+ goto err; - } else if (alg_k & SSL_kSRP) { - if (!tls_construct_cke_srp(s, pkt)) - goto err; -Index: util/libcrypto.num -=================================================================== ---- util/libcrypto.num (revision 14523) -+++ util/libcrypto.num (working copy) -@@ -4587,3 +4587,8 @@ - EVP_PKEY_meth_get_digestverify 4541 1_1_1e EXIST::FUNCTION: - EVP_PKEY_meth_get_digestsign 4542 1_1_1e EXIST::FUNCTION: - RSA_get0_pss_params 4543 1_1_1e EXIST::FUNCTION:RSA -+CMS_add1_recipient 4544 1_1_1g EXIST::FUNCTION:CMS -+PKCS8_pkey_add1_attr 4545 1_1_1g EXIST::FUNCTION: -+PKCS8_pkey_add1_attr_by_OBJ 4546 1_1_1g EXIST::FUNCTION: -+CMS_decrypt_set1_pkey_and_peer 4547 1_1_1g EXIST::FUNCTION:CMS -+CMS_RecipientInfo_kari_set0_pkey_and_peer 4548 1_1_1g EXIST::FUNCTION:CMS + return 1; + err: + OPENSSL_cleanse(key, sizeof(key)); +diff --git util/libcrypto.num util/libcrypto.num +index 436f799b..021d60aa 100644 +--- util/libcrypto.num ++++ util/libcrypto.num +@@ -4591,3 +4591,8 @@ X509_ALGOR_copy 4544 1_1_1h EXIST::FUNCTION: + X509_REQ_set0_signature 4545 1_1_1h EXIST::FUNCTION: + X509_REQ_set1_signature_algo 4546 1_1_1h EXIST::FUNCTION: + EC_KEY_decoded_from_explicit_params 4547 1_1_1h EXIST::FUNCTION:EC ++CMS_RecipientInfo_kari_set0_pkey_and_peer 4548 1_1_1m EXIST::FUNCTION:CMS ++PKCS8_pkey_add1_attr 4549 1_1_1m EXIST::FUNCTION: ++CMS_decrypt_set1_pkey_and_peer 4550 1_1_1m EXIST::FUNCTION:CMS ++PKCS8_pkey_add1_attr_by_OBJ 4551 1_1_1m EXIST::FUNCTION: ++CMS_add1_recipient 4552 1_1_1m EXIST::FUNCTION:CMS diff --git a/patches/openssl_111g_obj.diff b/patches/openssl_111m_obj.diff similarity index 97% rename from patches/openssl_111g_obj.diff rename to patches/openssl_111m_obj.diff index cf32bd6..838c104 100644 --- a/patches/openssl_111g_obj.diff +++ b/patches/openssl_111m_obj.diff @@ -51,18 +51,9 @@ index 00000000..68d1d733 + +#endif diff --git crypto/objects/obj_dat.h crypto/objects/obj_dat.h -index d1b1bc7f..d8082b59 100644 +index 24b49a2d..d8082b59 100644 --- crypto/objects/obj_dat.h +++ crypto/objects/obj_dat.h -@@ -2,7 +2,7 @@ - * WARNING: do not edit! - * Generated by crypto/objects/obj_dat.pl - * -- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the OpenSSL license (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 @@ -10,7 +10,7 @@ */ @@ -570,18 +561,9 @@ index eda55e4e..5c81d68a 100644 +OBJ_classSignToolKB2="\x2A\x85\x03\x64\x71\x05" +OBJ_classSignToolKA1="\x2A\x85\x03\x64\x71\x06" diff --git include/openssl/obj_mac.h include/openssl/obj_mac.h -index 8795a5e3..90b5de76 100644 +index 260357b1..90b5de76 100644 --- include/openssl/obj_mac.h +++ include/openssl/obj_mac.h -@@ -2,7 +2,7 @@ - * WARNING: do not edit! - * Generated by crypto/objects/objects.pl - * -- * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the OpenSSL license (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 @@ -4164,22 +4164,22 @@ #define SN_id_tc26_modules "id-tc26-modules" diff --git a/patches/openssl_111m_tls13.diff b/patches/openssl_111m_tls13.diff new file mode 100644 index 0000000..0d6c7c4 --- /dev/null +++ b/patches/openssl_111m_tls13.diff @@ -0,0 +1,83 @@ +diff --git include/openssl/evp.h include/openssl/evp.h +index 8172316e..f9322b7b 100644 +--- include/openssl/evp.h ++++ include/openssl/evp.h +@@ -1342,6 +1342,8 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, + # define EVP_PKEY_CTRL_GET_MD 13 + + # define EVP_PKEY_CTRL_SET_DIGEST_SIZE 14 ++/* Used for GOST curves that have more than one name */ ++# define EVP_PKEY_CTRL_PARAMS_MATCH 15 + + # define EVP_PKEY_ALG_CTRL 0x1000 + +diff --git ssl/t1_lib.c ssl/t1_lib.c +index 72cfc450..092d8de1 100644 +--- ssl/t1_lib.c ++++ ssl/t1_lib.c +@@ -825,31 +825,31 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { + {"gostr34102012_256a", TLSEXT_SIGALG_gostr34102012_256a, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, +- NID_undef, NID_undef}, ++ NID_undef, NID_id_tc26_gost_3410_2012_256_paramSetA}, + {"gostr34102012_256b", TLSEXT_SIGALG_gostr34102012_256b, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, +- NID_undef, NID_undef}, ++ NID_undef, NID_id_tc26_gost_3410_2012_256_paramSetB}, + {"gostr34102012_256c", TLSEXT_SIGALG_gostr34102012_256c, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, +- NID_undef, NID_undef}, ++ NID_undef, NID_id_tc26_gost_3410_2012_256_paramSetC}, + {"gostr34102012_256d", TLSEXT_SIGALG_gostr34102012_256d, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, +- NID_undef, NID_undef}, ++ NID_undef, NID_id_tc26_gost_3410_2012_256_paramSetD}, + {"gostr34102012_512a", TLSEXT_SIGALG_gostr34102012_512a, + NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, + NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, +- NID_undef, NID_undef}, ++ NID_undef, NID_id_tc26_gost_3410_2012_512_paramSetA}, + {"gostr34102012_512b", TLSEXT_SIGALG_gostr34102012_512b, + NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, + NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, +- NID_undef, NID_undef}, ++ NID_undef, NID_id_tc26_gost_3410_2012_512_paramSetB}, + {"gostr34102012_512c", TLSEXT_SIGALG_gostr34102012_512c, + NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, + NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, +- NID_undef, NID_undef}, ++ NID_undef, NID_id_tc26_gost_3410_2012_512_paramSetC}, + {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, +@@ -2839,6 +2839,26 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) + if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(tmppkey), lu)) + continue; + } ++#ifndef OPENSSL_NO_GOST ++ else if (lu->sig == NID_id_GostR3410_2012_256 ++ || lu->sig == NID_id_GostR3410_2012_512) { ++ EVP_PKEY_CTX *tmp = EVP_PKEY_CTX_new(tmppkey, NULL); ++ int found = 0; ++ ++ if (tmp == NULL) ++ continue; ++ if (EVP_PKEY_sign_init(tmp) != 1) { ++ EVP_PKEY_CTX_free(tmp); ++ continue; ++ } ++ ++ /* содержательное совпадение параметров с параметрами ключа */ ++ found = (EVP_PKEY_CTX_ctrl(tmp, -1, -1, EVP_PKEY_CTRL_PARAMS_MATCH, lu->curve, NULL) > 0); ++ EVP_PKEY_CTX_free(tmp); ++ if (!found) ++ continue; ++ } ++#endif + break; + } + -- 2.39.2