From 9981a51e426b5b346848163ff89e8a63d0916097 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 23 Mar 2007 17:04:05 +0000 Subject: [PATCH] Stage 1 GOST ciphersuite support. Submitted by: ran@cryptocom.ru Reviewed by: steve@openssl.org --- apps/ciphers.c | 2 ++ crypto/objects/obj_dat.h | 9 ++++++--- crypto/objects/obj_mac.h | 3 +++ crypto/objects/obj_mac.num | 1 + crypto/objects/objects.txt | 1 + engines/ccgost/gost_crypt.c | 35 +++++++++++++++-------------------- engines/ccgost/gost_eng.c | 11 ++++++++--- engines/ccgost/gost_lcl.h | 1 + ssl/s3_lib.c | 18 ++++++++++++++++++ ssl/ssl_ciph.c | 11 +++++++++-- ssl/ssl_locl.h | 1 + 11 files changed, 65 insertions(+), 28 deletions(-) diff --git a/apps/ciphers.c b/apps/ciphers.c index be3fc18e0e..3d4c60db9e 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c @@ -115,6 +115,8 @@ int MAIN(int argc, char **argv) STDout = BIO_push(tmpbio, STDout); } #endif + if (!load_config(bio_err, NULL)) + goto end; argc--; argv++; diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 9c6bad7891..8dad99c0dc 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -62,9 +62,9 @@ * [including the GNU Public Licence.] */ -#define NUM_NID 835 -#define NUM_SN 831 -#define NUM_LN 831 +#define NUM_NID 836 +#define NUM_SN 832 +#define NUM_LN 832 #define NUM_OBJ 787 static unsigned char lvalues[5560]={ @@ -2208,6 +2208,7 @@ static ASN1_OBJECT nid_objs[NUM_NID]={ &(lvalues[5541]),0}, {"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9, &(lvalues[5550]),0}, +{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0}, }; static ASN1_OBJECT *sn_objs[NUM_SN]={ @@ -2483,6 +2484,7 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={ &(nid_objs[784]),/* "gost2001" */ &(nid_objs[823]),/* "gost2001cc" */ &(nid_objs[786]),/* "gost89" */ +&(nid_objs[835]),/* "gost89-cnt" */ &(nid_objs[785]),/* "gost94" */ &(nid_objs[822]),/* "gost94cc" */ &(nid_objs[772]),/* "hmacWithMD5" */ @@ -3333,6 +3335,7 @@ static ASN1_OBJECT *ln_objs[NUM_LN]={ &(nid_objs[509]),/* "generationQualifier" */ &(nid_objs[601]),/* "generic cryptogram" */ &(nid_objs[99]),/* "givenName" */ +&(nid_objs[835]),/* "gost89-cnt" */ &(nid_objs[772]),/* "hmacWithMD5" */ &(nid_objs[163]),/* "hmacWithSHA1" */ &(nid_objs[773]),/* "hmacWithSHA224" */ diff --git a/crypto/objects/obj_mac.h b/crypto/objects/obj_mac.h index db846f49c0..131199a633 100644 --- a/crypto/objects/obj_mac.h +++ b/crypto/objects/obj_mac.h @@ -3419,6 +3419,9 @@ #define NID_id_Gost28147_89 786 #define OBJ_id_Gost28147_89 OBJ_cryptopro,21L +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 835 + #define SN_id_Gost28147_89_MAC "id-Gost28147-89-MAC" #define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" #define NID_id_Gost28147_89_MAC 787 diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 1a200207ff..b9d34d26d5 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -832,3 +832,4 @@ ecdsa_with_SHA384 831 ecdsa_with_SHA512 832 dsa_with_SHA224 833 dsa_with_SHA256 834 +gost89_cnt 835 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index e2a6c24c4c..1f48abfc24 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1091,6 +1091,7 @@ cryptopro 19 : gost2001 : GOST R 34.10-2001 cryptopro 20 : gost94 : GOST R 34.10-94 !Cname id-Gost28147-89 cryptopro 21 : gost89 : GOST 28147-89 + : gost89-cnt cryptopro 22 : id-Gost28147-89-MAC : GOST 28147-89 MAC !Cname id-GostR3411-94-prf cryptopro 23 : prf-gostr3411-94 : GOST R 34.11-94 PRF diff --git a/engines/ccgost/gost_crypt.c b/engines/ccgost/gost_crypt.c index fca7b2d9d5..04b1e555c2 100644 --- a/engines/ccgost/gost_crypt.c +++ b/engines/ccgost/gost_crypt.c @@ -13,21 +13,19 @@ #include "gost_lcl.h" static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); +static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); #ifdef USE_SSL /* Specialized init functions which set specific parameters */ static int gost_cipher_init_vizir(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); -static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); #endif /* Handles block of data in CFB mode */ static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl); -#if 0 /* Handles block of data in CNT mode */ static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl); -#endif /* Cleanup function */ static int gost_cipher_cleanup(EVP_CIPHER_CTX *); /* set/get cipher parameters */ @@ -54,17 +52,16 @@ EVP_CIPHER cipher_gost = NULL, }; -#ifdef USE_SSL -static EVP_CIPHER cipher_gost_vizircfb = +EVP_CIPHER cipher_gost_cpacnt = { - NID_undef, + NID_gost89_cnt, 1,/*block_size*/ 32,/*key_size*/ 8,/*iv_len - ñèíõðîïîñûëêà*/ - EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING | + EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING | EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, - gost_cipher_init_vizir, - gost_cipher_do_cfb, + gost_cipher_init_cpa, + gost_cipher_do_cnt, gost_cipher_cleanup, sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ gost89_set_asn1_parameters, @@ -73,16 +70,17 @@ static EVP_CIPHER cipher_gost_vizircfb = NULL, }; -static EVP_CIPHER cipher_gost_cpacnt = +#ifdef USE_SSL +static EVP_CIPHER cipher_gost_vizircfb = { NID_undef, 1,/*block_size*/ 32,/*key_size*/ 8,/*iv_len - ñèíõðîïîñûëêà*/ - EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING | + EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING | EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, - gost_cipher_init_cpa, - gost_cipher_do_cnt, + gost_cipher_init_vizir, + gost_cipher_do_cfb, gost_cipher_cleanup, sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ gost89_set_asn1_parameters, @@ -90,6 +88,7 @@ static EVP_CIPHER cipher_gost_cpacnt = gost_cipher_ctl, NULL, }; + /* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */ /* Init functions which set specific parameters */ static int gost_imit_init_vizir(EVP_MD_CTX *ctx); @@ -227,8 +226,6 @@ static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; } -#ifdef USE_SSL -/* Initializes EVP_CIPHER_CTX with fixed cryptopro A paramset */ static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { @@ -241,6 +238,8 @@ static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); return 1; } +#ifdef USE_SSL +/* Initializes EVP_CIPHER_CTX with fixed cryptopro A paramset */ /* Initializes EVP_CIPHER_CTX with fixed vizir paramset */ static int gost_cipher_init_vizir(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -278,7 +277,6 @@ static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf) c->count+=8; } -#ifdef USE_SSL static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) { struct ossl_gost_cipher_ctx *c = ctx; @@ -309,7 +307,6 @@ static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) gostcrypt(&(c->cctx),buf1,buf); c->count +=8; } -#endif /* def USE_SSL */ /* GOST encryption in CFB mode */ int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, @@ -374,7 +371,6 @@ int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, return 1; } -#if USE_SSL static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { @@ -428,7 +424,6 @@ static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, } return 1; } -#endif /* def USE_SSL */ /* Cleaning up of EVP_CIPHER_CTX */ int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) diff --git a/engines/ccgost/gost_eng.c b/engines/ccgost/gost_eng.c index 0c47253e2a..1c5a493df6 100644 --- a/engines/ccgost/gost_eng.c +++ b/engines/ccgost/gost_eng.c @@ -31,7 +31,7 @@ static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, const int **nids, int nid); static int gost_cipher_nids[] = - {NID_id_Gost28147_89, 0}; + {NID_id_Gost28147_89, NID_gost89_cnt,0}; static int gost_digest_nids[] = {NID_id_GostR3411_94, 0}; @@ -129,6 +129,7 @@ static int bind_gost (ENGINE *e,const char *id) || ! ENGINE_register_pkey_meths(e) /* These two actually should go in LIST_ADD command */ || ! EVP_add_cipher(&cipher_gost) + || ! EVP_add_cipher(&cipher_gost_cpacnt) || ! EVP_add_digest(&digest_gost) ) { @@ -175,14 +176,18 @@ static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher, if (!cipher) { *nids = gost_cipher_nids; - return 1; /* Only one cipher supported */ + return 2; /* two ciphers are supported */ } if(nid == NID_id_Gost28147_89) { *cipher = &cipher_gost; } - else + else if (nid == NID_gost89_cnt) + { + *cipher = &cipher_gost_cpacnt; + } + else { ok = 0; *cipher = NULL; diff --git a/engines/ccgost/gost_lcl.h b/engines/ccgost/gost_lcl.h index b40b88463c..5904eeb834 100644 --- a/engines/ccgost/gost_lcl.h +++ b/engines/ccgost/gost_lcl.h @@ -135,6 +135,7 @@ extern struct gost_cipher_info gost_cipher_list[]; const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj); /* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ extern EVP_CIPHER cipher_gost; +extern EVP_CIPHER cipher_gost_cpacnt; #ifdef USE_SSL #define EVP_MD_FLAG_NEEDS_KEY 0x20 #define EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH (EVP_MD_CTRL_ALG_CTRL+1) diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 759a9e4e12..6e4ce00caf 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -1855,6 +1855,24 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ }, #endif /* OPENSSL_NO_ECDH */ +#ifdef TEMP_GOST_TLS +/* Cipher FF00 */ + { + 1, + "GOST-MD5", + 0x0300ff00, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + 0, + 256, + 256, + }, +#endif + /* end of list */ }; diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 9b5a2648f6..aa7893b346 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -155,11 +155,12 @@ #define SSL_ENC_AES256_IDX 7 #define SSL_ENC_CAMELLIA128_IDX 8 #define SSL_ENC_CAMELLIA256_IDX 9 -#define SSL_ENC_NUM_IDX 10 +#define SSL_ENC_GOST89_IDX 10 +#define SSL_ENC_NUM_IDX 11 static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ - NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, }; #define SSL_COMP_NULL_IDX 0 @@ -305,6 +306,8 @@ void ssl_load_ciphers(void) EVP_get_cipherbyname(SN_camellia_128_cbc); ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX]= EVP_get_cipherbyname(SN_camellia_256_cbc); + ssl_cipher_methods[SSL_ENC_GOST89_IDX]= + EVP_get_cipherbyname(SN_gost89_cnt); ssl_digest_methods[SSL_MD_MD5_IDX]= EVP_get_digestbyname(SN_md5); @@ -427,6 +430,9 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_CAMELLIA256: i=SSL_ENC_CAMELLIA256_IDX; break; + case SSL_eGOST2814789CNT: + i=SSL_ENC_GOST89_IDX; + break; default: i= -1; break; @@ -549,6 +555,7 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0; *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0; *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0; + *enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0; *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index d4d773a0b1..6dbcef3de1 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -310,6 +310,7 @@ #define SSL_AES256 0x00000080L #define SSL_CAMELLIA128 0x00000100L #define SSL_CAMELLIA256 0x00000200L +#define SSL_eGOST2814789CNT 0x00000400L #define SSL_AES (SSL_AES128|SSL_AES256) #define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) -- 2.34.1