diff --git a/Feature-shim-support-SMx-verify.patch b/Feature-shim-support-SMx-verify.patch deleted file mode 100644 index 3ba9d7b1e46a22695f23555c2affe94ef4e4168b..0000000000000000000000000000000000000000 --- a/Feature-shim-support-SMx-verify.patch +++ /dev/null @@ -1,14560 +0,0 @@ -From 5589c21862f49f682d55c321389cd6f631972564 Mon Sep 17 00:00:00 2001 -From: Huaxin Lu -Date: Tue, 18 Oct 2022 12:50:09 +0800 -Subject: [PATCH] shim support sm verify - -Co-authored-by: Yusong Gao -Signed-off-by: Huaxin Lu ---- - Cryptlib/Hash/CryptSm3.c | 231 ++++ - Cryptlib/Include/openssl/crypto.h | 10 + - Cryptlib/Include/openssl/ec.h | 20 + - Cryptlib/Include/openssl/ecdsa.h | 7 + - Cryptlib/Include/openssl/err.h | 6 + - Cryptlib/Include/openssl/evp.h | 25 + - Cryptlib/Include/openssl/obj_mac.h | 33 + - Cryptlib/Include/openssl/opensslconf.h | 8 +- - Cryptlib/Include/openssl/sm2.h | 79 ++ - Cryptlib/Include/openssl/sm2err.h | 65 + - Cryptlib/Include/openssl/sm3.h | 39 + - Cryptlib/Include/openssl/x509.h | 7 + - Cryptlib/Library/BaseCryptLib.h | 111 ++ - Cryptlib/Makefile | 6 + - Cryptlib/OpenSSL/Makefile | 38 +- - Cryptlib/OpenSSL/crypto/asn1/a_sign.c | 11 +- - Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c | 8 +- - Cryptlib/OpenSSL/crypto/asn1/x_req.c | 13 + - Cryptlib/OpenSSL/crypto/asn1/x_x509.c | 6 + - Cryptlib/OpenSSL/crypto/bn/bn_lib.c | 3 - - Cryptlib/OpenSSL/crypto/ec/ec_ameth.c | 646 +++++++++ - Cryptlib/OpenSSL/crypto/ec/ec_asn1.c | 1278 ++++++++++++++++++ - Cryptlib/OpenSSL/crypto/ec/ec_check.c | 120 ++ - Cryptlib/OpenSSL/crypto/ec/ec_curve.c | 343 +++++ - Cryptlib/OpenSSL/crypto/ec/ec_cvt.c | 154 +++ - Cryptlib/OpenSSL/crypto/ec/ec_err.c | 332 +++++ - Cryptlib/OpenSSL/crypto/ec/ec_key.c | 564 ++++++++ - Cryptlib/OpenSSL/crypto/ec/ec_lcl.h | 470 +++++++ - Cryptlib/OpenSSL/crypto/ec/ec_lib.c | 1077 +++++++++++++++ - Cryptlib/OpenSSL/crypto/ec/ec_mult.c | 913 +++++++++++++ - Cryptlib/OpenSSL/crypto/ec/ec_oct.c | 163 +++ - Cryptlib/OpenSSL/crypto/ec/ec_pmeth.c | 410 ++++++ - Cryptlib/OpenSSL/crypto/ec/ec_print.c | 179 +++ - Cryptlib/OpenSSL/crypto/ec/eck_prn.c | 330 +++++ - Cryptlib/OpenSSL/crypto/ec/ecp_mont.c | 308 +++++ - Cryptlib/OpenSSL/crypto/ec/ecp_nist.c | 220 +++ - Cryptlib/OpenSSL/crypto/ec/ecp_oct.c | 428 ++++++ - Cryptlib/OpenSSL/crypto/ec/ecp_smpl.c | 1418 ++++++++++++++++++++ - Cryptlib/OpenSSL/crypto/ecdsa/ecs_asn1.c | 75 ++ - Cryptlib/OpenSSL/crypto/ecdsa/ecs_err.c | 107 ++ - Cryptlib/OpenSSL/crypto/ecdsa/ecs_lib.c | 354 +++++ - Cryptlib/OpenSSL/crypto/ecdsa/ecs_locl.h | 120 ++ - Cryptlib/OpenSSL/crypto/ecdsa/ecs_ossl.c | 464 +++++++ - Cryptlib/OpenSSL/crypto/ecdsa/ecs_sign.c | 106 ++ - Cryptlib/OpenSSL/crypto/ecdsa/ecs_vrf.c | 112 ++ - Cryptlib/OpenSSL/crypto/err/err.c | 1 + - Cryptlib/OpenSSL/crypto/evp/c_alld.c | 3 + - Cryptlib/OpenSSL/crypto/evp/digest.c | 62 +- - Cryptlib/OpenSSL/crypto/evp/evp_lib.c | 5 + - Cryptlib/OpenSSL/crypto/evp/evp_locl.h | 10 + - Cryptlib/OpenSSL/crypto/evp/m_sigver.c | 17 + - Cryptlib/OpenSSL/crypto/evp/p_lib.c | 44 + - Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c | 16 +- - Cryptlib/OpenSSL/crypto/mem.c | 18 + - Cryptlib/OpenSSL/crypto/o_str.c | 87 ++ - Cryptlib/OpenSSL/crypto/objects/obj_dat.h | 46 +- - Cryptlib/OpenSSL/crypto/objects/obj_xref.h | 2 + - Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c | 34 +- - Cryptlib/OpenSSL/crypto/sm2/sm2_err.c | 71 + - Cryptlib/OpenSSL/crypto/sm2/sm2_pmeth.c | 292 ++++ - Cryptlib/OpenSSL/crypto/sm2/sm2_sign.c | 325 +++++ - Cryptlib/OpenSSL/crypto/sm3/m_sm3.c | 52 + - Cryptlib/OpenSSL/crypto/sm3/sm3.c | 196 +++ - Cryptlib/OpenSSL/crypto/sm3/sm3_local.h | 79 ++ - Cryptlib/OpenSSL/crypto/x509/x_all.c | 142 ++ - Cryptlib/Pk/CryptPkcs7Verify.c | 5 + - Makefile | 2 +- - MokManager.c | 8 + - include/pe.h | 7 + - include/peimage.h | 3 + - pe.c | 100 ++ - shim.c | 73 +- - shim.h | 20 + - 73 files changed, 13094 insertions(+), 43 deletions(-) - create mode 100644 Cryptlib/Hash/CryptSm3.c - create mode 100644 Cryptlib/Include/openssl/sm2.h - create mode 100644 Cryptlib/Include/openssl/sm2err.h - create mode 100644 Cryptlib/Include/openssl/sm3.h - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_ameth.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_asn1.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_check.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_curve.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_cvt.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_err.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_key.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_lcl.h - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_lib.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_mult.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_oct.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_pmeth.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ec_print.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/eck_prn.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ecp_mont.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ecp_nist.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ecp_oct.c - create mode 100644 Cryptlib/OpenSSL/crypto/ec/ecp_smpl.c - create mode 100644 Cryptlib/OpenSSL/crypto/ecdsa/ecs_asn1.c - create mode 100644 Cryptlib/OpenSSL/crypto/ecdsa/ecs_err.c - create mode 100644 Cryptlib/OpenSSL/crypto/ecdsa/ecs_lib.c - create mode 100644 Cryptlib/OpenSSL/crypto/ecdsa/ecs_locl.h - create mode 100644 Cryptlib/OpenSSL/crypto/ecdsa/ecs_ossl.c - create mode 100644 Cryptlib/OpenSSL/crypto/ecdsa/ecs_sign.c - create mode 100644 Cryptlib/OpenSSL/crypto/ecdsa/ecs_vrf.c - create mode 100644 Cryptlib/OpenSSL/crypto/sm2/sm2_err.c - create mode 100644 Cryptlib/OpenSSL/crypto/sm2/sm2_pmeth.c - create mode 100644 Cryptlib/OpenSSL/crypto/sm2/sm2_sign.c - create mode 100644 Cryptlib/OpenSSL/crypto/sm3/m_sm3.c - create mode 100644 Cryptlib/OpenSSL/crypto/sm3/sm3.c - create mode 100644 Cryptlib/OpenSSL/crypto/sm3/sm3_local.h - -diff --git a/Cryptlib/Hash/CryptSm3.c b/Cryptlib/Hash/CryptSm3.c -new file mode 100644 -index 0000000..c522365 ---- /dev/null -+++ b/Cryptlib/Hash/CryptSm3.c -@@ -0,0 +1,231 @@ -+/** @file -+ SM3 Digest Wrapper Implementation over OpenSSL. -+ -+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
-+This program and the accompanying materials -+are licensed and made available under the terms and conditions of the BSD License -+which accompanies this distribution. The full text of the license may be found at -+http://opensource.org/licenses/bsd-license.php -+ -+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -+ -+**/ -+ -+#include "InternalCryptLib.h" -+#include -+ -+/** -+ Retrieves the size, in bytes, of the context buffer required for SM3 hash operations. -+ -+ @return The size, in bytes, of the context buffer required for SM3 hash operations. -+ -+**/ -+UINTN -+EFIAPI -+Sm3GetContextSize ( -+ VOID -+ ) -+{ -+ // -+ // Retrieves OpenSSL SM3 Context Size -+ // -+ return (UINTN) (sizeof (SM3_CTX)); -+} -+ -+/** -+ Initializes user-supplied memory pointed by Sm3Context as SM3 hash context for -+ subsequent use. -+ -+ If Sm3Context is NULL, then return FALSE. -+ -+ @param[out] Sm3Context Pointer to SM3 context being initialized. -+ -+ @retval TRUE SM3 context initialization succeeded. -+ @retval FALSE SM3 context initialization failed. -+ -+**/ -+BOOLEAN -+EFIAPI -+Sm3Init ( -+ OUT VOID *Sm3Context -+ ) -+{ -+ // -+ // Check input parameters. -+ // -+ if (Sm3Context == NULL) { -+ return FALSE; -+ } -+ -+ // -+ // OpenSSL SM3 Context Initialization -+ // -+ return (BOOLEAN) (sm3_init ((SM3_CTX *) Sm3Context)); -+} -+ -+/** -+ Makes a copy of an existing SM3 context. -+ -+ If Sm3Context is NULL, then return FALSE. -+ If NewSm3Context is NULL, then return FALSE. -+ -+ @param[in] Sm3Context Pointer to SM3 context being copied. -+ @param[out] NewSm3Context Pointer to new SM3 context. -+ -+ @retval TRUE SM3 context copy succeeded. -+ @retval FALSE SM3 context copy failed. -+ -+**/ -+BOOLEAN -+EFIAPI -+Sm3Duplicate ( -+ IN CONST VOID *Sm3Context, -+ OUT VOID *NewSm3Context -+ ) -+{ -+ // -+ // Check input parameters. -+ // -+ if (Sm3Context == NULL || NewSm3Context == NULL) { -+ return FALSE; -+ } -+ -+ CopyMem (NewSm3Context, (void *)Sm3Context, sizeof (SM3_CTX)); -+ -+ return TRUE; -+} -+ -+/** -+ Digests the input data and updates SM3 context. -+ -+ This function performs SM3 digest on a data buffer of the specified size. -+ It can be called multiple times to compute the digest of long or discontinuous data streams. -+ SM3 context should be already correctly initialized by Sm3Init(), and should not be finalized -+ by Sm3Final(). Behavior with invalid context is undefined. -+ -+ If Sm3Context is NULL, then return FALSE. -+ -+ @param[in, out] Sm3Context Pointer to the SM3 context. -+ @param[in] Data Pointer to the buffer containing the data to be hashed. -+ @param[in] DataSize Size of Data buffer in bytes. -+ -+ @retval TRUE SM3 data digest succeeded. -+ @retval FALSE SM3 data digest failed. -+ -+**/ -+BOOLEAN -+EFIAPI -+Sm3Update ( -+ IN OUT VOID *Sm3Context, -+ IN CONST VOID *Data, -+ IN UINTN DataSize -+ ) -+{ -+ // -+ // Check input parameters. -+ // -+ if (Sm3Context == NULL) { -+ return FALSE; -+ } -+ -+ // -+ // Check invalid parameters, in case that only DataLength was checked in OpenSSL -+ // -+ if (Data == NULL && DataSize != 0) { -+ return FALSE; -+ } -+ -+ // -+ // OpenSSL SM3 Hash Update -+ // -+ return (BOOLEAN) (sm3_update ((SM3_CTX *) Sm3Context, Data, DataSize)); -+} -+ -+/** -+ Completes computation of the SM3 digest value. -+ -+ This function completes SM3 hash computation and retrieves the digest value into -+ the specified memory. After this function has been called, the SM3 context cannot -+ be used again. -+ SM3 context should be already correctly initialized by Sm3Init(), and should not be -+ finalized by Sm3Final(). Behavior with invalid SM3 context is undefined. -+ -+ If Sm3Context is NULL, then return FALSE. -+ If HashValue is NULL, then return FALSE. -+ -+ @param[in, out] Sm3Context Pointer to the SM3 context. -+ @param[out] HashValue Pointer to a buffer that receives the SM3 digest -+ value (32 bytes). -+ -+ @retval TRUE SM3 digest computation succeeded. -+ @retval FALSE SM3 digest computation failed. -+ -+**/ -+BOOLEAN -+EFIAPI -+Sm3Final ( -+ IN OUT VOID *Sm3Context, -+ OUT UINT8 *HashValue -+ ) -+{ -+ // -+ // Check input parameters. -+ // -+ if (Sm3Context == NULL || HashValue == NULL) { -+ return FALSE; -+ } -+ -+ // -+ // OpenSSL SM3 Hash Finalization -+ // -+ return (BOOLEAN) (sm3_final (HashValue, (SM3_CTX *) Sm3Context)); -+} -+ -+/** -+ Computes the SM3 message digest of a input data buffer. -+ -+ This function performs the SM3 message digest of a given data buffer, and places -+ the digest value into the specified memory. -+ -+ If this interface is not supported, then return FALSE. -+ -+ @param[in] Data Pointer to the buffer containing the data to be hashed. -+ @param[in] DataSize Size of Data buffer in bytes. -+ @param[out] HashValue Pointer to a buffer that receives the SM3 digest -+ value (32 bytes). -+ -+ @retval TRUE SM3 digest computation succeeded. -+ @retval FALSE SM3 digest computation failed. -+ @retval FALSE This interface is not supported. -+ -+**/ -+BOOLEAN -+EFIAPI -+Sm3HashAll ( -+ IN CONST VOID *Data, -+ IN UINTN DataSize, -+ OUT UINT8 *HashValue -+ ) -+{ -+ // -+ // Check input parameters. -+ // -+ if (HashValue == NULL) { -+ return FALSE; -+ } -+ if (Data == NULL && DataSize != 0) { -+ return FALSE; -+ } -+ -+ // -+ // OpenSSL SM3 Hash Computation. -+ // -+ -+ SM3_CTX c; -+ sm3_init(&c); -+ sm3_update(&c, Data, DataSize); -+ sm3_final(HashValue, &c); -+ -+ return TRUE; -+} -diff --git a/Cryptlib/Include/openssl/crypto.h b/Cryptlib/Include/openssl/crypto.h -index e201a12..b0fbe1c 100644 ---- a/Cryptlib/Include/openssl/crypto.h -+++ b/Cryptlib/Include/openssl/crypto.h -@@ -380,6 +380,7 @@ int CRYPTO_is_mem_check_on(void); - # define is_MemCheck_on() CRYPTO_is_mem_check_on() - - # define OPENSSL_malloc(num) CRYPTO_malloc((int)num,OPENSSL_FILE,OPENSSL_LINE) -+# define OPENSSL_zalloc(num) CRYPTO_zalloc((int)num,OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_strdup(str) CRYPTO_strdup((str),OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_realloc(addr,num) \ - CRYPTO_realloc((char *)addr,(int)num,OPENSSL_FILE,OPENSSL_LINE) -@@ -389,6 +390,8 @@ int CRYPTO_is_mem_check_on(void); - CRYPTO_remalloc((char **)addr,(int)num,OPENSSL_FILE,OPENSSL_LINE) - # define OPENSSL_freeFunc CRYPTO_free - # define OPENSSL_free(addr) CRYPTO_free(addr) -+# define OPENSSL_clear_free(addr, num) \ -+ CRYPTO_clear_free(addr,num,OPENSSL_FILE,OPENSSL_LINE) - - # define OPENSSL_malloc_locked(num) \ - CRYPTO_malloc_locked((int)num,OPENSSL_FILE,OPENSSL_LINE) -@@ -399,6 +402,8 @@ unsigned long SSLeay(void); - - int OPENSSL_issetugid(void); - -+unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); -+ - /* An opaque type representing an implementation of "ex_data" support */ - typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; - /* Return an opaque pointer to the current "ex_data" implementation */ -@@ -533,12 +538,14 @@ void CRYPTO_get_mem_debug_functions(void (**m) - void *CRYPTO_malloc_locked(int num, const char *file, int line); - void CRYPTO_free_locked(void *ptr); - void *CRYPTO_malloc(int num, const char *file, int line); -+void *CRYPTO_zalloc(int num, const char *file, int line); - char *CRYPTO_strdup(const char *str, const char *file, int line); - void CRYPTO_free(void *ptr); - void *CRYPTO_realloc(void *addr, int num, const char *file, int line); - void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file, - int line); - void *CRYPTO_remalloc(void *addr, int num, const char *file, int line); -+void CRYPTO_clear_free(void *ptr, int num, const char *file, int line); - - void OPENSSL_cleanse(void *ptr, size_t len); - -@@ -651,10 +658,13 @@ void ERR_load_CRYPTO_strings(void); - # define CRYPTO_F_INT_DUP_EX_DATA 106 - # define CRYPTO_F_INT_FREE_EX_DATA 107 - # define CRYPTO_F_INT_NEW_EX_DATA 108 -+# define CRYPTO_F_OPENSSL_HEXSTR2BUF 118 - - /* Reason codes. */ - # define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 - # define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 -+# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102 -+# define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103 - - #ifdef __cplusplus - } -diff --git a/Cryptlib/Include/openssl/ec.h b/Cryptlib/Include/openssl/ec.h -index 81e6faf..e315025 100644 ---- a/Cryptlib/Include/openssl/ec.h -+++ b/Cryptlib/Include/openssl/ec.h -@@ -254,6 +254,12 @@ BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); - */ - int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); - -+/** Gets the order of an EC_GROUP -+ * \param group EC_GROUP object -+ * \return the group order -+ */ -+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); -+ - /** Gets the cofactor of a EC_GROUP - * \param group EC_GROUP object - * \param cofactor BIGNUM to which the cofactor is copied -@@ -1053,6 +1059,17 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p) -+# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \ -+ EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ -+ EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id)) -+ -+# define EVP_PKEY_CTX_get1_id(ctx, id) \ -+ EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ -+ EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id)) -+ -+# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \ -+ EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ -+ EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len)) - - # 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) -@@ -1064,6 +1081,9 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); - # define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) - # define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) - # define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) -+# define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11) -+# define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12) -+# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13) - /* KDF types */ - # define EVP_PKEY_ECDH_KDF_NONE 1 - # define EVP_PKEY_ECDH_KDF_X9_62 2 -diff --git a/Cryptlib/Include/openssl/ecdsa.h b/Cryptlib/Include/openssl/ecdsa.h -index a6f0930..e51d924 100644 ---- a/Cryptlib/Include/openssl/ecdsa.h -+++ b/Cryptlib/Include/openssl/ecdsa.h -@@ -90,6 +90,13 @@ ECDSA_SIG *ECDSA_SIG_new(void); - */ - void ECDSA_SIG_free(ECDSA_SIG *sig); - -+/** Accessor for r and s fields of ECDSA_SIG -+ * \param sig pointer to ECDSA_SIG structure -+ * \param pr pointer to BIGNUM pointer for r (may be NULL) -+ * \param ps pointer to BIGNUM pointer for s (may be NULL) -+ */ -+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); -+ - /** DER encode content of ECDSA_SIG object (note: this function modifies *pp - * (*pp += length of the DER encoded signature)). - * \param sig pointer to the ECDSA_SIG object -diff --git a/Cryptlib/Include/openssl/err.h b/Cryptlib/Include/openssl/err.h -index 5a01980..c8286e1 100644 ---- a/Cryptlib/Include/openssl/err.h -+++ b/Cryptlib/Include/openssl/err.h -@@ -197,6 +197,8 @@ typedef struct err_state_st { - # define ERR_LIB_TS 47 - # define ERR_LIB_HMAC 48 - # define ERR_LIB_JPAKE 49 -+# define ERR_LIB_SM2 53 -+ - - # define ERR_LIB_USER 128 - -@@ -233,6 +235,7 @@ typedef struct err_state_st { - # define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) - # define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) - # define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -+# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,(f),(r),OPENSSL_FILE,OPENSSL_LINE) - - /* - * Borland C seems too stupid to be able to shift and do longs in the -@@ -304,6 +307,9 @@ typedef struct err_state_st { - # define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) - # define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) - # define ERR_R_DISABLED (5|ERR_R_FATAL) -+# define ERR_R_INIT_FAIL (6|ERR_R_FATAL) -+# define ERR_R_PASSED_INVALID_ARGUMENT (7) -+# define ERR_R_OPERATION_FAIL (8|ERR_R_FATAL) - - /* - * 99 is the maximum possible ERR_R_... code, higher values are reserved for -diff --git a/Cryptlib/Include/openssl/evp.h b/Cryptlib/Include/openssl/evp.h -index 376f260..4e1d9bb 100644 ---- a/Cryptlib/Include/openssl/evp.h -+++ b/Cryptlib/Include/openssl/evp.h -@@ -115,6 +115,7 @@ - # define EVP_PKEY_DH NID_dhKeyAgreement - # define EVP_PKEY_DHX NID_dhpublicnumber - # define EVP_PKEY_EC NID_X9_62_id_ecPublicKey -+# define EVP_PKEY_SM2 NID_sm2 - # define EVP_PKEY_HMAC NID_hmac - # define EVP_PKEY_CMAC NID_cmac - -@@ -122,6 +123,12 @@ - extern "C" { - #endif - -+/* -+ * Don't free up md_ctx->pctx in EVP_MD_CTX_reset, use the reserved flag -+ * values in evp.h -+ */ -+#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400 -+ - /* - * Type needs to be a bit field Sub-type needs to be for variations on the - * method, as in, can it do arbitrary encryption.... -@@ -526,6 +533,8 @@ const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); - # define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) - # define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) - -+void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); -+ - int EVP_CIPHER_nid(const EVP_CIPHER *cipher); - # define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) - int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); -@@ -583,6 +592,9 @@ int EVP_Cipher(EVP_CIPHER_CTX *c, - # define EVP_delete_digest_alias(alias) \ - OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); - -+EVP_MD_CTX *EVP_MD_CTX_new(void); -+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); -+void EVP_MD_CTX_free(EVP_MD_CTX *ctx); - void EVP_MD_CTX_init(EVP_MD_CTX *ctx); - int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); - EVP_MD_CTX *EVP_MD_CTX_create(void); -@@ -666,6 +678,10 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, - const unsigned char *sig, size_t siglen); - -+int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, -+ size_t siglen, const unsigned char *tbs, -+ size_t tbslen); -+ - int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, - const unsigned char *ek, int ekl, const unsigned char *iv, - EVP_PKEY *priv); -@@ -741,6 +757,9 @@ const EVP_MD *EVP_ripemd160(void); - # ifndef OPENSSL_NO_WHIRLPOOL - const EVP_MD *EVP_whirlpool(void); - # endif -+# ifndef OPENSSL_NO_SM3 -+const EVP_MD *EVP_sm3(void); -+# endif - const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ - # ifndef OPENSSL_NO_DES - const EVP_CIPHER *EVP_des_ecb(void); -@@ -954,10 +973,15 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey); - int EVP_PKEY_bits(EVP_PKEY *pkey); - int EVP_PKEY_size(EVP_PKEY *pkey); - int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); -+int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); - int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); - int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); - void *EVP_PKEY_get0(EVP_PKEY *pkey); - -+# ifndef OPENSSL_NO_SM2 -+int EVP_PKEY_is_sm2(EVP_PKEY *pkey); -+# endif -+ - # ifndef OPENSSL_NO_RSA - struct rsa_st; - int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); -@@ -976,6 +1000,7 @@ struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); - # ifndef OPENSSL_NO_EC - struct ec_key_st; - int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); -+struct ec_key_st *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); - struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); - # endif - -diff --git a/Cryptlib/Include/openssl/obj_mac.h b/Cryptlib/Include/openssl/obj_mac.h -index 779c309..91b75e0 100644 ---- a/Cryptlib/Include/openssl/obj_mac.h -+++ b/Cryptlib/Include/openssl/obj_mac.h -@@ -4192,3 +4192,36 @@ - #define LN_jurisdictionCountryName "jurisdictionCountryName" - #define NID_jurisdictionCountryName 957 - #define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L -+ -+#define SN_ISO_CN "ISO-CN" -+#define LN_ISO_CN "ISO CN Member Body" -+#define NID_ISO_CN 958 -+#define OBJ_ISO_CN OBJ_member_body,156L -+ -+#define SN_oscca "oscca" -+#define NID_oscca 959 -+#define OBJ_oscca OBJ_ISO_CN,10197L -+ -+#define SN_sm_scheme "sm-scheme" -+#define NID_sm_scheme 960 -+#define OBJ_sm_scheme OBJ_oscca,1L -+ -+#define SN_sm2 "SM2" -+#define LN_sm2 "sm2" -+#define NID_sm2 961 -+#define OBJ_sm2 OBJ_sm_scheme,301L -+ -+#define SN_sm3 "SM3" -+#define LN_sm3 "sm3" -+#define NID_sm3 962 -+#define OBJ_sm3 OBJ_sm_scheme,401L -+ -+#define SN_sm3WithRSAEncryption "RSA-SM3" -+#define LN_sm3WithRSAEncryption "sm3WithRSAEncryption" -+#define NID_sm3WithRSAEncryption 963 -+#define OBJ_sm3WithRSAEncryption OBJ_sm_scheme,504L -+ -+#define SN_SM2_with_SM3 "SM2-SM3" -+#define LN_SM2_with_SM3 "SM2-with-SM3" -+#define NID_SM2_with_SM3 964 -+#define OBJ_SM2_with_SM3 OBJ_sm_scheme,501L -diff --git a/Cryptlib/Include/openssl/opensslconf.h b/Cryptlib/Include/openssl/opensslconf.h -index 4a36e9f..6f19ce6 100644 ---- a/Cryptlib/Include/openssl/opensslconf.h -+++ b/Cryptlib/Include/openssl/opensslconf.h -@@ -10,7 +10,6 @@ extern "C" { - #endif - #ifndef OPENSSL_DOING_MAKEDEPEND - -- - #ifndef OPENSSL_NO_BF - # define OPENSSL_NO_BF - #endif -@@ -41,8 +40,8 @@ extern "C" { - #ifndef OPENSSL_NO_DYNAMIC_ENGINE - # define OPENSSL_NO_DYNAMIC_ENGINE - #endif --#ifndef OPENSSL_NO_EC --# define OPENSSL_NO_EC -+#ifndef OPENSSL_NO_EC2M -+# define OPENSSL_NO_EC2M - #endif - #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - # define OPENSSL_NO_EC_NISTP_64_GCC_128 -@@ -50,9 +49,6 @@ extern "C" { - #ifndef OPENSSL_NO_ECDH - # define OPENSSL_NO_ECDH - #endif --#ifndef OPENSSL_NO_ECDSA --# define OPENSSL_NO_ECDSA --#endif - #ifndef OPENSSL_NO_ENGINE - # define OPENSSL_NO_ENGINE - #endif -diff --git a/Cryptlib/Include/openssl/sm2.h b/Cryptlib/Include/openssl/sm2.h -new file mode 100644 -index 0000000..37c67a3 ---- /dev/null -+++ b/Cryptlib/Include/openssl/sm2.h -@@ -0,0 +1,79 @@ -+/* -+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 2017 Ribose Inc. All Rights Reserved. -+ * Ported from Ribose contributions from Botan. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#ifndef OSSL_CRYPTO_SM2_H -+# define OSSL_CRYPTO_SM2_H -+# include -+ -+# ifndef OPENSSL_NO_SM2 -+ -+# include -+# include -+ -+/* The default user id as specified in GM/T 0009-2012 */ -+# define SM2_DEFAULT_USERID "1234567812345678" -+# define SM2_DEFAULT_USERID_LEN 16 -+ -+int sm2_compute_z_digest(uint8_t *out, -+ const EVP_MD *digest, -+ const uint8_t *id, -+ const size_t id_len, -+ const EC_KEY *key); -+ -+/* -+ * SM2 signature operation. Computes Z and then signs H(Z || msg) using SM2 -+ */ -+ECDSA_SIG *sm2_do_sign(const EC_KEY *key, -+ const EVP_MD *digest, -+ const uint8_t *id, -+ const size_t id_len, -+ const uint8_t *msg, size_t msg_len); -+ -+int sm2_do_verify(const EC_KEY *key, -+ const EVP_MD *digest, -+ const ECDSA_SIG *signature, -+ const uint8_t *id, -+ const size_t id_len, -+ const uint8_t *msg, size_t msg_len); -+ -+/* -+ * SM2 signature generation. -+ */ -+int sm2_sign(const unsigned char *dgst, int dgstlen, -+ unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); -+ -+/* -+ * SM2 signature verification. -+ */ -+int sm2_verify(const unsigned char *dgst, int dgstlen, -+ const unsigned char *sig, int siglen, EC_KEY *eckey); -+ -+/* -+ * SM2 encryption -+ */ -+int sm2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len, -+ size_t *ct_size); -+ -+int sm2_plaintext_size(const unsigned char *ct, size_t ct_size, size_t *pt_size); -+ -+int sm2_encrypt(const EC_KEY *key, -+ const EVP_MD *digest, -+ const uint8_t *msg, -+ size_t msg_len, -+ uint8_t *ciphertext_buf, size_t *ciphertext_len); -+ -+int sm2_decrypt(const EC_KEY *key, -+ const EVP_MD *digest, -+ const uint8_t *ciphertext, -+ size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len); -+ -+# endif /* OPENSSL_NO_SM2 */ -+#endif -diff --git a/Cryptlib/Include/openssl/sm2err.h b/Cryptlib/Include/openssl/sm2err.h -new file mode 100644 -index 0000000..251c4f9 ---- /dev/null -+++ b/Cryptlib/Include/openssl/sm2err.h -@@ -0,0 +1,65 @@ -+/* -+ * Generated by util/mkerr.pl DO NOT EDIT -+ * Copyright 1995-2022 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 -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#ifndef HEADER_SM2ERR_H -+# define HEADER_SM2ERR_H -+ -+# include -+ -+# include -+ -+# ifndef OPENSSL_NO_SM2 -+ -+# ifdef __cplusplus -+extern "C" -+# endif -+int ERR_load_SM2_strings(void); -+ -+/* -+ * SM2 function codes. -+ */ -+# define SM2_F_PKEY_SM2_COPY 115 -+# define SM2_F_PKEY_SM2_CTRL 109 -+# define SM2_F_PKEY_SM2_CTRL_STR 110 -+# define SM2_F_PKEY_SM2_DIGEST_CUSTOM 114 -+# define SM2_F_PKEY_SM2_INIT 111 -+# define SM2_F_PKEY_SM2_SIGN 112 -+# define SM2_F_SM2_COMPUTE_KEY 116 -+# define SM2_F_SM2_COMPUTE_MSG_HASH 100 -+# define SM2_F_SM2_COMPUTE_USERID_DIGEST 101 -+# define SM2_F_SM2_COMPUTE_Z_DIGEST 113 -+# define SM2_F_SM2_DECRYPT 102 -+# define SM2_F_SM2_ENCRYPT 103 -+# define SM2_F_SM2_PLAINTEXT_SIZE 104 -+# define SM2_F_SM2_SIGN 105 -+# define SM2_F_SM2_SIG_GEN 106 -+# define SM2_F_SM2_SIG_VERIFY 107 -+# define SM2_F_SM2_VERIFY 108 -+ -+/* -+ * SM2 reason codes. -+ */ -+# define SM2_R_ASN1_ERROR 100 -+# define SM2_R_BAD_SIGNATURE 101 -+# define SM2_R_BUFFER_TOO_SMALL 107 -+# define SM2_R_DIST_ID_TOO_LARGE 110 -+# define SM2_R_ID_NOT_SET 112 -+# define SM2_R_ID_TOO_LARGE 111 -+# define SM2_R_INVALID_CURVE 108 -+# define SM2_R_INVALID_DIGEST 102 -+# define SM2_R_INVALID_DIGEST_TYPE 103 -+# define SM2_R_INVALID_ENCODING 104 -+# define SM2_R_INVALID_FIELD 105 -+# define SM2_R_NO_PARAMETERS_SET 109 -+# define SM2_R_NO_PRIVATE_VALUE 113 -+# define SM2_R_USER_ID_TOO_LARGE 106 -+ -+# endif -+#endif -diff --git a/Cryptlib/Include/openssl/sm3.h b/Cryptlib/Include/openssl/sm3.h -new file mode 100644 -index 0000000..97e7460 ---- /dev/null -+++ b/Cryptlib/Include/openssl/sm3.h -@@ -0,0 +1,39 @@ -+/* -+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 2017 Ribose Inc. 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 -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#ifndef OSSL_CRYPTO_SM3_H -+# define OSSL_CRYPTO_SM3_H -+ -+# include -+ -+# ifdef OPENSSL_NO_SM3 -+# error SM3 is disabled. -+# endif -+ -+# define SM3_DIGEST_LENGTH 32 -+# define SM3_WORD unsigned int -+ -+# define SM3_CBLOCK 64 -+# define SM3_LBLOCK (SM3_CBLOCK/4) -+ -+typedef struct SM3state_st { -+ SM3_WORD A, B, C, D, E, F, G, H; -+ SM3_WORD Nl, Nh; -+ SM3_WORD data[SM3_LBLOCK]; -+ unsigned int num; -+} SM3_CTX; -+ -+int sm3_init(SM3_CTX *c); -+int sm3_update(SM3_CTX *c, const void *data, size_t len); -+int sm3_final(unsigned char *md, SM3_CTX *c); -+ -+void sm3_block_data_order(SM3_CTX *c, const void *p, size_t num); -+ -+#endif -diff --git a/Cryptlib/Include/openssl/x509.h b/Cryptlib/Include/openssl/x509.h -index 6fa28eb..eda456b 100644 ---- a/Cryptlib/Include/openssl/x509.h -+++ b/Cryptlib/Include/openssl/x509.h -@@ -237,6 +237,9 @@ typedef struct X509_req_st { - X509_ALGOR *sig_alg; - ASN1_BIT_STRING *signature; - int references; -+# ifndef OPENSSL_NO_SM2 -+ ASN1_OCTET_STRING *sm2_id; -+# endif - } X509_REQ; - - typedef struct x509_cinf_st { -@@ -296,6 +299,10 @@ struct x509_st { - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; - # endif - X509_CERT_AUX *aux; -+ volatile int ex_cached; -+# ifndef OPENSSL_NO_SM2 -+ ASN1_OCTET_STRING *sm2_id; -+# endif - } /* X509 */ ; - - DECLARE_STACK_OF(X509) -diff --git a/Cryptlib/Library/BaseCryptLib.h b/Cryptlib/Library/BaseCryptLib.h -index 2df8bd2..a7fea2c 100644 ---- a/Cryptlib/Library/BaseCryptLib.h -+++ b/Cryptlib/Library/BaseCryptLib.h -@@ -52,6 +52,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - /// - #define SHA512_DIGEST_SIZE 64 - -+/// -+/// SM3 digest size in bytes -+/// -+#define SM3_DIGEST_SIZE 32 -+ - /// - /// TDES block size in bytes - /// -@@ -893,6 +898,112 @@ Sha512HashAll ( - OUT UINT8 *HashValue - ); - -+/** -+ Retrieves the size, in bytes, of the context buffer required for SM3 hash operations. -+ @return The size, in bytes, of the context buffer required for SM3 hash operations. -+**/ -+UINTN -+EFIAPI -+Sm3GetContextSize ( -+ VOID -+ ); -+ -+/** -+ Initializes user-supplied memory pointed by Sm3Context as SM3 hash context for -+ subsequent use. -+ If Sm3Context is NULL, then return FALSE. -+ @param[out] Sm3Context Pointer to SM3 context being initialized. -+ @retval TRUE SM3 context initialization succeeded. -+ @retval FALSE SM3 context initialization failed. -+**/ -+BOOLEAN -+EFIAPI -+Sm3Init ( -+ OUT VOID *Sm3Context -+ ); -+ -+/** -+ Makes a copy of an existing SM3 context. -+ If Sm3Context is NULL, then return FALSE. -+ If NewSm3Context is NULL, then return FALSE. -+ If this interface is not supported, then return FALSE. -+ @param[in] Sm3Context Pointer to SM3 context being copied. -+ @param[out] NewSm3Context Pointer to new SM3 context. -+ @retval TRUE SM3 context copy succeeded. -+ @retval FALSE SM3 context copy failed. -+ @retval FALSE This interface is not supported. -+**/ -+BOOLEAN -+EFIAPI -+Sm3Duplicate ( -+ IN CONST VOID *Sm3Context, -+ OUT VOID *NewSm3Context -+ ); -+ -+/** -+ Digests the input data and updates SM3 context. -+ This function performs SM3 digest on a data buffer of the specified size. -+ It can be called multiple times to compute the digest of long or discontinuous data streams. -+ SM3 context should be already correctly initialized by Sm3Init(), and should not be finalied -+ by Sm3Final(). Behavior with invalid context is undefined. -+ If Sm3Context is NULL, then return FALSE. -+ @param[in, out] Sm3Context Pointer to the SM3 context. -+ @param[in] Data Pointer to the buffer containing the data to be hashed. -+ @param[in] DataSize Size of Data buffer in bytes. -+ @retval TRUE SM3 data digest succeeded. -+ @retval FALSE SM3 data digest failed. -+**/ -+BOOLEAN -+EFIAPI -+Sm3Update ( -+ IN OUT VOID *Sm3Context, -+ IN CONST VOID *Data, -+ IN UINTN DataSize -+ ); -+ -+/** -+ Completes computation of the SM3 digest value. -+ This function completes SM3 hash computation and retrieves the digest value into -+ the specified memory. After this function has been called, the SM3 context cannot -+ be used again. -+ SM3 context should be already correctly initialized by Sm3Init(), and should not be -+ finalized by Sm3Final(). Behavior with invalid SM3 context is undefined. -+ If Sm3Context is NULL, then return FALSE. -+ If HashValue is NULL, then return FALSE. -+ @param[in, out] Sm3Context Pointer to the SM3 context. -+ @param[out] HashValue Pointer to a buffer that receives the SM3 digest -+ value (32 bytes). -+ @retval TRUE SM3 digest computation succeeded. -+ @retval FALSE SM3 digest computation failed. -+**/ -+BOOLEAN -+EFIAPI -+Sm3Final ( -+ IN OUT VOID *Sm3Context, -+ OUT UINT8 *HashValue -+ ); -+ -+/** -+ Computes the SM3 message digest of a input data buffer. -+ This function performs the SM3 message digest of a given data buffer, and places -+ the digest value into the specified memory. -+ If this interface is not supported, then return FALSE. -+ @param[in] Data Pointer to the buffer containing the data to be hashed. -+ @param[in] DataSize Size of Data buffer in bytes. -+ @param[out] HashValue Pointer to a buffer that receives the SM3 digest -+ value (32 bytes). -+ @retval TRUE SM3 digest computation succeeded. -+ @retval FALSE SM3 digest computation failed. -+ @retval FALSE This interface is not supported. -+**/ -+BOOLEAN -+EFIAPI -+Sm3HashAll ( -+ IN CONST VOID *Data, -+ IN UINTN DataSize, -+ OUT UINT8 *HashValue -+ ); -+ - //===================================================================================== - // MAC (Message Authentication Code) Primitive - //===================================================================================== -diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile -index 89fd5cd..7885a1a 100644 ---- a/Cryptlib/Makefile -+++ b/Cryptlib/Makefile -@@ -66,6 +66,12 @@ OBJS = Hash/CryptMd4Null.o \ - SysCall/BaseMemAllocation.o \ - SysCall/BaseStrings.o - -+ifdef SHIM_ENABLE_SM -+OBJS += Hash/CryptSm3.o -+else -+DEFINES += -DOPENSSL_NO_SM3 -+endif -+ - all: $(TARGET) - - libcryptlib.a: $(OBJS) -diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile -index 795f471..32fb235 100644 ---- a/Cryptlib/OpenSSL/Makefile -+++ b/Cryptlib/OpenSSL/Makefile -@@ -459,7 +459,43 @@ OBJS = crypto/cryptlib.o \ - crypto/ocsp/ocsp_err.o \ - crypto/cmac/cmac.o \ - crypto/cmac/cm_ameth.o \ -- crypto/cmac/cm_pmeth.o \ -+ crypto/cmac/cm_pmeth.o -+ -+ifdef SHIM_ENABLE_SM -+OBJS +=crypto/ec/ec_ameth.o \ -+ crypto/ec/ec_cvt.o \ -+ crypto/ec/eck_prn.o \ -+ crypto/ec/ec_oct.o \ -+ crypto/ec/ecp_smpl.o \ -+ crypto/ec/ec_asn1.o \ -+ crypto/ec/ec_err.o \ -+ crypto/ec/ec_pmeth.o \ -+ crypto/ec/ec_check.o \ -+ crypto/ec/ec_lib.o \ -+ crypto/ec/ecp_mont.o \ -+ crypto/ec/ecp_oct.o \ -+ crypto/ec/ec_curve.o \ -+ crypto/ec/ec_key.o \ -+ crypto/ec/ec_mult.o \ -+ crypto/ec/ecp_nist.o \ -+ crypto/ec/ec_print.o \ -+ crypto/ecdsa/ecs_asn1.o \ -+ crypto/ecdsa/ecs_err.o \ -+ crypto/ecdsa/ecs_lib.o \ -+ crypto/ecdsa/ecs_ossl.o \ -+ crypto/ecdsa/ecs_sign.o \ -+ crypto/ecdsa/ecs_vrf.o \ -+ crypto/sm3/sm3.o \ -+ crypto/sm3/m_sm3.o \ -+ crypto/sm2/sm2_err.o \ -+ crypto/sm2/sm2_pmeth.o \ -+ crypto/sm2/sm2_sign.o -+else -+DEFINES +=-DOPENSSL_NO_EC \ -+ -DOPENSSL_NO_ECDSA \ -+ -DOPENSSL_NO_SM2 \ -+ -DOPENSSL_NO_SM3 -+endif - - all: $(TARGET) - -diff --git a/Cryptlib/OpenSSL/crypto/asn1/a_sign.c b/Cryptlib/OpenSSL/crypto/asn1/a_sign.c -index 51c6a0c..68a2ae6 100644 ---- a/Cryptlib/OpenSSL/crypto/asn1/a_sign.c -+++ b/Cryptlib/OpenSSL/crypto/asn1/a_sign.c -@@ -238,7 +238,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, - unsigned char *buf_in = NULL, *buf_out = NULL; - size_t inl = 0, outl = 0, outll = 0; - int signid, paramtype; -- int rv; -+ int rv, pkey_id; - - type = EVP_MD_CTX_md(ctx); - pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); -@@ -268,10 +268,17 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, - - if (rv == 2) { - if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { -+ -+ pkey_id = -+#ifndef OPENSSL_NO_SM2 -+ EVP_PKEY_id(pkey) == NID_sm2 ? NID_sm2 : -+#endif -+ pkey->ameth->pkey_id; -+ - if (!pkey->ameth || - !OBJ_find_sigid_by_algs(&signid, - EVP_MD_nid(type), -- pkey->ameth->pkey_id)) { -+ pkey_id)) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, - ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); - return 0; -diff --git a/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c b/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c -index 43ddebb..db3d27d 100644 ---- a/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c -+++ b/Cryptlib/OpenSSL/crypto/asn1/ameth_lib.c -@@ -64,6 +64,7 @@ - # include - #endif - #include "asn1_locl.h" -+#include - - extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; - extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; -@@ -72,6 +73,8 @@ extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; - extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; - extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; - extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; -+extern const EVP_PKEY_ASN1_METHOD sm2_asn1_meth; -+ - - /* Keep this sorted in type order !! */ - static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { -@@ -97,7 +100,10 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { - &cmac_asn1_meth, - #endif - #ifndef OPENSSL_NO_DH -- &dhx_asn1_meth -+ &dhx_asn1_meth, -+#endif -+#ifndef OPENSSL_NO_SM2 -+ &sm2_asn1_meth, - #endif - }; - -diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_req.c b/Cryptlib/OpenSSL/crypto/asn1/x_req.c -index ae293aa..575564e 100644 ---- a/Cryptlib/OpenSSL/crypto/asn1/x_req.c -+++ b/Cryptlib/OpenSSL/crypto/asn1/x_req.c -@@ -114,3 +114,16 @@ ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = { - IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) - - IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) -+ -+#ifndef OPENSSL_NO_SM2 -+void X509_REQ_set0_sm2_id(X509_REQ *x, ASN1_OCTET_STRING *sm2_id) -+{ -+ ASN1_OCTET_STRING_free(x->sm2_id); -+ x->sm2_id = sm2_id; -+} -+ -+ASN1_OCTET_STRING *X509_REQ_get0_sm2_id(X509_REQ *x) -+{ -+ return x->sm2_id; -+} -+#endif -diff --git a/Cryptlib/OpenSSL/crypto/asn1/x_x509.c b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c -index aada4a8..8969918 100644 ---- a/Cryptlib/OpenSSL/crypto/asn1/x_x509.c -+++ b/Cryptlib/OpenSSL/crypto/asn1/x_x509.c -@@ -98,6 +98,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - #ifndef OPENSSL_NO_RFC3779 - ret->rfc3779_addr = NULL; - ret->rfc3779_asid = NULL; -+#endif -+#ifndef OPENSSL_NO_SM2 -+ ret->sm2_id = NULL; - #endif - ret->aux = NULL; - ret->crldp = NULL; -@@ -123,6 +126,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); - ASIdentifiers_free(ret->rfc3779_asid); - #endif -+#ifndef OPENSSL_NO_SM2 -+ ASN1_OCTET_STRING_free(ret->sm2_id); -+#endif - - if (ret->name != NULL) - OPENSSL_free(ret->name); -diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_lib.c b/Cryptlib/OpenSSL/crypto/bn/bn_lib.c -index 2671f35..10b78f5 100644 ---- a/Cryptlib/OpenSSL/crypto/bn/bn_lib.c -+++ b/Cryptlib/OpenSSL/crypto/bn/bn_lib.c -@@ -496,9 +496,6 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) - if (bn_wexpand(a, b->top) == NULL) - return (NULL); - -- if (!a || !b || !a->d || !b->d) -- return (NULL); -- - #if 1 - A = a->d; - B = b->d; -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_ameth.c b/Cryptlib/OpenSSL/crypto/ec/ec_ameth.c -new file mode 100644 -index 0000000..d55dcca ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_ameth.c -@@ -0,0 +1,646 @@ -+/* -+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project -+ * 2006. -+ */ -+/* ==================================================================== -+ * Copyright (c) 2006 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 -+ * licensing@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 -+#include "cryptlib.h" -+#include -+#include -+#include -+#include -+#include "asn1_locl.h" -+#include "ec_lcl.h" -+ -+#ifndef OPENSSL_NO_SM2 -+const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = { -+ EVP_PKEY_SM2, -+ EVP_PKEY_EC, -+ ASN1_PKEY_ALIAS -+}; -+#endif -+ -+extern UINTN EFIAPI console_print(const CHAR16 *fmt, ...); -+ -+static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) -+{ -+ const EC_GROUP *group; -+ int nid; -+ if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { -+ ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); -+ return 0; -+ } -+ if (EC_GROUP_get_asn1_flag(group) -+ && (nid = EC_GROUP_get_curve_name(group))) -+ /* we have a 'named curve' => just set the OID */ -+ { -+ *ppval = OBJ_nid2obj(nid); -+ *pptype = V_ASN1_OBJECT; -+ } else { /* explicit parameters */ -+ -+ ASN1_STRING *pstr = NULL; -+ pstr = ASN1_STRING_new(); -+ if (!pstr) -+ return 0; -+ pstr->length = i2d_ECParameters(ec_key, &pstr->data); -+ if (pstr->length <= 0) { -+ ASN1_STRING_free(pstr); -+ ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); -+ return 0; -+ } -+ *ppval = pstr; -+ *pptype = V_ASN1_SEQUENCE; -+ } -+ return 1; -+} -+ -+static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) -+{ -+ EC_KEY *ec_key = pkey->pkey.ec; -+ void *pval = NULL; -+ int ptype; -+ unsigned char *penc = NULL, *p; -+ int penclen; -+ -+ if (!eckey_param2type(&ptype, &pval, ec_key)) { -+ ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); -+ return 0; -+ } -+ penclen = i2o_ECPublicKey(ec_key, NULL); -+ if (penclen <= 0) -+ goto err; -+ penc = OPENSSL_malloc(penclen); -+ if (!penc) -+ goto err; -+ p = penc; -+ penclen = i2o_ECPublicKey(ec_key, &p); -+ if (penclen <= 0) -+ goto err; -+ if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), -+ ptype, pval, penc, penclen)) -+ return 1; -+ err: -+ if (ptype == V_ASN1_OBJECT) -+ ASN1_OBJECT_free(pval); -+ else -+ ASN1_STRING_free(pval); -+ if (penc) -+ OPENSSL_free(penc); -+ return 0; -+} -+ -+static EC_KEY *eckey_type2param(int ptype, void *pval) -+{ -+ EC_KEY *eckey = NULL; -+ if (ptype == V_ASN1_SEQUENCE) { -+ ASN1_STRING *pstr = pval; -+ const unsigned char *pm = NULL; -+ int pmlen; -+ pm = pstr->data; -+ pmlen = pstr->length; -+ if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) { -+ ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); -+ goto ecerr; -+ } -+ } else if (ptype == V_ASN1_OBJECT) { -+ ASN1_OBJECT *poid = pval; -+ EC_GROUP *group; -+ -+ /* -+ * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID -+ */ -+ if ((eckey = EC_KEY_new()) == NULL) { -+ ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); -+ goto ecerr; -+ } -+ group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); -+ if (group == NULL){ -+ goto ecerr;} -+ EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); -+ if (EC_KEY_set_group(eckey, group) == 0) { -+ goto ecerr; -+ } -+ EC_GROUP_free(group); -+ } else { -+ ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); -+ goto ecerr; -+ } -+ -+ return eckey; -+ -+ ecerr: -+ if (eckey) -+ EC_KEY_free(eckey); -+ return NULL; -+} -+ -+static int eckey_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; -+ -+ 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 eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -+{ -+ int r; -+ const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); -+ const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), -+ *pb = EC_KEY_get0_public_key(b->pkey.ec); -+ if (group == NULL || pa == NULL || pb == NULL) -+ return -2; -+ r = EC_POINT_cmp(group, pa, pb, NULL); -+ if (r == 0) -+ return 1; -+ if (r == 1) -+ return 0; -+ return -2; -+} -+ -+static int eckey_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; -+ -+ 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_EC_KEY(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 eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) -+{ -+ EC_KEY ec_key = *(pkey->pkey.ec); -+ unsigned char *ep, *p; -+ int eplen, ptype; -+ void *pval; -+ unsigned int old_flags; -+ -+ if (!eckey_param2type(&ptype, &pval, &ec_key)) { -+ ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); -+ return 0; -+ } -+ -+ /* set the private key */ -+ -+ /* -+ * do not include the parameters in the SEC1 private key see PKCS#11 -+ * 12.11 -+ */ -+ old_flags = EC_KEY_get_enc_flags(&ec_key); -+ EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); -+ -+ eplen = i2d_ECPrivateKey(&ec_key, NULL); -+ if (!eplen) { -+ ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); -+ return 0; -+ } -+ ep = (unsigned char *)OPENSSL_malloc(eplen); -+ if (!ep) { -+ ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ p = ep; -+ if (!i2d_ECPrivateKey(&ec_key, &p)) { -+ OPENSSL_free(ep); -+ ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); -+ return 0; -+ } -+ -+ if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, -+ ptype, pval, ep, eplen)) -+ return 0; -+ -+ return 1; -+} -+ -+static int int_ec_size(const EVP_PKEY *pkey) -+{ -+ return ECDSA_size(pkey->pkey.ec); -+} -+ -+static int ec_bits(const EVP_PKEY *pkey) -+{ -+ BIGNUM *order = BN_new(); -+ const EC_GROUP *group; -+ int ret; -+ -+ if (!order) { -+ ERR_clear_error(); -+ return 0; -+ } -+ group = EC_KEY_get0_group(pkey->pkey.ec); -+ if (!EC_GROUP_get_order(group, order, NULL)) { -+ ERR_clear_error(); -+ return 0; -+ } -+ -+ ret = BN_num_bits(order); -+ BN_free(order); -+ return ret; -+} -+ -+static int ec_missing_parameters(const EVP_PKEY *pkey) -+{ -+ if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL) -+ return 1; -+ return 0; -+} -+ -+static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) -+{ -+ EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); -+ if (group == NULL) -+ return 0; -+ if (EC_KEY_set_group(to->pkey.ec, group) == 0) -+ return 0; -+ EC_GROUP_free(group); -+ return 1; -+} -+ -+static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) -+{ -+ const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), -+ *group_b = EC_KEY_get0_group(b->pkey.ec); -+ if (group_a == NULL || group_b == NULL) -+ return -2; -+ if (EC_GROUP_cmp(group_a, group_b, NULL)) -+ return 0; -+ else -+ return 1; -+} -+ -+static void int_ec_free(EVP_PKEY *pkey) -+{ -+ EC_KEY_free(pkey->pkey.ec); -+} -+ -+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) -+{ -+ unsigned char *buffer = NULL; -+ const char *ecstr; -+ size_t buf_len = 0, i; -+ int ret = 0, reason = ERR_R_BIO_LIB; -+ BIGNUM *pub_key = NULL, *order = NULL; -+ BN_CTX *ctx = NULL; -+ const EC_GROUP *group; -+ const EC_POINT *public_key; -+ const BIGNUM *priv_key; -+ -+ if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { -+ reason = ERR_R_PASSED_NULL_PARAMETER; -+ goto err; -+ } -+ -+ ctx = BN_CTX_new(); -+ if (ctx == NULL) { -+ reason = ERR_R_MALLOC_FAILURE; -+ goto err; -+ } -+ -+ if (ktype > 0) { -+ public_key = EC_KEY_get0_public_key(x); -+ if (public_key != NULL) { -+ if ((pub_key = EC_POINT_point2bn(group, public_key, -+ EC_KEY_get_conv_form(x), NULL, -+ ctx)) == NULL) { -+ reason = ERR_R_EC_LIB; -+ goto err; -+ } -+ buf_len = (size_t)BN_num_bytes(pub_key); -+ } -+ } -+ -+ if (ktype == 2) { -+ priv_key = EC_KEY_get0_private_key(x); -+ if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) -+ buf_len = i; -+ } else -+ priv_key = NULL; -+ -+ if (ktype > 0) { -+ buf_len += 10; -+ if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { -+ reason = ERR_R_MALLOC_FAILURE; -+ goto err; -+ } -+ } -+ if (ktype == 2) -+ ecstr = "Private-Key"; -+ else if (ktype == 1) -+ ecstr = "Public-Key"; -+ else -+ ecstr = "ECDSA-Parameters"; -+ -+ if (!BIO_indent(bp, off, 128)) -+ goto err; -+ if ((order = BN_new()) == NULL) -+ goto err; -+ if (!EC_GROUP_get_order(group, order, NULL)) -+ goto err; -+ if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) -+ goto err; -+ -+ if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, -+ buffer, off)) -+ goto err; -+ if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, -+ buffer, off)) -+ goto err; -+ if (!ECPKParameters_print(bp, group, off)) -+ goto err; -+ ret = 1; -+ err: -+ if (!ret) -+ ECerr(EC_F_DO_EC_KEY_PRINT, reason); -+ if (pub_key) -+ BN_free(pub_key); -+ if (order) -+ BN_free(order); -+ if (ctx) -+ BN_CTX_free(ctx); -+ if (buffer != NULL) -+ OPENSSL_free(buffer); -+ return (ret); -+} -+ -+static int eckey_param_decode(EVP_PKEY *pkey, -+ const unsigned char **pder, int derlen) -+{ -+ EC_KEY *eckey; -+ if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { -+ ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); -+ return 0; -+ } -+ EVP_PKEY_assign_EC_KEY(pkey, eckey); -+ return 1; -+} -+ -+static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) -+{ -+ return i2d_ECParameters(pkey->pkey.ec, pder); -+} -+ -+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, -+ ASN1_PCTX *ctx) -+{ -+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); -+} -+ -+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, -+ ASN1_PCTX *ctx) -+{ -+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); -+} -+ -+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, -+ ASN1_PCTX *ctx) -+{ -+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); -+} -+ -+static int old_ec_priv_decode(EVP_PKEY *pkey, -+ const unsigned char **pder, int derlen) -+{ -+ EC_KEY *ec; -+ if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { -+ ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); -+ return 0; -+ } -+ EVP_PKEY_assign_EC_KEY(pkey, ec); -+ return 1; -+} -+ -+static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) -+{ -+ return i2d_ECPrivateKey(pkey->pkey.ec, pder); -+} -+ -+static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -+{ -+ switch (op) { -+ case ASN1_PKEY_CTRL_PKCS7_SIGN: -+ if (arg1 == 0) { -+ int snid, hnid; -+ X509_ALGOR *alg1, *alg2; -+ PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); -+ if (alg1 == NULL || alg1->algorithm == NULL) -+ return -1; -+ hnid = OBJ_obj2nid(alg1->algorithm); -+ if (hnid == NID_undef) -+ return -1; -+ if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) -+ return -1; -+ X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); -+ } -+ return 1; -+#ifndef OPENSSL_NO_CMS -+ case ASN1_PKEY_CTRL_CMS_SIGN: -+ if (arg1 == 0) { -+ int snid, hnid; -+ X509_ALGOR *alg1, *alg2; -+ CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); -+ if (alg1 == NULL || alg1->algorithm == NULL) -+ return -1; -+ hnid = OBJ_obj2nid(alg1->algorithm); -+ if (hnid == NID_undef) -+ return -1; -+ if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) -+ return -1; -+ X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); -+ } -+ return 1; -+ -+ case ASN1_PKEY_CTRL_CMS_ENVELOPE: -+ if (arg1 == 1) -+ return ecdh_cms_decrypt(arg2); -+ else if (arg1 == 0) -+ return ecdh_cms_encrypt(arg2); -+ return -2; -+ -+ case ASN1_PKEY_CTRL_CMS_RI_TYPE: -+ *(int *)arg2 = CMS_RECIPINFO_AGREE; -+ return 1; -+#endif -+ -+ case ASN1_PKEY_CTRL_DEFAULT_MD_NID: -+ /* For SM2, the only valid digest-alg is SM3 */ -+ *(int *)arg2 = NID_sm3; -+ return 1; -+ -+ default: -+ return -2; -+ -+ } -+ -+} -+ -+const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { -+ EVP_PKEY_EC, -+ EVP_PKEY_EC, -+ 0, -+ "EC", -+ "OpenSSL EC 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 -+}; -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_asn1.c b/Cryptlib/OpenSSL/crypto/ec/ec_asn1.c -new file mode 100644 -index 0000000..cc0ce8e ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_asn1.c -@@ -0,0 +1,1278 @@ -+/* crypto/ec/ec_asn1.c */ -+/* -+ * Written by Nils Larsch for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 2000-2003 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 -+ * licensing@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 -+#include "ec_lcl.h" -+#include -+#include -+#include -+ -+int EC_GROUP_get_basis_type(const EC_GROUP *group) -+{ -+ int i = 0; -+ -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != -+ NID_X9_62_characteristic_two_field) -+ /* everything else is currently not supported */ -+ return 0; -+ -+ while (group->poly[i] != 0) -+ i++; -+ -+ if (i == 4) -+ return NID_X9_62_ppBasis; -+ else if (i == 2) -+ return NID_X9_62_tpBasis; -+ else -+ /* everything else is currently not supported */ -+ return 0; -+} -+ -+/* some structures needed for the asn1 encoding */ -+typedef struct x9_62_pentanomial_st { -+ long k1; -+ long k2; -+ long k3; -+} X9_62_PENTANOMIAL; -+ -+typedef struct x9_62_characteristic_two_st { -+ long m; -+ ASN1_OBJECT *type; -+ union { -+ char *ptr; -+ /* NID_X9_62_onBasis */ -+ ASN1_NULL *onBasis; -+ /* NID_X9_62_tpBasis */ -+ ASN1_INTEGER *tpBasis; -+ /* NID_X9_62_ppBasis */ -+ X9_62_PENTANOMIAL *ppBasis; -+ /* anything else */ -+ ASN1_TYPE *other; -+ } p; -+} X9_62_CHARACTERISTIC_TWO; -+ -+typedef struct x9_62_fieldid_st { -+ ASN1_OBJECT *fieldType; -+ union { -+ char *ptr; -+ /* NID_X9_62_prime_field */ -+ ASN1_INTEGER *prime; -+ /* NID_X9_62_characteristic_two_field */ -+ X9_62_CHARACTERISTIC_TWO *char_two; -+ /* anything else */ -+ ASN1_TYPE *other; -+ } p; -+} X9_62_FIELDID; -+ -+typedef struct x9_62_curve_st { -+ ASN1_OCTET_STRING *a; -+ ASN1_OCTET_STRING *b; -+ ASN1_BIT_STRING *seed; -+} X9_62_CURVE; -+ -+typedef struct ec_parameters_st { -+ long version; -+ X9_62_FIELDID *fieldID; -+ X9_62_CURVE *curve; -+ ASN1_OCTET_STRING *base; -+ ASN1_INTEGER *order; -+ ASN1_INTEGER *cofactor; -+} ECPARAMETERS; -+ -+struct ecpk_parameters_st { -+ int type; -+ union { -+ ASN1_OBJECT *named_curve; -+ ECPARAMETERS *parameters; -+ ASN1_NULL *implicitlyCA; -+ } value; -+} /* ECPKPARAMETERS */ ; -+ -+/* SEC1 ECPrivateKey */ -+typedef struct ec_privatekey_st { -+ long version; -+ ASN1_OCTET_STRING *privateKey; -+ ECPKPARAMETERS *parameters; -+ ASN1_BIT_STRING *publicKey; -+} EC_PRIVATEKEY; -+ -+/* the OpenSSL ASN.1 definitions */ -+ASN1_SEQUENCE(X9_62_PENTANOMIAL) = { -+ ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), -+ ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), -+ ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG) -+} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) -+ -+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) -+ -+ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); -+ -+ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { -+ ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), -+ ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), -+ ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) -+} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); -+ -+ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { -+ ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), -+ ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), -+ ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) -+} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) -+ -+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) -+ -+ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); -+ -+ASN1_ADB(X9_62_FIELDID) = { -+ ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), -+ ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) -+} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); -+ -+ASN1_SEQUENCE(X9_62_FIELDID) = { -+ ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), -+ ASN1_ADB_OBJECT(X9_62_FIELDID) -+} ASN1_SEQUENCE_END(X9_62_FIELDID) -+ -+ASN1_SEQUENCE(X9_62_CURVE) = { -+ ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), -+ ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), -+ ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) -+} ASN1_SEQUENCE_END(X9_62_CURVE) -+ -+ASN1_SEQUENCE(ECPARAMETERS) = { -+ ASN1_SIMPLE(ECPARAMETERS, version, LONG), -+ ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), -+ ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), -+ ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), -+ ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), -+ ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) -+} ASN1_SEQUENCE_END(ECPARAMETERS) -+ -+DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) -+ -+ASN1_CHOICE(ECPKPARAMETERS) = { -+ ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), -+ ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), -+ ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) -+} ASN1_CHOICE_END(ECPKPARAMETERS) -+ -+DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) -+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) -+IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) -+ -+ASN1_SEQUENCE(EC_PRIVATEKEY) = { -+ ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), -+ ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), -+ ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), -+ ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) -+} ASN1_SEQUENCE_END(EC_PRIVATEKEY) -+ -+DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) -+DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) -+IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) -+ -+/* some declarations of internal function */ -+ -+/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ -+static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); -+/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ -+static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); -+/* -+ * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS -+ * object -+ */ -+static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); -+/* -+ * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP -+ * object -+ */ -+static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, -+ ECPARAMETERS *); -+/* -+ * ec_asn1_pkparameters2group() creates a EC_GROUP object from a -+ * ECPKPARAMETERS object -+ */ -+static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); -+/* -+ * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a -+ * EC_GROUP object -+ */ -+static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, -+ ECPKPARAMETERS *); -+ -+/* the function definitions */ -+ -+static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) -+{ -+ int ok = 0, nid; -+ BIGNUM *tmp = NULL; -+ -+ if (group == NULL || field == NULL) -+ return 0; -+ -+ /* clear the old values (if necessary) */ -+ if (field->fieldType != NULL) -+ ASN1_OBJECT_free(field->fieldType); -+ if (field->p.other != NULL) -+ ASN1_TYPE_free(field->p.other); -+ -+ nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); -+ /* set OID for the field */ -+ if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); -+ goto err; -+ } -+ -+ if (nid == NID_X9_62_prime_field) { -+ if ((tmp = BN_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ /* the parameters are specified by the prime number p */ -+ if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); -+ goto err; -+ } -+ /* set the prime number */ -+ field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); -+ if (field->p.prime == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ } else /* nid == NID_X9_62_characteristic_two_field */ -+#ifdef OPENSSL_NO_EC2M -+ { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); -+ goto err; -+ } -+#else -+ { -+ int field_type; -+ X9_62_CHARACTERISTIC_TWO *char_two; -+ -+ field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); -+ char_two = field->p.char_two; -+ -+ if (char_two == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ char_two->m = (long)EC_GROUP_get_degree(group); -+ -+ field_type = EC_GROUP_get_basis_type(group); -+ -+ if (field_type == 0) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); -+ goto err; -+ } -+ /* set base type OID */ -+ if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); -+ goto err; -+ } -+ -+ if (field_type == NID_X9_62_tpBasis) { -+ unsigned int k; -+ -+ if (!EC_GROUP_get_trinomial_basis(group, &k)) -+ goto err; -+ -+ char_two->p.tpBasis = ASN1_INTEGER_new(); -+ if (!char_two->p.tpBasis) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ } else if (field_type == NID_X9_62_ppBasis) { -+ unsigned int k1, k2, k3; -+ -+ if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) -+ goto err; -+ -+ char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); -+ if (!char_two->p.ppBasis) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* set k? values */ -+ char_two->p.ppBasis->k1 = (long)k1; -+ char_two->p.ppBasis->k2 = (long)k2; -+ char_two->p.ppBasis->k3 = (long)k3; -+ } else { /* field_type == NID_X9_62_onBasis */ -+ -+ /* for ONB the parameters are (asn1) NULL */ -+ char_two->p.onBasis = ASN1_NULL_new(); -+ if (!char_two->p.onBasis) { -+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ } -+#endif -+ -+ ok = 1; -+ -+ err:if (tmp) -+ BN_free(tmp); -+ return (ok); -+} -+ -+static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) -+{ -+ int ok = 0, nid; -+ BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; -+ unsigned char *buffer_1 = NULL, *buffer_2 = NULL, -+ *a_buf = NULL, *b_buf = NULL; -+ size_t len_1, len_2; -+ unsigned char char_zero = 0; -+ -+ if (!group || !curve || !curve->a || !curve->b) -+ return 0; -+ -+ if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); -+ -+ /* get a and b */ -+ if (nid == NID_X9_62_prime_field) { -+ if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#ifndef OPENSSL_NO_EC2M -+ else { /* nid == NID_X9_62_characteristic_two_field */ -+ -+ if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#endif -+ len_1 = (size_t)BN_num_bytes(tmp_1); -+ len_2 = (size_t)BN_num_bytes(tmp_2); -+ -+ if (len_1 == 0) { -+ /* len_1 == 0 => a == 0 */ -+ a_buf = &char_zero; -+ len_1 = 1; -+ } else { -+ if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); -+ goto err; -+ } -+ a_buf = buffer_1; -+ } -+ -+ if (len_2 == 0) { -+ /* len_2 == 0 => b == 0 */ -+ b_buf = &char_zero; -+ len_2 = 1; -+ } else { -+ if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); -+ goto err; -+ } -+ b_buf = buffer_2; -+ } -+ -+ /* set a and b */ -+ if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || -+ !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ -+ /* set the seed (optional) */ -+ if (group->seed) { -+ if (!curve->seed) -+ if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); -+ curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; -+ if (!ASN1_BIT_STRING_set(curve->seed, group->seed, -+ (int)group->seed_len)) { -+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ } else { -+ if (curve->seed) { -+ ASN1_BIT_STRING_free(curve->seed); -+ curve->seed = NULL; -+ } -+ } -+ -+ ok = 1; -+ -+ err:if (buffer_1) -+ OPENSSL_free(buffer_1); -+ if (buffer_2) -+ OPENSSL_free(buffer_2); -+ if (tmp_1) -+ BN_free(tmp_1); -+ if (tmp_2) -+ BN_free(tmp_2); -+ return (ok); -+} -+ -+static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, -+ ECPARAMETERS *param) -+{ -+ int ok = 0; -+ size_t len = 0; -+ ECPARAMETERS *ret = NULL; -+ BIGNUM *tmp = NULL; -+ unsigned char *buffer = NULL; -+ const EC_POINT *point = NULL; -+ point_conversion_form_t form; -+ -+ if ((tmp = BN_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (param == NULL) { -+ if ((ret = ECPARAMETERS_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } else -+ ret = param; -+ -+ /* set the version (always one) */ -+ ret->version = (long)0x1; -+ -+ /* set the fieldID */ -+ if (!ec_asn1_group2fieldid(group, ret->fieldID)) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* set the curve */ -+ if (!ec_asn1_group2curve(group, ret->curve)) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* set the base point */ -+ if ((point = EC_GROUP_get0_generator(group)) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); -+ goto err; -+ } -+ -+ form = EC_GROUP_get_point_conversion_form(group); -+ -+ len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); -+ if (len == 0) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); -+ goto err; -+ } -+ if ((buffer = OPENSSL_malloc(len)) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ -+ /* set the order */ -+ if (!EC_GROUP_get_order(group, tmp, NULL)) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); -+ goto err; -+ } -+ ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); -+ if (ret->order == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ -+ /* set the cofactor (optional) */ -+ if (EC_GROUP_get_cofactor(group, tmp, NULL)) { -+ ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); -+ if (ret->cofactor == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ } -+ -+ ok = 1; -+ -+ err:if (!ok) { -+ if (ret && !param) -+ ECPARAMETERS_free(ret); -+ ret = NULL; -+ } -+ if (tmp) -+ BN_free(tmp); -+ if (buffer) -+ OPENSSL_free(buffer); -+ return (ret); -+} -+ -+ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, -+ ECPKPARAMETERS *params) -+{ -+ int ok = 1, tmp; -+ ECPKPARAMETERS *ret = params; -+ -+ if (ret == NULL) { -+ if ((ret = ECPKPARAMETERS_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ } else { -+ if (ret->type == 0 && ret->value.named_curve) -+ ASN1_OBJECT_free(ret->value.named_curve); -+ else if (ret->type == 1 && ret->value.parameters) -+ ECPARAMETERS_free(ret->value.parameters); -+ } -+ -+ if (EC_GROUP_get_asn1_flag(group)) { -+ /* -+ * use the asn1 OID to describe the the elliptic curve parameters -+ */ -+ tmp = EC_GROUP_get_curve_name(group); -+ if (tmp) { -+ ret->type = 0; -+ if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) -+ ok = 0; -+ } else -+ /* we don't kmow the nid => ERROR */ -+ ok = 0; -+ } else { -+ /* use the ECPARAMETERS structure */ -+ ret->type = 1; -+ if ((ret->value.parameters = -+ ec_asn1_group2parameters(group, NULL)) == NULL) -+ ok = 0; -+ } -+ -+ if (!ok) { -+ ECPKPARAMETERS_free(ret); -+ return NULL; -+ } -+ return ret; -+} -+ -+static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) -+{ -+ int ok = 0, tmp; -+ EC_GROUP *ret = NULL; -+ BIGNUM *p = NULL, *a = NULL, *b = NULL; -+ EC_POINT *point = NULL; -+ long field_bits; -+ -+ if (!params->fieldID || !params->fieldID->fieldType || -+ !params->fieldID->p.ptr) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ goto err; -+ } -+ -+ /* now extract the curve parameters a and b */ -+ if (!params->curve || !params->curve->a || -+ !params->curve->a->data || !params->curve->b || -+ !params->curve->b->data) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ goto err; -+ } -+ a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); -+ if (a == NULL) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); -+ goto err; -+ } -+ b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); -+ if (b == NULL) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ /* get the field parameters */ -+ tmp = OBJ_obj2nid(params->fieldID->fieldType); -+ if (tmp == NID_X9_62_characteristic_two_field) -+#ifdef OPENSSL_NO_EC2M -+ { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED); -+ goto err; -+ } -+#else -+ { -+ X9_62_CHARACTERISTIC_TWO *char_two; -+ -+ char_two = params->fieldID->p.char_two; -+ -+ field_bits = char_two->m; -+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); -+ goto err; -+ } -+ -+ if ((p = BN_new()) == NULL) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* get the base type */ -+ tmp = OBJ_obj2nid(char_two->type); -+ -+ if (tmp == NID_X9_62_tpBasis) { -+ long tmp_long; -+ -+ if (!char_two->p.tpBasis) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ goto err; -+ } -+ -+ tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); -+ -+ if (!(char_two->m > tmp_long && tmp_long > 0)) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, -+ EC_R_INVALID_TRINOMIAL_BASIS); -+ goto err; -+ } -+ -+ /* create the polynomial */ -+ if (!BN_set_bit(p, (int)char_two->m)) -+ goto err; -+ if (!BN_set_bit(p, (int)tmp_long)) -+ goto err; -+ if (!BN_set_bit(p, 0)) -+ goto err; -+ } else if (tmp == NID_X9_62_ppBasis) { -+ X9_62_PENTANOMIAL *penta; -+ -+ penta = char_two->p.ppBasis; -+ if (!penta) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ goto err; -+ } -+ -+ if (! -+ (char_two->m > penta->k3 && penta->k3 > penta->k2 -+ && penta->k2 > penta->k1 && penta->k1 > 0)) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, -+ EC_R_INVALID_PENTANOMIAL_BASIS); -+ goto err; -+ } -+ -+ /* create the polynomial */ -+ if (!BN_set_bit(p, (int)char_two->m)) -+ goto err; -+ if (!BN_set_bit(p, (int)penta->k1)) -+ goto err; -+ if (!BN_set_bit(p, (int)penta->k2)) -+ goto err; -+ if (!BN_set_bit(p, (int)penta->k3)) -+ goto err; -+ if (!BN_set_bit(p, 0)) -+ goto err; -+ } else if (tmp == NID_X9_62_onBasis) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); -+ goto err; -+ } else { /* error */ -+ -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ goto err; -+ } -+ -+ /* create the EC_GROUP structure */ -+ ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); -+ } -+#endif -+ else if (tmp == NID_X9_62_prime_field) { -+ /* we have a curve over a prime field */ -+ /* extract the prime number */ -+ if (!params->fieldID->p.prime) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ goto err; -+ } -+ p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); -+ if (p == NULL) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ -+ if (BN_is_negative(p) || BN_is_zero(p)) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); -+ goto err; -+ } -+ -+ field_bits = BN_num_bits(p); -+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); -+ goto err; -+ } -+ -+ /* create the EC_GROUP structure */ -+ ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); -+ } else { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); -+ goto err; -+ } -+ -+ if (ret == NULL) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* extract seed (optional) */ -+ if (params->curve->seed != NULL) { -+ if (ret->seed != NULL) -+ OPENSSL_free(ret->seed); -+ if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ memcpy(ret->seed, params->curve->seed->data, -+ params->curve->seed->length); -+ ret->seed_len = params->curve->seed->length; -+ } -+ -+ if (!params->order || !params->base || !params->base->data) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ goto err; -+ } -+ -+ if ((point = EC_POINT_new(ret)) == NULL) -+ goto err; -+ -+ /* set the point conversion form */ -+ EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) -+ (params->base->data[0] & ~0x01)); -+ -+ /* extract the ec point */ -+ if (!EC_POINT_oct2point(ret, point, params->base->data, -+ params->base->length, NULL)) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ /* extract the order */ -+ if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ if (BN_is_negative(a) || BN_is_zero(a)) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); -+ goto err; -+ } -+ if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); -+ goto err; -+ } -+ -+ /* extract the cofactor (optional) */ -+ if (params->cofactor == NULL) { -+ if (b) { -+ BN_free(b); -+ b = NULL; -+ } -+ } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ /* set the generator, order and cofactor (if present) */ -+ if (!EC_GROUP_set_generator(ret, point, a, b)) { -+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ ok = 1; -+ -+ err:if (!ok) { -+ if (ret) -+ EC_GROUP_clear_free(ret); -+ ret = NULL; -+ } -+ -+ if (p) -+ BN_free(p); -+ if (a) -+ BN_free(a); -+ if (b) -+ BN_free(b); -+ if (point) -+ EC_POINT_free(point); -+ return (ret); -+} -+ -+EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) -+{ -+ EC_GROUP *ret = NULL; -+ int tmp = 0; -+ -+ if (params == NULL) { -+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS); -+ return NULL; -+ } -+ -+ if (params->type == 0) { /* the curve is given by an OID */ -+ tmp = OBJ_obj2nid(params->value.named_curve); -+ if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { -+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, -+ EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); -+ return NULL; -+ } -+ EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); -+ } else if (params->type == 1) { /* the parameters are given by a -+ * ECPARAMETERS structure */ -+ ret = ec_asn1_parameters2group(params->value.parameters); -+ if (!ret) { -+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); -+ return NULL; -+ } -+ EC_GROUP_set_asn1_flag(ret, 0x0); -+ } else if (params->type == 2) { /* implicitlyCA */ -+ return NULL; -+ } else { -+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); -+ return NULL; -+ } -+ -+ return ret; -+} -+ -+/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ -+ -+EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) -+{ -+ EC_GROUP *group = NULL; -+ ECPKPARAMETERS *params = NULL; -+ const unsigned char *p = *in; -+ -+ if ((params = d2i_ECPKPARAMETERS(NULL, &p, 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); -+ *in = p; -+ return (group); -+} -+ -+int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) -+{ -+ int ret = 0; -+ ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); -+ if (tmp == NULL) { -+ ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); -+ return 0; -+ } -+ if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { -+ ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); -+ ECPKPARAMETERS_free(tmp); -+ return 0; -+ } -+ ECPKPARAMETERS_free(tmp); -+ return (ret); -+} -+ -+/* some EC_KEY functions */ -+ -+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) -+{ -+ int ok = 0; -+ EC_KEY *ret = NULL; -+ EC_PRIVATEKEY *priv_key = NULL; -+ const unsigned char *p = *in; -+ -+ if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); -+ return NULL; -+ } -+ -+ if (a == NULL || *a == NULL) { -+ if ((ret = EC_KEY_new()) == NULL) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } else -+ ret = *a; -+ -+ if (priv_key->parameters) { -+ if (ret->group) -+ EC_GROUP_clear_free(ret->group); -+ ret->group = ec_asn1_pkparameters2group(priv_key->parameters); -+ } -+ -+ if (ret->group == NULL) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ ret->version = priv_key->version; -+ -+ if (priv_key->privateKey) { -+ ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey), -+ M_ASN1_STRING_length(priv_key->privateKey), -+ ret->priv_key); -+ if (ret->priv_key == NULL) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB); -+ goto err; -+ } -+ } else { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY); -+ goto err; -+ } -+ -+ if (ret->pub_key) -+ EC_POINT_clear_free(ret->pub_key); -+ ret->pub_key = EC_POINT_new(ret->group); -+ if (ret->pub_key == NULL) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ if (priv_key->publicKey) { -+ const unsigned char *pub_oct; -+ int pub_oct_len; -+ -+ pub_oct = M_ASN1_STRING_data(priv_key->publicKey); -+ pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); -+ /* -+ * The first byte - point conversion form - must be present. -+ */ -+ if (pub_oct_len <= 0) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); -+ goto err; -+ } -+ /* Save the point conversion form. */ -+ ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); -+ if (!EC_POINT_oct2point(ret->group, ret->pub_key, -+ pub_oct, (size_t)(pub_oct_len), NULL)) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ } else { -+ if (!EC_POINT_mul -+ (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) { -+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ /* Remember the original private-key-only encoding. */ -+ ret->enc_flag |= EC_PKEY_NO_PUBKEY; -+ } -+ -+ if (a) -+ *a = ret; -+ *in = p; -+ ok = 1; -+ err: -+ if (!ok) { -+ if (ret && (a == NULL || *a != ret)) -+ EC_KEY_free(ret); -+ ret = NULL; -+ } -+ -+ if (priv_key) -+ EC_PRIVATEKEY_free(priv_key); -+ -+ return (ret); -+} -+ -+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) -+{ -+ int ret = 0, ok = 0; -+ unsigned char *buffer = NULL; -+ size_t buf_len = 0, tmp_len, bn_len; -+ EC_PRIVATEKEY *priv_key = NULL; -+ -+ if (a == NULL || a->group == NULL || a->priv_key == NULL || -+ (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); -+ goto err; -+ } -+ -+ if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ priv_key->version = a->version; -+ -+ bn_len = (size_t)BN_num_bytes(a->priv_key); -+ -+ /* Octetstring may need leading zeros if BN is to short */ -+ -+ buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; -+ -+ if (bn_len > buf_len) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); -+ goto err; -+ } -+ -+ buffer = OPENSSL_malloc(buf_len); -+ if (buffer == NULL) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ if (buf_len - bn_len > 0) { -+ memset(buffer, 0, buf_len - bn_len); -+ } -+ -+ if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ -+ if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { -+ if ((priv_key->parameters = -+ ec_asn1_group2pkparameters(a->group, -+ priv_key->parameters)) == NULL) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+ -+ if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { -+ priv_key->publicKey = M_ASN1_BIT_STRING_new(); -+ if (priv_key->publicKey == NULL) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ tmp_len = EC_POINT_point2oct(a->group, a->pub_key, -+ a->conv_form, NULL, 0, NULL); -+ -+ if (tmp_len > buf_len) { -+ unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); -+ if (!tmp_buffer) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ buffer = tmp_buffer; -+ buf_len = tmp_len; -+ } -+ -+ if (!EC_POINT_point2oct(a->group, a->pub_key, -+ a->conv_form, buffer, buf_len, NULL)) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); -+ priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; -+ if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ } -+ -+ if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { -+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ ok = 1; -+ err: -+ if (buffer) -+ OPENSSL_free(buffer); -+ if (priv_key) -+ EC_PRIVATEKEY_free(priv_key); -+ return (ok ? ret : 0); -+} -+ -+int i2d_ECParameters(EC_KEY *a, unsigned char **out) -+{ -+ if (a == NULL) { -+ ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ return i2d_ECPKParameters(a->group, out); -+} -+ -+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) -+{ -+ EC_KEY *ret; -+ -+ if (in == NULL || *in == NULL) { -+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); -+ return NULL; -+ } -+ -+ if (a == NULL || *a == NULL) { -+ if ((ret = EC_KEY_new()) == NULL) { -+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ } else -+ ret = *a; -+ -+ if (!d2i_ECPKParameters(&ret->group, in, len)) { -+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); -+ if (a == NULL || *a != ret) -+ EC_KEY_free(ret); -+ return NULL; -+ } -+ -+ if (a) -+ *a = ret; -+ -+ return ret; -+} -+ -+EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) -+{ -+ EC_KEY *ret = NULL; -+ -+ if (a == NULL || (*a) == NULL || (*a)->group == NULL) { -+ /* -+ * sorry, but a EC_GROUP-structur is necessary to set the public key -+ */ -+ ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ ret = *a; -+ if (ret->pub_key == NULL && -+ (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { -+ ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { -+ ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); -+ return 0; -+ } -+ /* save the point conversion form */ -+ ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); -+ *in += len; -+ return ret; -+} -+ -+int i2o_ECPublicKey(EC_KEY *a, unsigned char **out) -+{ -+ size_t buf_len = 0; -+ int new_buffer = 0; -+ -+ if (a == NULL) { -+ ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ -+ buf_len = EC_POINT_point2oct(a->group, a->pub_key, -+ a->conv_form, NULL, 0, NULL); -+ -+ if (out == NULL || buf_len == 0) -+ /* out == NULL => just return the length of the octet string */ -+ return buf_len; -+ -+ if (*out == NULL) { -+ if ((*out = OPENSSL_malloc(buf_len)) == NULL) { -+ ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ new_buffer = 1; -+ } -+ if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, -+ *out, buf_len, NULL)) { -+ ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); -+ if (new_buffer) { -+ OPENSSL_free(*out); -+ *out = NULL; -+ } -+ return 0; -+ } -+ if (!new_buffer) -+ *out += buf_len; -+ return buf_len; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_check.c b/Cryptlib/OpenSSL/crypto/ec/ec_check.c -new file mode 100644 -index 0000000..dd6f0ac ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_check.c -@@ -0,0 +1,120 @@ -+/* crypto/ec/ec_check.c */ -+/* ==================================================================== -+ * 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 "ec_lcl.h" -+#include -+ -+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) -+{ -+ int ret = 0; -+ BIGNUM *order; -+ BN_CTX *new_ctx = NULL; -+ EC_POINT *point = NULL; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) { -+ ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ BN_CTX_start(ctx); -+ if ((order = BN_CTX_get(ctx)) == NULL) -+ goto err; -+ -+ /* check the discriminant */ -+ if (!EC_GROUP_check_discriminant(group, ctx)) { -+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO); -+ goto err; -+ } -+ -+ /* check the generator */ -+ if (group->generator == NULL) { -+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); -+ goto err; -+ } -+ if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { -+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); -+ goto err; -+ } -+ -+ /* check the order of the generator */ -+ if ((point = EC_POINT_new(group)) == NULL) -+ goto err; -+ if (!EC_GROUP_get_order(group, order, ctx)) -+ goto err; -+ if (BN_is_zero(order)) { -+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER); -+ goto err; -+ } -+ -+ if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) -+ goto err; -+ if (!EC_POINT_is_at_infinity(group, point)) { -+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER); -+ goto err; -+ } -+ -+ ret = 1; -+ -+ err: -+ if (ctx != NULL) -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ if (point) -+ EC_POINT_free(point); -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_curve.c b/Cryptlib/OpenSSL/crypto/ec/ec_curve.c -new file mode 100644 -index 0000000..0ec05f8 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_curve.c -@@ -0,0 +1,343 @@ -+/* crypto/ec/ec_curve.c */ -+/* -+ * Written by Nils Larsch for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2010 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * -+ * Portions of the attached software ("Contribution") are developed by -+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. -+ * -+ * The Contribution is licensed pursuant to the OpenSSL open source -+ * license provided above. -+ * -+ * The elliptic curve binary polynomial software is originally written by -+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. -+ * -+ */ -+ -+#include -+#include "ec_lcl.h" -+#include -+#include -+#include -+ -+#ifdef OPENSSL_FIPS -+# include -+#endif -+ -+typedef struct { -+ int field_type, /* either NID_X9_62_prime_field or -+ * NID_X9_62_characteristic_two_field */ -+ seed_len, param_len; -+ unsigned int cofactor; /* promoted to BN_ULONG */ -+} EC_CURVE_DATA; -+ -+#ifndef OPENSSL_NO_SM2 -+static const struct { -+ EC_CURVE_DATA h; -+ unsigned char data[0 + 32 * 6]; -+} _EC_sm2p256v1 = { -+ { -+ NID_X9_62_prime_field, 0, 32, 1 -+ }, -+ { -+ /* no seed */ -+ -+ /* p */ -+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ /* a */ -+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, -+ /* b */ -+ 0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b, -+ 0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92, -+ 0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93, -+ /* x */ -+ 0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46, -+ 0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1, -+ 0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7, -+ /* y */ -+ 0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3, -+ 0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40, -+ 0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0, -+ /* order */ -+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, 0x72, 0x03, 0xdf, 0x6b, 0x21, 0xc6, 0x05, 0x2b, -+ 0x53, 0xbb, 0xf4, 0x09, 0x39, 0xd5, 0x41, 0x23, -+ } -+}; -+#endif /* OPENSSL_NO_SM2 */ -+ -+typedef struct _ec_list_element_st { -+ int nid; -+ const EC_CURVE_DATA *data; -+ const EC_METHOD *(*meth) (void); -+ const char *comment; -+} ec_list_element; -+ -+static const ec_list_element curve_list[] = { -+ /* prime field curves */ -+ /* secg curves */ -+#ifndef OPENSSL_NO_SM2 -+ {NID_sm2, &_EC_sm2p256v1.h, 0, -+ "SM2 curve over a 256 bit prime field"}, -+#endif -+}; -+ -+#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element)) -+ -+static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) -+{ -+ EC_GROUP *group = NULL; -+ EC_POINT *P = NULL; -+ BN_CTX *ctx = NULL; -+ BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = -+ NULL; -+ int ok = 0; -+ int seed_len, param_len; -+ const EC_METHOD *meth; -+ const EC_CURVE_DATA *data; -+ const unsigned char *params; -+ -+ if ((ctx = BN_CTX_new()) == NULL) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ data = curve.data; -+ seed_len = data->seed_len; -+ param_len = data->param_len; -+ params = (const unsigned char *)(data + 1); /* skip header */ -+ params += seed_len; /* skip seed */ -+ -+ if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) -+ || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) -+ || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ if (curve.meth != 0) { -+ meth = curve.meth(); -+ if (((group = EC_GROUP_new(meth)) == NULL) || -+ (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); -+ goto err; -+ } -+ } else if (data->field_type == NID_X9_62_prime_field) { -+ if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#ifndef OPENSSL_NO_EC2M -+ else { /* field_type == -+ * NID_X9_62_characteristic_two_field */ -+ -+ if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#endif -+ -+ if ((P = EC_POINT_new(group)) == NULL) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) -+ || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); -+ goto err; -+ } -+ if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) -+ || !BN_set_word(x, (BN_ULONG)data->cofactor)) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); -+ goto err; -+ } -+ if (!EC_GROUP_set_generator(group, P, order, x)) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (seed_len) { -+ if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) { -+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+ ok = 1; -+ err: -+ if (!ok) { -+ EC_GROUP_free(group); -+ group = NULL; -+ } -+ if (P) -+ EC_POINT_free(P); -+ if (ctx) -+ BN_CTX_free(ctx); -+ if (p) -+ BN_free(p); -+ if (a) -+ BN_free(a); -+ if (b) -+ BN_free(b); -+ if (order) -+ BN_free(order); -+ if (x) -+ BN_free(x); -+ if (y) -+ BN_free(y); -+ return group; -+} -+ -+EC_GROUP *EC_GROUP_new_by_curve_name(int nid) -+{ -+ size_t i; -+ EC_GROUP *ret = NULL; -+ -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode()) -+ return FIPS_ec_group_new_by_curve_name(nid); -+#endif -+ if (nid <= 0) -+ return NULL; -+ -+ for (i = 0; i < curve_list_length; i++) -+ if (curve_list[i].nid == nid) { -+ ret = ec_group_new_from_data(curve_list[i]); -+ break; -+ } -+ -+ if (ret == NULL) { -+ ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); -+ return NULL; -+ } -+ -+ EC_GROUP_set_curve_name(ret, nid); -+ -+ return ret; -+} -+ -+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) -+{ -+ size_t i, min; -+ -+ if (r == NULL || nitems == 0) -+ return curve_list_length; -+ -+ min = nitems < curve_list_length ? nitems : curve_list_length; -+ -+ for (i = 0; i < min; i++) { -+ r[i].nid = curve_list[i].nid; -+ r[i].comment = curve_list[i].comment; -+ } -+ -+ return curve_list_length; -+} -+ -+/* Functions to translate between common NIST curve names and NIDs */ -+ -+typedef struct { -+ const char *name; /* NIST Name of curve */ -+ int nid; /* Curve NID */ -+} EC_NIST_NAME; -+ -+static EC_NIST_NAME nist_curves[] = { -+ {"B-163", NID_sect163r2}, -+ {"B-233", NID_sect233r1}, -+ {"B-283", NID_sect283r1}, -+ {"B-409", NID_sect409r1}, -+ {"B-571", NID_sect571r1}, -+ {"K-163", NID_sect163k1}, -+ {"K-233", NID_sect233k1}, -+ {"K-283", NID_sect283k1}, -+ {"K-409", NID_sect409k1}, -+ {"K-571", NID_sect571k1}, -+ {"P-192", NID_X9_62_prime192v1}, -+ {"P-224", NID_secp224r1}, -+ {"P-256", NID_X9_62_prime256v1}, -+ {"P-384", NID_secp384r1}, -+ {"P-521", NID_secp521r1} -+}; -+ -+const char *EC_curve_nid2nist(int nid) -+{ -+ size_t i; -+ for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { -+ if (nist_curves[i].nid == nid) -+ return nist_curves[i].name; -+ } -+ return NULL; -+} -+ -+int EC_curve_nist2nid(const char *name) -+{ -+ size_t i; -+ for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { -+ if (!strcmp(nist_curves[i].name, name)) -+ return nist_curves[i].nid; -+ } -+ return NID_undef; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_cvt.c b/Cryptlib/OpenSSL/crypto/ec/ec_cvt.c -new file mode 100644 -index 0000000..5fa68c2 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_cvt.c -@@ -0,0 +1,154 @@ -+/* crypto/ec/ec_cvt.c */ -+/* -+ * Originally written by Bodo Moeller for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * -+ * Portions of the attached software ("Contribution") are developed by -+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. -+ * -+ * The Contribution is licensed pursuant to the OpenSSL open source -+ * license provided above. -+ * -+ * The elliptic curve binary polynomial software is originally written by -+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. -+ * -+ */ -+ -+#include -+#include "ec_lcl.h" -+ -+#ifdef OPENSSL_FIPS -+# include -+#endif -+ -+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx) -+{ -+ const EC_METHOD *meth; -+ EC_GROUP *ret; -+ -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode()) -+ return FIPS_ec_group_new_curve_gfp(p, a, b, ctx); -+#endif -+#if defined(OPENSSL_BN_ASM_MONT) -+ /* -+ * This might appear controversial, but the fact is that generic -+ * prime method was observed to deliver better performance even -+ * for NIST primes on a range of platforms, e.g.: 60%-15% -+ * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25% -+ * in 32-bit build and 35%--12% in 64-bit build on Core2... -+ * Coefficients are relative to optimized bn_nist.c for most -+ * intensive ECDSA verify and ECDH operations for 192- and 521- -+ * bit keys respectively. Choice of these boundary values is -+ * arguable, because the dependency of improvement coefficient -+ * from key length is not a "monotone" curve. For example while -+ * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's -+ * generally faster, sometimes "respectfully" faster, sometimes -+ * "tolerably" slower... What effectively happens is that loop -+ * with bn_mul_add_words is put against bn_mul_mont, and the -+ * latter "wins" on short vectors. Correct solution should be -+ * implementing dedicated NxN multiplication subroutines for -+ * small N. But till it materializes, let's stick to generic -+ * prime method... -+ * -+ */ -+ meth = EC_GFp_mont_method(); -+#else -+ meth = EC_GFp_nist_method(); -+#endif -+ -+ ret = EC_GROUP_new(meth); -+ if (ret == NULL) -+ return NULL; -+ -+ if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { -+ unsigned long err; -+ -+ err = ERR_peek_last_error(); -+ -+ if (!(ERR_GET_LIB(err) == ERR_LIB_EC && -+ ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) || -+ (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) { -+ /* real error */ -+ -+ EC_GROUP_clear_free(ret); -+ return NULL; -+ } -+ -+ /* -+ * not an actual error, we just cannot use EC_GFp_nist_method -+ */ -+ -+ ERR_clear_error(); -+ -+ EC_GROUP_clear_free(ret); -+ meth = EC_GFp_mont_method(); -+ -+ ret = EC_GROUP_new(meth); -+ if (ret == NULL) -+ return NULL; -+ -+ if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { -+ EC_GROUP_clear_free(ret); -+ return NULL; -+ } -+ } -+ -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_err.c b/Cryptlib/OpenSSL/crypto/ec/ec_err.c -new file mode 100644 -index 0000000..6fe5baa ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_err.c -@@ -0,0 +1,332 @@ -+/* crypto/ec/ec_err.c */ -+/* ==================================================================== -+ * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * 3. All advertising materials mentioning features or use of this -+ * software must display the following acknowledgment: -+ * "This product includes software developed by the OpenSSL Project -+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" -+ * -+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to -+ * endorse or promote products derived from this software without -+ * prior written permission. For written permission, please contact -+ * openssl-core@OpenSSL.org. -+ * -+ * 5. Products derived from this software may not be called "OpenSSL" -+ * nor may "OpenSSL" appear in their names without prior written -+ * permission of the OpenSSL Project. -+ * -+ * 6. Redistributions of any form whatsoever must retain the following -+ * acknowledgment: -+ * "This product includes software developed by the OpenSSL Project -+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY -+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR -+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+ * OF THE POSSIBILITY OF SUCH DAMAGE. -+ * ==================================================================== -+ * -+ * This product includes cryptographic software written by Eric Young -+ * (eay@cryptsoft.com). This product includes software written by Tim -+ * Hudson (tjh@cryptsoft.com). -+ * -+ */ -+ -+/* -+ * NOTE: this file was auto generated by the mkerr.pl script: any changes -+ * made to it will be overwritten when the script next updates this file, -+ * only reason strings will be preserved. -+ */ -+ -+#include -+#include -+#include -+ -+/* BEGIN ERROR CODES */ -+#ifndef OPENSSL_NO_ERR -+ -+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0) -+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason) -+ -+static ERR_STRING_DATA EC_str_functs[] = { -+ {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"}, -+ {ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"}, -+ {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"}, -+ {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"}, -+ {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"}, -+ {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"}, -+ {ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ECDH_CMS_DECRYPT"}, -+ {ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ECDH_CMS_SET_SHARED_INFO"}, -+ {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"}, -+ {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"}, -+ {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"}, -+ {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"}, -+ {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"}, -+ {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"}, -+ {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"}, -+ {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"}, -+ {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"}, -+ {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"}, -+ {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"}, -+ {ERR_FUNC(EC_F_ECP_NISTZ256_GET_AFFINE), "ecp_nistz256_get_affine"}, -+ {ERR_FUNC(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE), -+ "ecp_nistz256_mult_precompute"}, -+ {ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"}, -+ {ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"}, -+ {ERR_FUNC(EC_F_ECP_NISTZ256_SET_WORDS), "ecp_nistz256_set_words"}, -+ {ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"}, -+ {ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"}, -+ {ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"}, -+ {ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"}, -+ {ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"}, -+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"}, -+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"}, -+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"}, -+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"}, -+ {ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"}, -+ {ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"}, -+ {ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"}, -+ {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), -+ "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"}, -+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), -+ "ec_GF2m_simple_group_check_discriminant"}, -+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), -+ "ec_GF2m_simple_group_set_curve"}, -+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"}, -+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"}, -+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), -+ "ec_GF2m_simple_point_get_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), -+ "ec_GF2m_simple_point_set_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), -+ "ec_GF2m_simple_set_compressed_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"}, -+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"}, -+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"}, -+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), -+ "ec_GFp_mont_field_set_to_one"}, -+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"}, -+ {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), -+ "ec_GFp_mont_group_set_curve"}, -+ {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), -+ "EC_GFP_MONT_GROUP_SET_CURVE_GFP"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), -+ "ec_GFp_nistp224_group_set_curve"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), -+ "ec_GFp_nistp224_point_get_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), -+ "ec_GFp_nistp256_group_set_curve"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), -+ "ec_GFp_nistp256_point_get_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), -+ "ec_GFp_nistp521_group_set_curve"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"}, -+ {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), -+ "ec_GFp_nistp521_point_get_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"}, -+ {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"}, -+ {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), -+ "ec_GFp_nist_group_set_curve"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), -+ "ec_GFp_simple_group_check_discriminant"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), -+ "ec_GFp_simple_group_set_curve"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), -+ "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), -+ "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), -+ "ec_GFp_simple_points_make_affine"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), -+ "ec_GFp_simple_point_get_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), -+ "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), -+ "ec_GFp_simple_point_set_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), -+ "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), -+ "ec_GFp_simple_set_compressed_coordinates"}, -+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), -+ "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"}, -+ {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"}, -+ {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), -+ "EC_GROUP_check_discriminant"}, -+ {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), -+ "EC_GROUP_get_pentanomial_basis"}, -+ {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), -+ "EC_GROUP_get_trinomial_basis"}, -+ {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"}, -+ {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"}, -+ {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"}, -+ {ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"}, -+ {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"}, -+ {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"}, -+ {ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"}, -+ {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"}, -+ {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"}, -+ {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"}, -+ {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"}, -+ {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"}, -+ {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"}, -+ {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"}, -+ {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), -+ "EC_KEY_set_public_key_affine_coordinates"}, -+ {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, -+ {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, -+ {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, -+ {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, -+ {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"}, -+ {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), -+ "EC_POINT_get_affine_coordinates_GF2m"}, -+ {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), -+ "EC_POINT_get_affine_coordinates_GFp"}, -+ {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), -+ "EC_POINT_get_Jprojective_coordinates_GFp"}, -+ {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"}, -+ {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"}, -+ {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"}, -+ {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"}, -+ {ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"}, -+ {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"}, -+ {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"}, -+ {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"}, -+ {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), -+ "EC_POINT_set_affine_coordinates_GF2m"}, -+ {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), -+ "EC_POINT_set_affine_coordinates_GFp"}, -+ {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), -+ "EC_POINT_set_compressed_coordinates_GF2m"}, -+ {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), -+ "EC_POINT_set_compressed_coordinates_GFp"}, -+ {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), -+ "EC_POINT_set_Jprojective_coordinates_GFp"}, -+ {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"}, -+ {ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"}, -+ {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"}, -+ {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"}, -+ {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"}, -+ {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"}, -+ {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"}, -+ {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"}, -+ {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"}, -+ {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"}, -+ {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"}, -+ {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"}, -+ {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"}, -+ {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"}, -+ {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_DERIVE), "PKEY_EC_DERIVE"}, -+ {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"}, -+ {0, NULL} -+}; -+ -+static ERR_STRING_DATA EC_str_reasons[] = { -+ {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"}, -+ {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"}, -+ {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"}, -+ {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"}, -+ {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"}, -+ {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), -+ "d2i ecpkparameters failure"}, -+ {ERR_REASON(EC_R_DECODE_ERROR), "decode error"}, -+ {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, -+ {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), -+ "ec group new by name failure"}, -+ {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"}, -+ {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"}, -+ {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), -+ "group2pkparameters failure"}, -+ {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), -+ "i2d ecpkparameters failure"}, -+ {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"}, -+ {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"}, -+ {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, -+ {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"}, -+ {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"}, -+ {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"}, -+ {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"}, -+ {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"}, -+ {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"}, -+ {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, -+ {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, -+ {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, -+ {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, -+ {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"}, -+ {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"}, -+ {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"}, -+ {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"}, -+ {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), -+ "not a supported NIST prime"}, -+ {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"}, -+ {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"}, -+ {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"}, -+ {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"}, -+ {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, -+ {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"}, -+ {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), -+ "pkparameters2group failure"}, -+ {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"}, -+ {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"}, -+ {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"}, -+ {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, -+ {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, -+ {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, -+ {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, -+ {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, -+ {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, -+ {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"}, -+ {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"}, -+ {0, NULL} -+}; -+ -+#endif -+ -+void ERR_load_EC_strings(void) -+{ -+#ifndef OPENSSL_NO_ERR -+ -+ if (ERR_func_error_string(EC_str_functs[0].error) == NULL) { -+ ERR_load_strings(0, EC_str_functs); -+ ERR_load_strings(0, EC_str_reasons); -+ } -+#endif -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_key.c b/Cryptlib/OpenSSL/crypto/ec/ec_key.c -new file mode 100644 -index 0000000..456080e ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_key.c -@@ -0,0 +1,564 @@ -+/* crypto/ec/ec_key.c */ -+/* -+ * 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Portions originally developed by SUN MICROSYSTEMS, INC., and -+ * contributed to the OpenSSL project. -+ */ -+ -+#include -+#include "ec_lcl.h" -+#include -+#ifdef OPENSSL_FIPS -+# include -+#endif -+ -+EC_KEY *EC_KEY_new(void) -+{ -+ EC_KEY *ret; -+ -+ ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); -+ if (ret == NULL) { -+ ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); -+ return (NULL); -+ } -+ -+ ret->version = 1; -+ ret->flags = 0; -+ ret->group = NULL; -+ ret->pub_key = NULL; -+ ret->priv_key = NULL; -+ ret->enc_flag = 0; -+ ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; -+ ret->references = 1; -+ ret->method_data = NULL; -+ return (ret); -+} -+ -+EC_KEY *EC_KEY_new_by_curve_name(int nid) -+{ -+ EC_KEY *ret = EC_KEY_new(); -+ if (ret == NULL) -+ return NULL; -+ ret->group = EC_GROUP_new_by_curve_name(nid); -+ if (ret->group == NULL) { -+ EC_KEY_free(ret); -+ return NULL; -+ } -+ return ret; -+} -+ -+void EC_KEY_free(EC_KEY *r) -+{ -+ int i; -+ -+ if (r == NULL) -+ return; -+ -+ i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); -+#ifdef REF_PRINT -+ REF_PRINT("EC_KEY", r); -+#endif -+ if (i > 0) -+ return; -+#ifdef REF_CHECK -+ if (i < 0) { -+ fprintf(stderr, "EC_KEY_free, bad reference count\n"); -+ abort(); -+ } -+#endif -+ -+ if (r->group != NULL) -+ EC_GROUP_free(r->group); -+ if (r->pub_key != NULL) -+ EC_POINT_free(r->pub_key); -+ if (r->priv_key != NULL) -+ BN_clear_free(r->priv_key); -+ -+ EC_EX_DATA_free_all_data(&r->method_data); -+ -+ OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); -+ -+ OPENSSL_free(r); -+} -+ -+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) -+{ -+ EC_EXTRA_DATA *d; -+ -+ if (dest == NULL || src == NULL) { -+ ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); -+ return NULL; -+ } -+ /* copy the parameters */ -+ if (src->group) { -+ const EC_METHOD *meth = EC_GROUP_method_of(src->group); -+ /* clear the old group */ -+ if (dest->group) -+ EC_GROUP_free(dest->group); -+ dest->group = EC_GROUP_new(meth); -+ if (dest->group == NULL) -+ return NULL; -+ if (!EC_GROUP_copy(dest->group, src->group)) -+ return NULL; -+ } -+ /* copy the public key */ -+ if (src->pub_key && src->group) { -+ if (dest->pub_key) -+ EC_POINT_free(dest->pub_key); -+ dest->pub_key = EC_POINT_new(src->group); -+ if (dest->pub_key == NULL) -+ return NULL; -+ if (!EC_POINT_copy(dest->pub_key, src->pub_key)) -+ return NULL; -+ } -+ /* copy the private key */ -+ if (src->priv_key) { -+ if (dest->priv_key == NULL) { -+ dest->priv_key = BN_new(); -+ if (dest->priv_key == NULL) -+ return NULL; -+ } -+ if (!BN_copy(dest->priv_key, src->priv_key)) -+ return NULL; -+ } -+ /* copy method/extra data */ -+ EC_EX_DATA_free_all_data(&dest->method_data); -+ -+ for (d = src->method_data; d != NULL; d = d->next) { -+ void *t = d->dup_func(d->data); -+ -+ if (t == NULL) -+ return 0; -+ if (!EC_EX_DATA_set_data -+ (&dest->method_data, t, d->dup_func, d->free_func, -+ d->clear_free_func)) -+ return 0; -+ } -+ -+ /* copy the rest */ -+ dest->enc_flag = src->enc_flag; -+ dest->conv_form = src->conv_form; -+ dest->version = src->version; -+ dest->flags = src->flags; -+ -+ return dest; -+} -+ -+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) -+{ -+ EC_KEY *ret = EC_KEY_new(); -+ if (ret == NULL) -+ return NULL; -+ if (EC_KEY_copy(ret, ec_key) == NULL) { -+ EC_KEY_free(ret); -+ return NULL; -+ } -+ return ret; -+} -+ -+int EC_KEY_up_ref(EC_KEY *r) -+{ -+ int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); -+#ifdef REF_PRINT -+ REF_PRINT("EC_KEY", r); -+#endif -+#ifdef REF_CHECK -+ if (i < 2) { -+ fprintf(stderr, "EC_KEY_up, bad reference count\n"); -+ abort(); -+ } -+#endif -+ return ((i > 1) ? 1 : 0); -+} -+ -+int EC_KEY_generate_key(EC_KEY *eckey) -+{ -+ int ok = 0; -+ BN_CTX *ctx = NULL; -+ BIGNUM *priv_key = NULL, *order = NULL; -+ EC_POINT *pub_key = NULL; -+ -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode()) -+ return FIPS_ec_key_generate_key(eckey); -+#endif -+ -+ if (!eckey || !eckey->group) { -+ ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ -+ if ((order = BN_new()) == NULL) -+ goto err; -+ if ((ctx = BN_CTX_new()) == NULL) -+ goto err; -+ -+ if (eckey->priv_key == NULL) { -+ priv_key = BN_new(); -+ if (priv_key == NULL) -+ goto err; -+ } else -+ priv_key = eckey->priv_key; -+ -+ if (!EC_GROUP_get_order(eckey->group, order, ctx)) -+ goto err; -+ -+ do -+ if (!BN_rand_range(priv_key, order)) -+ goto err; -+ while (BN_is_zero(priv_key)) ; -+ -+ if (eckey->pub_key == NULL) { -+ pub_key = EC_POINT_new(eckey->group); -+ if (pub_key == NULL) -+ goto err; -+ } else -+ pub_key = eckey->pub_key; -+ -+ if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) -+ goto err; -+ -+ eckey->priv_key = priv_key; -+ eckey->pub_key = pub_key; -+ -+ ok = 1; -+ -+ err: -+ if (order) -+ BN_free(order); -+ if (pub_key != NULL && eckey->pub_key == NULL) -+ EC_POINT_free(pub_key); -+ if (priv_key != NULL && eckey->priv_key == NULL) -+ BN_free(priv_key); -+ if (ctx != NULL) -+ BN_CTX_free(ctx); -+ return (ok); -+} -+ -+int EC_KEY_check_key(const EC_KEY *eckey) -+{ -+ int ok = 0; -+ BN_CTX *ctx = NULL; -+ const BIGNUM *order = NULL; -+ EC_POINT *point = NULL; -+ -+ if (!eckey || !eckey->group || !eckey->pub_key) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ -+ if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); -+ goto err; -+ } -+ -+ if ((ctx = BN_CTX_new()) == NULL) -+ goto err; -+ if ((point = EC_POINT_new(eckey->group)) == NULL) -+ goto err; -+ -+ /* testing whether the pub_key is on the elliptic curve */ -+ if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); -+ goto err; -+ } -+ /* testing whether pub_key * order is the point at infinity */ -+ order = &eckey->group->order; -+ if (BN_is_zero(order)) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); -+ goto err; -+ } -+ if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (!EC_POINT_is_at_infinity(eckey->group, point)) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); -+ goto err; -+ } -+ /* -+ * in case the priv_key is present : check if generator * priv_key == -+ * pub_key -+ */ -+ if (eckey->priv_key) { -+ if (BN_cmp(eckey->priv_key, order) >= 0) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); -+ goto err; -+ } -+ if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, -+ NULL, NULL, ctx)) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { -+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); -+ goto err; -+ } -+ } -+ ok = 1; -+ err: -+ if (ctx != NULL) -+ BN_CTX_free(ctx); -+ if (point != NULL) -+ EC_POINT_free(point); -+ return (ok); -+} -+ -+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, -+ BIGNUM *y) -+{ -+ BN_CTX *ctx = NULL; -+ BIGNUM *tx, *ty; -+ EC_POINT *point = NULL; -+ int ok = 0; -+#ifndef OPENSSL_NO_EC2M -+ int tmp_nid, is_char_two = 0; -+#endif -+ -+ if (!key || !key->group || !x || !y) { -+ ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, -+ ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ BN_CTX_start(ctx); -+ point = EC_POINT_new(key->group); -+ -+ if (!point) -+ goto err; -+ -+ tx = BN_CTX_get(ctx); -+ ty = BN_CTX_get(ctx); -+ if (ty == NULL) -+ goto err; -+ -+#ifndef OPENSSL_NO_EC2M -+ tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); -+ -+ if (tmp_nid == NID_X9_62_characteristic_two_field) -+ is_char_two = 1; -+ -+ if (is_char_two) { -+ if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, -+ x, y, ctx)) -+ goto err; -+ if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, -+ tx, ty, ctx)) -+ goto err; -+ } else -+#endif -+ { -+ if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, -+ x, y, ctx)) -+ goto err; -+ if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, -+ tx, ty, ctx)) -+ goto err; -+ } -+ /* -+ * Check if retrieved coordinates match originals: if not values are out -+ * of range. -+ */ -+ if (BN_cmp(x, tx) || BN_cmp(y, ty)) { -+ ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, -+ EC_R_COORDINATES_OUT_OF_RANGE); -+ goto err; -+ } -+ -+ if (!EC_KEY_set_public_key(key, point)) -+ goto err; -+ -+ if (EC_KEY_check_key(key) == 0) -+ goto err; -+ -+ ok = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ BN_CTX_free(ctx); -+ EC_POINT_free(point); -+ return ok; -+ -+} -+ -+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) -+{ -+ return key->group; -+} -+ -+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) -+{ -+ if (key->group != NULL) -+ EC_GROUP_free(key->group); -+ key->group = EC_GROUP_dup(group); -+ return (key->group == NULL) ? 0 : 1; -+} -+ -+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) -+{ -+ return key->priv_key; -+} -+ -+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) -+{ -+ if (key->priv_key) -+ BN_clear_free(key->priv_key); -+ key->priv_key = BN_dup(priv_key); -+ return (key->priv_key == NULL) ? 0 : 1; -+} -+ -+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) -+{ -+ return key->pub_key; -+} -+ -+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) -+{ -+ if (key->pub_key != NULL) -+ EC_POINT_free(key->pub_key); -+ key->pub_key = EC_POINT_dup(pub_key, key->group); -+ return (key->pub_key == NULL) ? 0 : 1; -+} -+ -+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) -+{ -+ return key->enc_flag; -+} -+ -+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) -+{ -+ key->enc_flag = flags; -+} -+ -+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) -+{ -+ return key->conv_form; -+} -+ -+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) -+{ -+ key->conv_form = cform; -+ if (key->group != NULL) -+ EC_GROUP_set_point_conversion_form(key->group, cform); -+} -+ -+void *EC_KEY_get_key_method_data(EC_KEY *key, -+ void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)) -+{ -+ void *ret; -+ -+ CRYPTO_r_lock(CRYPTO_LOCK_EC); -+ ret = -+ EC_EX_DATA_get_data(key->method_data, dup_func, free_func, -+ clear_free_func); -+ CRYPTO_r_unlock(CRYPTO_LOCK_EC); -+ -+ return ret; -+} -+ -+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, -+ void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)) -+{ -+ EC_EXTRA_DATA *ex_data; -+ -+ CRYPTO_w_lock(CRYPTO_LOCK_EC); -+ ex_data = -+ EC_EX_DATA_get_data(key->method_data, dup_func, free_func, -+ clear_free_func); -+ if (ex_data == NULL) -+ EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, -+ clear_free_func); -+ CRYPTO_w_unlock(CRYPTO_LOCK_EC); -+ -+ return ex_data; -+} -+ -+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) -+{ -+ if (key->group != NULL) -+ EC_GROUP_set_asn1_flag(key->group, flag); -+} -+ -+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) -+{ -+ if (key->group == NULL) -+ return 0; -+ return EC_GROUP_precompute_mult(key->group, ctx); -+} -+ -+int EC_KEY_get_flags(const EC_KEY *key) -+{ -+ return key->flags; -+} -+ -+void EC_KEY_set_flags(EC_KEY *key, int flags) -+{ -+ key->flags |= flags; -+} -+ -+void EC_KEY_clear_flags(EC_KEY *key, int flags) -+{ -+ key->flags &= ~flags; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_lcl.h b/Cryptlib/OpenSSL/crypto/ec/ec_lcl.h -new file mode 100644 -index 0000000..68a1550 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_lcl.h -@@ -0,0 +1,470 @@ -+/* crypto/ec/ec_lcl.h */ -+/* -+ * Originally written by Bodo Moeller for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2010 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * -+ * Portions of the attached software ("Contribution") are developed by -+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. -+ * -+ * The Contribution is licensed pursuant to the OpenSSL open source -+ * license provided above. -+ * -+ * The elliptic curve binary polynomial software is originally written by -+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. -+ * -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#if defined(__SUNPRO_C) -+# if __SUNPRO_C >= 0x520 -+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) -+# endif -+#endif -+ -+/* Use default functions for poin2oct, oct2point and compressed coordinates */ -+#define EC_FLAGS_DEFAULT_OCT 0x1 -+ -+/* -+ * Structure details are not part of the exported interface, so all this may -+ * change in future versions. -+ */ -+ -+struct ec_method_st { -+ /* Various method flags */ -+ int flags; -+ /* used by EC_METHOD_get_field_type: */ -+ int field_type; /* a NID */ -+ /* -+ * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, -+ * EC_GROUP_copy: -+ */ -+ int (*group_init) (EC_GROUP *); -+ void (*group_finish) (EC_GROUP *); -+ void (*group_clear_finish) (EC_GROUP *); -+ int (*group_copy) (EC_GROUP *, const EC_GROUP *); -+ /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */ -+ /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */ -+ int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+ int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, -+ BN_CTX *); -+ /* used by EC_GROUP_get_degree: */ -+ int (*group_get_degree) (const EC_GROUP *); -+ /* used by EC_GROUP_check: */ -+ int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *); -+ /* -+ * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, -+ * EC_POINT_copy: -+ */ -+ int (*point_init) (EC_POINT *); -+ void (*point_finish) (EC_POINT *); -+ void (*point_clear_finish) (EC_POINT *); -+ int (*point_copy) (EC_POINT *, const EC_POINT *); -+ /*- -+ * used by EC_POINT_set_to_infinity, -+ * EC_POINT_set_Jprojective_coordinates_GFp, -+ * EC_POINT_get_Jprojective_coordinates_GFp, -+ * EC_POINT_set_affine_coordinates_GFp, ..._GF2m, -+ * EC_POINT_get_affine_coordinates_GFp, ..._GF2m, -+ * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m: -+ */ -+ int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *); -+ int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *, -+ EC_POINT *, const BIGNUM *x, -+ const BIGNUM *y, -+ const BIGNUM *z, BN_CTX *); -+ int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *, -+ const EC_POINT *, BIGNUM *x, -+ BIGNUM *y, BIGNUM *z, -+ BN_CTX *); -+ int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *, -+ const BIGNUM *x, const BIGNUM *y, -+ BN_CTX *); -+ int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *, -+ BIGNUM *x, BIGNUM *y, BN_CTX *); -+ int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *, -+ const BIGNUM *x, int y_bit, -+ BN_CTX *); -+ /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ -+ size_t (*point2oct) (const EC_GROUP *, const EC_POINT *, -+ point_conversion_form_t form, unsigned char *buf, -+ size_t len, BN_CTX *); -+ int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf, -+ size_t len, BN_CTX *); -+ /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */ -+ int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, -+ const EC_POINT *b, BN_CTX *); -+ int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); -+ int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *); -+ /* -+ * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: -+ */ -+ int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *); -+ int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *); -+ int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, -+ BN_CTX *); -+ /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */ -+ int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *); -+ int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[], -+ BN_CTX *); -+ /* -+ * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, -+ * EC_POINT_have_precompute_mult (default implementations are used if the -+ * 'mul' pointer is 0): -+ */ -+ int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, -+ size_t num, const EC_POINT *points[], const BIGNUM *scalars[], -+ BN_CTX *); -+ int (*precompute_mult) (EC_GROUP *group, BN_CTX *); -+ int (*have_precompute_mult) (const EC_GROUP *group); -+ /* internal functions */ -+ /* -+ * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and -+ * 'dbl' so that the same implementations of point operations can be used -+ * with different optimized implementations of expensive field -+ * operations: -+ */ -+ int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+ int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); -+ int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+ /* e.g. to Montgomery */ -+ int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+ /* e.g. from Montgomery */ -+ int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+ int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *); -+} /* EC_METHOD */ ; -+ -+typedef struct ec_extra_data_st { -+ struct ec_extra_data_st *next; -+ void *data; -+ void *(*dup_func) (void *); -+ void (*free_func) (void *); -+ void (*clear_free_func) (void *); -+} EC_EXTRA_DATA; /* used in EC_GROUP */ -+ -+struct ec_group_st { -+ const EC_METHOD *meth; -+ EC_POINT *generator; /* optional */ -+ BIGNUM order, cofactor; -+ int curve_name; /* optional NID for named curve */ -+ int asn1_flag; /* flag to control the asn1 encoding */ -+ /* -+ * Kludge: upper bit of ans1_flag is used to denote structure -+ * version. Is set, then last field is present. This is done -+ * for interoperation with FIPS code. -+ */ -+#define EC_GROUP_ASN1_FLAG_MASK 0x7fffffff -+#define EC_GROUP_VERSION(p) (p->asn1_flag&~EC_GROUP_ASN1_FLAG_MASK) -+ point_conversion_form_t asn1_form; -+ unsigned char *seed; /* optional seed for parameters (appears in -+ * ASN1) */ -+ size_t seed_len; -+ EC_EXTRA_DATA *extra_data; /* linked list */ -+ /* -+ * The following members are handled by the method functions, even if -+ * they appear generic -+ */ -+ /* -+ * Field specification. For curves over GF(p), this is the modulus; for -+ * curves over GF(2^m), this is the irreducible polynomial defining the -+ * field. -+ */ -+ BIGNUM field; -+ /* -+ * Field specification for curves over GF(2^m). The irreducible f(t) is -+ * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m = -+ * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with -+ * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero -+ * terms. -+ */ -+ int poly[6]; -+ /* -+ * Curve coefficients. (Here the assumption is that BIGNUMs can be used -+ * or abused for all kinds of fields, not just GF(p).) For characteristic -+ * > 3, the curve is defined by a Weierstrass equation of the form y^2 = -+ * x^3 + a*x + b. For characteristic 2, the curve is defined by an -+ * equation of the form y^2 + x*y = x^3 + a*x^2 + b. -+ */ -+ BIGNUM a, b; -+ /* enable optimized point arithmetics for special case */ -+ int a_is_minus3; -+ /* method-specific (e.g., Montgomery structure) */ -+ void *field_data1; -+ /* method-specific */ -+ void *field_data2; -+ /* method-specific */ -+ int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *, -+ BN_CTX *); -+ BN_MONT_CTX *mont_data; /* data for ECDSA inverse */ -+} /* EC_GROUP */ ; -+ -+struct ec_key_st { -+ int version; -+ EC_GROUP *group; -+ EC_POINT *pub_key; -+ BIGNUM *priv_key; -+ unsigned int enc_flag; -+ point_conversion_form_t conv_form; -+ int references; -+ int flags; -+ EC_EXTRA_DATA *method_data; -+} /* EC_KEY */ ; -+ -+/* -+ * Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs -+ * only (with visibility limited to 'package' level for now). We use the -+ * function pointers as index for retrieval; this obviates global -+ * ex_data-style index tables. -+ */ -+int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data, -+ void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)); -+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)); -+void EC_EX_DATA_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)); -+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)); -+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **); -+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **); -+ -+struct ec_point_st { -+ const EC_METHOD *meth; -+ /* -+ * All members except 'meth' are handled by the method functions, even if -+ * they appear generic -+ */ -+ BIGNUM X; -+ BIGNUM Y; -+ BIGNUM Z; /* Jacobian projective coordinates: (X, Y, Z) -+ * represents (X/Z^2, Y/Z^3) if Z != 0 */ -+ int Z_is_one; /* enable optimized point arithmetics for -+ * special case */ -+} /* EC_POINT */ ; -+ -+/* -+ * method functions in ec_mult.c (ec_lib.c uses these as defaults if -+ * group->method->mul is 0) -+ */ -+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, -+ size_t num, const EC_POINT *points[], const BIGNUM *scalars[], -+ BN_CTX *); -+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); -+int ec_wNAF_have_precompute_mult(const EC_GROUP *group); -+ -+/* method functions in ecp_smpl.c */ -+int ec_GFp_simple_group_init(EC_GROUP *); -+void ec_GFp_simple_group_finish(EC_GROUP *); -+void ec_GFp_simple_group_clear_finish(EC_GROUP *); -+int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); -+int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, -+ const BIGNUM *a, const BIGNUM *b, BN_CTX *); -+int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, -+ BIGNUM *b, BN_CTX *); -+int ec_GFp_simple_group_get_degree(const EC_GROUP *); -+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); -+int ec_GFp_simple_point_init(EC_POINT *); -+void ec_GFp_simple_point_finish(EC_POINT *); -+void ec_GFp_simple_point_clear_finish(EC_POINT *); -+int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); -+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); -+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, -+ EC_POINT *, const BIGNUM *x, -+ const BIGNUM *y, -+ const BIGNUM *z, BN_CTX *); -+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, -+ const EC_POINT *, BIGNUM *x, -+ BIGNUM *y, BIGNUM *z, -+ BN_CTX *); -+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, -+ const BIGNUM *x, -+ const BIGNUM *y, BN_CTX *); -+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, -+ const EC_POINT *, BIGNUM *x, -+ BIGNUM *y, BN_CTX *); -+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, -+ const BIGNUM *x, int y_bit, -+ BN_CTX *); -+size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, -+ point_conversion_form_t form, -+ unsigned char *buf, size_t len, BN_CTX *); -+int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, -+ const unsigned char *buf, size_t len, BN_CTX *); -+int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, -+ const EC_POINT *b, BN_CTX *); -+int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, -+ BN_CTX *); -+int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -+int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); -+int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); -+int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, -+ BN_CTX *); -+int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -+int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, -+ EC_POINT *[], BN_CTX *); -+int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+ -+/* method functions in ecp_mont.c */ -+int ec_GFp_mont_group_init(EC_GROUP *); -+int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+void ec_GFp_mont_group_finish(EC_GROUP *); -+void ec_GFp_mont_group_clear_finish(EC_GROUP *); -+int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); -+int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); -+ -+/* method functions in ecp_nist.c */ -+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); -+int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+ -+/* method functions in ec2_smpl.c */ -+int ec_GF2m_simple_group_init(EC_GROUP *); -+void ec_GF2m_simple_group_finish(EC_GROUP *); -+void ec_GF2m_simple_group_clear_finish(EC_GROUP *); -+int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *); -+int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, -+ const BIGNUM *a, const BIGNUM *b, -+ BN_CTX *); -+int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, -+ BIGNUM *b, BN_CTX *); -+int ec_GF2m_simple_group_get_degree(const EC_GROUP *); -+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); -+int ec_GF2m_simple_point_init(EC_POINT *); -+void ec_GF2m_simple_point_finish(EC_POINT *); -+void ec_GF2m_simple_point_clear_finish(EC_POINT *); -+int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *); -+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); -+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, -+ const BIGNUM *x, -+ const BIGNUM *y, BN_CTX *); -+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, -+ const EC_POINT *, BIGNUM *x, -+ BIGNUM *y, BN_CTX *); -+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, -+ const BIGNUM *x, int y_bit, -+ BN_CTX *); -+size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, -+ point_conversion_form_t form, -+ unsigned char *buf, size_t len, BN_CTX *); -+int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *, -+ const unsigned char *buf, size_t len, BN_CTX *); -+int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, -+ const EC_POINT *b, BN_CTX *); -+int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, -+ BN_CTX *); -+int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); -+int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); -+int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, -+ BN_CTX *); -+int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -+int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, -+ EC_POINT *[], BN_CTX *); -+int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *); -+int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *); -+ -+/* method functions in ec2_mult.c */ -+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, -+ const BIGNUM *scalar, size_t num, -+ const EC_POINT *points[], const BIGNUM *scalars[], -+ BN_CTX *); -+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -+int ec_GF2m_have_precompute_mult(const EC_GROUP *group); -+ -+int ec_precompute_mont_data(EC_GROUP *); -+ -+#ifdef OPENSSL_FIPS -+EC_GROUP *FIPS_ec_group_new_curve_gfp(const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx); -+EC_GROUP *FIPS_ec_group_new_curve_gf2m(const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx); -+EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid); -+#endif -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_lib.c b/Cryptlib/OpenSSL/crypto/ec/ec_lib.c -new file mode 100644 -index 0000000..4512c59 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_lib.c -@@ -0,0 +1,1077 @@ -+/* crypto/ec/ec_lib.c */ -+/* -+ * Originally written by Bodo Moeller for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2003 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Binary polynomial ECC support in OpenSSL originally developed by -+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "ec_lcl.h" -+ -+const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; -+ -+/* functions for EC_GROUP objects */ -+ -+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) -+{ -+ EC_GROUP *ret; -+ -+ if (meth == NULL) { -+ ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); -+ return NULL; -+ } -+ if (meth->group_init == 0) { -+ ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return NULL; -+ } -+ -+ ret = OPENSSL_malloc(sizeof *ret); -+ if (ret == NULL) { -+ ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ ret->meth = meth; -+ -+ ret->extra_data = NULL; -+ ret->mont_data = NULL; -+ -+ ret->generator = NULL; -+ BN_init(&ret->order); -+ BN_init(&ret->cofactor); -+ -+ ret->curve_name = 0; -+ ret->asn1_flag = ~EC_GROUP_ASN1_FLAG_MASK; -+ ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; -+ -+ ret->seed = NULL; -+ ret->seed_len = 0; -+ -+ if (!meth->group_init(ret)) { -+ OPENSSL_free(ret); -+ return NULL; -+ } -+ -+ return ret; -+} -+ -+void EC_GROUP_free(EC_GROUP *group) -+{ -+ if (!group) -+ return; -+ -+ if (group->meth->group_finish != 0) -+ group->meth->group_finish(group); -+ -+ EC_EX_DATA_free_all_data(&group->extra_data); -+ -+ if (EC_GROUP_VERSION(group) && group->mont_data) -+ BN_MONT_CTX_free(group->mont_data); -+ -+ if (group->generator != NULL) -+ EC_POINT_free(group->generator); -+ BN_free(&group->order); -+ BN_free(&group->cofactor); -+ -+ if (group->seed) -+ OPENSSL_free(group->seed); -+ -+ OPENSSL_free(group); -+} -+ -+void EC_GROUP_clear_free(EC_GROUP *group) -+{ -+ if (!group) -+ return; -+ -+ if (group->meth->group_clear_finish != 0) -+ group->meth->group_clear_finish(group); -+ else if (group->meth->group_finish != 0) -+ group->meth->group_finish(group); -+ -+ EC_EX_DATA_clear_free_all_data(&group->extra_data); -+ -+ if (EC_GROUP_VERSION(group) && group->mont_data) -+ BN_MONT_CTX_free(group->mont_data); -+ -+ if (group->generator != NULL) -+ EC_POINT_clear_free(group->generator); -+ BN_clear_free(&group->order); -+ BN_clear_free(&group->cofactor); -+ -+ if (group->seed) { -+ OPENSSL_cleanse(group->seed, group->seed_len); -+ OPENSSL_free(group->seed); -+ } -+ -+ OPENSSL_cleanse(group, sizeof *group); -+ OPENSSL_free(group); -+} -+ -+int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) -+{ -+ EC_EXTRA_DATA *d; -+ -+ if (dest->meth->group_copy == 0) { -+ ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (dest->meth != src->meth) { -+ ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ if (dest == src) -+ return 1; -+ -+ EC_EX_DATA_free_all_data(&dest->extra_data); -+ -+ for (d = src->extra_data; d != NULL; d = d->next) { -+ void *t = d->dup_func(d->data); -+ -+ if (t == NULL) -+ return 0; -+ if (!EC_EX_DATA_set_data -+ (&dest->extra_data, t, d->dup_func, d->free_func, -+ d->clear_free_func)) -+ return 0; -+ } -+ -+ if (EC_GROUP_VERSION(src) && src->mont_data != NULL) { -+ if (dest->mont_data == NULL) { -+ dest->mont_data = BN_MONT_CTX_new(); -+ if (dest->mont_data == NULL) -+ return 0; -+ } -+ if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) -+ return 0; -+ } else { -+ /* src->generator == NULL */ -+ if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) { -+ BN_MONT_CTX_free(dest->mont_data); -+ dest->mont_data = NULL; -+ } -+ } -+ -+ if (src->generator != NULL) { -+ if (dest->generator == NULL) { -+ dest->generator = EC_POINT_new(dest); -+ if (dest->generator == NULL) -+ return 0; -+ } -+ if (!EC_POINT_copy(dest->generator, src->generator)) -+ return 0; -+ } else { -+ /* src->generator == NULL */ -+ if (dest->generator != NULL) { -+ EC_POINT_clear_free(dest->generator); -+ dest->generator = NULL; -+ } -+ } -+ -+ if (!BN_copy(&dest->order, &src->order)) -+ return 0; -+ if (!BN_copy(&dest->cofactor, &src->cofactor)) -+ return 0; -+ -+ dest->curve_name = src->curve_name; -+ dest->asn1_flag = src->asn1_flag; -+ dest->asn1_form = src->asn1_form; -+ -+ if (src->seed) { -+ if (dest->seed) -+ OPENSSL_free(dest->seed); -+ dest->seed = OPENSSL_malloc(src->seed_len); -+ if (dest->seed == NULL) -+ return 0; -+ if (!memcpy(dest->seed, src->seed, src->seed_len)) -+ return 0; -+ dest->seed_len = src->seed_len; -+ } else { -+ if (dest->seed) -+ OPENSSL_free(dest->seed); -+ dest->seed = NULL; -+ dest->seed_len = 0; -+ } -+ -+ return dest->meth->group_copy(dest, src); -+} -+ -+EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) -+{ -+ EC_GROUP *t = NULL; -+ int ok = 0; -+ -+ if (a == NULL) -+ return NULL; -+ -+ if ((t = EC_GROUP_new(a->meth)) == NULL) -+ return (NULL); -+ if (!EC_GROUP_copy(t, a)) -+ goto err; -+ -+ ok = 1; -+ -+ err: -+ if (!ok) { -+ if (t) -+ EC_GROUP_free(t); -+ return NULL; -+ } else -+ return t; -+} -+ -+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) -+{ -+ return group->meth; -+} -+ -+int EC_METHOD_get_field_type(const EC_METHOD *meth) -+{ -+ return meth->field_type; -+} -+ -+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, -+ const BIGNUM *order, const BIGNUM *cofactor) -+{ -+ if (generator == NULL) { -+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ -+ if (group->generator == NULL) { -+ group->generator = EC_POINT_new(group); -+ if (group->generator == NULL) -+ return 0; -+ } -+ if (!EC_POINT_copy(group->generator, generator)) -+ return 0; -+ -+ if (order != NULL) { -+ if (!BN_copy(&group->order, order)) -+ return 0; -+ } else -+ BN_zero(&group->order); -+ -+ if (cofactor != NULL) { -+ if (!BN_copy(&group->cofactor, cofactor)) -+ return 0; -+ } else -+ BN_zero(&group->cofactor); -+ -+ /* -+ * We ignore the return value because some groups have an order with -+ * factors of two, which makes the Montgomery setup fail. -+ * |group->mont_data| will be NULL in this case. -+ */ -+ ec_precompute_mont_data(group); -+ -+ return 1; -+} -+ -+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) -+{ -+ return group->generator; -+} -+ -+BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) -+{ -+ return EC_GROUP_VERSION(group) ? group->mont_data : NULL; -+} -+ -+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) -+{ -+ if (!BN_copy(order, &group->order)) -+ return 0; -+ -+ return !BN_is_zero(order); -+} -+ -+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) -+{ -+ return &group->order; -+} -+ -+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, -+ BN_CTX *ctx) -+{ -+ if (!BN_copy(cofactor, &group->cofactor)) -+ return 0; -+ -+ return !BN_is_zero(&group->cofactor); -+} -+ -+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) -+{ -+ group->curve_name = nid; -+} -+ -+int EC_GROUP_get_curve_name(const EC_GROUP *group) -+{ -+ return group->curve_name; -+} -+ -+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) -+{ -+ group->asn1_flag &= ~EC_GROUP_ASN1_FLAG_MASK; -+ group->asn1_flag |= flag & EC_GROUP_ASN1_FLAG_MASK; -+} -+ -+int EC_GROUP_get_asn1_flag(const EC_GROUP *group) -+{ -+ return group->asn1_flag & EC_GROUP_ASN1_FLAG_MASK; -+} -+ -+void EC_GROUP_set_point_conversion_form(EC_GROUP *group, -+ point_conversion_form_t form) -+{ -+ group->asn1_form = form; -+} -+ -+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP -+ *group) -+{ -+ return group->asn1_form; -+} -+ -+size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) -+{ -+ if (group->seed) { -+ OPENSSL_free(group->seed); -+ group->seed = NULL; -+ group->seed_len = 0; -+ } -+ -+ if (!len || !p) -+ return 1; -+ -+ if ((group->seed = OPENSSL_malloc(len)) == NULL) -+ return 0; -+ memcpy(group->seed, p, len); -+ group->seed_len = len; -+ -+ return len; -+} -+ -+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group) -+{ -+ return group->seed; -+} -+ -+size_t EC_GROUP_get_seed_len(const EC_GROUP *group) -+{ -+ return group->seed_len; -+} -+ -+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx) -+{ -+ if (group->meth->group_set_curve == 0) { -+ ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ return group->meth->group_set_curve(group, p, a, b, ctx); -+} -+ -+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, -+ BIGNUM *b, BN_CTX *ctx) -+{ -+ if (group->meth->group_get_curve == 0) { -+ ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ return group->meth->group_get_curve(group, p, a, b, ctx); -+} -+ -+int EC_GROUP_get_degree(const EC_GROUP *group) -+{ -+ if (group->meth->group_get_degree == 0) { -+ ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ return group->meth->group_get_degree(group); -+} -+ -+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) -+{ -+ if (group->meth->group_check_discriminant == 0) { -+ ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ return group->meth->group_check_discriminant(group, ctx); -+} -+ -+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) -+{ -+ int r = 0; -+ BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; -+ BN_CTX *ctx_new = NULL; -+ -+ /* compare the field types */ -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != -+ EC_METHOD_get_field_type(EC_GROUP_method_of(b))) -+ return 1; -+ /* compare the curve name (if present in both) */ -+ if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && -+ EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) -+ return 1; -+ -+ if (!ctx) -+ ctx_new = ctx = BN_CTX_new(); -+ if (!ctx) -+ return -1; -+ -+ BN_CTX_start(ctx); -+ a1 = BN_CTX_get(ctx); -+ a2 = BN_CTX_get(ctx); -+ a3 = BN_CTX_get(ctx); -+ b1 = BN_CTX_get(ctx); -+ b2 = BN_CTX_get(ctx); -+ b3 = BN_CTX_get(ctx); -+ if (!b3) { -+ BN_CTX_end(ctx); -+ if (ctx_new) -+ BN_CTX_free(ctx); -+ return -1; -+ } -+ -+ /* -+ * XXX This approach assumes that the external representation of curves -+ * over the same field type is the same. -+ */ -+ if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || -+ !b->meth->group_get_curve(b, b1, b2, b3, ctx)) -+ r = 1; -+ -+ if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) -+ r = 1; -+ -+ /* XXX EC_POINT_cmp() assumes that the methods are equal */ -+ if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), -+ EC_GROUP_get0_generator(b), ctx)) -+ r = 1; -+ -+ if (!r) { -+ /* compare the order and cofactor */ -+ if (!EC_GROUP_get_order(a, a1, ctx) || -+ !EC_GROUP_get_order(b, b1, ctx) || -+ !EC_GROUP_get_cofactor(a, a2, ctx) || -+ !EC_GROUP_get_cofactor(b, b2, ctx)) { -+ BN_CTX_end(ctx); -+ if (ctx_new) -+ BN_CTX_free(ctx); -+ return -1; -+ } -+ if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) -+ r = 1; -+ } -+ -+ BN_CTX_end(ctx); -+ if (ctx_new) -+ BN_CTX_free(ctx); -+ -+ return r; -+} -+ -+/* this has 'package' visibility */ -+int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data, -+ void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)) -+{ -+ EC_EXTRA_DATA *d; -+ -+ if (ex_data == NULL) -+ return 0; -+ -+ for (d = *ex_data; d != NULL; d = d->next) { -+ if (d->dup_func == dup_func && d->free_func == free_func -+ && d->clear_free_func == clear_free_func) { -+ ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL); -+ return 0; -+ } -+ } -+ -+ if (data == NULL) -+ /* no explicit entry needed */ -+ return 1; -+ -+ d = OPENSSL_malloc(sizeof *d); -+ if (d == NULL) -+ return 0; -+ -+ d->data = data; -+ d->dup_func = dup_func; -+ d->free_func = free_func; -+ d->clear_free_func = clear_free_func; -+ -+ d->next = *ex_data; -+ *ex_data = d; -+ -+ return 1; -+} -+ -+/* this has 'package' visibility */ -+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data, -+ void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)) -+{ -+ const EC_EXTRA_DATA *d; -+ -+ for (d = ex_data; d != NULL; d = d->next) { -+ if (d->dup_func == dup_func && d->free_func == free_func -+ && d->clear_free_func == clear_free_func) -+ return d->data; -+ } -+ -+ return NULL; -+} -+ -+/* this has 'package' visibility */ -+void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data, -+ void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)) -+{ -+ EC_EXTRA_DATA **p; -+ -+ if (ex_data == NULL) -+ return; -+ -+ for (p = ex_data; *p != NULL; p = &((*p)->next)) { -+ if ((*p)->dup_func == dup_func && (*p)->free_func == free_func -+ && (*p)->clear_free_func == clear_free_func) { -+ EC_EXTRA_DATA *next = (*p)->next; -+ -+ (*p)->free_func((*p)->data); -+ OPENSSL_free(*p); -+ -+ *p = next; -+ return; -+ } -+ } -+} -+ -+/* this has 'package' visibility */ -+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data, -+ void *(*dup_func) (void *), -+ void (*free_func) (void *), -+ void (*clear_free_func) (void *)) -+{ -+ EC_EXTRA_DATA **p; -+ -+ if (ex_data == NULL) -+ return; -+ -+ for (p = ex_data; *p != NULL; p = &((*p)->next)) { -+ if ((*p)->dup_func == dup_func && (*p)->free_func == free_func -+ && (*p)->clear_free_func == clear_free_func) { -+ EC_EXTRA_DATA *next = (*p)->next; -+ -+ (*p)->clear_free_func((*p)->data); -+ OPENSSL_free(*p); -+ -+ *p = next; -+ return; -+ } -+ } -+} -+ -+/* this has 'package' visibility */ -+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data) -+{ -+ EC_EXTRA_DATA *d; -+ -+ if (ex_data == NULL) -+ return; -+ -+ d = *ex_data; -+ while (d) { -+ EC_EXTRA_DATA *next = d->next; -+ -+ d->free_func(d->data); -+ OPENSSL_free(d); -+ -+ d = next; -+ } -+ *ex_data = NULL; -+} -+ -+/* this has 'package' visibility */ -+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data) -+{ -+ EC_EXTRA_DATA *d; -+ -+ if (ex_data == NULL) -+ return; -+ -+ d = *ex_data; -+ while (d) { -+ EC_EXTRA_DATA *next = d->next; -+ -+ d->clear_free_func(d->data); -+ OPENSSL_free(d); -+ -+ d = next; -+ } -+ *ex_data = NULL; -+} -+ -+/* functions for EC_POINT objects */ -+ -+EC_POINT *EC_POINT_new(const EC_GROUP *group) -+{ -+ EC_POINT *ret; -+ -+ if (group == NULL) { -+ ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); -+ return NULL; -+ } -+ if (group->meth->point_init == 0) { -+ ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return NULL; -+ } -+ -+ ret = OPENSSL_malloc(sizeof *ret); -+ if (ret == NULL) { -+ ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ ret->meth = group->meth; -+ -+ if (!ret->meth->point_init(ret)) { -+ OPENSSL_free(ret); -+ return NULL; -+ } -+ -+ return ret; -+} -+ -+void EC_POINT_free(EC_POINT *point) -+{ -+ if (!point) -+ return; -+ -+ if (point->meth->point_finish != 0) -+ point->meth->point_finish(point); -+ OPENSSL_free(point); -+} -+ -+void EC_POINT_clear_free(EC_POINT *point) -+{ -+ if (!point) -+ return; -+ -+ if (point->meth->point_clear_finish != 0) -+ point->meth->point_clear_finish(point); -+ else if (point->meth->point_finish != 0) -+ point->meth->point_finish(point); -+ OPENSSL_cleanse(point, sizeof *point); -+ OPENSSL_free(point); -+} -+ -+int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) -+{ -+ if (dest->meth->point_copy == 0) { -+ ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (dest->meth != src->meth) { -+ ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ if (dest == src) -+ return 1; -+ return dest->meth->point_copy(dest, src); -+} -+ -+EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) -+{ -+ EC_POINT *t; -+ int r; -+ -+ if (a == NULL) -+ return NULL; -+ -+ t = EC_POINT_new(group); -+ if (t == NULL) -+ return (NULL); -+ r = EC_POINT_copy(t, a); -+ if (!r) { -+ EC_POINT_free(t); -+ return NULL; -+ } else -+ return t; -+} -+ -+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) -+{ -+ return point->meth; -+} -+ -+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) -+{ -+ if (group->meth->point_set_to_infinity == 0) { -+ ECerr(EC_F_EC_POINT_SET_TO_INFINITY, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->point_set_to_infinity(group, point); -+} -+ -+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, -+ EC_POINT *point, const BIGNUM *x, -+ const BIGNUM *y, const BIGNUM *z, -+ BN_CTX *ctx) -+{ -+ if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { -+ ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, -+ EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, -+ y, z, ctx); -+} -+ -+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, -+ const EC_POINT *point, BIGNUM *x, -+ BIGNUM *y, BIGNUM *z, -+ BN_CTX *ctx) -+{ -+ if (group->meth->point_get_Jprojective_coordinates_GFp == 0) { -+ ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, -+ EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, -+ y, z, ctx); -+} -+ -+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, -+ EC_POINT *point, const BIGNUM *x, -+ const BIGNUM *y, BN_CTX *ctx) -+{ -+ if (group->meth->point_set_affine_coordinates == 0) { -+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, -+ EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); -+} -+ -+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, -+ const EC_POINT *point, BIGNUM *x, -+ BIGNUM *y, BN_CTX *ctx) -+{ -+ if (group->meth->point_get_affine_coordinates == 0) { -+ ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, -+ EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); -+} -+ -+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, -+ const EC_POINT *b, BN_CTX *ctx) -+{ -+ if (group->meth->add == 0) { -+ ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if ((group->meth != r->meth) || (r->meth != a->meth) -+ || (a->meth != b->meth)) { -+ ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->add(group, r, a, b, ctx); -+} -+ -+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, -+ BN_CTX *ctx) -+{ -+ if (group->meth->dbl == 0) { -+ ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if ((group->meth != r->meth) || (r->meth != a->meth)) { -+ ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->dbl(group, r, a, ctx); -+} -+ -+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) -+{ -+ if (group->meth->invert == 0) { -+ ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != a->meth) { -+ ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->invert(group, a, ctx); -+} -+ -+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) -+{ -+ if (group->meth->is_at_infinity == 0) { -+ ECerr(EC_F_EC_POINT_IS_AT_INFINITY, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->is_at_infinity(group, point); -+} -+ -+/* -+ * Check whether an EC_POINT is on the curve or not. Note that the return -+ * value for this function should NOT be treated as a boolean. Return values: -+ * 1: The point is on the curve -+ * 0: The point is not on the curve -+ * -1: An error occurred -+ */ -+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, -+ BN_CTX *ctx) -+{ -+ if (group->meth->is_on_curve == 0) { -+ ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->is_on_curve(group, point, ctx); -+} -+ -+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, -+ BN_CTX *ctx) -+{ -+ if (group->meth->point_cmp == 0) { -+ ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return -1; -+ } -+ if ((group->meth != a->meth) || (a->meth != b->meth)) { -+ ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); -+ return -1; -+ } -+ return group->meth->point_cmp(group, a, b, ctx); -+} -+ -+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) -+{ -+ if (group->meth->make_affine == 0) { -+ ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ return group->meth->make_affine(group, point, ctx); -+} -+ -+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, -+ EC_POINT *points[], BN_CTX *ctx) -+{ -+ size_t i; -+ -+ if (group->meth->points_make_affine == 0) { -+ ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ for (i = 0; i < num; i++) { -+ if (group->meth != points[i]->meth) { -+ ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ } -+ return group->meth->points_make_affine(group, num, points, ctx); -+} -+ -+/* -+ * Functions for point multiplication. If group->meth->mul is 0, we use the -+ * wNAF-based implementations in ec_mult.c; otherwise we dispatch through -+ * methods. -+ */ -+ -+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, -+ size_t num, const EC_POINT *points[], -+ const BIGNUM *scalars[], BN_CTX *ctx) -+{ -+ if (group->meth->mul == 0) -+ /* use default */ -+ return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); -+ -+ return group->meth->mul(group, r, scalar, num, points, scalars, ctx); -+} -+ -+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, -+ const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) -+{ -+ /* just a convenient interface to EC_POINTs_mul() */ -+ -+ const EC_POINT *points[1]; -+ const BIGNUM *scalars[1]; -+ -+ points[0] = point; -+ scalars[0] = p_scalar; -+ -+ return EC_POINTs_mul(group, r, g_scalar, -+ (point != NULL -+ && p_scalar != NULL), points, scalars, ctx); -+} -+ -+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -+{ -+ if (group->meth->mul == 0) -+ /* use default */ -+ return ec_wNAF_precompute_mult(group, ctx); -+ -+ if (group->meth->precompute_mult != 0) -+ return group->meth->precompute_mult(group, ctx); -+ else -+ return 1; /* nothing to do, so report success */ -+} -+ -+int EC_GROUP_have_precompute_mult(const EC_GROUP *group) -+{ -+ if (group->meth->mul == 0) -+ /* use default */ -+ return ec_wNAF_have_precompute_mult(group); -+ -+ if (group->meth->have_precompute_mult != 0) -+ return group->meth->have_precompute_mult(group); -+ else -+ return 0; /* cannot tell whether precomputation has -+ * been performed */ -+} -+ -+/* -+ * ec_precompute_mont_data sets |group->mont_data| from |group->order| and -+ * returns one on success. On error it returns zero. -+ */ -+int ec_precompute_mont_data(EC_GROUP *group) -+{ -+ BN_CTX *ctx = BN_CTX_new(); -+ int ret = 0; -+ -+ if (!EC_GROUP_VERSION(group)) -+ goto err; -+ -+ if (group->mont_data) { -+ BN_MONT_CTX_free(group->mont_data); -+ group->mont_data = NULL; -+ } -+ -+ if (ctx == NULL) -+ goto err; -+ -+ group->mont_data = BN_MONT_CTX_new(); -+ if (!group->mont_data) -+ goto err; -+ -+ if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) { -+ BN_MONT_CTX_free(group->mont_data); -+ group->mont_data = NULL; -+ goto err; -+ } -+ -+ ret = 1; -+ -+ err: -+ -+ if (ctx) -+ BN_CTX_free(ctx); -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_mult.c b/Cryptlib/OpenSSL/crypto/ec/ec_mult.c -new file mode 100644 -index 0000000..23b8c30 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_mult.c -@@ -0,0 +1,913 @@ -+/* crypto/ec/ec_mult.c */ -+/* -+ * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2007 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Portions of this software developed by SUN MICROSYSTEMS, INC., -+ * and contributed to the OpenSSL project. -+ */ -+ -+#include -+ -+#include -+ -+#include "ec_lcl.h" -+ -+/* -+ * This file implements the wNAF-based interleaving multi-exponentation method -+ * (); -+ * for multiplication with precomputation, we use wNAF splitting -+ * (). -+ */ -+ -+/* structure for precomputed multiples of the generator */ -+typedef struct ec_pre_comp_st { -+ const EC_GROUP *group; /* parent EC_GROUP object */ -+ size_t blocksize; /* block size for wNAF splitting */ -+ size_t numblocks; /* max. number of blocks for which we have -+ * precomputation */ -+ size_t w; /* window size */ -+ EC_POINT **points; /* array with pre-calculated multiples of -+ * generator: 'num' pointers to EC_POINT -+ * objects followed by a NULL */ -+ size_t num; /* numblocks * 2^(w-1) */ -+ int references; -+} EC_PRE_COMP; -+ -+/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */ -+static void *ec_pre_comp_dup(void *); -+static void ec_pre_comp_free(void *); -+static void ec_pre_comp_clear_free(void *); -+ -+static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) -+{ -+ EC_PRE_COMP *ret = NULL; -+ -+ if (!group) -+ return NULL; -+ -+ ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP)); -+ if (!ret) { -+ ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); -+ return ret; -+ } -+ ret->group = group; -+ ret->blocksize = 8; /* default */ -+ ret->numblocks = 0; -+ ret->w = 4; /* default */ -+ ret->points = NULL; -+ ret->num = 0; -+ ret->references = 1; -+ return ret; -+} -+ -+static void *ec_pre_comp_dup(void *src_) -+{ -+ EC_PRE_COMP *src = src_; -+ -+ /* no need to actually copy, these objects never change! */ -+ -+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); -+ -+ return src_; -+} -+ -+static void ec_pre_comp_free(void *pre_) -+{ -+ int i; -+ EC_PRE_COMP *pre = pre_; -+ -+ if (!pre) -+ return; -+ -+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); -+ if (i > 0) -+ return; -+ -+ if (pre->points) { -+ EC_POINT **p; -+ -+ for (p = pre->points; *p != NULL; p++) -+ EC_POINT_free(*p); -+ OPENSSL_free(pre->points); -+ } -+ OPENSSL_free(pre); -+} -+ -+static void ec_pre_comp_clear_free(void *pre_) -+{ -+ int i; -+ EC_PRE_COMP *pre = pre_; -+ -+ if (!pre) -+ return; -+ -+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); -+ if (i > 0) -+ return; -+ -+ if (pre->points) { -+ EC_POINT **p; -+ -+ for (p = pre->points; *p != NULL; p++) { -+ EC_POINT_clear_free(*p); -+ OPENSSL_cleanse(p, sizeof *p); -+ } -+ OPENSSL_free(pre->points); -+ } -+ OPENSSL_cleanse(pre, sizeof *pre); -+ OPENSSL_free(pre); -+} -+ -+/*- -+ * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. -+ * This is an array r[] of values that are either zero or odd with an -+ * absolute value less than 2^w satisfying -+ * scalar = \sum_j r[j]*2^j -+ * where at most one of any w+1 consecutive digits is non-zero -+ * with the exception that the most significant digit may be only -+ * w-1 zeros away from that next non-zero digit. -+ */ -+static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) -+{ -+ int window_val; -+ int ok = 0; -+ signed char *r = NULL; -+ int sign = 1; -+ int bit, next_bit, mask; -+ size_t len = 0, j; -+ -+ if (BN_is_zero(scalar)) { -+ r = OPENSSL_malloc(1); -+ if (!r) { -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ r[0] = 0; -+ *ret_len = 1; -+ return r; -+ } -+ -+ if (w <= 0 || w > 7) { /* 'signed char' can represent integers with -+ * absolute values less than 2^7 */ -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ bit = 1 << w; /* at most 128 */ -+ next_bit = bit << 1; /* at most 256 */ -+ mask = next_bit - 1; /* at most 255 */ -+ -+ if (BN_is_negative(scalar)) { -+ sign = -1; -+ } -+ -+ if (scalar->d == NULL || scalar->top == 0) { -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ len = BN_num_bits(scalar); -+ r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer -+ * than binary representation (*ret_len will -+ * be set to the actual length, i.e. at most -+ * BN_num_bits(scalar) + 1) */ -+ if (r == NULL) { -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ window_val = scalar->d[0] & mask; -+ j = 0; -+ while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len, -+ * window_val will not -+ * increase */ -+ int digit = 0; -+ -+ /* 0 <= window_val <= 2^(w+1) */ -+ -+ if (window_val & 1) { -+ /* 0 < window_val < 2^(w+1) */ -+ -+ if (window_val & bit) { -+ digit = window_val - next_bit; /* -2^w < digit < 0 */ -+ -+#if 1 /* modified wNAF */ -+ if (j + w + 1 >= len) { -+ /* -+ * special case for generating modified wNAFs: no new -+ * bits will be added into window_val, so using a -+ * positive digit here will decrease the total length of -+ * the representation -+ */ -+ -+ digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ -+ } -+#endif -+ } else { -+ digit = window_val; /* 0 < digit < 2^w */ -+ } -+ -+ if (digit <= -bit || digit >= bit || !(digit & 1)) { -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ window_val -= digit; -+ -+ /* -+ * now window_val is 0 or 2^(w+1) in standard wNAF generation; -+ * for modified window NAFs, it may also be 2^w -+ */ -+ if (window_val != 0 && window_val != next_bit -+ && window_val != bit) { -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ } -+ -+ r[j++] = sign * digit; -+ -+ window_val >>= 1; -+ window_val += bit * BN_is_bit_set(scalar, j + w); -+ -+ if (window_val > next_bit) { -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ } -+ -+ if (j > len + 1) { -+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ len = j; -+ ok = 1; -+ -+ err: -+ if (!ok) { -+ OPENSSL_free(r); -+ r = NULL; -+ } -+ if (ok) -+ *ret_len = len; -+ return r; -+} -+ -+/* -+ * TODO: table should be optimised for the wNAF-based implementation, -+ * sometimes smaller windows will give better performance (thus the -+ * boundaries should be increased) -+ */ -+#define EC_window_bits_for_scalar_size(b) \ -+ ((size_t) \ -+ ((b) >= 2000 ? 6 : \ -+ (b) >= 800 ? 5 : \ -+ (b) >= 300 ? 4 : \ -+ (b) >= 70 ? 3 : \ -+ (b) >= 20 ? 2 : \ -+ 1)) -+ -+/*- -+ * Compute -+ * \sum scalars[i]*points[i], -+ * also including -+ * scalar*generator -+ * in the addition if scalar != NULL -+ */ -+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, -+ size_t num, const EC_POINT *points[], const BIGNUM *scalars[], -+ BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ const EC_POINT *generator = NULL; -+ EC_POINT *tmp = NULL; -+ size_t totalnum; -+ size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ -+ size_t pre_points_per_block = 0; -+ size_t i, j; -+ int k; -+ int r_is_inverted = 0; -+ int r_is_at_infinity = 1; -+ size_t *wsize = NULL; /* individual window sizes */ -+ signed char **wNAF = NULL; /* individual wNAFs */ -+ size_t *wNAF_len = NULL; -+ size_t max_len = 0; -+ size_t num_val; -+ EC_POINT **val = NULL; /* precomputation */ -+ EC_POINT **v; -+ EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or -+ * 'pre_comp->points' */ -+ const EC_PRE_COMP *pre_comp = NULL; -+ int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be -+ * treated like other scalars, i.e. -+ * precomputation is not available */ -+ int ret = 0; -+ -+ if (group->meth != r->meth) { -+ ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ -+ if ((scalar == NULL) && (num == 0)) { -+ return EC_POINT_set_to_infinity(group, r); -+ } -+ -+ for (i = 0; i < num; i++) { -+ if (group->meth != points[i]->meth) { -+ ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ } -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ goto err; -+ } -+ -+ if (scalar != NULL) { -+ generator = EC_GROUP_get0_generator(group); -+ if (generator == NULL) { -+ ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR); -+ goto err; -+ } -+ -+ /* look if we can use precomputed multiples of generator */ -+ -+ pre_comp = -+ EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, -+ ec_pre_comp_free, ec_pre_comp_clear_free); -+ -+ if (pre_comp && pre_comp->numblocks -+ && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == -+ 0)) { -+ blocksize = pre_comp->blocksize; -+ -+ /* -+ * determine maximum number of blocks that wNAF splitting may -+ * yield (NB: maximum wNAF length is bit length plus one) -+ */ -+ numblocks = (BN_num_bits(scalar) / blocksize) + 1; -+ -+ /* -+ * we cannot use more blocks than we have precomputation for -+ */ -+ if (numblocks > pre_comp->numblocks) -+ numblocks = pre_comp->numblocks; -+ -+ pre_points_per_block = (size_t)1 << (pre_comp->w - 1); -+ -+ /* check that pre_comp looks sane */ -+ if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ } else { -+ /* can't use precomputation */ -+ pre_comp = NULL; -+ numblocks = 1; -+ num_scalar = 1; /* treat 'scalar' like 'num'-th element of -+ * 'scalars' */ -+ } -+ } -+ -+ totalnum = num + numblocks; -+ -+ wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]); -+ wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]); -+ wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space -+ * for pivot */ -+ val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]); -+ -+ /* Ensure wNAF is initialised in case we end up going to err */ -+ if (wNAF) -+ wNAF[0] = NULL; /* preliminary pivot */ -+ -+ if (!wsize || !wNAF_len || !wNAF || !val_sub) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* -+ * num_val will be the total number of temporarily precomputed points -+ */ -+ num_val = 0; -+ -+ for (i = 0; i < num + num_scalar; i++) { -+ size_t bits; -+ -+ bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); -+ wsize[i] = EC_window_bits_for_scalar_size(bits); -+ num_val += (size_t)1 << (wsize[i] - 1); -+ wNAF[i + 1] = NULL; /* make sure we always have a pivot */ -+ wNAF[i] = -+ compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], -+ &wNAF_len[i]); -+ if (wNAF[i] == NULL) -+ goto err; -+ if (wNAF_len[i] > max_len) -+ max_len = wNAF_len[i]; -+ } -+ -+ if (numblocks) { -+ /* we go here iff scalar != NULL */ -+ -+ if (pre_comp == NULL) { -+ if (num_scalar != 1) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ /* we have already generated a wNAF for 'scalar' */ -+ } else { -+ signed char *tmp_wNAF = NULL; -+ size_t tmp_len = 0; -+ -+ if (num_scalar != 0) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ /* -+ * use the window size for which we have precomputation -+ */ -+ wsize[num] = pre_comp->w; -+ tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len); -+ if (!tmp_wNAF) -+ goto err; -+ -+ if (tmp_len <= max_len) { -+ /* -+ * One of the other wNAFs is at least as long as the wNAF -+ * belonging to the generator, so wNAF splitting will not buy -+ * us anything. -+ */ -+ -+ numblocks = 1; -+ totalnum = num + 1; /* don't use wNAF splitting */ -+ wNAF[num] = tmp_wNAF; -+ wNAF[num + 1] = NULL; -+ wNAF_len[num] = tmp_len; -+ if (tmp_len > max_len) -+ max_len = tmp_len; -+ /* -+ * pre_comp->points starts with the points that we need here: -+ */ -+ val_sub[num] = pre_comp->points; -+ } else { -+ /* -+ * don't include tmp_wNAF directly into wNAF array - use wNAF -+ * splitting and include the blocks -+ */ -+ -+ signed char *pp; -+ EC_POINT **tmp_points; -+ -+ if (tmp_len < numblocks * blocksize) { -+ /* -+ * possibly we can do with fewer blocks than estimated -+ */ -+ numblocks = (tmp_len + blocksize - 1) / blocksize; -+ if (numblocks > pre_comp->numblocks) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ totalnum = num + numblocks; -+ } -+ -+ /* split wNAF in 'numblocks' parts */ -+ pp = tmp_wNAF; -+ tmp_points = pre_comp->points; -+ -+ for (i = num; i < totalnum; i++) { -+ if (i < totalnum - 1) { -+ wNAF_len[i] = blocksize; -+ if (tmp_len < blocksize) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ tmp_len -= blocksize; -+ } else -+ /* -+ * last block gets whatever is left (this could be -+ * more or less than 'blocksize'!) -+ */ -+ wNAF_len[i] = tmp_len; -+ -+ wNAF[i + 1] = NULL; -+ wNAF[i] = OPENSSL_malloc(wNAF_len[i]); -+ if (wNAF[i] == NULL) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); -+ OPENSSL_free(tmp_wNAF); -+ goto err; -+ } -+ memcpy(wNAF[i], pp, wNAF_len[i]); -+ if (wNAF_len[i] > max_len) -+ max_len = wNAF_len[i]; -+ -+ if (*tmp_points == NULL) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); -+ OPENSSL_free(tmp_wNAF); -+ goto err; -+ } -+ val_sub[i] = tmp_points; -+ tmp_points += pre_points_per_block; -+ pp += blocksize; -+ } -+ OPENSSL_free(tmp_wNAF); -+ } -+ } -+ } -+ -+ /* -+ * All points we precompute now go into a single array 'val'. -+ * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a -+ * subarray of 'pre_comp->points' if we already have precomputation. -+ */ -+ val = OPENSSL_malloc((num_val + 1) * sizeof val[0]); -+ if (val == NULL) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ val[num_val] = NULL; /* pivot element */ -+ -+ /* allocate points for precomputation */ -+ v = val; -+ for (i = 0; i < num + num_scalar; i++) { -+ val_sub[i] = v; -+ for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { -+ *v = EC_POINT_new(group); -+ if (*v == NULL) -+ goto err; -+ v++; -+ } -+ } -+ if (!(v == val + num_val)) { -+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ if (!(tmp = EC_POINT_new(group))) -+ goto err; -+ -+ /*- -+ * prepare precomputed values: -+ * val_sub[i][0] := points[i] -+ * val_sub[i][1] := 3 * points[i] -+ * val_sub[i][2] := 5 * points[i] -+ * ... -+ */ -+ for (i = 0; i < num + num_scalar; i++) { -+ if (i < num) { -+ if (!EC_POINT_copy(val_sub[i][0], points[i])) -+ goto err; -+ } else { -+ if (!EC_POINT_copy(val_sub[i][0], generator)) -+ goto err; -+ } -+ -+ if (wsize[i] > 1) { -+ if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) -+ goto err; -+ for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) { -+ if (!EC_POINT_add -+ (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) -+ goto err; -+ } -+ } -+ } -+ -+#if 1 /* optional; EC_window_bits_for_scalar_size -+ * assumes we do this step */ -+ if (!EC_POINTs_make_affine(group, num_val, val, ctx)) -+ goto err; -+#endif -+ -+ r_is_at_infinity = 1; -+ -+ for (k = max_len - 1; k >= 0; k--) { -+ if (!r_is_at_infinity) { -+ if (!EC_POINT_dbl(group, r, r, ctx)) -+ goto err; -+ } -+ -+ for (i = 0; i < totalnum; i++) { -+ if (wNAF_len[i] > (size_t)k) { -+ int digit = wNAF[i][k]; -+ int is_neg; -+ -+ if (digit) { -+ is_neg = digit < 0; -+ -+ if (is_neg) -+ digit = -digit; -+ -+ if (is_neg != r_is_inverted) { -+ if (!r_is_at_infinity) { -+ if (!EC_POINT_invert(group, r, ctx)) -+ goto err; -+ } -+ r_is_inverted = !r_is_inverted; -+ } -+ -+ /* digit > 0 */ -+ -+ if (r_is_at_infinity) { -+ if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) -+ goto err; -+ r_is_at_infinity = 0; -+ } else { -+ if (!EC_POINT_add -+ (group, r, r, val_sub[i][digit >> 1], ctx)) -+ goto err; -+ } -+ } -+ } -+ } -+ } -+ -+ if (r_is_at_infinity) { -+ if (!EC_POINT_set_to_infinity(group, r)) -+ goto err; -+ } else { -+ if (r_is_inverted) -+ if (!EC_POINT_invert(group, r, ctx)) -+ goto err; -+ } -+ -+ ret = 1; -+ -+ err: -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ if (tmp != NULL) -+ EC_POINT_free(tmp); -+ if (wsize != NULL) -+ OPENSSL_free(wsize); -+ if (wNAF_len != NULL) -+ OPENSSL_free(wNAF_len); -+ if (wNAF != NULL) { -+ signed char **w; -+ -+ for (w = wNAF; *w != NULL; w++) -+ OPENSSL_free(*w); -+ -+ OPENSSL_free(wNAF); -+ } -+ if (val != NULL) { -+ for (v = val; *v != NULL; v++) -+ EC_POINT_clear_free(*v); -+ -+ OPENSSL_free(val); -+ } -+ if (val_sub != NULL) { -+ OPENSSL_free(val_sub); -+ } -+ return ret; -+} -+ -+/*- -+ * ec_wNAF_precompute_mult() -+ * creates an EC_PRE_COMP object with preprecomputed multiples of the generator -+ * for use with wNAF splitting as implemented in ec_wNAF_mul(). -+ * -+ * 'pre_comp->points' is an array of multiples of the generator -+ * of the following form: -+ * points[0] = generator; -+ * points[1] = 3 * generator; -+ * ... -+ * points[2^(w-1)-1] = (2^(w-1)-1) * generator; -+ * points[2^(w-1)] = 2^blocksize * generator; -+ * points[2^(w-1)+1] = 3 * 2^blocksize * generator; -+ * ... -+ * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator -+ * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator -+ * ... -+ * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator -+ * points[2^(w-1)*numblocks] = NULL -+ */ -+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -+{ -+ const EC_POINT *generator; -+ EC_POINT *tmp_point = NULL, *base = NULL, **var; -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *order; -+ size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; -+ EC_POINT **points = NULL; -+ EC_PRE_COMP *pre_comp; -+ int ret = 0; -+ -+ /* if there is an old EC_PRE_COMP object, throw it away */ -+ EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, -+ ec_pre_comp_free, ec_pre_comp_clear_free); -+ -+ if ((pre_comp = ec_pre_comp_new(group)) == NULL) -+ return 0; -+ -+ generator = EC_GROUP_get0_generator(group); -+ if (generator == NULL) { -+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); -+ goto err; -+ } -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ goto err; -+ } -+ -+ BN_CTX_start(ctx); -+ order = BN_CTX_get(ctx); -+ if (order == NULL) -+ goto err; -+ -+ if (!EC_GROUP_get_order(group, order, ctx)) -+ goto err; -+ if (BN_is_zero(order)) { -+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); -+ goto err; -+ } -+ -+ bits = BN_num_bits(order); -+ /* -+ * The following parameters mean we precompute (approximately) one point -+ * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other -+ * bit lengths, other parameter combinations might provide better -+ * efficiency. -+ */ -+ blocksize = 8; -+ w = 4; -+ if (EC_window_bits_for_scalar_size(bits) > w) { -+ /* let's not make the window too small ... */ -+ w = EC_window_bits_for_scalar_size(bits); -+ } -+ -+ numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks -+ * to use for wNAF -+ * splitting */ -+ -+ pre_points_per_block = (size_t)1 << (w - 1); -+ num = pre_points_per_block * numblocks; /* number of points to compute -+ * and store */ -+ -+ points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1)); -+ if (!points) { -+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ var = points; -+ var[num] = NULL; /* pivot */ -+ for (i = 0; i < num; i++) { -+ if ((var[i] = EC_POINT_new(group)) == NULL) { -+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ -+ if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) { -+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (!EC_POINT_copy(base, generator)) -+ goto err; -+ -+ /* do the precomputation */ -+ for (i = 0; i < numblocks; i++) { -+ size_t j; -+ -+ if (!EC_POINT_dbl(group, tmp_point, base, ctx)) -+ goto err; -+ -+ if (!EC_POINT_copy(*var++, base)) -+ goto err; -+ -+ for (j = 1; j < pre_points_per_block; j++, var++) { -+ /* -+ * calculate odd multiples of the current base point -+ */ -+ if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) -+ goto err; -+ } -+ -+ if (i < numblocks - 1) { -+ /* -+ * get the next base (multiply current one by 2^blocksize) -+ */ -+ size_t k; -+ -+ if (blocksize <= 2) { -+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ if (!EC_POINT_dbl(group, base, tmp_point, ctx)) -+ goto err; -+ for (k = 2; k < blocksize; k++) { -+ if (!EC_POINT_dbl(group, base, base, ctx)) -+ goto err; -+ } -+ } -+ } -+ -+ if (!EC_POINTs_make_affine(group, num, points, ctx)) -+ goto err; -+ -+ pre_comp->group = group; -+ pre_comp->blocksize = blocksize; -+ pre_comp->numblocks = numblocks; -+ pre_comp->w = w; -+ pre_comp->points = points; -+ points = NULL; -+ pre_comp->num = num; -+ -+ if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp, -+ ec_pre_comp_dup, ec_pre_comp_free, -+ ec_pre_comp_clear_free)) -+ goto err; -+ pre_comp = NULL; -+ -+ ret = 1; -+ err: -+ if (ctx != NULL) -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ if (pre_comp) -+ ec_pre_comp_free(pre_comp); -+ if (points) { -+ EC_POINT **p; -+ -+ for (p = points; *p != NULL; p++) -+ EC_POINT_free(*p); -+ OPENSSL_free(points); -+ } -+ if (tmp_point) -+ EC_POINT_free(tmp_point); -+ if (base) -+ EC_POINT_free(base); -+ return ret; -+} -+ -+int ec_wNAF_have_precompute_mult(const EC_GROUP *group) -+{ -+ if (EC_EX_DATA_get_data -+ (group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, -+ ec_pre_comp_clear_free) != NULL) -+ return 1; -+ else -+ return 0; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_oct.c b/Cryptlib/OpenSSL/crypto/ec/ec_oct.c -new file mode 100644 -index 0000000..4ef58f6 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_oct.c -@@ -0,0 +1,163 @@ -+/* crypto/ec/ec_lib.c */ -+/* -+ * Originally written by Bodo Moeller for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2003 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Binary polynomial ECC support in OpenSSL originally developed by -+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "ec_lcl.h" -+ -+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, -+ EC_POINT *point, const BIGNUM *x, -+ int y_bit, BN_CTX *ctx) -+{ -+ if (group->meth->point_set_compressed_coordinates == 0 -+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { -+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, -+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, -+ EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { -+ if (group->meth->field_type == NID_X9_62_prime_field) -+ return ec_GFp_simple_set_compressed_coordinates(group, point, x, -+ y_bit, ctx); -+ else -+#ifdef OPENSSL_NO_EC2M -+ { -+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, -+ EC_R_GF2M_NOT_SUPPORTED); -+ return 0; -+ } -+#else -+ return ec_GF2m_simple_set_compressed_coordinates(group, point, x, -+ y_bit, ctx); -+#endif -+ } -+ return group->meth->point_set_compressed_coordinates(group, point, x, -+ y_bit, ctx); -+} -+ -+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, -+ point_conversion_form_t form, unsigned char *buf, -+ size_t len, BN_CTX *ctx) -+{ -+ if (group->meth->point2oct == 0 -+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { -+ ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { -+ if (group->meth->field_type == NID_X9_62_prime_field) -+ return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); -+ else -+#ifdef OPENSSL_NO_EC2M -+ { -+ ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED); -+ return 0; -+ } -+#else -+ return ec_GF2m_simple_point2oct(group, point, -+ form, buf, len, ctx); -+#endif -+ } -+ -+ return group->meth->point2oct(group, point, form, buf, len, ctx); -+} -+ -+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, -+ const unsigned char *buf, size_t len, BN_CTX *ctx) -+{ -+ if (group->meth->oct2point == 0 -+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { -+ ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ return 0; -+ } -+ if (group->meth != point->meth) { -+ ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); -+ return 0; -+ } -+ if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { -+ if (group->meth->field_type == NID_X9_62_prime_field) -+ return ec_GFp_simple_oct2point(group, point, buf, len, ctx); -+ else -+#ifdef OPENSSL_NO_EC2M -+ { -+ ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED); -+ return 0; -+ } -+#else -+ return ec_GF2m_simple_oct2point(group, point, buf, len, ctx); -+#endif -+ } -+ return group->meth->oct2point(group, point, buf, len, ctx); -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_pmeth.c b/Cryptlib/OpenSSL/crypto/ec/ec_pmeth.c -new file mode 100644 -index 0000000..9844857 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_pmeth.c -@@ -0,0 +1,410 @@ -+/* -+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project -+ * 2006. -+ */ -+/* ==================================================================== -+ * Copyright (c) 2006 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 -+ * licensing@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 -+#include "cryptlib.h" -+#include -+#include -+#include -+#include "ec_lcl.h" -+#include -+#include -+#include "evp_locl.h" -+#include -+ -+/* EC pkey context structure */ -+ -+typedef struct { -+ /* Key and paramgen group */ -+ EC_GROUP *gen_group; -+ /* message digest */ -+ const EVP_MD *md; -+ /* Duplicate key if custom cofactor needed */ -+ EC_KEY *co_key; -+ /* Cofactor mode */ -+ signed char cofactor_mode; -+ /* KDF (if any) to use for ECDH */ -+ char kdf_type; -+ /* Message digest to use for key derivation */ -+ const EVP_MD *kdf_md; -+ /* User key material */ -+ unsigned char *kdf_ukm; -+ size_t kdf_ukmlen; -+ /* KDF output length */ -+ size_t kdf_outlen; -+} EC_PKEY_CTX; -+ -+static int pkey_ec_init(EVP_PKEY_CTX *ctx) -+{ -+ EC_PKEY_CTX *dctx; -+ dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); -+ if (!dctx) -+ return 0; -+ dctx->gen_group = NULL; -+ dctx->md = NULL; -+ -+ 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_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -+{ -+ EC_PKEY_CTX *dctx, *sctx; -+ if (!pkey_ec_init(dst)) -+ return 0; -+ sctx = src->data; -+ dctx = dst->data; -+ if (sctx->gen_group) { -+ dctx->gen_group = EC_GROUP_dup(sctx->gen_group); -+ if (!dctx->gen_group) -+ return 0; -+ } -+ dctx->md = sctx->md; -+ -+ if (sctx->co_key) { -+ dctx->co_key = EC_KEY_dup(sctx->co_key); -+ if (!dctx->co_key) -+ return 0; -+ } -+ dctx->kdf_type = sctx->kdf_type; -+ dctx->kdf_md = sctx->kdf_md; -+ dctx->kdf_outlen = sctx->kdf_outlen; -+ if (sctx->kdf_ukm) { -+ dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); -+ if (!dctx->kdf_ukm) -+ return 0; -+ } else -+ dctx->kdf_ukm = NULL; -+ dctx->kdf_ukmlen = sctx->kdf_ukmlen; -+ return 1; -+} -+ -+static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) -+{ -+ EC_PKEY_CTX *dctx = ctx->data; -+ if (dctx) { -+ if (dctx->gen_group) -+ EC_GROUP_free(dctx->gen_group); -+ if (dctx->co_key) -+ EC_KEY_free(dctx->co_key); -+ if (dctx->kdf_ukm) -+ OPENSSL_free(dctx->kdf_ukm); -+ OPENSSL_free(dctx); -+ } -+} -+ -+static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -+{ -+ EC_PKEY_CTX *dctx = ctx->data; -+ EC_GROUP *group; -+ switch (type) { -+ case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: -+ group = EC_GROUP_new_by_curve_name(p1); -+ if (group == NULL) { -+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); -+ return 0; -+ } -+ if (dctx->gen_group) -+ EC_GROUP_free(dctx->gen_group); -+ dctx->gen_group = group; -+ return 1; -+ -+ case EVP_PKEY_CTRL_EC_PARAM_ENC: -+ if (!dctx->gen_group) { -+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET); -+ return 0; -+ } -+ EC_GROUP_set_asn1_flag(dctx->gen_group, p1); -+ return 1; -+ -+#ifndef OPENSSL_NO_ECDH -+ case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: -+ if (p1 == -2) { -+ if (dctx->cofactor_mode != -1) -+ return dctx->cofactor_mode; -+ else { -+ EC_KEY *ec_key = ctx->pkey->pkey.ec; -+ return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : -+ 0; -+ } -+ } else if (p1 < -1 || p1 > 1) -+ return -2; -+ dctx->cofactor_mode = p1; -+ if (p1 != -1) { -+ EC_KEY *ec_key = ctx->pkey->pkey.ec; -+ if (!ec_key->group) -+ return -2; -+ /* If cofactor is 1 cofactor mode does nothing */ -+ if (BN_is_one(&ec_key->group->cofactor)) -+ return 1; -+ if (!dctx->co_key) { -+ dctx->co_key = EC_KEY_dup(ec_key); -+ if (!dctx->co_key) -+ return 0; -+ } -+ if (p1) -+ EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); -+ else -+ EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); -+ } else if (dctx->co_key) { -+ EC_KEY_free(dctx->co_key); -+ dctx->co_key = NULL; -+ } -+ return 1; -+#endif -+ -+ case EVP_PKEY_CTRL_EC_KDF_TYPE: -+ if (p1 == -2) -+ return dctx->kdf_type; -+ if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62) -+ return -2; -+ dctx->kdf_type = p1; -+ return 1; -+ -+ case EVP_PKEY_CTRL_EC_KDF_MD: -+ dctx->kdf_md = p2; -+ return 1; -+ -+ case EVP_PKEY_CTRL_GET_EC_KDF_MD: -+ *(const EVP_MD **)p2 = dctx->kdf_md; -+ return 1; -+ -+ case EVP_PKEY_CTRL_EC_KDF_OUTLEN: -+ if (p1 <= 0) -+ return -2; -+ dctx->kdf_outlen = (size_t)p1; -+ return 1; -+ -+ case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: -+ *(int *)p2 = dctx->kdf_outlen; -+ return 1; -+ -+ case EVP_PKEY_CTRL_EC_KDF_UKM: -+ if (dctx->kdf_ukm) -+ OPENSSL_free(dctx->kdf_ukm); -+ dctx->kdf_ukm = p2; -+ if (p2) -+ dctx->kdf_ukmlen = p1; -+ else -+ dctx->kdf_ukmlen = 0; -+ return 1; -+ -+ case EVP_PKEY_CTRL_GET_EC_KDF_UKM: -+ *(unsigned char **)p2 = dctx->kdf_ukm; -+ return dctx->kdf_ukmlen; -+ -+ case EVP_PKEY_CTRL_MD: -+ if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && -+ 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 && -+ EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && -+ EVP_MD_type((const EVP_MD *)p2) != NID_sha512 && -+ EVP_MD_type((const EVP_MD *)p2) != NID_sm3) { -+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); -+ return 0; -+ } -+ dctx->md = p2; -+ return 1; -+ -+ case EVP_PKEY_CTRL_GET_MD: -+ *(const EVP_MD **)p2 = dctx->md; -+ return 1; -+ -+ case EVP_PKEY_CTRL_PEER_KEY: -+ /* Default behaviour is OK */ -+ case EVP_PKEY_CTRL_DIGESTINIT: -+ case EVP_PKEY_CTRL_PKCS7_SIGN: -+ case EVP_PKEY_CTRL_CMS_SIGN: -+ return 1; -+ -+ default: -+ return -2; -+ -+ } -+} -+ -+static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, -+ const char *type, const char *value) -+{ -+ if (!strcmp(type, "ec_paramgen_curve")) { -+ int nid; -+ nid = EC_curve_nist2nid(value); -+ if (nid == NID_undef) -+ nid = OBJ_sn2nid(value); -+ if (nid == NID_undef) -+ nid = OBJ_ln2nid(value); -+ if (nid == NID_undef) { -+ ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); -+ return 0; -+ } -+ return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); -+ } else if (!strcmp(type, "ec_param_enc")) { -+ int param_enc; -+ if (!strcmp(value, "explicit")) -+ param_enc = 0; -+ else if (!strcmp(value, "named_curve")) -+ param_enc = OPENSSL_EC_NAMED_CURVE; -+ else -+ return -2; -+ return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); -+ } else if (!strcmp(type, "ecdh_kdf_md")) { -+ const EVP_MD *md; -+ if (!(md = EVP_get_digestbyname(value))) { -+ ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST); -+ return 0; -+ } -+ return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md); -+ } else if (!strcmp(type, "ecdh_cofactor_mode")) { -+ int co_mode; -+ co_mode = atoi(value); -+ return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode); -+ } -+ -+ return -2; -+} -+ -+static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -+{ -+ EC_KEY *ec = NULL; -+ EC_PKEY_CTX *dctx = ctx->data; -+ int ret = 0; -+ if (dctx->gen_group == NULL) { -+ ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); -+ return 0; -+ } -+ ec = EC_KEY_new(); -+ if (!ec) -+ return 0; -+ ret = EC_KEY_set_group(ec, dctx->gen_group); -+ if (ret) -+ EVP_PKEY_assign_EC_KEY(pkey, ec); -+ else -+ EC_KEY_free(ec); -+ return ret; -+} -+ -+static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -+{ -+ EC_KEY *ec = NULL; -+ EC_PKEY_CTX *dctx = ctx->data; -+ if (ctx->pkey == NULL && dctx->gen_group == NULL) { -+ ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); -+ return 0; -+ } -+ ec = EC_KEY_new(); -+ if (!ec) -+ return 0; -+ EVP_PKEY_assign_EC_KEY(pkey, ec); -+ if (ctx->pkey) { -+ /* Note: if error return, pkey is freed by parent routine */ -+ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) -+ return 0; -+ } else { -+ if (!EC_KEY_set_group(ec, dctx->gen_group)) -+ return 0; -+ } -+ return EC_KEY_generate_key(pkey->pkey.ec); -+} -+ -+const EVP_PKEY_METHOD ec_pkey_meth = { -+ EVP_PKEY_EC, -+ 0, -+ pkey_ec_init, -+ pkey_ec_copy, -+ pkey_ec_cleanup, -+ -+ 0, -+ pkey_ec_paramgen, -+ -+ 0, -+ pkey_ec_keygen, -+ -+ 0, -+ 0, // pkey_ec_sign, -+ -+ 0, -+ 0, // pkey_ec_verify, -+ -+ 0, 0, -+ -+ 0, 0, 0, 0, -+ -+ 0, 0, -+ -+ 0, 0, -+ -+ 0, -+#ifndef OPENSSL_NO_ECDH -+ pkey_ec_kdf_derive, -+#else -+ 0, -+#endif -+ -+ pkey_ec_ctrl, -+ pkey_ec_ctrl_str -+}; -diff --git a/Cryptlib/OpenSSL/crypto/ec/ec_print.c b/Cryptlib/OpenSSL/crypto/ec/ec_print.c -new file mode 100644 -index 0000000..96b294d ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ec_print.c -@@ -0,0 +1,179 @@ -+/* crypto/ec/ec_print.c */ -+/* ==================================================================== -+ * 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 -+#include "ec_lcl.h" -+ -+BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, -+ const EC_POINT *point, -+ point_conversion_form_t form, -+ BIGNUM *ret, BN_CTX *ctx) -+{ -+ size_t buf_len = 0; -+ unsigned char *buf; -+ -+ buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); -+ if (buf_len == 0) -+ return NULL; -+ -+ if ((buf = OPENSSL_malloc(buf_len)) == NULL) -+ return NULL; -+ -+ if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { -+ OPENSSL_free(buf); -+ return NULL; -+ } -+ -+ ret = BN_bin2bn(buf, buf_len, ret); -+ -+ OPENSSL_free(buf); -+ -+ return ret; -+} -+ -+EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, -+ const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) -+{ -+ size_t buf_len = 0; -+ unsigned char *buf; -+ EC_POINT *ret; -+ -+ if ((buf_len = BN_num_bytes(bn)) == 0) -+ return NULL; -+ buf = OPENSSL_malloc(buf_len); -+ if (buf == NULL) -+ return NULL; -+ -+ if (!BN_bn2bin(bn, buf)) { -+ OPENSSL_free(buf); -+ return NULL; -+ } -+ -+ if (point == NULL) { -+ if ((ret = EC_POINT_new(group)) == NULL) { -+ OPENSSL_free(buf); -+ return NULL; -+ } -+ } else -+ ret = point; -+ -+ if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { -+ if (point == NULL) -+ EC_POINT_clear_free(ret); -+ OPENSSL_free(buf); -+ return NULL; -+ } -+ -+ OPENSSL_free(buf); -+ return ret; -+} -+ -+static const char *HEX_DIGITS = "0123456789ABCDEF"; -+ -+/* the return value must be freed (using OPENSSL_free()) */ -+char *EC_POINT_point2hex(const EC_GROUP *group, -+ const EC_POINT *point, -+ point_conversion_form_t form, BN_CTX *ctx) -+{ -+ char *ret, *p; -+ size_t buf_len = 0, i; -+ unsigned char *buf, *pbuf; -+ -+ buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); -+ if (buf_len == 0) -+ return NULL; -+ -+ if ((buf = OPENSSL_malloc(buf_len)) == NULL) -+ return NULL; -+ -+ if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { -+ OPENSSL_free(buf); -+ return NULL; -+ } -+ -+ ret = (char *)OPENSSL_malloc(buf_len * 2 + 2); -+ if (ret == NULL) { -+ OPENSSL_free(buf); -+ return NULL; -+ } -+ p = ret; -+ pbuf = buf; -+ for (i = buf_len; i > 0; i--) { -+ int v = (int)*(pbuf++); -+ *(p++) = HEX_DIGITS[v >> 4]; -+ *(p++) = HEX_DIGITS[v & 0x0F]; -+ } -+ *p = '\0'; -+ -+ OPENSSL_free(buf); -+ -+ return ret; -+} -+ -+EC_POINT *EC_POINT_hex2point(const EC_GROUP *group, -+ const char *buf, EC_POINT *point, BN_CTX *ctx) -+{ -+ EC_POINT *ret = NULL; -+ BIGNUM *tmp_bn = NULL; -+ -+ if (!BN_hex2bn(&tmp_bn, buf)) -+ return NULL; -+ -+ ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); -+ -+ BN_clear_free(tmp_bn); -+ -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/eck_prn.c b/Cryptlib/OpenSSL/crypto/ec/eck_prn.c -new file mode 100644 -index 0000000..a3bd1db ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/eck_prn.c -@@ -0,0 +1,330 @@ -+/* crypto/ec/eck_prn.c */ -+/* -+ * 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Portions originally developed by SUN MICROSYSTEMS, INC., and -+ * contributed to the OpenSSL project. -+ */ -+ -+#include -+#include "cryptlib.h" -+#include -+#include -+#include -+ -+int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) -+{ -+ EVP_PKEY *pk; -+ int ret; -+ pk = EVP_PKEY_new(); -+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) -+ return 0; -+ ret = EVP_PKEY_print_private(bp, pk, off, NULL); -+ EVP_PKEY_free(pk); -+ return ret; -+} -+ -+int ECParameters_print(BIO *bp, const EC_KEY *x) -+{ -+ EVP_PKEY *pk; -+ int ret; -+ pk = EVP_PKEY_new(); -+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) -+ return 0; -+ ret = EVP_PKEY_print_params(bp, pk, 4, NULL); -+ EVP_PKEY_free(pk); -+ return ret; -+} -+ -+static int print_bin(BIO *fp, const char *str, const unsigned char *num, -+ size_t len, int off); -+ -+int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) -+{ -+ unsigned char *buffer = NULL; -+ size_t buf_len = 0, i; -+ int ret = 0, reason = ERR_R_BIO_LIB; -+ BN_CTX *ctx = NULL; -+ const EC_POINT *point = NULL; -+ BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, -+ *order = NULL, *cofactor = NULL; -+ const unsigned char *seed; -+ size_t seed_len = 0; -+ -+ static const char *gen_compressed = "Generator (compressed):"; -+ static const char *gen_uncompressed = "Generator (uncompressed):"; -+ static const char *gen_hybrid = "Generator (hybrid):"; -+ -+ if (!x) { -+ reason = ERR_R_PASSED_NULL_PARAMETER; -+ goto err; -+ } -+ -+ ctx = BN_CTX_new(); -+ if (ctx == NULL) { -+ reason = ERR_R_MALLOC_FAILURE; -+ goto err; -+ } -+ -+ if (EC_GROUP_get_asn1_flag(x)) { -+ /* the curve parameter are given by an asn1 OID */ -+ int nid; -+ const char *nname; -+ -+ if (!BIO_indent(bp, off, 128)) -+ goto err; -+ -+ nid = EC_GROUP_get_curve_name(x); -+ if (nid == 0) -+ goto err; -+ -+ if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) -+ goto err; -+ if (BIO_printf(bp, "\n") <= 0) -+ goto err; -+ nname = EC_curve_nid2nist(nid); -+ if (nname) { -+ if (!BIO_indent(bp, off, 128)) -+ goto err; -+ if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0) -+ goto err; -+ } -+ } else { -+ /* explicit parameters */ -+ int is_char_two = 0; -+ point_conversion_form_t form; -+ int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); -+ -+ if (tmp_nid == NID_X9_62_characteristic_two_field) -+ is_char_two = 1; -+ -+ if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || -+ (b = BN_new()) == NULL || (order = BN_new()) == NULL || -+ (cofactor = BN_new()) == NULL) { -+ reason = ERR_R_MALLOC_FAILURE; -+ goto err; -+ } -+#ifndef OPENSSL_NO_EC2M -+ if (is_char_two) { -+ if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) { -+ reason = ERR_R_EC_LIB; -+ goto err; -+ } -+ } else /* prime field */ -+#endif -+ { -+ if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) { -+ reason = ERR_R_EC_LIB; -+ goto err; -+ } -+ } -+ -+ if ((point = EC_GROUP_get0_generator(x)) == NULL) { -+ reason = ERR_R_EC_LIB; -+ goto err; -+ } -+ if (!EC_GROUP_get_order(x, order, NULL) || -+ !EC_GROUP_get_cofactor(x, cofactor, NULL)) { -+ reason = ERR_R_EC_LIB; -+ goto err; -+ } -+ -+ form = EC_GROUP_get_point_conversion_form(x); -+ -+ if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { -+ reason = ERR_R_EC_LIB; -+ goto err; -+ } -+ -+ buf_len = (size_t)BN_num_bytes(p); -+ if (buf_len < (i = (size_t)BN_num_bytes(a))) -+ buf_len = i; -+ if (buf_len < (i = (size_t)BN_num_bytes(b))) -+ buf_len = i; -+ if (buf_len < (i = (size_t)BN_num_bytes(gen))) -+ buf_len = i; -+ if (buf_len < (i = (size_t)BN_num_bytes(order))) -+ buf_len = i; -+ if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) -+ buf_len = i; -+ -+ if ((seed = EC_GROUP_get0_seed(x)) != NULL) -+ seed_len = EC_GROUP_get_seed_len(x); -+ -+ buf_len += 10; -+ if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { -+ reason = ERR_R_MALLOC_FAILURE; -+ goto err; -+ } -+ -+ if (!BIO_indent(bp, off, 128)) -+ goto err; -+ -+ /* print the 'short name' of the field type */ -+ if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) -+ <= 0) -+ goto err; -+ -+ if (is_char_two) { -+ /* print the 'short name' of the base type OID */ -+ int basis_type = EC_GROUP_get_basis_type(x); -+ if (basis_type == 0) -+ goto err; -+ -+ if (!BIO_indent(bp, off, 128)) -+ goto err; -+ -+ if (BIO_printf(bp, "Basis Type: %s\n", -+ OBJ_nid2sn(basis_type)) <= 0) -+ goto err; -+ -+ /* print the polynomial */ -+ if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, -+ off)) -+ goto err; -+ } else { -+ if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off)) -+ goto err; -+ } -+ if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) -+ goto err; -+ if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) -+ goto err; -+ if (form == POINT_CONVERSION_COMPRESSED) { -+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, -+ buffer, off)) -+ goto err; -+ } else if (form == POINT_CONVERSION_UNCOMPRESSED) { -+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, -+ buffer, off)) -+ goto err; -+ } else { /* form == POINT_CONVERSION_HYBRID */ -+ -+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, -+ buffer, off)) -+ goto err; -+ } -+ if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, -+ buffer, off)) -+ goto err; -+ if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, -+ buffer, off)) -+ goto err; -+ if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) -+ goto err; -+ } -+ ret = 1; -+ err: -+ if (!ret) -+ ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); -+ if (p) -+ BN_free(p); -+ if (a) -+ BN_free(a); -+ if (b) -+ BN_free(b); -+ if (gen) -+ BN_free(gen); -+ if (order) -+ BN_free(order); -+ if (cofactor) -+ BN_free(cofactor); -+ if (ctx) -+ BN_CTX_free(ctx); -+ if (buffer != NULL) -+ OPENSSL_free(buffer); -+ return (ret); -+} -+ -+static int print_bin(BIO *fp, const char *name, const unsigned char *buf, -+ size_t len, int off) -+{ -+ size_t i; -+ char str[128]; -+ -+ if (buf == NULL) -+ return 1; -+ if (off > 0) { -+ if (off > 128) -+ off = 128; -+ memset(str, ' ', off); -+ if (BIO_write(fp, str, off) <= 0) -+ return 0; -+ } else { -+ off = 0; -+ } -+ -+ if (BIO_printf(fp, "%s", name) <= 0) -+ return 0; -+ -+ for (i = 0; i < len; i++) { -+ if ((i % 15) == 0) { -+ str[0] = '\n'; -+ memset(&(str[1]), ' ', off + 4); -+ if (BIO_write(fp, str, off + 1 + 4) <= 0) -+ return 0; -+ } -+ if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= -+ 0) -+ return 0; -+ } -+ if (BIO_write(fp, "\n", 1) <= 0) -+ return 0; -+ -+ return 1; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ecp_mont.c b/Cryptlib/OpenSSL/crypto/ec/ecp_mont.c -new file mode 100644 -index 0000000..b2de7fa ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ecp_mont.c -@@ -0,0 +1,308 @@ -+/* crypto/ec/ecp_mont.c */ -+/* -+ * Originally written by Bodo Moeller for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2001 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Portions of this software developed by SUN MICROSYSTEMS, INC., -+ * and contributed to the OpenSSL project. -+ */ -+ -+#include -+ -+#ifdef OPENSSL_FIPS -+# include -+#endif -+ -+#include "ec_lcl.h" -+ -+const EC_METHOD *EC_GFp_mont_method(void) -+{ -+ static const EC_METHOD ret = { -+ EC_FLAGS_DEFAULT_OCT, -+ NID_X9_62_prime_field, -+ ec_GFp_mont_group_init, -+ ec_GFp_mont_group_finish, -+ ec_GFp_mont_group_clear_finish, -+ ec_GFp_mont_group_copy, -+ ec_GFp_mont_group_set_curve, -+ ec_GFp_simple_group_get_curve, -+ ec_GFp_simple_group_get_degree, -+ ec_GFp_simple_group_check_discriminant, -+ ec_GFp_simple_point_init, -+ ec_GFp_simple_point_finish, -+ ec_GFp_simple_point_clear_finish, -+ ec_GFp_simple_point_copy, -+ ec_GFp_simple_point_set_to_infinity, -+ ec_GFp_simple_set_Jprojective_coordinates_GFp, -+ ec_GFp_simple_get_Jprojective_coordinates_GFp, -+ ec_GFp_simple_point_set_affine_coordinates, -+ ec_GFp_simple_point_get_affine_coordinates, -+ 0, 0, 0, -+ ec_GFp_simple_add, -+ ec_GFp_simple_dbl, -+ ec_GFp_simple_invert, -+ ec_GFp_simple_is_at_infinity, -+ ec_GFp_simple_is_on_curve, -+ ec_GFp_simple_cmp, -+ ec_GFp_simple_make_affine, -+ ec_GFp_simple_points_make_affine, -+ 0 /* mul */ , -+ 0 /* precompute_mult */ , -+ 0 /* have_precompute_mult */ , -+ ec_GFp_mont_field_mul, -+ ec_GFp_mont_field_sqr, -+ 0 /* field_div */ , -+ ec_GFp_mont_field_encode, -+ ec_GFp_mont_field_decode, -+ ec_GFp_mont_field_set_to_one -+ }; -+ -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode()) -+ return fips_ec_gfp_mont_method(); -+#endif -+ -+ return &ret; -+} -+ -+int ec_GFp_mont_group_init(EC_GROUP *group) -+{ -+ int ok; -+ -+ ok = ec_GFp_simple_group_init(group); -+ group->field_data1 = NULL; -+ group->field_data2 = NULL; -+ return ok; -+} -+ -+void ec_GFp_mont_group_finish(EC_GROUP *group) -+{ -+ if (group->field_data1 != NULL) { -+ BN_MONT_CTX_free(group->field_data1); -+ group->field_data1 = NULL; -+ } -+ if (group->field_data2 != NULL) { -+ BN_free(group->field_data2); -+ group->field_data2 = NULL; -+ } -+ ec_GFp_simple_group_finish(group); -+} -+ -+void ec_GFp_mont_group_clear_finish(EC_GROUP *group) -+{ -+ if (group->field_data1 != NULL) { -+ BN_MONT_CTX_free(group->field_data1); -+ group->field_data1 = NULL; -+ } -+ if (group->field_data2 != NULL) { -+ BN_clear_free(group->field_data2); -+ group->field_data2 = NULL; -+ } -+ ec_GFp_simple_group_clear_finish(group); -+} -+ -+int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) -+{ -+ if (dest->field_data1 != NULL) { -+ BN_MONT_CTX_free(dest->field_data1); -+ dest->field_data1 = NULL; -+ } -+ if (dest->field_data2 != NULL) { -+ BN_clear_free(dest->field_data2); -+ dest->field_data2 = NULL; -+ } -+ -+ if (!ec_GFp_simple_group_copy(dest, src)) -+ return 0; -+ -+ if (src->field_data1 != NULL) { -+ dest->field_data1 = BN_MONT_CTX_new(); -+ if (dest->field_data1 == NULL) -+ return 0; -+ if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) -+ goto err; -+ } -+ if (src->field_data2 != NULL) { -+ dest->field_data2 = BN_dup(src->field_data2); -+ if (dest->field_data2 == NULL) -+ goto err; -+ } -+ -+ return 1; -+ -+ err: -+ if (dest->field_data1 != NULL) { -+ BN_MONT_CTX_free(dest->field_data1); -+ dest->field_data1 = NULL; -+ } -+ return 0; -+} -+ -+int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, -+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ BN_MONT_CTX *mont = NULL; -+ BIGNUM *one = NULL; -+ int ret = 0; -+ -+ if (group->field_data1 != NULL) { -+ BN_MONT_CTX_free(group->field_data1); -+ group->field_data1 = NULL; -+ } -+ if (group->field_data2 != NULL) { -+ BN_free(group->field_data2); -+ group->field_data2 = NULL; -+ } -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ mont = BN_MONT_CTX_new(); -+ if (mont == NULL) -+ goto err; -+ if (!BN_MONT_CTX_set(mont, p, ctx)) { -+ ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB); -+ goto err; -+ } -+ one = BN_new(); -+ if (one == NULL) -+ goto err; -+ if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) -+ goto err; -+ -+ group->field_data1 = mont; -+ mont = NULL; -+ group->field_data2 = one; -+ one = NULL; -+ -+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); -+ -+ if (!ret) { -+ BN_MONT_CTX_free(group->field_data1); -+ group->field_data1 = NULL; -+ BN_free(group->field_data2); -+ group->field_data2 = NULL; -+ } -+ -+ err: -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ if (mont != NULL) -+ BN_MONT_CTX_free(mont); -+ return ret; -+} -+ -+int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx) -+{ -+ if (group->field_data1 == NULL) { -+ ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED); -+ return 0; -+ } -+ -+ return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx); -+} -+ -+int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *ctx) -+{ -+ if (group->field_data1 == NULL) { -+ ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED); -+ return 0; -+ } -+ -+ return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx); -+} -+ -+int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, -+ const BIGNUM *a, BN_CTX *ctx) -+{ -+ if (group->field_data1 == NULL) { -+ ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED); -+ return 0; -+ } -+ -+ return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx); -+} -+ -+int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, -+ const BIGNUM *a, BN_CTX *ctx) -+{ -+ if (group->field_data1 == NULL) { -+ ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED); -+ return 0; -+ } -+ -+ return BN_from_montgomery(r, a, group->field_data1, ctx); -+} -+ -+int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, -+ BN_CTX *ctx) -+{ -+ if (group->field_data2 == NULL) { -+ ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED); -+ return 0; -+ } -+ -+ if (!BN_copy(r, group->field_data2)) -+ return 0; -+ return 1; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ecp_nist.c b/Cryptlib/OpenSSL/crypto/ec/ecp_nist.c -new file mode 100644 -index 0000000..3944e24 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ecp_nist.c -@@ -0,0 +1,220 @@ -+/* crypto/ec/ecp_nist.c */ -+/* -+ * Written by Nils Larsch for the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2003 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Portions of this software developed by SUN MICROSYSTEMS, INC., -+ * and contributed to the OpenSSL project. -+ */ -+ -+#include -+ -+#include -+#include -+#include "ec_lcl.h" -+ -+#ifdef OPENSSL_FIPS -+# include -+#endif -+ -+const EC_METHOD *EC_GFp_nist_method(void) -+{ -+ static const EC_METHOD ret = { -+ EC_FLAGS_DEFAULT_OCT, -+ NID_X9_62_prime_field, -+ ec_GFp_simple_group_init, -+ ec_GFp_simple_group_finish, -+ ec_GFp_simple_group_clear_finish, -+ ec_GFp_nist_group_copy, -+ ec_GFp_nist_group_set_curve, -+ ec_GFp_simple_group_get_curve, -+ ec_GFp_simple_group_get_degree, -+ ec_GFp_simple_group_check_discriminant, -+ ec_GFp_simple_point_init, -+ ec_GFp_simple_point_finish, -+ ec_GFp_simple_point_clear_finish, -+ ec_GFp_simple_point_copy, -+ ec_GFp_simple_point_set_to_infinity, -+ ec_GFp_simple_set_Jprojective_coordinates_GFp, -+ ec_GFp_simple_get_Jprojective_coordinates_GFp, -+ ec_GFp_simple_point_set_affine_coordinates, -+ ec_GFp_simple_point_get_affine_coordinates, -+ 0, 0, 0, -+ ec_GFp_simple_add, -+ ec_GFp_simple_dbl, -+ ec_GFp_simple_invert, -+ ec_GFp_simple_is_at_infinity, -+ ec_GFp_simple_is_on_curve, -+ ec_GFp_simple_cmp, -+ ec_GFp_simple_make_affine, -+ ec_GFp_simple_points_make_affine, -+ 0 /* mul */ , -+ 0 /* precompute_mult */ , -+ 0 /* have_precompute_mult */ , -+ ec_GFp_nist_field_mul, -+ ec_GFp_nist_field_sqr, -+ 0 /* field_div */ , -+ 0 /* field_encode */ , -+ 0 /* field_decode */ , -+ 0 /* field_set_to_one */ -+ }; -+ -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode()) -+ return fips_ec_gfp_nist_method(); -+#endif -+ -+ return &ret; -+} -+ -+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) -+{ -+ dest->field_mod_func = src->field_mod_func; -+ -+ return ec_GFp_simple_group_copy(dest, src); -+} -+ -+int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, -+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -+{ -+ int ret = 0; -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *tmp_bn; -+ -+ if (ctx == NULL) -+ if ((ctx = new_ctx = BN_CTX_new()) == NULL) -+ return 0; -+ -+ BN_CTX_start(ctx); -+ if ((tmp_bn = BN_CTX_get(ctx)) == NULL) -+ goto err; -+ -+ if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) -+ group->field_mod_func = BN_nist_mod_192; -+ else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) -+ group->field_mod_func = BN_nist_mod_224; -+ else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0) -+ group->field_mod_func = BN_nist_mod_256; -+ else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0) -+ group->field_mod_func = BN_nist_mod_384; -+ else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) -+ group->field_mod_func = BN_nist_mod_521; -+ else { -+ ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME); -+ goto err; -+ } -+ -+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx) -+{ -+ int ret = 0; -+ BN_CTX *ctx_new = NULL; -+ -+ if (!group || !r || !a || !b) { -+ ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER); -+ goto err; -+ } -+ if (!ctx) -+ if ((ctx_new = ctx = BN_CTX_new()) == NULL) -+ goto err; -+ -+ if (!BN_mul(r, a, b, ctx)) -+ goto err; -+ if (!group->field_mod_func(r, r, &group->field, ctx)) -+ goto err; -+ -+ ret = 1; -+ err: -+ if (ctx_new) -+ BN_CTX_free(ctx_new); -+ return ret; -+} -+ -+int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *ctx) -+{ -+ int ret = 0; -+ BN_CTX *ctx_new = NULL; -+ -+ if (!group || !r || !a) { -+ ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER); -+ goto err; -+ } -+ if (!ctx) -+ if ((ctx_new = ctx = BN_CTX_new()) == NULL) -+ goto err; -+ -+ if (!BN_sqr(r, a, ctx)) -+ goto err; -+ if (!group->field_mod_func(r, r, &group->field, ctx)) -+ goto err; -+ -+ ret = 1; -+ err: -+ if (ctx_new) -+ BN_CTX_free(ctx_new); -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ecp_oct.c b/Cryptlib/OpenSSL/crypto/ec/ecp_oct.c -new file mode 100644 -index 0000000..1bc3f39 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ecp_oct.c -@@ -0,0 +1,428 @@ -+/* crypto/ec/ecp_oct.c */ -+/* -+ * Includes code written by Lenka Fibikova -+ * for the OpenSSL project. Includes code written by Bodo Moeller for the -+ * OpenSSL project. -+ */ -+/* ==================================================================== -+ * 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Portions of this software developed by SUN MICROSYSTEMS, INC., -+ * and contributed to the OpenSSL project. -+ */ -+ -+#include -+#include -+ -+#include "ec_lcl.h" -+ -+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, -+ EC_POINT *point, -+ const BIGNUM *x_, int y_bit, -+ BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *tmp1, *tmp2, *x, *y; -+ int ret = 0; -+ -+ /* clear error queue */ -+ ERR_clear_error(); -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ y_bit = (y_bit != 0); -+ -+ BN_CTX_start(ctx); -+ tmp1 = BN_CTX_get(ctx); -+ tmp2 = BN_CTX_get(ctx); -+ x = BN_CTX_get(ctx); -+ y = BN_CTX_get(ctx); -+ if (y == NULL) -+ goto err; -+ -+ /*- -+ * Recover y. We have a Weierstrass equation -+ * y^2 = x^3 + a*x + b, -+ * so y is one of the square roots of x^3 + a*x + b. -+ */ -+ -+ /* tmp1 := x^3 */ -+ if (!BN_nnmod(x, x_, &group->field, ctx)) -+ goto err; -+ if (group->meth->field_decode == 0) { -+ /* field_{sqr,mul} work on standard representation */ -+ if (!group->meth->field_sqr(group, tmp2, x_, ctx)) -+ goto err; -+ if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) -+ goto err; -+ } else { -+ if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) -+ goto err; -+ if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) -+ goto err; -+ } -+ -+ /* tmp1 := tmp1 + a*x */ -+ if (group->a_is_minus3) { -+ if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) -+ goto err; -+ if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) -+ goto err; -+ if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) -+ goto err; -+ } else { -+ if (group->meth->field_decode) { -+ if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) -+ goto err; -+ if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) -+ goto err; -+ } else { -+ /* field_mul works on standard representation */ -+ if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) -+ goto err; -+ } -+ -+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) -+ goto err; -+ } -+ -+ /* tmp1 := tmp1 + b */ -+ if (group->meth->field_decode) { -+ if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) -+ goto err; -+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) -+ goto err; -+ } else { -+ if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) -+ goto err; -+ } -+ -+ if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { -+ unsigned long err = ERR_peek_last_error(); -+ -+ if (ERR_GET_LIB(err) == ERR_LIB_BN -+ && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { -+ ERR_clear_error(); -+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, -+ EC_R_INVALID_COMPRESSED_POINT); -+ } else -+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, -+ ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ if (y_bit != BN_is_odd(y)) { -+ if (BN_is_zero(y)) { -+ int kron; -+ -+ kron = BN_kronecker(x, &group->field, ctx); -+ if (kron == -2) -+ goto err; -+ -+ if (kron == 1) -+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, -+ EC_R_INVALID_COMPRESSION_BIT); -+ else -+ /* -+ * BN_mod_sqrt() should have cought this error (not a square) -+ */ -+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, -+ EC_R_INVALID_COMPRESSED_POINT); -+ goto err; -+ } -+ if (!BN_usub(y, &group->field, y)) -+ goto err; -+ } -+ if (y_bit != BN_is_odd(y)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, -+ ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) -+ goto err; -+ -+ ret = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, -+ point_conversion_form_t form, -+ unsigned char *buf, size_t len, BN_CTX *ctx) -+{ -+ size_t ret; -+ BN_CTX *new_ctx = NULL; -+ int used_ctx = 0; -+ BIGNUM *x, *y; -+ size_t field_len, i, skip; -+ -+ if ((form != POINT_CONVERSION_COMPRESSED) -+ && (form != POINT_CONVERSION_UNCOMPRESSED) -+ && (form != POINT_CONVERSION_HYBRID)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); -+ goto err; -+ } -+ -+ if (EC_POINT_is_at_infinity(group, point)) { -+ /* encodes to a single 0 octet */ -+ if (buf != NULL) { -+ if (len < 1) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); -+ return 0; -+ } -+ buf[0] = 0; -+ } -+ return 1; -+ } -+ -+ /* ret := required output buffer length */ -+ field_len = BN_num_bytes(&group->field); -+ ret = -+ (form == -+ POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; -+ -+ /* if 'buf' is NULL, just return required length */ -+ if (buf != NULL) { -+ if (len < ret) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); -+ goto err; -+ } -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ used_ctx = 1; -+ x = BN_CTX_get(ctx); -+ y = BN_CTX_get(ctx); -+ if (y == NULL) -+ goto err; -+ -+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) -+ goto err; -+ -+ if ((form == POINT_CONVERSION_COMPRESSED -+ || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) -+ buf[0] = form + 1; -+ else -+ buf[0] = form; -+ -+ i = 1; -+ -+ skip = field_len - BN_num_bytes(x); -+ if (skip > field_len) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ while (skip > 0) { -+ buf[i++] = 0; -+ skip--; -+ } -+ skip = BN_bn2bin(x, buf + i); -+ i += skip; -+ if (i != 1 + field_len) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ if (form == POINT_CONVERSION_UNCOMPRESSED -+ || form == POINT_CONVERSION_HYBRID) { -+ skip = field_len - BN_num_bytes(y); -+ if (skip > field_len) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ while (skip > 0) { -+ buf[i++] = 0; -+ skip--; -+ } -+ skip = BN_bn2bin(y, buf + i); -+ i += skip; -+ } -+ -+ if (i != ret) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ } -+ -+ if (used_ctx) -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+ -+ err: -+ if (used_ctx) -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return 0; -+} -+ -+int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, -+ const unsigned char *buf, size_t len, BN_CTX *ctx) -+{ -+ point_conversion_form_t form; -+ int y_bit; -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *x, *y; -+ size_t field_len, enc_len; -+ int ret = 0; -+ -+ if (len == 0) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); -+ return 0; -+ } -+ form = buf[0]; -+ y_bit = form & 1; -+ form = form & ~1U; -+ if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) -+ && (form != POINT_CONVERSION_UNCOMPRESSED) -+ && (form != POINT_CONVERSION_HYBRID)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); -+ return 0; -+ } -+ if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); -+ return 0; -+ } -+ -+ if (form == 0) { -+ if (len != 1) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); -+ return 0; -+ } -+ -+ return EC_POINT_set_to_infinity(group, point); -+ } -+ -+ field_len = BN_num_bytes(&group->field); -+ enc_len = -+ (form == -+ POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; -+ -+ if (len != enc_len) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); -+ return 0; -+ } -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ x = BN_CTX_get(ctx); -+ y = BN_CTX_get(ctx); -+ if (y == NULL) -+ goto err; -+ -+ if (!BN_bin2bn(buf + 1, field_len, x)) -+ goto err; -+ if (BN_ucmp(x, &group->field) >= 0) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); -+ goto err; -+ } -+ -+ if (form == POINT_CONVERSION_COMPRESSED) { -+ if (!EC_POINT_set_compressed_coordinates_GFp -+ (group, point, x, y_bit, ctx)) -+ goto err; -+ } else { -+ if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) -+ goto err; -+ if (BN_ucmp(y, &group->field) >= 0) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); -+ goto err; -+ } -+ if (form == POINT_CONVERSION_HYBRID) { -+ if (y_bit != BN_is_odd(y)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); -+ goto err; -+ } -+ } -+ -+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) -+ goto err; -+ } -+ -+ /* test required by X9.62 */ -+ if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { -+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); -+ goto err; -+ } -+ -+ ret = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ec/ecp_smpl.c b/Cryptlib/OpenSSL/crypto/ec/ecp_smpl.c -new file mode 100644 -index 0000000..2b84821 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ec/ecp_smpl.c -@@ -0,0 +1,1418 @@ -+/* crypto/ec/ecp_smpl.c */ -+/* -+ * Includes code written by Lenka Fibikova -+ * for the OpenSSL project. Includes code written by Bodo Moeller for the -+ * OpenSSL project. -+ */ -+/* ==================================================================== -+ * 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). -+ * -+ */ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * Portions of this software developed by SUN MICROSYSTEMS, INC., -+ * and contributed to the OpenSSL project. -+ */ -+ -+#include -+#include -+ -+#ifdef OPENSSL_FIPS -+# include -+#endif -+ -+#include "ec_lcl.h" -+ -+const EC_METHOD *EC_GFp_simple_method(void) -+{ -+ static const EC_METHOD ret = { -+ EC_FLAGS_DEFAULT_OCT, -+ NID_X9_62_prime_field, -+ ec_GFp_simple_group_init, -+ ec_GFp_simple_group_finish, -+ ec_GFp_simple_group_clear_finish, -+ ec_GFp_simple_group_copy, -+ ec_GFp_simple_group_set_curve, -+ ec_GFp_simple_group_get_curve, -+ ec_GFp_simple_group_get_degree, -+ ec_GFp_simple_group_check_discriminant, -+ ec_GFp_simple_point_init, -+ ec_GFp_simple_point_finish, -+ ec_GFp_simple_point_clear_finish, -+ ec_GFp_simple_point_copy, -+ ec_GFp_simple_point_set_to_infinity, -+ ec_GFp_simple_set_Jprojective_coordinates_GFp, -+ ec_GFp_simple_get_Jprojective_coordinates_GFp, -+ ec_GFp_simple_point_set_affine_coordinates, -+ ec_GFp_simple_point_get_affine_coordinates, -+ 0, 0, 0, -+ ec_GFp_simple_add, -+ ec_GFp_simple_dbl, -+ ec_GFp_simple_invert, -+ ec_GFp_simple_is_at_infinity, -+ ec_GFp_simple_is_on_curve, -+ ec_GFp_simple_cmp, -+ ec_GFp_simple_make_affine, -+ ec_GFp_simple_points_make_affine, -+ 0 /* mul */ , -+ 0 /* precompute_mult */ , -+ 0 /* have_precompute_mult */ , -+ ec_GFp_simple_field_mul, -+ ec_GFp_simple_field_sqr, -+ 0 /* field_div */ , -+ 0 /* field_encode */ , -+ 0 /* field_decode */ , -+ 0 /* field_set_to_one */ -+ }; -+ -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode()) -+ return fips_ec_gfp_simple_method(); -+#endif -+ -+ return &ret; -+} -+ -+/* -+ * Most method functions in this file are designed to work with -+ * non-trivial representations of field elements if necessary -+ * (see ecp_mont.c): while standard modular addition and subtraction -+ * are used, the field_mul and field_sqr methods will be used for -+ * multiplication, and field_encode and field_decode (if defined) -+ * will be used for converting between representations. -+ * -+ * Functions ec_GFp_simple_points_make_affine() and -+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume -+ * that if a non-trivial representation is used, it is a Montgomery -+ * representation (i.e. 'encoding' means multiplying by some factor R). -+ */ -+ -+int ec_GFp_simple_group_init(EC_GROUP *group) -+{ -+ BN_init(&group->field); -+ BN_init(&group->a); -+ BN_init(&group->b); -+ group->a_is_minus3 = 0; -+ return 1; -+} -+ -+void ec_GFp_simple_group_finish(EC_GROUP *group) -+{ -+ BN_free(&group->field); -+ BN_free(&group->a); -+ BN_free(&group->b); -+} -+ -+void ec_GFp_simple_group_clear_finish(EC_GROUP *group) -+{ -+ BN_clear_free(&group->field); -+ BN_clear_free(&group->a); -+ BN_clear_free(&group->b); -+} -+ -+int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) -+{ -+ if (!BN_copy(&dest->field, &src->field)) -+ return 0; -+ if (!BN_copy(&dest->a, &src->a)) -+ return 0; -+ if (!BN_copy(&dest->b, &src->b)) -+ return 0; -+ -+ dest->a_is_minus3 = src->a_is_minus3; -+ -+ return 1; -+} -+ -+int ec_GFp_simple_group_set_curve(EC_GROUP *group, -+ const BIGNUM *p, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx) -+{ -+ int ret = 0; -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *tmp_a; -+ -+ /* p must be a prime > 3 */ -+ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD); -+ return 0; -+ } -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ tmp_a = BN_CTX_get(ctx); -+ if (tmp_a == NULL) -+ goto err; -+ -+ /* group->field */ -+ if (!BN_copy(&group->field, p)) -+ goto err; -+ BN_set_negative(&group->field, 0); -+ -+ /* group->a */ -+ if (!BN_nnmod(tmp_a, a, p, ctx)) -+ goto err; -+ if (group->meth->field_encode) { -+ if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) -+ goto err; -+ } else if (!BN_copy(&group->a, tmp_a)) -+ goto err; -+ -+ /* group->b */ -+ if (!BN_nnmod(&group->b, b, p, ctx)) -+ goto err; -+ if (group->meth->field_encode) -+ if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) -+ goto err; -+ -+ /* group->a_is_minus3 */ -+ if (!BN_add_word(tmp_a, 3)) -+ goto err; -+ group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); -+ -+ ret = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, -+ BIGNUM *b, BN_CTX *ctx) -+{ -+ int ret = 0; -+ BN_CTX *new_ctx = NULL; -+ -+ if (p != NULL) { -+ if (!BN_copy(p, &group->field)) -+ return 0; -+ } -+ -+ if (a != NULL || b != NULL) { -+ if (group->meth->field_decode) { -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ if (a != NULL) { -+ if (!group->meth->field_decode(group, a, &group->a, ctx)) -+ goto err; -+ } -+ if (b != NULL) { -+ if (!group->meth->field_decode(group, b, &group->b, ctx)) -+ goto err; -+ } -+ } else { -+ if (a != NULL) { -+ if (!BN_copy(a, &group->a)) -+ goto err; -+ } -+ if (b != NULL) { -+ if (!BN_copy(b, &group->b)) -+ goto err; -+ } -+ } -+ } -+ -+ ret = 1; -+ -+ err: -+ if (new_ctx) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_group_get_degree(const EC_GROUP *group) -+{ -+ return BN_num_bits(&group->field); -+} -+ -+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) -+{ -+ int ret = 0; -+ BIGNUM *a, *b, *order, *tmp_1, *tmp_2; -+ const BIGNUM *p = &group->field; -+ BN_CTX *new_ctx = NULL; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) { -+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, -+ ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ BN_CTX_start(ctx); -+ a = BN_CTX_get(ctx); -+ b = BN_CTX_get(ctx); -+ tmp_1 = BN_CTX_get(ctx); -+ tmp_2 = BN_CTX_get(ctx); -+ order = BN_CTX_get(ctx); -+ if (order == NULL) -+ goto err; -+ -+ if (group->meth->field_decode) { -+ if (!group->meth->field_decode(group, a, &group->a, ctx)) -+ goto err; -+ if (!group->meth->field_decode(group, b, &group->b, ctx)) -+ goto err; -+ } else { -+ if (!BN_copy(a, &group->a)) -+ goto err; -+ if (!BN_copy(b, &group->b)) -+ goto err; -+ } -+ -+ /*- -+ * check the discriminant: -+ * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p) -+ * 0 =< a, b < p -+ */ -+ if (BN_is_zero(a)) { -+ if (BN_is_zero(b)) -+ goto err; -+ } else if (!BN_is_zero(b)) { -+ if (!BN_mod_sqr(tmp_1, a, p, ctx)) -+ goto err; -+ if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) -+ goto err; -+ if (!BN_lshift(tmp_1, tmp_2, 2)) -+ goto err; -+ /* tmp_1 = 4*a^3 */ -+ -+ if (!BN_mod_sqr(tmp_2, b, p, ctx)) -+ goto err; -+ if (!BN_mul_word(tmp_2, 27)) -+ goto err; -+ /* tmp_2 = 27*b^2 */ -+ -+ if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) -+ goto err; -+ if (BN_is_zero(a)) -+ goto err; -+ } -+ ret = 1; -+ -+ err: -+ if (ctx != NULL) -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_point_init(EC_POINT *point) -+{ -+ BN_init(&point->X); -+ BN_init(&point->Y); -+ BN_init(&point->Z); -+ point->Z_is_one = 0; -+ -+ return 1; -+} -+ -+void ec_GFp_simple_point_finish(EC_POINT *point) -+{ -+ BN_free(&point->X); -+ BN_free(&point->Y); -+ BN_free(&point->Z); -+} -+ -+void ec_GFp_simple_point_clear_finish(EC_POINT *point) -+{ -+ BN_clear_free(&point->X); -+ BN_clear_free(&point->Y); -+ BN_clear_free(&point->Z); -+ point->Z_is_one = 0; -+} -+ -+int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) -+{ -+ if (!BN_copy(&dest->X, &src->X)) -+ return 0; -+ if (!BN_copy(&dest->Y, &src->Y)) -+ return 0; -+ if (!BN_copy(&dest->Z, &src->Z)) -+ return 0; -+ dest->Z_is_one = src->Z_is_one; -+ -+ return 1; -+} -+ -+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, -+ EC_POINT *point) -+{ -+ point->Z_is_one = 0; -+ BN_zero(&point->Z); -+ return 1; -+} -+ -+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, -+ EC_POINT *point, -+ const BIGNUM *x, -+ const BIGNUM *y, -+ const BIGNUM *z, -+ BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ int ret = 0; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ if (x != NULL) { -+ if (!BN_nnmod(&point->X, x, &group->field, ctx)) -+ goto err; -+ if (group->meth->field_encode) { -+ if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) -+ goto err; -+ } -+ } -+ -+ if (y != NULL) { -+ if (!BN_nnmod(&point->Y, y, &group->field, ctx)) -+ goto err; -+ if (group->meth->field_encode) { -+ if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) -+ goto err; -+ } -+ } -+ -+ if (z != NULL) { -+ int Z_is_one; -+ -+ if (!BN_nnmod(&point->Z, z, &group->field, ctx)) -+ goto err; -+ Z_is_one = BN_is_one(&point->Z); -+ if (group->meth->field_encode) { -+ if (Z_is_one && (group->meth->field_set_to_one != 0)) { -+ if (!group->meth->field_set_to_one(group, &point->Z, ctx)) -+ goto err; -+ } else { -+ if (!group-> -+ meth->field_encode(group, &point->Z, &point->Z, ctx)) -+ goto err; -+ } -+ } -+ point->Z_is_one = Z_is_one; -+ } -+ -+ ret = 1; -+ -+ err: -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, -+ const EC_POINT *point, -+ BIGNUM *x, BIGNUM *y, -+ BIGNUM *z, BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ int ret = 0; -+ -+ if (group->meth->field_decode != 0) { -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ if (x != NULL) { -+ if (!group->meth->field_decode(group, x, &point->X, ctx)) -+ goto err; -+ } -+ if (y != NULL) { -+ if (!group->meth->field_decode(group, y, &point->Y, ctx)) -+ goto err; -+ } -+ if (z != NULL) { -+ if (!group->meth->field_decode(group, z, &point->Z, ctx)) -+ goto err; -+ } -+ } else { -+ if (x != NULL) { -+ if (!BN_copy(x, &point->X)) -+ goto err; -+ } -+ if (y != NULL) { -+ if (!BN_copy(y, &point->Y)) -+ goto err; -+ } -+ if (z != NULL) { -+ if (!BN_copy(z, &point->Z)) -+ goto err; -+ } -+ } -+ -+ ret = 1; -+ -+ err: -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, -+ EC_POINT *point, -+ const BIGNUM *x, -+ const BIGNUM *y, BN_CTX *ctx) -+{ -+ if (x == NULL || y == NULL) { -+ /* -+ * unlike for projective coordinates, we do not tolerate this -+ */ -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, -+ ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ -+ return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, -+ BN_value_one(), ctx); -+} -+ -+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, -+ const EC_POINT *point, -+ BIGNUM *x, BIGNUM *y, -+ BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *Z, *Z_1, *Z_2, *Z_3; -+ const BIGNUM *Z_; -+ int ret = 0; -+ -+ if (EC_POINT_is_at_infinity(group, point)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, -+ EC_R_POINT_AT_INFINITY); -+ return 0; -+ } -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ Z = BN_CTX_get(ctx); -+ Z_1 = BN_CTX_get(ctx); -+ Z_2 = BN_CTX_get(ctx); -+ Z_3 = BN_CTX_get(ctx); -+ if (Z_3 == NULL) -+ goto err; -+ -+ /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */ -+ -+ if (group->meth->field_decode) { -+ if (!group->meth->field_decode(group, Z, &point->Z, ctx)) -+ goto err; -+ Z_ = Z; -+ } else { -+ Z_ = &point->Z; -+ } -+ -+ if (BN_is_one(Z_)) { -+ if (group->meth->field_decode) { -+ if (x != NULL) { -+ if (!group->meth->field_decode(group, x, &point->X, ctx)) -+ goto err; -+ } -+ if (y != NULL) { -+ if (!group->meth->field_decode(group, y, &point->Y, ctx)) -+ goto err; -+ } -+ } else { -+ if (x != NULL) { -+ if (!BN_copy(x, &point->X)) -+ goto err; -+ } -+ if (y != NULL) { -+ if (!BN_copy(y, &point->Y)) -+ goto err; -+ } -+ } -+ } else { -+ if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, -+ ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ if (group->meth->field_encode == 0) { -+ /* field_sqr works on standard representation */ -+ if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) -+ goto err; -+ } else { -+ if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) -+ goto err; -+ } -+ -+ if (x != NULL) { -+ /* -+ * in the Montgomery case, field_mul will cancel out Montgomery -+ * factor in X: -+ */ -+ if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) -+ goto err; -+ } -+ -+ if (y != NULL) { -+ if (group->meth->field_encode == 0) { -+ /* -+ * field_mul works on standard representation -+ */ -+ if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) -+ goto err; -+ } else { -+ if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) -+ goto err; -+ } -+ -+ /* -+ * in the Montgomery case, field_mul will cancel out Montgomery -+ * factor in Y: -+ */ -+ if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) -+ goto err; -+ } -+ } -+ -+ ret = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, -+ const EC_POINT *b, BN_CTX *ctx) -+{ -+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, -+ const BIGNUM *, BN_CTX *); -+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); -+ const BIGNUM *p; -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; -+ int ret = 0; -+ -+ if (a == b) -+ return EC_POINT_dbl(group, r, a, ctx); -+ if (EC_POINT_is_at_infinity(group, a)) -+ return EC_POINT_copy(r, b); -+ if (EC_POINT_is_at_infinity(group, b)) -+ return EC_POINT_copy(r, a); -+ -+ field_mul = group->meth->field_mul; -+ field_sqr = group->meth->field_sqr; -+ p = &group->field; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ n0 = BN_CTX_get(ctx); -+ n1 = BN_CTX_get(ctx); -+ n2 = BN_CTX_get(ctx); -+ n3 = BN_CTX_get(ctx); -+ n4 = BN_CTX_get(ctx); -+ n5 = BN_CTX_get(ctx); -+ n6 = BN_CTX_get(ctx); -+ if (n6 == NULL) -+ goto end; -+ -+ /* -+ * Note that in this function we must not read components of 'a' or 'b' -+ * once we have written the corresponding components of 'r'. ('r' might -+ * be one of 'a' or 'b'.) -+ */ -+ -+ /* n1, n2 */ -+ if (b->Z_is_one) { -+ if (!BN_copy(n1, &a->X)) -+ goto end; -+ if (!BN_copy(n2, &a->Y)) -+ goto end; -+ /* n1 = X_a */ -+ /* n2 = Y_a */ -+ } else { -+ if (!field_sqr(group, n0, &b->Z, ctx)) -+ goto end; -+ if (!field_mul(group, n1, &a->X, n0, ctx)) -+ goto end; -+ /* n1 = X_a * Z_b^2 */ -+ -+ if (!field_mul(group, n0, n0, &b->Z, ctx)) -+ goto end; -+ if (!field_mul(group, n2, &a->Y, n0, ctx)) -+ goto end; -+ /* n2 = Y_a * Z_b^3 */ -+ } -+ -+ /* n3, n4 */ -+ if (a->Z_is_one) { -+ if (!BN_copy(n3, &b->X)) -+ goto end; -+ if (!BN_copy(n4, &b->Y)) -+ goto end; -+ /* n3 = X_b */ -+ /* n4 = Y_b */ -+ } else { -+ if (!field_sqr(group, n0, &a->Z, ctx)) -+ goto end; -+ if (!field_mul(group, n3, &b->X, n0, ctx)) -+ goto end; -+ /* n3 = X_b * Z_a^2 */ -+ -+ if (!field_mul(group, n0, n0, &a->Z, ctx)) -+ goto end; -+ if (!field_mul(group, n4, &b->Y, n0, ctx)) -+ goto end; -+ /* n4 = Y_b * Z_a^3 */ -+ } -+ -+ /* n5, n6 */ -+ if (!BN_mod_sub_quick(n5, n1, n3, p)) -+ goto end; -+ if (!BN_mod_sub_quick(n6, n2, n4, p)) -+ goto end; -+ /* n5 = n1 - n3 */ -+ /* n6 = n2 - n4 */ -+ -+ if (BN_is_zero(n5)) { -+ if (BN_is_zero(n6)) { -+ /* a is the same point as b */ -+ BN_CTX_end(ctx); -+ ret = EC_POINT_dbl(group, r, a, ctx); -+ ctx = NULL; -+ goto end; -+ } else { -+ /* a is the inverse of b */ -+ BN_zero(&r->Z); -+ r->Z_is_one = 0; -+ ret = 1; -+ goto end; -+ } -+ } -+ -+ /* 'n7', 'n8' */ -+ if (!BN_mod_add_quick(n1, n1, n3, p)) -+ goto end; -+ if (!BN_mod_add_quick(n2, n2, n4, p)) -+ goto end; -+ /* 'n7' = n1 + n3 */ -+ /* 'n8' = n2 + n4 */ -+ -+ /* Z_r */ -+ if (a->Z_is_one && b->Z_is_one) { -+ if (!BN_copy(&r->Z, n5)) -+ goto end; -+ } else { -+ if (a->Z_is_one) { -+ if (!BN_copy(n0, &b->Z)) -+ goto end; -+ } else if (b->Z_is_one) { -+ if (!BN_copy(n0, &a->Z)) -+ goto end; -+ } else { -+ if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) -+ goto end; -+ } -+ if (!field_mul(group, &r->Z, n0, n5, ctx)) -+ goto end; -+ } -+ r->Z_is_one = 0; -+ /* Z_r = Z_a * Z_b * n5 */ -+ -+ /* X_r */ -+ if (!field_sqr(group, n0, n6, ctx)) -+ goto end; -+ if (!field_sqr(group, n4, n5, ctx)) -+ goto end; -+ if (!field_mul(group, n3, n1, n4, ctx)) -+ goto end; -+ if (!BN_mod_sub_quick(&r->X, n0, n3, p)) -+ goto end; -+ /* X_r = n6^2 - n5^2 * 'n7' */ -+ -+ /* 'n9' */ -+ if (!BN_mod_lshift1_quick(n0, &r->X, p)) -+ goto end; -+ if (!BN_mod_sub_quick(n0, n3, n0, p)) -+ goto end; -+ /* n9 = n5^2 * 'n7' - 2 * X_r */ -+ -+ /* Y_r */ -+ if (!field_mul(group, n0, n0, n6, ctx)) -+ goto end; -+ if (!field_mul(group, n5, n4, n5, ctx)) -+ goto end; /* now n5 is n5^3 */ -+ if (!field_mul(group, n1, n2, n5, ctx)) -+ goto end; -+ if (!BN_mod_sub_quick(n0, n0, n1, p)) -+ goto end; -+ if (BN_is_odd(n0)) -+ if (!BN_add(n0, n0, p)) -+ goto end; -+ /* now 0 <= n0 < 2*p, and n0 is even */ -+ if (!BN_rshift1(&r->Y, n0)) -+ goto end; -+ /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ -+ -+ ret = 1; -+ -+ end: -+ if (ctx) /* otherwise we already called BN_CTX_end */ -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, -+ BN_CTX *ctx) -+{ -+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, -+ const BIGNUM *, BN_CTX *); -+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); -+ const BIGNUM *p; -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *n0, *n1, *n2, *n3; -+ int ret = 0; -+ -+ if (EC_POINT_is_at_infinity(group, a)) { -+ BN_zero(&r->Z); -+ r->Z_is_one = 0; -+ return 1; -+ } -+ -+ field_mul = group->meth->field_mul; -+ field_sqr = group->meth->field_sqr; -+ p = &group->field; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ n0 = BN_CTX_get(ctx); -+ n1 = BN_CTX_get(ctx); -+ n2 = BN_CTX_get(ctx); -+ n3 = BN_CTX_get(ctx); -+ if (n3 == NULL) -+ goto err; -+ -+ /* -+ * Note that in this function we must not read components of 'a' once we -+ * have written the corresponding components of 'r'. ('r' might the same -+ * as 'a'.) -+ */ -+ -+ /* n1 */ -+ if (a->Z_is_one) { -+ if (!field_sqr(group, n0, &a->X, ctx)) -+ goto err; -+ if (!BN_mod_lshift1_quick(n1, n0, p)) -+ goto err; -+ if (!BN_mod_add_quick(n0, n0, n1, p)) -+ goto err; -+ if (!BN_mod_add_quick(n1, n0, &group->a, p)) -+ goto err; -+ /* n1 = 3 * X_a^2 + a_curve */ -+ } else if (group->a_is_minus3) { -+ if (!field_sqr(group, n1, &a->Z, ctx)) -+ goto err; -+ if (!BN_mod_add_quick(n0, &a->X, n1, p)) -+ goto err; -+ if (!BN_mod_sub_quick(n2, &a->X, n1, p)) -+ goto err; -+ if (!field_mul(group, n1, n0, n2, ctx)) -+ goto err; -+ if (!BN_mod_lshift1_quick(n0, n1, p)) -+ goto err; -+ if (!BN_mod_add_quick(n1, n0, n1, p)) -+ goto err; -+ /*- -+ * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) -+ * = 3 * X_a^2 - 3 * Z_a^4 -+ */ -+ } else { -+ if (!field_sqr(group, n0, &a->X, ctx)) -+ goto err; -+ if (!BN_mod_lshift1_quick(n1, n0, p)) -+ goto err; -+ if (!BN_mod_add_quick(n0, n0, n1, p)) -+ goto err; -+ if (!field_sqr(group, n1, &a->Z, ctx)) -+ goto err; -+ if (!field_sqr(group, n1, n1, ctx)) -+ goto err; -+ if (!field_mul(group, n1, n1, &group->a, ctx)) -+ goto err; -+ if (!BN_mod_add_quick(n1, n1, n0, p)) -+ goto err; -+ /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ -+ } -+ -+ /* Z_r */ -+ if (a->Z_is_one) { -+ if (!BN_copy(n0, &a->Y)) -+ goto err; -+ } else { -+ if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) -+ goto err; -+ } -+ if (!BN_mod_lshift1_quick(&r->Z, n0, p)) -+ goto err; -+ r->Z_is_one = 0; -+ /* Z_r = 2 * Y_a * Z_a */ -+ -+ /* n2 */ -+ if (!field_sqr(group, n3, &a->Y, ctx)) -+ goto err; -+ if (!field_mul(group, n2, &a->X, n3, ctx)) -+ goto err; -+ if (!BN_mod_lshift_quick(n2, n2, 2, p)) -+ goto err; -+ /* n2 = 4 * X_a * Y_a^2 */ -+ -+ /* X_r */ -+ if (!BN_mod_lshift1_quick(n0, n2, p)) -+ goto err; -+ if (!field_sqr(group, &r->X, n1, ctx)) -+ goto err; -+ if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) -+ goto err; -+ /* X_r = n1^2 - 2 * n2 */ -+ -+ /* n3 */ -+ if (!field_sqr(group, n0, n3, ctx)) -+ goto err; -+ if (!BN_mod_lshift_quick(n3, n0, 3, p)) -+ goto err; -+ /* n3 = 8 * Y_a^4 */ -+ -+ /* Y_r */ -+ if (!BN_mod_sub_quick(n0, n2, &r->X, p)) -+ goto err; -+ if (!field_mul(group, n0, n1, n0, ctx)) -+ goto err; -+ if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) -+ goto err; -+ /* Y_r = n1 * (n2 - X_r) - n3 */ -+ -+ ret = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) -+{ -+ if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) -+ /* point is its own inverse */ -+ return 1; -+ -+ return BN_usub(&point->Y, &group->field, &point->Y); -+} -+ -+int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) -+{ -+ return BN_is_zero(&point->Z); -+} -+ -+int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, -+ BN_CTX *ctx) -+{ -+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, -+ const BIGNUM *, BN_CTX *); -+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); -+ const BIGNUM *p; -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *rh, *tmp, *Z4, *Z6; -+ int ret = -1; -+ -+ if (EC_POINT_is_at_infinity(group, point)) -+ return 1; -+ -+ field_mul = group->meth->field_mul; -+ field_sqr = group->meth->field_sqr; -+ p = &group->field; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return -1; -+ } -+ -+ BN_CTX_start(ctx); -+ rh = BN_CTX_get(ctx); -+ tmp = BN_CTX_get(ctx); -+ Z4 = BN_CTX_get(ctx); -+ Z6 = BN_CTX_get(ctx); -+ if (Z6 == NULL) -+ goto err; -+ -+ /*- -+ * We have a curve defined by a Weierstrass equation -+ * y^2 = x^3 + a*x + b. -+ * The point to consider is given in Jacobian projective coordinates -+ * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). -+ * Substituting this and multiplying by Z^6 transforms the above equation into -+ * Y^2 = X^3 + a*X*Z^4 + b*Z^6. -+ * To test this, we add up the right-hand side in 'rh'. -+ */ -+ -+ /* rh := X^2 */ -+ if (!field_sqr(group, rh, &point->X, ctx)) -+ goto err; -+ -+ if (!point->Z_is_one) { -+ if (!field_sqr(group, tmp, &point->Z, ctx)) -+ goto err; -+ if (!field_sqr(group, Z4, tmp, ctx)) -+ goto err; -+ if (!field_mul(group, Z6, Z4, tmp, ctx)) -+ goto err; -+ -+ /* rh := (rh + a*Z^4)*X */ -+ if (group->a_is_minus3) { -+ if (!BN_mod_lshift1_quick(tmp, Z4, p)) -+ goto err; -+ if (!BN_mod_add_quick(tmp, tmp, Z4, p)) -+ goto err; -+ if (!BN_mod_sub_quick(rh, rh, tmp, p)) -+ goto err; -+ if (!field_mul(group, rh, rh, &point->X, ctx)) -+ goto err; -+ } else { -+ if (!field_mul(group, tmp, Z4, &group->a, ctx)) -+ goto err; -+ if (!BN_mod_add_quick(rh, rh, tmp, p)) -+ goto err; -+ if (!field_mul(group, rh, rh, &point->X, ctx)) -+ goto err; -+ } -+ -+ /* rh := rh + b*Z^6 */ -+ if (!field_mul(group, tmp, &group->b, Z6, ctx)) -+ goto err; -+ if (!BN_mod_add_quick(rh, rh, tmp, p)) -+ goto err; -+ } else { -+ /* point->Z_is_one */ -+ -+ /* rh := (rh + a)*X */ -+ if (!BN_mod_add_quick(rh, rh, &group->a, p)) -+ goto err; -+ if (!field_mul(group, rh, rh, &point->X, ctx)) -+ goto err; -+ /* rh := rh + b */ -+ if (!BN_mod_add_quick(rh, rh, &group->b, p)) -+ goto err; -+ } -+ -+ /* 'lh' := Y^2 */ -+ if (!field_sqr(group, tmp, &point->Y, ctx)) -+ goto err; -+ -+ ret = (0 == BN_ucmp(tmp, rh)); -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, -+ const EC_POINT *b, BN_CTX *ctx) -+{ -+ /*- -+ * return values: -+ * -1 error -+ * 0 equal (in affine coordinates) -+ * 1 not equal -+ */ -+ -+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, -+ const BIGNUM *, BN_CTX *); -+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *tmp1, *tmp2, *Za23, *Zb23; -+ const BIGNUM *tmp1_, *tmp2_; -+ int ret = -1; -+ -+ if (EC_POINT_is_at_infinity(group, a)) { -+ return EC_POINT_is_at_infinity(group, b) ? 0 : 1; -+ } -+ -+ if (EC_POINT_is_at_infinity(group, b)) -+ return 1; -+ -+ if (a->Z_is_one && b->Z_is_one) { -+ return ((BN_cmp(&a->X, &b->X) == 0) -+ && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; -+ } -+ -+ field_mul = group->meth->field_mul; -+ field_sqr = group->meth->field_sqr; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return -1; -+ } -+ -+ BN_CTX_start(ctx); -+ tmp1 = BN_CTX_get(ctx); -+ tmp2 = BN_CTX_get(ctx); -+ Za23 = BN_CTX_get(ctx); -+ Zb23 = BN_CTX_get(ctx); -+ if (Zb23 == NULL) -+ goto end; -+ -+ /*- -+ * We have to decide whether -+ * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), -+ * or equivalently, whether -+ * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). -+ */ -+ -+ if (!b->Z_is_one) { -+ if (!field_sqr(group, Zb23, &b->Z, ctx)) -+ goto end; -+ if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) -+ goto end; -+ tmp1_ = tmp1; -+ } else -+ tmp1_ = &a->X; -+ if (!a->Z_is_one) { -+ if (!field_sqr(group, Za23, &a->Z, ctx)) -+ goto end; -+ if (!field_mul(group, tmp2, &b->X, Za23, ctx)) -+ goto end; -+ tmp2_ = tmp2; -+ } else -+ tmp2_ = &b->X; -+ -+ /* compare X_a*Z_b^2 with X_b*Z_a^2 */ -+ if (BN_cmp(tmp1_, tmp2_) != 0) { -+ ret = 1; /* points differ */ -+ goto end; -+ } -+ -+ if (!b->Z_is_one) { -+ if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) -+ goto end; -+ if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) -+ goto end; -+ /* tmp1_ = tmp1 */ -+ } else -+ tmp1_ = &a->Y; -+ if (!a->Z_is_one) { -+ if (!field_mul(group, Za23, Za23, &a->Z, ctx)) -+ goto end; -+ if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) -+ goto end; -+ /* tmp2_ = tmp2 */ -+ } else -+ tmp2_ = &b->Y; -+ -+ /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ -+ if (BN_cmp(tmp1_, tmp2_) != 0) { -+ ret = 1; /* points differ */ -+ goto end; -+ } -+ -+ /* points are equal */ -+ ret = 0; -+ -+ end: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, -+ BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *x, *y; -+ int ret = 0; -+ -+ if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) -+ return 1; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ x = BN_CTX_get(ctx); -+ y = BN_CTX_get(ctx); -+ if (y == NULL) -+ goto err; -+ -+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) -+ goto err; -+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) -+ goto err; -+ if (!point->Z_is_one) { -+ ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ -+ ret = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ return ret; -+} -+ -+int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, -+ EC_POINT *points[], BN_CTX *ctx) -+{ -+ BN_CTX *new_ctx = NULL; -+ BIGNUM *tmp, *tmp_Z; -+ BIGNUM **prod_Z = NULL; -+ size_t i; -+ int ret = 0; -+ -+ if (num == 0) -+ return 1; -+ -+ if (ctx == NULL) { -+ ctx = new_ctx = BN_CTX_new(); -+ if (ctx == NULL) -+ return 0; -+ } -+ -+ BN_CTX_start(ctx); -+ tmp = BN_CTX_get(ctx); -+ tmp_Z = BN_CTX_get(ctx); -+ if (tmp == NULL || tmp_Z == NULL) -+ goto err; -+ -+ prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]); -+ if (prod_Z == NULL) -+ goto err; -+ for (i = 0; i < num; i++) { -+ prod_Z[i] = BN_new(); -+ if (prod_Z[i] == NULL) -+ goto err; -+ } -+ -+ /* -+ * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, -+ * skipping any zero-valued inputs (pretend that they're 1). -+ */ -+ -+ if (!BN_is_zero(&points[0]->Z)) { -+ if (!BN_copy(prod_Z[0], &points[0]->Z)) -+ goto err; -+ } else { -+ if (group->meth->field_set_to_one != 0) { -+ if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) -+ goto err; -+ } else { -+ if (!BN_one(prod_Z[0])) -+ goto err; -+ } -+ } -+ -+ for (i = 1; i < num; i++) { -+ if (!BN_is_zero(&points[i]->Z)) { -+ if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1], -+ &points[i]->Z, ctx)) -+ goto err; -+ } else { -+ if (!BN_copy(prod_Z[i], prod_Z[i - 1])) -+ goto err; -+ } -+ } -+ -+ /* -+ * Now use a single explicit inversion to replace every non-zero -+ * points[i]->Z by its inverse. -+ */ -+ -+ if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) { -+ ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); -+ goto err; -+ } -+ if (group->meth->field_encode != 0) { -+ /* -+ * In the Montgomery case, we just turned R*H (representing H) into -+ * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to -+ * multiply by the Montgomery factor twice. -+ */ -+ if (!group->meth->field_encode(group, tmp, tmp, ctx)) -+ goto err; -+ if (!group->meth->field_encode(group, tmp, tmp, ctx)) -+ goto err; -+ } -+ -+ for (i = num - 1; i > 0; --i) { -+ /* -+ * Loop invariant: tmp is the product of the inverses of points[0]->Z -+ * .. points[i]->Z (zero-valued inputs skipped). -+ */ -+ if (!BN_is_zero(&points[i]->Z)) { -+ /* -+ * Set tmp_Z to the inverse of points[i]->Z (as product of Z -+ * inverses 0 .. i, Z values 0 .. i - 1). -+ */ -+ if (!group-> -+ meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) -+ goto err; -+ /* -+ * Update tmp to satisfy the loop invariant for i - 1. -+ */ -+ if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx)) -+ goto err; -+ /* Replace points[i]->Z by its inverse. */ -+ if (!BN_copy(&points[i]->Z, tmp_Z)) -+ goto err; -+ } -+ } -+ -+ if (!BN_is_zero(&points[0]->Z)) { -+ /* Replace points[0]->Z by its inverse. */ -+ if (!BN_copy(&points[0]->Z, tmp)) -+ goto err; -+ } -+ -+ /* Finally, fix up the X and Y coordinates for all points. */ -+ -+ for (i = 0; i < num; i++) { -+ EC_POINT *p = points[i]; -+ -+ if (!BN_is_zero(&p->Z)) { -+ /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ -+ -+ if (!group->meth->field_sqr(group, tmp, &p->Z, ctx)) -+ goto err; -+ if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx)) -+ goto err; -+ -+ if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx)) -+ goto err; -+ if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) -+ goto err; -+ -+ if (group->meth->field_set_to_one != 0) { -+ if (!group->meth->field_set_to_one(group, &p->Z, ctx)) -+ goto err; -+ } else { -+ if (!BN_one(&p->Z)) -+ goto err; -+ } -+ p->Z_is_one = 1; -+ } -+ } -+ -+ ret = 1; -+ -+ err: -+ BN_CTX_end(ctx); -+ if (new_ctx != NULL) -+ BN_CTX_free(new_ctx); -+ if (prod_Z != NULL) { -+ for (i = 0; i < num; i++) { -+ if (prod_Z[i] == NULL) -+ break; -+ BN_clear_free(prod_Z[i]); -+ } -+ OPENSSL_free(prod_Z); -+ } -+ return ret; -+} -+ -+int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, -+ const BIGNUM *b, BN_CTX *ctx) -+{ -+ return BN_mod_mul(r, a, b, &group->field, ctx); -+} -+ -+int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, -+ BN_CTX *ctx) -+{ -+ return BN_mod_sqr(r, a, &group->field, ctx); -+} -diff --git a/Cryptlib/OpenSSL/crypto/ecdsa/ecs_asn1.c b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_asn1.c -new file mode 100644 -index 0000000..77a290d ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_asn1.c -@@ -0,0 +1,75 @@ -+/* crypto/ecdsa/ecs_asn1.c */ -+/* ==================================================================== -+ * Copyright (c) 2000-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 -+ * licensing@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 "ecs_locl.h" -+#include -+#include -+ -+ASN1_SEQUENCE(ECDSA_SIG) = { -+ ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), -+ ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) -+} ASN1_SEQUENCE_END(ECDSA_SIG) -+ -+DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG) -+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG) -+IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG) -+ -+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -+{ -+ if (pr != NULL) -+ *pr = sig->r; -+ if (ps != NULL) -+ *ps = sig->s; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ecdsa/ecs_err.c b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_err.c -new file mode 100644 -index 0000000..f1fa7b5 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_err.c -@@ -0,0 +1,107 @@ -+/* crypto/ecdsa/ecs_err.c */ -+/* ==================================================================== -+ * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * 3. All advertising materials mentioning features or use of this -+ * software must display the following acknowledgment: -+ * "This product includes software developed by the OpenSSL Project -+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" -+ * -+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to -+ * endorse or promote products derived from this software without -+ * prior written permission. For written permission, please contact -+ * openssl-core@OpenSSL.org. -+ * -+ * 5. Products derived from this software may not be called "OpenSSL" -+ * nor may "OpenSSL" appear in their names without prior written -+ * permission of the OpenSSL Project. -+ * -+ * 6. Redistributions of any form whatsoever must retain the following -+ * acknowledgment: -+ * "This product includes software developed by the OpenSSL Project -+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY -+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR -+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+ * OF THE POSSIBILITY OF SUCH DAMAGE. -+ * ==================================================================== -+ * -+ * This product includes cryptographic software written by Eric Young -+ * (eay@cryptsoft.com). This product includes software written by Tim -+ * Hudson (tjh@cryptsoft.com). -+ * -+ */ -+ -+/* -+ * NOTE: this file was auto generated by the mkerr.pl script: any changes -+ * made to it will be overwritten when the script next updates this file, -+ * only reason strings will be preserved. -+ */ -+ -+#include -+#include -+#include -+ -+/* BEGIN ERROR CODES */ -+#ifndef OPENSSL_NO_ERR -+ -+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0) -+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason) -+ -+static ERR_STRING_DATA ECDSA_str_functs[] = { -+ {ERR_FUNC(ECDSA_F_ECDSA_CHECK), "ECDSA_CHECK"}, -+ {ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"}, -+ {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"}, -+ {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"}, -+ {ERR_FUNC(ECDSA_F_ECDSA_METHOD_NEW), "ECDSA_METHOD_new"}, -+ {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"}, -+ {0, NULL} -+}; -+ -+static ERR_STRING_DATA ECDSA_str_reasons[] = { -+ {ERR_REASON(ECDSA_R_BAD_SIGNATURE), "bad signature"}, -+ {ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), -+ "data too large for key size"}, -+ {ERR_REASON(ECDSA_R_ERR_EC_LIB), "err ec lib"}, -+ {ERR_REASON(ECDSA_R_MISSING_PARAMETERS), "missing parameters"}, -+ {ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, -+ {ERR_REASON(ECDSA_R_NON_FIPS_METHOD), "non fips method"}, -+ {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED), -+ "random number generation failed"}, -+ {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED), "signature malloc failed"}, -+ {0, NULL} -+}; -+ -+#endif -+ -+void ERR_load_ECDSA_strings(void) -+{ -+#ifndef OPENSSL_NO_ERR -+ -+ if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) { -+ ERR_load_strings(0, ECDSA_str_functs); -+ ERR_load_strings(0, ECDSA_str_reasons); -+ } -+#endif -+} -diff --git a/Cryptlib/OpenSSL/crypto/ecdsa/ecs_lib.c b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_lib.c -new file mode 100644 -index 0000000..8dc1dda ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_lib.c -@@ -0,0 +1,354 @@ -+/* crypto/ecdsa/ecs_lib.c */ -+/* ==================================================================== -+ * 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). -+ * -+ */ -+ -+#include -+#include "ecs_locl.h" -+#ifndef OPENSSL_NO_ENGINE -+# include -+#endif -+#include -+#include -+#ifdef OPENSSL_FIPS -+# include -+#endif -+ -+const char ECDSA_version[] = "ECDSA" OPENSSL_VERSION_PTEXT; -+ -+static const ECDSA_METHOD *default_ECDSA_method = NULL; -+ -+static void *ecdsa_data_new(void); -+static void *ecdsa_data_dup(void *); -+static void ecdsa_data_free(void *); -+ -+void ECDSA_set_default_method(const ECDSA_METHOD *meth) -+{ -+ default_ECDSA_method = meth; -+} -+ -+const ECDSA_METHOD *ECDSA_get_default_method(void) -+{ -+ if (!default_ECDSA_method) { -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode()) -+ return FIPS_ecdsa_openssl(); -+ else -+ return ECDSA_OpenSSL(); -+#else -+ default_ECDSA_method = ECDSA_OpenSSL(); -+#endif -+ } -+ return default_ECDSA_method; -+} -+ -+int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth) -+{ -+ ECDSA_DATA *ecdsa; -+ -+ ecdsa = ecdsa_check(eckey); -+ -+ if (ecdsa == NULL) -+ return 0; -+ -+#ifndef OPENSSL_NO_ENGINE -+ if (ecdsa->engine) { -+ ENGINE_finish(ecdsa->engine); -+ ecdsa->engine = NULL; -+ } -+#endif -+ ecdsa->meth = meth; -+ -+ return 1; -+} -+ -+static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine) -+{ -+ ECDSA_DATA *ret; -+ -+ ret = (ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA)); -+ if (ret == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); -+ return (NULL); -+ } -+ -+ ret->init = NULL; -+ -+ ret->meth = ECDSA_get_default_method(); -+ ret->engine = engine; -+#ifndef OPENSSL_NO_ENGINE -+ if (!ret->engine) -+ ret->engine = ENGINE_get_default_ECDSA(); -+ if (ret->engine) { -+ ret->meth = ENGINE_get_ECDSA(ret->engine); -+ if (!ret->meth) { -+ ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); -+ ENGINE_finish(ret->engine); -+ OPENSSL_free(ret); -+ return NULL; -+ } -+ } -+#endif -+ -+ ret->flags = ret->meth->flags; -+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); -+#if 0 -+ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { -+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); -+ OPENSSL_free(ret); -+ ret = NULL; -+ } -+#endif -+ return (ret); -+} -+ -+static void *ecdsa_data_new(void) -+{ -+ return (void *)ECDSA_DATA_new_method(NULL); -+} -+ -+static void *ecdsa_data_dup(void *data) -+{ -+ ECDSA_DATA *r = (ECDSA_DATA *)data; -+ -+ /* XXX: dummy operation */ -+ if (r == NULL) -+ return NULL; -+ -+ return ecdsa_data_new(); -+} -+ -+static void ecdsa_data_free(void *data) -+{ -+ ECDSA_DATA *r = (ECDSA_DATA *)data; -+ -+#ifndef OPENSSL_NO_ENGINE -+ if (r->engine) -+ ENGINE_finish(r->engine); -+#endif -+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data); -+ -+ OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA)); -+ -+ OPENSSL_free(r); -+} -+ -+ECDSA_DATA *ecdsa_check(EC_KEY *key) -+{ -+ ECDSA_DATA *ecdsa_data; -+ -+ void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup, -+ ecdsa_data_free, ecdsa_data_free); -+ if (data == NULL) { -+ ecdsa_data = (ECDSA_DATA *)ecdsa_data_new(); -+ if (ecdsa_data == NULL) -+ return NULL; -+ data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data, -+ ecdsa_data_dup, ecdsa_data_free, -+ ecdsa_data_free); -+ if (data != NULL) { -+ /* -+ * Another thread raced us to install the key_method data and -+ * won. -+ */ -+ ecdsa_data_free(ecdsa_data); -+ ecdsa_data = (ECDSA_DATA *)data; -+ } -+ } else -+ ecdsa_data = (ECDSA_DATA *)data; -+#ifdef OPENSSL_FIPS -+ if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD) -+ && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { -+ ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD); -+ return NULL; -+ } -+#endif -+ -+ return ecdsa_data; -+} -+ -+int ECDSA_size(const EC_KEY *r) -+{ -+ int ret, i; -+ ASN1_INTEGER bs; -+ BIGNUM *order = NULL; -+ unsigned char buf[4]; -+ const EC_GROUP *group; -+ -+ if (r == NULL) -+ return 0; -+ group = EC_KEY_get0_group(r); -+ if (group == NULL) -+ return 0; -+ -+ if ((order = BN_new()) == NULL) -+ return 0; -+ if (!EC_GROUP_get_order(group, order, NULL)) { -+ BN_clear_free(order); -+ return 0; -+ } -+ i = BN_num_bits(order); -+ bs.length = (i + 7) / 8; -+ bs.data = buf; -+ bs.type = V_ASN1_INTEGER; -+ /* If the top bit is set the asn1 encoding is 1 larger. */ -+ buf[0] = 0xff; -+ -+ i = i2d_ASN1_INTEGER(&bs, NULL); -+ i += i; /* r and s */ -+ ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); -+ BN_clear_free(order); -+ return (ret); -+} -+ -+int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, -+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -+{ -+ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp, -+ new_func, dup_func, free_func); -+} -+ -+int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg) -+{ -+ ECDSA_DATA *ecdsa; -+ ecdsa = ecdsa_check(d); -+ if (ecdsa == NULL) -+ return 0; -+ return (CRYPTO_set_ex_data(&ecdsa->ex_data, idx, arg)); -+} -+ -+void *ECDSA_get_ex_data(EC_KEY *d, int idx) -+{ -+ ECDSA_DATA *ecdsa; -+ ecdsa = ecdsa_check(d); -+ if (ecdsa == NULL) -+ return NULL; -+ return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx)); -+} -+ -+ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_meth) -+{ -+ ECDSA_METHOD *ret; -+ -+ ret = OPENSSL_malloc(sizeof(ECDSA_METHOD)); -+ if (ret == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_METHOD_NEW, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ if (ecdsa_meth) -+ *ret = *ecdsa_meth; -+ else { -+ ret->ecdsa_sign_setup = 0; -+ ret->ecdsa_do_sign = 0; -+ ret->ecdsa_do_verify = 0; -+ ret->name = NULL; -+ ret->flags = 0; -+ } -+ ret->flags |= ECDSA_METHOD_FLAG_ALLOCATED; -+ return ret; -+} -+ -+void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, -+ ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char -+ *dgst, int dgst_len, -+ const BIGNUM *inv, -+ const BIGNUM *rp, -+ EC_KEY *eckey)) -+{ -+ ecdsa_method->ecdsa_do_sign = ecdsa_do_sign; -+} -+ -+void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, -+ int (*ecdsa_sign_setup) (EC_KEY *eckey, -+ BN_CTX *ctx, -+ BIGNUM **kinv, -+ BIGNUM **r)) -+{ -+ ecdsa_method->ecdsa_sign_setup = ecdsa_sign_setup; -+} -+ -+void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, -+ int (*ecdsa_do_verify) (const unsigned char -+ *dgst, int dgst_len, -+ const ECDSA_SIG *sig, -+ EC_KEY *eckey)) -+{ -+ ecdsa_method->ecdsa_do_verify = ecdsa_do_verify; -+} -+ -+void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags) -+{ -+ ecdsa_method->flags = flags | ECDSA_METHOD_FLAG_ALLOCATED; -+} -+ -+void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name) -+{ -+ ecdsa_method->name = name; -+} -+ -+void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method) -+{ -+ if (ecdsa_method->flags & ECDSA_METHOD_FLAG_ALLOCATED) -+ OPENSSL_free(ecdsa_method); -+} -+ -+void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app) -+{ -+ ecdsa_method->app_data = app; -+} -+ -+void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method) -+{ -+ return ecdsa_method->app_data; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ecdsa/ecs_locl.h b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_locl.h -new file mode 100644 -index 0000000..4e9bd44 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_locl.h -@@ -0,0 +1,120 @@ -+/* crypto/ecdsa/ecs_locl.h */ -+/* -+ * Written by Nils Larsch for the OpenSSL project -+ */ -+/* ==================================================================== -+ * Copyright (c) 2000-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 -+ * licensing@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). -+ * -+ */ -+ -+#ifndef HEADER_ECS_LOCL_H -+# define HEADER_ECS_LOCL_H -+ -+# include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct ecdsa_method { -+ const char *name; -+ ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char *dgst, int dgst_len, -+ const BIGNUM *inv, const BIGNUM *rp, -+ EC_KEY *eckey); -+ int (*ecdsa_sign_setup) (EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, -+ BIGNUM **r); -+ int (*ecdsa_do_verify) (const unsigned char *dgst, int dgst_len, -+ const ECDSA_SIG *sig, EC_KEY *eckey); -+# if 0 -+ int (*init) (EC_KEY *eckey); -+ int (*finish) (EC_KEY *eckey); -+# endif -+ int flags; -+ void *app_data; -+}; -+ -+/* The ECDSA_METHOD was allocated and can be freed */ -+ -+# define ECDSA_METHOD_FLAG_ALLOCATED 0x2 -+ -+/* -+ * If this flag is set the ECDSA method is FIPS compliant and can be used in -+ * FIPS mode. This is set in the validated module method. If an application -+ * sets this flag in its own methods it is its responsibility to ensure the -+ * result is compliant. -+ */ -+ -+# define ECDSA_FLAG_FIPS_METHOD 0x1 -+ -+typedef struct ecdsa_data_st { -+ /* EC_KEY_METH_DATA part */ -+ int (*init) (EC_KEY *); -+ /* method (ECDSA) specific part */ -+ ENGINE *engine; -+ int flags; -+ const ECDSA_METHOD *meth; -+ CRYPTO_EX_DATA ex_data; -+} ECDSA_DATA; -+ -+/** ecdsa_check -+ * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure -+ * and if not it removes the old meth_data and creates a ECDSA_DATA structure. -+ * \param eckey pointer to a EC_KEY object -+ * \return pointer to a ECDSA_DATA structure -+ */ -+ECDSA_DATA *ecdsa_check(EC_KEY *eckey); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* HEADER_ECS_LOCL_H */ -diff --git a/Cryptlib/OpenSSL/crypto/ecdsa/ecs_ossl.c b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_ossl.c -new file mode 100644 -index 0000000..dd76960 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_ossl.c -@@ -0,0 +1,464 @@ -+/* crypto/ecdsa/ecs_ossl.c */ -+/* -+ * Written by Nils Larsch for the OpenSSL project -+ */ -+/* ==================================================================== -+ * Copyright (c) 1998-2004 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 "ecs_locl.h" -+#include -+#include -+#include -+ -+static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, -+ const BIGNUM *, const BIGNUM *, -+ EC_KEY *eckey); -+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, -+ BIGNUM **rp); -+static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, -+ const ECDSA_SIG *sig, EC_KEY *eckey); -+ -+static ECDSA_METHOD openssl_ecdsa_meth = { -+ "OpenSSL ECDSA method", -+ ecdsa_do_sign, -+ ecdsa_sign_setup, -+ ecdsa_do_verify, -+#if 0 -+ NULL, /* init */ -+ NULL, /* finish */ -+#endif -+ 0, /* flags */ -+ NULL /* app_data */ -+}; -+ -+const ECDSA_METHOD *ECDSA_OpenSSL(void) -+{ -+ return &openssl_ecdsa_meth; -+} -+ -+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, -+ BIGNUM **rp) -+{ -+ BN_CTX *ctx = NULL; -+ BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; -+ EC_POINT *tmp_point = NULL; -+ const EC_GROUP *group; -+ int ret = 0; -+ -+ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); -+ return 0; -+ } -+ -+ if (ctx_in == NULL) { -+ if ((ctx = BN_CTX_new()) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ } else -+ ctx = ctx_in; -+ -+ k = BN_new(); /* this value is later returned in *kinvp */ -+ r = BN_new(); /* this value is later returned in *rp */ -+ order = BN_new(); -+ X = BN_new(); -+ if (!k || !r || !order || !X) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if ((tmp_point = EC_POINT_new(group)) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (!EC_GROUP_get_order(group, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ do { -+ /* get random k */ -+ do -+ if (!BN_rand_range(k, order)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, -+ ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); -+ goto err; -+ } -+ while (BN_is_zero(k)) ; -+ -+ /* -+ * We do not want timing information to leak the length of k, so we -+ * compute G*k using an equivalent scalar of fixed bit-length. -+ */ -+ -+ if (!BN_add(k, k, order)) -+ goto err; -+ if (BN_num_bits(k) <= BN_num_bits(order)) -+ if (!BN_add(k, k, order)) -+ goto err; -+ -+ /* compute r the x-coordinate of generator * k */ -+ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == -+ NID_X9_62_prime_field) { -+ if (!EC_POINT_get_affine_coordinates_GFp -+ (group, tmp_point, X, NULL, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#ifndef OPENSSL_NO_EC2M -+ else { /* NID_X9_62_characteristic_two_field */ -+ -+ if (!EC_POINT_get_affine_coordinates_GF2m(group, -+ tmp_point, X, NULL, -+ ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#endif -+ if (!BN_nnmod(r, X, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); -+ goto err; -+ } -+ } -+ while (BN_is_zero(r)); -+ -+ /* compute the inverse of k */ -+ if (EC_GROUP_get_mont_data(group) != NULL) { -+ /* -+ * We want inverse in constant time, therefore we utilize the fact -+ * order must be prime and use Fermats Little Theorem instead. -+ */ -+ if (!BN_set_word(X, 2)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); -+ goto err; -+ } -+ if (!BN_mod_sub(X, order, X, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); -+ goto err; -+ } -+ BN_set_flags(X, BN_FLG_CONSTTIME); -+ if (!BN_mod_exp_mont_consttime -+ (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); -+ goto err; -+ } -+ } else { -+ if (!BN_mod_inverse(k, k, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); -+ goto err; -+ } -+ } -+ -+ /* clear old values if necessary */ -+ if (*rp != NULL) -+ BN_clear_free(*rp); -+ if (*kinvp != NULL) -+ BN_clear_free(*kinvp); -+ /* save the pre-computed values */ -+ *rp = r; -+ *kinvp = k; -+ ret = 1; -+ err: -+ if (!ret) { -+ if (k != NULL) -+ BN_clear_free(k); -+ if (r != NULL) -+ BN_clear_free(r); -+ } -+ if (ctx_in == NULL) -+ BN_CTX_free(ctx); -+ if (order != NULL) -+ BN_free(order); -+ if (tmp_point != NULL) -+ EC_POINT_free(tmp_point); -+ if (X) -+ BN_clear_free(X); -+ return (ret); -+} -+ -+static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, -+ const BIGNUM *in_kinv, const BIGNUM *in_r, -+ EC_KEY *eckey) -+{ -+ int ok = 0, i; -+ BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; -+ const BIGNUM *ckinv; -+ BN_CTX *ctx = NULL; -+ const EC_GROUP *group; -+ ECDSA_SIG *ret; -+ ECDSA_DATA *ecdsa; -+ const BIGNUM *priv_key; -+ -+ ecdsa = ecdsa_check(eckey); -+ group = EC_KEY_get0_group(eckey); -+ priv_key = EC_KEY_get0_private_key(eckey); -+ -+ if (group == NULL || priv_key == NULL || ecdsa == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); -+ return NULL; -+ } -+ -+ ret = ECDSA_SIG_new(); -+ if (!ret) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ s = ret->s; -+ -+ if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || -+ (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ if (!EC_GROUP_get_order(group, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); -+ goto err; -+ } -+ i = BN_num_bits(order); -+ /* -+ * Need to truncate digest if it is too long: first truncate whole bytes. -+ */ -+ if (8 * dgst_len > i) -+ dgst_len = (i + 7) / 8; -+ if (!BN_bin2bn(dgst, dgst_len, m)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ /* If still too long truncate remaining bits with a shift */ -+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ do { -+ if (in_kinv == NULL || in_r == NULL) { -+ if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB); -+ goto err; -+ } -+ ckinv = kinv; -+ } else { -+ ckinv = in_kinv; -+ if (BN_copy(ret->r, in_r) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ -+ if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ if (!BN_mod_add_quick(s, tmp, m, order)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ if (!BN_mod_mul(s, s, ckinv, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); -+ goto err; -+ } -+ if (BN_is_zero(s)) { -+ /* -+ * if kinv and r have been supplied by the caller don't to -+ * generate new kinv and r values -+ */ -+ if (in_kinv != NULL && in_r != NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, -+ ECDSA_R_NEED_NEW_SETUP_VALUES); -+ goto err; -+ } -+ } else -+ /* s != 0 => we have a valid signature */ -+ break; -+ } -+ while (1); -+ -+ ok = 1; -+ err: -+ if (!ok) { -+ ECDSA_SIG_free(ret); -+ ret = NULL; -+ } -+ if (ctx) -+ BN_CTX_free(ctx); -+ if (m) -+ BN_clear_free(m); -+ if (tmp) -+ BN_clear_free(tmp); -+ if (order) -+ BN_free(order); -+ if (kinv) -+ BN_clear_free(kinv); -+ return ret; -+} -+ -+static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, -+ const ECDSA_SIG *sig, EC_KEY *eckey) -+{ -+ int ret = -1, i; -+ BN_CTX *ctx; -+ BIGNUM *order, *u1, *u2, *m, *X; -+ EC_POINT *point = NULL; -+ const EC_GROUP *group; -+ const EC_POINT *pub_key; -+ -+ /* check input values */ -+ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || -+ (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); -+ return -1; -+ } -+ -+ ctx = BN_CTX_new(); -+ if (!ctx) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ return -1; -+ } -+ BN_CTX_start(ctx); -+ order = BN_CTX_get(ctx); -+ u1 = BN_CTX_get(ctx); -+ u2 = BN_CTX_get(ctx); -+ m = BN_CTX_get(ctx); -+ X = BN_CTX_get(ctx); -+ if (!X) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ if (!EC_GROUP_get_order(group, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ -+ if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || -+ BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || -+ BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); -+ ret = 0; /* signature is invalid */ -+ goto err; -+ } -+ /* calculate tmp1 = inv(S) mod order */ -+ if (!BN_mod_inverse(u2, sig->s, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ /* digest -> m */ -+ i = BN_num_bits(order); -+ /* -+ * Need to truncate digest if it is too long: first truncate whole bytes. -+ */ -+ if (8 * dgst_len > i) -+ dgst_len = (i + 7) / 8; -+ if (!BN_bin2bn(dgst, dgst_len, m)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ /* If still too long truncate remaining bits with a shift */ -+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ /* u1 = m * tmp mod order */ -+ if (!BN_mod_mul(u1, m, u2, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ /* u2 = r * w mod q */ -+ if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ -+ if ((point = EC_POINT_new(group)) == NULL) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == -+ NID_X9_62_prime_field) { -+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#ifndef OPENSSL_NO_EC2M -+ else { /* NID_X9_62_characteristic_two_field */ -+ -+ if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); -+ goto err; -+ } -+ } -+#endif -+ if (!BN_nnmod(u1, X, order, ctx)) { -+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); -+ goto err; -+ } -+ /* if the signature is correct u1 is equal to sig->r */ -+ ret = (BN_ucmp(u1, sig->r) == 0); -+ err: -+ BN_CTX_end(ctx); -+ BN_CTX_free(ctx); -+ if (point) -+ EC_POINT_free(point); -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/ecdsa/ecs_sign.c b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_sign.c -new file mode 100644 -index 0000000..28652d4 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_sign.c -@@ -0,0 +1,106 @@ -+/* crypto/ecdsa/ecdsa_sign.c */ -+/* ==================================================================== -+ * 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 "ecs_locl.h" -+#ifndef OPENSSL_NO_ENGINE -+# include -+#endif -+#include -+ -+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) -+{ -+ return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey); -+} -+ -+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, -+ const BIGNUM *kinv, const BIGNUM *rp, -+ EC_KEY *eckey) -+{ -+ ECDSA_DATA *ecdsa = ecdsa_check(eckey); -+ if (ecdsa == NULL) -+ return NULL; -+ return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey); -+} -+ -+int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char -+ *sig, unsigned int *siglen, EC_KEY *eckey) -+{ -+ return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); -+} -+ -+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char -+ *sig, unsigned int *siglen, const BIGNUM *kinv, -+ const BIGNUM *r, EC_KEY *eckey) -+{ -+ ECDSA_SIG *s; -+ RAND_seed(dgst, dlen); -+ s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); -+ if (s == NULL) { -+ *siglen = 0; -+ return 0; -+ } -+ *siglen = i2d_ECDSA_SIG(s, &sig); -+ ECDSA_SIG_free(s); -+ return 1; -+} -+ -+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, -+ BIGNUM **rp) -+{ -+ ECDSA_DATA *ecdsa = ecdsa_check(eckey); -+ if (ecdsa == NULL) -+ return 0; -+ return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); -+} -diff --git a/Cryptlib/OpenSSL/crypto/ecdsa/ecs_vrf.c b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_vrf.c -new file mode 100644 -index 0000000..e909aeb ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/ecdsa/ecs_vrf.c -@@ -0,0 +1,112 @@ -+/* crypto/ecdsa/ecdsa_vrf.c */ -+/* -+ * Written by Nils Larsch for the OpenSSL project -+ */ -+/* ==================================================================== -+ * 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 "ecs_locl.h" -+#include -+#ifndef OPENSSL_NO_ENGINE -+# include -+#endif -+ -+/*- -+ * returns -+ * 1: correct signature -+ * 0: incorrect signature -+ * -1: error -+ */ -+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, -+ const ECDSA_SIG *sig, EC_KEY *eckey) -+{ -+ ECDSA_DATA *ecdsa = ecdsa_check(eckey); -+ if (ecdsa == NULL) -+ return 0; -+ return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); -+} -+ -+/*- -+ * returns -+ * 1: correct signature -+ * 0: incorrect signature -+ * -1: error -+ */ -+int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, -+ const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) -+{ -+ ECDSA_SIG *s; -+ const unsigned char *p = sigbuf; -+ unsigned char *der = NULL; -+ int derlen = -1; -+ int ret = -1; -+ -+ s = ECDSA_SIG_new(); -+ if (s == NULL) -+ return (ret); -+ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) -+ goto err; -+ /* Ensure signature uses DER and doesn't have trailing garbage */ -+ derlen = i2d_ECDSA_SIG(s, &der); -+ if (derlen != sig_len || memcmp(sigbuf, der, derlen)) -+ goto err; -+ ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); -+ err: -+ if (derlen > 0) { -+ OPENSSL_cleanse(der, derlen); -+ OPENSSL_free(der); -+ } -+ ECDSA_SIG_free(s); -+ return (ret); -+} -diff --git a/Cryptlib/OpenSSL/crypto/err/err.c b/Cryptlib/OpenSSL/crypto/err/err.c -index e225145..aac5956 100644 ---- a/Cryptlib/OpenSSL/crypto/err/err.c -+++ b/Cryptlib/OpenSSL/crypto/err/err.c -@@ -155,6 +155,7 @@ static ERR_STRING_DATA ERR_str_libraries[] = { - {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"}, - {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"}, - {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"}, - {0, NULL}, - }; - -diff --git a/Cryptlib/OpenSSL/crypto/evp/c_alld.c b/Cryptlib/OpenSSL/crypto/evp/c_alld.c -index fdbe3ee..6cad383 100644 ---- a/Cryptlib/OpenSSL/crypto/evp/c_alld.c -+++ b/Cryptlib/OpenSSL/crypto/evp/c_alld.c -@@ -111,4 +111,7 @@ void OpenSSL_add_all_digests(void) - #ifndef OPENSSL_NO_WHIRLPOOL - EVP_add_digest(EVP_whirlpool()); - #endif -+#ifndef OPENSSL_NO_SM3 -+ EVP_add_digest(EVP_sm3()); -+#endif - } -diff --git a/Cryptlib/OpenSSL/crypto/evp/digest.c b/Cryptlib/OpenSSL/crypto/evp/digest.c -index 4db1796..ffc03ef 100644 ---- a/Cryptlib/OpenSSL/crypto/evp/digest.c -+++ b/Cryptlib/OpenSSL/crypto/evp/digest.c -@@ -122,6 +122,48 @@ - # include "evp_locl.h" - #endif - -+/* This call frees resources associated with the context */ -+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) -+{ -+ if (ctx == NULL) -+ return 1; -+ -+ /* -+ * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because -+ * sometimes only copies of the context are ever finalised. -+ */ -+ if (ctx->digest && ctx->digest->cleanup -+ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) -+ ctx->digest->cleanup(ctx); -+ if (ctx->digest && ctx->digest->ctx_size && ctx->md_data -+ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { -+ OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); -+ } -+ /* -+ * pctx should be freed by the user of EVP_MD_CTX -+ * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set -+ */ -+ if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) -+ EVP_PKEY_CTX_free(ctx->pctx); -+#ifndef OPENSSL_NO_ENGINE -+ ENGINE_finish(ctx->engine); -+#endif -+ OPENSSL_cleanse(ctx, sizeof(*ctx)); -+ -+ return 1; -+} -+ -+EVP_MD_CTX *EVP_MD_CTX_new(void) -+{ -+ return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); -+} -+ -+void EVP_MD_CTX_free(EVP_MD_CTX *ctx) -+{ -+ EVP_MD_CTX_reset(ctx); -+ OPENSSL_free(ctx); -+} -+ - void EVP_MD_CTX_init(EVP_MD_CTX *ctx) - { - memset(ctx, '\0', sizeof *ctx); -@@ -139,7 +181,7 @@ EVP_MD_CTX *EVP_MD_CTX_create(void) - - int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) - { -- EVP_MD_CTX_init(ctx); -+ EVP_MD_CTX_reset(ctx); - return EVP_DigestInit_ex(ctx, type, NULL); - } - -@@ -264,7 +306,7 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) - { - int ret; - ret = EVP_DigestFinal_ex(ctx, md, size); -- EVP_MD_CTX_cleanup(ctx); -+ EVP_MD_CTX_reset(ctx); - return ret; - } - -@@ -291,7 +333,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) - - int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) - { -- EVP_MD_CTX_init(out); -+ EVP_MD_CTX_reset(out); - return EVP_MD_CTX_copy_ex(out, in); - } - -@@ -315,9 +357,19 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) - EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); - } else - tmp_buf = NULL; -- EVP_MD_CTX_cleanup(out); -+ EVP_MD_CTX_reset(out); - memcpy(out, in, sizeof *out); - -+ /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */ -+ EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); -+ -+ /* Null these variables, since they are getting fixed up -+ * properly below. Anything else may cause a memleak and/or -+ * double free if any of the memory allocations below fail -+ */ -+ out->md_data = NULL; -+ out->pctx = NULL; -+ - if (in->md_data && out->digest->ctx_size) { - if (tmp_buf) - out->md_data = tmp_buf; -@@ -336,7 +388,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) - if (in->pctx) { - out->pctx = EVP_PKEY_CTX_dup(in->pctx); - if (!out->pctx) { -- EVP_MD_CTX_cleanup(out); -+ EVP_MD_CTX_reset(out); - return 0; - } - } -diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_lib.c b/Cryptlib/OpenSSL/crypto/evp/evp_lib.c -index 7e0bab9..5945494 100644 ---- a/Cryptlib/OpenSSL/crypto/evp/evp_lib.c -+++ b/Cryptlib/OpenSSL/crypto/evp/evp_lib.c -@@ -389,3 +389,8 @@ int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) - { - return (ctx->flags & flags); - } -+ -+void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx) -+{ -+ return ctx->md_data; -+} -diff --git a/Cryptlib/OpenSSL/crypto/evp/evp_locl.h b/Cryptlib/OpenSSL/crypto/evp/evp_locl.h -index 2bb709a..1d179ef 100644 ---- a/Cryptlib/OpenSSL/crypto/evp/evp_locl.h -+++ b/Cryptlib/OpenSSL/crypto/evp/evp_locl.h -@@ -324,6 +324,16 @@ struct evp_pkey_method_st { - int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); - int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); - int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); -+ int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, -+ const unsigned char *tbs, size_t tbslen); -+ int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, -+ size_t siglen, const unsigned char *tbs, -+ size_t tbslen); -+ int (*check) (EVP_PKEY *pkey); -+ int (*public_check) (EVP_PKEY *pkey); -+ int (*param_check) (EVP_PKEY *pkey); -+ -+ int (*digest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); - } /* EVP_PKEY_METHOD */ ; - - void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); -diff --git a/Cryptlib/OpenSSL/crypto/evp/m_sigver.c b/Cryptlib/OpenSSL/crypto/evp/m_sigver.c -index 4492d20..771b659 100644 ---- a/Cryptlib/OpenSSL/crypto/evp/m_sigver.c -+++ b/Cryptlib/OpenSSL/crypto/evp/m_sigver.c -@@ -110,6 +110,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - return 1; - if (!EVP_DigestInit_ex(ctx, type, e)) - return 0; -+ /* -+ * This indicates the current algorithm requires -+ * special treatment before hashing the tbs-message. -+ */ -+ if (ctx->pctx->pmeth->digest_custom != NULL) -+ return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx); -+ - return 1; - } - -@@ -201,3 +208,13 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, - return r; - return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); - } -+ -+int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, -+ size_t siglen, const unsigned char *tbs, size_t tbslen) -+{ -+ if (ctx->pctx->pmeth->digestverify != NULL) -+ return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen); -+ if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) -+ return -1; -+ return EVP_DigestVerifyFinal(ctx, sigret, siglen); -+} -diff --git a/Cryptlib/OpenSSL/crypto/evp/p_lib.c b/Cryptlib/OpenSSL/crypto/evp/p_lib.c -index 545d04f..c95d038 100644 ---- a/Cryptlib/OpenSSL/crypto/evp/p_lib.c -+++ b/Cryptlib/OpenSSL/crypto/evp/p_lib.c -@@ -259,6 +259,24 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) - return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); - } - -+int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type) -+{ -+ if (pkey->type == type) { -+ return 1; /* it already is that type */ -+ } -+ -+ /* -+ * The application is requesting to alias this to a different pkey type, -+ * but not one that resolves to the base type. -+ */ -+ if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) { -+ return 0; -+ } -+ -+ pkey->type = type; -+ return 1; -+} -+ - int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) - { - if (pkey == NULL || !EVP_PKEY_set_type(pkey, type)) -@@ -272,6 +290,24 @@ void *EVP_PKEY_get0(EVP_PKEY *pkey) - return pkey->pkey.ptr; - } - -+# ifndef OPENSSL_NO_SM2 -+int EVP_PKEY_is_sm2(EVP_PKEY *pkey) -+{ -+ EC_KEY *eckey; -+ const EC_GROUP *group; -+ if (pkey == NULL) { -+ return 0; -+ } -+ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC -+ && (eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL -+ && (group = EC_KEY_get0_group(eckey)) != NULL -+ && EC_GROUP_get_curve_name(group) == NID_sm2) { -+ return 1; -+ } -+ return EVP_PKEY_id(pkey) == EVP_PKEY_SM2; -+} -+# endif -+ - #ifndef OPENSSL_NO_RSA - int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) - { -@@ -322,6 +358,14 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) - return ret; - } - -+EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) -+{ -+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { -+ return NULL; -+ } -+ return pkey->pkey.ec; -+} -+ - EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) - { - if (pkey->type != EVP_PKEY_EC) { -diff --git a/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c b/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c -index d066862..8e52917 100644 ---- a/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c -+++ b/Cryptlib/OpenSSL/crypto/evp/pmeth_lib.c -@@ -75,7 +75,7 @@ STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; - - extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth; - extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth; --extern const EVP_PKEY_METHOD dhx_pkey_meth; -+extern const EVP_PKEY_METHOD dhx_pkey_meth, sm2_pkey_meth; - - static const EVP_PKEY_METHOD *standard_methods[] = { - #ifndef OPENSSL_NO_RSA -@@ -95,7 +95,10 @@ static const EVP_PKEY_METHOD *standard_methods[] = { - &cmac_pkey_meth, - #endif - #ifndef OPENSSL_NO_DH -- &dhx_pkey_meth -+ &dhx_pkey_meth, -+#endif -+#ifndef OPENSSL_NO_SM2 -+ &sm2_pkey_meth, - #endif - }; - -@@ -135,9 +138,9 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) - EVP_PKEY_CTX *ret; - const EVP_PKEY_METHOD *pmeth; - if (id == -1) { -- if (!pkey || !pkey->ameth) -+ if (!pkey) - return NULL; -- id = pkey->ameth->pkey_id; -+ id = pkey->type; - } - #ifndef OPENSSL_NO_ENGINE - if (pkey && pkey->engine) -@@ -365,6 +368,10 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, - if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) - return -1; - -+/* Skip the operation checks since this is called in a very early stage */ -+ if (ctx->pmeth->digest_custom != NULL) -+ goto doit; -+ - if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); - return -1; -@@ -375,6 +382,7 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, - return -1; - } - -+doit: - ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); - - if (ret == -2) -diff --git a/Cryptlib/OpenSSL/crypto/mem.c b/Cryptlib/OpenSSL/crypto/mem.c -index 06c3960..ae5a165 100644 ---- a/Cryptlib/OpenSSL/crypto/mem.c -+++ b/Cryptlib/OpenSSL/crypto/mem.c -@@ -456,3 +456,21 @@ long CRYPTO_get_mem_debug_options(void) - return get_debug_options_func(); - return 0; - } -+ -+void *CRYPTO_zalloc(int num, const char *file, int line) -+{ -+ void *ret = CRYPTO_malloc(num, file, line); -+ -+ if (ret != NULL) -+ memset(ret, 0, num); -+ return ret; -+} -+ -+void CRYPTO_clear_free(void *str, int num, const char *file, int line) -+{ -+ if (str == NULL) -+ return; -+ if (num) -+ OPENSSL_cleanse(str, num); -+ CRYPTO_free(str); -+} -diff --git a/Cryptlib/OpenSSL/crypto/o_str.c b/Cryptlib/OpenSSL/crypto/o_str.c -index 7e61cde..c46c631 100644 ---- a/Cryptlib/OpenSSL/crypto/o_str.c -+++ b/Cryptlib/OpenSSL/crypto/o_str.c -@@ -60,6 +60,8 @@ - #include - #include - #include "o_str.h" -+#include "openssl/crypto.h" -+#include "openssl/err.h" - - #if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \ - !defined(OPENSSL_SYSNAME_WIN32) && !defined(OPENSSL_SYSNAME_WINCE) && \ -@@ -114,3 +116,88 @@ int OPENSSL_memcmp(const void *v1, const void *v2, size_t n) - - return ret; - } -+ -+int OPENSSL_hexchar2int(unsigned char c) -+{ -+#ifdef CHARSET_EBCDIC -+ c = os_toebcdic[c]; -+#endif -+ -+ switch (c) { -+ case '0': -+ return 0; -+ case '1': -+ return 1; -+ case '2': -+ return 2; -+ case '3': -+ return 3; -+ case '4': -+ return 4; -+ case '5': -+ return 5; -+ case '6': -+ return 6; -+ case '7': -+ return 7; -+ case '8': -+ return 8; -+ case '9': -+ return 9; -+ case 'a': case 'A': -+ return 0x0A; -+ case 'b': case 'B': -+ return 0x0B; -+ case 'c': case 'C': -+ return 0x0C; -+ case 'd': case 'D': -+ return 0x0D; -+ case 'e': case 'E': -+ return 0x0E; -+ case 'f': case 'F': -+ return 0x0F; -+ } -+ return -1; -+} -+ -+/* -+ * Give a string of hex digits convert to a buffer -+ */ -+unsigned char *OPENSSL_hexstr2buf(const char *str, long *len) -+{ -+ unsigned char *hexbuf, *q; -+ unsigned char ch, cl; -+ int chi, cli; -+ const unsigned char *p; -+ size_t s; -+ -+ s = strlen(str); -+ if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) { -+ CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (p = (const unsigned char *)str, q = hexbuf; *p; ) { -+ ch = *p++; -+ if (ch == ':') -+ continue; -+ cl = *p++; -+ if (!cl) { -+ CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, -+ CRYPTO_R_ODD_NUMBER_OF_DIGITS); -+ OPENSSL_free(hexbuf); -+ return NULL; -+ } -+ cli = OPENSSL_hexchar2int(cl); -+ chi = OPENSSL_hexchar2int(ch); -+ if (cli < 0 || chi < 0) { -+ OPENSSL_free(hexbuf); -+ CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); -+ return NULL; -+ } -+ *q++ = (unsigned char)((chi << 4) | cli); -+ } -+ -+ if (len) -+ *len = q - hexbuf; -+ return hexbuf; -+} -diff --git a/Cryptlib/OpenSSL/crypto/objects/obj_dat.h b/Cryptlib/OpenSSL/crypto/objects/obj_dat.h -index b7e3cf2..30ea261 100644 ---- a/Cryptlib/OpenSSL/crypto/objects/obj_dat.h -+++ b/Cryptlib/OpenSSL/crypto/objects/obj_dat.h -@@ -62,12 +62,12 @@ - * [including the GNU Public Licence.] - */ - --#define NUM_NID 958 --#define NUM_SN 951 --#define NUM_LN 951 --#define NUM_OBJ 890 -+#define NUM_NID 965 -+#define NUM_SN 958 -+#define NUM_LN 958 -+#define NUM_OBJ 897 - --static const unsigned char lvalues[6255]={ -+static const unsigned char lvalues[6301]={ - 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ -@@ -952,6 +952,13 @@ static const unsigned char lvalues[6255]={ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,/* [6221] OBJ_jurisdictionLocalityName */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,/* [6232] OBJ_jurisdictionStateOrProvinceName */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,/* [6243] OBJ_jurisdictionCountryName */ -+0x2A,0x81,0x1C, /* [6254] OBJ_ISO_CN */ -+0x2A,0x81,0x1C,0xCF,0x55, /* [6257] OBJ_oscca */ -+0x2A,0x81,0x1C,0xCF,0x55,0x01, /* [6262] OBJ_sm_scheme */ -+0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D, /* [6268] OBJ_sm2 */ -+0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11, /* [6276] OBJ_sm3 */ -+0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x78, /* [6284] OBJ_sm3WithRSAEncryption */ -+0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [6292] OBJ_SM2_with_SM3 */ - }; - - static const ASN1_OBJECT nid_objs[NUM_NID]={ -@@ -2514,6 +2521,14 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={ - NID_jurisdictionStateOrProvinceName,11,&(lvalues[6232]),0}, - {"jurisdictionC","jurisdictionCountryName", - NID_jurisdictionCountryName,11,&(lvalues[6243]),0}, -+{"ISO-CN","ISO CN Member Body",NID_ISO_CN,3,&(lvalues[6254]),0}, -+{"oscca","oscca",NID_oscca,5,&(lvalues[6257]),0}, -+{"sm-scheme","sm-scheme",NID_sm_scheme,6,&(lvalues[6262]),0}, -+{"SM2","sm2",NID_sm2,8,&(lvalues[6268]),0}, -+{"SM3","sm3",NID_sm3,8,&(lvalues[6276]),0}, -+{"RSA-SM3","sm3WithRSAEncryption",NID_sm3WithRSAEncryption,8, -+ &(lvalues[6284]),0}, -+{"SM2-SM3","SM2-with-SM3",NID_SM2_with_SM3,8,&(lvalues[6292]),0}, - }; - - static const unsigned int sn_objs[NUM_SN]={ -@@ -2615,6 +2630,7 @@ static const unsigned int sn_objs[NUM_SN]={ - 36, /* "IDEA-ECB" */ - 46, /* "IDEA-OFB" */ - 181, /* "ISO" */ -+958, /* "ISO-CN" */ - 183, /* "ISO-US" */ - 645, /* "ITU-T" */ - 646, /* "JOINT-ISO-ITU-T" */ -@@ -2685,6 +2701,10 @@ static const unsigned int sn_objs[NUM_SN]={ - 668, /* "RSA-SHA256" */ - 669, /* "RSA-SHA384" */ - 670, /* "RSA-SHA512" */ -+963, /* "RSA-SM3" */ -+961, /* "SM2" */ -+964, /* "SM2-SM3" */ -+962, /* "SM3" */ - 919, /* "RSAES-OAEP" */ - 912, /* "RSASSA-PSS" */ - 777, /* "SEED-CBC" */ -@@ -3176,6 +3196,7 @@ static const unsigned int sn_objs[NUM_SN]={ - 77, /* "nsSslServerName" */ - 681, /* "onBasis" */ - 491, /* "organizationalStatus" */ -+959, /* "oscca" */ - 475, /* "otherMailbox" */ - 876, /* "owner" */ - 489, /* "pagerTelephoneNumber" */ -@@ -3422,6 +3443,7 @@ static const unsigned int sn_objs[NUM_SN]={ - 52, /* "signingTime" */ - 454, /* "simpleSecurityObject" */ - 496, /* "singleLevelQuality" */ -+960, /* "sm-scheme" */ - 387, /* "snmpv2" */ - 660, /* "street" */ - 85, /* "subjectAltName" */ -@@ -3519,6 +3541,7 @@ static const unsigned int ln_objs[NUM_LN]={ - 294, /* "IPSec End System" */ - 295, /* "IPSec Tunnel" */ - 296, /* "IPSec User" */ -+958, /* "ISO CN Member Body" */ - 182, /* "ISO Member Body" */ - 183, /* "ISO US Member Body" */ - 667, /* "Independent" */ -@@ -3573,6 +3596,7 @@ static const unsigned int ln_objs[NUM_LN]={ - 2, /* "RSA Data Security, Inc. PKCS" */ - 188, /* "S/MIME" */ - 167, /* "S/MIME Capabilities" */ -+964, /* "SM2-with-SM3" */ - 387, /* "SNMPv2" */ - 512, /* "Secure Electronic Transactions" */ - 386, /* "Security" */ -@@ -4105,6 +4129,7 @@ static const unsigned int ln_objs[NUM_LN]={ - 17, /* "organizationName" */ - 491, /* "organizationalStatus" */ - 18, /* "organizationalUnitName" */ -+959, /* "oscca" */ - 475, /* "otherMailbox" */ - 876, /* "owner" */ - 935, /* "pSpecified" */ -@@ -4379,6 +4404,10 @@ static const unsigned int ln_objs[NUM_LN]={ - 52, /* "signingTime" */ - 454, /* "simpleSecurityObject" */ - 496, /* "singleLevelQuality" */ -+960, /* "sm-scheme" */ -+961, /* "sm2" */ -+962, /* "sm3" */ -+963, /* "sm3WithRSAEncryption" */ - 16, /* "stateOrProvinceName" */ - 660, /* "streetAddress" */ - 498, /* "subtreeMaximumQuality" */ -@@ -4444,6 +4473,7 @@ static const unsigned int obj_objs[NUM_OBJ]={ - 512, /* OBJ_id_set 2 23 42 */ - 678, /* OBJ_wap 2 23 43 */ - 435, /* OBJ_pss 0 9 2342 */ -+958, /* OBJ_ISO_CN 1 2 156 */ - 183, /* OBJ_ISO_US 1 2 840 */ - 381, /* OBJ_iana 1 3 6 1 */ - 677, /* OBJ_certicom_arc 1 3 132 */ -@@ -4659,6 +4689,7 @@ static const unsigned int obj_objs[NUM_OBJ]={ - 637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ - 638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ - 639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ -+959, /* OBJ_oscca 1 2 156 10197 */ - 805, /* OBJ_cryptopro 1 2 643 2 2 */ - 806, /* OBJ_cryptocom 1 2 643 2 9 */ - 184, /* OBJ_X9_57 1 2 840 10040 */ -@@ -4733,6 +4764,7 @@ static const unsigned int obj_objs[NUM_OBJ]={ - 745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ - 804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ - 124, /* OBJ_rle_compression 1 1 1 1 666 1 */ -+960, /* OBJ_sm_scheme 1 2 156 10197 1 */ - 773, /* OBJ_kisa 1 2 410 200004 */ - 807, /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ - 808, /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ -@@ -4836,6 +4868,10 @@ static const unsigned int obj_objs[NUM_OBJ]={ - 768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ - 759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ - 437, /* OBJ_pilot 0 9 2342 19200300 100 */ -+961, /* OBJ_sm2 1 2 156 10197 1 301 */ -+962, /* OBJ_sm3 1 2 156 10197 1 401 */ -+964, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */ -+963, /* OBJ_sm3WithRSAEncryption 1 2 156 10197 1 504 */ - 776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ - 777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ - 779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */ -diff --git a/Cryptlib/OpenSSL/crypto/objects/obj_xref.h b/Cryptlib/OpenSSL/crypto/objects/obj_xref.h -index e453e99..cf08a14 100644 ---- a/Cryptlib/OpenSSL/crypto/objects/obj_xref.h -+++ b/Cryptlib/OpenSSL/crypto/objects/obj_xref.h -@@ -56,6 +56,7 @@ static const nid_triple sigoid_srt[] = { - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha512kdf_scheme, NID_sha512, - NID_dh_cofactor_kdf}, -+ {NID_SM2_with_SM3, NID_sm3, NID_sm2}, - }; - - static const nid_triple *const sigoid_srt_xref[] = { -@@ -96,4 +97,5 @@ static const nid_triple *const sigoid_srt_xref[] = { - &sigoid_srt[26], - &sigoid_srt[27], - &sigoid_srt[28], -+ &sigoid_srt[40], - }; -diff --git a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c -index e6a44f4..2acd0c2 100644 ---- a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c -+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c -@@ -1032,10 +1032,10 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - ASN1_OCTET_STRING *os; - EVP_MD_CTX mdc_tmp, *mdc; - int ret = 0, i; -- int md_type; -+ int md_type, is_sm2 = 0; - STACK_OF(X509_ATTRIBUTE) *sk; - BIO *btmp; -- EVP_PKEY *pkey; -+ EVP_PKEY *pkey = NULL; - - EVP_MD_CTX_init(&mdc_tmp); - -@@ -1070,6 +1070,18 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - btmp = BIO_next(btmp); - } - -+#ifndef OPENSSL_NO_SM2 -+ pkey = X509_get_pubkey(x509); -+ if (!pkey) -+ goto err; -+ -+ if (EVP_PKEY_is_sm2(pkey)) { -+ is_sm2 = 1; -+ if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) -+ goto err; -+ } -+#endif -+ - /* - * mdc is the digest ctx that we want, unless there are attributes, in - * which case the digest is the signed attributes -@@ -1110,7 +1122,12 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - goto err; - } - -- if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL)) -+ ret = is_sm2 ? EVP_DigestVerifyInit(&mdc_tmp, NULL, EVP_get_digestbynid(md_type), NULL, pkey) : -+ EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL); -+ if (!ret) -+ goto err; -+ -+ if (!EVP_DigestVerifyInit(&mdc_tmp, NULL, EVP_get_digestbynid(md_type), NULL, pkey)) - goto err; - - alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, -@@ -1127,14 +1144,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - } - - os = si->enc_digest; -- pkey = X509_get_pubkey(x509); -- if (!pkey) { -- ret = -1; -- goto err; -- } -- -- i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); -- EVP_PKEY_free(pkey); -+ i = is_sm2 ? EVP_DigestVerifyFinal(&mdc_tmp, os->data, os->length) : -+ EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); - if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); - ret = -1; -@@ -1142,6 +1153,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - } else - ret = 1; - err: -+ EVP_PKEY_free(pkey); - EVP_MD_CTX_cleanup(&mdc_tmp); - return (ret); - } -diff --git a/Cryptlib/OpenSSL/crypto/sm2/sm2_err.c b/Cryptlib/OpenSSL/crypto/sm2/sm2_err.c -new file mode 100644 -index 0000000..6e06f6a ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/sm2/sm2_err.c -@@ -0,0 +1,71 @@ -+/* -+ * Generated by util/mkerr.pl DO NOT EDIT -+ * Copyright 1995-2022 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 -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+ -+#ifndef OPENSSL_NO_ERR -+ -+static const ERR_STRING_DATA SM2_str_functs[] = { -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_COPY, 0), "pkey_sm2_copy"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL, 0), "pkey_sm2_ctrl"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL_STR, 0), "pkey_sm2_ctrl_str"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_DIGEST_CUSTOM, 0), -+ "pkey_sm2_digest_custom"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_INIT, 0), "pkey_sm2_init"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_KEY, 0), "SM2_compute_key"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_MSG_HASH, 0), -+ "sm2_compute_msg_hash"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_USERID_DIGEST, 0), -+ "sm2_compute_userid_digest"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_Z_DIGEST, 0), -+ "sm2_compute_z_digest"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_DECRYPT, 0), "sm2_decrypt"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_ENCRYPT, 0), "sm2_encrypt"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_PLAINTEXT_SIZE, 0), "sm2_plaintext_size"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIGN, 0), "sm2_sign"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_GEN, 0), "sm2_sig_gen"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_VERIFY, 0), "sm2_sig_verify"}, -+ {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_VERIFY, 0), "sm2_verify"}, -+ {0, NULL} -+}; -+ -+static const ERR_STRING_DATA SM2_str_reasons[] = { -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ASN1_ERROR), "asn1 error"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BAD_SIGNATURE), "bad signature"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BUFFER_TOO_SMALL), "buffer too small"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_DIST_ID_TOO_LARGE), "dist id too large"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ID_NOT_SET), "id not set"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ID_TOO_LARGE), "id too large"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_CURVE), "invalid curve"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST), "invalid digest"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST_TYPE), -+ "invalid digest type"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ENCODING), "invalid encoding"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_FIELD), "invalid field"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PRIVATE_VALUE), "no private value"}, -+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"}, -+ {0, NULL} -+}; -+ -+#endif -+ -+int ERR_load_SM2_strings(void) -+{ -+#ifndef OPENSSL_NO_ERR -+ if (ERR_func_error_string(SM2_str_functs[0].error) == NULL) { -+ ERR_load_strings_const(SM2_str_functs); -+ ERR_load_strings_const(SM2_str_reasons); -+ } -+#endif -+ return 1; -+} -diff --git a/Cryptlib/OpenSSL/crypto/sm2/sm2_pmeth.c b/Cryptlib/OpenSSL/crypto/sm2/sm2_pmeth.c -new file mode 100644 -index 0000000..b0d9519 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/sm2/sm2_pmeth.c -@@ -0,0 +1,292 @@ -+/* -+ * Copyright 2006-2021 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 -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "crypto/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "crypto/evp/evp_locl.h" -+#include -+#include -+ -+/* EC pkey context structure */ -+ -+typedef struct { -+ /* Key and paramgen group */ -+ EC_GROUP *gen_group; -+ /* message digest */ -+ const EVP_MD *md; -+ /* Distinguishing Identifier, ISO/IEC 15946-3 */ -+ uint8_t *id; -+ size_t id_len; -+ /* id_set indicates if the 'id' field is set (1) or not (0) */ -+ int id_set; -+} SM2_PKEY_CTX; -+ -+static int pkey_sm2_init(EVP_PKEY_CTX *ctx) -+{ -+ SM2_PKEY_CTX *smctx; -+ -+ if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) { -+ SM2err(SM2_F_PKEY_SM2_INIT, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ -+ ctx->data = smctx; -+ return 1; -+} -+ -+static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx) -+{ -+ SM2_PKEY_CTX *smctx = ctx->data; -+ -+ if (smctx != NULL) { -+ EC_GROUP_free(smctx->gen_group); -+ OPENSSL_free(smctx->id); -+ OPENSSL_free(smctx); -+ ctx->data = NULL; -+ } -+} -+ -+static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -+{ -+ SM2_PKEY_CTX *dctx, *sctx; -+ -+ if (!pkey_sm2_init(dst)) -+ return 0; -+ sctx = src->data; -+ dctx = dst->data; -+ if (sctx->gen_group != NULL) { -+ dctx->gen_group = EC_GROUP_dup(sctx->gen_group); -+ if (dctx->gen_group == NULL) { -+ pkey_sm2_cleanup(dst); -+ return 0; -+ } -+ } -+ if (sctx->id != NULL) { -+ dctx->id = OPENSSL_malloc(sctx->id_len); -+ if (dctx->id == NULL) { -+ SM2err(SM2_F_PKEY_SM2_COPY, ERR_R_MALLOC_FAILURE); -+ pkey_sm2_cleanup(dst); -+ return 0; -+ } -+ memcpy(dctx->id, sctx->id, sctx->id_len); -+ } -+ dctx->id_len = sctx->id_len; -+ dctx->id_set = sctx->id_set; -+ dctx->md = sctx->md; -+ -+ return 1; -+} -+ -+static int pkey_sm2_verify(EVP_PKEY_CTX *ctx, -+ const unsigned char *sig, size_t siglen, -+ const unsigned char *tbs, size_t tbslen) -+{ -+ EC_KEY *ec = ctx->pkey->pkey.ec; -+ -+ return sm2_verify(tbs, tbslen, sig, siglen, ec); -+} -+ -+static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -+{ -+ SM2_PKEY_CTX *smctx = ctx->data; -+ EC_GROUP *group; -+ uint8_t *tmp_id; -+ -+ switch (type) { -+ case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: -+ group = EC_GROUP_new_by_curve_name(p1); -+ if (group == NULL) { -+ SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE); -+ return 0; -+ } -+ EC_GROUP_free(smctx->gen_group); -+ smctx->gen_group = group; -+ return 1; -+ -+ case EVP_PKEY_CTRL_EC_PARAM_ENC: -+ if (smctx->gen_group == NULL) { -+ SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_NO_PARAMETERS_SET); -+ return 0; -+ } -+ EC_GROUP_set_asn1_flag(smctx->gen_group, p1); -+ return 1; -+ -+ case EVP_PKEY_CTRL_MD: -+ smctx->md = p2; -+ return 1; -+ -+ case EVP_PKEY_CTRL_GET_MD: -+ *(const EVP_MD **)p2 = smctx->md; -+ return 1; -+ -+ case EVP_PKEY_CTRL_SET1_ID: -+ if (p1 > 0) { -+ tmp_id = OPENSSL_malloc(p1); -+ if (tmp_id == NULL) { -+ SM2err(SM2_F_PKEY_SM2_CTRL, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ memcpy(tmp_id, p2, p1); -+ OPENSSL_free(smctx->id); -+ smctx->id = tmp_id; -+ } else { -+ /* set null-ID */ -+ OPENSSL_free(smctx->id); -+ smctx->id = NULL; -+ } -+ smctx->id_len = (size_t)p1; -+ smctx->id_set = 1; -+ return 1; -+ -+ case EVP_PKEY_CTRL_GET1_ID: -+ memcpy(p2, smctx->id, smctx->id_len); -+ return 1; -+ -+ case EVP_PKEY_CTRL_GET1_ID_LEN: -+ *(size_t *)p2 = smctx->id_len; -+ return 1; -+ -+ case EVP_PKEY_CTRL_PKCS7_SIGN: -+ case EVP_PKEY_CTRL_DIGESTINIT: -+ /* nothing to be inited, this is to suppress the error... */ -+ return 1; -+ -+ default: -+ return -2; -+ } -+} -+ -+static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, -+ const char *type, const char *value) -+{ -+ uint8_t *hex_id; -+ long hex_len = 0; -+ int ret = 0; -+ -+ if (strcmp(type, "ec_paramgen_curve") == 0) { -+ int nid = NID_undef; -+ -+ if (((nid = EC_curve_nist2nid(value)) == NID_undef) -+ && ((nid = OBJ_sn2nid(value)) == NID_undef) -+ && ((nid = OBJ_ln2nid(value)) == NID_undef)) { -+ SM2err(SM2_F_PKEY_SM2_CTRL_STR, SM2_R_INVALID_CURVE); -+ return 0; -+ } -+ return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); -+ } else if (strcmp(type, "ec_param_enc") == 0) { -+ int param_enc; -+ -+ if (strcmp(value, "explicit") == 0) -+ param_enc = 0; -+ else if (strcmp(value, "named_curve") == 0) -+ param_enc = OPENSSL_EC_NAMED_CURVE; -+ else -+ return -2; -+ return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); -+ } else if (strcmp(type, "sm2_id") == 0) { -+ return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, -+ (int)strlen(value), (void *)value); -+ } else if (strcmp(type, "sm2_hex_id") == 0) { -+ /* -+ * TODO(3.0): reconsider the name "sm2_hex_id", OR change -+ * OSSL_PARAM_construct_from_text() / OSSL_PARAM_allocate_from_text() -+ * to handle infix "_hex_" -+ */ -+ hex_id = OPENSSL_hexstr2buf((const char *)value, &hex_len); -+ if (hex_id == NULL) { -+ SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_PASSED_INVALID_ARGUMENT); -+ return 0; -+ } -+ ret = pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, (int)hex_len, -+ (void *)hex_id); -+ OPENSSL_free(hex_id); -+ return ret; -+ } -+ -+ return -2; -+} -+ -+static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -+{ -+ uint8_t z[EVP_MAX_MD_SIZE]; -+ SM2_PKEY_CTX *smctx = ctx->data; -+ EC_KEY *ec = ctx->pkey->pkey.ec; -+ const EVP_MD *md = EVP_MD_CTX_md(mctx); -+ int mdlen = EVP_MD_size(md); -+ -+#ifndef OPENSSL_NO_SM2 -+ if (!smctx->id_set) -+ (void)pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, SM2_DEFAULT_USERID_LEN -+ , (void *)SM2_DEFAULT_USERID); -+#endif -+ if (!smctx->id_set) { -+ /* -+ * An ID value must be set. The specifications are not clear whether a -+ * NULL is allowed. We only allow it if set explicitly for maximum -+ * flexibility. -+ */ -+ SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET); -+ return 0; -+ } -+ -+ if (mdlen < 0) { -+ SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_INVALID_DIGEST); -+ return 0; -+ } -+ -+ /* get hashed prefix 'z' of tbs message */ -+ if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec)) -+ return 0; -+ -+ return EVP_DigestUpdate(mctx, z, (size_t)mdlen); -+} -+ -+const EVP_PKEY_METHOD sm2_pkey_meth = { -+ EVP_PKEY_SM2, -+ 0, -+ pkey_sm2_init, -+ pkey_sm2_copy, -+ pkey_sm2_cleanup, -+ -+ 0, -+ 0, -+ -+ 0, -+ 0, -+ -+ 0, -+ 0, // pkey_sm2_sign, -+ -+ 0, -+ pkey_sm2_verify, -+ -+ 0, 0, -+ -+ 0, 0, 0, 0, -+ -+ 0, -+ 0, // pkey_sm2_encrypt, -+ -+ 0, -+ 0, // pkey_sm2_decrypt, -+ -+ 0, -+ 0, -+ pkey_sm2_ctrl, -+ pkey_sm2_ctrl_str, -+ -+ 0, 0, -+ -+ 0, 0, 0, -+ -+ pkey_sm2_digest_custom -+}; -diff --git a/Cryptlib/OpenSSL/crypto/sm2/sm2_sign.c b/Cryptlib/OpenSSL/crypto/sm2/sm2_sign.c -new file mode 100644 -index 0000000..d206f33 ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/sm2/sm2_sign.c -@@ -0,0 +1,325 @@ -+/* -+ * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 2017 Ribose Inc. All Rights Reserved. -+ * Ported from Ribose contributions from Botan. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include /* ec_group_do_inverse_ord() */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int sm2_compute_z_digest(uint8_t *out, -+ const EVP_MD *digest, -+ const uint8_t *id, -+ const size_t id_len, -+ const EC_KEY *key) -+{ -+ int rc = 0; -+ const EC_GROUP *group = EC_KEY_get0_group(key); -+ BN_CTX *ctx = NULL; -+ EVP_MD_CTX *hash = NULL; -+ BIGNUM *p = NULL; -+ BIGNUM *a = NULL; -+ BIGNUM *b = NULL; -+ BIGNUM *xG = NULL; -+ BIGNUM *yG = NULL; -+ BIGNUM *xA = NULL; -+ BIGNUM *yA = NULL; -+ int p_bytes = 0; -+ uint8_t *buf = NULL; -+ uint16_t entl = 0; -+ uint8_t e_byte = 0; -+ -+ hash = EVP_MD_CTX_new(); -+ ctx = BN_CTX_new(); -+ if (hash == NULL || ctx == NULL) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ p = BN_CTX_get(ctx); -+ a = BN_CTX_get(ctx); -+ b = BN_CTX_get(ctx); -+ xG = BN_CTX_get(ctx); -+ yG = BN_CTX_get(ctx); -+ xA = BN_CTX_get(ctx); -+ yA = BN_CTX_get(ctx); -+ -+ if (yA == NULL) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ if (!EVP_DigestInit(hash, digest)) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); -+ goto done; -+ } -+ -+ /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */ -+ -+ if (id_len >= (UINT16_MAX / 8)) { -+ /* too large */ -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, SM2_R_ID_TOO_LARGE); -+ goto done; -+ } -+ -+ entl = (uint16_t)(8 * id_len); -+ -+ e_byte = entl >> 8; -+ if (!EVP_DigestUpdate(hash, &e_byte, 1)) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); -+ goto done; -+ } -+ e_byte = entl & 0xFF; -+ if (!EVP_DigestUpdate(hash, &e_byte, 1)) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); -+ goto done; -+ } -+ -+ if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB); -+ goto done; -+ } -+ -+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EC_LIB); -+ goto done; -+ } -+ -+ p_bytes = BN_num_bytes(p); -+ buf = OPENSSL_zalloc(p_bytes); -+ if (buf == NULL) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ if (BN_bn2bin(a, buf) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || BN_bn2bin(b, buf) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || !EC_POINT_get_affine_coordinates_GFp(group, -+ EC_GROUP_get0_generator(group), -+ xG, yG, ctx) -+ || BN_bn2bin(xG, buf) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || BN_bn2bin(yG, buf) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || !EC_POINT_get_affine_coordinates_GFp(group, -+ EC_KEY_get0_public_key(key), -+ xA, yA, ctx) -+ || BN_bn2bin(xA, buf) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || BN_bn2bin(yA, buf) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || !EVP_DigestFinal(hash, out, NULL)) { -+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_INTERNAL_ERROR); -+ goto done; -+ } -+ -+ rc = 1; -+ -+ done: -+ OPENSSL_free(buf); -+ BN_CTX_free(ctx); -+ EVP_MD_CTX_free(hash); -+ return rc; -+} -+ -+static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, -+ const EC_KEY *key, -+ const uint8_t *id, -+ const size_t id_len, -+ const uint8_t *msg, size_t msg_len) -+{ -+ EVP_MD_CTX *hash = EVP_MD_CTX_new(); -+ const int md_size = EVP_MD_size(digest); -+ uint8_t *z = NULL; -+ BIGNUM *e = NULL; -+ -+ if (md_size < 0) { -+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST); -+ goto done; -+ } -+ -+ z = OPENSSL_zalloc(md_size); -+ if (hash == NULL || z == NULL) { -+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ if (!sm2_compute_z_digest(z, digest, id, id_len, key)) { -+ /* SM2err already called */ -+ goto done; -+ } -+ -+ if (!EVP_DigestInit(hash, digest) -+ || !EVP_DigestUpdate(hash, z, md_size) -+ || !EVP_DigestUpdate(hash, msg, msg_len) -+ /* reuse z buffer to hold H(Z || M) */ -+ || !EVP_DigestFinal(hash, z, NULL)) { -+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB); -+ goto done; -+ } -+ -+ e = BN_bin2bn(z, md_size, NULL); -+ if (e == NULL) -+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR); -+ -+ done: -+ OPENSSL_free(z); -+ EVP_MD_CTX_free(hash); -+ return e; -+} -+ -+static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, -+ const BIGNUM *e) -+{ -+ int ret = 0; -+ const EC_GROUP *group = EC_KEY_get0_group(key); -+ const BIGNUM *order = EC_GROUP_get0_order(group); -+ BN_CTX *ctx = NULL; -+ EC_POINT *pt = NULL; -+ BIGNUM *t = NULL; -+ BIGNUM *x1 = NULL; -+ const BIGNUM *r = NULL; -+ const BIGNUM *s = NULL; -+ -+ ctx = BN_CTX_new(); -+ pt = EC_POINT_new(group); -+ if (ctx == NULL || pt == NULL) { -+ SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ BN_CTX_start(ctx); -+ t = BN_CTX_get(ctx); -+ x1 = BN_CTX_get(ctx); -+ if (x1 == NULL) { -+ SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ /* -+ * B1: verify whether r' in [1,n-1], verification failed if not -+ * B2: verify whether s' in [1,n-1], verification failed if not -+ * B3: set M'~=ZA || M' -+ * B4: calculate e'=Hv(M'~) -+ * B5: calculate t = (r' + s') modn, verification failed if t=0 -+ * B6: calculate the point (x1', y1')=[s']G + [t]PA -+ * B7: calculate R=(e'+x1') modn, verification pass if yes, otherwise failed -+ */ -+ -+ ECDSA_SIG_get0(sig, &r, &s); -+ -+ if (BN_cmp(r, BN_value_one()) < 0 -+ || BN_cmp(s, BN_value_one()) < 0 -+ || BN_cmp(order, r) <= 0 -+ || BN_cmp(order, s) <= 0) { -+ SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE); -+ goto done; -+ } -+ -+ if (!BN_mod_add(t, r, s, order, ctx)) { -+ SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB); -+ goto done; -+ } -+ -+ if (BN_is_zero(t)) { -+ SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE); -+ goto done; -+ } -+ -+ if (!EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx) -+ || !EC_POINT_get_affine_coordinates_GFp(group, pt, x1, NULL, ctx)) { -+ SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_EC_LIB); -+ goto done; -+ } -+ -+ if (!BN_mod_add(t, e, x1, order, ctx)) { -+ SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB); -+ goto done; -+ } -+ -+ if (BN_cmp(r, t) == 0) -+ ret = 1; -+ -+ done: -+ EC_POINT_free(pt); -+ BN_CTX_free(ctx); -+ return ret; -+} -+ -+int sm2_do_verify(const EC_KEY *key, -+ const EVP_MD *digest, -+ const ECDSA_SIG *sig, -+ const uint8_t *id, -+ const size_t id_len, -+ const uint8_t *msg, size_t msg_len) -+{ -+ BIGNUM *e = NULL; -+ int ret = 0; -+ -+ e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len); -+ if (e == NULL) { -+ /* SM2err already called */ -+ goto done; -+ } -+ -+ ret = sm2_sig_verify(key, sig, e); -+ -+ done: -+ BN_free(e); -+ return ret; -+} -+ -+int sm2_verify(const unsigned char *dgst, int dgstlen, -+ const unsigned char *sig, int sig_len, EC_KEY *eckey) -+{ -+ ECDSA_SIG *s = NULL; -+ BIGNUM *e = NULL; -+ const unsigned char *p = sig; -+ unsigned char *der = NULL; -+ int derlen = -1; -+ int ret = -1; -+ -+ s = ECDSA_SIG_new(); -+ if (s == NULL) { -+ SM2err(SM2_F_SM2_VERIFY, ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) { -+ SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING); -+ goto done; -+ } -+ /* Ensure signature uses DER and doesn't have trailing garbage */ -+ derlen = i2d_ECDSA_SIG(s, &der); -+ if (derlen != sig_len || memcmp(sig, der, derlen) != 0) { -+ SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING); -+ goto done; -+ } -+ -+ e = BN_bin2bn(dgst, dgstlen, NULL); -+ if (e == NULL) { -+ SM2err(SM2_F_SM2_VERIFY, ERR_R_BN_LIB); -+ goto done; -+ } -+ -+ ret = sm2_sig_verify(eckey, s, e); -+ -+ done: -+ OPENSSL_free(der); -+ BN_free(e); -+ ECDSA_SIG_free(s); -+ return ret; -+} -diff --git a/Cryptlib/OpenSSL/crypto/sm3/m_sm3.c b/Cryptlib/OpenSSL/crypto/sm3/m_sm3.c -new file mode 100644 -index 0000000..d429b8c ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/sm3/m_sm3.c -@@ -0,0 +1,52 @@ -+/* -+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 2017 Ribose Inc. 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 -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "cryptlib.h" -+ -+#ifndef OPENSSL_NO_SM3 -+# include -+# include -+ -+static int init(EVP_MD_CTX *ctx) -+{ -+ return sm3_init(EVP_MD_CTX_md_data(ctx)); -+} -+ -+static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -+{ -+ return sm3_update(EVP_MD_CTX_md_data(ctx), data, count); -+} -+ -+static int final(EVP_MD_CTX *ctx, unsigned char *md) -+{ -+ return sm3_final(md, EVP_MD_CTX_md_data(ctx)); -+} -+ -+static const EVP_MD sm3_md = { -+ NID_sm3, -+ NID_sm3WithRSAEncryption, -+ SM3_DIGEST_LENGTH, -+ 0, -+ init, -+ update, -+ final, -+ NULL, -+ NULL, -+ EVP_PKEY_NULL_method, -+ SM3_CBLOCK, -+ sizeof(EVP_MD *) + sizeof(SM3_CTX), -+}; -+ -+const EVP_MD *EVP_sm3(void) -+{ -+ return &sm3_md; -+} -+ -+#endif -diff --git a/Cryptlib/OpenSSL/crypto/sm3/sm3.c b/Cryptlib/OpenSSL/crypto/sm3/sm3.c -new file mode 100644 -index 0000000..d78292b ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/sm3/sm3.c -@@ -0,0 +1,196 @@ -+/* -+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 2017 Ribose Inc. All Rights Reserved. -+ * Ported from Ribose contributions from Botan. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "sm3_local.h" -+ -+int sm3_init(SM3_CTX *c) -+{ -+ memset(c, 0, sizeof(*c)); -+ c->A = SM3_A; -+ c->B = SM3_B; -+ c->C = SM3_C; -+ c->D = SM3_D; -+ c->E = SM3_E; -+ c->F = SM3_F; -+ c->G = SM3_G; -+ c->H = SM3_H; -+ return 1; -+} -+ -+void sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num) -+{ -+ const unsigned char *data = p; -+ register unsigned MD32_REG_T A, B, C, D, E, F, G, H; -+ -+ unsigned MD32_REG_T W00, W01, W02, W03, W04, W05, W06, W07, -+ W08, W09, W10, W11, W12, W13, W14, W15; -+ -+ for (; num--;) { -+ -+ A = ctx->A; -+ B = ctx->B; -+ C = ctx->C; -+ D = ctx->D; -+ E = ctx->E; -+ F = ctx->F; -+ G = ctx->G; -+ H = ctx->H; -+ -+ /* -+ * We have to load all message bytes immediately since SM3 reads -+ * them slightly out of order. -+ */ -+ (void)HOST_c2l(data, W00); -+ (void)HOST_c2l(data, W01); -+ (void)HOST_c2l(data, W02); -+ (void)HOST_c2l(data, W03); -+ (void)HOST_c2l(data, W04); -+ (void)HOST_c2l(data, W05); -+ (void)HOST_c2l(data, W06); -+ (void)HOST_c2l(data, W07); -+ (void)HOST_c2l(data, W08); -+ (void)HOST_c2l(data, W09); -+ (void)HOST_c2l(data, W10); -+ (void)HOST_c2l(data, W11); -+ (void)HOST_c2l(data, W12); -+ (void)HOST_c2l(data, W13); -+ (void)HOST_c2l(data, W14); -+ (void)HOST_c2l(data, W15); -+ -+ R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04); -+ W00 = EXPAND(W00, W07, W13, W03, W10); -+ R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05); -+ W01 = EXPAND(W01, W08, W14, W04, W11); -+ R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06); -+ W02 = EXPAND(W02, W09, W15, W05, W12); -+ R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07); -+ W03 = EXPAND(W03, W10, W00, W06, W13); -+ R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08); -+ W04 = EXPAND(W04, W11, W01, W07, W14); -+ R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09); -+ W05 = EXPAND(W05, W12, W02, W08, W15); -+ R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10); -+ W06 = EXPAND(W06, W13, W03, W09, W00); -+ R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11); -+ W07 = EXPAND(W07, W14, W04, W10, W01); -+ R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12); -+ W08 = EXPAND(W08, W15, W05, W11, W02); -+ R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13); -+ W09 = EXPAND(W09, W00, W06, W12, W03); -+ R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14); -+ W10 = EXPAND(W10, W01, W07, W13, W04); -+ R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15); -+ W11 = EXPAND(W11, W02, W08, W14, W05); -+ R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00); -+ W12 = EXPAND(W12, W03, W09, W15, W06); -+ R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01); -+ W13 = EXPAND(W13, W04, W10, W00, W07); -+ R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02); -+ W14 = EXPAND(W14, W05, W11, W01, W08); -+ R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03); -+ W15 = EXPAND(W15, W06, W12, W02, W09); -+ R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); -+ W00 = EXPAND(W00, W07, W13, W03, W10); -+ R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); -+ W01 = EXPAND(W01, W08, W14, W04, W11); -+ R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); -+ W02 = EXPAND(W02, W09, W15, W05, W12); -+ R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); -+ W03 = EXPAND(W03, W10, W00, W06, W13); -+ R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); -+ W04 = EXPAND(W04, W11, W01, W07, W14); -+ R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); -+ W05 = EXPAND(W05, W12, W02, W08, W15); -+ R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); -+ W06 = EXPAND(W06, W13, W03, W09, W00); -+ R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); -+ W07 = EXPAND(W07, W14, W04, W10, W01); -+ R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); -+ W08 = EXPAND(W08, W15, W05, W11, W02); -+ R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); -+ W09 = EXPAND(W09, W00, W06, W12, W03); -+ R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); -+ W10 = EXPAND(W10, W01, W07, W13, W04); -+ R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); -+ W11 = EXPAND(W11, W02, W08, W14, W05); -+ R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); -+ W12 = EXPAND(W12, W03, W09, W15, W06); -+ R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); -+ W13 = EXPAND(W13, W04, W10, W00, W07); -+ R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); -+ W14 = EXPAND(W14, W05, W11, W01, W08); -+ R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); -+ W15 = EXPAND(W15, W06, W12, W02, W09); -+ R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04); -+ W00 = EXPAND(W00, W07, W13, W03, W10); -+ R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05); -+ W01 = EXPAND(W01, W08, W14, W04, W11); -+ R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06); -+ W02 = EXPAND(W02, W09, W15, W05, W12); -+ R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07); -+ W03 = EXPAND(W03, W10, W00, W06, W13); -+ R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08); -+ W04 = EXPAND(W04, W11, W01, W07, W14); -+ R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09); -+ W05 = EXPAND(W05, W12, W02, W08, W15); -+ R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10); -+ W06 = EXPAND(W06, W13, W03, W09, W00); -+ R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11); -+ W07 = EXPAND(W07, W14, W04, W10, W01); -+ R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12); -+ W08 = EXPAND(W08, W15, W05, W11, W02); -+ R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13); -+ W09 = EXPAND(W09, W00, W06, W12, W03); -+ R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14); -+ W10 = EXPAND(W10, W01, W07, W13, W04); -+ R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15); -+ W11 = EXPAND(W11, W02, W08, W14, W05); -+ R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00); -+ W12 = EXPAND(W12, W03, W09, W15, W06); -+ R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01); -+ W13 = EXPAND(W13, W04, W10, W00, W07); -+ R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02); -+ W14 = EXPAND(W14, W05, W11, W01, W08); -+ R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03); -+ W15 = EXPAND(W15, W06, W12, W02, W09); -+ R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); -+ W00 = EXPAND(W00, W07, W13, W03, W10); -+ R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); -+ W01 = EXPAND(W01, W08, W14, W04, W11); -+ R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); -+ W02 = EXPAND(W02, W09, W15, W05, W12); -+ R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); -+ W03 = EXPAND(W03, W10, W00, W06, W13); -+ R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); -+ R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); -+ R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); -+ R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); -+ R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); -+ R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); -+ R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); -+ R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); -+ R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); -+ R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); -+ R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); -+ R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); -+ -+ ctx->A ^= A; -+ ctx->B ^= B; -+ ctx->C ^= C; -+ ctx->D ^= D; -+ ctx->E ^= E; -+ ctx->F ^= F; -+ ctx->G ^= G; -+ ctx->H ^= H; -+ } -+} -+ -diff --git a/Cryptlib/OpenSSL/crypto/sm3/sm3_local.h b/Cryptlib/OpenSSL/crypto/sm3/sm3_local.h -new file mode 100644 -index 0000000..dfb7bfb ---- /dev/null -+++ b/Cryptlib/OpenSSL/crypto/sm3/sm3_local.h -@@ -0,0 +1,79 @@ -+/* -+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. -+ * Copyright 2017 Ribose Inc. All Rights Reserved. -+ * Ported from Ribose contributions from Botan. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+ -+#define DATA_ORDER_IS_BIG_ENDIAN -+ -+#define HASH_LONG SM3_WORD -+#define HASH_CTX SM3_CTX -+#define HASH_CBLOCK SM3_CBLOCK -+#define HASH_UPDATE sm3_update -+#define HASH_TRANSFORM sm3_transform -+#define HASH_FINAL sm3_final -+#define HASH_MAKE_STRING(c, s) \ -+ do { \ -+ unsigned long ll; \ -+ ll=(c)->A; (void)HOST_l2c(ll, (s)); \ -+ ll=(c)->B; (void)HOST_l2c(ll, (s)); \ -+ ll=(c)->C; (void)HOST_l2c(ll, (s)); \ -+ ll=(c)->D; (void)HOST_l2c(ll, (s)); \ -+ ll=(c)->E; (void)HOST_l2c(ll, (s)); \ -+ ll=(c)->F; (void)HOST_l2c(ll, (s)); \ -+ ll=(c)->G; (void)HOST_l2c(ll, (s)); \ -+ ll=(c)->H; (void)HOST_l2c(ll, (s)); \ -+ } while (0) -+#define HASH_BLOCK_DATA_ORDER sm3_block_data_order -+ -+void sm3_transform(SM3_CTX *c, const unsigned char *data); -+ -+#include "crypto/md32_common.h" -+ -+#define P0(X) (X ^ ROTATE(X, 9) ^ ROTATE(X, 17)) -+#define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23)) -+ -+#define FF0(X,Y,Z) (X ^ Y ^ Z) -+#define GG0(X,Y,Z) (X ^ Y ^ Z) -+ -+#define FF1(X,Y,Z) ((X & Y) | ((X | Y) & Z)) -+#define GG1(X,Y,Z) ((Z ^ (X & (Y ^ Z)))) -+ -+#define EXPAND(W0,W7,W13,W3,W10) \ -+ (P1(W0 ^ W7 ^ ROTATE(W13, 15)) ^ ROTATE(W3, 7) ^ W10) -+ -+#define RND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF, GG) \ -+ do { \ -+ const SM3_WORD A12 = ROTATE(A, 12); \ -+ const SM3_WORD A12_SM = A12 + E + TJ; \ -+ const SM3_WORD SS1 = ROTATE(A12_SM, 7); \ -+ const SM3_WORD TT1 = FF(A, B, C) + D + (SS1 ^ A12) + (Wj); \ -+ const SM3_WORD TT2 = GG(E, F, G) + H + SS1 + Wi; \ -+ B = ROTATE(B, 9); \ -+ D = TT1; \ -+ F = ROTATE(F, 19); \ -+ H = P0(TT2); \ -+ } while(0) -+ -+#define R1(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \ -+ RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF0,GG0) -+ -+#define R2(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \ -+ RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF1,GG1) -+ -+#define SM3_A 0x7380166fUL -+#define SM3_B 0x4914b2b9UL -+#define SM3_C 0x172442d7UL -+#define SM3_D 0xda8a0600UL -+#define SM3_E 0xa96f30bcUL -+#define SM3_F 0x163138aaUL -+#define SM3_G 0xe38dee4dUL -+#define SM3_H 0xb0fb0e4eUL -diff --git a/Cryptlib/OpenSSL/crypto/x509/x_all.c b/Cryptlib/OpenSSL/crypto/x509/x_all.c -index 0f26c54..0228582 100644 ---- a/Cryptlib/OpenSSL/crypto/x509/x_all.c -+++ b/Cryptlib/OpenSSL/crypto/x509/x_all.c -@@ -71,16 +71,158 @@ - # include - #endif - -+#ifndef OPENSSL_NO_SM2 -+ -+# include "openssl/asn1.h" -+# include "openssl/evp.h" -+# include "crypto/asn1/asn1_locl.h" -+ -+static int common_verify_sm2(void *data, EVP_PKEY *pkey, -+ int mdnid, int pknid, int req) -+{ -+ X509 *x = NULL; -+ X509_REQ *r = NULL; -+ EVP_MD_CTX ctx; -+ unsigned char *buf_in = NULL; -+ int ret = -1, inl = 0; -+ size_t inll = 0; -+ EVP_PKEY_CTX *pctx = NULL; -+ const EVP_MD *type = EVP_get_digestbynid(mdnid); -+ ASN1_BIT_STRING *signature = NULL; -+ ASN1_OCTET_STRING *sm2_id = NULL; -+ ASN1_VALUE *tbv = NULL; -+ -+ if (type == NULL) { -+ goto err; -+ } -+ -+ if (pkey == NULL) { -+ return -1; -+ } -+ -+ if (req == 1) { -+ r = (X509_REQ *)data; -+ signature = r->signature; -+ sm2_id = r->sm2_id; -+ tbv = (ASN1_VALUE *)&r->req_info; -+ } else { -+ x = (X509 *)data; -+ signature = x->signature; -+ sm2_id = x->sm2_id; -+ tbv = (ASN1_VALUE *)x->cert_info; -+ } -+ -+ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { -+ return -1; -+ } -+ -+ EVP_MD_CTX_init(&ctx); -+ -+ /* Check public key OID matches public key type */ -+ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { -+ goto err; -+ } -+ -+ if (!EVP_PKEY_set_type(pkey, EVP_PKEY_SM2)) { -+ ret = 0; -+ goto err; -+ } -+ pctx = EVP_PKEY_CTX_new(pkey, NULL); -+ if (pctx == NULL) { -+ ret = 0; -+ goto err; -+ } -+ /* NOTE: we tolerate no actual ID, to provide maximum flexibility */ -+ if (sm2_id != NULL -+ && EVP_PKEY_CTX_set1_id(pctx, sm2_id->data, sm2_id->length) != 1) { -+ ret = 0; -+ goto err; -+ } -+ EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX); -+ -+ if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { -+ ret = 0; -+ goto err; -+ } -+ -+ inl = ASN1_item_i2d(tbv, &buf_in, -+ req == 1 ? -+ ASN1_ITEM_rptr(X509_REQ_INFO) : -+ ASN1_ITEM_rptr(X509_CINF)); -+ if (inl <= 0) { -+ goto err; -+ } -+ if (buf_in == NULL) { -+ goto err; -+ } -+ inll = inl; -+ -+ ret = EVP_DigestVerify(&ctx, signature->data, -+ (size_t)signature->length, buf_in, inl); -+ if (ret <= 0) { -+ goto err; -+ } -+ ret = 1; -+ err: -+ OPENSSL_cleanse(buf_in, inll); -+ EVP_MD_CTX_cleanup(&ctx); -+ EVP_PKEY_CTX_free(pctx); -+ return ret; -+} -+ -+static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid) -+{ -+ return common_verify_sm2(x, pkey, mdnid, pknid, 0); -+} -+ -+static int x509_req_verify_sm2(X509_REQ *x, EVP_PKEY *pkey, -+ int mdnid, int pknid) -+{ -+ return common_verify_sm2(x, pkey, mdnid, pknid, 1); -+} -+ -+#endif -+ -+ -+ - int X509_verify(X509 *a, EVP_PKEY *r) - { -+#ifndef OPENSSL_NO_SM2 -+ int mdnid, pknid; -+#endif - if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) - return 0; -+ -+#ifndef OPENSSL_NO_SM2 -+ /* Convert signature OID into digest and public key OIDs */ -+ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg->algorithm), -+ &mdnid, &pknid)) { -+ return 0; -+ } -+ -+ if (pknid == NID_sm2) -+ return x509_verify_sm2(a, r, mdnid, pknid); -+#endif -+ - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg, - a->signature, a->cert_info, r)); - } - - int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) - { -+#ifndef OPENSSL_NO_SM2 -+ int mdnid, pknid; -+ -+ /* Convert signature OID into digest and public key OIDs */ -+ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg->algorithm), -+ &mdnid, &pknid)) { -+ return 0; -+ } -+ -+ if (pknid == NID_sm2) -+ return x509_req_verify_sm2(a, r, mdnid, pknid); -+#endif -+ - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), - a->sig_alg, a->signature, a->req_info, r)); - } -diff --git a/Cryptlib/Pk/CryptPkcs7Verify.c b/Cryptlib/Pk/CryptPkcs7Verify.c -index c189384..7fa8c41 100644 ---- a/Cryptlib/Pk/CryptPkcs7Verify.c -+++ b/Cryptlib/Pk/CryptPkcs7Verify.c -@@ -878,6 +878,11 @@ Pkcs7Verify ( - if (EVP_add_digest (EVP_sha512 ()) == 0) { - return FALSE; - } -+#ifndef OPENSSL_NO_SM3 -+ if (EVP_add_digest (EVP_sm3 ()) == 0) { -+ return FALSE; -+ } -+#endif - if (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA) == 0) { - return FALSE; - } -diff --git a/Makefile b/Makefile -index 24ac314..8876f9f 100644 ---- a/Makefile -+++ b/Makefile -@@ -163,7 +163,7 @@ Cryptlib/libcryptlib.a: - $(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile - - Cryptlib/OpenSSL/libopenssl.a: -- for i in x509v3 x509 txt_db stack sha rsa rc4 rand pkcs7 pkcs12 pem ocsp objects modes md5 lhash kdf hmac evp err dso dh conf comp cmac buffer bn bio async/arch asn1 aes; do mkdir -p Cryptlib/OpenSSL/crypto/$$i; done -+ for i in x509v3 x509 txt_db stack sha rsa rc4 rand pkcs7 pkcs12 pem ocsp objects modes md5 lhash kdf hmac evp err dso dh conf comp cmac buffer bn bio async/arch asn1 aes ec sm3 sm2 ecdsa; do mkdir -p Cryptlib/OpenSSL/crypto/$$i; done - $(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib/OpenSSL -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile - - lib/lib.a: | $(TOPDIR)/lib/Makefile $(wildcard $(TOPDIR)/include/*.[ch]) -diff --git a/MokManager.c b/MokManager.c -index ffcd6a6..8b7fd4b 100644 ---- a/MokManager.c -+++ b/MokManager.c -@@ -1910,6 +1910,9 @@ static EFI_STATUS enroll_file(void *data, UINTN datasize, BOOLEAN hash) - if (hash) { - UINT8 sha256[SHA256_DIGEST_SIZE]; - UINT8 sha1[SHA1_DIGEST_SIZE]; -+#ifdef ENABLE_SHIM_SM -+ UINT8 sm3[SM3_DIGEST_SIZE]; -+#endif - SHIM_LOCK *shim_lock; - PE_COFF_LOADER_IMAGE_CONTEXT context; - -@@ -1929,8 +1932,13 @@ static EFI_STATUS enroll_file(void *data, UINTN datasize, BOOLEAN hash) - if (EFI_ERROR(efi_status)) - goto out; - -+#ifdef ENABLE_SHIM_SM -+ efi_status = shim_lock->Hash(data, datasize, &context, sha256, -+ sha1, sm3); -+#else - efi_status = shim_lock->Hash(data, datasize, &context, sha256, - sha1); -+#endif - if (EFI_ERROR(efi_status)) - goto out; - -diff --git a/include/pe.h b/include/pe.h -index ccc8798..93af091 100644 ---- a/include/pe.h -+++ b/include/pe.h -@@ -28,10 +28,17 @@ handle_image (void *data, unsigned int datasize, - EFI_PHYSICAL_ADDRESS *alloc_address, - UINTN *alloc_pages); - -+#ifdef ENABLE_SHIM_SM -+EFI_STATUS -+generate_hash (char *data, unsigned int datasize, -+ PE_COFF_LOADER_IMAGE_CONTEXT *context, -+ UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash); -+#else - EFI_STATUS - generate_hash (char *data, unsigned int datasize, - PE_COFF_LOADER_IMAGE_CONTEXT *context, - UINT8 *sha256hash, UINT8 *sha1hash); -+#endif - - EFI_STATUS - relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context, -diff --git a/include/peimage.h b/include/peimage.h -index e97b29c..7a4f356 100644 ---- a/include/peimage.h -+++ b/include/peimage.h -@@ -807,6 +807,9 @@ typedef struct { - - #define SHA1_DIGEST_SIZE 20 - #define SHA256_DIGEST_SIZE 32 -+#ifdef ENABLE_SHIM_SM -+#define SM3_DIGEST_SIZE 32 -+#endif - #define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 - - typedef struct { -diff --git a/pe.c b/pe.c -index ba3e2bb..37b08a3 100644 ---- a/pe.c -+++ b/pe.c -@@ -297,13 +297,24 @@ get_section_vma_by_name (char *name, size_t namesz, - * Calculate the SHA1 and SHA256 hashes of a binary - */ - -+#ifdef ENABLE_SHIM_SM -+EFI_STATUS -+generate_hash(char *data, unsigned int datasize, -+ PE_COFF_LOADER_IMAGE_CONTEXT *context, UINT8 *sha256hash, -+ UINT8 *sha1hash, UINT8 *sm3hash) -+#else - EFI_STATUS - generate_hash(char *data, unsigned int datasize, - PE_COFF_LOADER_IMAGE_CONTEXT *context, UINT8 *sha256hash, - UINT8 *sha1hash) -+#endif - { - unsigned int sha256ctxsize, sha1ctxsize; - void *sha256ctx = NULL, *sha1ctx = NULL; -+#ifdef ENABLE_SHIM_SM -+ unsigned int sm3ctxsize; -+ void *sm3ctx = NULL; -+#endif - char *hashbase; - unsigned int hashsize; - unsigned int SumOfBytesHashed, SumOfSectionBytes; -@@ -327,12 +338,25 @@ generate_hash(char *data, unsigned int datasize, - sha1ctxsize = Sha1GetContextSize(); - sha1ctx = AllocatePool(sha1ctxsize); - -+#ifdef SHIM_ENABLE_SM -+ sm3ctxsize = Sm3GetContextSize(); -+ sm3ctx = AllocatePool(sm3ctxsize); -+#endif -+ -+#ifdef SHIM_ENABLE_SM -+ if (!sha256ctx || !sha1ctx || !sm3ctx) { -+#else - if (!sha256ctx || !sha1ctx) { -+#endif - perror(L"Unable to allocate memory for hash context\n"); - return EFI_OUT_OF_RESOURCES; - } - -+#ifdef SHIM_ENABLE_SM -+ if (!Sha256Init(sha256ctx) || !Sha1Init(sha1ctx) || !Sm3Init(sm3ctx)) { -+#else - if (!Sha256Init(sha256ctx) || !Sha1Init(sha1ctx)) { -+#endif - perror(L"Unable to initialise hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -344,8 +368,14 @@ generate_hash(char *data, unsigned int datasize, - hashbase; - check_size(data, datasize, hashbase, hashsize); - -+#ifdef SHIM_ENABLE_SM -+ if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || -+ !(Sha1Update(sha1ctx, hashbase, hashsize)) || -+ !(Sm3Update(sm3ctx, hashbase, hashsize))) { -+#else - if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || - !(Sha1Update(sha1ctx, hashbase, hashsize))) { -+#endif - perror(L"Unable to generate hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -357,8 +387,14 @@ generate_hash(char *data, unsigned int datasize, - hashsize = (char *)context->SecDir - hashbase; - check_size(data, datasize, hashbase, hashsize); - -+#ifdef SHIM_ENABLE_SM -+ if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || -+ !(Sha1Update(sha1ctx, hashbase, hashsize)) || -+ !(Sm3Update(sm3ctx, hashbase, hashsize))) { -+#else - if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || - !(Sha1Update(sha1ctx, hashbase, hashsize))) { -+#endif - perror(L"Unable to generate hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -375,8 +411,14 @@ generate_hash(char *data, unsigned int datasize, - } - check_size(data, datasize, hashbase, hashsize); - -+#ifdef SHIM_ENABLE_SM -+ if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || -+ !(Sha1Update(sha1ctx, hashbase, hashsize)) || -+ !(Sm3Update(sm3ctx, hashbase, hashsize))) { -+#else - if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || - !(Sha1Update(sha1ctx, hashbase, hashsize))) { -+#endif - perror(L"Unable to generate hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -505,8 +547,14 @@ generate_hash(char *data, unsigned int datasize, - hashsize = (unsigned int) Section->SizeOfRawData; - check_size(data, datasize, hashbase, hashsize); - -+#ifdef SHIM_ENABLE_SM -+ if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || -+ !(Sha1Update(sha1ctx, hashbase, hashsize)) || -+ !(Sm3Update(sm3ctx, hashbase, hashsize))) { -+#else - if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || - !(Sha1Update(sha1ctx, hashbase, hashsize))) { -+#endif - perror(L"Unable to generate hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -531,8 +579,14 @@ generate_hash(char *data, unsigned int datasize, - } - check_size(data, datasize, hashbase, hashsize); - -+#ifdef SHIM_ENABLE_SM -+ if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || -+ !(Sha1Update(sha1ctx, hashbase, hashsize)) || -+ !(Sm3Update(sm3ctx, hashbase, hashsize))) { -+#else - if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || - !(Sha1Update(sha1ctx, hashbase, hashsize))) { -+#endif - perror(L"Unable to generate hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -551,8 +605,14 @@ generate_hash(char *data, unsigned int datasize, - - check_size(data, datasize, hashbase, hashsize); - -+#ifdef SHIM_ENABLE_SM -+ if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || -+ !(Sha1Update(sha1ctx, hashbase, hashsize)) || -+ !(Sm3Update(sm3ctx, hashbase, hashsize))) { -+#else - if (!(Sha256Update(sha256ctx, hashbase, hashsize)) || - !(Sha1Update(sha1ctx, hashbase, hashsize))) { -+#endif - perror(L"Unable to generate hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -562,8 +622,14 @@ generate_hash(char *data, unsigned int datasize, - } - #endif - -+#ifdef SHIM_ENABLE_SM -+ if (!(Sha256Final(sha256ctx, sha256hash)) || -+ !(Sha1Final(sha1ctx, sha1hash)) || -+ !(Sm3Final(sm3ctx, sm3hash))) { -+#else - if (!(Sha256Final(sha256ctx, sha256hash)) || - !(Sha1Final(sha1ctx, sha1hash))) { -+#endif - perror(L"Unable to finalise hash\n"); - efi_status = EFI_OUT_OF_RESOURCES; - goto done; -@@ -573,6 +639,10 @@ generate_hash(char *data, unsigned int datasize, - dhexdumpat(sha1hash, SHA1_DIGEST_SIZE, 0); - dprint(L"sha256 authenticode hash:\n"); - dhexdumpat(sha256hash, SHA256_DIGEST_SIZE, 0); -+#ifdef SHIM_ENABLE_SM -+ dprint(L"sm3 authenticode hash:\n"); -+ dhexdumpat(sm3hash, SM3_DIGEST_SIZE, 0); -+#endif - - done: - if (SectionHeader) -@@ -581,6 +651,10 @@ done: - FreePool(sha1ctx); - if (sha256ctx) - FreePool(sha256ctx); -+#ifdef SHIM_ENABLE_SM -+ if (sm3ctx) -+ FreePool(sm3ctx); -+#endif - - return efi_status; - } -@@ -1027,6 +1101,9 @@ EFI_STATUS verify_image(void *data, unsigned int datasize, - EFI_STATUS efi_status; - UINT8 sha1hash[SHA1_DIGEST_SIZE]; - UINT8 sha256hash[SHA256_DIGEST_SIZE]; -+#ifdef SHIM_ENABLE_SM -+ UINT8 sm3hash[SHA256_DIGEST_SIZE]; -+#endif - - /* - * The binary header contains relevant context and section pointers -@@ -1042,8 +1119,13 @@ EFI_STATUS verify_image(void *data, unsigned int datasize, - * in order to load it. - */ - if (secure_mode()) { -+#ifdef SHIM_ENABLE_SM -+ efi_status = verify_buffer(data, datasize, -+ context, sha256hash, sha1hash, sm3hash); -+#else - efi_status = verify_buffer(data, datasize, - context, sha256hash, sha1hash); -+#endif - if (EFI_ERROR(efi_status)) { - if (verbose) - console_print(L"Verification failed: %r\n", efi_status); -@@ -1061,8 +1143,13 @@ EFI_STATUS verify_image(void *data, unsigned int datasize, - * this is only useful for the TPM1.2 case. We should try to fix - * this in a follow-up. - */ -+#ifdef SHIM_ENABLE_SM -+ efi_status = generate_hash(data, datasize, context, sha256hash, -+ sha1hash, sm3hash); -+#else - efi_status = generate_hash(data, datasize, context, sha256hash, - sha1hash); -+#endif - if (EFI_ERROR(efi_status)) - return efi_status; - -@@ -1103,6 +1190,9 @@ handle_image (void *data, unsigned int datasize, - int found_entry_point = 0; - UINT8 sha1hash[SHA1_DIGEST_SIZE]; - UINT8 sha256hash[SHA256_DIGEST_SIZE]; -+#ifdef SHIM_ENABLE_SM -+ UINT8 sm3hash[SM3_DIGEST_SIZE]; -+#endif - - /* - * The binary header contains relevant context and section pointers -@@ -1118,8 +1208,13 @@ handle_image (void *data, unsigned int datasize, - * in order to load it. - */ - if (secure_mode ()) { -+#ifdef SHIM_ENABLE_SM -+ efi_status = verify_buffer(data, datasize, &context, sha256hash, -+ sha1hash, sm3hash); -+#else - efi_status = verify_buffer(data, datasize, &context, sha256hash, - sha1hash); -+#endif - - if (EFI_ERROR(efi_status)) { - if (verbose) -@@ -1140,8 +1235,13 @@ handle_image (void *data, unsigned int datasize, - * this is only useful for the TPM1.2 case. We should try to fix - * this in a follow-up. - */ -+#ifdef SHIM_ENABLE_SM -+ efi_status = generate_hash(data, datasize, &context, sha256hash, -+ sha1hash, sm3hash); -+#else - efi_status = generate_hash(data, datasize, &context, sha256hash, - sha1hash); -+#endif - if (EFI_ERROR(efi_status)) - return efi_status; - -diff --git a/shim.c b/shim.c -index fdd205e..5662ca8 100644 ---- a/shim.c -+++ b/shim.c -@@ -458,11 +458,20 @@ BOOLEAN secure_mode (void) - return TRUE; - } - -+#ifdef ENABLE_SHIM_SM -+static EFI_STATUS -+verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig, -+ UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash) -+#else - static EFI_STATUS - verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig, - UINT8 *sha256hash, UINT8 *sha1hash) -+#endif - { - EFI_STATUS efi_status; -+#ifdef ENABLE_SHIM_SM -+ sm3hash = sm3hash; -+#endif - - /* - * Ensure that the binary isn't forbidden -@@ -533,10 +542,15 @@ verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig, - dprint("verifying against vendor_cert\n"); - } - if (vendor_cert_size && -- AuthenticodeVerify(sig->CertData, -- sig->Hdr.dwLength - sizeof(sig->Hdr), -- vendor_cert, vendor_cert_size, -- sha256hash, SHA256_DIGEST_SIZE)) { -+#ifdef ENABLE_SHIM_SM -+ (AuthenticodeVerify(sig->CertData, sig->Hdr.dwLength - sizeof(sig->Hdr), -+ vendor_cert, vendor_cert_size, sha256hash, SHA256_DIGEST_SIZE) || -+ AuthenticodeVerify(sig->CertData, sig->Hdr.dwLength - sizeof(sig->Hdr), -+ vendor_cert, vendor_cert_size, sm3hash, SM3_DIGEST_SIZE))) { -+#else -+ (AuthenticodeVerify(sig->CertData, sig->Hdr.dwLength - sizeof(sig->Hdr), -+ vendor_cert, vendor_cert_size, sha256hash, SHA256_DIGEST_SIZE)) { -+#endif - dprint(L"AuthenticodeVerify(vendor_cert) succeeded\n"); - update_verification_method(VERIFIED_BY_CERT); - tpm_measure_variable(L"Shim", SHIM_LOCK_GUID, -@@ -558,10 +572,17 @@ verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig, - /* - * Check that the signature is valid and matches the binary - */ -+#ifdef ENABLE_SHIM_SM -+EFI_STATUS -+verify_buffer_authenticode (char *data, int datasize, -+ PE_COFF_LOADER_IMAGE_CONTEXT *context, -+ UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash) -+#else - EFI_STATUS - verify_buffer_authenticode (char *data, int datasize, - PE_COFF_LOADER_IMAGE_CONTEXT *context, - UINT8 *sha256hash, UINT8 *sha1hash) -+#endif - { - EFI_STATUS ret_efi_status; - size_t size = datasize; -@@ -578,7 +599,12 @@ verify_buffer_authenticode (char *data, int datasize, - */ - drain_openssl_errors(); - -+#ifdef ENABLE_SHIM_SM -+ ret_efi_status = generate_hash(data, datasize, context, sha256hash, sha1hash, sm3hash); -+#else - ret_efi_status = generate_hash(data, datasize, context, sha256hash, sha1hash); -+#endif -+ - if (EFI_ERROR(ret_efi_status)) { - dprint(L"generate_hash: %r\n", ret_efi_status); - PrintErrors(); -@@ -665,7 +691,11 @@ verify_buffer_authenticode (char *data, int datasize, - - dprint(L"Attempting to verify signature %d:\n", i++); - -+#ifdef ENABLE_SHIM_SM -+ efi_status = verify_one_signature(sig, sha256hash, sha1hash, sm3hash); -+#else - efi_status = verify_one_signature(sig, sha256hash, sha1hash); -+#endif - - /* - * If we didn't get EFI_SECURITY_VIOLATION from -@@ -746,10 +776,17 @@ verify_buffer_sbat (char *data, int datasize, - * Check that the signature is valid and matches the binary and that - * the binary is permitted to load by SBAT. - */ -+#ifdef ENABLE_SHIM_SM -+EFI_STATUS -+verify_buffer (char *data, int datasize, -+ PE_COFF_LOADER_IMAGE_CONTEXT *context, -+ UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash) -+#else - EFI_STATUS - verify_buffer (char *data, int datasize, - PE_COFF_LOADER_IMAGE_CONTEXT *context, - UINT8 *sha256hash, UINT8 *sha1hash) -+#endif - { - EFI_STATUS efi_status; - -@@ -757,7 +794,11 @@ verify_buffer (char *data, int datasize, - if (EFI_ERROR(efi_status)) - return efi_status; - -+#ifdef ENABLE_SHIM_SM -+ return verify_buffer_authenticode(data, datasize, context, sha256hash, sha1hash, sm3hash); -+#else - return verify_buffer_authenticode(data, datasize, context, sha256hash, sha1hash); -+#endif - } - - static int -@@ -970,6 +1011,9 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size) - PE_COFF_LOADER_IMAGE_CONTEXT context; - UINT8 sha1hash[SHA1_DIGEST_SIZE]; - UINT8 sha256hash[SHA256_DIGEST_SIZE]; -+#ifdef ENABLE_SHIM_SM -+ UINT8 sm3hash[SM3_DIGEST_SIZE]; -+#endif - - if ((INT32)size < 0) - return EFI_INVALID_PARAMETER; -@@ -981,8 +1025,13 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size) - if (EFI_ERROR(efi_status)) - goto done; - -+#ifdef ENABLE_SHIM_SM -+ efi_status = generate_hash(buffer, size, &context, -+ sha256hash, sha1hash, sm3hash); -+#else - efi_status = generate_hash(buffer, size, &context, - sha256hash, sha1hash); -+#endif - if (EFI_ERROR(efi_status)) - goto done; - -@@ -1002,16 +1051,27 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size) - goto done; - } - -+#ifdef ENABLE_SHIM_SM -+ efi_status = verify_buffer(buffer, size, -+ &context, sha256hash, sha1hash, sm3hash); -+#else - efi_status = verify_buffer(buffer, size, - &context, sha256hash, sha1hash); -+#endif - done: - in_protocol = 0; - return efi_status; - } - -+#ifdef ENABLE_SHIM_SM -+static EFI_STATUS shim_hash (char *data, int datasize, -+ PE_COFF_LOADER_IMAGE_CONTEXT *context, -+ UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash) -+#else - static EFI_STATUS shim_hash (char *data, int datasize, - PE_COFF_LOADER_IMAGE_CONTEXT *context, - UINT8 *sha256hash, UINT8 *sha1hash) -+#endif - { - EFI_STATUS efi_status; - -@@ -1019,8 +1079,13 @@ static EFI_STATUS shim_hash (char *data, int datasize, - return EFI_INVALID_PARAMETER; - - in_protocol = 1; -+#ifdef ENABLE_SHIM_SM -+ efi_status = generate_hash(data, datasize, context, -+ sha256hash, sha1hash, sm3hash); -+#else - efi_status = generate_hash(data, datasize, context, - sha256hash, sha1hash); -+#endif - in_protocol = 0; - - return efi_status; -diff --git a/shim.h b/shim.h -index b5272b9..b9aa982 100644 ---- a/shim.h -+++ b/shim.h -@@ -208,6 +208,18 @@ EFI_STATUS - IN UINT32 size - ); - -+#ifdef ENABLE_SHIM_SM -+typedef -+EFI_STATUS -+(*EFI_SHIM_LOCK_HASH) ( -+ IN char *data, -+ IN int datasize, -+ PE_COFF_LOADER_IMAGE_CONTEXT *context, -+ UINT8 *sha256hash, -+ UINT8 *sha1hash, -+ UINT8 *sm3hash -+ ); -+#else - typedef - EFI_STATUS - (*EFI_SHIM_LOCK_HASH) ( -@@ -217,6 +229,7 @@ EFI_STATUS - UINT8 *sha256hash, - UINT8 *sha1hash - ); -+#endif - - typedef - EFI_STATUS -@@ -271,10 +284,17 @@ extern UINT32 load_options_size; - - BOOLEAN secure_mode (void); - -+#ifdef ENABLE_SHIM_SM -+EFI_STATUS -+verify_buffer (char *data, int datasize, -+ PE_COFF_LOADER_IMAGE_CONTEXT *context, -+ UINT8 *sha256hash, UINT8 *sha1hash, UINT8 *sm3hash); -+#else - EFI_STATUS - verify_buffer (char *data, int datasize, - PE_COFF_LOADER_IMAGE_CONTEXT *context, - UINT8 *sha256hash, UINT8 *sha1hash); -+#endif - - #ifndef SHIM_UNIT_TEST - #define perror_(file, line, func, fmt, ...) ({ \ --- -2.33.0 - diff --git a/Feature-shim-support-sm2-and-sm3-algorithm.patch b/Feature-shim-support-sm2-and-sm3-algorithm.patch index ec99aac18263a25dce6479caa7b5b8ca2bd50001..81db1378f2fb8dfbf37fcda89c331a5d2c6839a1 100644 --- a/Feature-shim-support-sm2-and-sm3-algorithm.patch +++ b/Feature-shim-support-sm2-and-sm3-algorithm.patch @@ -27,9 +27,9 @@ index 24ac314..9b8d7e8 100644 +ifneq ($(origin ENABLE_SHIM_SM),undefined) +CFLAGS += -DENABLE_SHIM_SM +endif - OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o pe.o httpboot.o csv.o load-options.o + OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o httpboot.o csv.o load-options.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer - ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S + ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S @@ -163,7 +166,7 @@ Cryptlib/libcryptlib.a: $(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile diff --git a/shim-15.6.tar.bz2 b/shim-15.6.tar.bz2 deleted file mode 100644 index c88d790071b21728470d721c2c97c331d1eb2271..0000000000000000000000000000000000000000 Binary files a/shim-15.6.tar.bz2 and /dev/null differ diff --git a/shim-15.7.tar.bz2 b/shim-15.7.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..fb2f4fe2883899f4d3be2f40758f645be4aee5e5 Binary files /dev/null and b/shim-15.7.tar.bz2 differ diff --git a/shim.spec b/shim.spec index 6a10e484faf0316d2638a391e1446ac590fd3fe7..3184afcbbd07509b2dff2bd624258219958a7990 100644 --- a/shim.spec +++ b/shim.spec @@ -24,8 +24,8 @@ %global vendor_cert %{nil} Name: shim -Version: 15.6 -Release: 10 +Version: 15.7 +Release: 1 Summary: First-stage UEFI bootloader ExclusiveArch: x86_64 aarch64 License: BSD @@ -154,6 +154,9 @@ make test /usr/src/debug/%{name}-%{version}-%{release}/* %changelog +* Tue Jul 18 2023 jinlun - 15.7-1 +- update version to 15.7 + * Wed Jul 5 2023 yuxiating 15.6-10 - update openssl version description