From 91873b8da09711f4e1b3a6d3b691705c73a1432f Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Thu, 16 Feb 2017 12:02:25 +0800 Subject: [PATCH] update evp/ec --- crypto/ec/ec_err.c | 15 +++ crypto/ec/ec_lcl.h | 13 +++ crypto/ec/ec_pmeth.c | 235 ++++++++++++++++++++++++++++++++++++++++ crypto/evp/build.info | 3 +- crypto/evp/evp_ctxt.c | 69 ++++++++++++ crypto/evp/evp_err.c | 7 +- crypto/evp/evp_lib.c | 72 ++++++++++++ crypto/evp/p_enc.c | 107 +++++++++++++++--- crypto/skf/skf_err.c | 3 +- crypto/skf/skf_handle.c | 2 +- include/openssl/ec.h | 54 +++++++++ include/openssl/evp.h | 3 + include/openssl/gmskf.h | 1 + 13 files changed, 565 insertions(+), 19 deletions(-) create mode 100644 crypto/evp/evp_ctxt.c diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index e776d091..7291d860 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -221,7 +221,9 @@ static ERR_STRING_DATA EC_str_functs[] = { {ERR_FUNC(EC_F_PKEY_ECX_DERIVE), "pkey_ecx_derive"}, {ERR_FUNC(EC_F_PKEY_EC_CTRL), "pkey_ec_ctrl"}, {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "pkey_ec_ctrl_str"}, + {ERR_FUNC(EC_F_PKEY_EC_DECRYPT), "pkey_ec_decrypt"}, {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "pkey_ec_derive"}, + {ERR_FUNC(EC_F_PKEY_EC_ENCRYPT), "pkey_ec_encrypt"}, {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "pkey_ec_keygen"}, {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "pkey_ec_paramgen"}, {ERR_FUNC(EC_F_PKEY_EC_SIGN), "pkey_ec_sign"}, @@ -285,8 +287,14 @@ static ERR_STRING_DATA EC_str_reasons[] = { {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, {ERR_REASON(EC_R_ECDH_FAILED), "ecdh failed"}, {ERR_REASON(EC_R_ECDH_FAILURE), "ecdh failure"}, + {ERR_REASON(EC_R_ECIES_DECRYPT_FAILED), "ecies decrypt failed"}, {ERR_REASON(EC_R_ECIES_DECRYPT_INIT_FAILURE), "ecies decrypt init failure"}, + {ERR_REASON(EC_R_ECIES_DECRYPT_WITH_RECOMMENDED_FAILED), + "ecies decrypt with recommended failed"}, + {ERR_REASON(EC_R_ECIES_ENCRYPT_FAILED), "ecies encrypt failed"}, + {ERR_REASON(EC_R_ECIES_ENCRYPT_WITH_RECOMMENDED_FAILED), + "ecies encrypt with recommended failed"}, {ERR_REASON(EC_R_ECIES_VERIFY_MAC_FAILURE), "ecies verify mac failure"}, {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), "ec group new by name failure"}, @@ -320,6 +328,7 @@ static ERR_STRING_DATA EC_str_reasons[] = { {ERR_REASON(EC_R_INVALID_ECIES_PARAMETERS), "invalid ecies parameters"}, {ERR_REASON(EC_R_INVALID_EC_KEY), "invalid ec key"}, {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"}, + {ERR_REASON(EC_R_INVALID_ENC_TYPE), "invalid enc type"}, {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"}, {ERR_REASON(EC_R_INVALID_FORM), "invalid form"}, {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"}, @@ -366,6 +375,12 @@ static ERR_STRING_DATA EC_str_reasons[] = { "random number generation failed"}, {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"}, {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, + {ERR_REASON(EC_R_SM2_DECRYPT_FAILED), "sm2 decrypt failed"}, + {ERR_REASON(EC_R_SM2_DECRYPT_WITH_RECOMMENDED_FAILED), + "sm2 decrypt with recommended failed"}, + {ERR_REASON(EC_R_SM2_ENCRYPT_FAILED), "sm2 encrypt failed"}, + {ERR_REASON(EC_R_SM2_ENCRYPT_WITH_RECOMMENDED_FAILED), + "sm2 encrypt with recommended failed"}, {ERR_REASON(EC_R_SM2_KAP_NOT_INITED), "sm2 kap not inited"}, {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index ded35a72..56f4447e 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -26,6 +26,9 @@ #include #include #include +#ifndef OPENSSL_NO_SM2 +#include +#endif #include "e_os.h" @@ -579,6 +582,16 @@ struct ec_key_method_st { const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); int (*verify_sig)(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); +#ifndef OPENSSL_NO_SM2 + int (*encrypt)(int type, const unsigned char *in, size_t inlen, + unsigned char *out, size_t *outlen, EC_KEY *ec_key); + ECIES_CIPHERTEXT_VALUE *(*do_encrypt)(int type, const unsigned char *in, + size_t inlen, EC_KEY *ec_key); + int (*decrypt)(int type, const unsigned char *in, size_t inlen, + unsigned char *out, size_t *outlen, EC_KEY *ec_key); + int (*do_decrypt)(int type, const ECIES_CIPHERTEXT_VALUE *in, + unsigned char *out, size_t *outlen, EC_KEY *ec_key); +#endif }; #define EC_KEY_METHOD_DYNAMIC 1 diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c index 68ff2bbc..472630be 100644 --- a/crypto/ec/ec_pmeth.c +++ b/crypto/ec/ec_pmeth.c @@ -15,6 +15,9 @@ #include "ec_lcl.h" #include #include "internal/evp_int.h" +#ifndef OPENSSL_NO_SM2 +# include +#endif /* EC pkey context structure */ @@ -36,6 +39,16 @@ typedef struct { size_t kdf_ukmlen; /* KDF output length */ size_t kdf_outlen; +#ifndef OPENSSL_NO_SM2 + int sign_type; + int enc_type; + int dh_type; + union { + void *ptr; + ECIES_PARAMS *ecies; + SM2_ENC_PARAMS *sm2; + } enc_param; +#endif } EC_PKEY_CTX; static int pkey_ec_init(EVP_PKEY_CTX *ctx) @@ -48,6 +61,12 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx) dctx->cofactor_mode = -1; dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE; +#ifndef OPENSSL_NO_SM2 + dctx->sign_type = NID_secg_scheme; + dctx->enc_type = NID_secg_scheme; + dctx->dh_type = NID_secg_scheme; + dctx->enc_param.ptr = NULL; +#endif ctx->data = dctx; return 1; } @@ -81,6 +100,26 @@ static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) } else dctx->kdf_ukm = NULL; dctx->kdf_ukmlen = sctx->kdf_ukmlen; +#ifndef OPENSSL_NO_SM2 + dctx->sign_type = sctx->sign_type; + dctx->enc_type = sctx->enc_type; + dctx->dh_type = sctx->dh_type; + if (sctx->enc_param.ptr) { + if (sctx->enc_type == NID_secg_scheme) { + dctx->enc_param.ecies = ECIES_PARAMS_dup(sctx->enc_param.ecies); + if (!dctx->enc_param.ecies) { + return 0; + } + } else if (sctx->enc_type == NID_sm_scheme) { + dctx->enc_param.sm2 = SM2_ENC_PARAMS_dup(sctx->enc_param.sm2); + if (!dctx->enc_param.sm2) { + return 0; + } + } else { + return 0; + } + } +#endif return 1; } @@ -91,6 +130,18 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) EC_GROUP_free(dctx->gen_group); EC_KEY_free(dctx->co_key); OPENSSL_free(dctx->kdf_ukm); +#ifndef OPENSSL_NO_SM2 + if (dctx->enc_param.ptr) { + if (dctx->enc_type == NID_secg_scheme) { + ECIES_PARAMS_free(dctx->enc_param.ecies); + } else if (dctx->enc_type == NID_sm_scheme) { + SM2_ENC_PARAMS_free(dctx->enc_param.sm2); + } else { + /* this should not happen */ + OPENSSL_free(dctx->enc_param.ptr); + } + } +#endif OPENSSL_free(dctx); } } @@ -116,6 +167,12 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, else type = NID_sha1; +#ifndef OPENSSL_NO_SM2 + if (dctx->sign_type == NID_sm_scheme) + ret = SM2_sign(NID_undef, tbs, tbslen, sig, &sltmp, ec); + else +#endif + ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); if (ret <= 0) @@ -137,11 +194,105 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx, else type = NID_sha1; +#ifndef OPENSSL_NO_SM2 + if (dctx->sign_type == NID_sm_scheme) + ret = SM2_verify(NID_undef, tbs, tbslen, sig, siglen, ec); + else +#endif + ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); return ret; } +#ifndef OPENSSL_NO_SM2 +static int pkey_ec_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec_key = ctx->pkey->pkey.ec; + + switch (dctx->enc_type) { + case NID_sm_scheme: + if (dctx->enc_param.sm2) { + if (!SM2_encrypt(dctx->enc_param.sm2, out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_SM2_ENCRYPT_FAILED); + return 0; + } + } else { + if (!SM2_encrypt_with_recommended(out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_SM2_ENCRYPT_WITH_RECOMMENDED_FAILED); + return 0; + } + } + break; + + case NID_secg_scheme: + if (dctx->enc_param.ecies) { + if (!ECIES_encrypt(dctx->enc_param.ecies, out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_ECIES_ENCRYPT_FAILED); + return 0; + } + } else { + if (!ECIES_encrypt_with_recommended(out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_ECIES_ENCRYPT_WITH_RECOMMENDED_FAILED); + return 0; + } + } + break; + + default: + ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_INVALID_ENC_TYPE); + return 0; + } + + return 1; +} + +static int pkey_ec_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec_key = ctx->pkey->pkey.ec; + + switch (dctx->enc_type) { + case NID_sm_scheme: + if (dctx->enc_param.sm2) { + if (!SM2_decrypt(dctx->enc_param.sm2, out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_SM2_DECRYPT_FAILED); + return 0; + } + } else { + if (!SM2_decrypt_with_recommended(out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_SM2_DECRYPT_WITH_RECOMMENDED_FAILED); + return 0; + } + } + break; + + case NID_secg_scheme: + if (dctx->enc_param.ecies) { + if (!ECIES_decrypt(dctx->enc_param.ecies, out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_ECIES_DECRYPT_FAILED); + return 0; + } + } else { + if (!ECIES_decrypt_with_recommended(out, outlen, in, inlen, ec_key)) { + ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_ECIES_DECRYPT_WITH_RECOMMENDED_FAILED); + return 0; + } + } + break; + + default: + ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_INVALID_ENC_TYPE); + return 0; + } + + return 1; +} +#endif + #ifndef OPENSSL_NO_EC static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) @@ -173,6 +324,12 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, outlen = *keylen; +#ifndef OPENSSL_NO_SM2 + if (dctx->dh_type == NID_sm_scheme) + ret = SM2_compute_key(key, outlen, pubkey, eckey, 0); + else +#endif + ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); if (ret <= 0) return 0; @@ -281,6 +438,44 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) dctx->kdf_type = p1; return 1; +#ifndef OPENSSL_NO_SM2 + case EVP_PKEY_CTRL_EC_SIGN_TYPE: + if (p1 == -2) + return dctx->sign_type; + if (p1 != NID_secg_scheme && p1 != NID_sm_scheme) + return -2; + dctx->sign_type = p1; + return 1; + + case EVP_PKEY_CTRL_GET_EC_SIGN_TYPE: + *(int *)p2 = dctx->sign_type; + return 1; + + case EVP_PKEY_CTRL_EC_ENC_TYPE: + if (p1 == -2) + return dctx->enc_type; + if (p1 != NID_secg_scheme && p1 != NID_sm_scheme) + return -2; + dctx->enc_type = p1; + return 1; + + case EVP_PKEY_CTRL_GET_EC_ENC_TYPE: + *(int *)p2 = dctx->enc_type; + return 1; + + case EVP_PKEY_CTRL_EC_DH_TYPE: + if (p1 == -2) + return dctx->dh_type; + if (p1 != NID_secg_scheme && p1 != NID_sm_scheme) + return -2; + dctx->dh_type = p1; + return 1; + + case EVP_PKEY_CTRL_GET_EC_DH_TYPE: + *(int *)p2 = dctx->dh_type; + return 1; +#endif + case EVP_PKEY_CTRL_EC_KDF_MD: dctx->kdf_md = p2; return 1; @@ -314,6 +509,9 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_MD: if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && +#ifndef OPENSSL_NO_SM3 + EVP_MD_type((const EVP_MD *)p2) != NID_sm3 && +#endif 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 && @@ -357,6 +555,35 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, return 0; } return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); +#ifndef OPENSSL_NO_SM2 + } else if (!strcmp(type, "ec_sign_algor")) { + int sign_type; + if (!strcmp(value, "ecdsa")) + sign_type = NID_secg_scheme; + else if (!strcmp(value, "sm2")) + sign_type = NID_sm_scheme; + else + return -2; + return EVP_PKEY_CTX_set_ec_sign_type(ctx, sign_type); + } else if (!strcmp(type, "ec_encrypt_algor")) { + int enc_type; + if (!strcmp(value, "ecies")) + enc_type = NID_secg_scheme; + else if (!strcmp(value, "sm2")) + enc_type = NID_sm_scheme; + else + return -2; + return EVP_PKEY_CTX_set_ec_enc_type(ctx, enc_type); + } else if (!strcmp(type, "ec_derive_algor")) { + int dh_type; + if (!strcmp(value, "ecdh")) + dh_type = NID_secg_scheme; + else if (!strcmp(value, "sm2")) + dh_type = NID_sm_scheme; + else + return -2; + return EVP_PKEY_CTX_set_ec_dh_type(ctx, dh_type); +#endif } else if (strcmp(type, "ec_param_enc") == 0) { int param_enc; if (strcmp(value, "explicit") == 0) @@ -448,9 +675,17 @@ const EVP_PKEY_METHOD ec_pkey_meth = { 0, 0, 0, 0, +#ifndef OPENSSL_NO_SM2 + 0, + pkey_ec_encrypt, + + 0, + pkey_ec_decrypt, +#else 0, 0, 0, 0, +#endif 0, #ifndef OPENSSL_NO_EC diff --git a/crypto/evp/build.info b/crypto/evp/build.info index 67d10492..b9bc6fd0 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -14,7 +14,8 @@ SOURCE[../../libcrypto]=\ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c cmeth_lib.c \ m_sm3.c \ - e_sms4.c e_sms4_ccm.c e_sms4_gcm.c e_sms4_ocb.c e_sms4_wrap.c e_sms4_xts.c + e_sms4.c e_sms4_ccm.c e_sms4_gcm.c e_sms4_ocb.c e_sms4_wrap.c e_sms4_xts.c \ + evp_ctxt.c INCLUDE[e_aes.o]=.. ../modes INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes diff --git a/crypto/evp/evp_ctxt.c b/crypto/evp/evp_ctxt.c new file mode 100644 index 00000000..8177ee7f --- /dev/null +++ b/crypto/evp/evp_ctxt.c @@ -0,0 +1,69 @@ +/* ==================================================================== + * 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. + * ==================================================================== + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/evp_int.h" + +int EVP_PKEY_CTX_ciphertext_size(EVP_PKEY_CTX *ctx, + size_t inlen, size_t *outlen) +{ + if (inlen > 4096) { + EVPerr(EVP_F_EVP_PKEY_CTX_CIPHERTEXT_SIZE, + EVP_R_INVALID_INPUT_LENGTH); + return 0; + } + //FIXME: this function should call some func_ptr from ctx->pkey + *outlen = inlen + 4096; + return 1; +} + diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index e32a1c01..639ad522 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -50,6 +50,8 @@ static ERR_STRING_DATA EVP_str_functs[] = { {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"}, {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8), "EVP_PKEY2PKCS8"}, {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"}, + {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CIPHERTEXT_SIZE), + "EVP_PKEY_CTX_ciphertext_size"}, {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"}, {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"}, {ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"}, @@ -123,6 +125,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"}, {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"}, {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"}, + {ERR_REASON(EVP_R_INVALID_INPUT_LENGTH), "invalid input length"}, {ERR_REASON(EVP_R_INVALID_KEY), "invalid key"}, {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"}, @@ -144,6 +147,8 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"}, {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, + {ERR_REASON(EVP_R_RSA_PUBLIC_ENCRYPT_FAILED), + "rsa public encrypt failed"}, {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"}, {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"}, {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"}, diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 0c76db5a..d96e406c 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -1,3 +1,51 @@ +/* ==================================================================== + * 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 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * @@ -152,6 +200,30 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx) return NID_des_cfb64; +#ifndef OPENSSL_NO_SMS4 + case NID_sms4_cfb128: + case NID_sms4_cfb8: + case NID_sms4_cfb1: + + return NID_sms4_cfb128; +#endif + +#ifndef OPENSSL_NO_SM1: + case NID_sm1_cfb128: + case NID_sm1_cfb8: + case NID_sm1_cfb1: + + return NID_sm1_cfb128; +#endif + +#ifndef OPENSSL_NO_SSF33 + case NID_ssf33_cfb128: + case NID_ssf33_cfb8: + case NID_ssf33_cfb1: + + return NID_ssf33_cfb128; +#endif + default: /* Check it has an OID and it is valid */ otmp = OBJ_nid2obj(nid); diff --git a/crypto/evp/p_enc.c b/crypto/evp/p_enc.c index 3277fbb0..4559af72 100644 --- a/crypto/evp/p_enc.c +++ b/crypto/evp/p_enc.c @@ -1,3 +1,51 @@ + /* ==================================================================== + * 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. + * ==================================================================== + */ /* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * @@ -14,22 +62,51 @@ #include #include -int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, - int key_len, EVP_PKEY *pubk) +int EVP_PKEY_encrypt_old(unsigned char *out, const unsigned char *in, + int inlen, EVP_PKEY *pkey) { - int ret = 0; + int ret = 0; + EVP_PKEY_CTX *ctx = NULL; + size_t size; -#ifndef OPENSSL_NO_RSA - if (EVP_PKEY_id(pubk) != EVP_PKEY_RSA) { +# ifndef OPENSSL_NO_RSA + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + if ((ret = RSA_public_encrypt(inlen, in, out, + EVP_PKEY_get0_RSA(pkey), RSA_PKCS1_PADDING)) < 0) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, + EVP_R_RSA_PUBLIC_ENCRYPT_FAILED); + return 0; + } + } +# endif + +# ifndef OPENSSL_NO_SM2 + if (!(ctx = EVP_PKEY_CTX_new(pkey, NULL))) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!EVP_PKEY_encrypt_init(ctx)) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, ERR_R_EVP_LIB); + return 0; + } + + if (!EVP_PKEY_CTX_set_ec_enc_type(ctx, NID_sm_scheme)) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, ERR_R_EVP_LIB); + goto end; + } + + size = inlen + EVP_PKEY_size(pkey); + if (!EVP_PKEY_encrypt(ctx, out, &size, in, inlen)) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, ERR_R_EVP_LIB); + goto end; + } + + ret = (int)size; #endif - EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); -#ifndef OPENSSL_NO_RSA - goto err; - } - ret = - RSA_public_encrypt(key_len, key, ek, EVP_PKEY_get0_RSA(pubk), - RSA_PKCS1_PADDING); - err: -#endif - return (ret); + +end: + EVP_PKEY_CTX_free(ctx); + return ret; } + diff --git a/crypto/skf/skf_err.c b/crypto/skf/skf_err.c index 3a62ebe1..3efed92e 100644 --- a/crypto/skf/skf_err.c +++ b/crypto/skf/skf_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -46,6 +46,7 @@ static ERR_STRING_DATA SKF_str_functs[] = { {ERR_FUNC(SKF_F_SKF_HANDLE_GET_CBCMAC_CTX), "SKF_HANDLE_get_cbcmac_ctx"}, {ERR_FUNC(SKF_F_SKF_HANDLE_GET_CIPHER), "SKF_HANDLE_get_cipher"}, {ERR_FUNC(SKF_F_SKF_HANDLE_GET_CIPHER_CTX), "SKF_HANDLE_get_cipher_ctx"}, + {ERR_FUNC(SKF_F_SKF_HANDLE_GET_CMAC_CTX), "SKF_HANDLE_get_cmac_ctx"}, {ERR_FUNC(SKF_F_SKF_HANDLE_GET_KEY), "SKF_HANDLE_get_key"}, {ERR_FUNC(SKF_F_SKF_HANDLE_GET_MD_CTX), "SKF_HANDLE_get_md_ctx"}, {ERR_FUNC(SKF_F_SKF_MAC), "SKF_Mac"}, diff --git a/crypto/skf/skf_handle.c b/crypto/skf/skf_handle.c index 87e933f3..fef6439a 100644 --- a/crypto/skf/skf_handle.c +++ b/crypto/skf/skf_handle.c @@ -144,7 +144,7 @@ EVP_MD_CTX *SKF_HANDLE_get_md_ctx(HANDLE hHash) return ret; } -CMAC_CTX *SKF_HANDLE_get_cbcmac_ctx(HANDLE hMac) +CMAC_CTX *SKF_HANDLE_get_cmac_ctx(HANDLE hMac) { CMAC_CTX *ret; SKF_HANDLE *handle; diff --git a/include/openssl/ec.h b/include/openssl/ec.h index a1789f89..0df4137d 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -1342,6 +1342,40 @@ void EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth, EVP_PKEY_OP_DERIVE, \ EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p) +# ifndef OPENSSL_NO_SM2 +# define EVP_PKEY_CTX_set_ec_sign_type(ctx, type) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_SIGN|EVP_PKEY_OP_SIGNCTX| \ + EVP_PKEY_OP_VERIFY|EVP_PKEY_OP_VERIFYCTX, \ + EVP_PKEY_CTRL_EC_SIGN_TYPE, type, NULL) + +# define EVP_PKEY_CTX_get_ec_sign_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_SIGN|EVP_PKEY_OP_SIGNCTX| \ + EVP_PKEY_OP_VERIFY|EVP_PKEY_OP_VERIFYCTX, \ + EVP_PKEY_CTRL_EC_SIGN_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set_ec_enc_type(ctx, type) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_ENCRYPT|EVP_PKEY_OP_DECRYPT, \ + EVP_PKEY_CTRL_EC_ENC_TYPE, type, NULL) + +# define EVP_PKEY_CTX_get_ec_enc_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_ENCRYPT|EVP_PKEY_OP_DECRYPT, \ + EVP_PKEY_CTRL_EC_ENC_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set_ec_dh_type(ctx, type) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_DH_TYPE, type, NULL) + +# define EVP_PKEY_CTX_get_ec_dh_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_DH_TYPE, -2, NULL); +# endif + # define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) # define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) # define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) @@ -1356,6 +1390,15 @@ void EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth, # define EVP_PKEY_ECDH_KDF_NONE 1 # define EVP_PKEY_ECDH_KDF_X9_62 2 +# ifndef OPENSSL_NO_SM2 +# define EVP_PKEY_CTRL_EC_SIGN_TYPE (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_EC_SIGN_TYPE (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_EC_ENC_TYPE (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_GET_EC_ENC_TYPE (EVP_PKEY_ALG_CTRL + 14) +# define EVP_PKEY_CTRL_EC_DH_TYPE (EVP_PKEY_ALG_CTRL + 15) +# define EVP_PKEY_CTRL_GET_EC_DH_TYPE (EVP_PKEY_ALG_CTRL + 16) +# endif + /* BEGIN ERROR CODES */ /* * The following lines are auto generated by the script mkerr.pl. Any changes @@ -1528,7 +1571,9 @@ int ERR_load_EC_strings(void); # define EC_F_PKEY_ECX_DERIVE 269 # define EC_F_PKEY_EC_CTRL 197 # define EC_F_PKEY_EC_CTRL_STR 198 +# define EC_F_PKEY_EC_DECRYPT 318 # define EC_F_PKEY_EC_DERIVE 217 +# define EC_F_PKEY_EC_ENCRYPT 319 # define EC_F_PKEY_EC_KEYGEN 199 # define EC_F_PKEY_EC_PARAMGEN 219 # define EC_F_PKEY_EC_SIGN 218 @@ -1579,7 +1624,11 @@ int ERR_load_EC_strings(void); # define EC_R_DISCRIMINANT_IS_ZERO 118 # define EC_R_ECDH_FAILED 164 # define EC_R_ECDH_FAILURE 165 +# define EC_R_ECIES_DECRYPT_FAILED 196 # define EC_R_ECIES_DECRYPT_INIT_FAILURE 166 +# define EC_R_ECIES_DECRYPT_WITH_RECOMMENDED_FAILED 197 +# define EC_R_ECIES_ENCRYPT_FAILED 198 +# define EC_R_ECIES_ENCRYPT_WITH_RECOMMENDED_FAILED 199 # define EC_R_ECIES_VERIFY_MAC_FAILURE 167 # define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 # define EC_R_ENCRYPT_FAILED 168 @@ -1607,6 +1656,7 @@ int ERR_load_EC_strings(void); # define EC_R_INVALID_ECIES_PARAMETERS 172 # define EC_R_INVALID_EC_KEY 180 # define EC_R_INVALID_ENCODING 102 +# define EC_R_INVALID_ENC_TYPE 200 # define EC_R_INVALID_FIELD 103 # define EC_R_INVALID_FORM 104 # define EC_R_INVALID_GROUP_ORDER 122 @@ -1649,6 +1699,10 @@ int ERR_load_EC_strings(void); # define EC_R_RANDOM_NUMBER_GENERATION_FAILED 158 # define EC_R_SHARED_INFO_ERROR 150 # define EC_R_SLOT_FULL 108 +# define EC_R_SM2_DECRYPT_FAILED 201 +# define EC_R_SM2_DECRYPT_WITH_RECOMMENDED_FAILED 202 +# define EC_R_SM2_ENCRYPT_FAILED 203 +# define EC_R_SM2_ENCRYPT_WITH_RECOMMENDED_FAILED 204 # define EC_R_SM2_KAP_NOT_INITED 191 # define EC_R_UNDEFINED_GENERATOR 113 # define EC_R_UNDEFINED_ORDER 128 diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 21ccee9a..3d7e4f53 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1555,6 +1555,7 @@ int ERR_load_EVP_strings(void); # define EVP_F_EVP_PKCS82PKEY 111 # define EVP_F_EVP_PKEY2PKCS8 113 # define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +# define EVP_F_EVP_PKEY_CTX_CIPHERTEXT_SIZE 168 # define EVP_F_EVP_PKEY_CTX_CTRL 137 # define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 # define EVP_F_EVP_PKEY_CTX_DUP 156 @@ -1621,6 +1622,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_INPUT_NOT_INITIALIZED 111 # define EVP_R_INVALID_DIGEST 152 # define EVP_R_INVALID_FIPS_MODE 168 +# define EVP_R_INVALID_INPUT_LENGTH 164 # define EVP_R_INVALID_KEY 163 # define EVP_R_INVALID_KEY_LENGTH 130 # define EVP_R_INVALID_OPERATION 148 @@ -1640,6 +1642,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 # define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 # define EVP_R_PUBLIC_KEY_NOT_RSA 106 +# define EVP_R_RSA_PUBLIC_ENCRYPT_FAILED 175 # define EVP_R_UNKNOWN_CIPHER 160 # define EVP_R_UNKNOWN_DIGEST 161 # define EVP_R_UNKNOWN_OPTION 169 diff --git a/include/openssl/gmskf.h b/include/openssl/gmskf.h index cfadd2bb..18425763 100644 --- a/include/openssl/gmskf.h +++ b/include/openssl/gmskf.h @@ -127,6 +127,7 @@ int ERR_load_SKF_strings(void); # define SKF_F_SKF_HANDLE_GET_CBCMAC_CTX 124 # define SKF_F_SKF_HANDLE_GET_CIPHER 125 # define SKF_F_SKF_HANDLE_GET_CIPHER_CTX 126 +# define SKF_F_SKF_HANDLE_GET_CMAC_CTX 134 # define SKF_F_SKF_HANDLE_GET_KEY 127 # define SKF_F_SKF_HANDLE_GET_MD_CTX 128 # define SKF_F_SKF_MAC 129