diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2014-11-18 05:33:44 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2014-11-18 05:33:44 +0000 |
commit | 7f4d406116c74cb6830b7da5419560204d47258d (patch) | |
tree | d6f87ecff6e432a0df7647e1617e31ead3678596 /lib/libssl | |
parent | 989992f5daa824e6c2aeaae8c32d6e055e0db678 (diff) |
Update the GOST code in libssl, as contributed by Dmitry Eremin-Solenikov.
This causes a libssl major version bump as this affects the layout of some
internal-but-unfortunately-made-visible structs.
Diffstat (limited to 'lib/libssl')
-rw-r--r-- | lib/libssl/s3_clnt.c | 71 | ||||
-rw-r--r-- | lib/libssl/s3_lib.c | 47 | ||||
-rw-r--r-- | lib/libssl/s3_srvr.c | 78 | ||||
-rw-r--r-- | lib/libssl/shlib_version | 2 | ||||
-rw-r--r-- | lib/libssl/ssl.h | 4 | ||||
-rw-r--r-- | lib/libssl/ssl3.h | 4 | ||||
-rw-r--r-- | lib/libssl/ssl_algs.c | 12 | ||||
-rw-r--r-- | lib/libssl/ssl_cert.c | 6 | ||||
-rw-r--r-- | lib/libssl/ssl_ciph.c | 70 | ||||
-rw-r--r-- | lib/libssl/ssl_locl.h | 9 | ||||
-rw-r--r-- | lib/libssl/t1_enc.c | 14 | ||||
-rw-r--r-- | lib/libssl/t1_lib.c | 39 | ||||
-rw-r--r-- | lib/libssl/tls1.h | 14 |
13 files changed, 297 insertions, 73 deletions
diff --git a/lib/libssl/s3_clnt.c b/lib/libssl/s3_clnt.c index 4c086bae836..0a834f12bc0 100644 --- a/lib/libssl/s3_clnt.c +++ b/lib/libssl/s3_clnt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_clnt.c,v 1.93 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: s3_clnt.c,v 1.94 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -162,6 +162,9 @@ #ifndef OPENSSL_NO_ENGINE #include <openssl/engine.h> #endif +#ifndef OPENSSL_NO_GOST +#include <openssl/gost.h> +#endif static const SSL_METHOD *ssl3_get_client_method(int ver); static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b); @@ -781,6 +784,7 @@ ssl3_get_server_hello(SSL *s) unsigned int j, cipher_id; uint16_t cipher_value; long n; + unsigned long alg_k; n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, /* ?? */ &ok); @@ -943,7 +947,9 @@ ssl3_get_server_hello(SSL *s) * Don't digest cached records if no sigalgs: we may need them for * client authentication. */ - if (!SSL_USE_SIGALGS(s) && !ssl3_digest_cached_records(s)) { + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) && + !ssl3_digest_cached_records(s)) { al = SSL_AD_INTERNAL_ERROR; goto f_err; } @@ -1937,7 +1943,6 @@ ssl3_get_server_done(SSL *s) return (ret); } - int ssl3_send_client_key_exchange(SSL *s) { @@ -2273,18 +2278,16 @@ ssl3_send_client_key_exchange(SSL *s) size_t msglen; unsigned int md_len; - int keytype; unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; EVP_MD_CTX *ukm_hash; EVP_PKEY *pub_key; + int nid; /* Get server sertificate PKEY and create ctx from it */ - peer_cert = s->session->sess_cert->peer_pkeys[( - keytype = SSL_PKEY_GOST01)].x509; + peer_cert = s->session->sess_cert->peer_pkeys[SSL_PKEY_GOST01].x509; if (!peer_cert) - peer_cert = s->session->sess_cert->peer_pkeys[ - (keytype = SSL_PKEY_GOST94)].x509; + peer_cert = s->session->sess_cert->peer_pkeys[SSL_PKEY_GOST94].x509; if (!peer_cert) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); @@ -2329,8 +2332,12 @@ ssl3_send_client_key_exchange(SSL *s) ERR_R_MALLOC_FAILURE); goto err; } - EVP_DigestInit(ukm_hash, - EVP_get_digestbynid(NID_id_GostR3411_94)); + + if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94) + nid = NID_id_GostR3411_94; + else + nid = NID_id_tc26_gost3411_2012_256; + EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid)); EVP_DigestUpdate(ukm_hash, s->s3->client_random, SSL3_RANDOM_SIZE); EVP_DigestUpdate(ukm_hash, @@ -2498,24 +2505,48 @@ ssl3_send_client_verify(SSL *s) } s2n(j, p); n = j + 2; +#ifndef OPENSSL_NO_GOST } else if (pkey->type == NID_id_GostR3410_94 || - pkey->type == NID_id_GostR3410_2001) { - unsigned char signbuf[64]; - int i; - size_t sigsize = 64; - s->method->ssl3_enc->cert_verify_mac(s, - NID_id_GostR3411_94, data); - if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) - <= 0) { + pkey->type == NID_id_GostR3410_2001) { + unsigned char signbuf[128]; + long hdatalen = 0; + void *hdata; + const EVP_MD *md; + int nid; + size_t sigsize; + + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } - for (i = 63, j = 0; i >= 0; j++, i--) { - p[2 + j] = signbuf[i]; + if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || + !(md = EVP_get_digestbynid(nid))) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_EVP_LIB); + goto err; + } + if (!EVP_DigestInit_ex(&mctx, md, NULL) || + !EVP_DigestUpdate(&mctx, hdata, hdatalen) || + !EVP_DigestFinal(&mctx, signbuf, &u) || + (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || + (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, + GOST_SIG_FORMAT_RS_LE, + NULL) <= 0) || + (EVP_PKEY_sign(pctx, &(p[2]), &sigsize, + signbuf, u) <= 0)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, + ERR_R_EVP_LIB); + goto err; } + if (!ssl3_digest_cached_records(s)) + goto err; + j = sigsize; s2n(j, p); n = j + 2; +#endif } else { SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); diff --git a/lib/libssl/s3_lib.c b/lib/libssl/s3_lib.c index 21f1367442b..f2d2cb040d1 100644 --- a/lib/libssl/s3_lib.c +++ b/lib/libssl/s3_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_lib.c,v 1.84 2014/10/31 15:25:55 jsing Exp $ */ +/* $OpenBSD: s3_lib.c,v 1.85 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1759,6 +1759,40 @@ SSL_CIPHER ssl3_ciphers[] = { }, #endif + /* Cipher FF85 FIXME IANA */ + { + .valid = 1, + .name = "GOST2012256-GOST89-GOST89", + .id = 0x300ff85, /* FIXME IANA */ + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eGOST2814789CNT, + .algorithm_mac = SSL_GOST89MAC, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_HIGH, + .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256| + TLS1_STREAM_MAC, + .strength_bits = 256, + .alg_bits = 256 + }, + + /* Cipher FF87 FIXME IANA */ + { + .valid = 1, + .name = "GOST2012256-NULL-STREEBOG256", + .id = 0x300ff87, /* FIXME IANA */ + .algorithm_mkey = SSL_kGOST, + .algorithm_auth = SSL_aGOST01, + .algorithm_enc = SSL_eNULL, + .algorithm_mac = SSL_STREEBOG256, + .algorithm_ssl = SSL_TLSV1, + .algo_strength = SSL_STRONG_NONE, + .algorithm2 = SSL_HANDSHAKE_MAC_STREEBOG256|TLS1_PRF_STREEBOG256, + .strength_bits = 0, + .alg_bits = 0 + }, + + /* end of list */ }; @@ -2415,12 +2449,11 @@ ssl3_get_req_cert_type(SSL *s, unsigned char *p) alg_k = s->s3->tmp.new_cipher->algorithm_mkey; #ifndef OPENSSL_NO_GOST - if (s->version >= TLS1_VERSION) { - if (alg_k & SSL_kGOST) { - p[ret++] = TLS_CT_GOST94_SIGN; - p[ret++] = TLS_CT_GOST01_SIGN; - return (ret); - } + if ((alg_k & SSL_kGOST) && (s->version >= TLS1_VERSION)) { + p[ret++] = TLS_CT_GOST94_SIGN; + p[ret++] = TLS_CT_GOST01_SIGN; + p[ret++] = TLS_CT_GOST12_256_SIGN; + p[ret++] = TLS_CT_GOST12_512_SIGN; } #endif diff --git a/lib/libssl/s3_srvr.c b/lib/libssl/s3_srvr.c index a9f82b39d20..e1b2f9cf2dd 100644 --- a/lib/libssl/s3_srvr.c +++ b/lib/libssl/s3_srvr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s3_srvr.c,v 1.90 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: s3_srvr.c,v 1.91 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -159,6 +159,9 @@ #include <openssl/buffer.h> #include <openssl/evp.h> #include <openssl/dh.h> +#ifndef OPENSSL_NO_GOST +#include <openssl/gost.h> +#endif #include <openssl/hmac.h> #include <openssl/md5.h> #include <openssl/objects.h> @@ -516,6 +519,7 @@ ssl3_accept(SSL *s) ret = ssl3_get_client_key_exchange(s); if (ret <= 0) goto end; + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; if (ret == 2) { /* * For the ECDH ciphersuites when @@ -535,7 +539,7 @@ ssl3_accept(SSL *s) s->state = SSL3_ST_SR_FINISHED_A; #endif s->init_num = 0; - } else if (SSL_USE_SIGALGS(s)) { + } else if (SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) { s->state = SSL3_ST_SR_CERT_VRFY_A; s->init_num = 0; if (!s->session->peer) @@ -842,6 +846,7 @@ ssl3_get_client_hello(SSL *s) unsigned char *p, *d; SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *ciphers = NULL; + unsigned long alg_k; /* * We do this so that we will respond with our native type. @@ -1175,7 +1180,9 @@ ssl3_get_client_hello(SSL *s) s->s3->tmp.new_cipher = s->session->cipher; } - if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) { + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) || + !(s->verify_mode & SSL_VERIFY_PEER)) { if (!ssl3_digest_cached_records(s)) { al = SSL_AD_INTERNAL_ERROR; goto f_err; @@ -2336,7 +2343,7 @@ ssl3_get_cert_verify(SSL *s) goto f_err; } - if (EVP_VerifyFinal(&mctx, p , i, pkey) <= 0) { + if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE); @@ -2384,38 +2391,65 @@ ssl3_get_cert_verify(SSL *s) goto f_err; } } else +#ifndef OPENSSL_NO_GOST if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001) { - unsigned char signature[64]; - int idx; + long hdatalen = 0; + void *hdata; + unsigned char signature[128]; + unsigned int siglen = sizeof(signature); + int nid; EVP_PKEY_CTX *pctx; - - if (i != 64) { + + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, - SSL_R_WRONG_SIGNATURE_SIZE); - al = SSL_AD_DECODE_ERROR; + ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || + !(md = EVP_get_digestbynid(nid))) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; goto f_err; } pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (pctx == NULL) { + if (!pctx) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); - al = SSL_AD_DECODE_ERROR; + ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; goto f_err; } - EVP_PKEY_verify_init(pctx); - for (idx = 0; idx < 64; idx++) - signature[63 - idx] = p[idx]; - j = EVP_PKEY_verify(pctx, signature, 64, - s->s3->tmp.cert_verify_md, 32); - EVP_PKEY_CTX_free(pctx); - if (j <= 0) { + if (!EVP_DigestInit_ex(&mctx, md, NULL) || + !EVP_DigestUpdate(&mctx, hdata, hdatalen) || + !EVP_DigestFinal(&mctx, signature, &siglen) || + (EVP_PKEY_verify_init(pctx) <= 0) || + (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || + (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_VERIFY, + EVP_PKEY_CTRL_GOST_SIG_FORMAT, + GOST_SIG_FORMAT_RS_LE, + NULL) <= 0)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + EVP_PKEY_CTX_free(pctx); + goto f_err; + } + + if (EVP_PKEY_verify(pctx, p, i, signature, siglen) <= 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, - SSL_R_BAD_ECDSA_SIGNATURE); + SSL_R_BAD_SIGNATURE); + EVP_PKEY_CTX_free(pctx); goto f_err; } - } else { + + EVP_PKEY_CTX_free(pctx); + } else +#endif + { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); al = SSL_AD_UNSUPPORTED_CERTIFICATE; diff --git a/lib/libssl/shlib_version b/lib/libssl/shlib_version index 295c96b24e9..ade1e3940fb 100644 --- a/lib/libssl/shlib_version +++ b/lib/libssl/shlib_version @@ -1,2 +1,2 @@ -major=28 +major=29 minor=0 diff --git a/lib/libssl/ssl.h b/lib/libssl/ssl.h index 00a4b5e39be..2416b46d46f 100644 --- a/lib/libssl/ssl.h +++ b/lib/libssl/ssl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.h,v 1.71 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: ssl.h,v 1.72 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -295,6 +295,8 @@ extern "C" { #define SSL_TXT_GOST89MAC "GOST89MAC" #define SSL_TXT_SHA256 "SHA256" #define SSL_TXT_SHA384 "SHA384" +#define SSL_TXT_STREEBOG256 "STREEBOG256" +#define SSL_TXT_STREEBOG512 "STREEBOG512" #define SSL_TXT_DTLS1 "DTLSv1" #define SSL_TXT_DTLS1_BAD "DTLSv1-bad" diff --git a/lib/libssl/ssl3.h b/lib/libssl/ssl3.h index f10b288f310..5b9e31754ba 100644 --- a/lib/libssl/ssl3.h +++ b/lib/libssl/ssl3.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl3.h,v 1.28 2014/10/31 15:34:06 jsing Exp $ */ +/* $OpenBSD: ssl3.h,v 1.29 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -353,7 +353,7 @@ typedef struct ssl3_buffer_st { * enough to contain all of the cert types defined either for * SSLv3 and TLSv1. */ -#define SSL3_CT_NUMBER 9 +#define SSL3_CT_NUMBER 11 #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 diff --git a/lib/libssl/ssl_algs.c b/lib/libssl/ssl_algs.c index 842d50a7623..558d51ce7a0 100644 --- a/lib/libssl/ssl_algs.c +++ b/lib/libssl/ssl_algs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_algs.c,v 1.20 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: ssl_algs.c,v 1.21 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -98,6 +98,10 @@ SSL_library_init(void) EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_256_cbc()); #endif +#ifndef OPENSSL_NO_GOST + EVP_add_cipher(EVP_gost2814789_cfb64()); + EVP_add_cipher(EVP_gost2814789_cnt()); +#endif EVP_add_digest(EVP_md5()); EVP_add_digest_alias(SN_md5, "ssl2-md5"); @@ -114,6 +118,12 @@ SSL_library_init(void) EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); EVP_add_digest(EVP_ecdsa()); +#ifndef OPENSSL_NO_GOST + EVP_add_digest(EVP_gostr341194()); + EVP_add_digest(EVP_gost2814789imit()); + EVP_add_digest(EVP_streebog256()); + EVP_add_digest(EVP_streebog512()); +#endif /* initialize cipher/digest methods table */ ssl_load_ciphers(); return (1); diff --git a/lib/libssl/ssl_cert.c b/lib/libssl/ssl_cert.c index 7938c82c946..8bbfcd85d15 100644 --- a/lib/libssl/ssl_cert.c +++ b/lib/libssl/ssl_cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_cert.c,v 1.45 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: ssl_cert.c,v 1.46 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -166,6 +166,10 @@ ssl_cert_set_default_md(CERT *cert) cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +#ifndef OPENSSL_NO_GOST + cert->pkeys[SSL_PKEY_GOST94].digest = EVP_gostr341194(); + cert->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); +#endif } CERT * diff --git a/lib/libssl/ssl_ciph.c b/lib/libssl/ssl_ciph.c index 443c2ec6602..990fe9876c1 100644 --- a/lib/libssl/ssl_ciph.c +++ b/lib/libssl/ssl_ciph.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_ciph.c,v 1.73 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: ssl_ciph.c,v 1.74 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -175,30 +175,33 @@ static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { #define SSL_MD_GOST89MAC_IDX 3 #define SSL_MD_SHA256_IDX 4 #define SSL_MD_SHA384_IDX 5 +#define SSL_MD_STREEBOG256_IDX 6 +#define SSL_MD_STREEBOG512_IDX 7 /*Constant SSL_MAX_DIGEST equal to size of digests array should be * defined in the * ssl_locl.h */ #define SSL_MD_NUM_IDX SSL_MAX_DIGEST 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 }; /* PKEY_TYPE for GOST89MAC is known in advance, but, because * implementation is engine-provided, we'll fill it only if * corresponding EVP_PKEY_METHOD is found */ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { - EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, - EVP_PKEY_HMAC, EVP_PKEY_HMAC + EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_GOSTIMIT, + EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, }; static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0 }; static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = { SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA, SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, - SSL_HANDSHAKE_MAC_SHA384 + SSL_HANDSHAKE_MAC_SHA384, SSL_HANDSHAKE_MAC_STREEBOG256, + SSL_HANDSHAKE_MAC_STREEBOG512 }; #define CIPHER_ADD 1 @@ -325,7 +328,7 @@ static const SSL_CIPHER cipher_aliases[] = { .name = SSL_TXT_aGOST, .algorithm_auth = SSL_aGOST94|SSL_aGOST01, }, - + /* aliases combining key exchange and server authentication */ { .name = SSL_TXT_DHE, @@ -450,6 +453,14 @@ static const SSL_CIPHER cipher_aliases[] = { .name = SSL_TXT_SHA384, .algorithm_mac = SSL_SHA384, }, + { + .name = SSL_TXT_STREEBOG256, + .algorithm_mac = SSL_STREEBOG256, + }, + { + .name = SSL_TXT_STREEBOG512, + .algorithm_mac = SSL_STREEBOG512, + }, /* protocol version aliases */ { @@ -566,7 +577,6 @@ ssl_load_ciphers(void) } ssl_digest_methods[SSL_MD_GOST89MAC_IDX]= EVP_get_digestbyname(SN_id_Gost28147_89_MAC); - ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; } @@ -579,6 +589,14 @@ ssl_load_ciphers(void) EVP_get_digestbyname(SN_sha384); ssl_mac_secret_size[SSL_MD_SHA384_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); + ssl_digest_methods[SSL_MD_STREEBOG256_IDX]= + EVP_get_digestbyname(SN_id_tc26_gost3411_2012_256); + ssl_mac_secret_size[SSL_MD_STREEBOG256_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_STREEBOG256_IDX]); + ssl_digest_methods[SSL_MD_STREEBOG512_IDX]= + EVP_get_digestbyname(SN_id_tc26_gost3411_2012_512); + ssl_mac_secret_size[SSL_MD_STREEBOG512_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_STREEBOG512_IDX]); } int @@ -672,6 +690,12 @@ ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_GOST89MAC: i = SSL_MD_GOST89MAC_IDX; break; + case SSL_STREEBOG256: + i = SSL_MD_STREEBOG256_IDX; + break; + case SSL_STREEBOG512: + i = SSL_MD_STREEBOG512_IDX; + break; default: i = -1; break; @@ -829,7 +853,7 @@ ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, *auth |= SSL_aGOST01; } /* Disable GOST key exchange if no GOST signature algs are available. */ - if ((*auth & (SSL_aGOST94|SSL_aGOST01)) == (SSL_aGOST94|SSL_aGOST01)) { + if (((~*auth) & (SSL_aGOST94|SSL_aGOST01)) == 0) { *mkey |= SSL_kGOST; } #ifdef SSL_FORBID_ENULL @@ -853,7 +877,9 @@ ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256 : 0; *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384 : 0; *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94 : 0; - *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef) ? SSL_GOST89MAC : 0; + *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL) ? SSL_GOST89MAC : 0; + *mac |= (ssl_digest_methods[SSL_MD_STREEBOG256_IDX] == NULL) ? SSL_STREEBOG256 : 0; + *mac |= (ssl_digest_methods[SSL_MD_STREEBOG512_IDX] == NULL) ? SSL_STREEBOG512 : 0; } @@ -1581,6 +1607,9 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kECDHE: kx = "ECDH"; break; + case SSL_kGOST: + kx = "GOST"; + break; default: kx = "unknown"; } @@ -1601,6 +1630,12 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_aECDSA: au = "ECDSA"; break; + case SSL_aGOST94: + au = "GOST94"; + break; + case SSL_aGOST01: + au = "GOST01"; + break; default: au = "unknown"; break; @@ -1643,6 +1678,9 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_CHACHA20POLY1305: enc = "ChaCha20-Poly1305"; break; + case SSL_eGOST2814789CNT: + enc = "GOST-28178-89-CNT"; + break; default: enc = "unknown"; break; @@ -1664,6 +1702,18 @@ SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_AEAD: mac = "AEAD"; break; + case SSL_GOST94: + mac = "GOST94"; + break; + case SSL_GOST89MAC: + mac = "GOST89IMIT"; + break; + case SSL_STREEBOG256: + mac = "STREEBOG256"; + break; + case SSL_STREEBOG512: + mac = "STREEBOG512"; + break; default: mac = "unknown"; break; diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h index ec8f96e6455..74cacd4eec3 100644 --- a/lib/libssl/ssl_locl.h +++ b/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.76 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.77 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -299,6 +299,8 @@ #define SSL_SHA384 0x00000020L /* Not a real MAC, just an indication it is part of cipher */ #define SSL_AEAD 0x00000040L +#define SSL_STREEBOG256 0x00000080L +#define SSL_STREEBOG512 0x00000100L /* Bits for algorithm_ssl (protocol version) */ #define SSL_SSLV3 0x00000002L @@ -313,11 +315,13 @@ #define SSL_HANDSHAKE_MAC_GOST94 0x40 #define SSL_HANDSHAKE_MAC_SHA256 0x80 #define SSL_HANDSHAKE_MAC_SHA384 0x100 +#define SSL_HANDSHAKE_MAC_STREEBOG256 0x200 +#define SSL_HANDSHAKE_MAC_STREEBOG512 0x400 #define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) /* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX * make sure to update this constant too */ -#define SSL_MAX_DIGEST 6 +#define SSL_MAX_DIGEST 8 #define SSL3_CK_ID 0x03000000 #define SSL3_CK_VALUE_MASK 0x0000ffff @@ -330,6 +334,7 @@ #define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) #define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) #define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) +#define TLS1_PRF_STREEBOG256 (SSL_HANDSHAKE_MAC_STREEBOG256 << TLS1_PRF_DGST_SHIFT) #define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) /* Stream MAC for GOST ciphersuites from cryptopro draft diff --git a/lib/libssl/t1_enc.c b/lib/libssl/t1_enc.c index fc313efc2c7..620da6ddd0b 100644 --- a/lib/libssl/t1_enc.c +++ b/lib/libssl/t1_enc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t1_enc.c,v 1.72 2014/11/16 14:12:47 jsing Exp $ */ +/* $OpenBSD: t1_enc.c,v 1.73 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -448,6 +448,18 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, char use_client_keys, mac_secret_size, (unsigned char *)mac_secret); } + if (s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) { + int nid; + if (s->s3->tmp.new_cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94) + nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; + else + nid = NID_id_tc26_gost_28147_param_Z; + + EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GOST_SET_SBOX, nid, 0); + if (s->s3->tmp.new_cipher->algorithm_mac == SSL_GOST89MAC) + EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_GOST_SET_SBOX, nid, 0); + } + return (1); err: diff --git a/lib/libssl/t1_lib.c b/lib/libssl/t1_lib.c index b1b9ac4a87e..d593fe6bafa 100644 --- a/lib/libssl/t1_lib.c +++ b/lib/libssl/t1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t1_lib.c,v 1.66 2014/11/03 17:21:30 tedu Exp $ */ +/* $OpenBSD: t1_lib.c,v 1.67 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -587,6 +587,9 @@ static unsigned char tls12_sigalgs[] = { TLSEXT_hash_sha512, TLSEXT_signature_rsa, TLSEXT_hash_sha512, TLSEXT_signature_dsa, TLSEXT_hash_sha512, TLSEXT_signature_ecdsa, +#ifndef OPENSSL_NO_GOST + TLSEXT_hash_streebog_512, TLSEXT_signature_gostr12_512, +#endif TLSEXT_hash_sha384, TLSEXT_signature_rsa, TLSEXT_hash_sha384, TLSEXT_signature_dsa, @@ -596,6 +599,11 @@ static unsigned char tls12_sigalgs[] = { TLSEXT_hash_sha256, TLSEXT_signature_dsa, TLSEXT_hash_sha256, TLSEXT_signature_ecdsa, +#ifndef OPENSSL_NO_GOST + TLSEXT_hash_streebog_256, TLSEXT_signature_gostr12_256, + TLSEXT_hash_gost94, TLSEXT_signature_gostr01, +#endif + TLSEXT_hash_sha224, TLSEXT_signature_rsa, TLSEXT_hash_sha224, TLSEXT_signature_dsa, TLSEXT_hash_sha224, TLSEXT_signature_ecdsa, @@ -2166,13 +2174,17 @@ static tls12_lookup tls12_md[] = { {NID_sha224, TLSEXT_hash_sha224}, {NID_sha256, TLSEXT_hash_sha256}, {NID_sha384, TLSEXT_hash_sha384}, - {NID_sha512, TLSEXT_hash_sha512} + {NID_sha512, TLSEXT_hash_sha512}, + {NID_id_GostR3411_94, TLSEXT_hash_gost94}, + {NID_id_tc26_gost3411_2012_256, TLSEXT_hash_streebog_256}, + {NID_id_tc26_gost3411_2012_512, TLSEXT_hash_streebog_512} }; static tls12_lookup tls12_sig[] = { {EVP_PKEY_RSA, TLSEXT_signature_rsa}, {EVP_PKEY_DSA, TLSEXT_signature_dsa}, - {EVP_PKEY_EC, TLSEXT_signature_ecdsa} + {EVP_PKEY_EC, TLSEXT_signature_ecdsa}, + {EVP_PKEY_GOSTR01, TLSEXT_signature_gostr01}, }; static int @@ -2225,6 +2237,14 @@ tls12_get_hash(unsigned char hash_alg) return EVP_sha384(); case TLSEXT_hash_sha512: return EVP_sha512(); +#ifndef OPENSSL_NO_GOST + case TLSEXT_hash_gost94: + return EVP_gostr341194(); + case TLSEXT_hash_streebog_256: + return EVP_streebog256(); + case TLSEXT_hash_streebog_512: + return EVP_streebog512(); +#endif default: return NULL; } @@ -2251,6 +2271,8 @@ tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL; c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL; c->pkeys[SSL_PKEY_ECC].digest = NULL; + c->pkeys[SSL_PKEY_GOST94].digest = NULL; + c->pkeys[SSL_PKEY_GOST01].digest = NULL; for (i = 0; i < dsize; i += 2) { unsigned char hash_alg = data[i], sig_alg = data[i + 1]; @@ -2265,6 +2287,11 @@ tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) case TLSEXT_signature_ecdsa: idx = SSL_PKEY_ECC; break; + case TLSEXT_signature_gostr01: + case TLSEXT_signature_gostr12_256: + case TLSEXT_signature_gostr12_512: + idx = SSL_PKEY_GOST01; + break; default: continue; } @@ -2291,5 +2318,11 @@ tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) } if (!c->pkeys[SSL_PKEY_ECC].digest) c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +#ifndef OPENSSL_NO_GOST + if (!c->pkeys[SSL_PKEY_GOST94].digest) + c->pkeys[SSL_PKEY_GOST94].digest = EVP_gostr341194(); + if (!c->pkeys[SSL_PKEY_GOST01].digest) + c->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); +#endif return 1; } diff --git a/lib/libssl/tls1.h b/lib/libssl/tls1.h index d2d1657edfe..60dc7919a45 100644 --- a/lib/libssl/tls1.h +++ b/lib/libssl/tls1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls1.h,v 1.21 2014/10/31 15:50:28 jsing Exp $ */ +/* $OpenBSD: tls1.h,v 1.22 2014/11/18 05:33:43 miod Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -275,6 +275,10 @@ extern "C" { #define TLSEXT_signature_rsa 1 #define TLSEXT_signature_dsa 2 #define TLSEXT_signature_ecdsa 3 +/* FIXME IANA */ +#define TLSEXT_signature_gostr01 237 +#define TLSEXT_signature_gostr12_256 238 +#define TLSEXT_signature_gostr12_512 239 #define TLSEXT_hash_none 0 #define TLSEXT_hash_md5 1 @@ -283,6 +287,10 @@ extern "C" { #define TLSEXT_hash_sha256 4 #define TLSEXT_hash_sha384 5 #define TLSEXT_hash_sha512 6 +/* FIXME IANA */ +#define TLSEXT_hash_gost94 237 +#define TLSEXT_hash_streebog_256 238 +#define TLSEXT_hash_streebog_512 239 #define TLSEXT_MAXLEN_host_name 255 @@ -669,9 +677,11 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) #define TLS_CT_ECDSA_FIXED_ECDH 66 #define TLS_CT_GOST94_SIGN 21 #define TLS_CT_GOST01_SIGN 22 +#define TLS_CT_GOST12_256_SIGN 238 /* FIXME: IANA */ +#define TLS_CT_GOST12_512_SIGN 239 /* FIXME: IANA */ /* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see * comment there) */ -#define TLS_CT_NUMBER 9 +#define TLS_CT_NUMBER 11 #define TLS1_FINISH_MAC_LENGTH 12 |