Hello guys.
Just after 5.9 tag, sending you to consider the Subject patch for -current,
requesting to commit it to the LibreSSL upstream.
Together with prepared and remediation patch (see inline, the original is here:
https://github.com/libressl-portable/openbsd/compare/master...crypto-org-ua:dstu)
I enclose the text of the standard (sorry, only in Ukrainian language) in case
you'll need it for verification of implemented algorithms
(http://atmnis.com/~apelsin/tmp/dstu-4145-2002.doc) + certified and tested use
case for openssl(1) (also inline).
If you have any questions, suggestions, comments, etc., please, Email.
Thank you very much for your assistance and time.
Sergey.
Index: lib/libcrypto/crypto/Makefile
===================================================================
RCS file: /cvs/src/lib/libcrypto/crypto/Makefile,v
retrieving revision 1.67
diff -u -p -r1.67 Makefile
--- lib/libcrypto/crypto/Makefile 19 Oct 2015 16:32:37 -0000 1.67
+++ lib/libcrypto/crypto/Makefile 26 Feb 2016 15:47:37 -0000
@@ -115,6 +115,10 @@ SRCS+= dsa_err.c dsa_ossl.c dsa_depr.c d
SRCS+= dso_dlfcn.c dso_err.c dso_lib.c dso_null.c
SRCS+= dso_openssl.c
+# dstu/
+SRCS+= dstu_params.c dstu_err.c dstu_sign.c dstu_asn1.c dstu_compress.c
+SRCS+= dstu_key.c dstu_pmeth.c dstu_ameth.c
+
# ec/
SRCS+= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c
SRCS+= ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c
@@ -155,6 +159,7 @@ SRCS+= e_old.c pmeth_lib.c pmeth_fn.c pm
SRCS+= e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c
SRCS+= e_chacha.c evp_aead.c e_chacha20poly1305.c
SRCS+= e_gost2814789.c m_gost2814789.c m_gostr341194.c m_streebog.c
+SRCS+= e_dstu.c m_dstu.c
# gost/
SRCS+= gost2814789.c gost89_keywrap.c gost89_params.c gost89imit_ameth.c
@@ -276,6 +281,7 @@ SRCS+= pcy_cache.c pcy_node.c pcy_data.c
${LCRYPTO_SRC}/dh \
${LCRYPTO_SRC}/dsa \
${LCRYPTO_SRC}/dso \
+ ${LCRYPTO_SRC}/dstu \
${LCRYPTO_SRC}/ec \
${LCRYPTO_SRC}/ecdh \
${LCRYPTO_SRC}/ecdsa \
Index: lib/libssl/src/crypto/asn1/ameth_lib.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/asn1/ameth_lib.c,v
retrieving revision 1.15
diff -u -p -r1.15 ameth_lib.c
--- lib/libssl/src/crypto/asn1/ameth_lib.c 9 Nov 2014 19:17:13 -0000
1.15
+++ lib/libssl/src/crypto/asn1/ameth_lib.c 26 Feb 2016 15:47:38 -0000
@@ -79,6 +79,10 @@ extern const EVP_PKEY_ASN1_METHOD gostim
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
+#ifndef OPENSSL_NO_DSTU
+extern const EVP_PKEY_ASN1_METHOD dstu_asn1_meth_le, dstu_asn1_meth_be;
+#endif
+
/* Keep this sorted in type order !! */
static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
#ifndef OPENSSL_NO_RSA
@@ -107,6 +111,10 @@ static const EVP_PKEY_ASN1_METHOD *stand
#ifndef OPENSSL_NO_GOST
&gostr01_asn1_meths[1],
&gostr01_asn1_meths[2],
+#endif
+#ifndef OPENSSL_NO_DSTU
+ &dstu_asn1_meth_le,
+ &dstu_asn1_meth_be,
#endif
};
Index: lib/libssl/src/crypto/dstu/dstu.h
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu.h
diff -N lib/libssl/src/crypto/dstu/dstu.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu.h 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,60 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#ifndef HEADER_DSTU_H
+#define HEADER_DSTU_H
+
+#include <openssl/gost.h>
+#include <openssl/evp.h>
+
+#define DSTU_SET_CUSTOM_SBOX (EVP_MD_CTRL_ALG_CTRL + 1)
+#define DSTU_SET_CURVE (EVP_PKEY_ALG_CTRL + 2)
+
+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);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl.
+ * Any changes made after this point may be overwritten by the script during
+ * next run.
+ */
+void ERR_load_DSTU_strings(void);
+
+/* 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
+
+#endif /* HEADER_DSTU_H */
Index: lib/libssl/src/crypto/dstu/dstu_ameth.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_ameth.c
diff -N lib/libssl/src/crypto/dstu/dstu_ameth.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_ameth.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,700 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include "dstu.h"
+#include "dstu_asn1.h"
+#include "dstu_key.h"
+#include "dstu_params.h"
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include <string.h>
+#include "dstu_compress.h"
+
+#include "asn1_locl.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;
+ unsigned char *bn_bytes = NULL;
+ int prk_encoded_bytes = 0, params_type = 0, algnid, res = 0;
+
+ 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, ¶ms_type, (void **) ¶ms, 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 **)
¶ms_encoded,
+ ASN1_STRING_length(params)))
+ return 0;
+
+ bn_bytes = malloc(prk_encoded_bytes);
+ if (!bn_bytes) {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ reverse_bytes_copy(bn_bytes, prk_encoded, prk_encoded_bytes);
+
+ prk = BN_bin2bn(bn_bytes, prk_encoded_bytes, NULL);
+ if (!prk) {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_BN_LIB);
+ goto err;
+ }
+ key = EVP_PKEY_get0((EVP_PKEY *) pk);
+ if (!EC_KEY_set_private_key(key->ec, prk)) {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (!dstu_add_public_key(key->ec)) {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_DECODE, ERR_R_EC_LIB);
+ goto err;
+ }
+ res = 1;
+
+err:
+ if (prk)
+ BN_free(prk);
+
+ if (bn_bytes)
+ free(bn_bytes);
+
+ return res;
+}
+
+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;
+ 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;
+ }
+ prk_encoded_bytes = BN_num_bytes(d);
+ prk_encoded = malloc(prk_encoded_bytes);
+ if (!prk_encoded) {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!BN_bn2bin(d, prk_encoded)) {
+ DSTUerr(DSTU_F_DSTU_ASN1_PRIV_ENCODE, ERR_R_BN_LIB);
+ goto err;
+ }
+ reverse_bytes(prk_encoded, prk_encoded_bytes);
+
+ 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)
+ free(prk_encoded);
+
+ 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)
+{
+ DSTU_KEY *key = EVP_PKEY_get0((EVP_PKEY *) pk);
+ const EC_GROUP *group;
+ BIGNUM *n = BN_new();
+ int res = 0;
+
+ if (!n)
+ return 0;
+
+ if (key) {
+ group = EC_KEY_get0_group(key->ec);
+ if (group) {
+ if (EC_GROUP_get_order(group, n, NULL))
+ res = ASN1_object_size(0, BN_num_bytes(n) * 2,
+ V_ASN1_OCTET_STRING);
+ }
+ }
+ BN_free(n);
+ return res;
+}
+
+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, ¶m_type, (void **) ¶ms, 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 **)
¶ms_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 = 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)) {
+ free(compressed);
+ DSTUerr(DSTU_F_DSTU_ASN1_PUB_DECODE,
+ DSTU_R_POINT_UNCOMPRESS_FAILED);
+ goto err;
+ }
+ 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 = 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)
+ free(pbk_encoded);
+
+ if (public_key)
+ ASN1_OCTET_STRING_free(public_key);
+
+ if (compressed)
+ 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_PKCS7_SIGN:
+ if (arg1 == 0) {
+ X509_ALGOR *alg1 = NULL, *alg2 = NULL;
+ int nid = EVP_PKEY_base_id(pkey);
+ PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *) arg2,
+ NULL, &alg1, &alg2);
+ X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_dstu34311),
V_ASN1_NULL, 0);
+ if (nid == NID_undef) {
+ return (-1);
+ }
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
+ }
+ return 1;
+#ifndef OPENSSL_NO_CMS
+ case ASN1_PKEY_CTRL_CMS_SIGN:
+ if (arg1 == 0) {
+ X509_ALGOR *alg1 = NULL, *alg2 = NULL;
+ int nid = EVP_PKEY_base_id(pkey);
+ CMS_SignerInfo_get0_algs((CMS_SignerInfo *) arg2,
+ NULL, NULL, &alg1, &alg2);
+ X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_dstu34311),
V_ASN1_NULL, 0);
+ if (nid == NID_undef) {
+ return (-1);
+ }
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
+ }
+ return 1;
+#endif
+ 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;
+}
+
+const EVP_PKEY_ASN1_METHOD dstu_asn1_meth_le = {
+ .pkey_id = NID_dstu4145le,
+ .pkey_base_id = NID_dstu4145le,
+ .pem_str = SN_dstu4145le,
+ .info = LN_dstu4145le,
+
+ .param_encode = dstu_asn1_param_encode,
+ .param_decode = dstu_asn1_param_decode,
+ .param_copy = dstu_asn1_param_copy,
+ .param_cmp = dstu_asn1_param_cmp,
+ .param_print = dstu_asn1_param_print,
+
+ .priv_encode = dstu_asn1_priv_encode,
+ .priv_decode = dstu_asn1_priv_decode,
+ .priv_print = dstu_asn1_priv_print,
+
+ .pub_encode = dstu_asn1_pub_encode,
+ .pub_decode = dstu_asn1_pub_decode,
+ .pub_cmp = dstu_asn1_pub_cmp,
+ .pub_print = dstu_asn1_pub_print,
+
+ .pkey_size = dstu_asn1_pkey_size,
+ .pkey_bits = dstu_asn1_pkey_bits,
+
+ .pkey_ctrl = dstu_asn1_pkey_ctrl,
+ .pkey_free = dstu_asn1_pkey_free
+};
+
+const EVP_PKEY_ASN1_METHOD dstu_asn1_meth_be = {
+ .pkey_id = NID_dstu4145be,
+ .pkey_base_id = NID_dstu4145be,
+ .pem_str = SN_dstu4145be,
+ .info = LN_dstu4145be,
+
+ .param_encode = dstu_asn1_param_encode,
+ .param_decode = dstu_asn1_param_decode,
+ .param_copy = dstu_asn1_param_copy,
+ .param_cmp = dstu_asn1_param_cmp,
+ .param_print = dstu_asn1_param_print,
+
+ .priv_encode = dstu_asn1_priv_encode,
+ .priv_decode = dstu_asn1_priv_decode,
+ .priv_print = dstu_asn1_priv_print,
+
+ .pub_encode = dstu_asn1_pub_encode,
+ .pub_decode = dstu_asn1_pub_decode,
+ .pub_cmp = dstu_asn1_pub_cmp,
+ .pub_print = dstu_asn1_pub_print,
+
+ .pkey_size = dstu_asn1_pkey_size,
+ .pkey_bits = dstu_asn1_pkey_bits,
+
+ .pkey_ctrl = dstu_asn1_pkey_ctrl,
+ .pkey_free = dstu_asn1_pkey_free
+};
Index: lib/libssl/src/crypto/dstu/dstu_asn1.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_asn1.c
diff -N lib/libssl/src/crypto/dstu/dstu_asn1.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_asn1.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,394 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include "dstu.h"
+#include "dstu_asn1.h"
+
+static const ASN1_TEMPLATE DSTU_Pentanomial_seq_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_Pentanomial, k),
+ .field_name = "k",
+ .item = &ASN1_INTEGER_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_Pentanomial, j),
+ .field_name = "j",
+ .item = &ASN1_INTEGER_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_Pentanomial, l),
+ .field_name = "l",
+ .item = &ASN1_INTEGER_it
+ },
+};
+
+const ASN1_ITEM DSTU_Pentanomial_it = {
+ ASN1_ITYPE_SEQUENCE,
+ V_ASN1_SEQUENCE,
+ DSTU_Pentanomial_seq_tt,
+ sizeof(DSTU_Pentanomial_seq_tt) / sizeof(ASN1_TEMPLATE),
+ NULL,
+ sizeof(DSTU_Pentanomial),
+ "DSTU_Pentanomial"
+};
+
+DSTU_Pentanomial *
+d2i_DSTU_Pentanomial(DSTU_Pentanomial ** a, const unsigned char **in, long len)
+{
+ return (DSTU_Pentanomial *) ASN1_item_d2i((ASN1_VALUE **) a, in, len,
(&(DSTU_Pentanomial_it)));
+}
+
+int
+i2d_DSTU_Pentanomial(DSTU_Pentanomial * a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *) a, out, (&(DSTU_Pentanomial_it)));
+}
+
+DSTU_Pentanomial *
+DSTU_Pentanomial_new(void)
+{
+ return (DSTU_Pentanomial *) ASN1_item_new((&(DSTU_Pentanomial_it)));
+}
+
+void
+DSTU_Pentanomial_free(DSTU_Pentanomial * a)
+{
+ ASN1_item_free((ASN1_VALUE *) a, (&(DSTU_Pentanomial_it)));
+}
+
+static const ASN1_TEMPLATE DSTU_Polynomial_ch_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_Polynomial, poly.k),
+ .field_name = "poly.k",
+ .item = &ASN1_INTEGER_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_Polynomial, poly.pentanomial),
+ .field_name = "poly.pentanomial",
+ .item = &DSTU_Pentanomial_it
+ }
+};
+
+const ASN1_ITEM DSTU_Polynomial_it = {
+ ASN1_ITYPE_CHOICE,
+ offsetof(DSTU_Polynomial, type),
+ DSTU_Polynomial_ch_tt,
+ sizeof(DSTU_Polynomial_ch_tt) / sizeof(ASN1_TEMPLATE),
+ NULL,
+ sizeof(DSTU_Polynomial),
+ "DSTU_Polynomial"
+};
+
+DSTU_Polynomial *
+d2i_DSTU_Polynomial(DSTU_Polynomial ** a, const unsigned char **in, long len)
+{
+ return (DSTU_Polynomial *) ASN1_item_d2i((ASN1_VALUE **) a, in, len,
(&(DSTU_Polynomial_it)));
+}
+
+int
+i2d_DSTU_Polynomial(DSTU_Polynomial * a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *) a, out, (&(DSTU_Polynomial_it)));
+ \
+}
+
+DSTU_Polynomial *
+DSTU_Polynomial_new(void)
+{
+ return (DSTU_Polynomial *) ASN1_item_new((&(DSTU_Polynomial_it)));
+}
+
+void
+DSTU_Polynomial_free(DSTU_Polynomial * a)
+{
+ ASN1_item_free((ASN1_VALUE *) a, (&(DSTU_Polynomial_it)));
+}
+
+static const ASN1_TEMPLATE DSTU_BinaryField_seq_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_BinaryField, m),
+ .field_name = "m",
+ .item = &ASN1_INTEGER_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_BinaryField, poly),
+ .field_name = "poly",
+ .item = &DSTU_Polynomial_it
+ }
+};
+
+const ASN1_ITEM DSTU_BinaryField_it = {
+ ASN1_ITYPE_SEQUENCE,
+ V_ASN1_SEQUENCE,
+ DSTU_BinaryField_seq_tt,
+ sizeof(DSTU_BinaryField_seq_tt) / sizeof(ASN1_TEMPLATE),
+ NULL,
+ sizeof(DSTU_BinaryField),
+ "DSTU_BinaryField"
+};
+
+DSTU_BinaryField *
+d2i_DSTU_BinaryField(DSTU_BinaryField ** a, const unsigned char **in, long len)
+{
+ return (DSTU_BinaryField *) ASN1_item_d2i((ASN1_VALUE **) a, in, len,
(&(DSTU_BinaryField_it)));
+}
+
+int
+i2d_DSTU_BinaryField(DSTU_BinaryField * a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *) a, out, (&(DSTU_BinaryField_it)));
+}
+
+DSTU_BinaryField *
+DSTU_BinaryField_new(void)
+{
+ return (DSTU_BinaryField *) ASN1_item_new((&(DSTU_BinaryField_it)));
+}
+
+void
+DSTU_BinaryField_free(DSTU_BinaryField * a)
+{
+ ASN1_item_free((ASN1_VALUE *) a, (&(DSTU_BinaryField_it)));
+}
+
+static const ASN1_TEMPLATE DSTU_CustomCurveSpec_seq_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_CustomCurveSpec, field),
+ .field_name = "field",
+ .item = &DSTU_BinaryField_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_CustomCurveSpec, a),
+ .field_name = "a",
+ .item = &ASN1_INTEGER_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_CustomCurveSpec, b),
+ .field_name = "b",
+ .item = &ASN1_OCTET_STRING_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_CustomCurveSpec, n),
+ .field_name = "n",
+ .item = &ASN1_INTEGER_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_CustomCurveSpec, bp),
+ .field_name = "bp",
+ .item = &ASN1_OCTET_STRING_it
+ }
+};
+
+const ASN1_ITEM DSTU_CustomCurveSpec_it = {
+ ASN1_ITYPE_SEQUENCE,
+ V_ASN1_SEQUENCE,
+ DSTU_CustomCurveSpec_seq_tt,
+ sizeof(DSTU_CustomCurveSpec_seq_tt) / sizeof(ASN1_TEMPLATE),
+ NULL,
+ sizeof(DSTU_CustomCurveSpec),
+ "DSTU_CustomCurveSpec"
+};
+
+DSTU_CustomCurveSpec *
+d2i_DSTU_CustomCurveSpec(DSTU_CustomCurveSpec ** a, const unsigned char **in,
long len)
+{
+ return (DSTU_CustomCurveSpec *) ASN1_item_d2i((ASN1_VALUE **) a, in,
len, (&(DSTU_CustomCurveSpec_it)));
+}
+
+int
+i2d_DSTU_CustomCurveSpec(DSTU_CustomCurveSpec * a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *) a, out,
(&(DSTU_CustomCurveSpec_it)));
+}
+
+DSTU_CustomCurveSpec *
+DSTU_CustomCurveSpec_new(void)
+{
+ return (DSTU_CustomCurveSpec *)
ASN1_item_new((&(DSTU_CustomCurveSpec_it)));
+}
+
+void
+DSTU_CustomCurveSpec_free(DSTU_CustomCurveSpec * a)
+{
+ ASN1_item_free((ASN1_VALUE *) a, (&(DSTU_CustomCurveSpec_it)));
+}
+
+static const ASN1_TEMPLATE DSTU_CurveSpec_ch_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_CurveSpec, curve.named_curve),
+ .field_name = "curve.named_curve",
+ .item = &ASN1_OBJECT_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_CurveSpec, curve.custom_curve),
+ .field_name = "curve.custom_curve",
+ .item = &DSTU_CustomCurveSpec_it
+ }
+};
+
+const ASN1_ITEM DSTU_CurveSpec_it = {
+ ASN1_ITYPE_CHOICE,
+ offsetof(DSTU_CurveSpec, type),
+ DSTU_CurveSpec_ch_tt,
+ sizeof(DSTU_CurveSpec_ch_tt) / sizeof(ASN1_TEMPLATE),
+ NULL,
+ sizeof(DSTU_CurveSpec),
+ "DSTU_CurveSpec"
+};
+
+DSTU_CurveSpec *
+d2i_DSTU_CurveSpec(DSTU_CurveSpec ** a, const unsigned char **in, long len)
+{
+ return (DSTU_CurveSpec *) ASN1_item_d2i((ASN1_VALUE **) a, in, len,
(&(DSTU_CurveSpec_it)));
+}
+
+int
+i2d_DSTU_CurveSpec(DSTU_CurveSpec * a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *) a, out, (&(DSTU_CurveSpec_it)));
+}
+
+DSTU_CurveSpec *
+DSTU_CurveSpec_new(void)
+{
+ return (DSTU_CurveSpec *) ASN1_item_new((&(DSTU_CurveSpec_it)));
+}
+
+void
+DSTU_CurveSpec_free(DSTU_CurveSpec * a)
+{
+ ASN1_item_free((ASN1_VALUE *) a, (&(DSTU_CurveSpec_it)));
+}
+
+static const ASN1_TEMPLATE DSTU_AlgorithmParameters_seq_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_AlgorithmParameters, curve),
+ .field_name = "curve",
+ .item = &DSTU_CurveSpec_it
+ },
+ {
+ .flags = ASN1_TFLG_OPTIONAL,
+ .tag = 0,
+ .offset = offsetof(DSTU_AlgorithmParameters, sbox),
+ .field_name = "sbox",
+ .item = &ASN1_OCTET_STRING_it
+ }
+};
+
+const ASN1_ITEM DSTU_AlgorithmParameters_it = {
+ ASN1_ITYPE_SEQUENCE,
+ V_ASN1_SEQUENCE,
+ DSTU_AlgorithmParameters_seq_tt,
+ sizeof(DSTU_AlgorithmParameters_seq_tt) / sizeof(ASN1_TEMPLATE),
+ NULL,
+ sizeof(DSTU_AlgorithmParameters),
+ "DSTU_AlgorithmParameters"
+};
+
+DSTU_AlgorithmParameters *
+d2i_DSTU_AlgorithmParameters(DSTU_AlgorithmParameters ** a, const unsigned
char **in, long len)
+{
+ return (DSTU_AlgorithmParameters *) ASN1_item_d2i((ASN1_VALUE **) a,
in, len, (&(DSTU_AlgorithmParameters_it)));
+}
+
+int
+i2d_DSTU_AlgorithmParameters(DSTU_AlgorithmParameters * a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *) a, out,
(&(DSTU_AlgorithmParameters_it)));
+}
+
+DSTU_AlgorithmParameters *
+DSTU_AlgorithmParameters_new(void)
+{
+ return (DSTU_AlgorithmParameters *)
ASN1_item_new((&(DSTU_AlgorithmParameters_it)));
+}
+
+void
+DSTU_AlgorithmParameters_free(DSTU_AlgorithmParameters * a)
+{
+ ASN1_item_free((ASN1_VALUE *) a, (&(DSTU_AlgorithmParameters_it)));
+}
+static const ASN1_TEMPLATE DSTU_Gost28147Parameters_seq_tt[] = {
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_Gost28147Parameters, iv),
+ .field_name = "iv",
+ .item = &ASN1_OCTET_STRING_it
+ },
+ {
+ .flags = 0,
+ .tag = 0,
+ .offset = offsetof(DSTU_Gost28147Parameters, dke),
+ .field_name = "dke",
+ .item = &ASN1_OCTET_STRING_it
+ }
+};
+
+const ASN1_ITEM DSTU_Gost28147Parameters_it = {
+ ASN1_ITYPE_SEQUENCE,
+ V_ASN1_SEQUENCE,
+ DSTU_Gost28147Parameters_seq_tt,
+ sizeof(DSTU_Gost28147Parameters_seq_tt) / sizeof(ASN1_TEMPLATE),
+ NULL,
+ sizeof(DSTU_Gost28147Parameters),
+ "DSTU_Gost28147Parameters"
+};
+
+DSTU_Gost28147Parameters *
+d2i_DSTU_Gost28147Parameters(DSTU_Gost28147Parameters ** a, const unsigned
char **in, long len)
+{
+ return (DSTU_Gost28147Parameters *) ASN1_item_d2i((ASN1_VALUE **) a,
in, len, (&(DSTU_Gost28147Parameters_it)));
+}
+
+int
+i2d_DSTU_Gost28147Parameters(DSTU_Gost28147Parameters * a, unsigned char **out)
+{
+ return ASN1_item_i2d((ASN1_VALUE *) a, out,
(&(DSTU_Gost28147Parameters_it)));
+}
+
+DSTU_Gost28147Parameters *
+DSTU_Gost28147Parameters_new(void)
+{
+ return (DSTU_Gost28147Parameters *)
ASN1_item_new((&(DSTU_Gost28147Parameters_it)));
+}
+
+void
+DSTU_Gost28147Parameters_free(DSTU_Gost28147Parameters * a)
+{
+ ASN1_item_free((ASN1_VALUE *) a, (&(DSTU_Gost28147Parameters_it)));
+}
Index: lib/libssl/src/crypto/dstu/dstu_asn1.h
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_asn1.h
diff -N lib/libssl/src/crypto/dstu/dstu_asn1.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_asn1.h 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,70 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#ifndef DSTU_ASN1_H_
+#define DSTU_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)
+ typedef struct DSTU_Gost28147Parameters_st {
+ ASN1_OCTET_STRING *iv;
+ ASN1_OCTET_STRING *dke;
+} DSTU_Gost28147Parameters;
+
+DECLARE_ASN1_FUNCTIONS(DSTU_Gost28147Parameters)
+#endif /* DSTU_ASN1_H_ */
Index: lib/libssl/src/crypto/dstu/dstu_compress.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_compress.c
diff -N lib/libssl/src/crypto/dstu/dstu_compress.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_compress.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,204 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * 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;
+}
Index: lib/libssl/src/crypto/dstu/dstu_compress.h
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_compress.h
diff -N lib/libssl/src/crypto/dstu/dstu_compress.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_compress.h 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,21 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#ifndef DSTU_COMPRESS_H_
+#define DSTU_COMPRESS_H_
+
+#include <openssl/ec.h>
+#include "dstu.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_ */
Index: lib/libssl/src/crypto/dstu/dstu_err.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_err.c
diff -N lib/libssl/src/crypto/dstu/dstu_err.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_err.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,114 @@
+/* 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
+ * [email protected].
+ *
+ * 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
+ * ([email protected]). This product includes software written by Tim Hudson
+ * ([email protected]).
+ *
+ */
+
+/*
+ * 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 "dstu.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSTU,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSTU,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
+
+void
+ERR_load_DSTU_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(0, DSTU_str_functs);
+ ERR_load_strings(0, DSTU_str_reasons);
+#endif
+}
Index: lib/libssl/src/crypto/dstu/dstu_key.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_key.c
diff -N lib/libssl/src/crypto/dstu/dstu_key.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_key.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,479 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * 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 = malloc(sizeof(DSTU_KEY));
+
+ if (!key)
+ return NULL;
+ key->ec = EC_KEY_new();
+ if (!(key->ec)) {
+ 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)
+ free(key->sbox);
+ key->sbox = sbox;
+ }
+}
+
+void
+DSTU_KEY_free(DSTU_KEY * key)
+{
+ if (key) {
+ if (key->sbox)
+ free(key->sbox);
+ if (key->ec)
+ EC_KEY_free(key->ec);
+ 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 = 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)
+ 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 =
+ 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)) {
+ free(reverse_buffer);
+ goto err;
+ }
+ 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 =
+ 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)) {
+ free(reverse_buffer);
+ goto err;
+ }
+ 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 = 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)
+ 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) {
+ free(ctx->sbox);
+ ctx->sbox = NULL;
+ }
+ free(ctx);
+ }
+}
Index: lib/libssl/src/crypto/dstu/dstu_key.h
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_key.h
diff -N lib/libssl/src/crypto/dstu/dstu_key.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_key.h 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,42 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#ifndef DSTU_KEY_H_
+#define DSTU_KEY_H_
+
+#include <openssl/ec.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_ */
Index: lib/libssl/src/crypto/dstu/dstu_params.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_params.c
diff -N lib/libssl/src/crypto/dstu/dstu_params.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_params.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,707 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include "dstu_params.h"
+#include "../gost/gost_locl.h"
+#include <string.h>
+#include <openssl/evp.h>
+
+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
+};
+
+static void
+unpack_sbox(const 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];
+ }
+}
+
+static void
+pack_sbox(const gost_subst_block * unpacked_sbox, unsigned char *packed_sbox)
+{
+ int i;
+ for (i = 0; i < 8; i++) {
+ packed_sbox[i] =
+ ((unpacked_sbox->
+ k1[2 * i] << 4) & 0xf0) | (unpacked_sbox->k1[(2 * i) +
+ 1] & 0x0f);
+ packed_sbox[i + 8] =
+ ((unpacked_sbox->
+ k2[2 * i] << 4) & 0xf0) | (unpacked_sbox->k2[(2 * i) +
+ 1] & 0x0f);
+ packed_sbox[i + 16] =
+ ((unpacked_sbox->
+ k3[2 * i] << 4) & 0xf0) | (unpacked_sbox->k3[(2 * i) +
+ 1] & 0x0f);
+ packed_sbox[i + 24] =
+ ((unpacked_sbox->
+ k4[2 * i] << 4) & 0xf0) | (unpacked_sbox->k4[(2 * i) +
+ 1] & 0x0f);
+ packed_sbox[i + 32] =
+ ((unpacked_sbox->
+ k5[2 * i] << 4) & 0xf0) | (unpacked_sbox->k5[(2 * i) +
+ 1] & 0x0f);
+ packed_sbox[i + 40] =
+ ((unpacked_sbox->
+ k6[2 * i] << 4) & 0xf0) | (unpacked_sbox->k6[(2 * i) +
+ 1] & 0x0f);
+ packed_sbox[i + 48] =
+ ((unpacked_sbox->
+ k7[2 * i] << 4) & 0xf0) | (unpacked_sbox->k7[(2 * i) +
+ 1] & 0x0f);
+ packed_sbox[i + 56] =
+ ((unpacked_sbox->
+ k8[2 * i] << 4) & 0xf0) | (unpacked_sbox->k8[(2 * i) +
+ 1] & 0x0f);
+
+ }
+}
+
+void
+dstu_set_sbox(GOST2814789_KEY * key, const unsigned char sbox[64])
+{
+ gost_subst_block unpacked_sbox;
+ unsigned int t;
+ int i;
+
+ if (!sbox) {
+ /* set default */
+ sbox = default_sbox;
+ }
+ unpack_sbox(sbox, &unpacked_sbox);
+
+ for (i = 0; i < 256; i++) {
+ t = (unsigned int) (unpacked_sbox.k8[i >> 4] << 4 |
unpacked_sbox.k7[i & 15]) << 24;
+ key->k87[i] = (t << 11) | (t >> 21);
+ t = (unsigned int) (unpacked_sbox.k6[i >> 4] << 4 |
unpacked_sbox.k5[i & 15]) << 16;
+ key->k65[i] = (t << 11) | (t >> 21);
+ t = (unsigned int) (unpacked_sbox.k4[i >> 4] << 4 |
unpacked_sbox.k3[i & 15]) << 8;
+ key->k43[i] = (t << 11) | (t >> 21);
+ t = (unsigned int) (unpacked_sbox.k2[i >> 4] << 4 |
unpacked_sbox.k1[i & 15]) << 0;
+ key->k21[i] = (t << 11) | (t >> 21);
+ }
+}
+
+void
+dstu_get_sbox(const GOST2814789_KEY * ctx, unsigned char sbox[64])
+{
+ gost_subst_block unpacked_sbox;
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ unpacked_sbox.k8[i >> 4] = (ctx->k87[i] >> 28) & 0xf;
+ unpacked_sbox.k7[i & 15] = (ctx->k87[i] >> 24) & 0xf;
+
+ unpacked_sbox.k6[i >> 4] = (ctx->k65[i] >> 20) & 0xf;
+ unpacked_sbox.k5[i & 15] = (ctx->k65[i] >> 16) & 0xf;
+
+ unpacked_sbox.k4[i >> 4] = (ctx->k43[i] >> 12) & 0xf;
+ unpacked_sbox.k3[i & 15] = (ctx->k43[i] >> 8) & 0xf;
+
+ unpacked_sbox.k2[i >> 4] = (ctx->k21[i] >> 4) & 0xf;
+ unpacked_sbox.k1[i & 15] = ctx->k21[i] & 0xf;
+ }
+
+ pack_sbox(&unpacked_sbox, 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));
+}
+
+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;
+}
+
+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(const unsigned char sbox[64])
+{
+ unsigned char *copy = malloc(sizeof(default_sbox));
+
+ if (copy)
+ memcpy(copy, sbox, sizeof(default_sbox));
+
+ return copy;
+}
+
+int
+is_default_sbox(const unsigned char sbox[64])
+{
+ return !memcmp(default_sbox, sbox, sizeof(default_sbox));
+}
Index: lib/libssl/src/crypto/dstu/dstu_params.h
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_params.h
diff -N lib/libssl/src/crypto/dstu/dstu_params.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_params.h 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,44 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#ifndef DSTU_PARAMS_H_
+#define DSTU_PARAMS_H_
+
+#include <openssl/ec.h>
+#include "dstu.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];
+
+int is_default_sbox(const unsigned char sbox[64]);
+unsigned char *copy_sbox(const unsigned char sbox[64]);
+
+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);
+
+void dstu_set_sbox(GOST2814789_KEY * key, const unsigned char sbox[64]);
+void dstu_get_sbox(const GOST2814789_KEY * ctx, unsigned char sbox[64]);
+
+#endif /* DSTU_PARAMS_H_ */
Index: lib/libssl/src/crypto/dstu/dstu_pmeth.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_pmeth.c
diff -N lib/libssl/src/crypto/dstu/dstu_pmeth.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_pmeth.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,395 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include "dstu.h"
+#include "dstu_key.h"
+#include "dstu_params.h"
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <string.h>
+
+#include "evp_locl.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:
+ case EVP_PKEY_CTRL_PKCS7_SIGN:
+#ifndef OPENSSL_NO_CMS
+ case EVP_PKEY_CTRL_CMS_SIGN:
+#endif
+ 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;
+ BIGNUM *n = 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;
+ }
+ n = BN_new();
+ if (!n)
+ return 0;
+
+ if (!EC_GROUP_get_order(group, n, NULL))
+ goto err;
+
+ field_size = BN_num_bytes(n);
+ encoded_sig_size = EVP_PKEY_size(pkey);
+
+ if (encoded_sig_size > *siglen) {
+ *siglen = encoded_sig_size;
+ goto err;
+ }
+ *siglen = encoded_sig_size;
+
+ if (sig) {
+ dstu_sig = ASN1_OCTET_STRING_new();
+ if (!dstu_sig)
+ goto err;
+
+ sig_data = 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)
+ free(sig_data);
+
+ if (dstu_sig)
+ ASN1_OCTET_STRING_free(dstu_sig);
+
+ if (n)
+ BN_free(n);
+
+ 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;
+ BIGNUM *n = 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;
+ }
+ n = BN_new();
+ if (!n)
+ return 0;
+
+ if (!EC_GROUP_get_order(group, n, NULL)) {
+ DSTUerr(DSTU_F_DSTU_PKEY_VERIFY, DSTU_R_NOT_DSTU_KEY);
+ goto err;
+ }
+ field_size = BN_num_bytes(n);
+
+ if (!d2i_ASN1_OCTET_STRING(&dstu_sig, &sig, siglen))
+ goto err;
+
+ 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 = 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);
+ free(sig_be);
+ } else
+ ret = dstu_do_verify(key->ec, tbs, tbslen, sig, siglen);
+
+err:
+ if (n)
+ BN_free(n);
+
+ 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;
+}
+
+const EVP_PKEY_METHOD dstu_pkey_meth_le = {
+ .pkey_id = NID_dstu4145le,
+ .flags = 0,
+ .init = dstu_pkey_init_le,
+ .cleanup = dstu_pkey_cleanup,
+ .copy = dstu_pkey_copy,
+ .keygen = dstu_pkey_keygen,
+ .sign = dstu_pkey_sign,
+ .verify = dstu_pkey_verify,
+ .ctrl = dstu_pkey_ctrl,
+ .ctrl_str = dstu_pkey_ctrl_str
+};
+
+const EVP_PKEY_METHOD dstu_pkey_meth_be = {
+ .pkey_id = NID_dstu4145be,
+ .flags = 0,
+ .init = dstu_pkey_init_be,
+ .cleanup = dstu_pkey_cleanup,
+ .copy = dstu_pkey_copy,
+ .keygen = dstu_pkey_keygen,
+ .sign = dstu_pkey_sign,
+ .verify = dstu_pkey_verify,
+ .ctrl = dstu_pkey_ctrl,
+ .ctrl_str = dstu_pkey_ctrl_str
+};
Index: lib/libssl/src/crypto/dstu/dstu_sign.c
===================================================================
RCS file: lib/libssl/src/crypto/dstu/dstu_sign.c
diff -N lib/libssl/src/crypto/dstu/dstu_sign.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/dstu/dstu_sign.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,243 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <string.h>
+#include "dstu_params.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 = 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)) {
+ free(h);
+ return 0;
+ }
+ 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;
+ }
+ 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;
+
+ field_size = BN_num_bytes(n);
+
+ 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;
+}
Index: lib/libssl/src/crypto/err/err.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/err/err.c,v
retrieving revision 1.41
diff -u -p -r1.41 err.c
--- lib/libssl/src/crypto/err/err.c 9 Nov 2014 19:17:13 -0000 1.41
+++ lib/libssl/src/crypto/err/err.c 26 Feb 2016 15:47:38 -0000
@@ -158,11 +158,12 @@ static ERR_STRING_DATA ERR_str_libraries
{ERR_PACK(ERR_LIB_CMS,0,0), "CMS routines"},
{ERR_PACK(ERR_LIB_HMAC,0,0), "HMAC routines"},
{ERR_PACK(ERR_LIB_GOST,0,0), "GOST routines"},
+ {ERR_PACK(ERR_LIB_DSTU,0,0), "DSTU routines"},
{0, NULL},
};
static ERR_STRING_DATA ERR_str_functs[] = {
- {ERR_PACK(0,SYS_F_FOPEN, 0), "fopen"},
+ {ERR_PACK(0,SYS_F_FOPEN, 0), "fopen"},
{ERR_PACK(0,SYS_F_CONNECT, 0), "connect"},
{ERR_PACK(0,SYS_F_GETSERVBYNAME, 0), "getservbyname"},
{ERR_PACK(0,SYS_F_SOCKET, 0), "socket"},
Index: lib/libssl/src/crypto/err/err.h
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/err/err.h,v
retrieving revision 1.22
diff -u -p -r1.22 err.h
--- lib/libssl/src/crypto/err/err.h 9 Nov 2014 19:17:13 -0000 1.22
+++ lib/libssl/src/crypto/err/err.h 26 Feb 2016 15:47:38 -0000
@@ -196,6 +196,7 @@ typedef struct err_state_st {
#define ERR_LIB_HMAC 48
#define ERR_LIB_JPAKE 49
#define ERR_LIB_GOST 50
+#define ERR_LIB_DSTU 51
#define ERR_LIB_USER 128
@@ -233,6 +234,7 @@ typedef struct err_state_st {
#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__)
#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__)
#define GOSTerr(f,r) ERR_PUT_error(ERR_LIB_GOST,(f),(r),__FILE__,__LINE__)
+#define DSTUerr(f,r) ERR_PUT_error(ERR_LIB_DSTU,(f),(r),__FILE__,__LINE__)
#define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)<<24L)| \
((((unsigned long)f)&0xfffL)<<12L)| \
Index: lib/libssl/src/crypto/err/openssl.ec
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/err/openssl.ec,v
retrieving revision 1.11
diff -u -p -r1.11 openssl.ec
--- lib/libssl/src/crypto/err/openssl.ec 9 Nov 2014 19:17:13 -0000
1.11
+++ lib/libssl/src/crypto/err/openssl.ec 26 Feb 2016 15:47:38 -0000
@@ -35,6 +35,7 @@ L TS crypto/ts/ts.h
crypto/ts/ts_err.
L HMAC crypto/hmac/hmac.h crypto/hmac/hmac_err.c
L CMS crypto/cms/cms.h crypto/cms/cms_err.c
L GOST crypto/gost/gost.h crypto/gost/gost_err.c
+L DSTU crypto/dstu/dstu.h crypto/dstu/dstu_err.c
# additional header files to be scanned for function names
L NONE crypto/x509/x509_vfy.h NONE
@@ -93,4 +94,3 @@ R RSAREF_R_PUBLIC_KEY 0x040a
R RSAREF_R_SIGNATURE 0x040b
R RSAREF_R_SIGNATURE_ENCODING 0x040c
R RSAREF_R_ENCRYPTION_ALGORITHM 0x040d
-
Index: lib/libssl/src/crypto/evp/c_all.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/evp/c_all.c,v
retrieving revision 1.20
diff -u -p -r1.20 c_all.c
--- lib/libssl/src/crypto/evp/c_all.c 14 Sep 2015 01:45:03 -0000 1.20
+++ lib/libssl/src/crypto/evp/c_all.c 26 Feb 2016 15:47:38 -0000
@@ -223,6 +223,10 @@ OpenSSL_add_all_ciphers(void)
EVP_add_cipher(EVP_gost2814789_cfb64());
EVP_add_cipher(EVP_gost2814789_cnt());
#endif
+
+#ifndef OPENSSL_NO_DSTU
+ EVP_add_cipher(EVP_dstu28147_cfb64());
+#endif
}
void
@@ -263,6 +267,9 @@ OpenSSL_add_all_digests(void)
EVP_add_digest(EVP_gost2814789imit());
EVP_add_digest(EVP_streebog256());
EVP_add_digest(EVP_streebog512());
+#endif
+#ifndef OPENSSL_NO_DSTU
+ EVP_add_digest(EVP_dstu34311());
#endif
#ifndef OPENSSL_NO_RIPEMD
EVP_add_digest(EVP_ripemd160());
Index: lib/libssl/src/crypto/evp/e_dstu.c
===================================================================
RCS file: lib/libssl/src/crypto/evp/e_dstu.c
diff -N lib/libssl/src/crypto/evp/e_dstu.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/evp/e_dstu.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,147 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_DSTU
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/gost.h>
+#include "../dstu/dstu_params.h"
+#include "evp_locl.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
+#define DSTU_CIPHER_SBOX_SIZE 64
+
+/*
+ * 2 bytes for sequence header, 2 bytes for each octet string header and 8
bytes
+ * for iv and 64 bytes for dke.
+ * Total 78 < 128 so we are ok with 1 byte length.
+ */
+#define DSTU_CIPHER_ASN1_PARAM_SIZE (2 + 2 + DSTU_CIPHER_BLOCK_SIZE + 2 +
DSTU_CIPHER_SBOX_SIZE)
+
+typedef struct {
+ GOST2814789_KEY ks;
+} EVP_DSTU28147_CTX;
+
+static int
+dstu_cipher_init(EVP_CIPHER_CTX * ctx, const unsigned char *key, const
unsigned char *iv, int enc)
+{
+ EVP_DSTU28147_CTX *c = ctx->cipher_data;
+
+ /* We do not use key meshing. */
+ c->ks.key_meshing = 0;
+
+ return Gost2814789_set_key(&c->ks, key, ctx->key_len * 8);
+}
+
+static int
+dstu_cipher_ctrl(EVP_CIPHER_CTX * ctx, int cmd, int p1, void *p2)
+{
+ EVP_DSTU28147_CTX *c = ctx->cipher_data;
+
+ switch (cmd) {
+ case EVP_CTRL_INIT:
+ /* Default value to have any s-box set at all. */
+ dstu_set_sbox(&(c->ks), NULL);
+ return 1;
+ case DSTU_SET_CUSTOM_SBOX:
+ /*
+ * Unlike GOST, which accepts nid, we accept pointer to sbox,
+ * so p2 is used!
+ */
+ dstu_set_sbox(&(c->ks), p2);
+ return 1;
+ case EVP_CTRL_PBE_PRF_NID:
+ if (!p2)
+ return 0;
+ *((int *) (p2)) = NID_hmacWithDstu34311;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+dstu_cipher_set_asn1_parameters(EVP_CIPHER_CTX * ctx, ASN1_TYPE * asn1_type)
+{
+ /*
+ * We defined params asn1 structure, but for now we will use manual
+ * composition for speed here.
+ */
+ EVP_DSTU28147_CTX *c = ctx->cipher_data;
+
+ unsigned char params[DSTU_CIPHER_ASN1_PARAM_SIZE];
+ ASN1_STRING seq;
+
+ params[0] = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
+ params[1] = 2 + DSTU_CIPHER_BLOCK_SIZE + 2 + DSTU_CIPHER_SBOX_SIZE;
+ params[2] = V_ASN1_OCTET_STRING;
+ params[3] = DSTU_CIPHER_BLOCK_SIZE;
+
+ memcpy(&(params[4]), ctx->oiv, DSTU_CIPHER_BLOCK_SIZE);
+
+ params[4 + DSTU_CIPHER_BLOCK_SIZE] = V_ASN1_OCTET_STRING;
+ params[4 + DSTU_CIPHER_BLOCK_SIZE + 1] = DSTU_CIPHER_SBOX_SIZE;
+
+ dstu_get_sbox(&(c->ks), &(params[4 + DSTU_CIPHER_BLOCK_SIZE + 2]));
+
+ seq.type = V_ASN1_SEQUENCE;
+ seq.length = sizeof(params);
+ seq.flags = 0;
+ seq.data = params;
+
+ if (ASN1_TYPE_set1(asn1_type, V_ASN1_SEQUENCE, &seq))
+ return 1;
+
+ return -1;
+}
+
+static int
+dstu_cipher_get_asn1_parameters(EVP_CIPHER_CTX * ctx, ASN1_TYPE * asn1_type)
+{
+ if (V_ASN1_SEQUENCE != asn1_type->type)
+ return -1;
+
+ if (DSTU_CIPHER_ASN1_PARAM_SIZE != asn1_type->value.sequence->length)
+ return -1;
+
+ if ((V_ASN1_OCTET_STRING != asn1_type->value.sequence->data[2])
+ || (DSTU_CIPHER_BLOCK_SIZE != asn1_type->value.sequence->data[3]))
+ return -1;
+
+ if ((V_ASN1_OCTET_STRING !=
+ asn1_type->value.sequence->data[4 + DSTU_CIPHER_BLOCK_SIZE])
+ || (DSTU_CIPHER_SBOX_SIZE !=
+ asn1_type->value.sequence->data[4 + DSTU_CIPHER_BLOCK_SIZE +
1]))
+ return -1;
+
+ memcpy(ctx->oiv, &(asn1_type->value.sequence->data[4]),
+ DSTU_CIPHER_BLOCK_SIZE);
+
+ if (dstu_cipher_ctrl
+ (ctx, EVP_CTRL_GOST_SET_SBOX, DSTU_CIPHER_SBOX_SIZE,
+ &(asn1_type->value.sequence->data[4 + DSTU_CIPHER_BLOCK_SIZE +
2])))
+ return 1;
+
+ return -1;
+}
+
+BLOCK_CIPHER_func_cfb(dstu28147, Gost2814789, 64, EVP_DSTU28147_CTX, ks)
+#define NID_dstu89_cfb64 NID_dstu28147_cfb
+
+BLOCK_CIPHER_def_cfb(dstu28147, EVP_DSTU28147_CTX, NID_dstu89, 32, 8, 64,
+ EVP_CIPH_NO_PADDING | EVP_CIPH_CTRL_INIT,
+ dstu_cipher_init, NULL, dstu_cipher_set_asn1_parameters,
+ dstu_cipher_get_asn1_parameters, dstu_cipher_ctrl)
+#endif
Index: lib/libssl/src/crypto/evp/evp.h
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/evp/evp.h,v
retrieving revision 1.49
diff -u -p -r1.49 evp.h
--- lib/libssl/src/crypto/evp/evp.h 2 Nov 2015 15:40:53 -0000 1.49
+++ lib/libssl/src/crypto/evp/evp.h 26 Feb 2016 15:47:38 -0000
@@ -680,6 +680,9 @@ const EVP_MD *EVP_gost2814789imit(void);
const EVP_MD *EVP_streebog256(void);
const EVP_MD *EVP_streebog512(void);
#endif
+#ifndef OPENSSL_NO_DSTU
+const EVP_MD *EVP_dstu34311(void);
+#endif
const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
#ifndef OPENSSL_NO_DES
const EVP_CIPHER *EVP_des_ecb(void);
@@ -812,6 +815,10 @@ const EVP_CIPHER *EVP_chacha20(void);
const EVP_CIPHER *EVP_gost2814789_ecb(void);
const EVP_CIPHER *EVP_gost2814789_cfb64(void);
const EVP_CIPHER *EVP_gost2814789_cnt(void);
+#endif
+
+#ifndef OPENSSL_NO_DSTU
+const EVP_CIPHER *EVP_dstu28147_cfb64(void);
#endif
void OPENSSL_add_all_algorithms_noconf(void);
Index: lib/libssl/src/crypto/evp/m_dstu.c
===================================================================
RCS file: lib/libssl/src/crypto/evp/m_dstu.c
diff -N lib/libssl/src/crypto/evp/m_dstu.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libssl/src/crypto/evp/m_dstu.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,78 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_DSTU
+
+#include <openssl/evp.h>
+#include <openssl/gost.h>
+#include <openssl/objects.h>
+
+#include "../dstu/dstu_params.h"
+#include "../dstu/dstu_key.h"
+
+typedef GOSTR341194_CTX DSTU34311_CTX;
+
+static int
+dstu34311_init(EVP_MD_CTX * ctx)
+{
+ DSTU34311_CTX *c = ctx->md_data;
+ EVP_PKEY *pkey;
+ DSTU_KEY *dstu_key;
+
+ memset(c, 0, sizeof(DSTU34311_CTX));
+
+ /* 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) {
+ dstu_set_sbox(&(c->cipher),
dstu_key->sbox);
+ return 1;
+ }
+ }
+ }
+ }
+ dstu_set_sbox(&(c->cipher), NULL);
+ return 1;
+}
+
+static int
+dstu34311_update(EVP_MD_CTX * ctx, const void *data, size_t count)
+{
+ return GOSTR341194_Update(ctx->md_data, data, count);
+}
+
+static int
+dstu34311_final(EVP_MD_CTX * ctx, unsigned char *md)
+{
+ return GOSTR341194_Final(md, ctx->md_data);
+}
+
+static const EVP_MD dstu34311_md = {
+ .type = NID_dstu34311,
+ .pkey_type = NID_undef,
+ .md_size = GOSTR341194_LENGTH,
+ .flags = EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
+ .init = dstu34311_init,
+ .update = dstu34311_update,
+ .final = dstu34311_final,
+ .block_size = GOSTR341194_CBLOCK,
+ .ctx_size = sizeof(EVP_MD *) + sizeof(GOSTR341194_CTX),
+};
+
+const EVP_MD *
+EVP_dstu34311(void)
+{
+ return (&dstu34311_md);
+}
+#endif
Index: lib/libssl/src/crypto/evp/pmeth_lib.c
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/evp/pmeth_lib.c,v
retrieving revision 1.11
diff -u -p -r1.11 pmeth_lib.c
--- lib/libssl/src/crypto/evp/pmeth_lib.c 11 Feb 2015 03:19:37 -0000
1.11
+++ lib/libssl/src/crypto/evp/pmeth_lib.c 26 Feb 2016 15:47:38 -0000
@@ -82,6 +82,10 @@ extern const EVP_PKEY_METHOD rsa_pkey_me
extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
extern const EVP_PKEY_METHOD gostimit_pkey_meth, gostr01_pkey_meth;
+#ifndef OPENSSL_NO_DSTU
+extern const EVP_PKEY_METHOD dstu_pkey_meth_le, dstu_pkey_meth_be;
+#endif
+
static const EVP_PKEY_METHOD *standard_methods[] = {
#ifndef OPENSSL_NO_RSA
&rsa_pkey_meth,
@@ -101,6 +105,10 @@ static const EVP_PKEY_METHOD *standard_m
#endif
&hmac_pkey_meth,
&cmac_pkey_meth,
+#ifndef OPENSSL_NO_DSTU
+ &dstu_pkey_meth_le,
+ &dstu_pkey_meth_be,
+#endif
};
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
Index: lib/libssl/src/crypto/objects/obj_mac.num
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/objects/obj_mac.num,v
retrieving revision 1.13
diff -u -p -r1.13 obj_mac.num
--- lib/libssl/src/crypto/objects/obj_mac.num 9 Nov 2014 19:17:13 -0000
1.13
+++ lib/libssl/src/crypto/objects/obj_mac.num 26 Feb 2016 15:47:38 -0000
@@ -947,3 +947,23 @@ id_tc26_gost3410_2012_256 946
id_tc26_gost3410_2012_512 947
id_tc26_signwithdigest_gost3410_2012_256 948
id_tc26_signwithdigest_gost3410_2012_512 949
+ISO_UA 950
+ua_pki 951
+dstu28147 952
+dstu28147_ofb 953
+dstu28147_cfb 954
+dstu28147_wrap 955
+hmacWithDstu34311 956
+dstu34311 957
+dstu4145le 958
+dstu4145be 959
+uacurve0 960
+uacurve1 961
+uacurve2 962
+uacurve3 963
+uacurve4 964
+uacurve5 965
+uacurve6 966
+uacurve7 967
+uacurve8 968
+uacurve9 969
Index: lib/libssl/src/crypto/objects/obj_xref.h
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/objects/obj_xref.h,v
retrieving revision 1.3
diff -u -p -r1.3 obj_xref.h
--- lib/libssl/src/crypto/objects/obj_xref.h 9 Nov 2014 19:17:13 -0000
1.3
+++ lib/libssl/src/crypto/objects/obj_xref.h 26 Feb 2016 15:47:38 -0000
@@ -42,6 +42,8 @@ static const nid_triple sigoid_srt[] =
{NID_rsassaPss, NID_undef, NID_rsaEncryption},
{NID_id_tc26_signwithdigest_gost3410_2012_256,
NID_id_tc26_gost3411_2012_256, NID_id_GostR3410_2001},
{NID_id_tc26_signwithdigest_gost3410_2012_512,
NID_id_tc26_gost3411_2012_512, NID_id_GostR3410_2001},
+ {NID_dstu4145le, NID_dstu34311, NID_dstu4145le},
+ {NID_dstu4145be, NID_dstu34311, NID_dstu4145be},
};
static const nid_triple * const sigoid_srt_xref[] =
@@ -78,5 +80,6 @@ static const nid_triple * const sigoid_s
&sigoid_srt[28],
&sigoid_srt[30],
&sigoid_srt[31],
+ &sigoid_srt[32],
+ &sigoid_srt[33],
};
-
Index: lib/libssl/src/crypto/objects/obj_xref.txt
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/objects/obj_xref.txt,v
retrieving revision 1.2
diff -u -p -r1.2 obj_xref.txt
--- lib/libssl/src/crypto/objects/obj_xref.txt 9 Nov 2014 19:17:13 -0000
1.2
+++ lib/libssl/src/crypto/objects/obj_xref.txt 26 Feb 2016 15:47:38 -0000
@@ -46,3 +46,6 @@ id_GostR3411_94_with_GostR3410_94_cc id_
id_GostR3411_94_with_GostR3410_2001_cc id_GostR3411_94 id_GostR3410_2001_cc
id_tc26_signwithdigest_gost3410_2012_256 id_tc26_gost3411_2012_256
id_tc26_gost3410_2012_256
id_tc26_signwithdigest_gost3410_2012_512 id_tc26_gost3411_2012_512
id_tc26_gost3410_2012_512
+
+dstu4145le dstu34311 dstu4145le
+dstu4145be dstu34311 dstu4145be
Index: lib/libssl/src/crypto/objects/objects.txt
===================================================================
RCS file: /cvs/src/lib/libssl/src/crypto/objects/objects.txt,v
retrieving revision 1.16
diff -u -p -r1.16 objects.txt
--- lib/libssl/src/crypto/objects/objects.txt 9 Nov 2014 19:17:13 -0000
1.16
+++ lib/libssl/src/crypto/objects/objects.txt 26 Feb 2016 15:47:38 -0000
@@ -558,7 +558,7 @@ id-cmc 19 : id-cmc-responseInfo
id-cmc 21 : id-cmc-queryPending
id-cmc 22 : id-cmc-popLinkRandom
id-cmc 23 : id-cmc-popLinkWitness
-id-cmc 24 : id-cmc-confirmCertAcceptance
+id-cmc 24 : id-cmc-confirmCertAcceptance
# other names
id-on 1 : id-on-personalData
@@ -1240,7 +1240,7 @@ cryptocom 1 8 1 : id-GostR3410-2001-Par
# Definitions for Camellia cipher - ECB, CFB, OFB MODE
!Alias ntt-ds 0 3 4401 5
-!Alias camellia ntt-ds 3 1 9
+!Alias camellia ntt-ds 3 1 9
camellia 1 : CAMELLIA-128-ECB : camellia-128-ecb
!Cname camellia-128-ofb128
@@ -1328,3 +1328,29 @@ tc26 1 1 1 : id-tc26-gost3410-2012-256
tc26 1 1 2 : id-tc26-gost3410-2012-512 : GOST R 34.10-2012 (512
bit)
tc26 1 3 2 : id-tc26-signwithdigest-gost3410-2012-256 : GOST R
34.11-2012 with GOST R 34.10-2012 (256 bit)
tc26 1 3 3 : id-tc26-signwithdigest-gost3410-2012-512 : GOST R
34.11-2012 with GOST R 34.10-2012 (512 bit)
+
+# 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 1 2 : hmacWithDstu34311 : HMAC DSTU Gost 34311-95
+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 2 0 : uacurve0 : DSTU curve 0
+dstu4145le 2 1 : uacurve1 : DSTU curve 1
+dstu4145le 2 2 : uacurve2 : DSTU curve 2
+dstu4145le 2 3 : uacurve3 : DSTU curve 3
+dstu4145le 2 4 : uacurve4 : DSTU curve 4
+dstu4145le 2 5 : uacurve5 : DSTU curve 5
+dstu4145le 2 6 : uacurve6 : DSTU curve 6
+dstu4145le 2 7 : uacurve7 : DSTU curve 7
+dstu4145le 2 8 : uacurve8 : DSTU curve 8
+dstu4145le 2 9 : uacurve9 : DSTU curve 9
Index: regress/lib/libcrypto/Makefile
===================================================================
RCS file: /cvs/src/regress/lib/libcrypto/Makefile,v
retrieving revision 1.22
diff -u -p -r1.22 Makefile
--- regress/lib/libcrypto/Makefile 25 Sep 2015 16:12:30 -0000 1.22
+++ regress/lib/libcrypto/Makefile 26 Feb 2016 15:47:38 -0000
@@ -14,6 +14,7 @@ SUBDIR= \
des \
dh \
dsa \
+ dstu \
ec \
ecdh \
ecdsa \
Index: regress/lib/libcrypto/dstu/Makefile
===================================================================
RCS file: regress/lib/libcrypto/dstu/Makefile
diff -N regress/lib/libcrypto/dstu/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regress/lib/libcrypto/dstu/Makefile 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,9 @@
+# $OpenBSD$
+
+PROG= dstutest
+LDADD= -lcrypto
+DPADD= ${LIBCRYPTO}
+WARNINGS= Yes
+CFLAGS+= -DLIBRESSL_INTERNAL -Werror
+
+.include <bsd.regress.mk>
Index: regress/lib/libcrypto/dstu/dstutest.c
===================================================================
RCS file: regress/lib/libcrypto/dstu/dstutest.c
diff -N regress/lib/libcrypto/dstu/dstutest.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regress/lib/libcrypto/dstu/dstutest.c 26 Feb 2016 15:47:38 -0000
@@ -0,0 +1,263 @@
+/*
+ * ===========================================================
+ * Author: Ignat Korchagin <[email protected]>.
+ * This file is distributed under the same license as OpenSSL.
+ * ===========================================================
+ */
+
+#include <string.h>
+#include <openssl/evp.h>
+
+/*
+ * We need to fake random, if we want to run fixed test vectors test, because
+ * DSTU signature is randomized. We redefine arc4random_buf for this.
+ * We cannot use real arc4random_buf anymore, if we really need random data,
+ * because we will get into endless recursive loop.
+ * Instead, we will implement it using arc4random.
+ */
+
+static void
+real_random(void *buf, size_t n)
+{
+ unsigned char *bytes = buf;
+
+ while (n) {
+ uint32_t rnd = arc4random();
+ size_t to_copy = sizeof(rnd) < n ? sizeof(rnd) : n;
+
+ memcpy(bytes, &rnd, to_copy);
+ bytes += to_copy;
+ n -= to_copy;
+ }
+}
+
+static struct {
+ int fake_rnd;
+ const void *fake_rnd_src;
+ size_t fake_rnd_size;
+} rand_ctrl = {
+ 0, NULL, 0
+};
+
+void
+arc4random_buf(void *buf, size_t n)
+{
+ if (rand_ctrl.fake_rnd) {
+ if (n > rand_ctrl.fake_rnd_size) {
+ exit(1);
+ }
+ memcpy(buf, rand_ctrl.fake_rnd_src, n);
+ } else {
+ real_random(buf, n);
+ }
+}
+
+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, 0x40, 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, 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
+};
+
+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;
+ size_t 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 int
+sig_test(void)
+{
+ EVP_PKEY_CTX *pkey_ctx = NULL;
+ EVP_PKEY *pkey = NULL;
+ unsigned char sig[256];
+ size_t siglen = sizeof(sig);
+ struct dstu_test_vector *vector;
+ int ret = 1;
+
+ printf("Testing DSTU 4145-2002\n");
+ fflush(NULL);
+
+ 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_ctrl.fake_rnd = 1;
+ rand_ctrl.fake_rnd_src = vector->d;
+ rand_ctrl.fake_rnd_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_ctrl.fake_rnd_src = 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);
+
+ rand_ctrl.fake_rnd = 0;
+
+ return ret;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int err = 0;
+
+ err |= sig_test();
+
+ return err;
+}
Index: regress/lib/libcrypto/evp/evptest.c
===================================================================
RCS file: /cvs/src/regress/lib/libcrypto/evp/evptest.c,v
retrieving revision 1.6
diff -u -p -r1.6 evptest.c
--- regress/lib/libcrypto/evp/evptest.c 18 Jul 2015 17:19:56 -0000 1.6
+++ regress/lib/libcrypto/evp/evptest.c 26 Feb 2016 15:47:38 -0000
@@ -411,7 +411,14 @@ main(int argc, char **argv)
#endif
#ifdef OPENSSL_NO_GOST
if (strstr(cipher, "md_gost") == cipher ||
- strstr(cipher, "streebog") == cipher) {
+ strstr(cipher, "streebog") == cipher) {
+ fprintf(stdout, "Cipher disabled, skipping
%s\n", cipher);
+ continue;
+ }
+#endif
+#ifdef OPENSSL_NO_DSTU
+ if (strstr(cipher, "dstu28147-cfb") == cipher ||
+ strstr(cipher, "dstu34311") == cipher) {
fprintf(stdout, "Cipher disabled, skipping
%s\n", cipher);
continue;
}
Index: regress/lib/libcrypto/evp/evptests.txt
===================================================================
RCS file: /cvs/src/regress/lib/libcrypto/evp/evptests.txt,v
retrieving revision 1.3
diff -u -p -r1.3 evptests.txt
--- regress/lib/libcrypto/evp/evptests.txt 18 Nov 2014 21:52:43 -0000
1.3
+++ regress/lib/libcrypto/evp/evptests.txt 26 Feb 2016 15:47:40 -0000
@@ -74,29 +74,29 @@ AES-128-ECB:2B7E151628AED2A6ABF7158809CF
AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
-# ECB-AES192.Encrypt and ECB-AES192.Decrypt
+# ECB-AES192.Encrypt and ECB-AES192.Decrypt
AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC
AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF
AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E
AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E
-# ECB-AES256.Encrypt and ECB-AES256.Decrypt
+# ECB-AES256.Encrypt and ECB-AES256.Decrypt
AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
# For all CBC encrypts and decrypts, the transformed sequence is
# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CBC-AES128.Encrypt and CBC-AES128.Decrypt
+# CBC-AES128.Encrypt and CBC-AES128.Decrypt
AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
-# CBC-AES192.Encrypt and CBC-AES192.Decrypt
+# CBC-AES192.Encrypt and CBC-AES192.Decrypt
AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
-# CBC-AES256.Encrypt and CBC-AES256.Decrypt
+# CBC-AES256.Encrypt and CBC-AES256.Decrypt
AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
@@ -104,12 +104,12 @@ AES-256-CBC:603DEB1015CA71BE2B73AEF0857D
# We don't support CFB{1,8}-AESxxx.{En,De}crypt
# For all CFB128 encrypts and decrypts, the transformed sequence is
# AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CFB128-AES128.Encrypt
+# CFB128-AES128.Encrypt
AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1
AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1
AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1
-# CFB128-AES128.Decrypt
+# CFB128-AES128.Decrypt
AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0
AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0
@@ -124,44 +124,44 @@ AES-192-CFB:8E73B0F7DA0E6452C810F32B8090
AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0
AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0
AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0
-# CFB128-AES256.Encrypt
+# CFB128-AES256.Encrypt
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1
-# CFB128-AES256.Decrypt
+# CFB128-AES256.Decrypt
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0
AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0
# For all OFB encrypts and decrypts, the transformed sequence is
# AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec
-# OFB-AES128.Encrypt
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1
-# OFB-AES128.Decrypt
+# OFB-AES128.Encrypt
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1
+# OFB-AES128.Decrypt
AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
-# OFB-AES192.Encrypt
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1
-# OFB-AES192.Decrypt
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0
-# OFB-AES256.Encrypt
+# OFB-AES192.Encrypt
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1
+# OFB-AES192.Decrypt
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0
+AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0
+# OFB-AES256.Encrypt
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
-# OFB-AES256.Decrypt
+# OFB-AES256.Decrypt
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
@@ -217,19 +217,19 @@ CAMELLIA-128-ECB:000102030405060708090A0
CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1
CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1
-# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt
+# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt
CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96
CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B
CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636
CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A
-# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt
+# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt
CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3
CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A
CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366
CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26
-# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt
+# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt
CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA
CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA
CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28
@@ -237,19 +237,19 @@ CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF
# For all CBC encrypts and decrypts, the transformed sequence is
# CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt
+# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt
CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB
CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887
CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54
CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980
-# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt
+# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt
CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93
CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5
CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449
CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08
-# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt
+# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt
CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA
CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50
CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83
@@ -258,13 +258,13 @@ CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF
# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt
# For all CFB128 encrypts and decrypts, the transformed sequence is
# CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CFB128-CAMELLIA128.Encrypt
+# CFB128-CAMELLIA128.Encrypt
CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1
CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1
CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1
-# CFB128-CAMELLIA128.Decrypt
+# CFB128-CAMELLIA128.Decrypt
CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0
CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0
@@ -282,13 +282,13 @@ CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32
CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0
CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0
-# CFB128-CAMELLIA256.Encrypt
+# CFB128-CAMELLIA256.Encrypt
CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1
CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1
CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1
-# CFB128-CAMELLIA256.Decrypt
+# CFB128-CAMELLIA256.Decrypt
CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0
CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0
@@ -296,37 +296,37 @@ CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF
# For all OFB encrypts and decrypts, the transformed sequence is
# CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec
-# OFB-CAMELLIA128.Encrypt
+# OFB-CAMELLIA128.Encrypt
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1
-# OFB-CAMELLIA128.Decrypt
+# OFB-CAMELLIA128.Decrypt
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0
CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0
-# OFB-CAMELLIA192.Encrypt
+# OFB-CAMELLIA192.Encrypt
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1
-# OFB-CAMELLIA192.Decrypt
+# OFB-CAMELLIA192.Decrypt
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0
CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0
-# OFB-CAMELLIA256.Encrypt
+# OFB-CAMELLIA256.Encrypt
CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1
CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1
CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1
-# OFB-CAMELLIA256.Decrypt
+# OFB-CAMELLIA256.Decrypt
CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0
CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0
@@ -351,3 +351,16 @@ ChaCha:555555555555555555555555555555555
ChaCha:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaa:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:9aa2a9f656efde5aa7591c5fed4b35aea2895dec7cb4543b9e9f21f5e7bcbcf3c43c748a970888f8248393a09d43e0b7e164bc4d0b0fb240a2d72115c4808906:1
ChaCha:00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100:0f1e2d3c4b5a6978:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:9fadf409c00811d00431d67efbd88fba59218d5d6708b1d685863fabbb0e961eea480fd6fb532bfd494b2151015057423ab60a63fe4f55f7a212e2167ccab931:1
ChaCha:c46ec1b18ce8a878725a37e780dfb7351f68ed2e194c79fbc6aebee1a667975d:1ada31d5cf688221:00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:f63a89b75c2271f9368816542ba52f06ed49241792302b00b5e8f80ae9a473afc25b218f519af0fdd406362e8d69de7f54c604a6e00f353f110f771bdca8ab92:1
+
+# DSTU 28147 tests
+dstu28147-cfb:a110827c8acb5da6ac8553f4b94e3b54dcde6fde2d7f89c5d4cb0ea4c0263f35:e34ce94908f9aa27:3bd7264cea7d91e63a28fbfef4600959536fa8e4fed53ab64c68cdf5fa6b4491a21b87c306a14517:fbcf51a67dfe6045a5f34400952183d181aedef334ea69e2f0265e18ec9f9edd129f8567f4ea4d1a:1
+dstu28147-cfb:a110827c8acb5da6ac8553f4b94e3b54dcde6fde2d7f89c5d4cb0ea4c0263f35:e34ce94908f9aa27:3bd7264cea7d91e63a28fbfef4600959536fa8e4fed53ab64c68cdf5fa6b4491a21b87c306a14517:fbcf51a67dfe6045a5f34400952183d181aedef334ea69e2f0265e18ec9f9edd129f8567f4ea4d1a:0
+dstu28147-cfb:164f1564075aca1e26d9b3242346f0f854da62438290cc1d53e5e8d82f62a166:81c1498a2ca0dff3:17d47fe9da6eb8000b378f39261f3e578cb95783a67e52ef99c421ecc333187e6149090e4099c588:5dcc5ed96399c84b51365dea3baf04be03a22706e292bad58c3a247f4396cc15b8798b6b9c1edc50:1
+dstu28147-cfb:164f1564075aca1e26d9b3242346f0f854da62438290cc1d53e5e8d82f62a166:81c1498a2ca0dff3:17d47fe9da6eb8000b378f39261f3e578cb95783a67e52ef99c421ecc333187e6149090e4099c588:5dcc5ed96399c84b51365dea3baf04be03a22706e292bad58c3a247f4396cc15b8798b6b9c1edc50:0
+dstu28147-cfb:13a39905bb829a2bef28a74058834cfa33e3f9d3c651ab2b90cab3811a695b47:912396e3548cda94:7fd960a570b0e05a60325981ac209ad65d6182c1930bc24300387012ec70a5dd797de23d51d98e07:6028314029f2290992f29fa652e6705d6ebe4f678a277da6e08fd675718185933cd5b511c0c0af51:1
+dstu28147-cfb:13a39905bb829a2bef28a74058834cfa33e3f9d3c651ab2b90cab3811a695b47:912396e3548cda94:7fd960a570b0e05a60325981ac209ad65d6182c1930bc24300387012ec70a5dd797de23d51d98e07:6028314029f2290992f29fa652e6705d6ebe4f678a277da6e08fd675718185933cd5b511c0c0af51:0
+
+# DSTU 34311 tests
+dstu34311:::87adff960046b5d0b275cc1c8d2e9a6d37709d21d867f5a67b6bfeb2ff1d72c2a70141dfe527ed41d37cedb49bfde4643c15:b2575c09590219ab899a95669f08631815a35b0e67d63b1b8b184f7d14658da1
+dstu34311:::67ebce4d14953b2ccf0a04e1ceae483c21dc5f2533ec98d5d0a282b752c476349685d1ccbeca2f8a811e7248fddb4f581e8e:b5d5e34507705c6578d85b45f68b198f388cf5a8063d77722d8ff943dd12dac1
+dstu34311:::bf425424f33853daef2ce0217af1fcd6da896d75107454aa08451134db01afd6cba9ce132929b0a72041bd338fa689d348c2:c0ca9b0570896d6d3548f132da81fe54696a6d48b94c0efe1c7537d3a6de11c9
1. Encrypt and decrypt files with DSTU 28147:2009 in CFB mode:
openssl dstu28147-cfb -a -salt -in plain.txt -out cipher.txt
openssl dstu28147-cfb -d -a -in cipher.txt -out decrypted.txt
2. Hash with DSTU 34.311-95
echo -n “abc” | openssl dstu34311
3. DSTU 4145-2002 signature
- generate default 257-bit curve private key
openssl genpkey -algorithm dstu4145le -out dstu.key
- generate private key with specified standard curve (X=0..9)
openssl genpkey -algorithm dstu4145le -pkeyopt curve:uacurveX -out dstu.key
- generate private key with custom sbox for DSTU 34.311-95
openssl genpkey -algorithm dstu4145le -pkeyopt sbox:<sbox in compact 64 byte
hex> -out dstu.key
- generate private key with big-endian field encoding
openssl genpkey -algorithm dstu4145be -out dstu.key
- get public key from private key
openssl pkey -in dstu.key -pubout -out dstu.pub
- sign a file
openssl pkeyutl -sign -inkey dstu.key -in some.txt > some.sig
- verify signature
openssl pkeyutl -verify -pubin -inkey dstu.pub -sigfile some.sig -in some.txt