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

@@ -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