1285 lines
42 KiB
Diff
1285 lines
42 KiB
Diff
From 62d73c2dd0cc4b2a80186d55de5ffd4298462a83 Mon Sep 17 00:00:00 2001
|
|
From: Huaxin Lu <luhuaxin1@huawei.com>
|
|
Date: Mon, 7 Nov 2022 11:44:18 +0800
|
|
Subject: [PATCH 3/5] shim openssl add sm2 and sm3 support
|
|
|
|
Co-authored-by: Yusong Gao <gaoyusong2@huawei.com>
|
|
Signed-off-by: Yusong Gao <gaoyusong2@huawei.com>
|
|
Signed-off-by: Huaxin Lu <luhuaxin1@huawei.com>
|
|
---
|
|
Cryptlib/Include/openssl/sm2.h | 79 ++++++
|
|
Cryptlib/Include/openssl/sm2err.h | 65 +++++
|
|
Cryptlib/Include/openssl/sm3.h | 39 +++
|
|
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 ++++++
|
|
9 files changed, 1198 insertions(+)
|
|
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/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/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 <openssl/opensslconf.h>
|
|
+
|
|
+# ifndef OPENSSL_NO_SM2
|
|
+
|
|
+# include <openssl/ec.h>
|
|
+# include <openssl/ecdsa.h>
|
|
+
|
|
+/* 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 <openssl/symhacks.h>
|
|
+
|
|
+# include <openssl/opensslconf.h>
|
|
+
|
|
+# 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 <openssl/opensslconf.h>
|
|
+
|
|
+# 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/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 <openssl/err.h>
|
|
+#include <openssl/sm2err.h>
|
|
+
|
|
+#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 <openssl/asn1t.h>
|
|
+#include <openssl/ec.h>
|
|
+#include <openssl/ecdsa.h>
|
|
+#include <openssl/evp.h>
|
|
+#include "crypto/evp/evp_locl.h"
|
|
+#include <openssl/sm2.h>
|
|
+#include <openssl/sm2err.h>
|
|
+
|
|
+/* 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 <openssl/sm2.h>
|
|
+#include <openssl/sm2err.h>
|
|
+#include <openssl/ec.h> /* ec_group_do_inverse_ord() */
|
|
+#include <openssl/ecdsa.h>
|
|
+#include <openssl/err.h>
|
|
+#include <openssl/evp.h>
|
|
+#include <openssl/err.h>
|
|
+#include <openssl/bn.h>
|
|
+#include <string.h>
|
|
+
|
|
+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 <openssl/evp.h>
|
|
+# include <openssl/sm3.h>
|
|
+
|
|
+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 <openssl/e_os2.h>
|
|
+#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 <string.h>
|
|
+#include <openssl/sm3.h>
|
|
+
|
|
+#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
|
|
--
|
|
2.33.0
|
|
|