Skip to content

Instantly share code, notes, and snippets.

@proger
Created January 14, 2014 10:27
Show Gist options
  • Save proger/8416306 to your computer and use it in GitHub Desktop.
Save proger/8416306 to your computer and use it in GitHub Desktop.
diff -urN openssl-1.0.1e/Configure openssl-1.0.1e.patched/Configure
--- openssl-1.0.1e/Configure 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/Configure 2013-12-28 15:32:08.135101218 +0900
@@ -982,6 +982,7 @@
{
$disabled{"ecdsa"} = "forced";
$disabled{"ecdh"} = "forced";
+ $disabled{"dstu"} = "forced";
}
# SSL 2.0 requires MD5 and RSA
@@ -1595,6 +1596,7 @@
$sdirs = 0 unless /\\$/;
s/engines // if (/^DIRS=/ && $disabled{"engine"});
s/ccgost// if (/^ENGDIRS=/ && $disabled{"gost"});
+ s/uadstu// if (/^ENGDIRS=/ && $disabled{"dstu"});
s/^VERSION=.*/VERSION=$version/;
s/^MAJOR=.*/MAJOR=$major/;
s/^MINOR=.*/MINOR=$minor/;
diff -urN openssl-1.0.1e/crypto/engine/eng_all.c openssl-1.0.1e.patched/crypto/engine/eng_all.c
--- openssl-1.0.1e/crypto/engine/eng_all.c 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/crypto/engine/eng_all.c 2013-12-28 15:32:08.135101218 +0900
@@ -113,6 +113,9 @@
#ifndef OPENSSL_NO_GOST
ENGINE_load_gost();
#endif
+#ifndef OPENSSL_NO_DSTU
+ ENGINE_load_dstu();
+#endif
#ifndef OPENSSL_NO_GMP
ENGINE_load_gmp();
#endif
diff -urN openssl-1.0.1e/crypto/engine/engine.h openssl-1.0.1e.patched/crypto/engine/engine.h
--- openssl-1.0.1e/crypto/engine/engine.h 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/crypto/engine/engine.h 2013-12-28 15:32:08.135101218 +0900
@@ -349,6 +349,9 @@
#ifndef OPENSSL_NO_GOST
void ENGINE_load_gost(void);
#endif
+#ifndef OPENSSL_NO_DSTU
+void ENGINE_load_dstu(void);
+#endif
#endif
void ENGINE_load_cryptodev(void);
void ENGINE_load_rsax(void);
diff -urN openssl-1.0.1e/crypto/objects/objects.txt openssl-1.0.1e.patched/crypto/objects/objects.txt
--- openssl-1.0.1e/crypto/objects/objects.txt 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/crypto/objects/objects.txt 2013-12-28 15:32:08.135101218 +0900
@@ -1290,3 +1290,28 @@
: AES-128-CBC-HMAC-SHA1 : aes-128-cbc-hmac-sha1
: AES-192-CBC-HMAC-SHA1 : aes-192-cbc-hmac-sha1
: AES-256-CBC-HMAC-SHA1 : aes-256-cbc-hmac-sha1
+
+# DSTU OIDs
+member-body 804 : ISO-UA
+ISO-UA 2 1 1 1 : ua-pki
+ua-pki 1 1 1 : dstu28147 : DSTU Gost 28147-2009
+dstu28147 2 : dstu28147-ofb : DSTU Gost 28147-2009 OFB mode
+dstu28147 3 : dstu28147-cfb : DSTU Gost 28147-2009 CFB mode
+dstu28147 5 : dstu28147-wrap : DSTU Gost 28147-2009 key wrap
+
+ua-pki 1 2 1 : dstu34311 : DSTU Gost 34311-95
+
+ua-pki 1 3 1 1 : dstu4145le : DSTU 4145-2002 little endian
+dstu4145le 1 1 : dstu4145be : DSTU 4145-2002 big endian
+
+# DSTU named curves
+dstu4145le 1 2 0 : uacurve0 : DSTU curve 0
+dstu4145le 1 2 1 : uacurve1 : DSTU curve 1
+dstu4145le 1 2 2 : uacurve2 : DSTU curve 2
+dstu4145le 1 2 3 : uacurve3 : DSTU curve 3
+dstu4145le 1 2 4 : uacurve4 : DSTU curve 4
+dstu4145le 1 2 5 : uacurve5 : DSTU curve 5
+dstu4145le 1 2 6 : uacurve6 : DSTU curve 6
+dstu4145le 1 2 7 : uacurve7 : DSTU curve 7
+dstu4145le 1 2 8 : uacurve8 : DSTU curve 8
+dstu4145le 1 2 9 : uacurve9 : DSTU curve 9
--- openssl-1.0.1e/crypto/objects/obj_xref.txt 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/crypto/objects/obj_xref.txt 2013-12-28 22:04:21.549438415 +0900
@@ -44,3 +44,6 @@
id_GostR3411_94_with_GostR3410_94 id_GostR3411_94 id_GostR3410_94
id_GostR3411_94_with_GostR3410_94_cc id_GostR3411_94 id_GostR3410_94_cc
id_GostR3411_94_with_GostR3410_2001_cc id_GostR3411_94 id_GostR3410_2001_cc
+
+dstu4145le dstu34311 dstu4145le
+dstu4145be dstu34311 dstu4145be
diff -urN openssl-1.0.1e/crypto/x509/x509type.c openssl-1.0.1e.patched/crypto/x509/x509type.c
--- openssl-1.0.1e/crypto/x509/x509type.c 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/crypto/x509/x509type.c 2013-12-28 15:32:08.135101218 +0900
@@ -96,6 +96,9 @@
case NID_id_GostR3410_2001:
ret=EVP_PKT_EXCH|EVP_PKT_SIGN;
break;
+ case NID_dstu4145le:
+ ret=EVP_PKT_SIGN;
+ break;
default:
break;
}
diff -urN openssl-1.0.1e/engines/Makefile openssl-1.0.1e.patched/engines/Makefile
--- openssl-1.0.1e/engines/Makefile 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/engines/Makefile 2013-12-28 15:33:38.699550300 +0900
@@ -9,7 +9,7 @@
CFLAG=-g
MAKEFILE= Makefile
AR= ar r
-ENGDIRS= ccgost
+ENGDIRS= ccgost uadstu
RECURSIVE_MAKE= [ -z "$(ENGDIRS)" ] || for i in $(ENGDIRS) ; do \
(cd $$i && echo "making $$target in $(DIR)/$$i..." && \
@@ -139,6 +139,7 @@
-nostatic -staticloader -write e_$$l.c; \
done
(cd ccgost; $(MAKE) PERL=$(PERL) errors)
+ (cd uadstu; $(MAKE) PERL=$(PERL) errors)
tests:
diff -urN openssl-1.0.1e/engines/uadstu/dstu89.c openssl-1.0.1e.patched/engines/uadstu/dstu89.c
--- openssl-1.0.1e/engines/uadstu/dstu89.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu89.c 2013-12-28 12:56:38.701489000 +0900
@@ -0,0 +1,15 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+/* Probably, this is the most cross-platform way to include gost code
+ * in our engine. If the library is compiled without gost engine or
+ * engines are in separate dynamic libraries then we will have our own
+ * independent copy of the code. If the library is compiled statically
+ * with gost engine then we rely on linker to remove duplicate code */
+#include "../ccgost/gost89.h"
+
+#include "../ccgost/gost89.c"
+
+
diff -urN openssl-1.0.1e/engines/uadstu/dstu_ameth.c openssl-1.0.1e.patched/engines/uadstu/dstu_ameth.c
--- openssl-1.0.1e/engines/uadstu/dstu_ameth.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_ameth.c 2013-12-28 12:56:38.701489000 +0900
@@ -0,0 +1,714 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+#include "dstu_engine.h"
+#include "dstu_asn1.h"
+#include "dstu_key.h"
+#include "dstu_params.h"
+#include <openssl/x509.h>
+#include "dstu_compress.h"
+
+#include "e_dstu_err.h"
+
+static int dstu_asn1_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
+ int derlen)
+ {
+ DSTU_AlgorithmParameters* params = d2i_DSTU_AlgorithmParameters(NULL, pder,
+ derlen);
+ DSTU_KEY* key = NULL;
+ int ret = 0, type;
+ if (!params)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_DECODE, DSTU_R_INVALID_ASN1_PARAMETERS);
+ return 0;
+ }
+
+ type = EVP_PKEY_id(pkey);
+
+ key = key_from_asn1(params, NID_dstu4145le == type);
+ if (!key)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_DECODE, DSTU_R_INVALID_ASN1_PARAMETERS);
+ goto err;
+ }
+
+ if (!EVP_PKEY_assign(pkey, type, key))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_DECODE, ERR_R_EVP_LIB);
+ goto err;
+ }
+
+ key = NULL;
+ ret = 1;
+
+ err: DSTU_AlgorithmParameters_free(params);
+
+ if (key)
+ DSTU_KEY_free(key);
+
+ return ret;
+ }
+
+static int dstu_asn1_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+ {
+ DSTU_AlgorithmParameters* params = NULL;
+ const DSTU_KEY* key = EVP_PKEY_get0((EVP_PKEY *) pkey);
+ int bytes_encoded = 0, type = EVP_PKEY_id(pkey);
+
+ if (!key)
+ return 0;
+
+ params = asn1_from_key(key, NID_dstu4145le == type);
+ if (!params)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_ENCODE,
+ DSTU_R_ASN1_PARAMETER_ENCODE_FAILED);
+ return 0;
+ }
+
+ bytes_encoded = i2d_DSTU_AlgorithmParameters(params, pder);
+
+ DSTU_AlgorithmParameters_free(params);
+
+ return bytes_encoded;
+ }
+
+static int dstu_asn1_param_copy(EVP_PKEY *to, const EVP_PKEY *from)
+ {
+ DSTU_KEY *to_key = EVP_PKEY_get0(to);
+ DSTU_KEY *from_key = EVP_PKEY_get0((EVP_PKEY*) from);
+ const EC_GROUP *from_group;
+
+ if (from_key)
+ {
+ from_group = EC_KEY_get0_group(from_key->ec);
+ if (!from_group)
+ return 0;
+
+ if (!to_key)
+ {
+ to_key = DSTU_KEY_new();
+ if (!EVP_PKEY_assign(to, EVP_PKEY_id(from), to_key))
+ {
+ DSTU_KEY_free(to_key);
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_COPY, ERR_R_EVP_LIB);
+ return 0;
+ }
+ }
+
+ if (!EC_KEY_set_group(to_key->ec, from_group))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_COPY, ERR_R_EC_LIB);
+ return 0;
+ }
+
+ if (from_key->sbox)
+ {
+ to_key->sbox = copy_sbox(from_key->sbox);
+ if (!to_key->sbox)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_COPY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+static int dstu_asn1_param_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+ {
+ DSTU_KEY *first = EVP_PKEY_get0((EVP_PKEY*) a);
+ DSTU_KEY *second = EVP_PKEY_get0((EVP_PKEY*) b);
+
+ if (!first || !second)
+ return -2;
+
+ if (first->sbox != second->sbox)
+ {
+ if (first->sbox && second->sbox)
+ {
+ if (memcmp(first->sbox, second->sbox, sizeof(default_sbox)))
+ return 0;
+ }
+ else
+ return 0;
+ }
+
+ if (EC_GROUP_cmp(EC_KEY_get0_group(first->ec),
+ EC_KEY_get0_group(second->ec), NULL))
+ return 0;
+ else
+ return 1;
+ }
+
+static int dstu_asn1_param_print(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx)
+ {
+ DSTU_KEY *dstu_key = EVP_PKEY_get0((EVP_PKEY*) pkey);
+ EVP_PKEY *pk;
+ int ret;
+
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, dstu_key->ec))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PARAM_PRINT, ERR_R_EVP_LIB);
+ return 0;
+ }
+
+ ret = EVP_PKEY_print_params(out, pk, indent, NULL);
+
+ EVP_PKEY_free(pk);
+ return ret;
+ }
+
+static int dstu_asn1_priv_decode(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8)
+ {
+ ASN1_OBJECT* algoid = NULL;
+ X509_ALGOR* alg = NULL;
+ const unsigned char* prk_encoded = NULL;
+ unsigned char* params_encoded = NULL;
+ ASN1_STRING* params = NULL;
+ DSTU_KEY* key = NULL;
+ BIGNUM* prk = NULL;
+ ASN1_INTEGER* asn1key = NULL;
+ int prk_encoded_bytes = 0, params_type = 0, algnid;
+
+ if (!PKCS8_pkey_get0(&algoid, &prk_encoded, &prk_encoded_bytes, &alg, p8))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_X509_LIB);
+ return 0;
+ }
+
+ algnid = OBJ_obj2nid(algoid);
+
+ if ((algnid == NID_dstu4145le) || (algnid == NID_dstu4145be))
+ {
+ if (!EVP_PKEY_set_type(pk, algnid))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_EVP_LIB);
+ return 0;
+ }
+ }
+ else
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ X509_ALGOR_get0(NULL, &params_type, (void**) &params, alg);
+ if (V_ASN1_SEQUENCE != params_type)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_EXPECTING_AN_ASN1_SEQUENCE);
+ return 0;
+ }
+
+ params_encoded = ASN1_STRING_data(params);
+ if (!params_encoded)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ if (!dstu_asn1_param_decode(pk, (const unsigned char**) &params_encoded,
+ ASN1_STRING_length(params)))
+ return 0;
+
+ asn1key = d2i_ASN1_INTEGER(NULL, &prk_encoded, prk_encoded_bytes);
+ if (!asn1key)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_ASN1_LIB);
+ return 0;
+ }
+ prk = ASN1_INTEGER_to_BN(asn1key, NULL);
+ if (!prk)
+ {
+ ASN1_INTEGER_free(asn1key);
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_ASN1_LIB);
+ return 0;
+ }
+
+ key = EVP_PKEY_get0((EVP_PKEY*) pk);
+ if (!EC_KEY_set_private_key(key->ec, prk))
+ {
+ BN_free(prk);
+ ASN1_INTEGER_free(asn1key);
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_EC_LIB);
+ return 0;
+ }
+
+ if (!dstu_add_public_key(key->ec))
+ {
+ BN_free(prk);
+ ASN1_INTEGER_free(asn1key);
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_EC_LIB);
+ return 0;
+ }
+
+ BN_free(prk);
+ ASN1_INTEGER_free(asn1key);
+
+ return 1;
+ }
+
+static int dstu_asn1_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
+ {
+ unsigned char* encoded_params = NULL;
+ int encoded_params_bytes = 0;
+ ASN1_INTEGER* asn1key = NULL;
+ unsigned char* prk_encoded = NULL;
+ int prk_encoded_bytes = 0;
+ int ret = 0, algnid = EVP_PKEY_id(pk);
+ DSTU_KEY* key;
+ const BIGNUM *d;
+ ASN1_STRING *params;
+
+ if ((algnid != NID_dstu4145le) && (algnid != NID_dstu4145be))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ params = ASN1_STRING_type_new(V_ASN1_SEQUENCE);
+ if (!params)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, ERR_R_ASN1_LIB);
+ return 0;
+ }
+
+ encoded_params_bytes = dstu_asn1_param_encode(pk, &encoded_params);
+ if (!encoded_params_bytes)
+ goto err;
+
+ key = EVP_PKEY_get0((EVP_PKEY*) pk);
+ if (!key)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, DSTU_R_NOT_DSTU_KEY);
+ goto err;
+ }
+
+ d = EC_KEY_get0_private_key(key->ec);
+ if (!d)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, DSTU_R_NOT_DSTU_KEY);
+ goto err;
+ }
+
+ asn1key = BN_to_ASN1_INTEGER(d, NULL);
+ if (!asn1key)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ prk_encoded_bytes = i2d_ASN1_INTEGER(asn1key, &prk_encoded);
+ if (!prk_encoded)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ ASN1_STRING_set0(params, encoded_params, encoded_params_bytes);
+
+ if (PKCS8_pkey_set0(p8, OBJ_nid2obj(algnid), 0, V_ASN1_SEQUENCE, params,
+ prk_encoded, prk_encoded_bytes))
+ {
+ prk_encoded = NULL;
+ params = NULL;
+ ret = 1;
+ }
+ else
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, ERR_R_ASN1_LIB);
+ }
+
+ err: if (prk_encoded)
+ OPENSSL_free(prk_encoded);
+ if (asn1key)
+ ASN1_INTEGER_free(asn1key);
+ if (params)
+ ASN1_STRING_free(params);
+
+ return ret;
+ }
+
+static int dstu_asn1_pkey_bits(const EVP_PKEY *pk)
+ {
+ DSTU_KEY* key = EVP_PKEY_get0((EVP_PKEY *) pk);
+ const EC_GROUP* group;
+
+ if (key)
+ {
+ group = EC_KEY_get0_group(key->ec);
+ if (group)
+ return EC_GROUP_get_degree(group);
+ }
+ return 0;
+ }
+
+static int dstu_asn1_pkey_size(const EVP_PKEY *pk)
+ {
+ return ASN1_object_size(0, ((dstu_asn1_pkey_bits(pk) + 7) / 8) * 2,
+ V_ASN1_OCTET_STRING);
+ }
+
+void dstu_asn1_pkey_free(EVP_PKEY *pkey)
+ {
+ DSTU_KEY* key = EVP_PKEY_get0(pkey);
+
+ if (key)
+ DSTU_KEY_free(key);
+ }
+
+static int dstu_asn1_pub_decode(EVP_PKEY *pk, X509_PUBKEY *pub)
+ {
+ ASN1_OBJECT* algoid = NULL;
+ const unsigned char *pbk_buf = NULL;
+ unsigned char *compressed = NULL;
+ int pbk_buf_len, param_type, algnid;
+ unsigned char *params_encoded = NULL, *public_key_data;
+ ASN1_STRING* params = NULL;
+ ASN1_OCTET_STRING* public_key = NULL;
+ X509_ALGOR* algid;
+ DSTU_KEY* key = NULL;
+ EC_POINT* point = NULL;
+ int ret = 0;
+
+ if (!X509_PUBKEY_get0_param(&algoid, &pbk_buf, &pbk_buf_len, &algid, pub))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, ERR_R_X509_LIB);
+ return 0;
+ }
+
+ X509_ALGOR_get0(&algoid, &param_type, (void**) &params, algid);
+ if (V_ASN1_SEQUENCE != param_type)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, ERR_R_EXPECTING_AN_ASN1_SEQUENCE);
+ return 0;
+ }
+
+ algnid = OBJ_obj2nid(algoid);
+
+ if ((algnid == NID_dstu4145le) || (algnid == NID_dstu4145be))
+ {
+ if (!EVP_PKEY_set_type(pk, algnid))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, ERR_R_EVP_LIB);
+ return 0;
+ }
+ }
+ else
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ params_encoded = ASN1_STRING_data(params);
+ if (!params_encoded)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ if (!dstu_asn1_param_decode(pk, (const unsigned char**) &params_encoded,
+ ASN1_STRING_length(params)))
+ return 0;
+
+ key = EVP_PKEY_get0(pk);
+ if (!key)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ point = EC_POINT_new(EC_KEY_get0_group(key->ec));
+ if (!point)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, ERR_R_EC_LIB);
+ return 0;
+ }
+
+ public_key_data = ASN1_STRING_data(pub->public_key);
+ if (!d2i_ASN1_OCTET_STRING(&public_key,
+ (const unsigned char **) &public_key_data,
+ ASN1_STRING_length(pub->public_key)))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ if (algnid == NID_dstu4145le)
+ {
+ compressed = OPENSSL_malloc(ASN1_STRING_length(public_key));
+ if (!compressed)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ reverse_bytes_copy(compressed, ASN1_STRING_data(public_key),
+ ASN1_STRING_length(public_key));
+ if (!dstu_point_expand(compressed, ASN1_STRING_length(public_key),
+ EC_KEY_get0_group(key->ec), point))
+ {
+ OPENSSL_free(compressed);
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE,
+ DSTU_R_POINT_UNCOMPRESS_FAILED);
+ goto err;
+ }
+ OPENSSL_free(compressed);
+ }
+ else
+ {
+ if (!dstu_point_expand(ASN1_STRING_data(public_key),
+ ASN1_STRING_length(public_key), EC_KEY_get0_group(key->ec),
+ point))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE,
+ DSTU_R_POINT_UNCOMPRESS_FAILED);
+ goto err;
+ }
+ }
+
+ if (EC_KEY_set_public_key(key->ec, point))
+ ret = 1;
+
+ err: if (public_key)
+ ASN1_OCTET_STRING_free(public_key);
+
+ if (point)
+ EC_POINT_free(point);
+
+ return ret;
+ }
+
+static int dstu_asn1_pub_encode(X509_PUBKEY *pub, const EVP_PKEY *pk)
+ {
+ unsigned char *compressed = NULL, *pbk_encoded = NULL;
+ ASN1_OCTET_STRING* public_key = NULL;
+ int ret = 0, algnid = EVP_PKEY_id(pk), field_size, pbk_encoded_bytes;
+ DSTU_KEY* key;
+ const EC_GROUP* group;
+ ASN1_STRING *params;
+ const EC_POINT* point = NULL;
+
+ if ((algnid != NID_dstu4145le) && (algnid != NID_dstu4145be))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ params = ASN1_STRING_type_new(V_ASN1_SEQUENCE);
+ if (!params)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, ERR_R_ASN1_LIB);
+ return 0;
+ }
+
+ params->length = dstu_asn1_param_encode(pk, &(params->data));
+ if (params->length <= 0)
+ goto err;
+
+ key = EVP_PKEY_get0((EVP_PKEY*) pk);
+ if (!key)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, DSTU_R_NOT_DSTU_KEY);
+ goto err;
+ }
+
+ group = EC_KEY_get0_group(key->ec);
+ if (!group)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ field_size = (EC_GROUP_get_degree(group) + 7) / 8;
+
+ point = EC_KEY_get0_public_key(key->ec);
+ if (!point)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, DSTU_R_NOT_DSTU_KEY);
+ goto err;
+ }
+
+ compressed = OPENSSL_malloc(field_size);
+ if (!compressed)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!dstu_point_compress(group, point, compressed, field_size))
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, DSTU_R_POINT_COMPRESS_FAILED);
+ goto err;
+ }
+
+ if (algnid == NID_dstu4145le)
+ reverse_bytes(compressed, field_size);
+
+ public_key = ASN1_OCTET_STRING_new();
+ if (!public_key)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ ASN1_STRING_set0((ASN1_STRING*) public_key, compressed, field_size);
+ compressed = NULL;
+
+ pbk_encoded_bytes = i2d_ASN1_OCTET_STRING(public_key, &pbk_encoded);
+ if (!pbk_encoded)
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ if (X509_PUBKEY_set0_param(pub, OBJ_nid2obj(algnid), V_ASN1_SEQUENCE,
+ params, pbk_encoded, pbk_encoded_bytes))
+ {
+ pbk_encoded = NULL;
+ params = NULL;
+ ret = 1;
+ }
+ else
+ {
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_ENCODE, ERR_R_X509_LIB);
+ }
+
+ err: if (pbk_encoded)
+ OPENSSL_free(pbk_encoded);
+
+ if (public_key)
+ ASN1_OCTET_STRING_free(public_key);
+
+ if (compressed)
+ OPENSSL_free(compressed);
+
+ if (params)
+ ASN1_STRING_free(params);
+
+ return ret;
+ }
+
+static int dstu_asn1_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+ {
+ DSTU_KEY *first = EVP_PKEY_get0((EVP_PKEY*) a);
+ DSTU_KEY *second = EVP_PKEY_get0((EVP_PKEY*) b);
+
+ if (!first || !second)
+ return -2;
+
+ /* We do not compare sboxes here because it will be done in params_cmp by EVP API */
+
+ if (EC_POINT_cmp(EC_KEY_get0_group(first->ec),
+ EC_KEY_get0_public_key(first->ec),
+ EC_KEY_get0_public_key(second->ec), NULL))
+ return 0;
+ else
+ return 1;
+ }
+
+static int dstu_asn1_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+ {
+ switch (op)
+ {
+ case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+ *((int *) arg2) = NID_dstu34311;
+ return 2;
+ }
+
+ return 0;
+ }
+
+static int dstu_asn1_priv_print(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx)
+ {
+ /* Reusing basic EC keys printing */
+ DSTU_KEY *dstu_key = EVP_PKEY_get0((EVP_PKEY*) pkey);
+ EVP_PKEY *pk;
+ int ret;
+
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, dstu_key->ec))
+ return 0;
+
+ ret = EVP_PKEY_print_private(out, pk, indent, pctx);
+
+ EVP_PKEY_free(pk);
+ return ret;
+ }
+
+static int dstu_asn1_pub_print(BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx)
+ {
+ /* Reusing basic EC keys printing */
+ DSTU_KEY *dstu_key = EVP_PKEY_get0((EVP_PKEY*) pkey);
+ EVP_PKEY *pk;
+ int ret;
+
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, dstu_key->ec))
+ return 0;
+
+ ret = EVP_PKEY_print_public(out, pk, indent, pctx);
+
+ EVP_PKEY_free(pk);
+ return ret;
+ }
+
+EVP_PKEY_ASN1_METHOD *dstu_asn1_meth_le = NULL, *dstu_asn1_meth_be = NULL;
+
+int dstu_asn1_meth_init(void)
+ {
+ dstu_asn1_meth_le = EVP_PKEY_asn1_new(NID_dstu4145le, 0, SN_dstu4145le,
+ LN_dstu4145le);
+ if (!dstu_asn1_meth_le)
+ return 0;
+
+ dstu_asn1_meth_be = EVP_PKEY_asn1_new(NID_dstu4145be, 0, SN_dstu4145be,
+ LN_dstu4145be);
+ if (!dstu_asn1_meth_be)
+ {
+ EVP_PKEY_asn1_free(dstu_asn1_meth_le);
+ dstu_asn1_meth_le = NULL;
+ return 0;
+ }
+
+ EVP_PKEY_asn1_set_param(dstu_asn1_meth_le, dstu_asn1_param_decode,
+ dstu_asn1_param_encode, /*dstu_asn1_param_missing*/NULL,
+ dstu_asn1_param_copy, dstu_asn1_param_cmp, dstu_asn1_param_print);
+ EVP_PKEY_asn1_set_private(dstu_asn1_meth_le, dstu_asn1_priv_decode,
+ dstu_asn1_priv_encode, dstu_asn1_priv_print);
+ EVP_PKEY_asn1_set_public(dstu_asn1_meth_le, dstu_asn1_pub_decode,
+ dstu_asn1_pub_encode, dstu_asn1_pub_cmp, dstu_asn1_pub_print,
+ dstu_asn1_pkey_size, dstu_asn1_pkey_bits);
+ EVP_PKEY_asn1_set_free(dstu_asn1_meth_le, dstu_asn1_pkey_free);
+ EVP_PKEY_asn1_set_ctrl(dstu_asn1_meth_le, dstu_asn1_pkey_ctrl);
+
+ EVP_PKEY_asn1_set_param(dstu_asn1_meth_be, dstu_asn1_param_decode,
+ dstu_asn1_param_encode, /*dstu_asn1_param_missing*/NULL,
+ dstu_asn1_param_copy, dstu_asn1_param_cmp, dstu_asn1_param_print);
+ EVP_PKEY_asn1_set_private(dstu_asn1_meth_be, dstu_asn1_priv_decode,
+ dstu_asn1_priv_encode, dstu_asn1_priv_print);
+ EVP_PKEY_asn1_set_public(dstu_asn1_meth_be, dstu_asn1_pub_decode,
+ dstu_asn1_pub_encode, dstu_asn1_pub_cmp, dstu_asn1_pub_print,
+ dstu_asn1_pkey_size, dstu_asn1_pkey_bits);
+ EVP_PKEY_asn1_set_free(dstu_asn1_meth_be, dstu_asn1_pkey_free);
+ EVP_PKEY_asn1_set_ctrl(dstu_asn1_meth_be, dstu_asn1_pkey_ctrl);
+
+ return 1;
+ }
+
+void dstu_asn1_meth_finish(void)
+ {
+ if (dstu_asn1_meth_le)
+ EVP_PKEY_asn1_free(dstu_asn1_meth_le);
+
+ if (dstu_asn1_meth_be)
+ EVP_PKEY_asn1_free(dstu_asn1_meth_be);
+ }
diff -urN openssl-1.0.1e/engines/uadstu/dstu_asn1.c openssl-1.0.1e.patched/engines/uadstu/dstu_asn1.c
--- openssl-1.0.1e/engines/uadstu/dstu_asn1.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_asn1.c 2013-12-28 12:56:38.701489000 +0900
@@ -0,0 +1,58 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+#include "dstu_engine.h"
+#include "dstu_asn1.h"
+
+ASN1_SEQUENCE(DSTU_Pentanomial) =
+ {
+ ASN1_SIMPLE(DSTU_Pentanomial, k, ASN1_INTEGER),
+ ASN1_SIMPLE(DSTU_Pentanomial, j, ASN1_INTEGER),
+ ASN1_SIMPLE(DSTU_Pentanomial, l, ASN1_INTEGER)
+ }ASN1_SEQUENCE_END(DSTU_Pentanomial)
+
+IMPLEMENT_ASN1_FUNCTIONS(DSTU_Pentanomial)
+
+ASN1_CHOICE(DSTU_Polynomial) =
+ {
+ ASN1_SIMPLE(DSTU_Polynomial, poly.k, ASN1_INTEGER),
+ ASN1_SIMPLE(DSTU_Polynomial, poly.pentanomial, DSTU_Pentanomial)
+ }ASN1_CHOICE_END(DSTU_Polynomial)
+
+IMPLEMENT_ASN1_FUNCTIONS(DSTU_Polynomial)
+
+ASN1_SEQUENCE(DSTU_BinaryField) =
+ {
+ ASN1_SIMPLE(DSTU_BinaryField, m, ASN1_INTEGER),
+ ASN1_SIMPLE(DSTU_BinaryField, poly, DSTU_Polynomial)
+ }ASN1_SEQUENCE_END(DSTU_BinaryField)
+
+IMPLEMENT_ASN1_FUNCTIONS(DSTU_BinaryField)
+
+ASN1_SEQUENCE(DSTU_CustomCurveSpec) =
+ {
+ ASN1_SIMPLE(DSTU_CustomCurveSpec, field, DSTU_BinaryField),
+ ASN1_SIMPLE(DSTU_CustomCurveSpec, a, ASN1_INTEGER),
+ ASN1_SIMPLE(DSTU_CustomCurveSpec, b, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(DSTU_CustomCurveSpec, n, ASN1_INTEGER),
+ ASN1_SIMPLE(DSTU_CustomCurveSpec, bp, ASN1_OCTET_STRING)
+ }ASN1_SEQUENCE_END(DSTU_CustomCurveSpec)
+
+IMPLEMENT_ASN1_FUNCTIONS(DSTU_CustomCurveSpec)
+
+ASN1_CHOICE(DSTU_CurveSpec) =
+ {
+ ASN1_SIMPLE(DSTU_CurveSpec, curve.named_curve, ASN1_OBJECT),
+ ASN1_SIMPLE(DSTU_CurveSpec, curve.custom_curve, DSTU_CustomCurveSpec)
+ }ASN1_CHOICE_END(DSTU_CurveSpec)
+
+IMPLEMENT_ASN1_FUNCTIONS(DSTU_CurveSpec)
+
+ASN1_SEQUENCE(DSTU_AlgorithmParameters) =
+ {
+ ASN1_SIMPLE(DSTU_AlgorithmParameters, curve, DSTU_CurveSpec),
+ ASN1_OPT(DSTU_AlgorithmParameters, sbox, ASN1_OCTET_STRING)
+ }ASN1_SEQUENCE_END(DSTU_AlgorithmParameters)
+
+IMPLEMENT_ASN1_FUNCTIONS(DSTU_AlgorithmParameters)
diff -urN openssl-1.0.1e/engines/uadstu/dstu_asn1.h openssl-1.0.1e.patched/engines/uadstu/dstu_asn1.h
--- openssl-1.0.1e/engines/uadstu/dstu_asn1.h 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_asn1.h 2013-12-28 12:56:38.701489000 +0900
@@ -0,0 +1,81 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#ifndef DSTU_ASN1_H_
+#define DSTU_ASN1_H_
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+typedef struct DSTU_Pentanomial_st
+ {
+ ASN1_INTEGER* k;
+ ASN1_INTEGER* j;
+ ASN1_INTEGER* l;
+ } DSTU_Pentanomial;
+
+DECLARE_ASN1_FUNCTIONS(DSTU_Pentanomial)
+
+typedef struct DSTU_Polynomial_st
+ {
+
+#define DSTU_TRINOMIAL 0
+#define DSTU_PENTANOMIAL 1
+
+ int type;
+ union
+ {
+ ASN1_INTEGER* k;
+ DSTU_Pentanomial* pentanomial;
+ } poly;
+ } DSTU_Polynomial;
+
+DECLARE_ASN1_FUNCTIONS(DSTU_Polynomial)
+
+typedef struct DSTU_BinaryField_st
+ {
+ ASN1_INTEGER* m;
+ DSTU_Polynomial* poly;
+ } DSTU_BinaryField;
+
+DECLARE_ASN1_FUNCTIONS(DSTU_BinaryField)
+
+typedef struct DSTU_CustomCurveSpec_st
+ {
+ DSTU_BinaryField* field;
+ ASN1_INTEGER* a;
+ ASN1_OCTET_STRING* b;
+ ASN1_INTEGER* n;
+ ASN1_OCTET_STRING* bp;
+ } DSTU_CustomCurveSpec;
+
+DECLARE_ASN1_FUNCTIONS(DSTU_CustomCurveSpec)
+
+typedef struct DSTU_CurveSpec_st
+ {
+
+#define DSTU_STANDARD_CURVE 0
+#define DSTU_CUSTOM_CURVE 1
+
+ int type;
+ union
+ {
+ ASN1_OBJECT* named_curve;
+ DSTU_CustomCurveSpec* custom_curve;
+ } curve;
+
+ } DSTU_CurveSpec;
+
+DECLARE_ASN1_FUNCTIONS(DSTU_CurveSpec)
+
+typedef struct DSTU_AlgorithmParameters_st
+ {
+ DSTU_CurveSpec* curve;
+ ASN1_OCTET_STRING* sbox;
+ } DSTU_AlgorithmParameters;
+
+DECLARE_ASN1_FUNCTIONS(DSTU_AlgorithmParameters)
+
+#endif /* DSTU_ASN1_H_ */
diff -urN openssl-1.0.1e/engines/uadstu/dstu_cipher.c openssl-1.0.1e.patched/engines/uadstu/dstu_cipher.c
--- openssl-1.0.1e/engines/uadstu/dstu_cipher.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_cipher.c 2013-12-28 12:56:38.701489000 +0900
@@ -0,0 +1,171 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_engine.h"
+#include "dstu_params.h"
+#include "../ccgost/gost89.h"
+
+/* DSTU uses Russian GOST 28147 but with different s-boxes and no key meshing */
+/* We implement CFB mode here because it is mostly used */
+
+#define DSTU_CIPHER_BLOCK_SIZE 8
+
+static int dstu_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ gost_subst_block sbox;
+ gost_ctx* gctx = ctx->cipher_data;
+
+ unpack_sbox(default_sbox, &sbox);
+ gost_init(gctx, &sbox);
+
+ if (key)
+ gost_key(gctx, key);
+
+ if (iv)
+ {
+ memcpy(ctx->oiv, iv, DSTU_CIPHER_BLOCK_SIZE);
+ memcpy(ctx->iv, iv, DSTU_CIPHER_BLOCK_SIZE);
+ gostcrypt(gctx, ctx->iv, ctx->buf);
+ ctx->num = 0;
+ }
+
+ return 1;
+ }
+
+static int dstu_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+ {
+ size_t to_use, i, blocks;
+ gost_ctx* gctx = ctx->cipher_data;
+ unsigned char tmpiv[DSTU_CIPHER_BLOCK_SIZE], *out_start = out;
+
+ if ((!inl) && (!in))
+ return 0;
+
+ if ((!inl) || (!in))
+ return -1;
+
+ if (ctx->num)
+ {
+ to_use = (ctx->num < inl) ? ctx->num : inl;
+
+ for (i = 0; i < to_use; i++)
+ {
+ if (ctx->encrypt)
+ {
+ *out = *in ^ ctx->buf[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i];
+ ctx->iv[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i] = *out;
+ }
+ else
+ {
+ ctx->iv[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i] = *in;
+ *out = *in ^ ctx->buf[DSTU_CIPHER_BLOCK_SIZE - ctx->num + i];
+ }
+ in++;
+ out++;
+ }
+
+ ctx->num -= to_use;
+ inl -= to_use;
+
+ if (!ctx->num)
+ gostcrypt(gctx, ctx->iv, ctx->buf);
+ }
+
+ if (inl)
+ {
+ blocks = inl >> 3;
+
+ if (blocks)
+ {
+ if (ctx->encrypt)
+ {
+ gost_enc_cfb(gctx, ctx->iv, in, out, blocks);
+ memcpy(ctx->iv, out + (blocks * DSTU_CIPHER_BLOCK_SIZE)- DSTU_CIPHER_BLOCK_SIZE,
+ DSTU_CIPHER_BLOCK_SIZE);
+ }
+ else
+ {
+ memcpy(tmpiv, ctx->iv, DSTU_CIPHER_BLOCK_SIZE);
+ memcpy(ctx->iv, in + (blocks * DSTU_CIPHER_BLOCK_SIZE)- DSTU_CIPHER_BLOCK_SIZE,
+ DSTU_CIPHER_BLOCK_SIZE);
+ gost_dec_cfb(gctx, tmpiv, in, out, blocks);
+ }
+ gostcrypt(gctx, ctx->iv, ctx->buf);
+
+ out += blocks * DSTU_CIPHER_BLOCK_SIZE;
+ in += blocks * DSTU_CIPHER_BLOCK_SIZE;
+ inl -= blocks * DSTU_CIPHER_BLOCK_SIZE;
+ }
+ }
+
+ if (inl)
+ {
+ for (i = 0; i < inl; i++)
+ {
+ if (ctx->encrypt)
+ {
+ *out = *in ^ ctx->buf[i];
+ ctx->iv[i] = *out;
+ }
+ else
+ {
+ ctx->iv[i] = *in;
+ *out = *in ^ ctx->buf[i];
+ }
+ in++;
+ out++;
+ }
+
+ ctx->num = DSTU_CIPHER_BLOCK_SIZE - inl;
+ }
+
+ return out - out_start;
+ }
+
+static int dstu_cipher_cleanup(EVP_CIPHER_CTX *ctx)
+ {
+ return 1;
+ }
+
+static int dstu_cipher_ctrl(EVP_CIPHER_CTX *ctx, int cmd, int p1, void *p2)
+ {
+ gost_subst_block sbox;
+ gost_ctx* gctx = ctx->cipher_data;
+
+ switch (cmd)
+ {
+ case DSTU_SET_CUSTOM_SBOX:
+ if ((!p2) || (sizeof(default_sbox) != p1))
+ return 0;
+ unpack_sbox((unsigned char *) p2, &sbox);
+ gost_init(gctx, &sbox);
+ memcpy(ctx->iv, ctx->oiv, DSTU_CIPHER_BLOCK_SIZE);
+ gostcrypt(gctx, ctx->iv, ctx->buf);
+ return 1;
+ }
+
+ return 0;
+ }
+
+EVP_CIPHER dstu_cipher =
+ {
+ NID_dstu28147_cfb,
+ 1,
+ 32,
+ DSTU_CIPHER_BLOCK_SIZE,
+ EVP_CIPH_CFB_MODE | EVP_CIPH_NO_PADDING | EVP_CIPH_CUSTOM_IV
+ | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT,
+ dstu_cipher_init,
+ dstu_cipher_do_cipher,
+ dstu_cipher_cleanup,
+ sizeof(gost_ctx),
+ NULL,
+ NULL,
+ dstu_cipher_ctrl,
+ NULL
+ };
+
diff -urN openssl-1.0.1e/engines/uadstu/dstu_compress.c openssl-1.0.1e.patched/engines/uadstu/dstu_compress.c
--- openssl-1.0.1e/engines/uadstu/dstu_compress.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_compress.c 2013-12-28 12:56:38.701489000 +0900
@@ -0,0 +1,213 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_compress.h"
+#include "dstu_params.h"
+#include <string.h>
+
+static int bn_trace(const BIGNUM* bn, const BIGNUM* p, BN_CTX* ctx)
+ {
+ BIGNUM* r = NULL;
+ int res = -1, i;
+
+ BN_CTX_start(ctx);
+
+ r = BN_CTX_get(ctx);
+
+ if (!BN_copy(r, bn))
+ goto err;
+ for (i = 1; i <= (BN_num_bits(p) - 2); i++)
+ {
+ if (!BN_GF2m_mod_sqr(r, r, p, ctx))
+ goto err;
+ if (!BN_GF2m_add(r, r, bn))
+ goto err;
+ }
+
+ if (BN_is_one(r))
+ res = 1;
+ else if (BN_is_zero(r))
+ res = 0;
+
+ err:
+
+ BN_CTX_end(ctx);
+ return res;
+ }
+
+int dstu_point_compress(const EC_GROUP* group, const EC_POINT* point,
+ unsigned char* compressed, int compressed_length)
+ {
+ int field_size, res = 0, trace;
+ BN_CTX* ctx;
+ BIGNUM *p, *x_inv, *x, *y;
+
+ field_size = (EC_GROUP_get_degree(group) + 7) / 8;
+ if (compressed_length < field_size)
+ return 0;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ return 0;
+
+ BN_CTX_start(ctx);
+ p = BN_CTX_get(ctx);
+ x_inv = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+
+ if (!y)
+ goto err;
+
+ if (!EC_GROUP_get_curve_GF2m(group, p, NULL, NULL, ctx))
+ goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
+ goto err;
+
+ if (BN_is_zero(x))
+ {
+ memset(compressed, 0, field_size);
+ res = 1;
+ goto err;
+ }
+
+ if (!BN_GF2m_mod_inv(x_inv, x, p, ctx))
+ goto err;
+
+ if (!BN_GF2m_mod_mul(y, y, x_inv, p, ctx))
+ goto err;
+
+ trace = bn_trace(y, p, ctx);
+ if (-1 == trace)
+ goto err;
+
+ if (trace)
+ {
+ if (!BN_set_bit(x, 0))
+ goto err;
+ }
+ else
+ {
+ if (!BN_clear_bit(x, 0))
+ goto err;
+ }
+
+ if (bn_encode(x, compressed, field_size))
+ res = 1;
+
+ err: if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return res;
+ }
+
+int dstu_point_expand(const unsigned char* compressed, int compressed_length,
+ const EC_GROUP* group, EC_POINT* point)
+ {
+ int field_size, res = 0, trace, k;
+ BN_CTX* ctx;
+ BIGNUM *p, *a, *b, *x2, *x, *y;
+
+ field_size = (EC_GROUP_get_degree(group) + 7) / 8;
+ if (compressed_length < field_size)
+ return 0;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ return 0;
+
+ BN_CTX_start(ctx);
+ p = BN_CTX_get(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ x2 = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+
+ if (!y)
+ goto err;
+
+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx))
+ goto err;
+
+ if (!BN_bin2bn(compressed, compressed_length, x))
+ goto err;
+
+ if (BN_is_zero(x))
+ {
+ if (!BN_GF2m_mod_sqrt(y, b, p, ctx))
+ goto err;
+
+ if (EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
+ res = 1;
+
+ goto err;
+ }
+
+ k = BN_is_bit_set(x, 0);
+
+ if (!BN_clear_bit(x, 0))
+ goto err;
+
+ trace = bn_trace(x, p, ctx);
+ if (-1 == trace)
+ goto err;
+
+ if ((trace && BN_is_zero(a)) || ((!trace) && BN_is_one(a)))
+ {
+ if (!BN_set_bit(x, 0))
+ goto err;
+ }
+
+ if (!BN_GF2m_mod_sqr(x2, x, p, ctx))
+ goto err;
+
+ if (!BN_GF2m_mod_mul(y, x2, x, p, ctx))
+ goto err;
+
+ if (BN_is_one(a))
+ {
+ if (!BN_GF2m_add(y, y, x2))
+ goto err;
+ }
+
+ if (!BN_GF2m_add(y, y, b))
+ goto err;
+
+ if (!BN_GF2m_mod_inv(x2, x2, p, ctx))
+ goto err;
+
+ if (!BN_GF2m_mod_mul(y, y, x2, p, ctx))
+ goto err;
+
+ if (!BN_GF2m_mod_solve_quad(y, y, p, ctx))
+ goto err;
+
+ trace = bn_trace(y, p, ctx);
+
+ if ((k && !trace) || (!k && trace))
+ {
+ if (!BN_GF2m_add(y, y, BN_value_one()))
+ goto err;
+ }
+
+ if (!BN_GF2m_mod_mul(y, y, x, p, ctx))
+ goto err;
+
+ if (EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
+ res = 1;
+
+ err:
+
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return res;
+ }
diff -urN openssl-1.0.1e/engines/uadstu/dstu_compress.h openssl-1.0.1e.patched/engines/uadstu/dstu_compress.h
--- openssl-1.0.1e/engines/uadstu/dstu_compress.h 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_compress.h 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1,16 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#ifndef DSTU_COMPRESS_H_
+#define DSTU_COMPRESS_H_
+
+#include <openssl/ec.h>
+
+int dstu_point_compress(const EC_GROUP* group, const EC_POINT* point,
+ unsigned char* compressed, int compressed_length);
+int dstu_point_expand(const unsigned char* compressed, int compressed_length,
+ const EC_GROUP* group, EC_POINT* point);
+
+#endif /* DSTU_COMPRESS_H_ */
diff -urN openssl-1.0.1e/engines/uadstu/dstu.ec openssl-1.0.1e.patched/engines/uadstu/dstu.ec
--- openssl-1.0.1e/engines/uadstu/dstu.ec 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu.ec 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1 @@
+L DSTU e_dstu_err.h e_dstu_err.c
diff -urN openssl-1.0.1e/engines/uadstu/dstu_engine.c openssl-1.0.1e.patched/engines/uadstu/dstu_engine.c
--- openssl-1.0.1e/engines/uadstu/dstu_engine.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_engine.c 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1,285 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_engine.h"
+#include "dstu_params.h"
+#include <openssl/objects.h>
+
+#include "e_dstu_err.h"
+
+static const char *engine_dstu_id = "dstu";
+static const char *engine_dstu_name = "Reference implementation of DSTU engine";
+
+static int dstu_nids[] =
+ {
+ NID_dstu4145le, NID_dstu4145be
+ };
+static int digest_nids[] =
+ {
+ NID_dstu34311
+ };
+static int cipher_nids[] =
+ {
+ NID_dstu28147_cfb
+ };
+
+static const int DSTU_ENGINE_FLAGS = ENGINE_METHOD_PKEY_METHS
+ | ENGINE_METHOD_PKEY_ASN1_METHS | ENGINE_METHOD_DIGESTS
+ | ENGINE_METHOD_CIPHERS | ENGINE_METHOD_RAND;
+
+static int dstu_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids,
+ int nid)
+ {
+ if (!pmeth)
+ {
+ *nids = dstu_nids;
+ return sizeof(dstu_nids) / sizeof(int);
+ }
+
+ if (dstu_nids[0] == nid)
+ {
+ *pmeth = dstu_pkey_meth_le;
+ return 1;
+ }
+
+ if (dstu_nids[1] == nid)
+ {
+ *pmeth = dstu_pkey_meth_be;
+ return 1;
+ }
+
+ *pmeth = NULL;
+ return 0;
+ }
+
+static int dstu_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
+ const int **nids, int nid)
+ {
+ if (!ameth)
+ {
+ *nids = dstu_nids;
+ return sizeof(dstu_nids) / sizeof(int);
+ }
+
+ if (dstu_nids[0] == nid)
+ {
+ *ameth = dstu_asn1_meth_le;
+ return 1;
+ }
+
+ if (dstu_nids[1] == nid)
+ {
+ *ameth = dstu_asn1_meth_be;
+ return 1;
+ }
+
+ *ameth = NULL;
+ return 0;
+ }
+
+static int dstu_engine_init(ENGINE *e)
+ {
+ return 1;
+ }
+
+static int dstu_engine_finish(ENGINE *e)
+ {
+ return 1;
+ }
+
+static int dstu_digests(ENGINE *e, const EVP_MD **digest, const int **nids,
+ int nid)
+ {
+ if (digest && nid)
+ {
+ if (NID_dstu34311 == nid)
+ {
+ *digest = &dstu_md;
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ if (!nids)
+ return -1;
+ *nids = digest_nids;
+ return 1;
+ }
+ }
+
+static int dstu_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids,
+ int nid)
+ {
+ if (cipher && nid)
+ {
+ if (NID_dstu28147_cfb == nid)
+ {
+ *cipher = &dstu_cipher;
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ if (!nids)
+ return -1;
+ *nids = cipher_nids;
+ return 1;
+ }
+ }
+
+static int bind_dstu(ENGINE *e, const char *id)
+ {
+ if (id && strcmp(id, engine_dstu_id))
+ return 0;
+
+ if (!ENGINE_set_id(e, engine_dstu_id))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+ if (!ENGINE_set_name(e, engine_dstu_name))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+
+ if (!ENGINE_set_init_function(e, dstu_engine_init))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+ if (!ENGINE_set_finish_function(e, dstu_engine_finish))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+ if (!ENGINE_set_digests(e, dstu_digests))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+ if (!ENGINE_set_ciphers(e, dstu_ciphers))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+ if (!ENGINE_set_RAND(e, &dstu_rand_meth))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+ if (!dstu_pkey_meth_init())
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, DSTU_R_PMETH_INIT_FAILED);
+ return 0;
+ }
+ if (!dstu_asn1_meth_init())
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, DSTU_R_AMETH_INIT_FAILED);
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!ENGINE_set_pkey_meths(e, dstu_pkey_meths))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!ENGINE_set_pkey_asn1_meths(e, dstu_asn1_meths))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!ENGINE_set_flags(e, DSTU_ENGINE_FLAGS))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!ENGINE_register_pkey_meths(e))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!ENGINE_register_pkey_asn1_meths(e))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!ENGINE_register_digests(e))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!ENGINE_register_ciphers(e))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_ENGINE_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!EVP_add_digest(&dstu_md))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_EVP_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+ if (!EVP_add_cipher(&dstu_cipher))
+ {
+ DSTUerr(DSTU_F_BIND_DSTU, ERR_R_EVP_LIB);
+ dstu_asn1_meth_finish();
+ dstu_pkey_meth_finish();
+ return 0;
+ }
+
+ ERR_load_DSTU_strings();
+ return 1;
+ }
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+IMPLEMENT_DYNAMIC_BIND_FN(bind_dstu)
+IMPLEMENT_DYNAMIC_CHECK_FN()
+#endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *engine_dstu(void)
+ {
+ ENGINE *ret = ENGINE_new();
+ if (!ret)
+ return NULL;
+ if (!bind_dstu(ret, engine_dstu_id))
+ {
+ ENGINE_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
+
+void ENGINE_load_dstu(void)
+ {
+ ENGINE *toadd = engine_dstu();
+ if (!toadd)
+ return;
+ ENGINE_add(toadd);
+ ENGINE_free(toadd);
+ ERR_clear_error();
+ }
+#endif
+
diff -urN openssl-1.0.1e/engines/uadstu/dstu_engine.h openssl-1.0.1e.patched/engines/uadstu/dstu_engine.h
--- openssl-1.0.1e/engines/uadstu/dstu_engine.h 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_engine.h 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1,41 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#ifndef DSTU_ENGINE_H_
+#define DSTU_ENGINE_H_
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/engine.h>
+#include <openssl/obj_mac.h>
+
+extern EVP_PKEY_METHOD *dstu_pkey_meth_le, *dstu_pkey_meth_be;
+int dstu_pkey_meth_init(void);
+void dstu_pkey_meth_finish(void);
+
+extern EVP_PKEY_ASN1_METHOD *dstu_asn1_meth_le, *dstu_asn1_meth_be;
+int dstu_asn1_meth_init(void);
+void dstu_asn1_meth_finish(void);
+
+int dstu_do_sign(const EC_KEY* key, const unsigned char *tbs, size_t tbslen,
+ unsigned char *sig);
+int dstu_do_verify(const EC_KEY* key, const unsigned char *tbs, size_t tbslen,
+ const unsigned char *sig, size_t siglen);
+
+extern EVP_MD dstu_md;
+
+extern EVP_CIPHER dstu_cipher;
+
+extern RAND_METHOD dstu_rand_meth;
+
+/* This ctrl command to set custom sbox for MD and CIPHER */
+/* p2 should point to char array of 64 bytes (packed format, see default_sbox), p1 should be set to size of the array (64) */
+#define DSTU_SET_CUSTOM_SBOX (EVP_MD_CTRL_ALG_CTRL + 1)
+
+#define DSTU_SET_CURVE (EVP_PKEY_ALG_CTRL + 2)
+
+#endif /* DSTU_ENGINE_H_ */
diff -urN openssl-1.0.1e/engines/uadstu/dstuhash.c openssl-1.0.1e.patched/engines/uadstu/dstuhash.c
--- openssl-1.0.1e/engines/uadstu/dstuhash.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstuhash.c 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1,14 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+/* Probably, this is the most cross-platform way to include gost code
+ * in our engine. If the library is compiled without gost engine or
+ * engines are in separate dynamic libraries then we will have our own
+ * independent copy of the code. If the library is compiled statically
+ * with gost engine then we rely on linker to remove duplicate code */
+
+#include "../ccgost/gosthash.h"
+
+#include "../ccgost/gosthash.c"
diff -urN openssl-1.0.1e/engines/uadstu/dstu_key.c openssl-1.0.1e.patched/engines/uadstu/dstu_key.c
--- openssl-1.0.1e/engines/uadstu/dstu_key.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_key.c 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1,505 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_key.h"
+#include "dstu_asn1.h"
+#include "dstu_compress.h"
+#include "dstu_params.h"
+#include <openssl/objects.h>
+#include <string.h>
+
+DSTU_KEY* DSTU_KEY_new(void)
+ {
+ DSTU_KEY* key = OPENSSL_malloc(sizeof(DSTU_KEY));
+
+ if (!key)
+ return NULL;
+ key->ec = EC_KEY_new();
+ if (!(key->ec))
+ {
+ OPENSSL_free(key);
+ return NULL;
+ }
+ key->sbox = NULL;
+ return key;
+ }
+
+void DSTU_KEY_set(DSTU_KEY* key, EC_KEY* ec, unsigned char *sbox)
+ {
+ if (ec)
+ {
+ if (key->ec)
+ EC_KEY_free(key->ec);
+ key->ec = ec;
+ }
+
+ if (sbox)
+ {
+ if (key->sbox)
+ OPENSSL_free(key->sbox);
+ key->sbox = sbox;
+ }
+ }
+
+void DSTU_KEY_free(DSTU_KEY* key)
+ {
+ if (key)
+ {
+ if (key->sbox)
+ OPENSSL_free(key->sbox);
+ if (key->ec)
+ EC_KEY_free(key->ec);
+ OPENSSL_free(key);
+ }
+ }
+
+DSTU_AlgorithmParameters* asn1_from_key(const DSTU_KEY* key,
+ int is_little_endian)
+ {
+ DSTU_AlgorithmParameters *params = DSTU_AlgorithmParameters_new(), *ret =
+ NULL;
+ const EC_GROUP* group = EC_KEY_get0_group(key->ec);
+ int curve_nid, poly[6], field_size;
+ BN_CTX* ctx = NULL;
+ const EC_POINT* g = NULL;
+ BIGNUM *p, *a, *b, *n;
+ unsigned char *compressed = NULL;
+
+ if (!params || !group)
+ return NULL;
+
+ if (key->sbox)
+ {
+ if (!is_default_sbox(key->sbox))
+ {
+ params->sbox = ASN1_OCTET_STRING_new();
+ if (!params->sbox)
+ goto err;
+
+ if (!ASN1_OCTET_STRING_set(params->sbox, key->sbox,
+ sizeof(default_sbox)))
+ goto err;
+ }
+ }
+
+ /* Checking if group represents a standard curve. If we get NID_undef, that means the curve is custom */
+ curve_nid = curve_nid_from_group(group);
+ if (NID_undef == curve_nid)
+ {
+ /* Custom curve */
+ params->curve->curve.custom_curve = DSTU_CustomCurveSpec_new();
+ if (!params->curve->curve.custom_curve)
+ goto err;
+ params->curve->type = DSTU_CUSTOM_CURVE;
+
+ g = EC_GROUP_get0_generator(group);
+ if (!g)
+ goto err;
+
+ ctx = BN_CTX_new();
+ BN_CTX_start(ctx);
+
+ p = BN_CTX_get(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ n = BN_CTX_get(ctx);
+
+ if (!n)
+ goto err;
+
+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx))
+ goto err;
+
+ if (!EC_GROUP_get_order(group, n, ctx))
+ goto err;
+
+ if (!BN_GF2m_poly2arr(p, poly, sizeof(poly) / sizeof(int)))
+ goto err;
+
+ if (!ASN1_INTEGER_set(params->curve->curve.custom_curve->field->m,
+ poly[0]))
+ goto err;
+
+ if ((-1 == poly[3]) && (0 == poly[2]))
+ {
+ /* We have a trinomial */
+ params->curve->curve.custom_curve->field->poly->poly.k =
+ ASN1_INTEGER_new();
+ if (!params->curve->curve.custom_curve->field->poly->poly.k)
+ goto err;
+ params->curve->curve.custom_curve->field->poly->type =
+ DSTU_TRINOMIAL;
+ if (!ASN1_INTEGER_set(
+ params->curve->curve.custom_curve->field->poly->poly.k,
+ poly[1]))
+ goto err;
+ }
+ else if ((-1 == poly[5]) && (0 == poly[4]))
+ {
+ /* We have a pentanomial */
+ params->curve->curve.custom_curve->field->poly->poly.pentanomial =
+ DSTU_Pentanomial_new();
+ if (!params->curve->curve.custom_curve->field->poly->poly.pentanomial)
+ goto err;
+ params->curve->curve.custom_curve->field->poly->type =
+ DSTU_PENTANOMIAL;
+
+ if (!ASN1_INTEGER_set(
+ params->curve->curve.custom_curve->field->poly->poly.pentanomial->l,
+ poly[1]))
+ goto err;
+
+ if (!ASN1_INTEGER_set(
+ params->curve->curve.custom_curve->field->poly->poly.pentanomial->j,
+ poly[2]))
+ goto err;
+
+ if (!ASN1_INTEGER_set(
+ params->curve->curve.custom_curve->field->poly->poly.pentanomial->k,
+ poly[3]))
+ goto err;
+ }
+ else
+ goto err;
+
+ if (!BN_to_ASN1_INTEGER(a, params->curve->curve.custom_curve->a))
+ goto err;
+
+ if (!BN_to_ASN1_INTEGER(n, params->curve->curve.custom_curve->n))
+ goto err;
+
+ field_size = (poly[0] + 7) / 8;
+
+ compressed = OPENSSL_malloc(field_size);
+ if (!compressed)
+ goto err;
+
+ if (!bn_encode(b, compressed, field_size))
+ goto err;
+
+ if (is_little_endian)
+ reverse_bytes(compressed, field_size);
+
+ if (!ASN1_OCTET_STRING_set(params->curve->curve.custom_curve->b,
+ compressed, field_size))
+ goto err;
+
+ if (!dstu_point_compress(group, g, compressed, field_size))
+ goto err;
+
+ if (is_little_endian)
+ reverse_bytes(compressed, field_size);
+
+ if (!ASN1_OCTET_STRING_set(params->curve->curve.custom_curve->bp,
+ compressed, field_size))
+ goto err;
+
+ }
+ else
+ {
+ /* Standard curve */
+ params->curve->curve.named_curve = OBJ_nid2obj(curve_nid);
+ if (!params->curve->curve.named_curve)
+ goto err;
+ params->curve->type = DSTU_STANDARD_CURVE;
+ }
+
+ ret = params;
+ params = NULL;
+
+ err:
+
+ if (compressed)
+ OPENSSL_free(compressed);
+
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ if (params)
+ DSTU_AlgorithmParameters_free(params);
+
+ return ret;
+ }
+
+DSTU_KEY* key_from_asn1(const DSTU_AlgorithmParameters* params,
+ int is_little_endian)
+ {
+ DSTU_KEY *key = DSTU_KEY_new(), *ret = NULL;
+ BIGNUM *p, *a, *b, *N;
+ EC_GROUP* group = NULL;
+ EC_POINT* g = NULL;
+ BN_CTX* ctx = NULL;
+ int poly[6];
+ unsigned char* reverse_buffer = NULL;
+
+ if (!key)
+ return NULL;
+
+ if (params->sbox)
+ {
+ if (64 != ASN1_STRING_length(params->sbox))
+ goto err;
+
+ if (!is_default_sbox(ASN1_STRING_data(params->sbox)))
+ {
+ key->sbox = copy_sbox(ASN1_STRING_data(params->sbox));
+ if (!(key->sbox))
+ goto err;
+ }
+ }
+
+ if (DSTU_STANDARD_CURVE == params->curve->type)
+ {
+ group = group_from_nid(OBJ_obj2nid(params->curve->curve.named_curve));
+ if (!group)
+ goto err;
+
+ if (!EC_KEY_set_group(key->ec, group))
+ goto err;
+ }
+ else
+ {
+ poly[0] = ASN1_INTEGER_get(params->curve->curve.custom_curve->field->m);
+ if (poly[0] <= 0)
+ goto err;
+
+ if (DSTU_TRINOMIAL
+ == params->curve->curve.custom_curve->field->poly->type)
+ {
+ poly[1] = ASN1_INTEGER_get(
+ params->curve->curve.custom_curve->field->poly->poly.k);
+ if (poly[1] <= 0)
+ goto err;
+ poly[2] = 0;
+ poly[3] = -1;
+ }
+ else
+ {
+ poly[1] =
+ ASN1_INTEGER_get(
+ params->curve->curve.custom_curve->field->poly->poly.pentanomial->l);
+ if (poly[1] <= 0)
+ goto err;
+
+ poly[2] =
+ ASN1_INTEGER_get(
+ params->curve->curve.custom_curve->field->poly->poly.pentanomial->j);
+ if (poly[2] <= 0)
+ goto err;
+
+ poly[3] =
+ ASN1_INTEGER_get(
+ params->curve->curve.custom_curve->field->poly->poly.pentanomial->k);
+ if (poly[3] <= 0)
+ goto err;
+
+ poly[4] = 0;
+ poly[5] = -1;
+ }
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ goto err;
+
+ BN_CTX_start(ctx);
+
+ p = BN_CTX_get(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ N = BN_CTX_get(ctx);
+
+ if (!N)
+ goto err;
+
+ if (!BN_GF2m_arr2poly(poly, p))
+ goto err;
+
+ if (!ASN1_INTEGER_to_BN(params->curve->curve.custom_curve->a, a))
+ goto err;
+
+ if (!BN_is_one(a) && !BN_is_zero(a))
+ goto err;
+
+ if (is_little_endian)
+ {
+ reverse_buffer =
+ OPENSSL_malloc(ASN1_STRING_length(params->curve->curve.custom_curve->b));
+ if (!reverse_buffer)
+ goto err;
+
+ reverse_bytes_copy(reverse_buffer,
+ ASN1_STRING_data(params->curve->curve.custom_curve->b),
+ ASN1_STRING_length(params->curve->curve.custom_curve->b));
+
+ if (!BN_bin2bn(reverse_buffer,
+ ASN1_STRING_length(params->curve->curve.custom_curve->b),
+ b))
+ {
+ OPENSSL_free(reverse_buffer);
+ goto err;
+ }
+
+ OPENSSL_free(reverse_buffer);
+ }
+ else
+ {
+ if (!BN_bin2bn(
+ ASN1_STRING_data(params->curve->curve.custom_curve->b),
+ ASN1_STRING_length(params->curve->curve.custom_curve->b),
+ b))
+ goto err;
+ }
+
+ if (!ASN1_INTEGER_to_BN(params->curve->curve.custom_curve->n, N))
+ goto err;
+
+ group = EC_GROUP_new_curve_GF2m(p, a, b, ctx);
+ if (!group)
+ goto err;
+
+ g = EC_POINT_new(group);
+ if (!g)
+ goto err;
+
+ if (is_little_endian)
+ {
+ reverse_buffer =
+ OPENSSL_malloc(ASN1_STRING_length(params->curve->curve.custom_curve->bp));
+ if (!reverse_buffer)
+ goto err;
+
+ reverse_bytes_copy(reverse_buffer,
+ ASN1_STRING_data(params->curve->curve.custom_curve->bp),
+ ASN1_STRING_length(params->curve->curve.custom_curve->bp));
+
+ if (!dstu_point_expand(reverse_buffer,
+ ASN1_STRING_length(params->curve->curve.custom_curve->bp),
+ group, g))
+ {
+ OPENSSL_free(reverse_buffer);
+ goto err;
+ }
+
+ OPENSSL_free(reverse_buffer);
+ }
+ else
+ {
+ if (!dstu_point_expand(
+ ASN1_STRING_data(params->curve->curve.custom_curve->bp),
+ ASN1_STRING_length(params->curve->curve.custom_curve->bp),
+ group, g))
+ goto err;
+ }
+
+ if (!EC_GROUP_set_generator(group, g, N, BN_value_one()))
+ goto err;
+
+ if (!EC_KEY_set_group(key->ec, group))
+ goto err;
+ }
+
+ ret = key;
+ key = NULL;
+
+ err:
+
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ if (g)
+ EC_POINT_free(g);
+
+ if (group)
+ EC_GROUP_free(group);
+
+ if (key)
+ DSTU_KEY_free(key);
+
+ return ret;
+ }
+
+DSTU_KEY_CTX* DSTU_KEY_CTX_new(void)
+ {
+ DSTU_KEY_CTX* ctx = OPENSSL_malloc(sizeof(DSTU_KEY_CTX));
+ if (ctx)
+ {
+ memset(ctx, 0, sizeof(DSTU_KEY_CTX));
+ return ctx;
+ }
+ return NULL;
+ }
+
+void DSTU_KEY_CTX_set(DSTU_KEY_CTX* ctx, EC_GROUP* group, unsigned char *sbox)
+ {
+ if (group)
+ {
+ if (ctx->group)
+ EC_GROUP_free(ctx->group);
+ ctx->group = group;
+ }
+
+ if (sbox)
+ {
+ if (ctx->sbox)
+ OPENSSL_free(ctx->sbox);
+ ctx->sbox = sbox;
+ }
+ }
+
+DSTU_KEY_CTX* DSTU_KEY_CTX_copy(const DSTU_KEY_CTX* ctx)
+ {
+ DSTU_KEY_CTX *copy = DSTU_KEY_CTX_new();
+
+ if (!copy)
+ return NULL;
+
+ copy->type = ctx->type;
+
+ if (ctx->group)
+ {
+ copy->group = EC_GROUP_dup(ctx->group);
+ if (!(copy->group))
+ {
+ DSTU_KEY_CTX_free(copy);
+ return NULL;
+ }
+ }
+
+ if (ctx->sbox)
+ {
+ copy->sbox = copy_sbox(ctx->sbox);
+ if (!(copy->sbox))
+ {
+ DSTU_KEY_CTX_free(copy);
+ return NULL;
+ }
+ }
+
+ return copy;
+ }
+
+void DSTU_KEY_CTX_free(DSTU_KEY_CTX* ctx)
+ {
+ if (ctx)
+ {
+ if (ctx->group)
+ {
+ EC_GROUP_free(ctx->group);
+ ctx->group = NULL;
+ }
+ if (ctx->sbox)
+ {
+ OPENSSL_free(ctx->sbox);
+ ctx->sbox = NULL;
+ }
+ OPENSSL_free(ctx);
+ }
+ }
diff -urN openssl-1.0.1e/engines/uadstu/dstu_key.h openssl-1.0.1e.patched/engines/uadstu/dstu_key.h
--- openssl-1.0.1e/engines/uadstu/dstu_key.h 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_key.h 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1,39 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#ifndef DSTU_KEY_H_
+#define DSTU_KEY_H_
+
+#include <openssl/ec.h>
+#include "../ccgost/gost89.h"
+#include "dstu_asn1.h"
+
+typedef struct dstu_key_st
+ {
+ EC_KEY* ec;
+ unsigned char* sbox;
+ } DSTU_KEY;
+
+typedef struct dstu_key_ctx_st
+ {
+ int type;
+ EC_GROUP* group;
+ unsigned char* sbox;
+ } DSTU_KEY_CTX;
+
+DSTU_KEY* DSTU_KEY_new(void);
+void DSTU_KEY_set(DSTU_KEY* key, EC_KEY* ec, unsigned char *sbox);
+DSTU_KEY* key_from_asn1(const DSTU_AlgorithmParameters* params,
+ int is_little_endian);
+DSTU_AlgorithmParameters* asn1_from_key(const DSTU_KEY* key,
+ int is_little_endian);
+void DSTU_KEY_free(DSTU_KEY* key);
+
+DSTU_KEY_CTX* DSTU_KEY_CTX_new(void);
+void DSTU_KEY_CTX_set(DSTU_KEY_CTX* ctx, EC_GROUP* group, unsigned char *sbox);
+DSTU_KEY_CTX* DSTU_KEY_CTX_copy(const DSTU_KEY_CTX* ctx);
+void DSTU_KEY_CTX_free(DSTU_KEY_CTX* ctx);
+
+#endif /* DSTU_KEY_H_ */
diff -urN openssl-1.0.1e/engines/uadstu/dstu_md.c openssl-1.0.1e.patched/engines/uadstu/dstu_md.c
--- openssl-1.0.1e/engines/uadstu/dstu_md.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_md.c 2013-12-28 12:56:38.705489000 +0900
@@ -0,0 +1,117 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_engine.h"
+#include "dstu_params.h"
+#include "dstu_key.h"
+#include "../ccgost/gosthash.h"
+
+struct dstu_digest_ctx
+ {
+ gost_hash_ctx dctx;
+ gost_ctx cctx;
+ };
+
+static int dstu_md_init(EVP_MD_CTX *ctx)
+ {
+ gost_subst_block sbox;
+ int use_default_sbox = 1;
+ struct dstu_digest_ctx *c = ctx->md_data;
+ DSTU_KEY* dstu_key = NULL;
+ EVP_PKEY* pkey = NULL;
+
+ /* If we have pkey_ctx, it may contain custom sbox, so let's check it */
+
+ if (ctx->pctx)
+ {
+ pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
+ if (pkey)
+ {
+ dstu_key = EVP_PKEY_get0(pkey);
+ if (dstu_key)
+ {
+ if (dstu_key->sbox)
+ {
+ unpack_sbox(dstu_key->sbox, &sbox);
+ use_default_sbox = 0;
+ }
+ }
+ }
+ }
+
+ if (use_default_sbox)
+ unpack_sbox(default_sbox, &sbox);
+ memset(&(c->dctx), 0, sizeof(gost_hash_ctx));
+ gost_init(&(c->cctx), &sbox);
+ c->dctx.cipher_ctx = &(c->cctx);
+ return 1;
+ }
+
+static int dstu_md_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+ {
+ return hash_block((gost_hash_ctx *) (ctx->md_data), data, count);
+ }
+
+static int dstu_md_final(EVP_MD_CTX *ctx, unsigned char *md)
+ {
+ return finish_hash((gost_hash_ctx *) (ctx->md_data), md);
+ }
+
+static int dstu_md_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
+ {
+ struct dstu_digest_ctx *md_ctx = to->md_data;
+ if (to->md_data && from->md_data)
+ {
+ memcpy(to->md_data, from->md_data, sizeof(struct dstu_digest_ctx));
+ md_ctx->dctx.cipher_ctx = &(md_ctx->cctx);
+ }
+ return 1;
+ }
+
+static int dstu_md_cleanup(EVP_MD_CTX *ctx)
+ {
+ if (ctx->md_data)
+ memset(ctx->md_data, 0, sizeof(struct dstu_digest_ctx));
+ return 1;
+ }
+
+static int dstu_md_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
+ {
+ gost_subst_block sbox;
+ struct dstu_digest_ctx *c = ctx->md_data;
+
+ switch (cmd)
+ {
+ case DSTU_SET_CUSTOM_SBOX:
+ if ((!p2) || (sizeof(default_sbox) != p1))
+ return 0;
+ unpack_sbox((unsigned char *) p2, &sbox);
+ gost_init(&(c->cctx), &sbox);
+ return 1;
+ }
+
+ return 0;
+ }
+
+EVP_MD dstu_md =
+ {
+ NID_dstu34311,
+ 0,
+ 32,
+ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
+ dstu_md_init,
+ dstu_md_update,
+ dstu_md_final,
+ dstu_md_copy,
+ dstu_md_cleanup,
+ NULL,
+ NULL,
+ {
+ 0, 0, 0, 0, 0
+ },
+ 32,
+ sizeof(struct dstu_digest_ctx),
+ dstu_md_ctrl
+ };
diff -urN openssl-1.0.1e/engines/uadstu/dstu_params.c openssl-1.0.1e.patched/engines/uadstu/dstu_params.c
--- openssl-1.0.1e/engines/uadstu/dstu_params.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_params.c 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,617 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_params.h"
+#include <openssl/evp.h>
+#include <string.h>
+
+static unsigned char data163[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x05, 0xFF, 0x61, 0x08, 0x46, 0x2A, 0x2D, 0xC8, 0x21, 0x0A, 0xB4, 0x03,
+ 0x92, 0x5E, 0x63, 0x8A, 0x19, 0xC1, 0x45, 0x5D, 0x21,
+
+ /*N*/
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xBE,
+ 0xC1, 0x2B, 0xE2, 0x26, 0x2D, 0x39, 0xBC, 0xF1, 0x4D,
+
+ /*Px*/
+ 0x02, 0xE2, 0xF8, 0x5F, 0x5D, 0xD7, 0x4C, 0xE9, 0x83, 0xA5, 0xC4, 0x23,
+ 0x72, 0x29, 0xDA, 0xF8, 0xA3, 0xF3, 0x58, 0x23, 0xBE,
+
+ /*Py*/
+ 0x03, 0x82, 0x6F, 0x00, 0x8A, 0x8C, 0x51, 0xD7, 0xB9, 0x52, 0x84, 0xD9,
+ 0xD0, 0x3F, 0xF0, 0xE0, 0x0C, 0xE2, 0xCD, 0x72, 0x3A
+ };
+
+static unsigned char data167[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x6E, 0xE3, 0xCE, 0xEB, 0x23, 0x08, 0x11, 0x75, 0x9F, 0x20, 0x51, 0x8A,
+ 0x09, 0x30, 0xF1, 0xA4, 0x31, 0x5A, 0x82, 0x7D, 0xAC,
+
+ /*N*/
+ 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB1,
+ 0x2E, 0xBC, 0xC7, 0xD7, 0xF2, 0x9F, 0xF7, 0x70, 0x1F,
+
+ /*Px*/
+ 0x7A, 0x1F, 0x66, 0x53, 0x78, 0x6A, 0x68, 0x19, 0x28, 0x03, 0x91, 0x0A,
+ 0x3D, 0x30, 0xB2, 0xA2, 0x01, 0x8B, 0x21, 0xCD, 0x54,
+
+ /*Py*/
+ 0x5F, 0x49, 0xEB, 0x26, 0x78, 0x1C, 0x0E, 0xC6, 0xB8, 0x90, 0x91, 0x56,
+ 0xD9, 0x8E, 0xD4, 0x35, 0xE4, 0x5F, 0xD5, 0x99, 0x18
+ };
+
+static unsigned char data173[] =
+ {
+ /*A*/
+ 0x00,
+
+ /*B*/
+ 0x10, 0x85, 0x76, 0xC8, 0x04, 0x99, 0xDB, 0x2F, 0xC1, 0x6E, 0xDD, 0xF6,
+ 0x85, 0x3B, 0xBB, 0x27, 0x8F, 0x6B, 0x6F, 0xB4, 0x37, 0xD9,
+
+ /*N*/
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x9B, 0x4E, 0x67, 0x60, 0x6E, 0x38, 0x25, 0xBB, 0x28, 0x31,
+
+ /*Px*/
+ 0x04, 0xD4, 0x1A, 0x61, 0x9B, 0xCC, 0x6E, 0xAD, 0xF0, 0x44, 0x8F, 0xA2,
+ 0x2F, 0xAD, 0x56, 0x7A, 0x91, 0x81, 0xD3, 0x73, 0x89, 0xCA,
+
+ /*Py*/
+ 0x10, 0xB5, 0x1C, 0xC1, 0x28, 0x49, 0xB2, 0x34, 0xC7, 0x5E, 0x6D, 0xD2,
+ 0x02, 0x8B, 0xF7, 0xFF, 0x5C, 0x1C, 0xE0, 0xD9, 0x91, 0xA1
+ };
+
+static unsigned char data179[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x04, 0xA6, 0xE0, 0x85, 0x65, 0x26, 0x43, 0x6F, 0x2F, 0x88, 0xDD, 0x07,
+ 0xA3, 0x41, 0xE3, 0x2D, 0x04, 0x18, 0x45, 0x72, 0xBE, 0xB7, 0x10,
+
+ /*N*/
+ 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xB9, 0x81, 0x96, 0x04, 0x35, 0xFE, 0x5A, 0xB6, 0x42, 0x36, 0xEF,
+
+ /*Px*/
+ 0x06, 0xBA, 0x06, 0xFE, 0x51, 0x46, 0x4B, 0x2B, 0xD2, 0x6D, 0xC5, 0x7F,
+ 0x48, 0x81, 0x9B, 0xA9, 0x95, 0x46, 0x67, 0x02, 0x2C, 0x7D, 0x03,
+
+ /*Py*/
+ 0x02, 0x5F, 0xBC, 0x36, 0x35, 0x82, 0xDC, 0xEC, 0x06, 0x50, 0x80, 0xCA,
+ 0x82, 0x87, 0xAA, 0xFF, 0x09, 0x78, 0x8A, 0x66, 0xDC, 0x3A, 0x9E
+ };
+
+static unsigned char data191[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x7B, 0xC8, 0x6E, 0x21, 0x02, 0x90, 0x2E, 0xC4, 0xD5, 0x89, 0x0E, 0x8B,
+ 0x6B, 0x49, 0x81, 0xff, 0x27, 0xE0, 0x48, 0x27, 0x50, 0xFE, 0xFC, 0x03,
+
+ /*N*/
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x69, 0xA7, 0x79, 0xCA, 0xC1, 0xDA, 0xBC, 0x67, 0x88, 0xF7, 0x47, 0x4F,
+
+ /*Px*/
+ 0x71, 0x41, 0x14, 0xB7, 0x62, 0xF2, 0xFF, 0x4A, 0x79, 0x12, 0xA6, 0xD2,
+ 0xAC, 0x58, 0xB9, 0xB5, 0xC2, 0xFC, 0xFE, 0x76, 0xDA, 0xEB, 0x71, 0x29,
+
+ /*Py*/
+ 0x29, 0xC4, 0x1E, 0x56, 0x8B, 0x77, 0xC6, 0x17, 0xEF, 0xE5, 0x90, 0x2F,
+ 0x11, 0xDB, 0x96, 0xFA, 0x96, 0x13, 0xCD, 0x8D, 0x03, 0xDB, 0x08, 0xDA
+ };
+
+static unsigned char data233[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x00, 0x69, 0x73, 0xB1, 0x50, 0x95, 0x67, 0x55, 0x34, 0xC7, 0xCF, 0x7E,
+ 0x64, 0xA2, 0x1B, 0xD5, 0x4E, 0xF5, 0xDD, 0x3B, 0x8A, 0x03, 0x26, 0xAA,
+ 0x93, 0x6E, 0xCE, 0x45, 0x4D, 0x2C,
+
+ /*N*/
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F, 0x8A, 0x69, 0x22, 0x03,
+ 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7,
+
+ /*Px*/
+ 0x00, 0x3F, 0xCD, 0xA5, 0x26, 0xB6, 0xCD, 0xF8, 0x3B, 0xA1, 0x11, 0x8D,
+ 0xF3, 0x5B, 0x3C, 0x31, 0x76, 0x1D, 0x35, 0x45, 0xF3, 0x27, 0x28, 0xD0,
+ 0x03, 0xEE, 0xB2, 0x5E, 0xFE, 0x96,
+
+ /*Py*/
+ 0x00, 0x9C, 0xA8, 0xB5, 0x7A, 0x93, 0x4C, 0x54, 0xDE, 0xED, 0xA9, 0xE5,
+ 0x4A, 0x7B, 0xBA, 0xD9, 0x5E, 0x3B, 0x2E, 0x91, 0xC5, 0x4D, 0x32, 0xBE,
+ 0x0B, 0x9D, 0xF9, 0x6D, 0x8D, 0x35
+ };
+
+static unsigned char data257[] =
+ {
+ /*A*/
+ 0x00,
+
+ /*B*/
+ 0x01, 0xCE, 0xF4, 0x94, 0x72, 0x01, 0x15, 0x65, 0x7E, 0x18, 0xF9, 0x38,
+ 0xD7, 0xA7, 0x94, 0x23, 0x94, 0xFF, 0x94, 0x25, 0xC1, 0x45, 0x8C, 0x57,
+ 0x86, 0x1F, 0x9E, 0xEA, 0x6A, 0xDB, 0xE3, 0xBE, 0x10,
+
+ /*N*/
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x59, 0x21, 0x3A, 0xF1, 0x82, 0xE9,
+ 0x87, 0xD3, 0xE1, 0x77, 0x14, 0x90, 0x7D, 0x47, 0x0D,
+
+ /*Px*/
+ 0x00, 0x2A, 0x29, 0xEF, 0x20, 0x7D, 0x0E, 0x9B, 0x6C, 0x55, 0xCD, 0x26,
+ 0x0B, 0x30, 0x6C, 0x7E, 0x00, 0x7A, 0xC4, 0x91, 0xCA, 0x1B, 0x10, 0xC6,
+ 0x23, 0x34, 0xA9, 0xE8, 0xDC, 0xD8, 0xD2, 0x0F, 0xB7,
+
+ /*Py*/
+ 0x01, 0x06, 0x86, 0xD4, 0x1F, 0xF7, 0x44, 0xD4, 0x44, 0x9F, 0xCC, 0xF6,
+ 0xD8, 0xEE, 0xA0, 0x31, 0x02, 0xE6, 0x81, 0x2C, 0x93, 0xA9, 0xD6, 0x0B,
+ 0x97, 0x8B, 0x70, 0x2C, 0xF1, 0x56, 0xD8, 0x14, 0xEF
+ };
+
+static unsigned char data307[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x03, 0x93, 0xC7, 0xF7, 0xD5, 0x36, 0x66, 0xB5, 0x05, 0x4B, 0x5E, 0x6C,
+ 0x6D, 0x3D, 0xE9, 0x4F, 0x42, 0x96, 0xC0, 0xC5, 0x99, 0xE2, 0xE2, 0xE2,
+ 0x41, 0x05, 0x0D, 0xF1, 0x8B, 0x60, 0x90, 0xBD, 0xC9, 0x01, 0x86, 0x90,
+ 0x49, 0x68, 0xBB,
+
+ /*N*/
+ 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x79, 0xC2, 0xF3,
+ 0x82, 0x5D, 0xA7, 0x0D, 0x39, 0x0F, 0xBB, 0xA5, 0x88, 0xD4, 0x60, 0x40,
+ 0x22, 0xB7, 0xB7,
+
+ /*Px*/
+ 0x02, 0x16, 0xEE, 0x8B, 0x18, 0x9D, 0x29, 0x1A, 0x02, 0x24, 0x98, 0x4C,
+ 0x1E, 0x92, 0xF1, 0xD1, 0x6B, 0xF7, 0x5C, 0xCD, 0x82, 0x5A, 0x08, 0x7A,
+ 0x23, 0x9B, 0x27, 0x6D, 0x31, 0x67, 0x74, 0x3C, 0x52, 0xC0, 0x2D, 0x6E,
+ 0x72, 0x32, 0xAA,
+
+ /*Py*/
+ 0x05, 0xD9, 0x30, 0x6B, 0xAC, 0xD2, 0x2B, 0x7F, 0xAE, 0xB0, 0x9D, 0x2E,
+ 0x04, 0x9C, 0x6E, 0x28, 0x66, 0xC5, 0xD1, 0x67, 0x77, 0x62, 0xA8, 0xF2,
+ 0xF2, 0xDC, 0x9A, 0x11, 0xC7, 0xF7, 0xBE, 0x83, 0x40, 0xAB, 0x22, 0x37,
+ 0xC7, 0xF2, 0xA0
+ };
+
+static unsigned char data367[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x43, 0xFC, 0x8A, 0xD2, 0x42, 0xB0, 0xB7, 0xA6, 0xF3, 0xD1, 0x62, 0x7A,
+ 0xD5, 0x65, 0x44, 0x47, 0x55, 0x6B, 0x47, 0xBF, 0x6A, 0xA4, 0xA6, 0x4B,
+ 0x0C, 0x2A, 0xFE, 0x42, 0xCA, 0xDA, 0xB8, 0xF9, 0x3D, 0x92, 0x39, 0x4C,
+ 0x79, 0xA7, 0x97, 0x55, 0x43, 0x7B, 0x56, 0x99, 0x51, 0x36,
+
+ /*N*/
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C,
+ 0x30, 0x0B, 0x75, 0xA3, 0xFA, 0x82, 0x4F, 0x22, 0x42, 0x8F, 0xD2, 0x8C,
+ 0xE8, 0x81, 0x22, 0x45, 0xEF, 0x44, 0x04, 0x9B, 0x2D, 0x49,
+
+ /*Px*/
+ 0x32, 0x4A, 0x6E, 0xDD, 0xD5, 0x12, 0xF0, 0x8C, 0x49, 0xA9, 0x9A, 0xE0,
+ 0xD3, 0xF9, 0x61, 0x19, 0x7A, 0x76, 0x41, 0x3E, 0x7B, 0xE8, 0x1A, 0x40,
+ 0x0C, 0xA6, 0x81, 0xE0, 0x96, 0x39, 0xB5, 0xFE, 0x12, 0xE5, 0x9A, 0x10,
+ 0x9F, 0x78, 0xBF, 0x4A, 0x37, 0x35, 0x41, 0xB3, 0xB9, 0xA1,
+
+ /*Py*/
+ 0x01, 0xAB, 0x59, 0x7A, 0x5B, 0x44, 0x77, 0xF5, 0x9E, 0x39, 0x53, 0x90,
+ 0x07, 0xC7, 0xF9, 0x77, 0xD1, 0xA5, 0x67, 0xB9, 0x2B, 0x04, 0x3A, 0x49,
+ 0xC6, 0xB6, 0x19, 0x84, 0xC3, 0xFE, 0x34, 0x81, 0xAA, 0xF4, 0x54, 0xCD,
+ 0x41, 0xBA, 0x1F, 0x05, 0x16, 0x26, 0x44, 0x2B, 0x3C, 0x10
+ };
+
+static unsigned char data431[] =
+ {
+ /*A*/
+ 0x01,
+
+ /*B*/
+ 0x03, 0xCE, 0x10, 0x49, 0x0F, 0x6A, 0x70, 0x8F, 0xC2, 0x6D, 0xFE, 0x8C,
+ 0x3D, 0x27, 0xC4, 0xF9, 0x4E, 0x69, 0x01, 0x34, 0xD5, 0xBF, 0xF9, 0x88,
+ 0xD8, 0xD2, 0x8A, 0xAE, 0xAE, 0xDE, 0x97, 0x59, 0x36, 0xC6, 0x6B, 0xAC,
+ 0x53, 0x6B, 0x18, 0xAE, 0x2D, 0xC3, 0x12, 0xCA, 0x49, 0x31, 0x17, 0xDA,
+ 0xA4, 0x69, 0xC6, 0x40, 0xCA, 0xF3,
+
+ /*N*/
+ 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xBA, 0x31, 0x75, 0x45, 0x80, 0x09, 0xA8, 0xC0, 0xA7,
+ 0x24, 0xF0, 0x2F, 0x81, 0xAA, 0x8A, 0x1F, 0xCB, 0xAF, 0x80, 0xD9, 0x0C,
+ 0x7A, 0x95, 0x11, 0x05, 0x04, 0xCF,
+
+ /*Px*/
+ 0x1A, 0x62, 0xBA, 0x79, 0xD9, 0x81, 0x33, 0xA1, 0x6B, 0xBA, 0xE7, 0xED,
+ 0x9A, 0x8E, 0x03, 0xC3, 0x2E, 0x08, 0x24, 0xD5, 0x7A, 0xEF, 0x72, 0xF8,
+ 0x89, 0x86, 0x87, 0x4E, 0x5A, 0xAE, 0x49, 0xC2, 0x7B, 0xED, 0x49, 0xA2,
+ 0xA9, 0x50, 0x58, 0x06, 0x84, 0x26, 0xC2, 0x17, 0x1E, 0x99, 0xFD, 0x3B,
+ 0x43, 0xC5, 0x94, 0x7C, 0x85, 0x7D,
+
+ /*Py*/
+ 0x70, 0xB5, 0xE1, 0xE1, 0x40, 0x31, 0xC1, 0xF7, 0x0B, 0xBE, 0xFE, 0x96,
+ 0xBD, 0xDE, 0x66, 0xF4, 0x51, 0x75, 0x4B, 0x4C, 0xA5, 0xF4, 0x8D, 0xA2,
+ 0x41, 0xF3, 0x31, 0xAA, 0x39, 0x6B, 0x8D, 0x18, 0x39, 0xA8, 0x55, 0xC1,
+ 0x76, 0x9B, 0x1E, 0xA1, 0x4B, 0xA5, 0x33, 0x08, 0xB5, 0xE2, 0x72, 0x37,
+ 0x24, 0xE0, 0x90, 0xE0, 0x2D, 0xB9
+ };
+
+DSTU_NAMED_CURVE dstu_curves[] =
+ {
+ {
+ NID_uacurve0,
+ {
+ 163, 7, 6, 3, 0, -1
+ }, data163
+ },
+ {
+ NID_uacurve1,
+ {
+ 167, 6, 0, -1, 0, 0
+ }, data167
+ },
+ {
+ NID_uacurve2,
+ {
+ 173, 10, 2, 1, 0, -1
+ }, data173
+ },
+ {
+ NID_uacurve3,
+ {
+ 179, 4, 2, 1, 0, -1
+ }, data179
+ },
+ {
+ NID_uacurve4,
+ {
+ 191, 9, 0, -1, 0, 0
+ }, data191
+ },
+ {
+ NID_uacurve5,
+ {
+ 233, 9, 4, 1, 0, -1
+ }, data233
+ },
+ {
+ NID_uacurve6,
+ {
+ 257, 12, 0, -1, 0, 0
+ }, data257
+ },
+ {
+ NID_uacurve7,
+ {
+ 307, 8, 4, 2, 0, -1
+ }, data307
+ },
+ {
+ NID_uacurve8,
+ {
+ 367, 21, 0, -1, 0, 0
+ }, data367
+ },
+ {
+ NID_uacurve9,
+ {
+ 431, 5, 3, 1, 0, -1
+ }, data431
+ }
+ };
+
+int curve_nid_from_group(const EC_GROUP* group)
+ {
+ int m = EC_GROUP_get_degree(group), i, nid = NID_undef;
+ EC_GROUP* std_group = NULL;
+
+ for (i = 0; i < (sizeof(dstu_curves) / sizeof(DSTU_NAMED_CURVE)); i++)
+ {
+ if (m == dstu_curves[i].poly[0])
+ break;
+ }
+
+ if (i < (sizeof(dstu_curves) / sizeof(DSTU_NAMED_CURVE)))
+ {
+ std_group = group_from_named_curve(i);
+
+ if (std_group)
+ {
+ if (!EC_GROUP_cmp(group, std_group, NULL))
+ nid = dstu_curves[i].nid;
+ }
+ }
+
+ if (std_group)
+ EC_GROUP_free(std_group);
+
+ return nid;
+ }
+
+void unpack_sbox(unsigned char* packed_sbox, gost_subst_block* unpacked_sbox)
+ {
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ unpacked_sbox->k1[2 * i] = 0x0f & (packed_sbox[i] >> 4);
+ unpacked_sbox->k1[(2 * i) + 1] = 0x0f & packed_sbox[i];
+
+ unpacked_sbox->k2[2 * i] = 0x0f & (packed_sbox[i + 8] >> 4);
+ unpacked_sbox->k2[(2 * i) + 1] = 0x0f & packed_sbox[i + 8];
+
+ unpacked_sbox->k3[2 * i] = 0x0f & (packed_sbox[i + 16] >> 4);
+ unpacked_sbox->k3[(2 * i) + 1] = 0x0f & packed_sbox[i + 16];
+
+ unpacked_sbox->k4[2 * i] = 0x0f & (packed_sbox[i + 24] >> 4);
+ unpacked_sbox->k4[(2 * i) + 1] = 0x0f & packed_sbox[i + 24];
+
+ unpacked_sbox->k5[2 * i] = 0x0f & (packed_sbox[i + 32] >> 4);
+ unpacked_sbox->k5[(2 * i) + 1] = 0x0f & packed_sbox[i + 32];
+
+ unpacked_sbox->k6[2 * i] = 0x0f & (packed_sbox[i + 40] >> 4);
+ unpacked_sbox->k6[(2 * i) + 1] = 0x0f & packed_sbox[i + 40];
+
+ unpacked_sbox->k7[2 * i] = 0x0f & (packed_sbox[i + 48] >> 4);
+ unpacked_sbox->k7[(2 * i) + 1] = 0x0f & packed_sbox[i + 48];
+
+ unpacked_sbox->k8[2 * i] = 0x0f & (packed_sbox[i + 56] >> 4);
+ unpacked_sbox->k8[(2 * i) + 1] = 0x0f & packed_sbox[i + 56];
+ }
+ }
+
+unsigned char default_sbox[64] =
+ {
+ 0xa9, 0xd6, 0xeb, 0x45, 0xf1, 0x3c, 0x70, 0x82,
+ 0x80, 0xc4, 0x96, 0x7b, 0x23, 0x1f, 0x5e, 0xad,
+ 0xf6, 0x58, 0xeb, 0xa4, 0xc0, 0x37, 0x29, 0x1d,
+ 0x38, 0xd9, 0x6b, 0xf0, 0x25, 0xca, 0x4e, 0x17,
+ 0xf8, 0xe9, 0x72, 0x0d, 0xc6, 0x15, 0xb4, 0x3a,
+ 0x28, 0x97, 0x5f, 0x0b, 0xc1, 0xde, 0xa3, 0x64,
+ 0x38, 0xb5, 0x64, 0xea, 0x2c, 0x17, 0x9f, 0xd0,
+ 0x12, 0x3e, 0x6d, 0xb8, 0xfa, 0xc5, 0x79, 0x04
+ };
+
+EC_GROUP* group_from_named_curve(int curve_num)
+ {
+ int bytesize = ((dstu_curves[curve_num].poly[0]) + 7) / 8;
+ BIGNUM *p, *a, *b, *Px, *Py, *N;
+ BN_CTX* ctx = NULL;
+ EC_GROUP *group = NULL, *ret = NULL;
+ EC_POINT* P = NULL;
+ unsigned char* data = dstu_curves[curve_num].data;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ return NULL;
+
+ BN_CTX_start(ctx);
+
+ p = BN_CTX_get(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ N = BN_CTX_get(ctx);
+ Px = BN_CTX_get(ctx);
+ Py = BN_CTX_get(ctx);
+
+ if (!Py)
+ goto err;
+
+ if (!BN_GF2m_arr2poly(dstu_curves[curve_num].poly, p))
+ goto err;
+
+ if (*data)
+ BN_one(a);
+ else
+ BN_zero(a);
+
+ data++;
+
+ if (!BN_bin2bn(data, bytesize, b))
+ goto err;
+ data += bytesize;
+
+ group = EC_GROUP_new_curve_GF2m(p, a, b, ctx);
+ if (!group)
+ goto err;
+
+ if (!BN_bin2bn(data, bytesize, N))
+ goto err;
+ data += bytesize;
+
+ P = EC_POINT_new(group);
+ if (!P)
+ goto err;
+
+ if (!BN_bin2bn(data, bytesize, Px))
+ goto err;
+ data += bytesize;
+
+ if (!BN_bin2bn(data, bytesize, Py))
+ goto err;
+
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, P, Px, Py, ctx))
+ goto err;
+
+ if (!EC_GROUP_set_generator(group, P, N, BN_value_one()))
+ goto err;
+
+ ret = group;
+ group = NULL;
+
+ err: if (P)
+ EC_POINT_free(P);
+ if (group)
+ EC_GROUP_free(group);
+
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ return ret;
+ }
+
+EC_GROUP* group_from_nid(int nid)
+ {
+ int i;
+
+ for (i = 0; i < (sizeof(dstu_curves) / sizeof(DSTU_NAMED_CURVE)); i++)
+ {
+ if (nid == dstu_curves[i].nid)
+ return group_from_named_curve(i);
+ }
+
+ return NULL;
+ }
+
+int dstu_generate_key(EC_KEY* key)
+ {
+ const EC_GROUP* group = EC_KEY_get0_group(key);
+ BIGNUM *order, *prk;
+ BN_CTX* ctx = NULL;
+ int ret = 0;
+
+ if (!group)
+ return 0;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ return 0;
+
+ BN_CTX_start(ctx);
+
+ order = BN_CTX_get(ctx);
+ prk = BN_CTX_get(ctx);
+
+ if (!prk)
+ goto err;
+
+ if (!EC_GROUP_get_order(group, order, NULL))
+ goto err;
+
+ do
+ {
+ if (!BN_rand_range(prk, order))
+ goto err;
+ }
+ while (BN_is_zero(prk));
+
+ if (!EC_KEY_set_private_key(key, prk))
+ goto err;
+
+ ret = dstu_add_public_key(key);
+
+ err: if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ret;
+ }
+
+int dstu_add_public_key(EC_KEY* key)
+ {
+ EC_POINT* pbk = NULL;
+ const EC_GROUP* group = EC_KEY_get0_group(key);
+ const BIGNUM* prk = EC_KEY_get0_private_key(key);
+ int ret = 0;
+
+ if (!group || !prk)
+ return 0;
+
+ pbk = EC_POINT_new(group);
+ if (!pbk)
+ return 0;
+
+ if (!EC_POINT_mul(group, pbk, prk, NULL, NULL, NULL))
+ goto err;
+
+ if (!EC_POINT_invert(group, pbk, NULL))
+ goto err;
+
+ if (!EC_KEY_set_public_key(key, pbk))
+ goto err;
+
+ ret = 1;
+
+ err: if (pbk)
+ EC_POINT_free(pbk);
+ return ret;
+ }
+
+void reverse_bytes(void *mem, int size)
+ {
+ unsigned char *bytes = mem;
+ unsigned char tmp;
+ int i;
+
+ for (i = 0; i < (size / 2); i++)
+ {
+ tmp = bytes[i];
+ bytes[i] = bytes[size - 1 - i];
+ bytes[size - 1 - i] = tmp;
+ }
+ }
+
+void reverse_bytes_copy(void *dst, const void *src, int size)
+ {
+ unsigned char *to = dst;
+ const unsigned char *from = src;
+ int i;
+
+ for (i = 0; i < size; i++)
+ to[i] = from[size - 1 - i];
+ }
+
+unsigned char* copy_sbox(unsigned char* sbox)
+ {
+ unsigned char* copy = OPENSSL_malloc(sizeof(default_sbox));
+
+ if (copy)
+ memcpy(copy, sbox, sizeof(default_sbox));
+
+ return copy;
+ }
+
+int is_default_sbox(unsigned char* sbox)
+ {
+ return !memcmp(default_sbox, sbox, sizeof(default_sbox));
+ }
+
+int bn_encode(const BIGNUM* bn, unsigned char* buffer, int length)
+ {
+ int bn_size = BN_num_bytes(bn);
+ if (length < bn_size)
+ return 0;
+
+ memset(buffer, 0, length - bn_size);
+ return BN_bn2bin(bn, buffer + (length - bn_size));
+ }
diff -urN openssl-1.0.1e/engines/uadstu/dstu_params.h openssl-1.0.1e.patched/engines/uadstu/dstu_params.h
--- openssl-1.0.1e/engines/uadstu/dstu_params.h 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_params.h 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,37 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#ifndef DSTU_PARAMS_H_
+#define DSTU_PARAMS_H_
+
+#include <openssl/ec.h>
+#include "../ccgost/gost89.h"
+
+#define DEFAULT_CURVE 6
+#define get_default_group() group_from_named_curve(DEFAULT_CURVE)
+
+typedef struct dstu_named_curve_st
+ {
+ int nid;
+ int poly[6];
+ unsigned char* data;
+ } DSTU_NAMED_CURVE;
+
+extern DSTU_NAMED_CURVE dstu_curves[];
+extern unsigned char default_sbox[64];
+void unpack_sbox(unsigned char* packed_sbox, gost_subst_block* unpacked_sbox);
+int is_default_sbox(unsigned char* sbox);
+unsigned char* copy_sbox(unsigned char* sbox);
+EC_GROUP* group_from_named_curve(int curve_num);
+EC_GROUP* group_from_nid(int nid);
+int dstu_generate_key(EC_KEY* key);
+int dstu_add_public_key(EC_KEY* key);
+
+void reverse_bytes(void *mem, int size);
+void reverse_bytes_copy(void *dst, const void *src, int size);
+int bn_encode(const BIGNUM* bn, unsigned char* buffer, int length);
+int curve_nid_from_group(const EC_GROUP* group);
+
+#endif /* DSTU_PARAMS_H_ */
diff -urN openssl-1.0.1e/engines/uadstu/dstu_pmeth.c openssl-1.0.1e.patched/engines/uadstu/dstu_pmeth.c
--- openssl-1.0.1e/engines/uadstu/dstu_pmeth.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_pmeth.c 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,418 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_engine.h"
+#include "dstu_key.h"
+#include "dstu_params.h"
+#include <openssl/asn1.h>
+
+#include "e_dstu_err.h"
+
+#define CURVE_PARAM_STR "curve"
+#define SBOX_PARAM_STR "sbox"
+
+/* Since we cannot access fields of EVP_PKEY_CTX to get associated methods to determine method nid later
+ * we use different init callbacks for each method and store the nid in the data field of ctx
+ */
+static int dstu_pkey_init_le(EVP_PKEY_CTX *ctx)
+ {
+ DSTU_KEY_CTX* dstu_ctx = DSTU_KEY_CTX_new();
+
+ if (!dstu_ctx)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_INIT_LE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ dstu_ctx->type = NID_dstu4145le;
+ EVP_PKEY_CTX_set_data(ctx, dstu_ctx);
+ return 1;
+ }
+
+static int dstu_pkey_init_be(EVP_PKEY_CTX *ctx)
+ {
+ DSTU_KEY_CTX* dstu_ctx = DSTU_KEY_CTX_new();
+
+ if (!dstu_ctx)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_INIT_BE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ dstu_ctx->type = NID_dstu4145be;
+ EVP_PKEY_CTX_set_data(ctx, dstu_ctx);
+ return 1;
+ }
+
+static void dstu_pkey_cleanup(EVP_PKEY_CTX *ctx)
+ {
+ DSTU_KEY_CTX* dstu_ctx = EVP_PKEY_CTX_get_data(ctx);
+
+ if (dstu_ctx)
+ {
+ DSTU_KEY_CTX_free(dstu_ctx);
+ /* Just to make sure */
+ EVP_PKEY_CTX_set_data(ctx, NULL);
+ }
+ }
+
+static int dstu_pkey_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+ {
+ DSTU_KEY* key = NULL;
+ DSTU_KEY_CTX* dstu_ctx = EVP_PKEY_CTX_get_data(ctx);
+ unsigned char* sbox = NULL;
+ int ret = 0;
+
+ if (!dstu_ctx)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_KEYGEN, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ if (!(dstu_ctx->group))
+ {
+ dstu_ctx->group = get_default_group();
+ if (!(dstu_ctx->group))
+ return 0;
+ }
+
+ key = DSTU_KEY_new();
+ if (!key)
+ goto err;
+
+ if (!EC_KEY_set_group(key->ec, dstu_ctx->group))
+ goto err;
+
+ if (!dstu_generate_key(key->ec))
+ goto err;
+
+ if (dstu_ctx->sbox)
+ {
+ sbox = copy_sbox(dstu_ctx->sbox);
+ if (!sbox)
+ goto err;
+ DSTU_KEY_set(key, NULL, sbox);
+ }
+
+ if (!EVP_PKEY_assign(pkey, dstu_ctx->type, key))
+ goto err;
+
+ key = NULL;
+ ret = 1;
+
+ err: if (key)
+ DSTU_KEY_free(key);
+
+ return ret;
+ }
+
+static int dstu_pkey_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+ {
+ DSTU_KEY_CTX* dstu_ctx = EVP_PKEY_CTX_get_data(ctx);
+ unsigned char *sbox = NULL;
+ EC_GROUP* group = NULL;
+
+ if (!dstu_ctx)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_CTRL, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ switch (type)
+ {
+ case DSTU_SET_CUSTOM_SBOX:
+ if ((!p2) || (sizeof(default_sbox) != p1))
+ return 0;
+ sbox = copy_sbox((unsigned char *) p2);
+ if (!sbox)
+ return 0;
+
+ DSTU_KEY_CTX_set(dstu_ctx, NULL, sbox);
+ return 1;
+ case DSTU_SET_CURVE:
+ if (!p2)
+ return 0;
+
+ group = EC_GROUP_dup((EC_GROUP*) p2);
+ if (!group)
+ return 0;
+
+ DSTU_KEY_CTX_set(dstu_ctx, group, NULL);
+ return 1;
+ case EVP_PKEY_CTRL_MD:
+ if (NID_dstu34311 != EVP_MD_type((const EVP_MD *) p2))
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_CTRL, DSTU_R_INVALID_DIGEST_TYPE);
+ return 0;
+ }
+ return 1;
+ case EVP_PKEY_CTRL_DIGESTINIT:
+ return 1;
+ }
+ return 0;
+ }
+
+static int dstu_pkey_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+ const char *value)
+ {
+ int curve_nid = NID_undef, res = 0;
+ EC_GROUP* group = NULL;
+ unsigned char sbox[sizeof(default_sbox)];
+ BIGNUM* tmp = NULL;
+
+ if (!strcmp(CURVE_PARAM_STR, type))
+ {
+ curve_nid = OBJ_sn2nid(value);
+ if (NID_undef == curve_nid)
+ return 0;
+
+ group = group_from_nid(curve_nid);
+ if (group)
+ {
+ res = dstu_pkey_ctrl(ctx, DSTU_SET_CURVE, 0, group);
+ EC_GROUP_free(group);
+ }
+ return res;
+ }
+
+ if (!strcmp(SBOX_PARAM_STR, type))
+ {
+ tmp = BN_new();
+ if (!tmp)
+ return 0;
+
+ if ((sizeof(default_sbox) * 2) != BN_hex2bn(&tmp, value))
+ {
+ BN_free(tmp);
+ return 0;
+ }
+
+ if (BN_is_negative(tmp))
+ {
+ BN_free(tmp);
+ return 0;
+ }
+
+ if (bn_encode(tmp, sbox, sizeof(sbox)))
+ res = dstu_pkey_ctrl(ctx, DSTU_SET_CUSTOM_SBOX, sizeof(sbox), sbox);
+ BN_free(tmp);
+ return res;
+ }
+
+ return 0;
+ }
+
+static int dstu_pkey_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+ {
+ EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+ DSTU_KEY* key = NULL;
+ const EC_GROUP* group = NULL;
+ int field_size, ret = 0, encoded_sig_size;
+ ASN1_OCTET_STRING *dstu_sig = NULL;
+ unsigned char *sig_data = NULL;
+
+ if (!pkey)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_SIGN, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ key = EVP_PKEY_get0(pkey);
+ if (!key)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_SIGN, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ group = EC_KEY_get0_group(key->ec);
+ if (!group)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_SIGN, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ field_size = (EC_GROUP_get_degree(group) + 7) / 8;
+ encoded_sig_size = EVP_PKEY_size(pkey);
+
+ if (encoded_sig_size > *siglen)
+ {
+ *siglen = encoded_sig_size;
+ return 0;
+ }
+
+ *siglen = encoded_sig_size;
+
+ if (sig)
+ {
+ dstu_sig = ASN1_OCTET_STRING_new();
+ if (!dstu_sig)
+ goto err;
+
+ sig_data = OPENSSL_malloc(2 * field_size);
+ if (!sig_data)
+ goto err;
+
+ if (!dstu_do_sign(key->ec, tbs, tbslen, sig_data))
+ goto err;
+
+ if (NID_dstu4145le == EVP_PKEY_id(pkey))
+ reverse_bytes(sig_data, 2 * field_size);
+
+ ASN1_STRING_set0((ASN1_STRING *) dstu_sig, sig_data, 2 * field_size);
+ sig_data = NULL;
+
+ *siglen = i2d_ASN1_OCTET_STRING(dstu_sig, &sig);
+ }
+
+ ret = 1;
+
+ err:
+
+ if (sig_data)
+ OPENSSL_free(sig_data);
+
+ if (dstu_sig)
+ ASN1_OCTET_STRING_free(dstu_sig);
+
+ return ret;
+ }
+
+/*static int dstu_pkey_verify_init(EVP_PKEY_CTX *ctx)
+ {
+ return 0;
+ }*/
+
+static int dstu_pkey_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
+ size_t siglen, const unsigned char *tbs, size_t tbslen)
+ {
+ EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+ DSTU_KEY* key = NULL;
+ const EC_GROUP* group = NULL;
+ int field_size, ret = 0;
+ unsigned char *sig_be;
+ ASN1_OCTET_STRING *dstu_sig = NULL;
+
+ if (!pkey)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_VERIFY, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ key = EVP_PKEY_get0(pkey);
+ if (!key)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_VERIFY, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ group = EC_KEY_get0_group(key->ec);
+ if (!group)
+ {
+ DSTUerr(DSTU_F_DSTU_PKEY_VERIFY, DSTU_R_NOT_DSTU_KEY);
+ return 0;
+ }
+
+ field_size = (EC_GROUP_get_degree(group) + 7) / 8;
+
+ if (!d2i_ASN1_OCTET_STRING(&dstu_sig, &sig, siglen))
+ return 0;
+
+ sig = ASN1_STRING_data(dstu_sig);
+ siglen = ASN1_STRING_length(dstu_sig);
+
+ if (siglen & 0x01)
+ goto err;
+
+ if (siglen < (2 * field_size))
+ goto err;
+
+ if (NID_dstu4145le == EVP_PKEY_id(pkey))
+ {
+ /* Signature is little-endian, need to reverse it */
+ sig_be = OPENSSL_malloc(siglen);
+ if (!sig_be)
+ goto err;
+
+ reverse_bytes_copy(sig_be, sig, siglen);
+ ret = dstu_do_verify(key->ec, tbs, tbslen, sig_be, siglen);
+ OPENSSL_free(sig_be);
+ }
+ else
+ ret = dstu_do_verify(key->ec, tbs, tbslen, sig, siglen);
+
+ err: if (dstu_sig)
+ ASN1_OCTET_STRING_free(dstu_sig);
+
+ return ret;
+ }
+
+static int dstu_pkey_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ DSTU_KEY_CTX *dstu_src_ctx = EVP_PKEY_CTX_get_data(src), *dstu_dst_ctx;
+
+ if (dstu_src_ctx)
+ {
+ dstu_dst_ctx = DSTU_KEY_CTX_copy(dstu_src_ctx);
+ if (!dstu_dst_ctx)
+ return 0;
+ EVP_PKEY_CTX_set_data(dst, dstu_dst_ctx);
+ }
+
+ return 1;
+ }
+
+EVP_PKEY_METHOD *dstu_pkey_meth_le = NULL, *dstu_pkey_meth_be = NULL;
+
+int dstu_pkey_meth_init(void)
+ {
+ dstu_pkey_meth_le = EVP_PKEY_meth_new(NID_dstu4145le, 0);
+ if (!dstu_pkey_meth_le)
+ return 0;
+
+ dstu_pkey_meth_be = EVP_PKEY_meth_new(NID_dstu4145be, 0);
+ if (!dstu_pkey_meth_be)
+ {
+ EVP_PKEY_meth_free(dstu_pkey_meth_le);
+ dstu_pkey_meth_le = NULL;
+ return 0;
+ }
+
+ EVP_PKEY_meth_set_init(dstu_pkey_meth_le, dstu_pkey_init_le);
+ EVP_PKEY_meth_set_cleanup(dstu_pkey_meth_le, dstu_pkey_cleanup);
+ EVP_PKEY_meth_set_keygen(dstu_pkey_meth_le, /*dstu_pkey_keygen_init*/NULL,
+ dstu_pkey_keygen);
+ EVP_PKEY_meth_set_ctrl(dstu_pkey_meth_le, dstu_pkey_ctrl,
+ dstu_pkey_ctrl_str);
+ EVP_PKEY_meth_set_sign(dstu_pkey_meth_le, /*dstu_pkey_sign_init*/NULL,
+ dstu_pkey_sign);
+ EVP_PKEY_meth_set_verify(dstu_pkey_meth_le, /*dstu_pkey_verify_init*/NULL,
+ dstu_pkey_verify);
+ EVP_PKEY_meth_set_copy(dstu_pkey_meth_le, dstu_pkey_copy);
+
+ EVP_PKEY_meth_set_init(dstu_pkey_meth_be, dstu_pkey_init_be);
+ EVP_PKEY_meth_set_cleanup(dstu_pkey_meth_be, dstu_pkey_cleanup);
+ EVP_PKEY_meth_set_keygen(dstu_pkey_meth_be, /*dstu_pkey_keygen_init*/NULL,
+ dstu_pkey_keygen);
+ EVP_PKEY_meth_set_ctrl(dstu_pkey_meth_be, dstu_pkey_ctrl,
+ dstu_pkey_ctrl_str);
+ EVP_PKEY_meth_set_sign(dstu_pkey_meth_be, /*dstu_pkey_sign_init*/NULL,
+ dstu_pkey_sign);
+ EVP_PKEY_meth_set_verify(dstu_pkey_meth_be, /*dstu_pkey_verify_init*/NULL,
+ dstu_pkey_verify);
+ EVP_PKEY_meth_set_copy(dstu_pkey_meth_be, dstu_pkey_copy);
+
+ return 1;
+ }
+
+void dstu_pkey_meth_finish(void)
+ {
+ if (dstu_pkey_meth_le)
+ EVP_PKEY_meth_free(dstu_pkey_meth_le);
+
+ if (dstu_pkey_meth_be)
+ EVP_PKEY_meth_free(dstu_pkey_meth_be);
+ }
+
diff -urN openssl-1.0.1e/engines/uadstu/dstu_rbg.c openssl-1.0.1e.patched/engines/uadstu/dstu_rbg.c
--- openssl-1.0.1e/engines/uadstu/dstu_rbg.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_rbg.c 2013-12-28 15:35:08.815997167 +0900
@@ -0,0 +1,140 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include "dstu_engine.h"
+#include "dstu_params.h"
+#include "../ccgost/gost89.h"
+#include <time.h>
+
+static u4 I[2];
+static u4 s[2];
+static gost_ctx cryptor;
+static int initialized = 0;
+
+/* DSTU RGB needs at least 40 bytes of seed to work properly */
+#define DSTU_RGB_SEED_SIZE 40
+
+/* We will reuse OPENSSL's default seeding logic and entropy collecting and will use its default RNG as a seeder */
+static void dstu_rbg_add(const void *buf, int num, double entropy)
+ {
+ RAND_SSLeay()->add(buf, num, entropy);
+ }
+
+static void dstu_rbg_seed(const void *buf, int num)
+ {
+ RAND_SSLeay()->seed(buf, num);
+ }
+
+static int dstu_rbg_init(void)
+ {
+ /* Since time can be 32-bit or 64-bit we will use byte array for time which is always 64-bit */
+ /* For 32-bit time "garbage" in rest of the bytes will even help with seeding */
+ byte curr[8];
+ gost_subst_block sbox;
+ unsigned char seed[DSTU_RGB_SEED_SIZE];
+
+ if (!RAND_SSLeay()->bytes(seed, DSTU_RGB_SEED_SIZE))
+ return 0;
+
+ time((time_t*) curr);
+ unpack_sbox(default_sbox, &sbox);
+
+ gost_init(&cryptor, &sbox);
+ gost_key(&cryptor, seed);
+ memcpy(s, seed + 32, 8);
+ gostcrypt(&cryptor, curr, (byte*) I);
+ initialized = 1;
+
+ OPENSSL_cleanse(seed, sizeof(seed));
+ return 1;
+ }
+
+/* DSTU RBG is bit oriented. It gives one bit at a time */
+static byte dstu_rbg_get_bit(void)
+ {
+ u4 x[2];
+
+ x[0] = I[0] ^ s[0];
+ x[1] = I[1] ^ s[1];
+ gostcrypt(&cryptor, (byte*) x, (byte*) x);
+
+ s[0] = x[0] ^ I[0];
+ s[1] = x[1] ^ I[1];
+ gostcrypt(&cryptor, (byte*) s, (byte*) s);
+
+ return (byte) (x[0] & 1);
+ }
+
+static int dstu_rbg_status(void)
+ {
+ int status = RAND_SSLeay()->status();
+
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ if (status && !initialized)
+ {
+ if (dstu_rbg_init())
+ {
+ initialized = 1;
+ status = initialized;
+ }
+ else
+ status = 0;
+ }
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ return status;
+ }
+
+static int dstu_rbg_bytes(unsigned char *buf, int num)
+ {
+ u4 i;
+ byte j;
+ int rv = 1;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ if (!initialized)
+ {
+ if (!dstu_rbg_status())
+ rv = 0;
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ *(buf + i) = 0;
+ for (j = 0; j < 8; j++)
+ {
+ *(buf + i) |= dstu_rbg_get_bit() << j;
+ }
+ }
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ return rv;
+ }
+
+static void dstu_rbg_cleanup(void)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ OPENSSL_cleanse(I, sizeof(I));
+ OPENSSL_cleanse(s, sizeof(s));
+ OPENSSL_cleanse(&cryptor, sizeof(gost_ctx));
+ initialized = 0;
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ }
+
+RAND_METHOD dstu_rand_meth =
+ {
+ dstu_rbg_seed,
+ dstu_rbg_bytes,
+ dstu_rbg_cleanup,
+ dstu_rbg_add,
+ dstu_rbg_bytes,
+ dstu_rbg_status,
+ };
diff -urN openssl-1.0.1e/engines/uadstu/dstu_sign.c openssl-1.0.1e.patched/engines/uadstu/dstu_sign.c
--- openssl-1.0.1e/engines/uadstu/dstu_sign.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstu_sign.c 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,251 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <string.h>
+#include "dstu_engine.h"
+#include "dstu_params.h"
+
+#include "e_dstu_err.h"
+
+static int bn_truncate_bits(BIGNUM* bn, int bitsize)
+ {
+ int num_bits = BN_num_bits(bn);
+ while (num_bits > bitsize)
+ {
+ if (!BN_clear_bit(bn, num_bits - 1))
+ return 0;
+ num_bits = BN_num_bits(bn);
+ }
+ return 1;
+ }
+
+static int hash_to_field(const unsigned char* hash, int hash_len, BIGNUM* fe,
+ int fieldsize)
+ {
+ unsigned char* h = OPENSSL_malloc(hash_len);
+ int i;
+ if (!h)
+ return 0;
+
+ for (i = 0; i < hash_len; i++)
+ h[i] = hash[hash_len - 1 - i];
+
+ if (!BN_bin2bn(h, hash_len, fe))
+ {
+ OPENSSL_free(h);
+ return 0;
+ }
+
+ OPENSSL_free(h);
+ if (BN_is_zero(fe))
+ BN_one(fe);
+
+ return bn_truncate_bits(fe, fieldsize);
+ }
+
+static int field_to_bn(BIGNUM* fe, const BIGNUM* order)
+ {
+ return bn_truncate_bits(fe, BN_num_bits(order) - 1);
+ }
+
+int dstu_do_sign(const EC_KEY* key, const unsigned char *tbs, size_t tbslen,
+ unsigned char *sig)
+ {
+ const BIGNUM* d = EC_KEY_get0_private_key(key);
+ const EC_GROUP* group = EC_KEY_get0_group(key);
+ BIGNUM *e, *Fe, *h, *r, *s, *n, *p;
+ BN_CTX* ctx = NULL;
+ EC_POINT* eG = NULL;
+ int field_size, ret = 0;
+
+ if (!d || !group)
+ return 0;
+
+ /* DSTU supports only binary fields */
+ if (NID_X9_62_characteristic_two_field
+ != EC_METHOD_get_field_type(EC_GROUP_method_of(group)))
+ {
+ DSTUerr(DSTU_F_DSTU_DO_SIGN, DSTU_R_INCORRECT_FIELD_TYPE);
+ return 0;
+ }
+
+ field_size = (EC_GROUP_get_degree(group) + 7) / 8;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ return 0;
+
+ BN_CTX_start(ctx);
+
+ e = BN_CTX_get(ctx);
+ Fe = BN_CTX_get(ctx);
+ h = BN_CTX_get(ctx);
+ n = BN_CTX_get(ctx);
+ p = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ s = BN_CTX_get(ctx);
+
+ if (!s)
+ goto err;
+
+ if (!EC_GROUP_get_order(group, n, ctx))
+ goto err;
+
+ if (!EC_GROUP_get_curve_GF2m(group, p, NULL, NULL, ctx))
+ goto err;
+
+ eG = EC_POINT_new(group);
+ if (!eG)
+ goto err;
+
+ if (!hash_to_field(tbs, tbslen, h, EC_GROUP_get_degree(group)))
+ goto err;
+
+ do
+ {
+ do
+ {
+ do
+ {
+ if (!BN_rand_range(e, n))
+ goto err;
+
+ if (!EC_POINT_mul(group, eG, e, NULL, NULL, ctx))
+ goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, eG, Fe, NULL,
+ ctx))
+ goto err;
+ }
+ while (BN_is_zero(Fe));
+
+ if (!BN_GF2m_mod_mul(r, h, Fe, p, ctx))
+ goto err;
+
+ if (!field_to_bn(r, n))
+ goto err;
+ }
+ while (BN_is_zero(r));
+
+ if (!BN_mod_mul(s, d, r, n, ctx))
+ goto err;
+
+ if (!BN_mod_add_quick(s, s, e, n))
+ goto err;
+ }
+ while (BN_is_zero(s));
+
+ if (!bn_encode(s, sig, field_size))
+ goto err;
+
+ if (!bn_encode(r, sig + field_size, field_size))
+ goto err;
+
+ ret = 1;
+
+ err: if (eG)
+ EC_POINT_free(eG);
+
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ret;
+ }
+
+int dstu_do_verify(const EC_KEY* key, const unsigned char *tbs, size_t tbslen,
+ const unsigned char *sig, size_t siglen)
+ {
+ const EC_GROUP* group = EC_KEY_get0_group(key);
+ const EC_POINT* Q = EC_KEY_get0_public_key(key);
+ int ret = 0;
+ BN_CTX* ctx = NULL;
+ EC_POINT *R = NULL;
+ BIGNUM *r, *s, *r1, *n, *Rx, *p;
+
+ if (!group || !Q)
+ return 0;
+
+ /* DSTU supports only binary fields */
+ if (NID_X9_62_characteristic_two_field
+ != EC_METHOD_get_field_type(EC_GROUP_method_of(group)))
+ {
+ DSTUerr(DSTU_F_DSTU_DO_VERIFY, DSTU_R_INCORRECT_FIELD_TYPE);
+ return 0;
+ }
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ return 0;
+
+ BN_CTX_start(ctx);
+
+ n = BN_CTX_get(ctx);
+ r1 = BN_CTX_get(ctx);
+ p = BN_CTX_get(ctx);
+ Rx = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ s = BN_CTX_get(ctx);
+
+ if (!s)
+ goto err;
+
+ if (!hash_to_field(tbs, tbslen, r1, EC_GROUP_get_degree(group)))
+ goto err;
+
+ if (!EC_GROUP_get_order(group, n, ctx))
+ goto err;
+
+ if (!EC_GROUP_get_curve_GF2m(group, p, NULL, NULL, ctx))
+ goto err;
+
+ if (!BN_bin2bn(sig, siglen / 2, s))
+ goto err;
+
+ if (!BN_bin2bn(sig + (siglen / 2), siglen / 2, r))
+ goto err;
+
+ if (BN_is_zero(s) || BN_is_zero(r))
+ goto err;
+
+ if ((BN_cmp(s, n) >= 0) || (BN_cmp(r, n) >= 0))
+ goto err;
+
+ R = EC_POINT_new(group);
+ if (!R)
+ goto err;
+
+ if (!EC_POINT_mul(group, R, s, Q, r, ctx))
+ goto err;
+
+ if (EC_POINT_is_at_infinity(group, R))
+ goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, R, Rx, NULL, ctx))
+ goto err;
+
+ if (!BN_GF2m_mod_mul(r1, r1, Rx, p, ctx))
+ goto err;
+
+ if (!field_to_bn(r1, n))
+ goto err;
+
+ if (!BN_cmp(r, r1))
+ ret = 1;
+
+ err: if (R)
+ EC_POINT_free(R);
+
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ return ret;
+ }
diff -urN openssl-1.0.1e/engines/uadstu/dstutest.c openssl-1.0.1e.patched/engines/uadstu/dstutest.c
--- openssl-1.0.1e/engines/uadstu/dstutest.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/dstutest.c 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,302 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#include <stdio.h>
+
+#if defined(OPENSSL_NO_ENGINE) || defined(OPENSSL_NO_DSTU)
+int main(int argc, char *argv[])
+ {
+ printf("No DSTU support\n");
+ return 0;
+ }
+#else
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/conf.h>
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/obj_mac.h>
+
+#include "../engines/uadstu/dstu_params.h"
+
+#define DSTU_ENGINE_ID "dstu"
+#define UADSTU_DIR "../engines/uadstu"
+
+static unsigned char hash[] = {0x10, 0xe6, 0x5a, 0x11, 0xac, 0xcc, 0x36, 0x5e, 0x18, 0x46, 0x67, 0x02, 0xb0, 0x64, 0x6d, 0x74, 0x92, 0x41, 0x9a, 0x9d, 0xa6, 0x57, 0xcf, 0x03, 0x64, 0x52, 0x7c, 0x33, 0x65, 0x55, 0x5b, 0xa7};
+
+static char c163[] = "uacurve0";
+static unsigned char e163[] = {0x01, 0x02, 0x5e, 0x40, 0xbd, 0x97, 0xdb, 0x01, 0x2b, 0x7a, 0x1d, 0x79, 0xde, 0x8e, 0x12, 0x93, 0x2d, 0x24, 0x7f, 0x61, 0xc6};
+static unsigned char d163[] = {0x03, 0xe0, 0x74, 0x8d, 0x62, 0x9e, 0xb5, 0x4a, 0x1d, 0x8f, 0x9a, 0x87, 0xeb, 0xde, 0x12, 0xca, 0x0e, 0xed, 0x48, 0x54, 0xa5};
+static unsigned char s163[] = {0x04, 0x2a, 0x66, 0xa7, 0x40, 0x07, 0x84, 0xa7, 0x4a, 0x72, 0xcc, 0xa7, 0x5b, 0x0c, 0x35, 0x8b, 0x4c, 0xdd, 0x6c, 0x2a, 0xa6, 0x36, 0x00, 0x00, 0xc4, 0x74, 0x66, 0xda, 0xd4, 0xe1, 0x01, 0x1b, 0x3e, 0x18, 0x95, 0x27, 0x72, 0xc0, 0x80, 0xa9, 0xa3, 0x1b, 0x31, 0x01};
+
+static char c257[] = "uacurve6";
+static unsigned char e257[] = {0x00, 0x43, 0x94, 0xe1, 0x9d, 0xcc, 0x1d, 0xef, 0x57, 0xdd, 0xbe, 0x6f, 0xb7, 0x05, 0x65, 0xc7, 0x49, 0xf2, 0x21, 0x44, 0x62, 0x6f, 0x05, 0x0a, 0x6d, 0xaa, 0xb4, 0xaf, 0x00, 0x71, 0xe6, 0xfe, 0xb9};
+static unsigned char d257[] = {0x00, 0x6f, 0x31, 0xc4, 0x44, 0x59, 0x14, 0xfb, 0x34, 0x7b, 0xa9, 0xbd, 0x27, 0x2b, 0xb5, 0xb7, 0xf5, 0x13, 0x42, 0x2f, 0xe1, 0x16, 0xdf, 0xa4, 0xf0, 0xdf, 0x34, 0xb1, 0xce, 0xb1, 0x1a, 0x64, 0x5c};
+static unsigned char s257[] = {0x04, 0x42, 0x6f, 0x77, 0x37, 0xe8, 0x65, 0xd2, 0x50, 0xd7, 0x0a, 0x29, 0xea, 0xdf, 0xe3, 0xc2, 0x3d, 0x37, 0x0c, 0x3f, 0xa7, 0xb5, 0xc9, 0x43, 0xcd, 0xed, 0x1b, 0x72, 0xf3, 0xe1, 0x53, 0x2d, 0x2c, 0x09, 0x00, 0xe1, 0x8b, 0x17, 0x72, 0x1d, 0xab, 0xeb, 0xec, 0x39, 0xbd, 0x4a, 0x87, 0x9a, 0xb0, 0x50, 0x7d, 0x80, 0xe9, 0x99, 0xe1, 0xea, 0x5d, 0x65, 0xb5, 0x56, 0xd6, 0xf1, 0x66, 0x44, 0x8b, 0xee, 0x26, 0x00};
+
+static char c431[] = "uacurve9";
+static unsigned char e431[] = {0x04, 0x57, 0xce, 0x62, 0x0e, 0x2b, 0x71, 0x10, 0x0d, 0x87, 0xf7, 0xe1, 0xc2, 0x32, 0x38, 0xaa, 0x36, 0x29, 0xba, 0x52, 0xc6, 0xba, 0xb4, 0x2c, 0x6a, 0x22, 0xdb, 0x43, 0x78, 0x15, 0xcc, 0xfe, 0xb9, 0xa4, 0x47, 0xb0, 0x2a, 0x82, 0x98, 0xe5, 0x26, 0x0a, 0x7f, 0xa9, 0x4a, 0x13, 0xc1, 0x82, 0x2d, 0x88, 0x5e, 0x8c, 0x5c, 0x69};
+static unsigned char d431[] = {0x31, 0x13, 0x1b, 0xec, 0x94, 0x8d, 0xac, 0xbb, 0xaf, 0xad, 0xbf, 0x9b, 0xb1, 0x50, 0xb0, 0xb7, 0x92, 0xdf, 0x32, 0x24, 0x79, 0x2a, 0x80, 0xf6, 0x76, 0x1a, 0x0b, 0x03, 0xb3, 0xb8, 0x2d, 0x11, 0x8b, 0xc3, 0xc2, 0x27, 0x1c, 0x04, 0xa0, 0x4c, 0x2d, 0x9b, 0x38, 0x76, 0xc2, 0x33, 0x86, 0x0b, 0x19, 0x0d, 0xcc, 0xea, 0x01, 0x77};
+static unsigned char s431[] = {0x04, 0x6c, 0xc4, 0xe4, 0xf0, 0xb5, 0xea, 0xb8, 0xe7, 0xaa, 0xf4, 0x17, 0xa6, 0xb5, 0xd1, 0xd7, 0x4f, 0xe5, 0x34, 0x81, 0x64, 0x50, 0xdf, 0x6d, 0xff, 0xd9, 0x37, 0x7d, 0xfc, 0xac, 0x5f, 0x25, 0x67, 0x6a, 0x11, 0x9e, 0x5f, 0x70, 0x0f, 0x92, 0xc2, 0x7c, 0x80, 0x17, 0xb6, 0xb3, 0xe3, 0xc2, 0x05, 0xf2, 0x74, 0xd5, 0x4c, 0xd3, 0x33, 0x00, 0xdd, 0x1e, 0xe8, 0x43, 0x63, 0x85, 0x69, 0xe1, 0x10, 0xe4, 0x15, 0xc4, 0x46, 0x0e, 0x4e, 0xb3, 0x25, 0x8f, 0xcf, 0xa7, 0x50, 0x98, 0xa5, 0xce, 0xb5, 0xad, 0x35, 0xb8, 0xfd, 0x28, 0xd1, 0x21, 0x06, 0xb5, 0x51, 0x14, 0x87, 0x43, 0x45, 0xef, 0x7d, 0xc1, 0xa1, 0x45, 0xa5, 0xbb, 0x1c, 0xcf, 0x27, 0x4b, 0x5d, 0x64, 0x80, 0x11};
+
+struct dstu_test_vector
+ {
+ char *curve;
+ int field_byte_size;
+ unsigned char *e;
+ unsigned char *d;
+ unsigned char *s;
+ };
+
+static struct dstu_test_vector vectors[] =
+ {
+ {c163, 21, e163, d163, s163},
+ {c257, 33, e257, d257, s257},
+ {c431, 54, e431, d431, s431}
+ };
+
+static unsigned char *rand_source;
+static int rand_size;
+static RAND_METHOD fake_rand;
+static const RAND_METHOD *old_rand;
+
+static int fbytes(unsigned char *buf, int num)
+ {
+ int to_copy = num;
+
+ while (to_copy)
+ {
+ memcpy(buf, rand_source, (to_copy > rand_size) ? rand_size : to_copy);
+ buf += (to_copy > rand_size) ? rand_size : to_copy;
+ to_copy -= (to_copy > rand_size) ? rand_size : to_copy;
+ }
+
+ return num;
+ }
+
+static int change_rand(void)
+ {
+ /* save old rand method */
+ if ((old_rand = RAND_get_rand_method()) == NULL)
+ return 0;
+
+ fake_rand.seed = old_rand->seed;
+ fake_rand.cleanup = old_rand->cleanup;
+ fake_rand.add = old_rand->add;
+ fake_rand.status = old_rand->status;
+ /* use own random function */
+ fake_rand.bytes = fbytes;
+ fake_rand.pseudorand = old_rand->bytes;
+ /* set new RAND_METHOD */
+ if (!RAND_set_rand_method(&fake_rand))
+ return 0;
+ return 1;
+ }
+
+static int restore_rand(void)
+ {
+ if (!RAND_set_rand_method(old_rand))
+ return 0;
+ else
+ return 1;
+ }
+
+static ENGINE* load_dstu(void)
+ {
+ ENGINE* ret = 0;
+ CONF *pConfig = NCONF_new(NULL);
+ BIO *bpConf = NULL;
+ long lErrLine;
+ char sConf[] = "openssl_conf = openssl_def\n"
+ "\n"
+ "[openssl_def]\n"
+ "engines = engine_section\n"
+ "\n"
+ "[engine_section]\n"
+ "dstu = dstu_section\n"
+ "\n"
+ "[dstu_section]\n"
+ "default_algorithms = ALL\n"
+ "\n";
+
+ if (!pConfig)
+ return 0;
+
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+ setenv("OPENSSL_ENGINES", UADSTU_DIR, 1);
+#endif
+ ERR_load_crypto_strings();
+ ENGINE_load_builtin_engines();
+ OPENSSL_load_builtin_modules();
+
+ bpConf = BIO_new_mem_buf(sConf, -1);
+ if (!bpConf)
+ goto err;
+
+ if (!NCONF_load_bio(pConfig, bpConf, &lErrLine))
+ {
+ fflush(NULL);
+ fprintf(stderr, "NCONF_load_bio: ErrLine=%ld: %s\n", lErrLine,
+ ERR_error_string(ERR_get_error(), NULL));
+ goto err;
+ }
+
+ if (!CONF_modules_load(pConfig, NULL, 0))
+ {
+ fflush(NULL);
+ fprintf(stderr, "CONF_modules_load: %s\n",
+ ERR_error_string(ERR_get_error(), NULL));
+ goto err;
+ }
+
+ ret = ENGINE_by_id(DSTU_ENGINE_ID);
+ if (!ret)
+ {
+ fflush(NULL);
+ fprintf(stderr, "Can't load engine id \"" DSTU_ENGINE_ID "\"\n");
+ goto err;
+ }
+
+ err: if (bpConf)
+ BIO_free(bpConf);
+
+ if (pConfig)
+ NCONF_free(pConfig);
+
+ return ret;
+ }
+
+int main(int argc, char *argv[])
+ {
+ EVP_PKEY_CTX *pkey_ctx = NULL;
+ EVP_PKEY *pkey = NULL;
+ ENGINE *dstu = load_dstu();
+ unsigned char sig[256];
+ size_t siglen = sizeof(sig);
+ struct dstu_test_vector *vector;
+ int ret = 1;
+
+ if (!dstu)
+ return 0;
+
+ printf("Testing DSTU 4145-2002\n");
+ fflush(NULL);
+
+ if (!change_rand())
+ {
+ fprintf(stderr, "Change random failed\n");
+ fflush(NULL);
+ return 1;
+ }
+
+ pkey = EVP_PKEY_new();
+ if (!pkey)
+ {
+ fprintf(stderr, "EVP_PKEY_new() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ if (!EVP_PKEY_set_type(pkey, NID_dstu4145le))
+ {
+ fprintf(stderr, "EVP_PKEY_set_type() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!pkey_ctx)
+ {
+ fprintf(stderr, "EVP_PKEY_CTX_new() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ for (vector = vectors; vector < vectors + (sizeof(vectors)/sizeof(struct dstu_test_vector)); vector++)
+ {
+ if (!EVP_PKEY_CTX_ctrl_str(pkey_ctx, "curve", vector->curve))
+ {
+ fprintf(stderr, "EVP_PKEY_CTX_ctrl_str() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ rand_source = vector->d;
+ rand_size = vector->field_byte_size;
+
+ if (!EVP_PKEY_keygen_init(pkey_ctx))
+ {
+ fprintf(stderr, "EVP_PKEY_keygen_init() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ if (!EVP_PKEY_keygen(pkey_ctx, &pkey))
+ {
+ fprintf(stderr, "EVP_PKEY_keygen() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ rand_source = vector->e;
+
+ if (!EVP_PKEY_sign_init(pkey_ctx))
+ {
+ fprintf(stderr, "EVP_PKEY_sign_init() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ if (!EVP_PKEY_sign(pkey_ctx, sig, &siglen, hash, sizeof(hash)))
+ {
+ fprintf(stderr, "EVP_PKEY_sign() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ if (memcmp(sig, vector->s, siglen))
+ {
+ fprintf(stderr, "%s: test signature mismatch\n", vector->curve);
+ fflush(NULL);
+ goto err;
+ }
+
+ if (!EVP_PKEY_verify_init(pkey_ctx))
+ {
+ fprintf(stderr, "EVP_PKEY_verify_init() failed\n");
+ fflush(NULL);
+ goto err;
+ }
+
+ if (1 != EVP_PKEY_verify(pkey_ctx, sig, siglen, hash, sizeof(hash)))
+ {
+ fprintf(stderr, "%s: test signature verification failed\n", vector->curve);
+ fflush(NULL);
+ goto err;
+ }
+
+ siglen = sizeof(sig);
+ }
+
+ ret = 0;
+ printf("Passed\n");
+ fflush(NULL);
+
+err:
+ if (pkey_ctx)
+ EVP_PKEY_CTX_free(pkey_ctx);
+
+ if (pkey)
+ EVP_PKEY_free(pkey);
+
+ restore_rand();
+
+ return ret;
+ }
+#endif
diff -urN openssl-1.0.1e/engines/uadstu/e_dstu_err.c openssl-1.0.1e.patched/engines/uadstu/e_dstu_err.c
--- openssl-1.0.1e/engines/uadstu/e_dstu_err.c 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/e_dstu_err.c 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,162 @@
+/* e_dstu_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_dstu_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(0,func,0)
+#define ERR_REASON(reason) ERR_PACK(0,0,reason)
+
+static ERR_STRING_DATA DSTU_str_functs[]=
+ {
+{ERR_FUNC(DSTU_F_BIND_DSTU), "BIND_DSTU"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PARAM_COPY), "DSTU_ASN1_PARAM_COPY"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PARAM_DECODE), "DSTU_ASN1_PARAM_DECODE"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PARAM_ENCODE), "DSTU_ASN1_PARAM_ENCODE"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PARAM_PRINT), "DSTU_ASN1_PARAM_PRINT"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PRIV_DECODE), "DSTU_ASN1_PRIV_DECODE"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PRIV_ENCODE), "DSTU_ASN1_PRIV_ENCODE"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PUB_DECODE), "DSTU_ASN1_PUB_DECODE"},
+{ERR_FUNC(DSTU_F_DSTU_ASN1_PUB_ENCODE), "DSTU_ASN1_PUB_ENCODE"},
+{ERR_FUNC(DSTU_F_DSTU_DO_SIGN), "DSTU_DO_SIGN"},
+{ERR_FUNC(DSTU_F_DSTU_DO_VERIFY), "DSTU_DO_VERIFY"},
+{ERR_FUNC(DSTU_F_DSTU_PKEY_CTRL), "DSTU_PKEY_CTRL"},
+{ERR_FUNC(DSTU_F_DSTU_PKEY_INIT_BE), "DSTU_PKEY_INIT_BE"},
+{ERR_FUNC(DSTU_F_DSTU_PKEY_INIT_LE), "DSTU_PKEY_INIT_LE"},
+{ERR_FUNC(DSTU_F_DSTU_PKEY_KEYGEN), "DSTU_PKEY_KEYGEN"},
+{ERR_FUNC(DSTU_F_DSTU_PKEY_SIGN), "DSTU_PKEY_SIGN"},
+{ERR_FUNC(DSTU_F_DSTU_PKEY_VERIFY), "DSTU_PKEY_VERIFY"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA DSTU_str_reasons[]=
+ {
+{ERR_REASON(DSTU_R_AMETH_INIT_FAILED) ,"ameth init failed"},
+{ERR_REASON(DSTU_R_ASN1_PARAMETER_ENCODE_FAILED),"asn1 parameter encode failed"},
+{ERR_REASON(DSTU_R_INCORRECT_FIELD_TYPE) ,"incorrect field type"},
+{ERR_REASON(DSTU_R_INVALID_ASN1_PARAMETERS),"invalid asn1 parameters"},
+{ERR_REASON(DSTU_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
+{ERR_REASON(DSTU_R_NOT_DSTU_KEY) ,"not dstu key"},
+{ERR_REASON(DSTU_R_PMETH_INIT_FAILED) ,"pmeth init failed"},
+{ERR_REASON(DSTU_R_POINT_COMPRESS_FAILED),"point compress failed"},
+{ERR_REASON(DSTU_R_POINT_UNCOMPRESS_FAILED),"point uncompress failed"},
+{0,NULL}
+ };
+
+#endif
+
+#ifdef DSTU_LIB_NAME
+static ERR_STRING_DATA DSTU_lib_name[]=
+ {
+{0 ,DSTU_LIB_NAME},
+{0,NULL}
+ };
+#endif
+
+
+static int DSTU_lib_error_code=0;
+static int DSTU_error_init=1;
+
+void ERR_load_DSTU_strings(void)
+ {
+ if (DSTU_lib_error_code == 0)
+ DSTU_lib_error_code=ERR_get_next_error_library();
+
+ if (DSTU_error_init)
+ {
+ DSTU_error_init=0;
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(DSTU_lib_error_code,DSTU_str_functs);
+ ERR_load_strings(DSTU_lib_error_code,DSTU_str_reasons);
+#endif
+
+#ifdef DSTU_LIB_NAME
+ DSTU_lib_name->error = ERR_PACK(DSTU_lib_error_code,0,0);
+ ERR_load_strings(0,DSTU_lib_name);
+#endif
+ }
+ }
+
+void ERR_unload_DSTU_strings(void)
+ {
+ if (DSTU_error_init == 0)
+ {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(DSTU_lib_error_code,DSTU_str_functs);
+ ERR_unload_strings(DSTU_lib_error_code,DSTU_str_reasons);
+#endif
+
+#ifdef DSTU_LIB_NAME
+ ERR_unload_strings(0,DSTU_lib_name);
+#endif
+ DSTU_error_init=1;
+ }
+ }
+
+void ERR_DSTU_error(int function, int reason, char *file, int line)
+ {
+ if (DSTU_lib_error_code == 0)
+ DSTU_lib_error_code=ERR_get_next_error_library();
+ ERR_PUT_error(DSTU_lib_error_code,function,reason,file,line);
+ }
diff -urN openssl-1.0.1e/engines/uadstu/e_dstu_err.h openssl-1.0.1e.patched/engines/uadstu/e_dstu_err.h
--- openssl-1.0.1e/engines/uadstu/e_dstu_err.h 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/e_dstu_err.h 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,59 @@
+/* =====================================================================
+ * Author: Ignat Korchagin <ignat.korchagin@gmail.com>
+ * This file is distributed under the same license as OpenSSL
+ ==================================================================== */
+
+#ifndef HEADER_DSTU_ERR_H
+#define HEADER_DSTU_ERR_H
+
+#include <openssl/err.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSTU_strings(void);
+void ERR_unload_DSTU_strings(void);
+void ERR_DSTU_error(int function, int reason, char *file, int line);
+#define DSTUerr(f,r) ERR_DSTU_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the DSTU functions. */
+
+/* Function codes. */
+#define DSTU_F_BIND_DSTU 100
+#define DSTU_F_DSTU_ASN1_PARAM_COPY 102
+#define DSTU_F_DSTU_ASN1_PARAM_DECODE 101
+#define DSTU_F_DSTU_ASN1_PARAM_ENCODE 103
+#define DSTU_F_DSTU_ASN1_PARAM_PRINT 104
+#define DSTU_F_DSTU_ASN1_PRIV_DECODE 105
+#define DSTU_F_DSTU_ASN1_PRIV_ENCODE 106
+#define DSTU_F_DSTU_ASN1_PUB_DECODE 107
+#define DSTU_F_DSTU_ASN1_PUB_ENCODE 108
+#define DSTU_F_DSTU_DO_SIGN 109
+#define DSTU_F_DSTU_DO_VERIFY 110
+#define DSTU_F_DSTU_PKEY_CTRL 116
+#define DSTU_F_DSTU_PKEY_INIT_BE 111
+#define DSTU_F_DSTU_PKEY_INIT_LE 112
+#define DSTU_F_DSTU_PKEY_KEYGEN 113
+#define DSTU_F_DSTU_PKEY_SIGN 114
+#define DSTU_F_DSTU_PKEY_VERIFY 115
+
+/* Reason codes. */
+#define DSTU_R_AMETH_INIT_FAILED 100
+#define DSTU_R_ASN1_PARAMETER_ENCODE_FAILED 103
+#define DSTU_R_INCORRECT_FIELD_TYPE 107
+#define DSTU_R_INVALID_ASN1_PARAMETERS 102
+#define DSTU_R_INVALID_DIGEST_TYPE 108
+#define DSTU_R_NOT_DSTU_KEY 104
+#define DSTU_R_PMETH_INIT_FAILED 101
+#define DSTU_R_POINT_COMPRESS_FAILED 105
+#define DSTU_R_POINT_UNCOMPRESS_FAILED 106
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff -urN openssl-1.0.1e/engines/uadstu/LICENSE openssl-1.0.1e.patched/engines/uadstu/LICENSE
--- openssl-1.0.1e/engines/uadstu/LICENSE 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/LICENSE 2013-12-28 12:56:38.717489000 +0900
@@ -0,0 +1,126 @@
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. Actually both licenses are BSD-style
+ Open Source licenses. In case of any license issues related to OpenSSL
+ please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
diff -urN openssl-1.0.1e/engines/uadstu/Makefile openssl-1.0.1e.patched/engines/uadstu/Makefile
--- openssl-1.0.1e/engines/uadstu/Makefile 1970-01-01 09:00:00.000000000 +0900
+++ openssl-1.0.1e.patched/engines/uadstu/Makefile 2013-12-28 12:58:12.997957000 +0900
@@ -0,0 +1,243 @@
+DIR=uadstu
+TOP=../..
+CC=cc
+INCLUDES= -I../../include
+CFLAG=-g
+MAKEFILE= Makefile
+AR= ar r
+CFLAGS= $(INCLUDES) $(CFLAG)
+LIB=$(TOP)/libcrypto.a
+
+TEST=dstutest.c
+
+LIBSRC= dstu_ameth.c dstu_asn1.c dstu_cipher.c dstu_compress.c dstu_engine.c dstu_key.c dstu_md.c dstu_params.c dstu_pmeth.c dstu_sign.c dstu89.c dstuhash.c dstu_rbg.c
+
+LIBOBJ= e_dstu_err.o dstu_ameth.o dstu_asn1.o dstu_cipher.o dstu_compress.o dstu_engine.o dstu_key.o dstu_md.o dstu_params.o dstu_pmeth.o dstu_sign.o dstu89.o dstuhash.o dstu_rbg.o
+
+SRC=$(LIBSRC)
+
+LIBNAME=dstu
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=engines EDIRS=$(DIR) sub_all)
+
+all: lib
+
+tags:
+ ctags $(SRC)
+
+errors:
+ $(PERL) ../../util/mkerr.pl -conf dstu.ec -nostatic -write $(SRC)
+
+lib: $(LIBOBJ)
+ if [ -n "$(SHARED_LIBS)" ]; then \
+ $(MAKE) -f $(TOP)/Makefile.shared -e \
+ LIBNAME=$(LIBNAME) \
+ LIBEXTRAS='$(LIBOBJ)' \
+ LIBDEPS='-L$(TOP) -lcrypto' \
+ link_o.$(SHLIB_TARGET); \
+ else \
+ $(AR) $(LIB) $(LIBOBJ); \
+ fi
+ @touch lib
+
+install:
+ [ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+ if [ -n "$(SHARED_LIBS)" ]; then \
+ set -e; \
+ echo installing $(LIBNAME); \
+ pfx=lib; \
+ if [ "$(PLATFORM)" != "Cygwin" ]; then \
+ case "$(CFLAGS)" in \
+ *DSO_BEOS*) sfx=".so";; \
+ *DSO_DLFCN*) sfx=`expr "$(SHLIB_EXT)" : '.*\(\.[a-z][a-z]*\)' \| ".so"`;; \
+ *DSO_DL*) sfx=".sl";; \
+ *DSO_WIN32*) sfx="eay32.dll"; pfx=;; \
+ *) sfx=".bad";; \
+ esac; \
+ cp $${pfx}$(LIBNAME)$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
+ else \
+ sfx=".so"; \
+ cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
+ fi; \
+ chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx; \
+ fi
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+
+tests:
+
+depend:
+ @if [ -z "$(THIS)" ]; then \
+ $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
+ else \
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
+ fi
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll *.dylib
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+dstu89.o: ../ccgost/gost89.c ../ccgost/gost89.h dstu89.c
+dstu_ameth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+dstu_ameth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+dstu_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dstu_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+dstu_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+dstu_ameth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dstu_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dstu_ameth.o: ../../include/openssl/objects.h
+dstu_ameth.o: ../../include/openssl/opensslconf.h
+dstu_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dstu_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dstu_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dstu_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dstu_ameth.o: ../../include/openssl/x509_vfy.h ../ccgost/gost89.h dstu_ameth.c
+dstu_ameth.o: dstu_asn1.h dstu_compress.h dstu_engine.h dstu_key.h
+dstu_ameth.o: dstu_params.h e_dstu_err.h
+dstu_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+dstu_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+dstu_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dstu_asn1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+dstu_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+dstu_asn1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dstu_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dstu_asn1.o: ../../include/openssl/objects.h
+dstu_asn1.o: ../../include/openssl/opensslconf.h
+dstu_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dstu_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dstu_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dstu_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dstu_asn1.o: ../../include/openssl/x509_vfy.h dstu_asn1.c dstu_asn1.h
+dstu_asn1.o: dstu_engine.h
+dstu_cipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dstu_cipher.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dstu_cipher.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dstu_cipher.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dstu_cipher.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dstu_cipher.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+dstu_cipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dstu_cipher.o: ../../include/openssl/opensslconf.h
+dstu_cipher.o: ../../include/openssl/opensslv.h
+dstu_cipher.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+dstu_cipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+dstu_cipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dstu_cipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+dstu_cipher.o: ../ccgost/gost89.h dstu_cipher.c dstu_engine.h dstu_params.h
+dstu_compress.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dstu_compress.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dstu_compress.o: ../../include/openssl/ec.h ../../include/openssl/opensslconf.h
+dstu_compress.o: ../../include/openssl/opensslv.h
+dstu_compress.o: ../../include/openssl/ossl_typ.h
+dstu_compress.o: ../../include/openssl/safestack.h
+dstu_compress.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dstu_compress.o: ../ccgost/gost89.h dstu_compress.c dstu_compress.h
+dstu_compress.o: dstu_params.h
+dstu_engine.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dstu_engine.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dstu_engine.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dstu_engine.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dstu_engine.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dstu_engine.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+dstu_engine.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dstu_engine.o: ../../include/openssl/opensslconf.h
+dstu_engine.o: ../../include/openssl/opensslv.h
+dstu_engine.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+dstu_engine.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+dstu_engine.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dstu_engine.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+dstu_engine.o: ../ccgost/gost89.h dstu_engine.c dstu_engine.h dstu_params.h
+dstu_engine.o: e_dstu_err.h
+dstu_key.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+dstu_key.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+dstu_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dstu_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dstu_key.o: ../../include/openssl/opensslconf.h
+dstu_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dstu_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dstu_key.o: ../../include/openssl/symhacks.h ../ccgost/gost89.h dstu_asn1.h
+dstu_key.o: dstu_compress.h dstu_key.c dstu_key.h dstu_params.h
+dstu_md.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+dstu_md.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+dstu_md.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dstu_md.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+dstu_md.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+dstu_md.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dstu_md.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dstu_md.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dstu_md.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dstu_md.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dstu_md.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dstu_md.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dstu_md.o: ../../include/openssl/x509_vfy.h ../ccgost/gost89.h
+dstu_md.o: ../ccgost/gosthash.h dstu_asn1.h dstu_engine.h dstu_key.h dstu_md.c
+dstu_md.o: dstu_params.h
+dstu_params.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dstu_params.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dstu_params.o: ../../include/openssl/ec.h ../../include/openssl/evp.h
+dstu_params.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dstu_params.o: ../../include/openssl/opensslconf.h
+dstu_params.o: ../../include/openssl/opensslv.h
+dstu_params.o: ../../include/openssl/ossl_typ.h
+dstu_params.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dstu_params.o: ../../include/openssl/symhacks.h ../ccgost/gost89.h
+dstu_params.o: dstu_params.c dstu_params.h
+dstu_pmeth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
+dstu_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+dstu_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dstu_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+dstu_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+dstu_pmeth.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dstu_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dstu_pmeth.o: ../../include/openssl/objects.h
+dstu_pmeth.o: ../../include/openssl/opensslconf.h
+dstu_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dstu_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dstu_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dstu_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dstu_pmeth.o: ../../include/openssl/x509_vfy.h ../ccgost/gost89.h dstu_asn1.h
+dstu_pmeth.o: dstu_engine.h dstu_key.h dstu_params.h dstu_pmeth.c e_dstu_err.h
+dstu_rbg.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dstu_rbg.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dstu_rbg.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dstu_rbg.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dstu_rbg.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dstu_rbg.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+dstu_rbg.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dstu_rbg.o: ../../include/openssl/opensslconf.h
+dstu_rbg.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dstu_rbg.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dstu_rbg.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dstu_rbg.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dstu_rbg.o: ../../include/openssl/x509_vfy.h ../ccgost/gost89.h dstu_engine.h
+dstu_rbg.o: dstu_params.h dstu_rbg.c
+dstu_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dstu_sign.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dstu_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dstu_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+dstu_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+dstu_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dstu_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dstu_sign.o: ../../include/openssl/objects.h
+dstu_sign.o: ../../include/openssl/opensslconf.h
+dstu_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dstu_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dstu_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dstu_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dstu_sign.o: ../../include/openssl/x509_vfy.h ../ccgost/gost89.h dstu_engine.h
+dstu_sign.o: dstu_params.h dstu_sign.c e_dstu_err.h
+dstuhash.o: ../ccgost/gost89.h ../ccgost/gosthash.c ../ccgost/gosthash.h
+dstuhash.o: dstuhash.c
diff -urN openssl-1.0.1e/Makefile.org openssl-1.0.1e.patched/Makefile.org
--- openssl-1.0.1e/Makefile.org 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/Makefile.org 2013-12-28 15:32:08.139101245 +0900
@@ -136,7 +136,7 @@
BASEADDR=
DIRS= crypto ssl engines apps test tools
-ENGDIRS= ccgost
+ENGDIRS= ccgost uadstu
SHLIBDIRS= crypto ssl
# dirs in crypto to build
diff -urN openssl-1.0.1e/test/Makefile openssl-1.0.1e.patched/test/Makefile
--- openssl-1.0.1e/test/Makefile 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/test/Makefile 2013-12-28 15:32:08.139101245 +0900
@@ -63,6 +63,7 @@
JPAKETEST= jpaketest
SRPTEST= srptest
ASN1TEST= asn1test
+DSTUTEST= dstutest
TESTS= alltests
@@ -72,6 +73,7 @@
$(DESTEST)$(EXE_EXT) $(SHATEST)$(EXE_EXT) $(SHA1TEST)$(EXE_EXT) $(SHA256TEST)$(EXE_EXT) $(SHA512TEST)$(EXE_EXT) \
$(MDC2TEST)$(EXE_EXT) $(RMDTEST)$(EXE_EXT) \
$(RANDTEST)$(EXE_EXT) $(DHTEST)$(EXE_EXT) $(ENGINETEST)$(EXE_EXT) \
+ $(DSTUTEST)$(EXE_EXT) \
$(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) $(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \
$(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) $(SRPTEST)$(EXE_EXT) \
$(ASN1TEST)$(EXE_EXT)
@@ -86,7 +88,7 @@
$(MDC2TEST).o $(RMDTEST).o \
$(RANDTEST).o $(DHTEST).o $(ENGINETEST).o $(CASTTEST).o \
$(BFTEST).o $(SSLTEST).o $(DSATEST).o $(EXPTEST).o $(RSATEST).o \
- $(EVPTEST).o $(IGETEST).o $(JPAKETEST).o $(ASN1TEST).o
+ $(EVPTEST).o $(IGETEST).o $(JPAKETEST).o $(ASN1TEST).o $(DSTUTEST).o
SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
$(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \
$(HMACTEST).c $(WPTEST).c \
@@ -94,7 +96,8 @@
$(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \
$(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \
$(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c \
- $(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c
+ $(EVPTEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c \
+ $(DSTUTEST).c
EXHEADER=
HEADER= $(EXHEADER)
@@ -137,7 +140,7 @@
test_enc test_x509 test_rsa test_crl test_sid \
test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
test_ss test_ca test_engine test_evp test_ssl test_tsa test_ige \
- test_jpake test_srp test_cms
+ test_jpake test_srp test_cms test_dstu
test_evp:
../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
@@ -318,6 +321,9 @@
@echo "Test SRP"
../util/shlib_wrap.sh ./srptest
+test_dstu: $(DSTUTEST)
+ ../util/shlib_wrap.sh ./$(DSTUTEST)
+
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
@@ -430,6 +436,9 @@
$(DESTEST)$(EXE_EXT): $(DESTEST).o $(DLIBCRYPTO)
@target=$(DESTEST); $(BUILD_CMD)
+$(DSTUTEST)$(EXE_EXT): $(DSTUTEST).o $(DLIBCRYPTO)
+ @target=$(DSTUTEST); $(BUILD_CMD)
+
$(RANDTEST)$(EXE_EXT): $(RANDTEST).o $(DLIBCRYPTO)
@target=$(RANDTEST); $(BUILD_CMD)
diff -urN openssl-1.0.1e/util/mk1mf.pl openssl-1.0.1e.patched/util/mk1mf.pl
--- openssl-1.0.1e/util/mk1mf.pl 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/util/mk1mf.pl 2013-12-28 15:32:08.139101245 +0900
@@ -276,6 +276,7 @@
$cflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
$cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
$cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
+$cflags.=" -DOPENSSL_NO_DSTU" if $no_dstu;
$cflags.=" -DOPENSSL_NO_ENGINE" if $no_engine;
$cflags.=" -DOPENSSL_NO_HW" if $no_hw;
$cflags.=" -DOPENSSL_FIPS" if $fips;
@@ -783,6 +784,7 @@
return("") if $no_dh && $dir =~ /\/dh/;
return("") if $no_ec && $dir =~ /\/ec/;
return("") if $no_gost && $dir =~ /\/ccgost/;
+ return("") if $no_dstu && $dir =~ /\/uadstu/;
return("") if $no_cms && $dir =~ /\/cms/;
return("") if $no_jpake && $dir =~ /\/jpake/;
if ($no_des && $dir =~ /\/des/)
@@ -1129,6 +1131,7 @@
"no-ecdsa" => \$no_ecdsa,
"no-ecdh" => \$no_ecdh,
"no-gost" => \$no_gost,
+ "no-dstu" => \$no_dstu,
"no-engine" => \$no_engine,
"no-hw" => \$no_hw,
"no-rsax" => 0,
diff -urN openssl-1.0.1e/util/mkdef.pl openssl-1.0.1e.patched/util/mkdef.pl
--- openssl-1.0.1e/util/mkdef.pl 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/util/mkdef.pl 2013-12-28 15:32:08.143101259 +0900
@@ -85,7 +85,7 @@
"CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
"SHA256", "SHA512", "RIPEMD",
"MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M",
- "HMAC", "AES", "CAMELLIA", "SEED", "GOST",
+ "HMAC", "AES", "CAMELLIA", "SEED", "GOST", "DSTU",
# EC_NISTP_64_GCC_128
"EC_NISTP_64_GCC_128",
# Envelope "algorithms"
diff -urN openssl-1.0.1e/util/mkfiles.pl openssl-1.0.1e.patched/util/mkfiles.pl
--- openssl-1.0.1e/util/mkfiles.pl 2013-02-12 00:26:04.000000000 +0900
+++ openssl-1.0.1e.patched/util/mkfiles.pl 2013-12-28 15:32:08.143101259 +0900
@@ -68,6 +68,7 @@
"apps",
"engines",
"engines/ccgost",
+"engines/uadstu",
"test",
"tools"
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment