Hi, On Thu, Sep 3, 2020 at 4:13 PM Tianjia Zhang <tianjia.zhang@xxxxxxxxxxxxxxxxx> wrote: > > The digital certificate format based on SM2 crypto algorithm as > specified in GM/T 0015-2012. It was published by State Encryption > Management Bureau, China. > > The method of generating Other User Information is defined as > ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA), it also > specified in https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02. > > The x509 certificate supports sm2-with-sm3 type certificate > verification. Because certificate verification requires ZA > in addition to tbs data, ZA also depends on elliptic curve > parameters and public key data, so you need to access tbs in sig > and calculate ZA. Finally calculate the digest of the > signature and complete the verification work. The calculation > process of ZA is declared in specifications GM/T 0009-2012 > and GM/T 0003.2-2012. > > Signed-off-by: Tianjia Zhang <tianjia.zhang@xxxxxxxxxxxxxxxxx> > Tested-by: Xufeng Zhang <yunbo.xufeng@xxxxxxxxxxxxxxxxx> > --- > crypto/asymmetric_keys/Makefile | 1 + > crypto/asymmetric_keys/public_key.c | 6 +++ > crypto/asymmetric_keys/public_key_sm2.c | 61 ++++++++++++++++++++++++ > crypto/asymmetric_keys/x509_public_key.c | 3 ++ > include/crypto/public_key.h | 15 ++++++ > 5 files changed, 86 insertions(+) > create mode 100644 crypto/asymmetric_keys/public_key_sm2.c > > diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile > index 28b91adba2ae..1a99ea5acb6b 100644 > --- a/crypto/asymmetric_keys/Makefile > +++ b/crypto/asymmetric_keys/Makefile > @@ -11,6 +11,7 @@ asymmetric_keys-y := \ > signature.o > > obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o > +obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key_sm2.o > obj-$(CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE) += asym_tpm.o > > # > diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c > index d8410ffd7f12..1d0492098bbd 100644 > --- a/crypto/asymmetric_keys/public_key.c > +++ b/crypto/asymmetric_keys/public_key.c > @@ -299,6 +299,12 @@ int public_key_verify_signature(const struct public_key *pkey, > if (ret) > goto error_free_key; > > + if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) { > + ret = cert_sig_digest_update(sig, tfm); > + if (ret) > + goto error_free_key; > + } > + > sg_init_table(src_sg, 2); > sg_set_buf(&src_sg[0], sig->s, sig->s_size); > sg_set_buf(&src_sg[1], sig->digest, sig->digest_size); > diff --git a/crypto/asymmetric_keys/public_key_sm2.c b/crypto/asymmetric_keys/public_key_sm2.c > new file mode 100644 > index 000000000000..7325cf21dbb4 > --- /dev/null > +++ b/crypto/asymmetric_keys/public_key_sm2.c > @@ -0,0 +1,61 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * asymmetric public-key algorithm for SM2-with-SM3 certificate > + * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and > + * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02 > + * > + * Copyright (c) 2020, Alibaba Group. > + * Authors: Tianjia Zhang <tianjia.zhang@xxxxxxxxxxxxxxxxx> > + */ > + > +#include <crypto/sm3_base.h> > +#include <crypto/sm2.h> > +#include <crypto/public_key.h> > + > +#if IS_REACHABLE(CONFIG_CRYPTO_SM2) > + > +int cert_sig_digest_update(const struct public_key_signature *sig, > + struct crypto_akcipher *tfm_pkey) > +{ > + struct crypto_shash *tfm; > + struct shash_desc *desc; > + size_t desc_size; > + unsigned char dgst[SM3_DIGEST_SIZE]; > + int ret; > + > + BUG_ON(!sig->data); > + > + ret = sm2_compute_z_digest(tfm_pkey, SM2_DEFAULT_USERID, > + SM2_DEFAULT_USERID_LEN, dgst); > + if (ret) > + return ret; > + > + tfm = crypto_alloc_shash(sig->hash_algo, 0, 0); > + if (IS_ERR(tfm)) > + return PTR_ERR(tfm); > + > + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); > + desc = kzalloc(desc_size, GFP_KERNEL); > + if (!desc) > + goto error_free_tfm; > + > + desc->tfm = tfm; > + > + ret = crypto_shash_init(desc); > + if (ret < 0) > + goto error_free_desc; > + > + ret = crypto_shash_update(desc, dgst, SM3_DIGEST_SIZE); > + if (ret < 0) > + goto error_free_desc; > + > + ret = crypto_shash_finup(desc, sig->data, sig->data_size, sig->digest); It looks like you are doing a separate init, update, finup every time - I would consider using crypto_shash_digest() in one go. In fact, considering the fact that you are allocating a tfm just for this use and then releasing it, I would consider switching to crypto_shash_tfm_digest() and dropping the kzalloc all together. This should simplify the code a bit. Other than that I don't have anything smart to say :-) Gilad -- Gilad Ben-Yossef Chief Coffee Drinker values of β will give rise to dom!