]> www.wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
Merge remote-tracking branch 'origin/openssl_1_1_0'
authorDmitry Belyavskiy <beldmit@gmail.com>
Sat, 19 Nov 2016 19:04:55 +0000 (22:04 +0300)
committerDmitry Belyavskiy <beldmit@gmail.com>
Sat, 19 Nov 2016 19:04:55 +0000 (22:04 +0300)
Conflicts:
gost_asn1.c
gost_crypt.c

1  2 
gost_ameth.c
gost_asn1.c
gost_crypt.c
gost_eng.c
gost_pmeth.c

diff --combined gost_ameth.c
index 2243a30a3cbd46f90f18bd1c1cf8cbf65bcfbcc9,8c2645061fa3fd6b195600447314305297265204..8e7d8d58a83c8849254357687d2025a43f068c3b
@@@ -23,7 -23,7 +23,7 @@@
   * Pack bignum into byte buffer of given size, filling all leading bytes by
   * zeros
   */
- int store_bignum(BIGNUM *bn, unsigned char *buf, int len)
+ int store_bignum(const BIGNUM *bn, unsigned char *buf, int len)
  {
      int bytes = BN_num_bytes(bn);
  
      return 1;
  }
  
- /* Convert byte buffer to bignum, skipping leading zeros*/
- BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len)
- {
-     BIGNUM *b;
-     while (*buf == 0 && len > 0) {
-         buf++;
-         len--;
-     }
-     if (len)
-         return BN_bin2bn(buf, len, NULL);
-     b = BN_new();
-     BN_zero(b);
-     return b;
- }
  static int pkey_bits_gost(const EVP_PKEY *pk)
  {
      if (!pk)
@@@ -145,9 -129,9 +129,9 @@@ static int gost_decode_nid_params(EVP_P
   * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting
   * NID and parameters
   */
- static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
+ static int decode_gost_algor_params(EVP_PKEY *pkey, const X509_ALGOR *palg)
  {
-     ASN1_OBJECT *palg_obj = NULL;
+     const ASN1_OBJECT *palg_obj = NULL;
      int ptype = V_ASN1_UNDEF;
      int pkey_nid = NID_undef, param_nid = NID_undef;
      ASN1_STRING *pval = NULL;
  
      if (!pkey || !palg)
          return 0;
-     X509_ALGOR_get0(&palg_obj, &ptype, (void **)&pval, palg);
+     X509_ALGOR_get0(&palg_obj, &ptype, (const void **)&pval, palg);
      if (ptype != V_ASN1_SEQUENCE) {
          GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
                  GOST_R_BAD_KEY_PARAMETERS_FORMAT);
@@@ -269,7 -253,7 +253,7 @@@ static int pkey_ctrl_gost(EVP_PKEY *pke
                  return -1;
              }
              PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg1);
-             X509_ALGOR_set0(alg1, OBJ_nid2obj(pkey->type),
+             X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_id(pkey)),
                              V_ASN1_SEQUENCE, params);
          }
          return 1;
              }
              CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL,
                                               NULL, &alg1);
-             X509_ALGOR_set0(alg1, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE,
-                             params);
+             X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_id(pkey)),
+                             V_ASN1_SEQUENCE, params);
          }
          return 1;
  #endif
  /* --------------------- free functions * ------------------------------*/
  static void pkey_free_gost_ec(EVP_PKEY *key)
  {
-     EC_KEY_free(key->pkey.ec);
+     EC_KEY_free(EVP_PKEY_get0_EC_KEY(key));
  }
  
  /* ------------------ private key functions  -----------------------------*/
@@@ -345,14 -329,14 +329,14 @@@ static BIGNUM *unmask_priv_key(EVP_PKE
      return pknum_masked;
  }
  
- static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
+ static int priv_decode_gost(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf)
  {
      const unsigned char *pkey_buf = NULL, *p = NULL;
      int priv_len = 0;
      BIGNUM *pk_num = NULL;
      int ret = 0;
-     X509_ALGOR *palg = NULL;
-     ASN1_OBJECT *palg_obj = NULL;
+     const X509_ALGOR *palg = NULL;
+     const ASN1_OBJECT *palg_obj = NULL;
      ASN1_INTEGER *priv_key = NULL;
      int expected_key_len = 32;
  
@@@ -431,10 -415,10 +415,10 @@@ static int priv_encode_gost(PKCS8_PRIV_
  {
      ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
      ASN1_STRING *params = encode_gost_algor_params(pk);
 -    unsigned char *priv_buf = NULL, *buf = NULL;
 -    int key_len = pkey_bits_gost(pk), priv_len = 0, i = 0;
 +    unsigned char /**priv_buf = NULL,*/ *buf = NULL;
 +    int key_len = pkey_bits_gost(pk), /*priv_len = 0,*/ i = 0;
  
 -    ASN1_STRING *octet = NULL;
 +    /*ASN1_STRING *octet = NULL;*/
      if (!params) {
          return 0;
      }
          buf[key_len - 1 - i] = tmp;
      }
  
 +/*
      octet = ASN1_STRING_new();
      ASN1_OCTET_STRING_set(octet, buf, key_len);
  
      OPENSSL_free(buf);
  
      return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params,
 -                           priv_buf, priv_len);
 +                           priv_buf, priv_len); */
 +    return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params,
 +                           buf, key_len); 
  }
  
  /* --------- printing keys --------------------------------*/
@@@ -687,8 -668,8 +671,8 @@@ static int pub_decode_gost_ec(EVP_PKEY 
      len = octet->length / 2;
      ASN1_OCTET_STRING_free(octet);
  
-     Y = getbnfrombuf(databuf, len);
-     X = getbnfrombuf(databuf + len, len);
+     Y = BN_bin2bn(databuf, len, NULL);
+     X = BN_bin2bn(databuf + len, len, NULL);
      OPENSSL_free(databuf);
      pub_key = EC_POINT_new(group);
      if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) {
@@@ -723,7 -704,7 +707,7 @@@ static int pub_encode_gost_ec(X509_PUBK
      int ptype = V_ASN1_UNDEF;
  
      algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
-     if (pk->save_parameters) {
+     if (EVP_PKEY_save_parameters((EVP_PKEY *)pk, -1)) {
          ASN1_STRING *params = encode_gost_algor_params(pk);
          pval = params;
          ptype = V_ASN1_SEQUENCE;
      store_bignum(X, databuf + data_len / 2, data_len / 2);
      store_bignum(Y, databuf, data_len / 2);
  
+               BUF_reverse(NULL, databuf, data_len);
      octet = ASN1_OCTET_STRING_new();
      if (octet == NULL) {
          GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
          goto err;
      }
-     ASN1_STRING_set(octet, NULL, data_len);
-     sptr = ASN1_STRING_data(octet);
-     for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
-         sptr[i] = databuf[j];
+     if (0 == ASN1_STRING_set(octet, databuf, data_len)) {
+         GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE);
+         goto err;
      }
  
      ret = i2d_ASN1_OCTET_STRING(octet, &buf);
@@@ -823,7 -806,7 +809,7 @@@ static int pkey_size_gost(const EVP_PKE
  /* ---------------------- ASN1 METHOD for GOST MAC  -------------------*/
  static void mackey_free_gost(EVP_PKEY *pk)
  {
-     OPENSSL_free(pk->pkey.ptr);
+     OPENSSL_free(EVP_PKEY_get0(pk));
  }
  
  static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
@@@ -896,6 -879,9 +882,9 @@@ int register_ameth_gost(int nid, EVP_PK
                                   pkey_size_gost, pkey_bits_gost);
  
          EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
+         EVP_PKEY_asn1_set_security_bits(*ameth, pkey_bits_gost);
+ #endif
          break;
      case NID_id_GostR3410_2012_256:
      case NID_id_GostR3410_2012_512:
diff --combined gost_asn1.c
index bcfe73fa84cc344434b3f36f7501d4c7fab4599f,3a106c2fc675409e7d5939a34ca30d956e4b2a24..0a1c05a8afd0dd11fdf073d458e43d8c3bba66aa
  
  ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = {
      ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
 -        ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info,
 -                 GOST_KEY_AGREEMENT_INFO, 0)
 +    ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info,
 +             GOST_KEY_AGREEMENT_INFO, 0)
  }
 -
  ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT)
 +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
  
 -    IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
 -
 -    ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) =
 +ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) =
  {
      ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING),
-     ASN1_SIMPLE(GOST_KEY_INFO, imit, ASN1_OCTET_STRING)
- }
- ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO)
+         ASN1_SIMPLE(GOST_KEY_INFO, imit, ASN1_OCTET_STRING)
+ } ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO)
  IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO)
  ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) =
  {
      ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT),
-     ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0),
-     ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING)
- }
- ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO)
+         ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0),
+         ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING)
+ } ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO)
  IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
  ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) =
  {
-     ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT),
-     ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT),
-     ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT),
- }
- ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS)
+ ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT),
+         ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT),
+         ASN1_OPT(GOST_KEY_PARAMS, cipher_params,
+                      ASN1_OBJECT),} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS)
  IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS)
  ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) =
  {
 -ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING),
 -        ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set,
 -                        ASN1_OBJECT),}
 +    ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING),
 +    ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT),
 +}
  ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS)
  IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
  ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) =
  {                               /* FIXME incomplete */
      ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)
 -} ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
 -
 -    IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
 +}
 +ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
 +IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
  
 -    ASN1_NDEF_SEQUENCE(MASKED_GOST_KEY) =
 +ASN1_NDEF_SEQUENCE(MASKED_GOST_KEY) =
  {
      ASN1_SIMPLE(MASKED_GOST_KEY, masked_priv_key, ASN1_OCTET_STRING),
-     ASN1_SIMPLE(MASKED_GOST_KEY, public_key, ASN1_OCTET_STRING)
- }
- ASN1_NDEF_SEQUENCE_END(MASKED_GOST_KEY)
+         ASN1_SIMPLE(MASKED_GOST_KEY, public_key, ASN1_OCTET_STRING)
+ } ASN1_NDEF_SEQUENCE_END(MASKED_GOST_KEY)
  IMPLEMENT_ASN1_FUNCTIONS(MASKED_GOST_KEY)
diff --combined gost_crypt.c
index 59d75d788a5493fb1c9d2c6d624f8085d2691a0b,f9ed2cf22b0c8125252ef354b653e096476b0251..a15317127f94acab9b852fcc927b5642876ebba3
@@@ -46,73 -46,158 +46,158 @@@ static int gost89_get_asn1_parameters(E
  /* Control function */
  static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
  
- EVP_CIPHER cipher_gost = {
-     NID_id_Gost28147_89,
-     1,                          /* block_size */
-     32,                         /* key_size */
-     8,                          /* iv_len */
-     EVP_CIPH_CFB_MODE | EVP_CIPH_NO_PADDING |
-         EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
-     gost_cipher_init,
-     gost_cipher_do_cfb,
-     gost_cipher_cleanup,
-     sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
-     gost89_set_asn1_parameters,
-     gost89_get_asn1_parameters,
-     gost_cipher_ctl,
-     NULL,
- };
+ static EVP_CIPHER *_hidden_Gost28147_89_cipher = NULL;
+ const EVP_CIPHER *cipher_gost(void)
+ {
+     if (_hidden_Gost28147_89_cipher == NULL
+         && ((_hidden_Gost28147_89_cipher =
+              EVP_CIPHER_meth_new(NID_id_Gost28147_89, 1 /* block_size */ ,
+                                  32 /* key_size */ )) == NULL
+             || !EVP_CIPHER_meth_set_iv_length(_hidden_Gost28147_89_cipher, 8)
+             || !EVP_CIPHER_meth_set_flags(_hidden_Gost28147_89_cipher,
+                                           EVP_CIPH_CFB_MODE |
+                                           EVP_CIPH_NO_PADDING |
+                                           EVP_CIPH_CUSTOM_IV |
+                                           EVP_CIPH_RAND_KEY |
+                                           EVP_CIPH_ALWAYS_CALL_INIT)
+             || !EVP_CIPHER_meth_set_init(_hidden_Gost28147_89_cipher,
+                                          gost_cipher_init)
+             || !EVP_CIPHER_meth_set_do_cipher(_hidden_Gost28147_89_cipher,
+                                               gost_cipher_do_cfb)
+             || !EVP_CIPHER_meth_set_cleanup(_hidden_Gost28147_89_cipher,
+                                             gost_cipher_cleanup)
+             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_Gost28147_89_cipher,
+                                                   sizeof(struct
+                                                          ossl_gost_cipher_ctx))
+             ||
+             !EVP_CIPHER_meth_set_set_asn1_params(_hidden_Gost28147_89_cipher,
+                                                  gost89_set_asn1_parameters)
+             ||
+             !EVP_CIPHER_meth_set_get_asn1_params(_hidden_Gost28147_89_cipher,
+                                                  gost89_get_asn1_parameters)
+             || !EVP_CIPHER_meth_set_ctrl(_hidden_Gost28147_89_cipher,
+                                          gost_cipher_ctl))) {
+         EVP_CIPHER_meth_free(_hidden_Gost28147_89_cipher);
+         _hidden_Gost28147_89_cipher = NULL;
+     }
+     return _hidden_Gost28147_89_cipher;
+ }
  
- EVP_CIPHER cipher_gost_cbc = {
-     NID_gost89_cbc,
-     8,                          /*block_size */
-     32,                         /*key_size */
-     8,                          /*iv_len */
-     EVP_CIPH_CBC_MODE |
-         EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
-     gost_cipher_init_cbc,
-     gost_cipher_do_cbc,
-     gost_cipher_cleanup,
-     sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
-     gost89_set_asn1_parameters,
-     gost89_get_asn1_parameters,
-     gost_cipher_ctl,
-     NULL,
- };
+ static EVP_CIPHER *_hidden_Gost28147_89_cbc = NULL;
+ const EVP_CIPHER *cipher_gost_cbc(void)
+ {
+     if (_hidden_Gost28147_89_cbc == NULL
+         && ((_hidden_Gost28147_89_cbc =
+              EVP_CIPHER_meth_new(NID_gost89_cbc, 8 /* block_size */ ,
+                                  32 /* key_size */ )) == NULL
+             || !EVP_CIPHER_meth_set_iv_length(_hidden_Gost28147_89_cbc, 8)
+             || !EVP_CIPHER_meth_set_flags(_hidden_Gost28147_89_cbc,
+                                           EVP_CIPH_CBC_MODE |
+                                           EVP_CIPH_CUSTOM_IV |
+                                           EVP_CIPH_RAND_KEY |
+                                           EVP_CIPH_ALWAYS_CALL_INIT)
+             || !EVP_CIPHER_meth_set_init(_hidden_Gost28147_89_cbc,
+                                          gost_cipher_init_cbc)
+             || !EVP_CIPHER_meth_set_do_cipher(_hidden_Gost28147_89_cbc,
+                                               gost_cipher_do_cbc)
+             || !EVP_CIPHER_meth_set_cleanup(_hidden_Gost28147_89_cbc,
+                                             gost_cipher_cleanup)
+             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_Gost28147_89_cbc,
+                                                   sizeof(struct
+                                                          ossl_gost_cipher_ctx))
+             || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_Gost28147_89_cbc,
+                                                     gost89_set_asn1_parameters)
+             || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_Gost28147_89_cbc,
+                                                     gost89_get_asn1_parameters)
+             || !EVP_CIPHER_meth_set_ctrl(_hidden_Gost28147_89_cbc,
+                                          gost_cipher_ctl))) {
+         EVP_CIPHER_meth_free(_hidden_Gost28147_89_cbc);
+         _hidden_Gost28147_89_cbc = NULL;
+     }
+     return _hidden_Gost28147_89_cbc;
+ }
  
- EVP_CIPHER cipher_gost_cpacnt = {
-     NID_gost89_cnt,
-     1,                          /* block_size */
-     32,                         /* key_size */
-     8,                          /* iv_len */
-     EVP_CIPH_OFB_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_cleanup,
-     sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
-     gost89_set_asn1_parameters,
-     gost89_get_asn1_parameters,
-     gost_cipher_ctl,
-     NULL,
- };
+ static EVP_CIPHER *_hidden_gost89_cnt = NULL;
+ const EVP_CIPHER *cipher_gost_cpacnt(void)
+ {
+     if (_hidden_gost89_cnt == NULL
+         && ((_hidden_gost89_cnt =
+              EVP_CIPHER_meth_new(NID_gost89_cnt, 1 /* block_size */ ,
+                                  32 /* key_size */ )) == NULL
+             || !EVP_CIPHER_meth_set_iv_length(_hidden_gost89_cnt, 8)
+             || !EVP_CIPHER_meth_set_flags(_hidden_gost89_cnt,
+                                           EVP_CIPH_OFB_MODE |
+                                           EVP_CIPH_NO_PADDING |
+                                           EVP_CIPH_CUSTOM_IV |
+                                           EVP_CIPH_RAND_KEY |
+                                           EVP_CIPH_ALWAYS_CALL_INIT)
+             || !EVP_CIPHER_meth_set_init(_hidden_gost89_cnt,
+                                          gost_cipher_init_cpa)
+             || !EVP_CIPHER_meth_set_do_cipher(_hidden_gost89_cnt,
+                                               gost_cipher_do_cnt)
+             || !EVP_CIPHER_meth_set_cleanup(_hidden_gost89_cnt,
+                                             gost_cipher_cleanup)
+             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_gost89_cnt,
+                                                   sizeof(struct
+                                                          ossl_gost_cipher_ctx))
+             || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_gost89_cnt,
+                                                     gost89_set_asn1_parameters)
+             || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_gost89_cnt,
+                                                     gost89_get_asn1_parameters)
+             || !EVP_CIPHER_meth_set_ctrl(_hidden_gost89_cnt,
+                                          gost_cipher_ctl))) {
+         EVP_CIPHER_meth_free(_hidden_gost89_cnt);
+         _hidden_gost89_cnt = NULL;
+     }
+     return _hidden_gost89_cnt;
+ }
  
- EVP_CIPHER cipher_gost_cpcnt_12 = {
-     NID_gost89_cnt_12,
-     1,                          /* block_size */
-     32,                         /* key_size */
-     8,                          /* iv_len */
-     EVP_CIPH_OFB_MODE | EVP_CIPH_NO_PADDING |
-         EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
-     gost_cipher_init_cp_12,
-     gost_cipher_do_cnt,
-     gost_cipher_cleanup,
-     sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
-     gost89_set_asn1_parameters,
-     gost89_get_asn1_parameters,
-     gost_cipher_ctl,
-     NULL,
- };
+ static EVP_CIPHER *_hidden_gost89_cnt_12 = NULL;
+ const EVP_CIPHER *cipher_gost_cpcnt_12(void)
+ {
+     if (_hidden_gost89_cnt_12 == NULL
+         && ((_hidden_gost89_cnt_12 =
+              EVP_CIPHER_meth_new(NID_gost89_cnt_12, 1 /* block_size */ ,
+                                  32 /* key_size */ )) == NULL
+             || !EVP_CIPHER_meth_set_iv_length(_hidden_gost89_cnt_12, 8)
+             || !EVP_CIPHER_meth_set_flags(_hidden_gost89_cnt_12,
+                                           EVP_CIPH_OFB_MODE |
+                                           EVP_CIPH_NO_PADDING |
+                                           EVP_CIPH_CUSTOM_IV |
+                                           EVP_CIPH_RAND_KEY |
+                                           EVP_CIPH_ALWAYS_CALL_INIT)
+             || !EVP_CIPHER_meth_set_init(_hidden_gost89_cnt_12,
+                                          gost_cipher_init_cp_12)
+             || !EVP_CIPHER_meth_set_do_cipher(_hidden_gost89_cnt_12,
+                                               gost_cipher_do_cnt)
+             || !EVP_CIPHER_meth_set_cleanup(_hidden_gost89_cnt_12,
+                                             gost_cipher_cleanup)
+             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_gost89_cnt_12,
+                                                   sizeof(struct
+                                                          ossl_gost_cipher_ctx))
+             || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_gost89_cnt_12,
+                                                     gost89_set_asn1_parameters)
+             || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_gost89_cnt_12,
+                                                     gost89_get_asn1_parameters)
+             || !EVP_CIPHER_meth_set_ctrl(_hidden_gost89_cnt_12,
+                                          gost_cipher_ctl))) {
+         EVP_CIPHER_meth_free(_hidden_gost89_cnt_12);
+         _hidden_gost89_cnt_12 = NULL;
+     }
+     return _hidden_gost89_cnt_12;
+ }
+ void cipher_gost_destroy(void)
+ {
+     EVP_CIPHER_meth_free(_hidden_Gost28147_89_cipher);
+     _hidden_Gost28147_89_cipher = NULL;
+     EVP_CIPHER_meth_free(_hidden_gost89_cnt);
+     _hidden_gost89_cnt = NULL;
+     EVP_CIPHER_meth_free(_hidden_Gost28147_89_cbc);
+     _hidden_Gost28147_89_cbc = NULL;
+     EVP_CIPHER_meth_free(_hidden_gost89_cnt_12);
+     _hidden_gost89_cnt_12 = NULL;
+ }
  
  /* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
  /* Init functions which set specific parameters */
@@@ -128,41 -213,72 +213,72 @@@ static int gost_imit_cleanup(EVP_MD_CT
  /* Control function, knows how to set MAC key.*/
  static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr);
  
- EVP_MD imit_gost_cpa = {
-     NID_id_Gost28147_89_MAC,
-     NID_undef,
-     4,
-     0,
-     gost_imit_init_cpa,
-     gost_imit_update,
-     gost_imit_final,
-     gost_imit_copy,
-     gost_imit_cleanup,
-     NULL,
-     NULL,
-     {0, 0, 0, 0, 0},
-     8,
-     sizeof(struct ossl_gost_imit_ctx),
-     gost_imit_ctrl
- };
+ static EVP_MD *_hidden_Gost28147_89_MAC_md = NULL;
+ static EVP_MD *_hidden_Gost28147_89_12_MAC_md = NULL;
  
- EVP_MD imit_gost_cp_12 = {
-     NID_gost_mac_12,
-     NID_undef,
-     4,
-     0,
-     gost_imit_init_cp_12,
-     gost_imit_update,
-     gost_imit_final,
-     gost_imit_copy,
-     gost_imit_cleanup,
-     NULL,
-     NULL,
-     {0, 0, 0, 0, 0},
-     8,
-     sizeof(struct ossl_gost_imit_ctx),
-     gost_imit_ctrl
- };
+ EVP_MD *imit_gost_cpa(void)
+ {
+     if (_hidden_Gost28147_89_MAC_md == NULL) {
+         EVP_MD *md;
+         if ((md = EVP_MD_meth_new(NID_id_Gost28147_89_MAC, NID_undef)) == NULL
+             || !EVP_MD_meth_set_result_size(md, 4)
+             || !EVP_MD_meth_set_input_blocksize(md, 8)
+             || !EVP_MD_meth_set_app_datasize(md,
+                                              sizeof(struct
+                                                     ossl_gost_imit_ctx))
+             || !EVP_MD_meth_set_flags(md, 0)
+             || !EVP_MD_meth_set_init(md, gost_imit_init_cpa)
+             || !EVP_MD_meth_set_update(md, gost_imit_update)
+             || !EVP_MD_meth_set_final(md, gost_imit_final)
+             || !EVP_MD_meth_set_copy(md, gost_imit_copy)
+             || !EVP_MD_meth_set_cleanup(md, gost_imit_cleanup)
+             || !EVP_MD_meth_set_ctrl(md, gost_imit_ctrl)) {
+             EVP_MD_meth_free(md);
+             md = NULL;
+         }
+         _hidden_Gost28147_89_MAC_md = md;
+     }
+     return _hidden_Gost28147_89_MAC_md;
+ }
+ void imit_gost_cpa_destroy(void)
+ {
+     EVP_MD_meth_free(_hidden_Gost28147_89_MAC_md);
+     _hidden_Gost28147_89_MAC_md = NULL;
+ }
+ EVP_MD *imit_gost_cp_12(void)
+ {
+     if (_hidden_Gost28147_89_12_MAC_md == NULL) {
+         EVP_MD *md;
+         if ((md = EVP_MD_meth_new(NID_gost_mac_12, NID_undef)) == NULL
+             || !EVP_MD_meth_set_result_size(md, 4)
+             || !EVP_MD_meth_set_input_blocksize(md, 8)
+             || !EVP_MD_meth_set_app_datasize(md,
+                                              sizeof(struct
+                                                     ossl_gost_imit_ctx))
+             || !EVP_MD_meth_set_flags(md, 0)
+             || !EVP_MD_meth_set_init(md, gost_imit_init_cp_12)
+             || !EVP_MD_meth_set_update(md, gost_imit_update)
+             || !EVP_MD_meth_set_final(md, gost_imit_final)
+             || !EVP_MD_meth_set_copy(md, gost_imit_copy)
+             || !EVP_MD_meth_set_cleanup(md, gost_imit_cleanup)
+             || !EVP_MD_meth_set_ctrl(md, gost_imit_ctrl)) {
+             EVP_MD_meth_free(md);
+             md = NULL;
+         }
+         _hidden_Gost28147_89_12_MAC_md = md;
+     }
+     return _hidden_Gost28147_89_12_MAC_md;
+ }
+ void imit_gost_cp_12_destroy(void)
+ {
+     EVP_MD_meth_free(_hidden_Gost28147_89_12_MAC_md);
+     _hidden_Gost28147_89_12_MAC_md = NULL;
+ }
  
  /*
   * Correspondence between gost parameter OIDs and substitution blocks
@@@ -252,17 -368,20 +368,20 @@@ static int gost_cipher_init_param(EVP_C
                                    const unsigned char *iv, int enc,
                                    int paramNID, int mode)
  {
-     struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
-     if (ctx->app_data == NULL) {
+     struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
+     if (EVP_CIPHER_CTX_get_app_data(ctx) == NULL) {
          if (!gost_cipher_set_param(c, paramNID))
              return 0;
-         ctx->app_data = ctx->cipher_data;
+         EVP_CIPHER_CTX_set_app_data(ctx, EVP_CIPHER_CTX_get_cipher_data(ctx));
      }
      if (key)
          gost_key(&(c->cctx), key);
-     if (iv)
-         memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-     memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+     if (iv) {
+         memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
+                EVP_CIPHER_CTX_iv_length(ctx));
+     }
+     memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
+            EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
      return 1;
  }
  
@@@ -271,15 -390,18 +390,18 @@@ static int gost_cipher_init_cnt(EVP_CIP
                                  const unsigned char *iv,
                                  gost_subst_block * block)
  {
-     struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
+     struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
      gost_init(&(c->cctx), block);
      c->key_meshing = 1;
      c->count = 0;
      if (key)
          gost_key(&(c->cctx), key);
-     if (iv)
-         memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-     memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+     if (iv) {
+         memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
+                EVP_CIPHER_CTX_iv_length(ctx));
+     }
+     memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
+            EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
      return 1;
  }
  
@@@ -365,19 -487,21 +487,20 @@@ static void gost_cnt_next(void *ctx, un
  int gost_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
                         const unsigned char *in, size_t inl)
  {
 -    OPENSSL_assert(inl % 8 == 0);
      unsigned char b[8];
      const unsigned char *in_ptr = in;
      unsigned char *out_ptr = out;
      int i;
-     struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
-     OPENSSL_assert(inl % 8 == 0);
-     if (ctx->encrypt) {
+     struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
+     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
+     if (EVP_CIPHER_CTX_encrypting(ctx)) {
          while (inl > 0) {
              for (i = 0; i < 8; i++) {
-                 b[i] = ctx->iv[i] ^ in_ptr[i];
+                 b[i] = iv[i] ^ in_ptr[i];
              }
              gostcrypt(&(c->cctx), b, out_ptr);
-             memcpy(ctx->iv, out_ptr, 8);
+             memcpy(iv, out_ptr, 8);
              out_ptr += 8;
              in_ptr += 8;
              inl -= 8;
          while (inl > 0) {
              gostdecrypt(&(c->cctx), in_ptr, b);
              for (i = 0; i < 8; i++) {
-                 out_ptr[i] = ctx->iv[i] ^ b[i];
+                 out_ptr[i] = iv[i] ^ b[i];
              }
-             memcpy(ctx->iv, in_ptr, 8);
+             memcpy(iv, in_ptr, 8);
              out_ptr += 8;
              in_ptr += 8;
              inl -= 8;
@@@ -405,21 -529,23 +528,23 @@@ int gost_cipher_do_cfb(EVP_CIPHER_CTX *
      unsigned char *out_ptr = out;
      size_t i = 0;
      size_t j = 0;
+     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
+     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
  /* process partial block if any */
-     if (ctx->num) {
-         for (j = ctx->num, i = 0; j < 8 && i < inl;
+     if (EVP_CIPHER_CTX_num(ctx)) {
+         for (j = EVP_CIPHER_CTX_num(ctx), i = 0; j < 8 && i < inl;
               j++, i++, in_ptr++, out_ptr++) {
-             if (!ctx->encrypt)
-                 ctx->buf[j + 8] = *in_ptr;
-             *out_ptr = ctx->buf[j] ^ (*in_ptr);
-             if (ctx->encrypt)
-                 ctx->buf[j + 8] = *out_ptr;
+             if (!EVP_CIPHER_CTX_encrypting(ctx))
+                 buf[j + 8] = *in_ptr;
+             *out_ptr = buf[j] ^ (*in_ptr);
+             if (EVP_CIPHER_CTX_encrypting(ctx))
+                 buf[j + 8] = *out_ptr;
          }
          if (j == 8) {
-             memcpy(ctx->iv, ctx->buf + 8, 8);
-             ctx->num = 0;
+             memcpy(iv, buf + 8, 8);
+             EVP_CIPHER_CTX_set_num(ctx, 0);
          } else {
-             ctx->num = j;
+             EVP_CIPHER_CTX_set_num(ctx, j);
              return 1;
          }
      }
          /*
           * block cipher current iv
           */
-         gost_crypt_mesh(ctx->cipher_data, ctx->iv, ctx->buf);
+         gost_crypt_mesh(EVP_CIPHER_CTX_get_cipher_data(ctx), iv, buf);
          /*
           * xor next block of input text with it and output it
           */
          /*
           * output this block
           */
-         if (!ctx->encrypt)
-             memcpy(ctx->iv, in_ptr, 8);
+         if (!EVP_CIPHER_CTX_encrypting(ctx))
+             memcpy(iv, in_ptr, 8);
          for (j = 0; j < 8; j++) {
-             out_ptr[j] = ctx->buf[j] ^ in_ptr[j];
+             out_ptr[j] = buf[j] ^ in_ptr[j];
          }
          /* Encrypt */
          /* Next iv is next block of cipher text */
-         if (ctx->encrypt)
-             memcpy(ctx->iv, out_ptr, 8);
+         if (EVP_CIPHER_CTX_encrypting(ctx))
+             memcpy(iv, out_ptr, 8);
      }
  /* Process rest of buffer */
      if (i < inl) {
-         gost_crypt_mesh(ctx->cipher_data, ctx->iv, ctx->buf);
-         if (!ctx->encrypt)
-             memcpy(ctx->buf + 8, in_ptr, inl - i);
+         gost_crypt_mesh(EVP_CIPHER_CTX_get_cipher_data(ctx), iv, buf);
+         if (!EVP_CIPHER_CTX_encrypting(ctx))
+             memcpy(buf + 8, in_ptr, inl - i);
          for (j = 0; i < inl; j++, i++) {
-             out_ptr[j] = ctx->buf[j] ^ in_ptr[j];
+             out_ptr[j] = buf[j] ^ in_ptr[j];
          }
-         ctx->num = j;
-         if (ctx->encrypt)
-             memcpy(ctx->buf + 8, out_ptr, j);
+         EVP_CIPHER_CTX_set_num(ctx, j);
+         if (EVP_CIPHER_CTX_encrypting(ctx))
+             memcpy(buf + 8, out_ptr, j);
      } else {
-         ctx->num = 0;
+         EVP_CIPHER_CTX_set_num(ctx, 0);
      }
      return 1;
  }
@@@ -469,16 -595,18 +594,18 @@@ static int gost_cipher_do_cnt(EVP_CIPHE
      unsigned char *out_ptr = out;
      size_t i = 0;
      size_t j;
+     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
+     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
  /* process partial block if any */
-     if (ctx->num) {
-         for (j = ctx->num, i = 0; j < 8 && i < inl;
+     if (EVP_CIPHER_CTX_num(ctx)) {
+         for (j = EVP_CIPHER_CTX_num(ctx), i = 0; j < 8 && i < inl;
               j++, i++, in_ptr++, out_ptr++) {
-             *out_ptr = ctx->buf[j] ^ (*in_ptr);
+             *out_ptr = buf[j] ^ (*in_ptr);
          }
          if (j == 8) {
-             ctx->num = 0;
+             EVP_CIPHER_CTX_set_num(ctx, 0);
          } else {
-             ctx->num = j;
+             EVP_CIPHER_CTX_set_num(ctx, j);
              return 1;
          }
      }
           * block cipher current iv
           */
          /* Encrypt */
-         gost_cnt_next(ctx->cipher_data, ctx->iv, ctx->buf);
+         gost_cnt_next(EVP_CIPHER_CTX_get_cipher_data(ctx), iv, buf);
          /*
           * xor next block of input text with it and output it
           */
           * output this block
           */
          for (j = 0; j < 8; j++) {
-             out_ptr[j] = ctx->buf[j] ^ in_ptr[j];
+             out_ptr[j] = buf[j] ^ in_ptr[j];
          }
      }
  /* Process rest of buffer */
      if (i < inl) {
-         gost_cnt_next(ctx->cipher_data, ctx->iv, ctx->buf);
+         gost_cnt_next(EVP_CIPHER_CTX_get_cipher_data(ctx), iv, buf);
          for (j = 0; i < inl; j++, i++) {
-             out_ptr[j] = ctx->buf[j] ^ in_ptr[j];
+             out_ptr[j] = buf[j] ^ in_ptr[j];
          }
-         ctx->num = j;
+         EVP_CIPHER_CTX_set_num(ctx, j);
      } else {
-         ctx->num = 0;
+         EVP_CIPHER_CTX_set_num(ctx, 0);
      }
      return 1;
  }
  /* Cleaning up of EVP_CIPHER_CTX */
  int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx)
  {
-     gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx);
-     ctx->app_data = NULL;
+     gost_destroy(&
+                  ((struct ossl_gost_cipher_ctx *)
+                   EVP_CIPHER_CTX_get_cipher_data(ctx))->cctx);
+     EVP_CIPHER_CTX_set_app_data(ctx, NULL);
      return 1;
  }
  
  int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
  {
      switch (type) {
+ #if 0
      case EVP_CTRL_INIT:
          {
-             struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
+             struct ossl_gost_cipher_ctx *c =
+                 EVP_CIPHER_CTX_get_cipher_data(ctx);
              if (c == NULL) {
                  return -1;
              }
              return gost_cipher_set_param(c, arg);
          }
+ #endif
      case EVP_CTRL_RAND_KEY:
          {
-             if (RAND_bytes((unsigned char *)ptr, ctx->key_len) <= 0) {
+             if (RAND_bytes
+                 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
                  GOSTerr(GOST_F_GOST_CIPHER_CTL, GOST_R_RNG_ERROR);
                  return -1;
              }
          } else {
              return 0;
          }
- #ifdef EVP_CTRL_SET_SBOX
 +    case EVP_CTRL_SET_SBOX:
 +        if (ptr) {
 +            struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
 +            int nid;
 +            int cur_meshing;
 +            int ret;
  
+     case EVP_CTRL_SET_SBOX:
+         if (ptr) {
+             struct ossl_gost_cipher_ctx *c =
+                 EVP_CIPHER_CTX_get_cipher_data(ctx);
+             int nid;
+             int cur_meshing;
+             int ret;
              if (c == NULL) {
                  return -1;
              }
          } else {
              return 0;
          }
- #endif
- #ifdef EVP_CTRL_KEY_MESH
      case EVP_CTRL_KEY_MESH:
          {
-             struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
+             struct ossl_gost_cipher_ctx *c =
+                 EVP_CIPHER_CTX_get_cipher_data(ctx);
  
              if (c == NULL) {
                  return -1;
              c->key_meshing = arg;
              return 1;
          }
- #endif
      default:
          GOSTerr(GOST_F_GOST_CIPHER_CTL,
                  GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
@@@ -618,14 -751,15 +756,15 @@@ int gost89_set_asn1_parameters(EVP_CIPH
      int len = 0;
      unsigned char *buf = NULL;
      unsigned char *p = NULL;
-     struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
+     struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
      GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
      ASN1_OCTET_STRING *os = NULL;
      if (!gcp) {
          GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE);
          return 0;
      }
-     if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) {
+     if (!ASN1_OCTET_STRING_set
+         (gcp->iv, EVP_CIPHER_CTX_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx))) {
          GOST_CIPHER_PARAMS_free(gcp);
          GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE);
          return 0;
@@@ -663,7 -797,7 +802,7 @@@ int gost89_get_asn1_parameters(EVP_CIPH
      int len;
      GOST_CIPHER_PARAMS *gcp = NULL;
      unsigned char *p;
-     struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
+     struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
      int nid;
  
      if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
                                   params->value.sequence->length);
  
      len = gcp->iv->length;
-     if (len != ctx->cipher->iv_len) {
+     if (len != EVP_CIPHER_CTX_iv_length(ctx)) {
          GOST_CIPHER_PARAMS_free(gcp);
          GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS, GOST_R_INVALID_IV_LENGTH);
          return -1;
          GOST_CIPHER_PARAMS_free(gcp);
          return -1;
      }
-     {
-         ASN1_TYPE tmp;
-         tmp.value.octet_string = gcp->iv;
-         tmp.type = V_ASN1_OCTET_STRING;
-         EVP_CIPHER_get_asn1_iv(ctx, &tmp);
-     }
+     /*XXX missing non-const accessor */
+     memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), gcp->iv->data,
+            EVP_CIPHER_CTX_iv_length(ctx));
  
      GOST_CIPHER_PARAMS_free(gcp);
  
  
  static int gost_imit_init(EVP_MD_CTX *ctx, gost_subst_block * block)
  {
-     struct ossl_gost_imit_ctx *c = ctx->md_data;
+     struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx);
      memset(c->buffer, 0, sizeof(c->buffer));
      memset(c->partial_block, 0, sizeof(c->partial_block));
      c->count = 0;
@@@ -749,7 -879,7 +884,7 @@@ static void mac_block_mesh(struct ossl_
  
  int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
  {
-     struct ossl_gost_imit_ctx *c = ctx->md_data;
+     struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx);
      const unsigned char *p = data;
      size_t bytes = count, i;
      if (!(c->key_set)) {
  
  int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md)
  {
-     struct ossl_gost_imit_ctx *c = ctx->md_data;
+     struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx);
      if (!c->key_set) {
          GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
          return 0;
@@@ -810,13 -940,14 +945,14 @@@ int gost_imit_ctrl(EVP_MD_CTX *ctx, in
          return 1;
      case EVP_MD_CTRL_SET_KEY:
          {
-             struct ossl_gost_imit_ctx *gost_imit_ctx = ctx->md_data;
+             struct ossl_gost_imit_ctx *gost_imit_ctx =
+                 EVP_MD_CTX_md_data(ctx);
  
-             if (ctx->digest->init(ctx) <= 0) {
+             if (EVP_MD_meth_get_init(EVP_MD_CTX_md(ctx)) (ctx) <= 0) {
                  GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_MAC_KEY_NOT_SET);
                  return 0;
              }
-             ctx->flags |= EVP_MD_CTX_FLAG_NO_INIT;
+             EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT);
  
              if (arg == 0) {
                  struct gost_mac_key *key = (struct gost_mac_key *)ptr;
          }
      case EVP_MD_CTRL_MAC_LEN:
          {
-             struct ossl_gost_imit_ctx *c = ctx->md_data;
+             struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx);
              if (arg < 1 || arg > 8) {
                  GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE);
                  return 0;
  
  int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
  {
-     memcpy(to->md_data, from->md_data, sizeof(struct ossl_gost_imit_ctx));
+     if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from)) {
+         memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from),
+                sizeof(struct ossl_gost_imit_ctx));
+     }
      return 1;
  }
  
  /* Clean up imit ctx */
  int gost_imit_cleanup(EVP_MD_CTX *ctx)
  {
-     memset(ctx->md_data, 0, sizeof(struct ossl_gost_imit_ctx));
+     memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(struct ossl_gost_imit_ctx));
      return 1;
  }
diff --combined gost_eng.c
index 7c0b156636aa9a5f0a0f5cfcfc3be87f34babb1d,472ba82573f0964a593374f8fb5eeb44a5b07eab..16316a16949db7de9b6c4acf7bb4bc2566821cb4
  #include <openssl/obj_mac.h>
  #include "e_gost_err.h"
  #include "gost_lcl.h"
- static const char *engine_gost_id = "gost";
- static const char *engine_gost_name =
-     "Reference implementation of GOST engine";
+ #include "gost_grasshopper_cipher.h"
+ static const char* engine_gost_id = "gost";
+ static const char* engine_gost_name =
+         "Reference implementation of GOST engine";
  
  /* Symmetric cipher and digest function registrar */
  
- static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-                         const int **nids, int nid);
+ static int gost_ciphers(ENGINE* e, const EVP_CIPHER** cipher,
+                         const int** nids, int nid);
  
- static int gost_digests(ENGINE *e, const EVP_MD **digest,
-                         const int **nids, int ind);
+ static int gost_digests(ENGINE* e, const EVP_MD** digest,
+                         const int** nids, int ind);
  
- static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
-                            const int **nids, int nid);
+ static int gost_pkey_meths(ENGINE* e, EVP_PKEY_METHOD** pmeth,
+                            const int** nids, int nid);
  
- static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
-                                 const int **nids, int nid);
+ 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,
-     NID_gost89_cnt,
-     NID_gost89_cnt_12,
-     NID_gost89_cbc,
-     0
+         NID_id_Gost28147_89,
+         NID_gost89_cnt,
+         NID_gost89_cnt_12,
+         NID_gost89_cbc,
+         NID_grasshopper_ecb,
+         NID_grasshopper_cbc,
+         NID_grasshopper_cfb,
+         NID_grasshopper_ofb,
+         NID_grasshopper_ctr,
+         0
  };
  
- static int gost_digest_nids[] = {
-     NID_id_GostR3411_94,
-     NID_id_Gost28147_89_MAC,
-     NID_id_GostR3411_2012_256,
-     NID_id_GostR3411_2012_512,
-     NID_gost_mac_12,
-     0
- };
+ static int gost_digest_nids(const int** nids) {
+     static int digest_nids[6] = {0, 0, 0, 0, 0, 0};
+     static int pos = 0;
+     static int init = 0;
+     if (!init) {
+         const EVP_MD* md;
+         if ((md = digest_gost()) != NULL)
+             digest_nids[pos++] = EVP_MD_type(md);
+         if ((md = imit_gost_cpa()) != NULL)
+             digest_nids[pos++] = EVP_MD_type(md);
+         if ((md = digest_gost2012_256()) != NULL)
+             digest_nids[pos++] = EVP_MD_type(md);
+         if ((md = digest_gost2012_512()) != NULL)
+             digest_nids[pos++] = EVP_MD_type(md);
+         if ((md = imit_gost_cp_12()) != NULL)
+             digest_nids[pos++] = EVP_MD_type(md);
+         digest_nids[pos] = 0;
+         init = 1;
+     }
+     *nids = digest_nids;
+     return pos;
+ }
  
  static int gost_pkey_meth_nids[] = {
-     NID_id_GostR3410_2001,
-     NID_id_Gost28147_89_MAC,
-     NID_id_GostR3410_2012_256,
-     NID_id_GostR3410_2012_512,
-     NID_gost_mac_12,
-     0
+         NID_id_GostR3410_2001,
+         NID_id_Gost28147_89_MAC,
+         NID_id_GostR3410_2012_256,
+         NID_id_GostR3410_2012_512,
+         NID_gost_mac_12,
+         0
  };
  
- static EVP_PKEY_METHOD *pmeth_GostR3410_2001 = NULL,
-     *pmeth_GostR3410_2012_256 = NULL,
-     *pmeth_GostR3410_2012_512 = NULL,
-     *pmeth_Gost28147_MAC = NULL, *pmeth_Gost28147_MAC_12 = NULL;
+ static EVP_PKEY_METHODpmeth_GostR3410_2001 = NULL,
+         * pmeth_GostR3410_2012_256 = NULL,
+         * pmeth_GostR3410_2012_512 = NULL,
+         * pmeth_Gost28147_MAC = NULL, * pmeth_Gost28147_MAC_12 = NULL;
  
- static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_2001 = NULL,
-     *ameth_GostR3410_2012_256 = NULL,
-     *ameth_GostR3410_2012_512 = NULL,
-     *ameth_Gost28147_MAC = NULL, *ameth_Gost28147_MAC_12 = NULL;
+ static EVP_PKEY_ASN1_METHODameth_GostR3410_2001 = NULL,
+         * ameth_GostR3410_2012_256 = NULL,
+         * ameth_GostR3410_2012_512 = NULL,
+         * ameth_Gost28147_MAC = NULL, * ameth_Gost28147_MAC_12 = NULL;
  
- static int gost_engine_init(ENGINE *e)
- {
+ static int gost_engine_init(ENGINE* e) {
      return 1;
  }
  
- static int gost_engine_finish(ENGINE *e)
- {
+ static int gost_engine_finish(ENGINE* e) {
      return 1;
  }
  
- static int gost_engine_destroy(ENGINE *e)
- {
+ static int gost_engine_destroy(ENGINE* e) {
+     digest_gost_destroy();
+     digest_gost2012_256_destroy();
+     digest_gost2012_512_destroy();
+     imit_gost_cpa_destroy();
+     imit_gost_cp_12_destroy();
+     cipher_gost_destroy();
      gost_param_free();
  
      pmeth_GostR3410_2001 = NULL;
      ameth_GostR3410_2012_512 = NULL;
      ameth_Gost28147_MAC_12 = NULL;
  
 +      ERR_unload_GOST_strings();
 +      
      return 1;
  }
  
- static int bind_gost(ENGINE *e, const char *id)
- {
+ static int bind_gost(ENGINE* e, const char* id) {
      int ret = 0;
-     if (id && strcmp(id, engine_gost_id))
+     if (id != NULL && strcmp(id, engine_gost_id) != 0)
          return 0;
      if (ameth_GostR3410_2001) {
          printf("GOST engine already loaded\n");
      }
  
      if (!register_ameth_gost
-         (NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001",
-          "GOST R 34.10-2001"))
+             (NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001",
+              "GOST R 34.10-2001"))
          goto end;
      if (!register_ameth_gost
-         (NID_id_GostR3410_2012_256, &ameth_GostR3410_2012_256, "GOST2012_256",
-          "GOST R 34.10-2012 with 256 bit key"))
+             (NID_id_GostR3410_2012_256, &ameth_GostR3410_2012_256, "GOST2012_256",
+              "GOST R 34.10-2012 with 256 bit key"))
          goto end;
      if (!register_ameth_gost
-         (NID_id_GostR3410_2012_512, &ameth_GostR3410_2012_512, "GOST2012_512",
-          "GOST R 34.10-2012 with 512 bit key"))
+             (NID_id_GostR3410_2012_512, &ameth_GostR3410_2012_512, "GOST2012_512",
+              "GOST R 34.10-2012 with 512 bit key"))
          goto end;
      if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
                               "GOST-MAC", "GOST 28147-89 MAC"))
          goto end;
  
      if (!register_pmeth_gost
-         (NID_id_GostR3410_2012_256, &pmeth_GostR3410_2012_256, 0))
+             (NID_id_GostR3410_2012_256, &pmeth_GostR3410_2012_256, 0))
          goto end;
      if (!register_pmeth_gost
-         (NID_id_GostR3410_2012_512, &pmeth_GostR3410_2012_512, 0))
+             (NID_id_GostR3410_2012_512, &pmeth_GostR3410_2012_512, 0))
          goto end;
      if (!register_pmeth_gost
-         (NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
+             (NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
          goto end;
      if (!register_pmeth_gost(NID_gost_mac_12, &pmeth_Gost28147_MAC_12, 0))
          goto end;
          || !ENGINE_register_digests(e)
          || !ENGINE_register_pkey_meths(e)
          /* These two actually should go in LIST_ADD command */
-         || !EVP_add_cipher(&cipher_gost)
-         || !EVP_add_cipher(&cipher_gost_cbc)
-         || !EVP_add_cipher(&cipher_gost_cpacnt)
-         || !EVP_add_cipher(&cipher_gost_cpcnt_12)
-         || !EVP_add_digest(&digest_gost)
-         || !EVP_add_digest(&digest_gost2012_512)
-         || !EVP_add_digest(&digest_gost2012_256)
-         || !EVP_add_digest(&imit_gost_cpa)
-         || !EVP_add_digest(&imit_gost_cp_12)
-         ) {
+         || !EVP_add_cipher(cipher_gost())
+         || !EVP_add_cipher(cipher_gost_cbc())
+         || !EVP_add_cipher(cipher_gost_cpacnt())
+         || !EVP_add_cipher(cipher_gost_cpcnt_12())
+         || !EVP_add_cipher(cipher_gost_grasshopper_ecb())
+         || !EVP_add_cipher(cipher_gost_grasshopper_cbc())
+         || !EVP_add_cipher(cipher_gost_grasshopper_cfb())
+         || !EVP_add_cipher(cipher_gost_grasshopper_ofb())
+         || !EVP_add_cipher(cipher_gost_grasshopper_ctr())
+         || !EVP_add_digest(digest_gost())
+         || !EVP_add_digest(digest_gost2012_512())
+         || !EVP_add_digest(digest_gost2012_256())
+         || !EVP_add_digest(imit_gost_cpa())
+         || !EVP_add_digest(imit_gost_cp_12())
+             ) {
          goto end;
      }
  
+     ENGINE_register_all_complete();
      ERR_load_GOST_strings();
      ret = 1;
-  end:
+     end:
      return ret;
  }
  
  IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
      IMPLEMENT_DYNAMIC_CHECK_FN()
  #endif                          /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
- static int gost_digests(ENGINE *e, const EVP_MD **digest,
-                         const int **nids, int nid)
- {
+ static int gost_digests(ENGINE* e, const EVP_MD** digest,
                        const int** nids, int nid) {
      int ok = 1;
-     if (!digest) {
-         *nids = gost_digest_nids;
-         return sizeof(gost_digest_nids) / sizeof(gost_digest_nids[0]) - 1;
+     if (digest == NULL) {
+         return gost_digest_nids(nids);
      }
      if (nid == NID_id_GostR3411_94) {
-         *digest = &digest_gost;
+         *digest = digest_gost();
+     } else if (nid == NID_id_Gost28147_89_MAC) {
+         *digest = imit_gost_cpa();
      } else if (nid == NID_id_GostR3411_2012_256) {
-         *digest = &digest_gost2012_256;
+         *digest = digest_gost2012_256();
      } else if (nid == NID_id_GostR3411_2012_512) {
-         *digest = &digest_gost2012_512;
-     } else if (nid == NID_id_Gost28147_89_MAC) {
-         *digest = &imit_gost_cpa;
+         *digest = digest_gost2012_512();
      } else if (nid == NID_gost_mac_12) {
-         *digest = &imit_gost_cp_12;
+         *digest = imit_gost_cp_12();
      } else {
          ok = 0;
          *digest = NULL;
      return ok;
  }
  
- static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-                         const int **nids, int nid)
- {
+ static int gost_ciphers(ENGINE* e, const EVP_CIPHER** cipher,
+                         const int** nids, int nid) {
      int ok = 1;
-     if (!cipher) {
+     if (cipher == NULL) {
          *nids = gost_cipher_nids;
          return sizeof(gost_cipher_nids) / sizeof(gost_cipher_nids[0]) - 1;
      }
  
      if (nid == NID_id_Gost28147_89) {
-         *cipher = &cipher_gost;
+         *cipher = cipher_gost();
      } else if (nid == NID_gost89_cnt) {
-         *cipher = &cipher_gost_cpacnt;
+         *cipher = cipher_gost_cpacnt();
      } else if (nid == NID_gost89_cnt_12) {
-         *cipher = &cipher_gost_cpcnt_12;
+         *cipher = cipher_gost_cpcnt_12();
      } else if (nid == NID_gost89_cbc) {
-         *cipher = &cipher_gost_cbc;
+         *cipher = cipher_gost_cbc();
+     } else if (nid == NID_grasshopper_ecb) {
+         *cipher = cipher_gost_grasshopper_ecb();
+     } else if (nid == NID_grasshopper_cbc) {
+         *cipher = cipher_gost_grasshopper_cbc();
+     } else if (nid == NID_grasshopper_cfb) {
+         *cipher = cipher_gost_grasshopper_cfb();
+     } else if (nid == NID_grasshopper_ofb) {
+         *cipher = cipher_gost_grasshopper_ofb();
+     } else if (nid == NID_grasshopper_ctr) {
+         *cipher = cipher_gost_grasshopper_ctr();
      } else {
          ok = 0;
          *cipher = NULL;
      return ok;
  }
  
- static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
-                            const int **nids, int nid)
- {
-     if (!pmeth) {
+ static int gost_pkey_meths(ENGINE* e, EVP_PKEY_METHOD** pmeth,
+                            const int** nids, int nid) {
+     if (pmeth == NULL) {
          *nids = gost_pkey_meth_nids;
-         return sizeof(gost_pkey_meth_nids) / sizeof(gost_pkey_meth_nids[0]) -
-             1;
+         return sizeof(gost_pkey_meth_nids) / sizeof(gost_pkey_meth_nids[0]) - 1;
      }
  
      switch (nid) {
-     case NID_id_GostR3410_2001:
-         *pmeth = pmeth_GostR3410_2001;
-         return 1;
-     case NID_id_GostR3410_2012_256:
-         *pmeth = pmeth_GostR3410_2012_256;
-         return 1;
-     case NID_id_GostR3410_2012_512:
-         *pmeth = pmeth_GostR3410_2012_512;
-         return 1;
-     case NID_id_Gost28147_89_MAC:
-         *pmeth = pmeth_Gost28147_MAC;
-         return 1;
-     case NID_gost_mac_12:
-         *pmeth = pmeth_Gost28147_MAC_12;
-         return 1;
-     default:;
+         case NID_id_GostR3410_2001:
+             *pmeth = pmeth_GostR3410_2001;
+             return 1;
+         case NID_id_GostR3410_2012_256:
+             *pmeth = pmeth_GostR3410_2012_256;
+             return 1;
+         case NID_id_GostR3410_2012_512:
+             *pmeth = pmeth_GostR3410_2012_512;
+             return 1;
+         case NID_id_Gost28147_89_MAC:
+             *pmeth = pmeth_Gost28147_MAC;
+             return 1;
+         case NID_gost_mac_12:
+             *pmeth = pmeth_Gost28147_MAC_12;
+             return 1;
+         default:;
      }
  
      *pmeth = NULL;
      return 0;
  }
  
- static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
-                                 const int **nids, int nid)
- {
-     if (!ameth) {
+ static int gost_pkey_asn1_meths(ENGINE* e, EVP_PKEY_ASN1_METHOD** ameth,
+                                 const int** nids, int nid) {
+     if (ameth == NULL) {
          *nids = gost_pkey_meth_nids;
-         return sizeof(gost_pkey_meth_nids) / sizeof(gost_pkey_meth_nids[0]) -
-             1;
+         return sizeof(gost_pkey_meth_nids) / sizeof(gost_pkey_meth_nids[0]) - 1;
      }
      switch (nid) {
-     case NID_id_GostR3410_2001:
-         *ameth = ameth_GostR3410_2001;
-         return 1;
-     case NID_id_GostR3410_2012_256:
-         *ameth = ameth_GostR3410_2012_256;
-         return 1;
-     case NID_id_GostR3410_2012_512:
-         *ameth = ameth_GostR3410_2012_512;
-         return 1;
-     case NID_id_Gost28147_89_MAC:
-         *ameth = ameth_Gost28147_MAC;
-         return 1;
-     case NID_gost_mac_12:
-         *ameth = ameth_Gost28147_MAC_12;
-         return 1;
-     default:;
+         case NID_id_GostR3410_2001:
+             *ameth = ameth_GostR3410_2001;
+             return 1;
+         case NID_id_GostR3410_2012_256:
+             *ameth = ameth_GostR3410_2012_256;
+             return 1;
+         case NID_id_GostR3410_2012_512:
+             *ameth = ameth_GostR3410_2012_512;
+             return 1;
+         case NID_id_Gost28147_89_MAC:
+             *ameth = ameth_Gost28147_MAC;
+             return 1;
+         case NID_gost_mac_12:
+             *ameth = ameth_Gost28147_MAC_12;
+             return 1;
+         default:;
      }
  
      *ameth = NULL;
  }
  
  #ifdef OPENSSL_NO_DYNAMIC_ENGINE
- static ENGINE *engine_gost(void)
- {
-     ENGINE *ret = ENGINE_new();
static ENGINE* engine_gost(void) {
+     ENGINEret = ENGINE_new();
      if (!ret)
          return NULL;
      if (!bind_gost(ret, engine_gost_id)) {
      return ret;
  }
  
- void ENGINE_load_gost(void)
- {
-     ENGINE *toadd;
+ void ENGINE_load_gost(void) {
+     ENGINE* toadd;
      if (pmeth_GostR3410_2001)
          return;
      toadd = engine_gost();
      ENGINE_free(toadd);
      ERR_clear_error();
  }
  #endif
diff --combined gost_pmeth.c
index ca824ffce78948b8f222ad3b903cbb1e300f3128,2ef949d2da79b3d1da1c6be2f42c44166fc76cfd..9a01822fdd818ada12b85b491819b11d1b4b4cdb
@@@ -146,8 -146,10 +146,10 @@@ static int pkey_gost_ctrl(EVP_PKEY_CTX 
      case EVP_PKEY_CTRL_SET_IV:
          OPENSSL_assert(p2 != NULL);
          pctx->shared_ukm = OPENSSL_malloc((int)p1);
-         if (!pctx->shared_ukm)
+         if (pctx->shared_ukm == NULL) {
+             GOSTerr(GOST_F_PKEY_GOST_CTRL, ERR_R_MALLOC_FAILURE);
              return 0;
+         }
          memcpy(pctx->shared_ukm, p2, (int)p1);
          return 1;
      case EVP_PKEY_CTRL_PEER_KEY:
@@@ -367,10 -369,12 +369,12 @@@ static int pkey_gost2012cp_keygen(EVP_P
   */
  int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
  {
+     const BIGNUM *sig_r = NULL, *sig_s = NULL;
+     DSA_SIG_get0(s, &sig_r, &sig_s);
      *siglen = 2 * order;
      memset(sig, 0, *siglen);
-     store_bignum(s->s, sig, order);
-     store_bignum(s->r, sig + order, order);
+     store_bignum(sig_s, sig, order);
+     store_bignum(sig_r, sig + order, order);
      DSA_SIG_free(s);
      return 1;
  }
@@@ -416,14 -420,16 +420,16 @@@ static int pkey_gost_ec_cp_sign(EVP_PKE
  DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen)
  {
      DSA_SIG *s;
+     const BIGNUM *sig_r = NULL, *sig_s = NULL;
  
      s = DSA_SIG_new();
      if (s == NULL) {
          GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE);
          return NULL;
      }
-     s->s = BN_bin2bn(sig, siglen / 2, NULL);
-     s->r = BN_bin2bn(sig + siglen / 2, siglen / 2, NULL);
+     DSA_SIG_get0(s, &sig_r, &sig_s);
+     sig_s = BN_bin2bn(sig, siglen / 2, NULL);
+     sig_r = BN_bin2bn(sig + siglen / 2, siglen / 2, NULL);
      return s;
  }
  
@@@ -478,7 -484,7 +484,7 @@@ static int pkey_gost_mac_init(EVP_PKEY_
          struct gost_mac_key *key = EVP_PKEY_get0(pkey);
          if (key) {
              data->mac_param_nid = key->mac_param_nid;
-                                               data->mac_size      = key->mac_size;
+             data->mac_size = key->mac_size;
          }
      }
  
@@@ -566,13 -572,12 +572,12 @@@ static int pkey_gost_mac_ctrl(EVP_PKEY_
                              GOST_R_MAC_KEY_NOT_SET);
                      return 0;
                  }
-                 return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 0,
-                                              key);
+                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
+                     (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
              } else {
-                 return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32,
-                                              &(data->key));
+                 return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
+                     (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
              }
-             return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key);
          }
      case EVP_PKEY_CTRL_MAC_LEN:
          {
@@@ -633,13 -638,11 +638,13 @@@ static int pkey_gost_mac_ctrl_str(EVP_P
          }
  
          param = get_encryption_params(obj);
 +                              ASN1_OBJECT_free(obj);
          if (param == NULL) {
              GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
              return 0;
          }
  
 +
          return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, 0,
                                    (void *)param);
      }
@@@ -660,7 -663,7 +665,7 @@@ static int pkey_gost_mac_keygen_base(EV
          return 0;
      memcpy(keydata->key, data->key, 32);
      keydata->mac_param_nid = data->mac_param_nid;
-               keydata->mac_size      = data->mac_size;
+     keydata->mac_size = data->mac_size;
      EVP_PKEY_assign(pkey, mac_nid, keydata);
      return 1;
  }
@@@ -679,9 -682,9 +684,9 @@@ static int pkey_gost_mac_signctx_init(E
  {
      struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
  
-               if (data == NULL) {
-                       pkey_gost_mac_init(ctx);
-               }
+     if (data == NULL) {
+         pkey_gost_mac_init(ctx);
+     }
  
      data = EVP_PKEY_CTX_get_data(ctx);
      if (!data) {
@@@ -709,7 -712,8 +714,8 @@@ static int pkey_gost_mac_signctx(EVP_PK
          return 1;
      }
  
-     mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_MAC_LEN, data->mac_size, NULL);
+     EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
+         (mctx, EVP_MD_CTRL_MAC_LEN, data->mac_size, NULL);
      ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
      *siglen = data->mac_size;
      return ret;