fast SMS4 with Intel AVX2/KNC-NI

This commit is contained in:
Zhi Guan
2016-05-09 09:20:02 +02:00
parent addcac4896
commit 8c0439e7d6
83 changed files with 3536 additions and 5882 deletions

View File

@@ -182,7 +182,7 @@ SHARED_LIBS_LINK_EXTS=.$(SHLIB_MAJOR).dylib .dylib
SHARED_LDFLAGS=-arch x86_64 -dynamiclib
GENERAL= Makefile
BASENAME= openssl
BASENAME= gmssl
NAME= $(BASENAME)-$(VERSION)
TARFILE= $(NAME).tar
WTARFILE= $(NAME)-win.tar

View File

@@ -151,7 +151,7 @@ SDIRS= \
buffer bio stack lhash rand err \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
cms pqueue ts srp cmac \
sm2 sm3 sms4 ecies
sm2 sm3 sms4 ecies zuc
# keep in mind that the above list is adjusted by ./Configure
# according to no-xxx arguments...
@@ -182,7 +182,7 @@ SHARED_LIBS_LINK_EXTS=.$(SHLIB_MAJOR).dylib .dylib
SHARED_LDFLAGS=-arch x86_64 -dynamiclib
GENERAL= Makefile
BASENAME= openssl
BASENAME= gmssl
NAME= $(BASENAME)-$(VERSION)
TARFILE= $(NAME).tar
WTARFILE= $(NAME)-win.tar

View File

@@ -180,7 +180,7 @@ SHARED_LIBS_LINK_EXTS=
SHARED_LDFLAGS=
GENERAL= Makefile
BASENAME= openssl
BASENAME= gmssl
NAME= $(BASENAME)-$(VERSION)
TARFILE= $(NAME).tar
WTARFILE= $(NAME)-win.tar

View File

@@ -1,6 +1,413 @@
/*
/* apps/cpk.c */
/* ====================================================================
* Copyright (c) 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
/*
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
* gmssl cpkparam
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_GMSSL
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include "apps.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/evp.h>
# include <openssl/pem.h>
# undef PROG
# define PROG cpk_main
/*-
* -inform arg - input format - default PEM (one of DER, NET or PEM)
* -outform arg - output format - default PEM
* -in arg - input file - default stdin
* -out arg - output file - default stdout
* -des - encrypt output if PEM format with DES in cbc mode
* -text - print a text version
* -param_out - print the elliptic curve parameters
* -conv_form arg - specifies the point encoding form
* -param_enc arg - specifies the parameter encoding
*/
int MAIN(int, char **);
int MAIN(int argc, char **argv)
{
int ret = 1;
EC_KEY *eckey = NULL;
const EC_GROUP *group;
int i, badops = 0;
const EVP_CIPHER *enc = NULL;
BIO *in = NULL, *out = NULL;
int informat, outformat, text = 0, noout = 0;
int pubin = 0, pubout = 0, param_out = 0;
char *infile, *outfile, *prog, *engine;
char *passargin = NULL, *passargout = NULL;
char *passin = NULL, *passout = NULL;
point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
int new_form = 0;
int asn1_flag = OPENSSL_EC_NAMED_CURVE;
int new_asn1_flag = 0;
apps_startup();
if (bio_err == NULL)
if ((bio_err = BIO_new(BIO_s_file())) != NULL)
BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
if (!load_config(bio_err, NULL))
goto end;
engine = NULL;
infile = NULL;
outfile = NULL;
informat = FORMAT_PEM;
outformat = FORMAT_PEM;
prog = argv[0];
argc--;
argv++;
while (argc >= 1) {
if (strcmp(*argv, "-inform") == 0) {
if (--argc < 1)
goto bad;
informat = str2fmt(*(++argv));
} else if (strcmp(*argv, "-outform") == 0) {
if (--argc < 1)
goto bad;
outformat = str2fmt(*(++argv));
} else if (strcmp(*argv, "-in") == 0) {
if (--argc < 1)
goto bad;
infile = *(++argv);
} else if (strcmp(*argv, "-out") == 0) {
if (--argc < 1)
goto bad;
outfile = *(++argv);
} else if (strcmp(*argv, "-passin") == 0) {
if (--argc < 1)
goto bad;
passargin = *(++argv);
} else if (strcmp(*argv, "-passout") == 0) {
if (--argc < 1)
goto bad;
passargout = *(++argv);
} else if (strcmp(*argv, "-engine") == 0) {
if (--argc < 1)
goto bad;
engine = *(++argv);
} else if (strcmp(*argv, "-noout") == 0)
noout = 1;
else if (strcmp(*argv, "-text") == 0)
text = 1;
else if (strcmp(*argv, "-conv_form") == 0) {
if (--argc < 1)
goto bad;
++argv;
new_form = 1;
if (strcmp(*argv, "compressed") == 0)
form = POINT_CONVERSION_COMPRESSED;
else if (strcmp(*argv, "uncompressed") == 0)
form = POINT_CONVERSION_UNCOMPRESSED;
else if (strcmp(*argv, "hybrid") == 0)
form = POINT_CONVERSION_HYBRID;
else
goto bad;
} else if (strcmp(*argv, "-param_enc") == 0) {
if (--argc < 1)
goto bad;
++argv;
new_asn1_flag = 1;
if (strcmp(*argv, "named_curve") == 0)
asn1_flag = OPENSSL_EC_NAMED_CURVE;
else if (strcmp(*argv, "explicit") == 0)
asn1_flag = 0;
else
goto bad;
} else if (strcmp(*argv, "-param_out") == 0)
param_out = 1;
else if (strcmp(*argv, "-pubin") == 0)
pubin = 1;
else if (strcmp(*argv, "-pubout") == 0)
pubout = 1;
else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) {
BIO_printf(bio_err, "unknown option %s\n", *argv);
badops = 1;
break;
}
argc--;
argv++;
}
if (badops) {
bad:
BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
BIO_printf(bio_err, "where options are\n");
BIO_printf(bio_err, " -inform arg input format - "
"DER or PEM\n");
BIO_printf(bio_err, " -outform arg output format - "
"DER or PEM\n");
BIO_printf(bio_err, " -in arg input file\n");
BIO_printf(bio_err, " -passin arg input file pass "
"phrase source\n");
BIO_printf(bio_err, " -out arg output file\n");
BIO_printf(bio_err, " -passout arg output file pass "
"phrase source\n");
BIO_printf(bio_err, " -engine e use engine e, "
"possibly a hardware device.\n");
BIO_printf(bio_err, " -des encrypt PEM output, "
"instead of 'des' every other \n"
" cipher "
"supported by OpenSSL can be used\n");
BIO_printf(bio_err, " -text print the key\n");
BIO_printf(bio_err, " -noout don't print key out\n");
BIO_printf(bio_err, " -param_out print the elliptic "
"curve parameters\n");
BIO_printf(bio_err, " -conv_form arg specifies the "
"point conversion form \n");
BIO_printf(bio_err, " possible values:"
" compressed\n");
BIO_printf(bio_err, " "
" uncompressed (default)\n");
BIO_printf(bio_err, " " " hybrid\n");
BIO_printf(bio_err, " -param_enc arg specifies the way"
" the ec parameters are encoded\n");
BIO_printf(bio_err, " in the asn1 der " "encoding\n");
BIO_printf(bio_err, " possible values:"
" named_curve (default)\n");
BIO_printf(bio_err, " "
"explicit\n");
goto end;
}
ERR_load_crypto_strings();
# ifndef OPENSSL_NO_ENGINE
setup_engine(bio_err, engine, 0);
# endif
if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if ((in == NULL) || (out == NULL)) {
ERR_print_errors(bio_err);
goto end;
}
if (infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, infile) <= 0) {
perror(infile);
goto end;
}
}
BIO_printf(bio_err, "read EC key\n");
if (informat == FORMAT_ASN1) {
if (pubin)
eckey = d2i_EC_PUBKEY_bio(in, NULL);
else
eckey = d2i_ECPrivateKey_bio(in, NULL);
} else if (informat == FORMAT_PEM) {
if (pubin)
eckey = PEM_read_bio_SM2_PUBKEY(in, NULL, NULL, NULL);
else
eckey = PEM_read_bio_SM2PrivateKey(in, NULL, NULL, passin);
} else {
BIO_printf(bio_err, "bad input format specified for key\n");
goto end;
}
if (eckey == NULL) {
BIO_printf(bio_err, "unable to load Key\n");
ERR_print_errors(bio_err);
goto end;
}
if (outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
# ifdef OPENSSL_SYS_VMS
{
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
out = BIO_push(tmpbio, out);
}
# endif
} else {
if (BIO_write_filename(out, outfile) <= 0) {
perror(outfile);
goto end;
}
}
group = EC_KEY_get0_group(eckey);
if (new_form)
EC_KEY_set_conv_form(eckey, form);
if (new_asn1_flag)
EC_KEY_set_asn1_flag(eckey, asn1_flag);
if (text)
if (!EC_KEY_print(out, eckey, 0)) {
perror(outfile);
ERR_print_errors(bio_err);
goto end;
}
if (noout) {
ret = 0;
goto end;
}
BIO_printf(bio_err, "writing SM2 key\n");
if (outformat == FORMAT_ASN1) {
if (param_out)
i = i2d_ECPKParameters_bio(out, group);
else if (pubin || pubout)
i = i2d_EC_PUBKEY_bio(out, eckey);
else
i = i2d_ECPrivateKey_bio(out, eckey);
} else if (outformat == FORMAT_PEM) {
if (param_out)
i = PEM_write_bio_SM2PKParameters(out, group);
else if (pubin || pubout)
i = PEM_write_bio_SM2_PUBKEY(out, eckey);
else
i = PEM_write_bio_SM2PrivateKey(out, eckey, enc,
NULL, 0, NULL, passout);
} else {
BIO_printf(bio_err, "bad output format specified for " "outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write private key\n");
ERR_print_errors(bio_err);
} else
ret = 0;
end:
if (in)
BIO_free(in);
if (out)
BIO_free_all(out);
if (eckey)
EC_KEY_free(eckey);
if (passin)
OPENSSL_free(passin);
if (passout)
OPENSSL_free(passout);
apps_shutdown();
OPENSSL_EXIT(ret);
}
#else /* !OPENSSL_NO_GMSSL */
# if PEDANTIC
static void *dummy = &dummy;
# endif
#endif

594
apps/cpkparam.c Normal file
View File

@@ -0,0 +1,594 @@
/* apps/cpkparam.c */
/* ====================================================================
* Copyright (c) 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
#ifndef OPENSSL_NO_GMSSL
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <string.h>
# include "apps.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/bn.h>
# include <openssl/dh.h>
# include <openssl/x509.h>
# include <openssl/pem.h>
# ifndef OPENSSL_NO_DSA
# include <openssl/dsa.h>
# endif
# undef PROG
# define PROG cpkparam_main
# define DEFBITS 2048
/*-
* -inform arg - input format - default PEM (DER or PEM)
* -outform arg - output format - default PEM
* -in arg - input file - default stdin
* -out arg - output file - default stdout
* -dsaparam - read or generate DSA parameters, convert to DH
* -check - check the parameters are ok
* -noout
* -text
* -C
*/
static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
int MAIN(int, char **);
int MAIN(int argc, char **argv)
{
DH *dh = NULL;
int i, badops = 0, text = 0;
# ifndef OPENSSL_NO_DSA
int dsaparam = 0;
# endif
BIO *in = NULL, *out = NULL;
int informat, outformat, check = 0, noout = 0, C = 0, ret = 1;
char *infile, *outfile, *prog;
char *inrand = NULL;
# ifndef OPENSSL_NO_ENGINE
char *engine = NULL;
# endif
int num = 0, g = 0;
apps_startup();
if (bio_err == NULL)
if ((bio_err = BIO_new(BIO_s_file())) != NULL)
BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
if (!load_config(bio_err, NULL))
goto end;
infile = NULL;
outfile = NULL;
informat = FORMAT_PEM;
outformat = FORMAT_PEM;
prog = argv[0];
argc--;
argv++;
while (argc >= 1) {
if (strcmp(*argv, "-inform") == 0) {
if (--argc < 1)
goto bad;
informat = str2fmt(*(++argv));
} else if (strcmp(*argv, "-outform") == 0) {
if (--argc < 1)
goto bad;
outformat = str2fmt(*(++argv));
} else if (strcmp(*argv, "-in") == 0) {
if (--argc < 1)
goto bad;
infile = *(++argv);
} else if (strcmp(*argv, "-out") == 0) {
if (--argc < 1)
goto bad;
outfile = *(++argv);
}
# ifndef OPENSSL_NO_ENGINE
else if (strcmp(*argv, "-engine") == 0) {
if (--argc < 1)
goto bad;
engine = *(++argv);
}
# endif
else if (strcmp(*argv, "-check") == 0)
check = 1;
else if (strcmp(*argv, "-text") == 0)
text = 1;
# ifndef OPENSSL_NO_DSA
else if (strcmp(*argv, "-dsaparam") == 0)
dsaparam = 1;
# endif
else if (strcmp(*argv, "-C") == 0)
C = 1;
else if (strcmp(*argv, "-noout") == 0)
noout = 1;
else if (strcmp(*argv, "-2") == 0)
g = 2;
else if (strcmp(*argv, "-5") == 0)
g = 5;
else if (strcmp(*argv, "-rand") == 0) {
if (--argc < 1)
goto bad;
inrand = *(++argv);
} else if (((sscanf(*argv, "%d", &num) == 0) || (num <= 0)))
goto bad;
argv++;
argc--;
}
if (badops) {
bad:
BIO_printf(bio_err, "%s [options] [numbits]\n", prog);
BIO_printf(bio_err, "where options are\n");
BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n");
BIO_printf(bio_err,
" -outform arg output format - one of DER PEM\n");
BIO_printf(bio_err, " -in arg input file\n");
BIO_printf(bio_err, " -out arg output file\n");
# ifndef OPENSSL_NO_DSA
BIO_printf(bio_err,
" -dsaparam read or generate DSA parameters, convert to DH\n");
# endif
BIO_printf(bio_err, " -check check the DH parameters\n");
BIO_printf(bio_err,
" -text print a text form of the DH parameters\n");
BIO_printf(bio_err, " -C Output C code\n");
BIO_printf(bio_err,
" -2 generate parameters using 2 as the generator value\n");
BIO_printf(bio_err,
" -5 generate parameters using 5 as the generator value\n");
BIO_printf(bio_err,
" numbits number of bits in to generate (default 2048)\n");
# ifndef OPENSSL_NO_ENGINE
BIO_printf(bio_err,
" -engine e use engine e, possibly a hardware device.\n");
# endif
BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
LIST_SEPARATOR_CHAR);
BIO_printf(bio_err,
" - load the file (or the files in the directory) into\n");
BIO_printf(bio_err, " the random number generator\n");
BIO_printf(bio_err, " -noout no output\n");
goto end;
}
ERR_load_crypto_strings();
# ifndef OPENSSL_NO_ENGINE
setup_engine(bio_err, engine, 0);
# endif
if (g && !num)
num = DEFBITS;
# ifndef OPENSSL_NO_DSA
if (dsaparam) {
if (g) {
BIO_printf(bio_err,
"generator may not be chosen for DSA parameters\n");
goto end;
}
} else
# endif
{
/* DH parameters */
if (num && !g)
g = 2;
}
if (num) {
BN_GENCB cb;
BN_GENCB_set(&cb, dh_cb, bio_err);
if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
# ifndef OPENSSL_NO_DSA
if (dsaparam) {
DSA *dsa = DSA_new();
BIO_printf(bio_err,
"Generating DSA parameters, %d bit long prime\n", num);
if (!dsa
|| !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL,
&cb)) {
if (dsa)
DSA_free(dsa);
ERR_print_errors(bio_err);
goto end;
}
dh = DSA_dup_DH(dsa);
DSA_free(dsa);
if (dh == NULL) {
ERR_print_errors(bio_err);
goto end;
}
} else
# endif
{
dh = DH_new();
BIO_printf(bio_err,
"Generating DH parameters, %d bit long safe prime, generator %d\n",
num, g);
BIO_printf(bio_err, "This is going to take a long time\n");
if (!dh || !DH_generate_parameters_ex(dh, num, g, &cb)) {
ERR_print_errors(bio_err);
goto end;
}
}
app_RAND_write_file(NULL, bio_err);
} else {
in = BIO_new(BIO_s_file());
if (in == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, infile) <= 0) {
perror(infile);
goto end;
}
}
if (informat != FORMAT_ASN1 && informat != FORMAT_PEM) {
BIO_printf(bio_err, "bad input format specified\n");
goto end;
}
# ifndef OPENSSL_NO_DSA
if (dsaparam) {
DSA *dsa;
if (informat == FORMAT_ASN1)
dsa = d2i_DSAparams_bio(in, NULL);
else /* informat == FORMAT_PEM */
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
if (dsa == NULL) {
BIO_printf(bio_err, "unable to load DSA parameters\n");
ERR_print_errors(bio_err);
goto end;
}
dh = DSA_dup_DH(dsa);
DSA_free(dsa);
if (dh == NULL) {
ERR_print_errors(bio_err);
goto end;
}
} else
# endif
{
if (informat == FORMAT_ASN1)
dh = d2i_DHparams_bio(in, NULL);
else /* informat == FORMAT_PEM */
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
if (dh == NULL) {
BIO_printf(bio_err, "unable to load DH parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
/* dh != NULL */
}
out = BIO_new(BIO_s_file());
if (out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
# ifdef OPENSSL_SYS_VMS
{
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
out = BIO_push(tmpbio, out);
}
# endif
} else {
if (BIO_write_filename(out, outfile) <= 0) {
perror(outfile);
goto end;
}
}
if (text) {
DHparams_print(out, dh);
}
if (check) {
if (!DH_check(dh, &i)) {
ERR_print_errors(bio_err);
goto end;
}
if (i & DH_CHECK_P_NOT_PRIME)
printf("p value is not prime\n");
if (i & DH_CHECK_P_NOT_SAFE_PRIME)
printf("p value is not a safe prime\n");
if (i & DH_UNABLE_TO_CHECK_GENERATOR)
printf("unable to check the generator value\n");
if (i & DH_NOT_SUITABLE_GENERATOR)
printf("the g value is not a generator\n");
if (i == 0)
printf("DH parameters appear to be ok.\n");
}
if (C) {
unsigned char *data;
int len, l, bits;
len = BN_num_bytes(dh->p);
bits = BN_num_bits(dh->p);
data = (unsigned char *)OPENSSL_malloc(len);
if (data == NULL) {
perror("OPENSSL_malloc");
goto end;
}
printf("#ifndef HEADER_DH_H\n"
"#include <openssl/dh.h>\n" "#endif\n");
printf("DH *get_dh%d()\n\t{\n", bits);
l = BN_bn2bin(dh->p, data);
printf("\tstatic unsigned char dh%d_p[]={", bits);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t\t");
printf("0x%02X,", data[i]);
}
printf("\n\t\t};\n");
l = BN_bn2bin(dh->g, data);
printf("\tstatic unsigned char dh%d_g[]={", bits);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t\t");
printf("0x%02X,", data[i]);
}
printf("\n\t\t};\n");
printf("\tDH *dh;\n\n");
printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
bits, bits);
printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
bits, bits);
printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
printf("\t\t{ DH_free(dh); return(NULL); }\n");
if (dh->length)
printf("\tdh->length = %ld;\n", dh->length);
printf("\treturn(dh);\n\t}\n");
OPENSSL_free(data);
}
if (!noout) {
if (outformat == FORMAT_ASN1)
i = i2d_DHparams_bio(out, dh);
else if (outformat == FORMAT_PEM) {
if (dh->q)
i = PEM_write_bio_DHxparams(out, dh);
else
i = PEM_write_bio_DHparams(out, dh);
} else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write DH parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
ret = 0;
end:
if (in != NULL)
BIO_free(in);
if (out != NULL)
BIO_free_all(out);
if (dh != NULL)
DH_free(dh);
apps_shutdown();
OPENSSL_EXIT(ret);
}
/* dh_cb is identical to dsa_cb in apps/dsaparam.c */
static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
{
char c = '*';
if (p == 0)
c = '.';
if (p == 1)
c = '+';
if (p == 2)
c = '*';
if (p == 3)
c = '\n';
BIO_write(cb->arg, &c, 1);
(void)BIO_flush(cb->arg);
# ifdef LINT
p = n;
# endif
return 1;
}
#else /* !OPENSSL_NO_GMSSL */
# if PEDANTIC
static void *dummy = &dummy;
# endif
#endif

View File

@@ -344,7 +344,11 @@ int MAIN(int argc, char **argv)
}
if (dgst == NULL) {
#ifndef OPENSSL_NO_GMSSL
dgst = EVP_sm3();
#else
dgst = EVP_md5();
#endif
}
if (bufsize != NULL) {

1
apps/openssl Symbolic link
View File

@@ -0,0 +1 @@
gmssl

View File

@@ -210,6 +210,8 @@ int MAIN(int argc, char **argv)
if (!pkey)
goto end;
printf("GMSSL %s %d\n", __FILE__, __LINE__);
if (!noout) {
if (outformat == FORMAT_PEM) {
if (pubout)

View File

@@ -72,6 +72,10 @@ static void usage(void);
#define PROG pkeyutl_main
#ifndef OPENSSL_NO_GMSSL
int is_sm2 = 0;
#endif
static EVP_PKEY_CTX *init_ctx(int *pkeysize,
char *keyfile, int keyform, int key_type,
char *passargin, int pkey_op, ENGINE *e);
@@ -206,6 +210,14 @@ int MAIN(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
#ifndef OPENSSL_NO_GMSSL
} else if (strcmp(*argv, "-algorithm") == 0) {
if (!argv[1])
goto end;
if (strcmp(*(++argv), "SM2"))
goto end;
is_sm2 = 1;
#endif
} else
badarg = 1;
if (badarg) {
@@ -396,7 +408,7 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
switch (key_type) {
case KEY_PRIVKEY:
pkey = load_key(bio_err, keyfile, keyform, 0,
passin, e, "Private Key");
passin, e, "Private Key"); //FIXME: GmSSL: we might set PKEY METHOD of EC
break;
case KEY_PUBKEY:
@@ -419,6 +431,16 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
if (!pkey)
goto end;
#ifndef OPENSSL_NO_GMSSL
if (is_sm2) {
if (!EVP_PKEY_set_type(pkey, EVP_PKEY_SM2)) {
fprintf(stderr, "GmSSL: %s %d\n", __FILE__, __LINE__);
ERR_print_errors_fp(stderr);
goto end;
}
}
#endif
ctx = EVP_PKEY_CTX_new(pkey, e);
EVP_PKEY_free(pkey);

0
apps/progs.pl Normal file → Executable file
View File

View File

@@ -94,14 +94,14 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
#endif
#ifndef OPENSSL_NO_EC
&eckey_asn1_meth,
#endif
#ifndef OPENSSL_NO_SM2
&sm2_asn1_meth,
#endif
&hmac_asn1_meth,
&cmac_asn1_meth,
#ifndef OPENSSL_NO_DH
&dhx_asn1_meth
&dhx_asn1_meth,
#endif
#ifndef OPENSSL_NO_SM2
&sm2_asn1_meth,
#endif
};
@@ -165,33 +165,6 @@ static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
}
ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods)
/ sizeof(EVP_PKEY_ASN1_METHOD *));
#ifndef OPENSSL_NO_SM2
//FIXME: i dont know why sm2_asn1_meth can not be found
/*
{
int i;
for (i = 0;
i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++)
fprintf(stderr, "Number %d id=%d (%s)\n", i,
standard_methods[i]->pkey_id,
OBJ_nid2sn(standard_methods[i]->pkey_id));
}
*/
/*
fprintf(stderr, "%s:%d: type = %d, NID_sm2 = %d\n", __FILE__, __LINE__,
type, NID_sm2p256v1);
if (ret == NULL) {
fprintf(stderr, "shit, not found!");
}
*/
if (type == EVP_PKEY_SM2) {
return &sm2_asn1_meth;
}
#endif
if (!ret || !*ret)
return NULL;
return *ret;
@@ -234,8 +207,6 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
int i;
const EVP_PKEY_ASN1_METHOD *ameth;
printf("%s:%d: EVP_PKEY_asn1_find_str(%s)\n", __FILE__, __LINE__, str);
if (len == -1)
len = strlen(str);
if (pe) {

View File

@@ -93,28 +93,38 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
goto err;
}
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
if (!ret->ameth->old_priv_decode ||
!ret->ameth->old_priv_decode(ret, pp, length)) {
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
if (ret->ameth->priv_decode) {
PKCS8_PRIV_KEY_INFO *p8 = NULL;
p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length);
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
if (!p8)
goto err;
EVP_PKEY_free(ret);
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
} else {
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
goto err;
}
}
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
if (a != NULL)
(*a) = ret;
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
return (ret);
err:
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
EVP_PKEY_free(ret);
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
return (NULL);
}
@@ -140,10 +150,16 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
* Since we only need to discern "traditional format" RSA and DSA keys we
* can just count the elements.
*/
fprintf(stderr, "GMSSL %s %d: %s %d\n", __FILE__, __LINE__, __FUNCTION__, sk_ASN1_TYPE_num(inkey));
if (sk_ASN1_TYPE_num(inkey) == 6)
keytype = EVP_PKEY_DSA;
else if (sk_ASN1_TYPE_num(inkey) == 4)
else if (sk_ASN1_TYPE_num(inkey) == 4) {
keytype = EVP_PKEY_EC;
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
}
else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
* traditional format */
PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length);

View File

@@ -187,7 +187,7 @@ dclean:
mv -f Makefile.new $(MAKEFILE)
clean:
rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
rm -f *.s asm/*.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
# DO NOT DELETE THIS LINE -- make depend depends on it.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -89,7 +89,7 @@ dclean:
mv -f Makefile.new $(MAKEFILE)
clean:
rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak *.s fluff
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@@ -502,6 +502,7 @@ static int eckey_param_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{
EC_KEY *eckey;
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
return 0;
@@ -641,40 +642,6 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
old_ec_priv_encode
};
#ifndef OPENSSL_NO_SM2
const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = {
EVP_PKEY_SM2,
EVP_PKEY_SM2,
0,
"SM2",
"GmSSL SM2 algorithm",
eckey_pub_decode,
eckey_pub_encode,
eckey_pub_cmp,
eckey_pub_print,
eckey_priv_decode,
eckey_priv_encode,
eckey_priv_print,
int_ec_size,
ec_bits,
eckey_param_decode,
eckey_param_encode,
ec_missing_parameters,
ec_copy_parameters,
ec_cmp_parameters,
eckey_param_print,
0,
int_ec_free,
ec_pkey_ctrl,
old_ec_priv_decode,
old_ec_priv_encode
};
#endif
#ifndef OPENSSL_NO_CMS
@@ -999,3 +966,174 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
}
#endif
#ifndef OPENSSL_NO_GMSSL
static int sm2_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
const unsigned char *p = NULL;
void *pval;
int ptype, pklen;
EC_KEY *eckey = NULL;
X509_ALGOR *palg;
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
return 0;
X509_ALGOR_get0(NULL, &ptype, &pval, palg);
eckey = eckey_type2param(ptype, pval);
if (!eckey) {
ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
return 0;
}
/* We have parameters now set public key */
if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
goto ecerr;
}
EVP_PKEY_assign_EC_KEY(pkey, eckey);
return 1;
ecerr:
if (eckey)
EC_KEY_free(eckey);
return 0;
}
static int sm2_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
{
const unsigned char *p = NULL;
void *pval;
int ptype, pklen;
EC_KEY *eckey = NULL;
X509_ALGOR *palg;
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
return 0;
X509_ALGOR_get0(NULL, &ptype, &pval, palg);
eckey = eckey_type2param(ptype, pval);
if (!eckey)
goto ecliberr;
/* We have parameters now set private key */
if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
goto ecerr;
}
/* calculate public key (if necessary) */
if (EC_KEY_get0_public_key(eckey) == NULL) {
const BIGNUM *priv_key;
const EC_GROUP *group;
EC_POINT *pub_key;
/*
* the public key was not included in the SEC1 private key =>
* calculate the public key
*/
group = EC_KEY_get0_group(eckey);
pub_key = EC_POINT_new(group);
if (pub_key == NULL) {
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
EC_POINT_free(pub_key);
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
priv_key = EC_KEY_get0_private_key(eckey);
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
EC_POINT_free(pub_key);
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
EC_POINT_free(pub_key);
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
EC_POINT_free(pub_key);
}
EVP_PKEY_assign_SM2(pkey, eckey);
return 1;
ecliberr:
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
ecerr:
if (eckey)
EC_KEY_free(eckey);
return 0;
}
static int sm2_param_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{
EC_KEY *eckey;
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
return 0;
}
EVP_PKEY_assign_SM2(pkey, eckey);
return 1;
}
static int old_sm2_priv_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{
EC_KEY *ec;
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
return 0;
}
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
EVP_PKEY_assign_SM2(pkey, ec);
fprintf(stderr, "GMSSL %s %d: %s\n", __FILE__, __LINE__, __FUNCTION__);
OPENSSL_assert(EC_KEY_get0_group(ec));
return 1;
}
const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = {
EVP_PKEY_SM2,
EVP_PKEY_SM2,
0,
"SM2",
"GmSSL SM2 algorithm",
sm2_pub_decode,
eckey_pub_encode,
eckey_pub_cmp,
eckey_pub_print,
sm2_priv_decode,
eckey_priv_encode,
eckey_priv_print,
int_ec_size,
ec_bits,
sm2_param_decode,
eckey_param_encode,
ec_missing_parameters,
ec_copy_parameters,
ec_cmp_parameters,
eckey_param_print,
0,
int_ec_free,
ec_pkey_ctrl,
old_sm2_priv_decode,
old_ec_priv_encode
};
#endif

View File

@@ -61,6 +61,9 @@
#include <openssl/err.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#ifndef OPENSSL_NO_GMSSL
#include <openssl/evp.h>
#endif
int EC_GROUP_get_basis_type(const EC_GROUP *group)
{
@@ -970,24 +973,20 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
{
EC_GROUP *group = NULL;
ECPKPARAMETERS *params = NULL;
if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
if (a && *a)
EC_GROUP_clear_free(*a);
if (a)
*a = group;
ECPKPARAMETERS_free(params);
return (group);
}

View File

@@ -385,6 +385,9 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
#ifndef OPENSSL_NO_GMSSL
EVP_MD_type((const EVP_MD *)p2) != NID_sm3 &&
#endif
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
@@ -562,6 +565,32 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
};
#ifndef OPENSSL_NO_SM2
static int pkey_sm2_init(EVP_PKEY_CTX *ctx)
{
EC_PKEY_CTX *dctx;
dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
if (!dctx)
return 0;
dctx->gen_group = EC_GROUP_new_by_curve_name(NID_sm2p256v1);
if (dctx->gen_group == NULL) {
return 0;
}
dctx->md = NULL; //FIXME: sm3
dctx->cofactor_mode = -1;
dctx->co_key = NULL;
dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
dctx->kdf_md = NULL;
dctx->kdf_outlen = 0;
dctx->kdf_ukm = NULL;
dctx->kdf_ukmlen = 0;
ctx->data = dctx;
return 1;
}
static int pkey_sm2_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
EC_KEY *ec = NULL;
@@ -593,8 +622,8 @@ static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
int ret;
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
int type;
unsigned int len;
int type = NID_sm3;
size_t len;
if (!sig) {
*siglen = SM2_signature_size(ec_key);
@@ -605,12 +634,11 @@ static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
return 0;
}
type = ec_ctx->md ? EVP_MD_type(ec_ctx->md) : NID_sm3;
if ((ret = SM2_sign(type, dgst, dgstlen, sig, &len, ec_key)) <= 0) {
return ret;
}
*siglen = (size_t)len;
*siglen = len;
return 1;
}
@@ -632,7 +660,7 @@ static int pkey_sm2_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
EC_KEY *ec_key = ctx->pkey->pkey.ec;
const EVP_MD *md = EVP_sm3();
unsigned char zid[EVP_MAX_MD_SIZE];
unsigned int zidlen;
unsigned int zidlen = sizeof(zid);
if (!SM2_compute_id_digest(md, zid, &zidlen, ec_key)) {
ECerr(EC_F_PKEY_SM2_SIGNCTX_INIT, ERR_R_SM2_LIB);
@@ -678,12 +706,11 @@ static int pkey_sm2_verifyctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
int ret = 0;
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
const EVP_MD *md = EVP_sm3();
const EVP_MD *md = EVP_sm3(); // FIXME: we need to get md from somewhere
unsigned char zid[EVP_MAX_MD_SIZE];
unsigned int zidlen;
// FIXME: we need to get md from somewhere
zidlen = sizeof(zid);
if (!SM2_compute_id_digest(md, zid, &zidlen, ec_key)) {
goto end;
}
@@ -693,25 +720,24 @@ static int pkey_sm2_verifyctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
ret = 1;
end:
return 0;
return ret;
}
static int pkey_sm2_verifyctx(EVP_PKEY_CTX *ctx,
const unsigned char *sig, int siglen, EVP_MD_CTX *mctx)
{
unsigned char dgst[EVP_MAX_MD_SIZE];
size_t dgstlen;
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
int type = ec_ctx->md ? EVP_MD_type(ec_ctx->md) : NID_sm3;
/*
dgstlen = sizeof(dgst);
if (!EVP_DigestFinal_ex(mctx, dgst, &dgstlen)) {
goto end;
return -1;
}
return SM2_verify(type, dgst, dgstlen, sig, siglen, ec_key);
*/
return 0;
}
static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx,
@@ -728,7 +754,9 @@ static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx,
kdf_md = EVP_sm3();
mac_md = EVP_sm3();
return SM2_encrypt(kdf_md, mac_md, point_form, in, inlen, out, outlen, ec_key);
//FIXME: where to put the parameters?
return SM2_encrypt(in, inlen, out, outlen, ec_key);
}
static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx,
@@ -741,12 +769,8 @@ static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx,
const EVP_MD *mac_md = ec_ctx->md;
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
//FIXME: the ec_ctx is not work, no one init it
kdf_md = EVP_sm3();
mac_md = EVP_sm3();
return SM2_decrypt(kdf_md, mac_md, point_form,
in, inlen, out, outlen, ec_key);
return SM2_decrypt(in, inlen, out, outlen, ec_key);
}
static int pkey_sm2_ctrl_digestinit(EVP_PKEY_CTX *pk_ctx, EVP_MD_CTX *md_ctx)
@@ -823,7 +847,7 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *pk_ctx, int type, int p1, void *p2)
const EVP_PKEY_METHOD sm2_pkey_meth = {
EVP_PKEY_SM2,
0,
pkey_ec_init,
pkey_sm2_init,
pkey_ec_copy,
pkey_ec_cleanup,
0,
@@ -846,7 +870,7 @@ const EVP_PKEY_METHOD sm2_pkey_meth = {
pkey_sm2_decrypt,
pkey_sm2_derive_init,
pkey_sm2_derive,
pkey_sm2_ctrl,
pkey_ec_ctrl,
pkey_ec_ctrl_str
};
#endif

View File

@@ -345,4 +345,10 @@ const EVP_CIPHER *EVP_sms4_wrap(void)
}
//TODO: EVP_sms4_256_xxx();
#endif

View File

@@ -254,6 +254,14 @@ typedef int evp_verify_method(int type, const unsigned char *m,
# define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method
# endif
# ifndef OPENSSL_NO_SM2
# define EVP_PKEY_SM2_method (evp_sign_method *)SM2_sign, \
(evp_verify_method *)SM2_verify, \
{EVP_PKEY_SM2,0,0,0}
# else
# define EVP_PKEY_SM2_method EVP_PKEY_NULL_method
# endif
# ifndef OPENSSL_NO_RSA
# define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \
(evp_verify_method *)RSA_verify, \

View File

@@ -227,3 +227,15 @@ int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
return 1;
return 0;
}
#ifndef OPENSSL_NO_GMSSL
int EVP_PKEY_ec_to_sm2(EVP_PKEY *pkey, int only_sm2_curve)
{
return 0;
}
int EVP_PKEY_sm2_to_ec(EVP_PKEY *pkey)
{
return 0;
}
#endif

View File

@@ -87,8 +87,6 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
}
//fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (ver) {
if (ctx->pctx->pmeth->verifyctx_init) {
if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
@@ -98,22 +96,21 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
return 0;
} else {
if (ctx->pctx->pmeth->signctx_init) {
if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) {
fprintf(stderr, "error %s %d\n", __FILE__, __LINE__);
return 0;
}
ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
} else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
return 0;
}
//fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
return 0;
//fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (pctx)
*pctx = ctx->pctx;
//fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
return 1;
//fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (!EVP_DigestInit_ex(ctx, type, e))
return 0;
return 1;

View File

@@ -85,7 +85,7 @@ static const EVP_MD sm3_md = {
final,
NULL,
NULL,
EVP_PKEY_RSA_method,
EVP_PKEY_SM2_method,
SM3_BLOCK_SIZE,
sizeof(EVP_MD *) + sizeof(sm3_ctx_t),
};

View File

@@ -101,10 +101,10 @@ int EVP_PKEY_decrypt_old(unsigned char *out, const unsigned char *in, int inlen,
return 0;
}
if (!EVP_PKEY_encrypt_init(ctx)) {
if (!EVP_PKEY_decrypt_init(ctx)) {
goto end;
}
if (!EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen)) {
if (!EVP_PKEY_decrypt(ctx, out, &outlen, in, inlen)) {
goto end;
}

View File

@@ -80,6 +80,10 @@
#include "asn1_locl.h"
#ifndef OPENSSL_NO_GMSSL
#include "../ec/ec_lcl.h"
#endif
static void EVP_PKEY_free_it(EVP_PKEY *x);
int EVP_PKEY_bits(EVP_PKEY *pkey)
@@ -206,7 +210,6 @@ EVP_PKEY *EVP_PKEY_new(void)
* Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
* is NULL just return 1 or 0 if the algorithm exists.
*/
static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
{
const EVP_PKEY_ASN1_METHOD *ameth;
@@ -247,6 +250,7 @@ static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
pkey->type = pkey->ameth->pkey_id;
pkey->save_type = type;
}
return 1;
}
@@ -345,6 +349,7 @@ int EVP_PKEY_set1_SM2(EVP_PKEY *pkey, EC_KEY *key)
EC_KEY *EVP_PKEY_get1_SM2(EVP_PKEY *pkey)
{
/* FIXME: reconsider the SM2 and EC_KEY relationship */
if (pkey->type != EVP_PKEY_SM2) {
EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);//FIXME:errno
return NULL;

View File

@@ -30,7 +30,7 @@ extern "C" {
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
# define OPENSSL_VERSION_NUMBER 0x1000204fL
# define OPENSSL_VERSION_NUMBER 0x10201000L
# ifdef OPENSSL_FIPS
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2d-fips 9 Jul 2015"
# else

View File

@@ -18,10 +18,10 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= pem_sign.c pem_seal.c pem_info.c pem_lib.c pem_all.c pem_err.c \
pem_x509.c pem_xaux.c pem_oth.c pem_pk8.c pem_pkey.c pvkfmt.c
pem_x509.c pem_xaux.c pem_oth.c pem_pk8.c pem_pkey.c pvkfmt.c pem_sm2.c
LIBOBJ= pem_sign.o pem_seal.o pem_info.o pem_lib.o pem_all.o pem_err.o \
pem_x509.o pem_xaux.o pem_oth.o pem_pk8.o pem_pkey.o pvkfmt.o
pem_x509.o pem_xaux.o pem_oth.o pem_pk8.o pem_pkey.o pvkfmt.o pem_sm2.o
SRC= $(LIBSRC)

View File

@@ -137,6 +137,10 @@ extern "C" {
# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
# define PEM_STRING_PARAMETERS "PARAMETERS"
# define PEM_STRING_CMS "CMS"
# ifndef OPENSSL_NO_GMSSL
# define PEM_STRING_SM2PARAMETERS "SM2 PARAMETERS"
# define PEM_STRING_SM2PRIVATEKEY "SM2 PRIVATE KEY"
# endif
/*
* Note that this structure is initialised by PEM_SealInit and cleaned up

View File

@@ -853,9 +853,14 @@ int pem_check_suffix(const char *pem_str, const char *suffix)
int pem_len = strlen(pem_str);
int suffix_len = strlen(suffix);
const char *p;
fprintf(stderr, "GMSSL: %s %d: pem_str = %s\n", __FILE__, __LINE__, pem_str);
fprintf(stderr, "GMSSL: %s %d: suffix = %s\n", __FILE__, __LINE__, suffix);
if (suffix_len + 1 >= pem_len)
return 0;
p = pem_str + pem_len - suffix_len;
fprintf(stderr, "GMSSL: %s %d: p = %s\n", __FILE__, __LINE__, suffix);
if (strcmp(p, suffix))
return 0;
p--;

View File

@@ -89,8 +89,10 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
return NULL;
p = data;
fprintf(stderr, "GMSSL: %s %d: nm = %s\n", __FILE__, __LINE__, nm);
if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
PKCS8_PRIV_KEY_INFO *p8inf;
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
if (!p8inf)
goto p8err;
@@ -106,6 +108,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
X509_SIG *p8;
int klen;
char psbuf[PEM_BUFSIZE];
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
p8 = d2i_X509_SIG(NULL, &p, len);
if (!p8)
goto p8err;
@@ -131,11 +134,20 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
PKCS8_PRIV_KEY_INFO_free(p8inf);
} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) {
const EVP_PKEY_ASN1_METHOD *ameth;
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
fprintf(stderr, "GMSSL: %s %d: slen = %d\n", __FILE__, __LINE__, slen);
ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
OPENSSL_assert(ameth != NULL);
if (!ameth || !ameth->old_priv_decode)
goto p8err;
fprintf(stderr, "GMSSL: %s %d: type id = %d\n", __FILE__, __LINE__, ameth->pkey_id);
ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len);
OPENSSL_assert(ret != NULL);
}
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
p8err:
if (ret == NULL)
PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB);
@@ -143,6 +155,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
OPENSSL_free(nm);
OPENSSL_cleanse(data, len);
OPENSSL_free(data);
fprintf(stderr, "GMSSL: %s %d\n", __FILE__, __LINE__);
return (ret);
}

270
crypto/pem/pem_sm2.c Normal file
View File

@@ -0,0 +1,270 @@
/* crypto/pem/pem_sm2.c */
/* ====================================================================
* Copyright (c) 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*
*/
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/pkcs7.h>
#include <openssl/pem.h>
#ifndef OPENSSL_NO_SM2
static EC_KEY *pkey_get_sm2key(EVP_PKEY *key, EC_KEY **eckey)
{
EC_KEY *dtmp;
if (!key)
return NULL;
dtmp = EVP_PKEY_get1_SM2(key);
EVP_PKEY_free(key);
if (!dtmp)
return NULL;
if (eckey) {
EC_KEY_free(*eckey);
*eckey = dtmp;
}
fprintf(stderr, "GMSSL %s %d\n", __FILE__, __LINE__);
return dtmp;
}
EC_KEY *PEM_read_bio_SM2PrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
void *u)
{
EVP_PKEY *pktmp;
pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
return pkey_get_sm2key(pktmp, key); /* will free pktmp */
}
IMPLEMENT_PEM_rw_const(SM2PKParameters, EC_GROUP, PEM_STRING_SM2PARAMETERS,
ECPKParameters)
# ifdef OPENSSL_FIPS
int PEM_write_bio_SM2PrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u)
{
if (FIPS_mode()) {
EVP_PKEY *k;
int ret;
k = EVP_PKEY_new();
if (!k)
return 0;
EVP_PKEY_set1_EC_KEY(k, x);
ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
EVP_PKEY_free(k);
return ret;
} else
return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
PEM_STRING_SM2PRIVATEKEY,
bp, x, enc, kstr, klen, cb, u);
}
# ifndef OPENSSL_NO_FP_API
int PEM_write_SM2PrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u)
{
if (FIPS_mode()) {
EVP_PKEY *k;
int ret;
k = EVP_PKEY_new();
if (!k)
return 0;
EVP_PKEY_set1_EC_KEY(k, x);
ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
EVP_PKEY_free(k);
return ret;
} else
return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
PEM_STRING_SM2PRIVATEKEY,
fp, x, enc, kstr, klen, cb, u);
}
# endif
# else
IMPLEMENT_PEM_write_cb(SM2PrivateKey, EC_KEY, PEM_STRING_SM2PRIVATEKEY,
ECPrivateKey)
# endif
IMPLEMENT_PEM_rw(SM2_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
# ifndef OPENSSL_NO_FP_API
EC_KEY *PEM_read_SM2PrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
void *u)
{
EVP_PKEY *pktmp;
pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
printf("GMSSL %s %d\n", __FILE__, __LINE__);
BIO *out = BIO_new_fp(stderr, BIO_NOCLOSE);
EVP_PKEY_print_public(out, pktmp, 0, NULL);
EVP_PKEY_print_private(out, pktmp, 0, NULL);
EVP_PKEY_print_params(out, pktmp, 0, NULL);
return pkey_get_sm2key(pktmp, eckey); /* will free pktmp */
}
# endif
#endif

View File

@@ -109,21 +109,27 @@ int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen,
EC_KEY *ec_key);
int SM2_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
int SM2_encrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
int SM2_decrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_encrypt(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_decrypt(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_compute_message_digest(const EVP_MD *id_md, const EVP_MD *msg_md,
const void *msg, size_t msglen, unsigned char *dgst,
unsigned int *dgstlen, EC_KEY *ec_key);
int SM2_digest(const void *msg, size_t msglen, unsigned char *dgst,
unsigned int *dgstlen, EC_KEY *ec_key);
#define SM2_signature_size(ec_key) ECDSA_size(ec_key)
int SM2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx, BIGNUM **a, BIGNUM **b);
@@ -181,7 +187,6 @@ typedef struct sm2_kap_ctx_st {
int SM2_KAP_CTX_init(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
EC_KEY *remote_pubkey, int is_initiator, int do_checksum);
void SM2_KAP_CTX_cleanup(SM2_KAP_CTX *ctx);
int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,
size_t *ephem_point_len);
int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_ephem_point,
@@ -189,6 +194,7 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_ephem_poin
unsigned char *checksum, size_t *checksumlen);
int SM2_KAP_final_check(SM2_KAP_CTX *ctx, const unsigned char *checksum,
size_t checksumlen);
void SM2_KAP_CTX_cleanup(SM2_KAP_CTX *ctx);

View File

@@ -110,21 +110,39 @@ IMPLEMENT_ASN1_DUP_FUNCTION(SM2CiphertextValue)
int i2d_SM2_CIPHERTEXT_VALUE(const SM2_CIPHERTEXT_VALUE *c, unsigned char **out)
{
int ret = 0;
SM2CiphertextValue *asn1 = NULL;
BIGNUM *x = NULL;
BIGNUM *y = NULL;
/*
asn1 = SM2CiphertextValue_new();
asn1->xCoordinate = BN_to_ASN1_INTEGER(x, NULL);
asn1->yCoordinate = BN_to_ASN1_INTEGER(y, NULL);
*/
return 0;
if (!(asn1 = SM2CiphertextValue_new())) {
goto end;
}
OPENSSL_assert(asn1->xCoordinate);
OPENSSL_assert(asn1->yCoordinate);
if (!BN_to_ASN1_INTEGER(x, asn1->xCoordinate)) {
}
if (!BN_to_ASN1_INTEGER(y, asn1->yCoordinate)) {
}
M_ASN1_OCTET_STRING_set(asn1->hash, c->mactag, c->mactag_size);
M_ASN1_OCTET_STRING_set(asn1->ciphertext, c->ciphertext, c->ciphertext_size);
ret = 1;
end:
return ret;
}
SM2_CIPHERTEXT_VALUE *d2i_SM2_CIPHERTEXT_VALUE(SM2_CIPHERTEXT_VALUE **c,
const unsigned char **in, long len)
{
return NULL;
}

View File

@@ -239,7 +239,7 @@ end:
return 0;
}
int SM2_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
int SM2_encrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
@@ -430,7 +430,7 @@ end:
return cv;
}
int SM2_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
int SM2_decrypt_ex(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
@@ -599,3 +599,26 @@ end:
return ret;
}
int SM2_encrypt(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
const EVP_MD *kdf_md = EVP_sm3();
const EVP_MD *mac_md = EVP_sm3();
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
return SM2_encrypt_ex(kdf_md, mac_md, point_form,
in, inlen, out, outlen, ec_key);
}
int SM2_decrypt(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
const EVP_MD *kdf_md = EVP_sm3();
const EVP_MD *mac_md = EVP_sm3();
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
return SM2_decrypt_ex(kdf_md, mac_md, point_form,
in, inlen, out, outlen, ec_key);
}

View File

@@ -155,6 +155,102 @@ void SM2_KAP_CTX_cleanup(SM2_KAP_CTX *ctx)
memset(ctx, 0, sizeof(*ctx));
}
#if 0
int SM2_update_key(EC_KEY *ec_key, EC_POINT **point)
{
EC_KEY *tmp = NULL;
BIGNUM *d = EC_KEY_get0_private_key(ec_key);
if (!(tmp = EC_KEY_new())) {
goto end;
}
if (!EC_KEY_set_group(tmp, EC_KEY_get0_group(ec_key))) {
goto end;
}
if (!EC_KEY_generate_key(tmp)) {
goto end;
}
if (!EC_KEY_get_affine_coordinates(tmp, x, y)) {
goto end;
}
/* convert x to x' */
if (**point == NULL) {
*point = EC_POINT_dup(EC_KEY_get0_public_key(ec_key), EC_KEY_get0_group(ec_key));
} else {
EC_POINT_copy(*point, EC_KEY_get0_public_key(ec_key), EC_KEY_get0_group(ec_key));
}
end:
EC_KEY_free(tmp);
return 0;
}
int SM2_update_public_key(EC_KEY *ec_key, const EC_POINT *pub_key)
{
EC_GROUP *group;
group = EC_KEY_get0_group(ec_key);
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group, pub_key, x, NULL, bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, pub_key, x, NULL, bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
}
if (!BN_nnmod(x, x, ctx->two_pow_w, bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_add(x, x, ctx->two_pow_w)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_mul(ctx->t, x, r, ctx->order, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!EC_POINT_mul(group, point, NULL, point, x, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
if (!EC_POINT_add(group, pubkey, pubkey, point, bn_ctx)) {
goto end;
}
ret = 1;
end:
return ret;
}
int SM2_derive_key(void *out, size_t outlen,
const EC_POINT *pub_key, EC_KEY *ec_key,
void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
{
return 0;
}
#endif
/* FIXME: ephem_point_len should be both input and output */
int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,

View File

@@ -298,3 +298,13 @@ err:
return ret;
}
int SM2_digest(const void *msg, size_t msglen, unsigned char *dgst,
unsigned int *dgstlen, EC_KEY *ec_key)
{
const EVP_MD *id_md = EVP_sm3();
const EVP_MD *msg_md = EVP_sm3();
return SM2_compute_message_digest(id_md, msg_md,
msg, msglen, dgst, dgstlen, ec_key);
}

View File

@@ -523,7 +523,7 @@ int test_sm2_test_vector()
"00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD",
"013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E",
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC972CF7E6B6F900945B3C6A0CF6161D",
"1");
"4");
if (!sm2p192test || !sm2p256test || !sm2b193test || !sm2b257test) {
goto end;

105
crypto/sms4/sms4_common.c Normal file
View File

@@ -0,0 +1,105 @@
/* crypto/sms4/sms4_common.c */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
#include <stdint.h>
#include "sms4_lcl.h"
uint8_t SBOX[256] = {
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
};
uint32_t SBOX32L[256 * 256];
uint32_t SBOX32H[256 * 256];
void sms4_init_sbox32(void)
{
int i, j;
uint32_t a;
for (i = 0; i < 256; i++) {
for (j = 0; j < 256; j++) {
a = SBOX[i] << 8 | SBOX[j];
SBOX32L[(i << 8) + j] = a;
SBOX32H[(i << 8) + j] = a << 16;
}
}
}

67
crypto/sms4/sms4_ede.c Normal file
View File

@@ -0,0 +1,67 @@
/* crypto/sms4/sms4_ede.c */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
#include "sms4.h"
void sms4_ede_encrypt(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out)
{
sms4_encrypt(&key->k1, in, out);
sms4_decrypt(&key->k2, out, in);
sms4_encrypt(&key->k1, in, out);
}
void sms4_ede_decrypt(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out)
{
sms4_decrypt(&key->k1, in, out);
sms4_encrypt(&key->k2, in, out);
sms4_decrypt(&key->k1, in, out);
}

30
crypto/sms4/sms4_ede.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef LIBSM_SMS4_EDE_H
#define LIBSM_SMS4_EDE_H
#define SMS4_EDE_KEY_LENGTH 32
#include "sms4.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
sms4_key_t k1;
sms4_key_t k2;
} sms4_ede_key_t;
void sms4_ede_set_encrypt_key(sms4_ede_key_t *key, const unsigned char *user_key);
void sms4_ede_set_decrypt_key(sms4_ede_key_t *key, const unsigned char *user_key);
void sms4_ede_encrypt(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out);
void sms4_ede_encrypt_8blocks(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out);
void sms4_ede_encrypt_16blocks(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out);
void sms4_ede_decrypt(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out);
void sms4_ede_decrypt_8blocks(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out);
void sms4_ede_decrypt_16blocks(sms4_ede_key_t *key, const unsigned char *in, unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif

87
crypto/sms4/sms4_enc.c Normal file
View File

@@ -0,0 +1,87 @@
/* crypto/sms4/sms4_enc.c */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
#include "sms4.h"
#include "sms4_lcl.h"
#define L32(x) \
((x) ^ \
ROT32((x), 2) ^ \
ROT32((x), 10) ^ \
ROT32((x), 18) ^ \
ROT32((x), 24))
#define ROUND(x0, x1, x2, x3, x4, i) \
x4 = x1 ^ x2 ^ x3 ^ *(rk + i); \
x4 = S32(x4); \
x4 = x0 ^ L32(x4)
void sms4_encrypt(sms4_key_t *key, const unsigned char *in, unsigned char *out)
{
uint32_t *rk = key->rk;
uint32_t x0, x1, x2, x3, x4;
x0 = GET32(in );
x1 = GET32(in + 4);
x2 = GET32(in + 8);
x3 = GET32(in + 12);
ROUNDS(x0, x1, x2, x3, x4);
PUT32(x0, out );
PUT32(x4, out + 4);
PUT32(x3, out + 8);
PUT32(x2, out + 12);
x0 = x1 = x2 = x3 = x4 = 0;
}

150
crypto/sms4/sms4_enc_avx2.c Normal file
View File

@@ -0,0 +1,150 @@
/* crypto/sms4/sms4_enc_avx2.c */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
#include "sms4.h"
#include "sms4_lcl.h"
#include <immintrin.h>
static __m256i mask_ffff;
static __m256i vindex_0s;
static __m256i vindex_4i;
static __m256i vindex_swap;
static __m256i vindex_read;
void sms4_encrypt_init(sms4_key_t *key)
{
mask_ffff = _mm256_set1_epi32(0xffff);
vindex_0s = _mm256_set1_epi32(0);
vindex_4i = _mm256_setr_epi32(0,4,8,12,16,20,24,28);
vindex_read = _mm256_setr_epi32(0,8,16,24,1,9,17,25);
vindex_swap = _mm256_setr_epi8(
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12
);
sms4_init_sbox32();
}
#define GET_BLKS(x0, x1, x2, x3, in) \
t0 = _mm256_i32gather_epi32((int *)(in+4*0), vindex_4i, 4); \
t1 = _mm256_i32gather_epi32((int *)(in+4*1), vindex_4i, 4); \
t2 = _mm256_i32gather_epi32((int *)(in+4*2), vindex_4i, 4); \
t3 = _mm256_i32gather_epi32((int *)(in+4*3), vindex_4i, 4); \
x0 = _mm256_shuffle_epi8(t0, vindex_swap); \
x1 = _mm256_shuffle_epi8(t1, vindex_swap); \
x2 = _mm256_shuffle_epi8(t2, vindex_swap); \
x3 = _mm256_shuffle_epi8(t3, vindex_swap)
#define PUT_BLKS(out, x0, x1, x2, x3) \
t0 = _mm256_shuffle_epi8(x0, vindex_swap); \
t1 = _mm256_shuffle_epi8(x1, vindex_swap); \
t2 = _mm256_shuffle_epi8(x2, vindex_swap); \
t3 = _mm256_shuffle_epi8(x3, vindex_swap); \
_mm256_storeu_si256((__m256i *)(out+32*0), t0); \
_mm256_storeu_si256((__m256i *)(out+32*1), t1); \
_mm256_storeu_si256((__m256i *)(out+32*2), t2); \
_mm256_storeu_si256((__m256i *)(out+32*3), t3); \
x0 = _mm256_i32gather_epi32((int *)(in+32*0), vindex_read, 4); \
x1 = _mm256_i32gather_epi32((int *)(in+32*1), vindex_read, 4); \
x2 = _mm256_i32gather_epi32((int *)(in+32*2), vindex_read, 4); \
x3 = _mm256_i32gather_epi32((int *)(in+32*3), vindex_read, 4); \
_mm256_storeu_si256((__m256i *)(out+2*0), x0); \
_mm256_storeu_si256((__m256i *)(out+2*1), x1); \
_mm256_storeu_si256((__m256i *)(out+2*2), x2); \
_mm256_storeu_si256((__m256i *)(out+2*3), x3)
#define S(x0, t0, t1, t2) \
t0 = _mm256_and_si256(x0, mask_ffff); \
t1 = _mm256_i32gather_epi32(SBOX32L, t0, 4); \
t0 = _mm256_srli_epi32(x0, 16); \
t2 = _mm256_i32gather_epi32(SBOX32H, t0, 4); \
x0 = _mm256_xor_si256(t1, t2)
#define ROT(r0, x0, i, t0, t1) \
t0 = _mm256_slli_epi32(x0, i); \
t1 = _mm256_srli_epi32(x0,32-i); \
r0 = _mm256_xor_si256(t0, t1)
#define L(x0, t0, t1, t2, t3, t4) \
ROT(t0, x0, 2, t2, t3); \
ROT(t1, x0, 10, t2, t3); \
t4 = _mm256_xor_si256(t0, t1); \
ROT(t0, x0, 18, t2, t3); \
ROT(t1, x0, 24, t2, t3); \
t3 = _mm256_xor_si256(t0, t1); \
t2 = _mm256_xor_si256(x0, t3); \
x0 = _mm256_xor_si256(t2, t4)
#define ROUND(x0, x1, x2, x3, x4, i) \
t0 = _mm256_i32gather_epi32(rk+i, vindex_0s, 4); \
t1 = _mm256_xor_si256(x1, x2); \
t2 = _mm256_xor_si256(x3, t0); \
t0 = _mm256_xor_si256(t1, t2); \
S(t0, x4, t1, t2); \
L(t0, x4, t1, t2, t3, t4); \
x4 = _mm256_xor_si256(x0, t0);
void sms4_encrypt_8blocks(sms4_key_t *key, const unsigned char *in, unsigned char *out)
{
int *rk = (int *)key->rk;
__m256i x0, x1, x2, x3, x4;
__m256i t0, t1, t2, t3, t4;
GET_BLKS(x0, x1, x2, x3, in);
ROUNDS(x0, x1, x2, x3, x4);
PUT_BLKS(out, x0, x4, x3, x2);
}
void sms4_encrypt_16blocks(sms4_key_t *key, const unsigned char *in, unsigned char *out)
{
sms4_encrypt_8blocks(key, in, out);
sms4_encrypt_8blocks(key, in + 16*8, out + 16*8);
}

160
crypto/sms4/sms4_enc_knc.c Normal file
View File

@@ -0,0 +1,160 @@
/* crypto/sms4/sms4_enc_knc.c */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
#include <stdint.h>
#include <zmmintrin.h>
#include "sms4.h"
#include "sms4_lcl.h"
static __m512i mask_ff00;
static __m512i mask_ffff;
static __m512i mask_ff0000;
static __m512i vindex_0s;
static __m512i vindex_4i;
void sms4_encrypt_init(sms4_key_t *key)
{
uint64_t value[sizeof(__m512i)/sizeof(uint64_t)];
int *p = (int *)value;
for (i = 0; i < 16; i++)
p[i] = 0xff00;
mask_ff00 = _mm512_load_epi32(value);
for (i = 0; i < 16; i++)
p[i] = 0xffff;
mask_ffff = _mm512_load_epi32(value);
for (i = 0; i < 16; i++)
p[i] = 0xff0000;
mask_ff0000 = _mm512_load_epi32(value);
for (i = 0; i < 16; i++)
p[i] = 0;
vindex_0s = _mm512_load_epi32(value);
for (i = 0; i < 16; i++)
p[i] = 4 * i;
vindex_4i = _mm512_load_epi32(value);
sms4_init_sbox32();
}
#define SWAP32(x) \
t0 = _mm512_slli_epi32(x, 24); \
t1 = _mm512_srli_epi32(x, 24); \
t2 = _mm512_or_epi32(t0, t1); \
t0 = _mm512_slli_epi32(x, 8); \
t1 = _mm512_and_epi32(t0, mask_ff0000); \
t0 = _mm512_or_epi32(t2, t1); \
t1 = _mm512_srli_epi32(x, 8); \
t2 = _mm512_and_epi32(t1, mask_ff00); \
x = _mm512_or_epi32(t0, t2)
#define GET_BLKS(x0, x1, x2, x3, in) \
x0 = _mm512_i32gather_epi32(vindex_4i, in+4*0, 4); \
x1 = _mm512_i32gather_epi32(vindex_4i, in+4*1, 4); \
x2 = _mm512_i32gather_epi32(vindex_4i, in+4*2, 4); \
x3 = _mm512_i32gather_epi32(vindex_4i, in+4*3, 4); \
SWAP32(x0); SWAP32(x1); SWAP32(x2); SWAP32(x3)
#define PUT_BLKS(out, x0, x1, x2, x3) \
SWAP32(x0); SWAP32(x1); SWAP32(x2); SWAP32(x3); \
_mm512_i32scatter_epi32(out+4*0, vindex_4i, x0, 4); \
_mm512_i32scatter_epi32(out+4*1, vindex_4i, x1, 4); \
_mm512_i32scatter_epi32(out+4*2, vindex_4i, x2, 4); \
_mm512_i32scatter_epi32(out+4*3, vindex_4i, x3, 4)
#define S(x0, t0, t1, t2) \
t0 = _mm512_and_epi32(x0, mask_ffff); \
t1 = _mm512_i32gather_epi32(t0, SBOX32L, 4); \
t0 = _mm512_srli_epi32(x0, 16); \
t2 = _mm512_i32gather_epi32(t0, SBOX32H, 4); \
x0 = _mm512_xor_epi32(t1, t2)
#define ROT(r0, x0, i, t0, t1) \
t0 = _mm512_slli_epi32(x0, i); \
t1 = _mm512_srli_epi32(x0, 32-i); \
r0 = _mm512_xor_epi32(t0, t1)
#define L(x0, t0, t1, t2, t3, t4) \
ROT(t0, x0, 2, t2, t3); \
ROT(t1, x0, 10, t2, t3); \
t4 = _mm512_xor_epi32(t0, t1); \
ROT(t0, x0, 18, t2, t3); \
ROT(t1, x0, 24, t2, t3); \
t3 = _mm512_xor_epi32(t0, t1); \
t2 = _mm512_xor_epi32(x0, t3); \
x0 = _mm512_xor_epi32(t2, t4)
#define ROUND(x0, x1, x2, x3, x4, i) \
t0 = _mm512_i32gather_epi32(vindex_0s, rk+i*4, 4); \
t1 = _mm512_xor_epi32(x1, x2); \
t2 = _mm512_xor_epi32(x3, t0); \
t0 = _mm512_xor_epi32(t1, t2); \
S(t0, x4, t1, t2); \
L(t0, x4, t1, t2, t3, t4); \
x4 = _mm512_xor_epi32(x0, t0)
void sms4_encrypt_16blocks(sms4_key_t *key, const unsigned char *in, unsigned char *out)
{
int *rk = (int *)key->rk;
__m512i x0, x1, x2, x3, x4;
__m512i t0, t1, t2, t3, t4;
GET_BLKS(x0, x1, x2, x3, in);
ROUNDS(x0, x1, x2, x3, x4, ROUND);
PUT_BLKS(out, x2, x3, x4, x0);
}

View File

@@ -0,0 +1,75 @@
/* crypto/sms4/sms4_enc_nblks.c */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
#include "sms4.h"
void sms4_encrypt_init(sms4_key_t *key)
{
}
void sms4_encrypt_8blocks(sms4_key_t *key, const unsigned char *in, unsigned char *out)
{
sms4_encrypt(key, in , out );
sms4_encrypt(key, in + 16 , out + 16 );
sms4_encrypt(key, in + 16 * 2, out + 16 * 2);
sms4_encrypt(key, in + 16 * 3, out + 16 * 3);
sms4_encrypt(key, in + 16 * 4, out + 16 * 4);
sms4_encrypt(key, in + 16 * 5, out + 16 * 5);
sms4_encrypt(key, in + 16 * 6, out + 16 * 6);
sms4_encrypt(key, in + 16 * 7, out + 16 * 7);
}
void sms4_encrypt_16blocks(sms4_key_t *key, const unsigned char *in, unsigned char *out)
{
sms4_encrypt_8blocks(key, in, out);
sms4_encrypt_8blocks(key, in + 16 * 8, out + 16 * 8);
}

125
crypto/sms4/sms4_lcl.h Normal file
View File

@@ -0,0 +1,125 @@
/* crypto/sms4/sms4_lcl.h */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL 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 GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL 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 GmSSL 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.
* ====================================================================
*/
#ifndef LIBSM_SMS4_LCL_H
#define LIBSM_SMS4_LCL_H
#ifdef __cplusplus
extern "C" {
#endif
extern uint8_t SBOX[256];
extern uint32_t SBOX32L[256 * 256];
extern uint32_t SBOX32H[256 * 256];
#define GET32(pc) ( \
((uint32_t)(pc)[0] << 24) ^ \
((uint32_t)(pc)[1] << 16) ^ \
((uint32_t)(pc)[2] << 8) ^ \
((uint32_t)(pc)[3]))
#define PUT32(st, ct) \
(ct)[0] = (uint8_t)((st) >> 24); \
(ct)[1] = (uint8_t)((st) >> 16); \
(ct)[2] = (uint8_t)((st) >> 8); \
(ct)[3] = (uint8_t)(st)
#define ROT32(x,i) \
(((x) << i) | ((x) >> (32-i)))
#define S32(A) \
((SBOX[((A) >> 24) ] << 24) ^ \
(SBOX[((A) >> 16) & 0xff] << 16) ^ \
(SBOX[((A) >> 8) & 0xff] << 8) ^ \
(SBOX[((A)) & 0xff]))
#define ROUNDS(x0, x1, x2, x3, x4) \
ROUND(x0, x1, x2, x3, x4, 0); \
ROUND(x1, x2, x3, x4, x0, 1); \
ROUND(x2, x3, x4, x0, x1, 2); \
ROUND(x3, x4, x0, x1, x2, 3); \
ROUND(x4, x0, x1, x2, x3, 4); \
ROUND(x0, x1, x2, x3, x4, 5); \
ROUND(x1, x2, x3, x4, x0, 6); \
ROUND(x2, x3, x4, x0, x1, 7); \
ROUND(x3, x4, x0, x1, x2, 8); \
ROUND(x4, x0, x1, x2, x3, 9); \
ROUND(x0, x1, x2, x3, x4, 10); \
ROUND(x1, x2, x3, x4, x0, 11); \
ROUND(x2, x3, x4, x0, x1, 12); \
ROUND(x3, x4, x0, x1, x2, 13); \
ROUND(x4, x0, x1, x2, x3, 14); \
ROUND(x0, x1, x2, x3, x4, 15); \
ROUND(x1, x2, x3, x4, x0, 16); \
ROUND(x2, x3, x4, x0, x1, 17); \
ROUND(x3, x4, x0, x1, x2, 18); \
ROUND(x4, x0, x1, x2, x3, 19); \
ROUND(x0, x1, x2, x3, x4, 20); \
ROUND(x1, x2, x3, x4, x0, 21); \
ROUND(x2, x3, x4, x0, x1, 22); \
ROUND(x3, x4, x0, x1, x2, 23); \
ROUND(x4, x0, x1, x2, x3, 24); \
ROUND(x0, x1, x2, x3, x4, 25); \
ROUND(x1, x2, x3, x4, x0, 26); \
ROUND(x2, x3, x4, x0, x1, 27); \
ROUND(x3, x4, x0, x1, x2, 28); \
ROUND(x4, x0, x1, x2, x3, 29); \
ROUND(x0, x1, x2, x3, x4, 30); \
ROUND(x1, x2, x3, x4, x0, 31)
void sms4_init_sbox32(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,4 +1,4 @@
/* demo/gmssl/sms4enc.c */
/* crypto/sms4/sms4speed.c */
/* ====================================================================
* Copyright (c) 2014 - 2016 The GmSSL Project. All rights reserved.
*
@@ -46,66 +46,42 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <string.h>
#include <libgen.h>
#include <openmp.h>
#include "sms4.h"
int main(int argc, char **argv)
{
int ret = -1;
FILE *fp = stdin;
unsigned char key[32];
unsigned char buf[1024];
int len;
const EVP_MD *md;
HMAC_CTX hmctx;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int maclen, i;
sms4_key_t sms4_key;
unsigned char user_key[16] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
};
size_t buflen = SMS4_BLOCK_SIZE * 8 * 3 * 1000 * 1000;
unsigned char *buf = NULL;
unsigned char *p;
int i;
if (argc == 2) {
if (!(fp = fopen(argv[1], "r"))) {
fprintf(stderr, "open file %s failed\n", argv[1]);
return -1;
}
if (!(buf = (unsigned char *)malloc(buflen))) {
fprintf(stderr, "malloc failed\n");
return -1;
}
HMAC_CTX_init(&hmctx);
RAND_bytes(key, sizeof(key));
OpenSSL_add_all_digests();
if (!(md = EVP_get_digestbyname("sm3"))) {
ERR_print_errors_fp(stderr);
goto end;
}
if (!EVP_DigestSignInit()) {
goto end;
sms4_set_encrypt_key(&sms4_key, user_key);
#pragma omp parallel for
for (i = 0, p = buf; i < buflen/(SMS4_BLOCK_SIZE * 16); i++, p += SMS4_BLOCK_SIZE * 16) {
sms4_encrypt_16blocks(&sms4_key, p, p);
}
while ((len = fread(buf, 1, sizeof(buf), fp))) {
EVP_DigestSignUpdate(&hmctx, buf, len);
}
if (!EVP_DigestSignFinal()) {
goto end;
}
for (i = 0; i < maclen; i++) {
printf("%02x", mac[i]);
}
printf("\n");
ret = 0;
end:
fclose(fp);
EVP_cleanup();
return ret;
return 0;
}

79
crypto/sms4/sms4test.c Normal file
View File

@@ -0,0 +1,79 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sms4.h"
int main(int argc, char **argv)
{
int i;
sms4_key_t key;
unsigned char buf[16];
unsigned char user_key[16] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
};
uint32_t rk[32] = {
0xf12186f9, 0x41662b61, 0x5a6ab19a, 0x7ba92077,
0x367360f4, 0x776a0c61, 0xb6bb89b3, 0x24763151,
0xa520307c, 0xb7584dbd, 0xc30753ed, 0x7ee55b57,
0x6988608c, 0x30d895b7, 0x44ba14af, 0x104495a1,
0xd120b428, 0x73b55fa3, 0xcc874966, 0x92244439,
0xe89e641f, 0x98ca015a, 0xc7159060, 0x99e1fd2e,
0xb79bd80c, 0x1d2115b0, 0x0e228aeb, 0xf1780c81,
0x428d3654, 0x62293496, 0x01cf72e5, 0x9124a012,
};
unsigned char plaintext[16] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
};
unsigned char ciphertext1[16] = {
0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e,
0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46,
};
unsigned char ciphertext2[16] = {
0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f,
0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, 0x3f, 0x66,
};
/* test key scheduling */
sms4_set_encrypt_key(&key, user_key);
if (memcmp(key.rk, rk, sizeof(rk)) != 0) {
printf("sms4 key scheduling not passed!\n");
goto end;
}
printf("sms4 key scheduling passed!\n");
/* test encrypt once */
sms4_encrypt(&key, plaintext, buf);
if (memcmp(buf, ciphertext1, sizeof(ciphertext1)) != 0) {
printf("sms4 encrypt not pass!\n");
goto end;
}
printf("sms4 encrypt pass!\n");
/* test encrypt 1000000 times */
memcpy(buf, plaintext, sizeof(plaintext));
for (i = 0; i < 1000000; i++) {
sms4_encrypt(&key, buf, buf);
}
if (memcmp(buf, ciphertext2, sizeof(ciphertext2)) != 0) {
printf("sms4 encrypt 1000000 times not pass!\n");
goto end;
}
printf("sms4 encrypt 1000000 times pass!\n");
printf("sms4 all test vectors pass!\n");
return 0;
end:
printf("some test vector failed\n");
return -1;
}

36
demos/ameth.c Normal file
View File

@@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
int main(int argc, char **argv)
{
int i;
/*
int EVP_PKEY_asn1_get_count(void);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
const char *str, int len);
*/
int count = EVP_PKEY_asn1_get_count();
printf("EVP_PKEY_asn1_get_count() = %d\n", count);
for (i = 0; i < count; i++) {
const EVP_PKEY_ASN1_METHOD *ameth;
ameth = EVP_PKEY_asn1_get0(i);
int j;
const unsigned char *p = (const unsigned char *)ameth;
for (j = 0; j < 64; j++) {
printf("%02x", p[j]);
}
printf("\n");
}
}

8
demos/gmssl/ec_key.pem Normal file
View File

@@ -0,0 +1,8 @@
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBAQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MF8CAQEEGFKLikRIH3/XDuvS4Ih6SFr+bWVAnAAv1aAKBggqhkjOPQMBAaE0AzIA
BP2x9MuZ06z72j1BMoUe6zYbmenKt3RgZZufuTMbAoz2XIeFwlmDk2pX6XS2+uiU
gA==
-----END EC PRIVATE KEY-----

10
demos/gmssl/eckey.pem Normal file
View File

@@ -0,0 +1,10 @@
-----BEGIN PRIVATE KEY-----
MIIBYQIBADCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////v//////
//////////////8AAAAA//////////8wRAQg/////v////////////////////8A
AAAA//////////wEICjp+p6dn140TVqeS89lCafzl4n1FauPkt28vUFNlA6TBEEE
MsSuLB8ZgRlfmQRGajnJlI/jC7/yZgvhcVpFiTNMdMe8Nzai9PZ3nFm9zuNraSFT
0KmHfMYqR0AC3zLlITnwoAIhAP////7///////////////9yA99rIcYFK1O79Ak5
1UEjAgEBBG0wawIBAQQgPiMJOFBUJIqDZgYNyIei38Yknx9O9PpMAcmLGVx4PQqh
RANCAARZKqeiImjJ27a/49Cquf0Zz8U0429NlCFxY6YmS1Lu9i9ApqUH7UfY7tb0
9w8CpoqgJk4TjDz9ZQxNJPA2kZlq
-----END PRIVATE KEY-----

7
demos/gmssl/ecparam.pem Normal file
View File

@@ -0,0 +1,7 @@
-----BEGIN EC PARAMETERS-----
MIHgAgEBMCwGByqGSM49AQECIQD////+/////////////////////wAAAAD/////
/////zBEBCD////+/////////////////////wAAAAD//////////AQgKOn6np2f
XjRNWp5Lz2UJp/OXifUVq4+S3by9QU2UDpMEQQQyxK4sHxmBGV+ZBEZqOcmUj+ML
v/JmC+FxWkWJM0x0x7w3NqL09necWb3O42tpIVPQqYd8xipHQALfMuUhOfCgAiEA
/////v///////////////3ID32shxgUrU7v0CTnVQSMCAQE=
-----END EC PARAMETERS-----

9
demos/gmssl/ecpubkey.pem Normal file
View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBMzCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////v//////////
//////////8AAAAA//////////8wRAQg/////v////////////////////8AAAAA
//////////wEICjp+p6dn140TVqeS89lCafzl4n1FauPkt28vUFNlA6TBEEEMsSu
LB8ZgRlfmQRGajnJlI/jC7/yZgvhcVpFiTNMdMe8Nzai9PZ3nFm9zuNraSFT0KmH
fMYqR0AC3zLlITnwoAIhAP////7///////////////9yA99rIcYFK1O79Ak51UEj
AgEBA0IABFkqp6IiaMnbtr/j0Kq5/RnPxTTjb02UIXFjpiZLUu72L0CmpQftR9ju
1vT3DwKmiqAmThOMPP1lDE0k8DaRmWo=
-----END PUBLIC KEY-----

View File

@@ -1,23 +1,27 @@
#!/bin/bash
gmssl=/usr/local/bin/gmssl
#gmssl=/usr/local/bin/gmssl
gmssl=../../apps/gmssl
paramfile=ecparam.pem
keyfile=eckey.pem
pubkeyfile=ecpubkey.pem
pkeyopt="-pkeyopt ec_paramgen_curve:sm2p256v1"
echo -n abc | $gmssl dgst -sm3
echo -n abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd | gmssl dgst -sm3
#echo -n abc | $gmssl dgst -sm3
#echo -n abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd | gmssl dgst -sm3
#$gmssl version
#$gmssl ecparam -list_curves | grep sm2
#$gmssl ecparam -text -noout -name sm2p256v1 -param_enc explicit
$gmssl version
$gmssl ecparam -list_curves | grep sm2
$gmssl ecparam -text -noout -name sm2p256v1 -param_enc explicit
$gmssl genpkey -genparam -algorithm SM2 $ecpkeyopt -out $paramfile
#$gmssl genpkey -algorithm EC $pkeyopt -out $keyfile
#$gmssl pkey -text -noout -in $keyfile
#$gmssl pkey -in $keyfile -pubout -out $pubkeyfile
#$gmssl pkey -text -noout -pubin -in $pubkeyfile
$gmssl genpkey -algorithm SM2 $ecpkeyopt -out $keyfile
$gmssl pkey -text -noout -in $keyfile
$gmssl pkey -in $keyfile -pubout -out $pubkeyfile
$gmssl pkey -text -noout -pubin -in $pubkeyfile
echo hello | $gmssl pkeyutl -sign -inkey $keyfile -hexdump

32
demos/gmssl/pem.c Normal file
View File

@@ -0,0 +1,32 @@
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/ec.h>
int main(int argc, char **argv)
{
BIO *in = BIO_new_fp(stdin, BIO_NOCLOSE);
EC_GROUP *group = NULL;
EC_KEY *ec_key = NULL;
ERR_load_crypto_strings();
group = PEM_read_bio_SM2PKParameters(in, NULL, NULL, NULL);
if (!group) {
ERR_print_errors_fp(stderr);
return 0;
}
if (!EC_GROUP_check(group, NULL)) {
ERR_print_errors_fp(stderr);
return 0;
}
return 0;
ec_key = EC_KEY_new();
EC_KEY_set_group(ec_key, group);
return 0;
}

111
demos/gmssl/seal.c Normal file
View File

@@ -0,0 +1,111 @@
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/ecies.h>
#include <openssl/objects.h>
EVP_PKEY *pkey_new_ec()
{
int rv;
ECIES_PARAMS param;
EC_KEY *ec_key = NULL;
EVP_PKEY *pkey = NULL;
ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);
OPENSSL_assert(ec_key);
rv = EC_KEY_generate_key(ec_key);
OPENSSL_assert(rv == 1);
param.mac_nid = NID_hmac_full_ecies;
param.kdf_md = EVP_sha1();
param.sym_cipher = EVP_aes_128_cbc();
param.mac_md = EVP_sha1();
rv = ECIES_set_parameters(ec_key, &param);
ERR_print_errors_fp(stderr);
OPENSSL_assert(rv == 1);
OPENSSL_assert(ECIES_get_parameters(ec_key) != NULL);
pkey = EVP_PKEY_new();
OPENSSL_assert(pkey);
const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, EVP_PKEY_SM2);
OPENSSL_assert(ameth);
rv = EVP_PKEY_set1_SM2(pkey, ec_key);
ERR_print_errors_fp(stderr);
OPENSSL_assert(rv == 1);
return pkey;
}
int test_pkey_enc(void)
{
int rv;
EVP_PKEY *pkey[2];
int num_pkeys = sizeof(pkey)/sizeof(pkey[0]);
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher = EVP_sms4_cbc();
unsigned char iv[16];
unsigned char ek[2][256];
int eklen[sizeof(pkey)/sizeof(pkey[0])];
char *msg1 = "Hello ";
char *msg2 = "World!";
unsigned char ctbuf[256];
unsigned char ptbuf[256];
unsigned char *p;
int len, ctlen;
int i;
for (i = 0; i < num_pkeys; i++) {
pkey[i] = pkey_new_ec();
}
EVP_CIPHER_CTX_init(&ctx);
RAND_bytes(iv, sizeof(iv));
/* EVP_SealInit/Update/Final() */
rv = EVP_SealInit(&ctx, cipher, ek, eklen, iv, pkey, num_pkeys);
OPENSSL_assert(rv == num_pkeys);
p = ctbuf;
rv = EVP_SealUpdate(&ctx, p, &len, (unsigned char *)msg1, strlen(msg1));
OPENSSL_assert(rv == 1);
p += len;
rv = EVP_SealUpdate(&ctx, p, &len, (unsigned char *)msg2, strlen(msg2));
OPENSSL_assert(rv == 1);
p += len;
rv = EVP_SealFinal(&ctx, p, &len);
OPENSSL_assert(rv == 1);
p += len;
ctlen = p - ctbuf;
/* EVP_OpenInit/Update/Final() */
printf("%s() success!\n", __FUNCTION__);
return 0;
}
int main(int argc, char **argv)
{
test_pkey_enc();
return 0;
}

11
demos/gmssl/sm2-gencert.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash -x
KEY_FILE=user.key
REQ_FILE=user.req
CERT_FILE=user.pem
gmssl ecparam -genkey -name sm2p256v1 -text -out $KEY_FILE
gmssl req -new -key $KEY_FILE -out $REQ_FILE
gmssl ca -out $CERT_FILE -outdir . -infiles $REQ_FILE
gmssl pkcs12 -export -out user.pfx -in $CERT_FILE -inkey $KEY_FILE -certfile ./demoCA/cacert.pem

19
demos/gmssl/sm2-initca.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
DIR=demoCA
rm -fr $DIR
mkdir $DIR
mkdir $DIR/certs
mkdir $DIR/crl
mkdir $DIR/newcerts
mkdir $DIR/private/
touch $DIR/index.txt
touch $DIR/crlnumber
touch $DIR/private/.rand
echo 01 > $DIR/serial
gmssl ecparam -genkey -name sm2p256v1 -text -out $DIR/private/cakey.pem
gmssl req -new -x509 -days 3650 -key $DIR/private/cakey.pem -out $DIR/cacert.pem
gmssl x509 -text -noout -in $DIR/cacert.pem

View File

@@ -59,14 +59,297 @@
#include <openssl/engine.h>
#include <openssl/sm2.h>
#define NUM_PKEYS 4
int main()
{
int ret = -1;
int verbose = 0;
BIO *out = NULL;
int id = EVP_PKEY_SM2;
const EVP_MD *md = EVP_sm3();
ENGINE *engine = NULL;
EVP_PKEY_CTX *pkctx;
EVP_PKEY_CTX *pkctx = NULL;
EVP_PKEY *pkey = NULL;
EVP_MD_CTX *mdctx = NULL;
EVP_CIPHER_CTX *cpctx = NULL;
unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world";
size_t dgstlen = 32;
unsigned char sig[256];
size_t siglen = sizeof(sig);
unsigned char msg[] = "hello world this is the message";
size_t msglen = sizeof(msg);
unsigned char cbuf[512];
size_t cbuflen = sizeof(cbuf);
unsigned char mbuf[512];
size_t mbuflen = sizeof(mbuf);
int len;
unsigned int ulen;
ERR_load_crypto_strings();
out = BIO_new_fp(stdout, BIO_NOCLOSE);
if (!(pkctx = EVP_PKEY_CTX_new_id(id, engine))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_keygen_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_keygen(pkctx, &pkey)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
EVP_PKEY_CTX_free(pkctx);
if (0) {
EVP_PKEY_print_public(out, pkey, 4, NULL);
BIO_printf(out, "\n");
EVP_PKEY_print_private(out, pkey, 4, NULL);
BIO_printf(out, "\n");
}
if (!(pkctx = EVP_PKEY_CTX_new(pkey, engine))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* EVP_PKEY_sign() */
if (!EVP_PKEY_sign_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
bzero(sig, sizeof(sig));
siglen = sizeof(sig);
dgstlen = 32;
if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
size_t i;
printf("signature (%zu bytes) = ", siglen);
for (i = 0; i < siglen; i++) {
printf("%02X", sig[i]);
}
printf("\n");
}
if (!EVP_PKEY_verify_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
printf("signature verification success!\n");
}
/* EVP_PKEY_encrypt() */
if (!EVP_PKEY_encrypt_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
cbuflen = sizeof(cbuf);
if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
size_t i;
printf("ciphertext (%zu bytes) = ", cbuflen);
for (i = 0; i < cbuflen; i++) {
printf("%02X", cbuf[i]);
}
printf("\n");
}
if (!EVP_PKEY_decrypt_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
bzero(mbuf, sizeof(mbuf));
mbuflen = sizeof(mbuf);
if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
printf("original message = %s\n", msg);
printf("decrypted message = %s\n", mbuf);
}
pkctx = EVP_PKEY_CTX_new_id(id, engine);
/* EVP_PKEY_encrypt_old */
if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
int i;
printf("ciphertext (%d bytes) = ", len);
for (i = 0; i < len; i++) {
printf("%02X", cbuf[i]);
}
printf("\n");
}
bzero(mbuf, sizeof(mbuf));
if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
printf("original message = %s\n", msg);
printf("decrypted message = %s\n", mbuf);
}
if (!(mdctx = EVP_MD_CTX_create())) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* EVP_SignInit_ex/Update/Final_ex */
if (!EVP_SignInit_ex(mdctx, EVP_sm3(), engine)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_SignUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_SignFinal(mdctx, sig, &ulen, pkey)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
siglen = ulen;
if (verbose) {
size_t i;
printf("signature (%zu bytes) = ", siglen);
for (i = 0; i < siglen; i++) {
printf("%02X", sig[i]);
}
printf("\n");
}
if (!EVP_VerifyInit_ex(mdctx, EVP_sm3(), engine)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_VerifyUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (EVP_VerifyFinal(mdctx, sig, ulen, pkey) != SM2_VERIFY_SUCCESS) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* EVP_DigestSignInit/Update/Final() */
// FIXME: return values might be different, not just 1 or 0
if (!EVP_DigestSignInit(mdctx, &pkctx, md, engine, pkey)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
siglen = sizeof(sig);
if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
pkctx = NULL;
if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, engine, pkey)) {
ERR_print_errors_fp(stderr);
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* EVP_SealInit/Update/Final() EVP_OpenInit/Update/Final() */
/*
EVP_PKEY *pk[NUM_PKEYS] = {0};
unsigned char iv[16];
unsigned char ek[NUM_PKEYS][256];
int eklen[NUM_PKEYS];
RAND_pseudo_bytes(iv, sizeof(iv));
int i;
for (i = 0; i < NUM_PKEYS; i++) {
}
if (!(cpctx = EVP_CIPHER_CTX_new())) {
goto end;
}
if (!EVP_SealInit(cpctx, cipher, ek, &ekl, iv, pubk, npubk)) {
goto end;
}
if (!EVP_SealUpdate(cpctx, msg, msglen)) {
goto end;
}
if (!EVP_SealFinal(cpctx, cbuf, (int *)&cbuflen)) {
goto end;
}
*/
printf("test success!\n");
ret = 1;
end:
ERR_print_errors_fp(stderr);
return ret;
}

View File

@@ -1,3 +1,7 @@
/*
* The SKF ENGINE will be released when EC_KEY_METHOD is avaiable
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -28,74 +32,106 @@ static int skf_destroy(ENGINE *e);
#define SKF_CMD_LIST_DEVS ENGINE_CMD_BASE
static int skf_open_container(const char *dev,
const unsigned char *authkey, size_t authkeylen,
const char *app, const char *pin,
const char *container, HCONTAINER *phContainer)
{
ULONG rv;
DEVINFO devInfo;
DEVHANDLE hDev = NULL;
HAPPLICATION hApp = NULL;
HCONTAINER hContainer = NULL;
if ((rv = SKF_ConnectDev(dev, &hDev)) != SAR_OK) {
goto end;
}
if ((rv = SKF_GetDevInfo(hDev, &devInfo)) != SAR_OK) {
goto end;
}
if ((rv = SKF_GenRandom(hDev, authRand, sizeof(authRand))) != SAR_OK) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* Encrypt(authRand, authData, authKey) */
if ((rv = SKF_DevAuth(hDev, authData, len)) != SAR_OK) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if ((rv = SKF_OpenApplication(hDev, appName, &hApp)) != SAR_OK) {
goto end;
}
if ((rv = SKF_VerifyPIN(hApp, USER_TYPE, pin, &retryCount)) != SAR_OK) {
goto end;
}
if ((rv = SKF_OpenContainer(hApp, containerName, &hContainer)) != SAR_OK) {
goto end;
}
if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) {
goto end;
}
if (containerType != CONTAINER_TYPE_ECC) {
goto end;
}
end:
return 0;
}
static EVP_PKEY *skf_load_pubkey(ENGINE *e, const char *key_id,
UI_METHOD *ui_method, void *callback_data)
{
ULONG rv, len;
EVP_PKEY *ret = NULL;
EC_KEY *ec_key = NULL;
ECCPUBLICKEYBLOB blob;
BIGNUM *x = NULL;
BIGNUM *y = NULL;
int nbytes;
len = sizeof(blob);
if ((rv = SKF_ExportPublicKey(hContainer, TRUE, &blob, &len)) != SAR_OK) {
goto end;
}
if (!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) {
goto end;
}
if (EC_KEY_get_degree(ec_key) != blob.BitLen) {
goto end;
}
nbytes = (blob.BitLen + 7)/8;
if (!(x = BN_bin2bn(&(blob.XCoordinate), nbytes, NULL))) {
goto end;
}
if (!(y = BN_bin2bn(&(blob.YCoordinate), nbytes, NULL))) {
goto end;
}
if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) {
goto end;
}
if (!(ret = EVP_PKEY_new())) {
goto end;
}
EVP_PKEY_assign_SM2(ret, ec_key);
end:
EC_KEY_free(ec_key);
BN_free(x);
BN_free(y)
return ret;
}
static int skf_init(ENGINE *e)
{
ULONG rv;
ULONG len;
BOOL bPresent = TRUE;
CHAR *devNameList = NULL;
LPSTR devName;
ULONG devState;
DEVINFO devInfo;
BYTE authData[16];
CHAR appNameList[256];
LPSTR appName;
HAPPLICATION hApp;
CHAR containerNameList[256];
LPSTR containerName;
HCONTAINER hContainer;
ULONG containerType;
if ((rv = SKF_EnumDev(bPresent, NULL, &len)) != SAR_OK) {
SKFerr(SKF_F_SKF_INIT, skf_err2openssl(rv));
goto end;
}
if (!(devNameList = OPENSSL_malloc(len))) {
goto end;
}
if ((rv = SKF_EnumDev(bPresent, devNameList, &len)) != SAR_OK) {
goto end;
}
if (devNameList[0] = 0) {
return -1;
}
devName = devNameList;
if ((rv = SKF_ConnectDev(devName, &hDev)) != SAR_OK) {
return -1;
}
if ((rv = SKF_GetDevInfo(hDev, &devInfo)) != SAR_OK) {
return -1;
}
if ((rv = SKF_DevAuth(hDev, authData, sizeof(authData))) != SAR_OK) {
return -1;
}
if ((rv = SKF_EnumApplication(hDev, NULL, &len)) != SAR_OK) {
return -1;
}
if (!(appNameList = OPENSSL_malloc(len))) {
return -1;
}
if ((rv = SKF_EnumApplication(hDev, appNameList, &len)) != SAR_OK) {
return -1;
}
if (appNameList[0] = 0) {
return -1;
}
appName = appNameList;
if ((rv = SKF_OpenApplication(hDev, appName, &hApp)) != SAR_OK) {
return -1;
}
for (p = containerNameList; p; p += strlen(p)) {
// check container type
}
return 0;
}
@@ -104,12 +140,6 @@ static int skf_finish(ENGINE *e)
return 0;
}
typedef struct {
HANDLE hKey;
} EVP_SKF_KEY;
static int skf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
@@ -476,7 +506,7 @@ static ENGINE *engine_skf(void)
return ret;
}
void ENGINE_load_4758cca(void)
void ENGINE_load_skf(void)
{
ENGINE *e_skf = engine_skf();
if (!e_skf) {
@@ -500,9 +530,15 @@ static int bind(ENGINE *e, const char *id)
if (!ENGINE_set_id(e, engine_skf_id) ||
!ENGINE_set_name(e, engine_skf_name) ||
!ENGINE_set_init_function(e, skf_init) ||
!ENGINE_set_finish_function(e, skf_finish) ||
!ENGINE_set_ctrl_function(e, skf_ctrl) ||
!ENGINE_set_destroy_function(e, skf_destroy) ||
!ENGINE_set_digests(e, skf_digests) ||
!ENGINE_set_ciphers(e, skf_ciphers) ||
!ENGINE_set_load_pubkey_function(e, skf_load_pubkey) ||
!ENGINE_set_RAND(e, &skf_random)) {
return 0;
}

BIN
engines/skf/a.out Executable file

Binary file not shown.

View File

@@ -143,9 +143,6 @@ typedef HANDLE HCONTAINER;
#define SECURE_USER_ACCOUNT 0x00000010
#define SECURE_ANYONE_ACCOUNT 0x000000FF
#define DEV_ABSENT_STATE 0x00000000
#define DEV_PRESENT_STATE 0x00000001
#define DEV_UNKNOW_STATE 0x00000010
@@ -259,6 +256,10 @@ ULONG DEVAPI SKF_EnumDev(BOOL bPresent,
ULONG DEVAPI SKF_ConnectDev(LPSTR szName,
DEVHANDLE *phDev);
ULONG DEVAPI SKF_DisConnectDev(DEVHANDLE hDev);
#define DEV_ABSENT_STATE 0x00000000
#define DEV_PRESENT_STATE 0x00000001
#define DEV_UNKNOW_STATE 0x00000010
ULONG DEVAPI SKF_GetDevState(LPSTR szDevName,
ULONG *pulDevState);
ULONG DEVAPI SKF_SetLabel(DEVHANDLE hDev,
@@ -354,17 +355,30 @@ ULONG DEVAPI SKF_OpenContainer(HAPPLICATION hApplication,
LPSTR szContainerName,
HCONTAINER *phContainer);
ULONG DEVAPI SKF_CloseContainer(HCONTAINER hContainer);
#define CONTAINER_TYPE_UNDEF 0
#define CONTAINER_TYPE_RSA 1
#define CONTAINER_TYPE_ECC 2
ULONG DEVAPI SKF_GetContainerType(HCONTAINER hContainer,
ULONG *pulContainerType);
ULONG DEVAPI SKF_ImportCertificate(HCONTAINER hContainer,
BOOL bSignFlag,
BOOL bExportSignKey,
BYTE *pbCert,
ULONG ulCertLen);
ULONG DEVAPI SKF_ExportCertificate(HCONTAINER hContainer,
BOOL bSignFlag,
BYTE *pbCert,
ULONG *pulCertLen);
ULONG DEVAPI SKF_ExportPublicKey(HCONTAINER hContainer,
BOOL bSignFlag,
BYTE *pbBlob,
ULONG *pulBlobLen);
ULONG DEVAPI SKF_GenRandom(DEVHANDLE hDev,
BYTE *pbRandom,
ULONG ulRandomLen);
@@ -409,14 +423,16 @@ ULONG DEVAPI SKF_ExtRSAPriKeyOperation(DEVHANDLE hDev,
ULONG ulInputLen,
BYTE *pbOutput,
ULONG *pulOutputLen);
ULONG DEVAPI SKF_GenECCKeyPair(HCONTAINER hContainer,
ULONG ulAlgId,
ECCPUBLICKEYBLOB *pBlob);
ULONG DEVAPI SKF_ImportECCKeyPair(HCONTAINER hContainer,
PENVELOPEDKEYBLOB pEnvelopedKeyBlob);
ULONG DEVAPI SKF_ECCSignData(HCONTAINER hContainer,
BYTE *pbData,
ULONG ulDataLen,
BYTE *pbDigest,
ULONG ulDigestLen,
PECCSIGNATUREBLOB pSignature);
ULONG DEVAPI SKF_ECCVerify(DEVHANDLE hDev,
@@ -439,7 +455,7 @@ ULONG DEVAPI SKF_ExtECCDecrypt(DEVHANDLE hDev,
PECCCIPHERBLOB pCipherText,
BYTE *pbPlainText,
ULONG *pulPlainTextLen);
ULONG DEVAPI SKF_ExtECCSign(DEVHANDLE hDev,
ULONG DEVAPI SKF_ExtECCSign(DEVHANDLE hDev,
ECCPRIVATEKEYBLOB *pECCPriKeyBlob,
BYTE *pbData,
ULONG ulDataLen,
@@ -449,6 +465,7 @@ ULONG DEVAPI SKF_ExtECCVerify(DEVHANDLE hDev,
BYTE *pbData,
ULONG ulDataLen,
PECCSIGNATUREBLOB pSignature);
ULONG DEVAPI SKF_GenerateAgreementDataWithECC(HCONTAINER hContainer,
ULONG ulAlgId,
ECCPUBLICKEYBLOB *pTempECCPubKeyBlob,
@@ -471,10 +488,8 @@ ULONG DEVAPI SKF_GenerateKeyWithECC(HANDLE hAgreementHandle,
BYTE *pbID,
ULONG ulIDLen,
HANDLE *phKeyHandle);
ULONG DEVAPI SKF_ExportPublicKey(HCONTAINER hContainer,
BOOL bSignFlag,
BYTE *pbBlob,
ULONG *pulBlobLen);
ULONG DEVAPI SKF_ImportSessionKey(HCONTAINER hContainer,
ULONG ulAlgId,
BYTE *pbWrapedData,
@@ -484,6 +499,7 @@ ULONG DEVAPI SKF_SetSymmKey(DEVHANDLE hDev,
BYTE *pbKey,
ULONG ulAlgID,
HANDLE *phKey);
ULONG DEVAPI SKF_EncryptInit(HANDLE hKey,
BLOCKCIPHERPARAM EncryptParam);
ULONG DEVAPI SKF_Encrypt(HANDLE hKey,
@@ -514,6 +530,7 @@ ULONG DEVAPI SKF_DecryptUpdate(HANDLE hKey,
ULONG DEVAPI SKF_DecryptFinal(HANDLE hKey,
BYTE *pbDecryptedData,
ULONG *pulDecryptedDataLen);
ULONG DEVAPI SKF_DigestInit(DEVHANDLE hDev,
ULONG ulAlgID,
ECCPUBLICKEYBLOB *pPubKey,

View File

@@ -2,24 +2,14 @@
#include <string.h>
#include "skf.h"
#define DEV_NAME "dev0"
#define DEV_NAME "skf-soft-token"
#define DEV_NAME_LIST DEV_NAME"\0"
#define APP_NAME "app0"
#define APP_NAME "default-app"
#define APP_NAME_LIST APP_NAME"\0"
#define CONTAINER_NAME "container0"
#define CONTAINER_NAME_LIST CONTAINER_NAME"\0"
#define CONTAINER_TYPE_UNDEF 0
#define CONTAINER_TYPE_RSA 1
#define CONTAINER_TYPE_ECC 2
int default_dev = 1;
int default_app = 1;
int default_container = 1;
DEVHANDLE DEV_HANDLE = &default_dev;
HAPPLICATION APP_HANDLE = &default_app;
HCONTAINER CONTAINER_HANDLE = &default_container;
ULONG DEVAPI SKF_WaitForDevEvent(LPSTR szDevName,
ULONG *pulDevNameLen, ULONG *pulEvent)
@@ -36,39 +26,12 @@ ULONG DEVAPI SKF_EnumDev(BOOL bPresent,
LPSTR szNameList,
ULONG *pulSize)
{
if (!szNameList) {
*pulSize = sizeof(DEV_NAME_LIST);
return SAR_OK;
}
if (*pulSize < sizeof(DEV_NAME_LIST)) {
return SAR_BUFFER_TOO_SMALL;
}
memcpy(szNameList, DEV_NAME_LIST, sizeof(DEV_NAME_LIST));
*pulSize = sizeof(DEV_NAME_LIST);
return SAR_OK;
}
ULONG DEVAPI SKF_ConnectDev(LPSTR szName,
DEVHANDLE *phDev)
{
printf("%s\n", (char *)szName);
if (!phDev) {
printf("shit\n");
return SAR_INVALIDPARAMERR;
}
if (memcmp(szName, DEV_NAME, sizeof(DEV_NAME))) {
printf("%s %s\n", szName, DEV_NAME);
return SAR_FAIL;
}
*phDev = DEV_HANDLE;
return SAR_OK;
}
@@ -80,23 +43,17 @@ ULONG DEVAPI SKF_DisConnectDev(DEVHANDLE hDev)
ULONG DEVAPI SKF_GetDevState(LPSTR szDevName,
ULONG *pulDevState)
{
if (!szDevName || !pulDevState) {
if (!pulDevState) {
return SAR_INVALIDPARAMERR;
}
if (memcmp(szDevName, DEV_NAME, sizeof(DEV_NAME))) {
return SAR_FAIL;
}
*pulDevState = DEV_PRESENT_STATE;
return SAR_OK;
}
ULONG DEVAPI SKF_SetLabel(DEVHANDLE hDev,
LPSTR szLabel)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_GetDevInfo(DEVHANDLE hDev,
@@ -131,12 +88,12 @@ ULONG DEVAPI SKF_GetDevInfo(DEVHANDLE hDev,
ULONG DEVAPI SKF_LockDev(DEVHANDLE hDev,
ULONG ulTimeOut)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_UnlockDev(DEVHANDLE hDev)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_Transmit(DEVHANDLE hDev,
@@ -145,14 +102,14 @@ ULONG DEVAPI SKF_Transmit(DEVHANDLE hDev,
BYTE *pbData,
ULONG *pulDataLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_ChangeDevAuthKey(DEVHANDLE hDev,
BYTE *pbKeyValue,
ULONG ulKeyLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_DevAuth(DEVHANDLE hDev,
@@ -168,7 +125,7 @@ ULONG DEVAPI SKF_ChangePIN(HAPPLICATION hApplication,
LPSTR szNewPin,
ULONG *pulRetryCount)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
LONG DEVAPI SKF_GetPINInfo(HAPPLICATION hApplication,
@@ -193,12 +150,12 @@ ULONG DEVAPI SKF_UnblockPIN(HAPPLICATION hApplication,
LPSTR szNewUserPIN,
ULONG *pulRetryCount)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_ClearSecureState(HAPPLICATION hApplication)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_CreateApplication(DEVHANDLE hDev,
@@ -210,7 +167,7 @@ ULONG DEVAPI SKF_CreateApplication(DEVHANDLE hDev,
DWORD dwCreateFileRights,
HAPPLICATION *phApplication)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_EnumApplication(DEVHANDLE hDev,
@@ -221,45 +178,31 @@ ULONG DEVAPI SKF_EnumApplication(DEVHANDLE hDev,
*pulSize = sizeof(APP_NAME_LIST);
return SAR_OK;
}
if (*pulSize < sizeof(APP_NAME_LIST)) {
return SAR_BUFFER_TOO_SMALL;
}
memcpy(szAppName, APP_NAME_LIST, sizeof(APP_NAME_LIST));
return SAR_OK;
}
ULONG DEVAPI SKF_DeleteApplication(DEVHANDLE hDev,
LPSTR szAppName)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_OpenApplication(DEVHANDLE hDev,
LPSTR szAppName,
HAPPLICATION *phApplication)
{
if (!szAppName || !phApplication) {
if (!phApplication) {
return SAR_INVALIDPARAMERR;
}
if (hDev != DEV_HANDLE || memcmp(szAppName, APP_NAME, sizeof(APP_NAME))) {
return SAR_FAIL;
}
*phApplication = APP_HANDLE;
return SAR_OK;
}
ULONG DEVAPI SKF_CloseApplication(HAPPLICATION hApplication)
{
if (hApplication != APP_HANDLE) {
return SAR_FAIL;
}
return SAR_OK;
}
@@ -315,13 +258,13 @@ ULONG DEVAPI SKF_CreateContainer(HAPPLICATION hApplication,
LPSTR szContainerName,
HCONTAINER *phContainer)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_DeleteContainer(HAPPLICATION hApplication,
LPSTR szContainerName)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_EnumContainer(HAPPLICATION hApplication,
@@ -331,22 +274,14 @@ ULONG DEVAPI SKF_EnumContainer(HAPPLICATION hApplication,
if (!pulSize) {
return SAR_INVALIDPARAMERR;
}
if (hApplication != APP_HANDLE) {
return SAR_FAIL;
}
if (!szContainerName) {
*pulSize = sizeof(CONTAINER_NAME_LIST);
return SAR_OK;
}
if (*pulSize < sizeof(CONTAINER_NAME_LIST)) {
return SAR_BUFFER_TOO_SMALL;
}
memcpy(szContainerName, CONTAINER_NAME_LIST, sizeof(CONTAINER_NAME_LIST));
return SAR_OK;
}
@@ -354,25 +289,11 @@ ULONG DEVAPI SKF_OpenContainer(HAPPLICATION hApplication,
LPSTR szContainerName,
HCONTAINER *phContainer)
{
if (!szContainerName || !phContainer) {
return SAR_INVALIDPARAMERR;
}
if (hApplication != APP_HANDLE || memcmp(szContainerName, CONTAINER_NAME, sizeof(CONTAINER_NAME))) {
return SAR_FAIL;
}
*phContainer = CONTAINER_HANDLE;
return SAR_OK;
}
ULONG DEVAPI SKF_CloseContainer(HCONTAINER hContainer)
{
if (hContainer != CONTAINER_HANDLE) {
return SAR_FAIL;
}
return SAR_OK;
}
@@ -382,13 +303,7 @@ ULONG DEVAPI SKF_GetContainerType(HCONTAINER hContainer,
if (!pulContainerType) {
return SAR_INVALIDPARAMERR;
}
if (hContainer != CONTAINER_HANDLE) {
return SAR_FAIL;
}
*pulContainerType = CONTAINER_TYPE_UNDEF;
*pulContainerType = CONTAINER_TYPE_ECC;
return SAR_OK;
}
@@ -397,7 +312,7 @@ ULONG DEVAPI SKF_ImportCertificate(HCONTAINER hContainer,
BYTE *pbCert,
ULONG ulCertLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_ExportCertificate(HCONTAINER hContainer,
@@ -412,19 +327,6 @@ ULONG DEVAPI SKF_GenRandom(DEVHANDLE hDev,
BYTE *pbRandom,
ULONG ulRandomLen)
{
/*
if (!pbRandom || ulRandomLen > 100 * 1024 * 1024) {
return SAR_INVALIDPARAMERR;
}
if (hDev != DEV_HANDLE) {
return SAR_FAIL;
}
if (!RAND_pseudo_bytes(pbRandom, ulRandomLen)) {
return SAR_GENRANDERR;
}
*/
return SAR_OK;
}
@@ -632,13 +534,13 @@ ULONG DEVAPI SKF_SetSymmKey(DEVHANDLE hDev,
ULONG ulAlgID,
HANDLE *phKey)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_EncryptInit(HANDLE hKey,
BLOCKCIPHERPARAM EncryptParam)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_Encrypt(HANDLE hKey,
@@ -647,7 +549,7 @@ ULONG DEVAPI SKF_Encrypt(HANDLE hKey,
BYTE *pbEncryptedData,
ULONG *pulEncryptedLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_EncryptUpdate(HANDLE hKey,
@@ -656,20 +558,20 @@ ULONG DEVAPI SKF_EncryptUpdate(HANDLE hKey,
BYTE *pbEncryptedData,
ULONG *pulEncryptedLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_EncryptFinal(HANDLE hKey,
BYTE *pbEncryptedData,
ULONG *pulEncryptedDataLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_DecryptInit(HANDLE hKey,
BLOCKCIPHERPARAM DecryptParam)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_Decrypt(HANDLE hKey,
@@ -678,7 +580,7 @@ ULONG DEVAPI SKF_Decrypt(HANDLE hKey,
BYTE *pbData,
ULONG *pulDataLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_DecryptUpdate(HANDLE hKey,
@@ -687,14 +589,14 @@ ULONG DEVAPI SKF_DecryptUpdate(HANDLE hKey,
BYTE *pbData,
ULONG *pulDataLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_DecryptFinal(HANDLE hKey,
BYTE *pbDecryptedData,
ULONG *pulDecryptedDataLen)
{
return SAR_NOTSUPPORTYETERR;
return SAR_OK;
}
ULONG DEVAPI SKF_DigestInit(DEVHANDLE hDev,

View File

@@ -4,45 +4,81 @@
#include <assert.h>
#include "skf.h"
#define AUTH_RAND_LEN 16
#define AUTH_DATA_LEN 16
#define AUTH_KEY_LEN 16
int main(int argc, char **argv)
{
ULONG rv;
BYTE buf[2048];
ULONG len;
BOOL bPresent = TRUE;
CHAR devNameList[256];
LPSTR devName;
DEVHANDLE hDev;
DEVHANDLE hDev = NULL;
ULONG devState;
char *devStateStr;
DEVINFO devInfo;
BYTE authData[16];
BYTE authRand[AUTH_RAND_LEN];
BYTE authData[AUTH_DATA_LEN];
BYTE authKey[AUTH_KEY_LEN];
BLOCKCIPHERPARAM authParam;
HANDLE hAuthKey = NULL;
CHAR appNameList[256];
LPSTR appName;
HAPPLICATION hApp;
HAPPLICATION hApp = NULL;
CHAR containerNameList[256];
LPSTR containerName;
HCONTAINER hContainer;
HCONTAINER hContainer = NULL;
ULONG containerType;
char *containerTypeStr;
BYTE dgst[32];
ULONG dgstLen = sizeof(dgst);
ECCSIGNATUREBLOB sigblob;
len = sizeof(devNameList);
rv = SKF_EnumDev(bPresent, devNameList, &len);
assert(rv == SAR_OK);
if ((rv = SKF_EnumDev(bPresent, devNameList, &len)) != SAR_OK) {
goto end;
}
devName = devNameList;
printf(" Device Name : %s\n", devName);
printf("Device Name : %s\n", devName);
rv = SKF_GetDevState(devName, &devState);
assert(rv == SAR_OK);
printf(" Device State: %ld\n", devState);
rv = SKF_ConnectDev(devName, &hDev);
assert(rv == SAR_OK);
if ((rv = SKF_GetDevState(devName, &devState)) != SAR_OK) {
goto end;
}
rv = SKF_GetDevInfo(hDev, &devInfo);
assert(rv == SAR_OK);
switch (devState) {
case DEV_ABSENT_STATE:
devStateStr = "DEV_ABSENT_STATE";
break;
case DEV_PRESENT_STATE:
devStateStr = "DEV_PRESENT_STATE";
break;
case DEV_UNKNOW_STATE:
devStateStr = "DEV_UNKNOW_STATE";
break;
default:
devStateStr = "(undefined)";
}
printf("Device State: %s\n", devStateStr);
if ((rv = SKF_ConnectDev(devName, &hDev)) != SAR_OK) {
goto end;
}
if ((rv = SKF_GetDevInfo(hDev, &devInfo)) != SAR_OK) {
goto end;
}
printf("Device Info:\n");
printf(" Device Version : %d.%d\n", devInfo.Version.major, devInfo.Version.minor);
printf(" Manufacturer : %s\n", devInfo.Manufacturer);
printf(" Issuer : %s\n", devInfo.Issuer);
@@ -54,67 +90,119 @@ int main(int argc, char **argv)
printf(" AlgAsymCap : 0x%08x\n", devInfo.AlgAsymCap);
printf(" AlgHashCap : 0x%08x\n", devInfo.AlgHashCap);
printf(" AlgHashCap : 0x%08x\n", devInfo.DevAuthAlgId);
printf(" Total Space : %ld\n", devInfo.TotalSpace);
printf(" Free Space : %ld\n", devInfo.FreeSpace);
printf(" MaxECCBuffer : %ld\n", devInfo.MaxECCBufferSize);
printf(" MaxBuffer : %ld\n", devInfo.MaxBufferSize);
printf(" Total Space : %u\n", devInfo.TotalSpace);
printf(" Free Space : %u\n", devInfo.FreeSpace);
printf(" MaxECCBuffer : %u\n", devInfo.MaxECCBufferSize);
printf(" MaxBuffer : %u\n", devInfo.MaxBufferSize);
/* Device Authentication */
if ((rv = SKF_GenRandom(hDev, authRand, sizeof(authRand))) != SAR_OK) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
ULONG ulAuthAlgId = devInfo.DevAuthAlgId;
unsigned char pbAuthKey[16] = {0};
if ((rv = SKF_SetSymmKey(hDev, authKey, devInfo.DevAuthAlgId, &hAuthKey)) != SAR_OK) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
bzero(&authParam, sizeof(authParam));
if ((rv = SKF_EncryptInit(hAuthKey, authParam)) != SAR_OK) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if ((rv = SKF_Encrypt(hAuthKey, authRand, sizeof(authRand), authData, &len)) != SAR_OK) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if ((rv = SKF_DevAuth(hDev, authData, len)) != SAR_OK) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
printf("Device Authentication Passed.\n");
/* get the DevAuth challenge from GenRandom API
* encrypt challenge with DevAuthKey
*/
rv = SKF_GenRandom(hDev, authRandom, sizeof(authRandom));
rv = SKF_EncryptInit(hKey, param);
rv = SKF_Encrypt(hKey, authRandom, 16, authResponse, &ulAuthLen);
rv = SKF_DevAuth(hDev, authData, authDataLen);
assert(rv == SAR_OK);
/*
*/
/* Open Application */
len = sizeof(appNameList);
rv = SKF_EnumApplication(hDev, appNameList, &len);
assert(rv == SAR_OK);
if ((rv = SKF_EnumApplication(hDev, appNameList, &len)) != SAR_OK) {
goto end;
}
appName = appNameList;
printf("Application Name : %s\n", appName);
rv = SKF_OpenApplication(hDev, appName, &hApp);
assert(rv == SAR_OK);
if ((rv = SKF_OpenApplication(hDev, appName, &hApp)) != SAR_OK) {
goto end;
}
/* Open Containter */
len = sizeof(containerNameList);
rv = SKF_EnumContainer(hApp, containerNameList, &len);
assert(rv == SAR_OK);
if ((rv = SKF_EnumContainer(hApp, containerNameList, &len)) != SAR_OK) {
goto end;
}
containerName = containerNameList;
printf("Container Name: %s\n", containerName);
rv = SKF_OpenContainer(hApp, containerName, &hContainer);
assert(rv == SAR_OK);
if ((rv = SKF_OpenContainer(hApp, containerName, &hContainer)) != SAR_OK) {
goto end;
}
rv = SKF_GetContainerType(hContainer, &containerType);
assert(rv == SAR_OK);
if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) {
goto end;
}
printf("Container Type: %ld\n", containerType);
switch (containerType) {
case CONTAINER_TYPE_UNDEF:
containerTypeStr = "Undef";
break;
case CONTAINER_TYPE_RSA:
containerTypeStr = "RSA";
break;
case CONTAINER_TYPE_ECC:
containerTypeStr = "ECC";
break;
default:
containerTypeStr = "(error)";
}
printf("Container Type: %s\n", containerTypeStr);
rv = SKF_CloseContainer(hContainer);
assert(rv == SAR_OK);
/* Sign */
if ((rv = SKF_ECCSignData(hContainer, dgst, dgstLen, &sigblob)) != SAR_OK) {
goto end;
}
rv = SKF_CloseApplication(hApp);
assert(rv == SAR_OK);
/* Export Signing Public Key */
if ((rv = SKF_ExportPublicKey(hContainer, TRUE, buf, &len)) != SAR_OK) {
goto end;
}
printf("Success\n");
end:
//SKF_CloseContainer(hContainer);
//SKF_CloseApplication(hApp);
return 0;
}
int open_container(const char *dev, const char *app, const char *container,
const unsigned char *authkey, size_t authkeylen)
{
DEVHANDLE hDev = NULL;
DEVINFO devInfo;
HAPPLICATION hApp = NULL;
HCONTAINER hContainer = NULL;
return 0;
}

BIN
engines/skf/skftest.o Normal file

Binary file not shown.