Skip to content

Commit

Permalink
Patch containing TLS implementation for GOST 2012
Browse files Browse the repository at this point in the history
This patch contains the necessary changes to provide GOST 2012
ciphersuites in TLS. It requires the use of an external GOST 2012 engine.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
  • Loading branch information
beldmit authored and mattcaswell committed Nov 23, 2015
1 parent 76eba0d commit e44380a
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 84 deletions.
2 changes: 2 additions & 0 deletions crypto/x509/x509type.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
ret = EVP_PK_DH | EVP_PKT_EXCH;
break;
case NID_id_GostR3410_2001:
case NID_id_GostR3410_2012_256:
case NID_id_GostR3410_2012_512:
ret = EVP_PKT_EXCH | EVP_PKT_SIGN;
break;
default:
Expand Down
13 changes: 9 additions & 4 deletions include/openssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,10 @@ extern "C" {
# define SSL_TXT_aECDH "aECDH"
# define SSL_TXT_aECDSA "aECDSA"
# define SSL_TXT_aPSK "aPSK"
# define SSL_TXT_aGOST94 "aGOST94"
# define SSL_TXT_aGOST01 "aGOST01"
# define SSL_TXT_aGOST "aGOST"
# define SSL_TXT_aGOST94 "aGOST94"
# define SSL_TXT_aGOST01 "aGOST01"
# define SSL_TXT_aGOST12 "aGOST12"
# define SSL_TXT_aGOST "aGOST"
# define SSL_TXT_aSRP "aSRP"

# define SSL_TXT_DSS "DSS"
Expand Down Expand Up @@ -250,12 +251,15 @@ extern "C" {
# define SSL_TXT_CAMELLIA128 "CAMELLIA128"
# define SSL_TXT_CAMELLIA256 "CAMELLIA256"
# define SSL_TXT_CAMELLIA "CAMELLIA"
# define SSL_TXT_GOST "GOST89"

# define SSL_TXT_MD5 "MD5"
# define SSL_TXT_SHA1 "SHA1"
# define SSL_TXT_SHA "SHA"/* same as "SHA1" */
# define SSL_TXT_GOST94 "GOST94"
# define SSL_TXT_GOST89MAC "GOST89MAC"
# define SSL_TXT_GOST89MAC "GOST89MAC"
# define SSL_TXT_GOST12 "GOST12"
# define SSL_TXT_GOST89MAC12 "GOST89MAC12"
# define SSL_TXT_SHA256 "SHA256"
# define SSL_TXT_SHA384 "SHA384"

Expand Down Expand Up @@ -2208,6 +2212,7 @@ void ERR_load_SSL_strings(void);
# define SSL_R_BAD_ECC_CERT 304
# define SSL_R_BAD_ECDSA_SIGNATURE 305
# define SSL_R_BAD_ECPOINT 306
# define SSL_R_BAD_GOST_SIGNATURE 406
# define SSL_R_BAD_HANDSHAKE_LENGTH 332
# define SSL_R_BAD_HELLO_REQUEST 105
# define SSL_R_BAD_LENGTH 271
Expand Down
13 changes: 11 additions & 2 deletions include/openssl/tls1.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,12 @@ extern "C" {
# define TLSEXT_signature_rsa 1
# define TLSEXT_signature_dsa 2
# define TLSEXT_signature_ecdsa 3
# define TLSEXT_signature_gostr34102001 237
# define TLSEXT_signature_gostr34102012_256 238
# define TLSEXT_signature_gostr34102012_512 239

/* Total number of different signature algorithms */
# define TLSEXT_signature_num 4
# define TLSEXT_signature_num 7

# define TLSEXT_hash_none 0
# define TLSEXT_hash_md5 1
Expand All @@ -291,10 +294,13 @@ extern "C" {
# define TLSEXT_hash_sha256 4
# define TLSEXT_hash_sha384 5
# define TLSEXT_hash_sha512 6
# define TLSEXT_hash_gostr3411 237
# define TLSEXT_hash_gostr34112012_256 238
# define TLSEXT_hash_gostr34112012_512 239

/* Total number of different digest algorithms */

# define TLSEXT_hash_num 7
# define TLSEXT_hash_num 10

/* Flag set for unrecognised algorithms */
# define TLSEXT_nid_unknown 0x1000000
Expand Down Expand Up @@ -920,6 +926,9 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
# 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

/*
* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
* comment there)
Expand Down
30 changes: 30 additions & 0 deletions ssl/s3_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -3770,6 +3770,34 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
256,
},

{
1,
"GOST2012-GOST8912-GOST8912",
0x0300ff85,
SSL_kGOST,
SSL_aGOST12 | SSL_aGOST01,
SSL_eGOST2814789CNT12,
SSL_GOST89MAC12,
SSL_TLSV1,
SSL_NOT_EXP | SSL_HIGH,
SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_STREAM_MAC,
256,
256},
{
1,
"GOST2012-NULL-GOST12",
0x0300ff87,
SSL_kGOST,
SSL_aGOST12 | SSL_aGOST01,
SSL_eNULL,
SSL_GOST12_256,
SSL_TLSV1,
SSL_NOT_EXP | SSL_STRONG_NONE,
SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256,
0,
0},


/* end of list */
};

Expand Down Expand Up @@ -4936,6 +4964,8 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
if (s->version >= TLS1_VERSION) {
if (alg_k & SSL_kGOST) {
p[ret++] = TLS_CT_GOST01_SIGN;
p[ret++] = TLS_CT_GOST12_SIGN;
p[ret++] = TLS_CT_GOST12_512_SIGN;
return (ret);
}
}
Expand Down
65 changes: 54 additions & 11 deletions ssl/ssl_ciph.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@
#define SSL_ENC_AES256CCM_IDX 15
#define SSL_ENC_AES128CCM8_IDX 16
#define SSL_ENC_AES256CCM8_IDX 17
#define SSL_ENC_NUM_IDX 18
#define SSL_ENC_GOST8912_IDX 18
#define SSL_ENC_NUM_IDX 19

/* NB: make sure indices in these tables match values above */

Expand Down Expand Up @@ -196,7 +197,8 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = {
{SSL_AES128CCM, NID_aes_128_ccm}, /* SSL_ENC_AES128CCM_IDX 14 */
{SSL_AES256CCM, NID_aes_256_ccm}, /* SSL_ENC_AES256CCM_IDX 15 */
{SSL_AES128CCM8, NID_aes_128_ccm}, /* SSL_ENC_AES128CCM8_IDX 16 */
{SSL_AES256CCM8, NID_aes_256_ccm} /* SSL_ENC_AES256CCM8_IDX 17 */
{SSL_AES256CCM8, NID_aes_256_ccm}, /* SSL_ENC_AES256CCM8_IDX 17 */
{SSL_eGOST2814789CNT12, NID_gost89_cnt_12}, /* SSL_ENC_GOST8912_IDX */
};

static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = {
Expand All @@ -216,6 +218,9 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
#define SSL_MD_GOST89MAC_IDX 3
#define SSL_MD_SHA256_IDX 4
#define SSL_MD_SHA384_IDX 5
#define SSL_MD_GOST12_256_IDX 6
#define SSL_MD_GOST89MAC12_IDX 7
#define SSL_MD_GOST12_512_IDX 8
/*
* Constant SSL_MAX_DIGEST equal to size of digests array should be defined
* in the ssl_locl.h
Expand All @@ -230,11 +235,14 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
{SSL_GOST94, NID_id_GostR3411_94}, /* SSL_MD_GOST94_IDX 2 */
{SSL_GOST89MAC, NID_id_Gost28147_89_MAC}, /* SSL_MD_GOST89MAC_IDX 3 */
{SSL_SHA256, NID_sha256}, /* SSL_MD_SHA256_IDX 4 */
{SSL_SHA384, NID_sha384} /* SSL_MD_SHA384_IDX 5 */
{SSL_SHA384, NID_sha384}, /* SSL_MD_SHA384_IDX 5 */
{SSL_GOST12_256, NID_id_GostR3411_2012_256}, /* SSL_MD_GOST12_256_IDX 6 */
{SSL_GOST89MAC12, NID_gost_mac_12}, /* SSL_MD_GOST89MAC12_IDX 7 */
{SSL_GOST12_512, NID_id_GostR3411_2012_512} /* SSL_MD_GOST12_512_IDX 8 */
};

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
};

/* Utility function for table lookup */
Expand All @@ -258,18 +266,23 @@ static int ssl_cipher_info_find(const ssl_cipher_table * table,
* found
*/
static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = {
/* MD5, SHA, GOST94, MAC89 */
EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef,
EVP_PKEY_HMAC, EVP_PKEY_HMAC
/* SHA256, SHA384, GOST2012_256, MAC89-12 */
EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef,
/* GOST2012_512 */
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, 0
};

static const 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_GOST12_256, 0,
SSL_HANDSHAKE_MAC_GOST12_512,
};

#define CIPHER_ADD 1
Expand Down Expand Up @@ -339,7 +352,9 @@ static const SSL_CIPHER cipher_aliases[] = {
{0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_aPSK, 0, 0, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_aGOST01, 0, 0, SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_aGOST, 0, 0, SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_aGOST12, 0, 0, SSL_aGOST12, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_aGOST, 0, 0, SSL_aGOST01 | SSL_aGOST12, 0, 0, 0,
0, 0, 0, 0},
{0, SSL_TXT_aSRP, 0, 0, SSL_aSRP, 0, 0, 0, 0, 0, 0, 0},

/* aliases combining key exchange and server authentication */
Expand All @@ -362,6 +377,8 @@ static const SSL_CIPHER cipher_aliases[] = {
{0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_GOST, 0, 0, 0, SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12, 0,
0, 0, 0, 0, 0},
{0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8, 0,
0, 0, 0, 0, 0},
{0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM | SSL_AES256CCM | SSL_AES256CCM8, 0,
Expand All @@ -383,9 +400,11 @@ static const SSL_CIPHER cipher_aliases[] = {
{0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0},
{0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0},
{0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94, 0, 0, 0, 0, 0},
{0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC, 0, 0, 0, 0, 0},
{0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC | SSL_GOST89MAC12, 0, 0,
0, 0, 0},
{0, SSL_TXT_SHA256, 0, 0, 0, 0, SSL_SHA256, 0, 0, 0, 0, 0},
{0, SSL_TXT_SHA384, 0, 0, 0, 0, SSL_SHA384, 0, 0, 0, 0, 0},
{0, SSL_TXT_GOST12, 0, 0, 0, 0, SSL_GOST12_256, 0, 0, 0, 0, 0},

/* protocol version aliases */
{0, SSL_TXT_SSLV3, 0, 0, 0, 0, 0, SSL_SSLV3, 0, 0, 0, 0},
Expand Down Expand Up @@ -542,12 +561,23 @@ void ssl_load_ciphers(void)
disabled_mac_mask |= SSL_GOST89MAC;
}

ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] = get_optional_pkey_id("gost-mac-12");
if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX]) {
ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
} else {
disabled_mac_mask |= SSL_GOST89MAC12;
}

if (!get_optional_pkey_id("gost2001"))
disabled_auth_mask |= SSL_aGOST01;
disabled_auth_mask |= SSL_aGOST01 | SSL_aGOST12;
if (!get_optional_pkey_id("gost2012_256"))
disabled_auth_mask |= SSL_aGOST12;
if (!get_optional_pkey_id("gost2012_512"))
disabled_auth_mask |= SSL_aGOST12;
/*
* Disable GOST key exchange if no GOST signature algs are available *
*/
if ((disabled_auth_mask & SSL_aGOST01) == SSL_aGOST01)
if ((disabled_auth_mask & (SSL_aGOST01 | SSL_aGOST12)) == (SSL_aGOST01 | SSL_aGOST12))
disabled_mkey_mask |= SSL_kGOST;
}

Expand Down Expand Up @@ -1704,6 +1734,10 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
case SSL_aGOST01:
au = "GOST01";
break;
/* New GOST ciphersuites have both SSL_aGOST12 and SSL_aGOST01 bits */
case (SSL_aGOST12 | SSL_aGOST01):
au = "GOST12";
break;
default:
au = "unknown";
break;
Expand Down Expand Up @@ -1762,6 +1796,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
enc = "SEED(128)";
break;
case SSL_eGOST2814789CNT:
case SSL_eGOST2814789CNT12:
enc = "GOST89(256)";
break;
default:
Expand All @@ -1786,11 +1821,16 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
mac = "AEAD";
break;
case SSL_GOST89MAC:
case SSL_GOST89MAC12:
mac = "GOST89";
break;
case SSL_GOST94:
mac = "GOST94";
break;
case SSL_GOST12_256:
case SSL_GOST12_512:
mac = "GOST2012";
break;
default:
mac = "unknown";
break;
Expand Down Expand Up @@ -1998,8 +2038,11 @@ int ssl_cipher_get_cert_index(const SSL_CIPHER *c)
return SSL_PKEY_DSA_SIGN;
else if (alg_a & SSL_aRSA)
return SSL_PKEY_RSA_ENC;
else if (alg_a & SSL_aGOST12)
return SSL_PKEY_GOST_EC;
else if (alg_a & SSL_aGOST01)
return SSL_PKEY_GOST01;

return -1;
}

Expand Down
20 changes: 20 additions & 0 deletions ssl/ssl_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2069,6 +2069,16 @@ void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
rsa_enc_export, rsa_sign, dsa_sign, dh_rsa, dh_dsa);
#endif

cpk = &(c->pkeys[SSL_PKEY_GOST12_512]);
if (cpk->x509 != NULL && cpk->privatekey != NULL) {
mask_k |= SSL_kGOST;
mask_a |= SSL_aGOST12;
}
cpk = &(c->pkeys[SSL_PKEY_GOST12_256]);
if (cpk->x509 != NULL && cpk->privatekey != NULL) {
mask_k |= SSL_kGOST;
mask_a |= SSL_aGOST12;
}
cpk = &(c->pkeys[SSL_PKEY_GOST01]);
if (cpk->x509 != NULL && cpk->privatekey != NULL) {
mask_k |= SSL_kGOST;
Expand Down Expand Up @@ -2255,6 +2265,16 @@ static int ssl_get_server_cert_index(const SSL *s)
idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509)
idx = SSL_PKEY_RSA_SIGN;
if (idx == SSL_PKEY_GOST_EC) {
if (s->cert->pkeys[SSL_PKEY_GOST12_512].x509)
idx = SSL_PKEY_GOST12_512;
else if (s->cert->pkeys[SSL_PKEY_GOST12_256].x509)
idx = SSL_PKEY_GOST12_256;
else if (s->cert->pkeys[SSL_PKEY_GOST01].x509)
idx = SSL_PKEY_GOST01;
else
idx = -1;
}
if (idx == -1)
SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR);
return idx;
Expand Down
Loading

0 comments on commit e44380a

Please sign in to comment.