252 lines
8.8 KiB
Diff
252 lines
8.8 KiB
Diff
|
|
From 32ab7eb58556d41df302af8166a77f2f2bf38754 Mon Sep 17 00:00:00 2001
|
||
|
|
From: xujing <xujing125@huawei.com>
|
||
|
|
Date: Wed, 18 Sep 2024 15:57:34 +0800
|
||
|
|
Subject: [PATCH] Support sm2p256v1 of ECDSA and sm3 of hash
|
||
|
|
|
||
|
|
---
|
||
|
|
include/rpm/rpmcrypto.h | 1 +
|
||
|
|
include/rpm/rpmpgp.h | 2 ++
|
||
|
|
macros.in | 4 +++
|
||
|
|
rpmio/digest_libgcrypt.c | 6 ++++
|
||
|
|
rpmio/digest_openssl.c | 69 +++++++++++++++++++++++++++++++++++++++-
|
||
|
|
rpmio/rpmpgp_internal.c | 1 +
|
||
|
|
rpmio/rpmpgpval.h | 1 +
|
||
|
|
sign/rpmsignfiles.c | 4 +++
|
||
|
|
8 files changed, 87 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/include/rpm/rpmcrypto.h b/include/rpm/rpmcrypto.h
|
||
|
|
index 69d329f..ef36e7a 100644
|
||
|
|
--- a/include/rpm/rpmcrypto.h
|
||
|
|
+++ b/include/rpm/rpmcrypto.h
|
||
|
|
@@ -27,6 +27,7 @@ typedef enum rpmHashAlgo_e {
|
||
|
|
RPM_HASH_SHA384 = 9, /*!< SHA384 */
|
||
|
|
RPM_HASH_SHA512 = 10, /*!< SHA512 */
|
||
|
|
RPM_HASH_SHA224 = 11, /*!< SHA224 */
|
||
|
|
+ RPM_HASH_SM3 = 109, /*!< SM3, the definition is the same as that of libgcrypt */
|
||
|
|
} rpmHashAlgo;
|
||
|
|
|
||
|
|
/** \ingroup rpmcrypto
|
||
|
|
diff --git a/include/rpm/rpmpgp.h b/include/rpm/rpmpgp.h
|
||
|
|
index a3238a6..0d46941 100644
|
||
|
|
--- a/include/rpm/rpmpgp.h
|
||
|
|
+++ b/include/rpm/rpmpgp.h
|
||
|
|
@@ -274,6 +274,7 @@ typedef enum pgpHashAlgo_e {
|
||
|
|
PGPHASHALGO_SHA384 = 9, /*!< SHA384 */
|
||
|
|
PGPHASHALGO_SHA512 = 10, /*!< SHA512 */
|
||
|
|
PGPHASHALGO_SHA224 = 11, /*!< SHA224 */
|
||
|
|
+ PGPHASHALGO_SM3 = 109, /*!< SM3, the definition is the same as that of libgcrypt */
|
||
|
|
} pgpHashAlgo;
|
||
|
|
|
||
|
|
/** \ingroup rpmpgp
|
||
|
|
@@ -290,6 +291,7 @@ typedef enum pgpCurveId_e {
|
||
|
|
PGPCURVE_BRAINPOOL_P512R1 = 5, /*!< brainpoolP512r1 */
|
||
|
|
PGPCURVE_ED25519 = 6, /*!< Ed25519 */
|
||
|
|
PGPCURVE_CURVE25519 = 7, /*!< Curve25519 */
|
||
|
|
+ PGPCURVE_SM2P256V1 = 8, /*!< sm2p256v1 */
|
||
|
|
} pgpCurveId;
|
||
|
|
|
||
|
|
/** \ingroup rpmpgp
|
||
|
|
diff --git a/macros.in b/macros.in
|
||
|
|
index 11c70be..1b05672 100644
|
||
|
|
--- a/macros.in
|
||
|
|
+++ b/macros.in
|
||
|
|
@@ -597,6 +597,10 @@ package or when debugging this package.\
|
||
|
|
-sbo %{shescape:%{?__signature_filename}} \
|
||
|
|
%{?__plaintext_filename:-- %{shescape:%{__plaintext_filename}}}
|
||
|
|
|
||
|
|
+# The sm3 hash algorithm and sm2p256v1 encryption and decryption algorithm
|
||
|
|
+# in ECDSA are disabled by default.
|
||
|
|
+%_enable_sm2p256v1_sm3_algo 0
|
||
|
|
+
|
||
|
|
#==============================================================================
|
||
|
|
# ---- Transaction macros.
|
||
|
|
# Macro(s) used to parameterize transactions.
|
||
|
|
diff --git a/rpmio/digest_libgcrypt.c b/rpmio/digest_libgcrypt.c
|
||
|
|
index 7a75d2d..d14cc52 100644
|
||
|
|
--- a/rpmio/digest_libgcrypt.c
|
||
|
|
+++ b/rpmio/digest_libgcrypt.c
|
||
|
|
@@ -42,6 +42,9 @@ size_t rpmDigestLength(int hashalgo)
|
||
|
|
return 28;
|
||
|
|
case RPM_HASH_SHA256:
|
||
|
|
return 32;
|
||
|
|
+ case RPM_HASH_SM3:
|
||
|
|
+ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}"))
|
||
|
|
+ return 32;
|
||
|
|
case RPM_HASH_SHA384:
|
||
|
|
return 48;
|
||
|
|
case RPM_HASH_SHA512:
|
||
|
|
@@ -66,6 +69,9 @@ static int hashalgo2gcryalgo(int hashalgo)
|
||
|
|
return GCRY_MD_SHA384;
|
||
|
|
case RPM_HASH_SHA512:
|
||
|
|
return GCRY_MD_SHA512;
|
||
|
|
+ case RPM_HASH_SM3:
|
||
|
|
+ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}"))
|
||
|
|
+ return GCRY_MD_SM3;
|
||
|
|
default:
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c
|
||
|
|
index eb9fbaa..92b8113 100644
|
||
|
|
--- a/rpmio/digest_openssl.c
|
||
|
|
+++ b/rpmio/digest_openssl.c
|
||
|
|
@@ -9,6 +9,7 @@
|
||
|
|
#include <openssl/ec.h>
|
||
|
|
|
||
|
|
#include <rpm/rpmcrypto.h>
|
||
|
|
+#include <rpm/rpmmacro.h>
|
||
|
|
#include "rpmio/rpmpgp_internal.h"
|
||
|
|
|
||
|
|
|
||
|
|
@@ -188,6 +189,10 @@ static const EVP_MD *getEVPMD(int hashalgo)
|
||
|
|
case RPM_HASH_SHA224:
|
||
|
|
return EVP_sha224();
|
||
|
|
|
||
|
|
+ case RPM_HASH_SM3:
|
||
|
|
+ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}"))
|
||
|
|
+ return EVP_sm3();
|
||
|
|
+
|
||
|
|
default:
|
||
|
|
return EVP_md_null();
|
||
|
|
}
|
||
|
|
@@ -837,6 +842,14 @@ static int constructECDSASigningKey(struct pgpDigKeyECDSA_s *key, int curve)
|
||
|
|
OSSL_PARAM_END
|
||
|
|
};
|
||
|
|
key->evp_pkey = construct_pkey_from_param(EVP_PKEY_EC, params);
|
||
|
|
+ } else if (curve == PGPCURVE_SM2P256V1 &&
|
||
|
|
+ rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) {
|
||
|
|
+ OSSL_PARAM params[] = {
|
||
|
|
+ OSSL_PARAM_utf8_string("group", "SM2", 3),
|
||
|
|
+ OSSL_PARAM_octet_string("pub", key->q, key->qlen),
|
||
|
|
+ OSSL_PARAM_END
|
||
|
|
+ };
|
||
|
|
+ key->evp_pkey = construct_pkey_from_param(EVP_PKEY_SM2, params);
|
||
|
|
}
|
||
|
|
return key->evp_pkey ? 1 : 0;
|
||
|
|
#else
|
||
|
|
@@ -950,6 +963,46 @@ static void pgpFreeSigECDSA(pgpDigAlg pgpsig)
|
||
|
|
free(pgpsig->data);
|
||
|
|
}
|
||
|
|
|
||
|
|
+/* Source of zin information refer to https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02.html#appendix-D */
|
||
|
|
+const unsigned char zin_default[] = {
|
||
|
|
+ 0x00, 0x80, /* id length */
|
||
|
|
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34,
|
||
|
|
+ 0x35, 0x36, 0x37, 0x38, /* default id: 1234567812345678 */
|
||
|
|
+ 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, /* sm2 a */
|
||
|
|
+ 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, /* sm2 b */
|
||
|
|
+ 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, /* sm2 x */
|
||
|
|
+ 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 /* sm2 y */
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static int calculate_sm2_hash(struct pgpDigKeyECDSA_s *key, uint8_t *msg, size_t msglen, uint8_t *hash)
|
||
|
|
+{
|
||
|
|
+ unsigned char z[32];
|
||
|
|
+
|
||
|
|
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||
|
|
+
|
||
|
|
+ EVP_DigestInit(ctx, EVP_sm3());
|
||
|
|
+ EVP_DigestUpdate(ctx, zin_default, sizeof(zin_default));
|
||
|
|
+ EVP_DigestUpdate(ctx, key->q + 1, key->qlen - 1);
|
||
|
|
+ EVP_DigestFinal_ex(ctx, z, NULL);
|
||
|
|
+
|
||
|
|
+ EVP_DigestInit(ctx, EVP_sm3());
|
||
|
|
+ EVP_DigestUpdate(ctx, z, sizeof(z));
|
||
|
|
+ EVP_DigestUpdate(ctx, msg, msglen);
|
||
|
|
+ EVP_DigestFinal_ex(ctx, hash, NULL);
|
||
|
|
+
|
||
|
|
+ EVP_MD_CTX_free(ctx);
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int pgpVerifySigECDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
|
||
|
|
uint8_t *hash, size_t hashlen, int hash_algo)
|
||
|
|
{
|
||
|
|
@@ -959,6 +1012,8 @@ static int pgpVerifySigECDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
|
||
|
|
unsigned char *xsig = NULL; /* signature encoded for X509 */
|
||
|
|
size_t xsig_len = 0;
|
||
|
|
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||
|
|
+ uint8_t *hash_to_use = hash;
|
||
|
|
+ uint8_t sm2_hash[32] = { 0 };
|
||
|
|
|
||
|
|
if (!constructECDSASigningKey(key, pgpkey->curve))
|
||
|
|
goto done;
|
||
|
|
@@ -974,7 +1029,16 @@ static int pgpVerifySigECDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
|
||
|
|
if (EVP_PKEY_verify_init(pkey_ctx) != 1)
|
||
|
|
goto done;
|
||
|
|
|
||
|
|
- if (EVP_PKEY_verify(pkey_ctx, xsig, xsig_len, hash, hashlen) == 1)
|
||
|
|
+ if (pgpkey->curve == PGPCURVE_SM2P256V1) {
|
||
|
|
+ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) {
|
||
|
|
+ calculate_sm2_hash(key, hash, hashlen, sm2_hash);
|
||
|
|
+ hash_to_use = sm2_hash;
|
||
|
|
+ } else {
|
||
|
|
+ goto done;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (EVP_PKEY_verify(pkey_ctx, xsig, xsig_len, hash_to_use, hashlen) == 1)
|
||
|
|
{
|
||
|
|
/* Success */
|
||
|
|
rc = 0;
|
||
|
|
@@ -1109,6 +1173,9 @@ static int pgpSupportedCurve(int algo, int curve)
|
||
|
|
return 1;
|
||
|
|
if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_NIST_P_521)
|
||
|
|
return 1;
|
||
|
|
+ if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_SM2P256V1 &&
|
||
|
|
+ rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}"))
|
||
|
|
+ return 1;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/rpmio/rpmpgp_internal.c b/rpmio/rpmpgp_internal.c
|
||
|
|
index 8b845b7..0960057 100644
|
||
|
|
--- a/rpmio/rpmpgp_internal.c
|
||
|
|
+++ b/rpmio/rpmpgp_internal.c
|
||
|
|
@@ -537,6 +537,7 @@ static uint8_t curve_oids[] = {
|
||
|
|
PGPCURVE_BRAINPOOL_P512R1, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d,
|
||
|
|
PGPCURVE_ED25519, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01,
|
||
|
|
PGPCURVE_CURVE25519, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01,
|
||
|
|
+ PGPCURVE_SM2P256V1, 0x08, 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x1, 0x82, 0x2d,
|
||
|
|
0,
|
||
|
|
};
|
||
|
|
|
||
|
|
diff --git a/rpmio/rpmpgpval.h b/rpmio/rpmpgpval.h
|
||
|
|
index ad8ed08..b8b7cb4 100644
|
||
|
|
--- a/rpmio/rpmpgpval.h
|
||
|
|
+++ b/rpmio/rpmpgpval.h
|
||
|
|
@@ -77,6 +77,7 @@ static struct pgpValTbl_s const pgpHashTbl[] = {
|
||
|
|
{ PGPHASHALGO_SHA384, "SHA384" },
|
||
|
|
{ PGPHASHALGO_SHA512, "SHA512" },
|
||
|
|
{ PGPHASHALGO_SHA224, "SHA224" },
|
||
|
|
+ { PGPHASHALGO_SM3, "SM3" },
|
||
|
|
{ -1, "Unknown hash algorithm" },
|
||
|
|
};
|
||
|
|
|
||
|
|
diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c
|
||
|
|
index 80ef233..fa20bf6 100644
|
||
|
|
--- a/sign/rpmsignfiles.c
|
||
|
|
+++ b/sign/rpmsignfiles.c
|
||
|
|
@@ -19,6 +19,10 @@
|
||
|
|
|
||
|
|
#define MAX_SIGNATURE_LENGTH 1024
|
||
|
|
|
||
|
|
+/*
|
||
|
|
+ * Currently, we do not support the sm3 hash algorithm to sign files.
|
||
|
|
+ * Therefore, we do not add sm3.
|
||
|
|
+ */
|
||
|
|
static const char *hash_algo_name[] = {
|
||
|
|
[RPM_HASH_MD5] = "md5",
|
||
|
|
[RPM_HASH_SHA1] = "sha1",
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|