]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/sm2/sm2_sign.c
2 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2017 Ribose Inc. All Rights Reserved.
4 * Ported from Ribose contributions from Botan.
6 * Licensed under the OpenSSL license (the "License"). You may not use
7 * this file except in compliance with the License. You can obtain a copy
8 * in the file LICENSE in the source distribution or at
9 * https://www.openssl.org/source/license.html
12 #include <openssl/sm2.h>
13 #include <openssl/evp.h>
14 #include <openssl/bn.h>
17 static BIGNUM
*compute_msg_hash(const EVP_MD
*digest
,
20 const uint8_t *msg
, size_t msg_len
)
22 EVP_MD_CTX
*hash
= EVP_MD_CTX_new();
23 const int md_size
= EVP_MD_size(digest
);
24 uint8_t *za
= OPENSSL_zalloc(md_size
);
33 if (SM2_compute_userid_digest(za
, digest
, user_id
, key
) == 0)
36 if (EVP_DigestInit(hash
, digest
) == 0)
39 if (EVP_DigestUpdate(hash
, za
, md_size
) == 0)
42 if (EVP_DigestUpdate(hash
, msg
, msg_len
) == 0)
45 /* reuse za buffer to hold H(ZA || M) */
46 if (EVP_DigestFinal(hash
, za
, NULL
) == 0)
49 e
= BN_bin2bn(za
, md_size
, NULL
);
53 EVP_MD_CTX_free(hash
);
58 ECDSA_SIG
*SM2_sig_gen(const EC_KEY
*key
, const BIGNUM
*e
)
60 const BIGNUM
*dA
= EC_KEY_get0_private_key(key
);
61 const EC_GROUP
*group
= EC_KEY_get0_group(key
);
62 const BIGNUM
*order
= EC_GROUP_get0_order(group
);
64 ECDSA_SIG
*sig
= NULL
;
74 kG
= EC_POINT_new(group
);
87 tmp
= BN_CTX_get(ctx
);
92 /* These values are returned and so should not be allocated out of the context */
96 if (r
== NULL
|| s
== NULL
)
100 BN_priv_rand_range(k
, order
);
102 if (EC_POINT_mul(group
, kG
, k
, NULL
, NULL
, ctx
) == 0)
105 if (EC_POINT_get_affine_coordinates_GFp(group
, kG
, x1
, NULL
, ctx
) == 0)
108 if (BN_mod_add(r
, e
, x1
, order
, ctx
) == 0)
111 /* try again if r == 0 or r+k == n */
117 if (BN_cmp(rk
, order
) == 0)
120 BN_add(s
, dA
, BN_value_one());
121 BN_mod_inverse(s
, s
, order
, ctx
);
123 BN_mod_mul(tmp
, dA
, r
, order
, ctx
);
126 BN_mod_mul(s
, s
, tmp
, order
, ctx
);
128 sig
= ECDSA_SIG_new();
133 /* takes ownership of r and s */
134 ECDSA_SIG_set0(sig
, r
, s
);
152 int SM2_sig_verify(const EC_KEY
*key
, const ECDSA_SIG
*sig
, const BIGNUM
*e
)
155 const EC_GROUP
*group
= EC_KEY_get0_group(key
);
156 const BIGNUM
*order
= EC_GROUP_get0_order(group
);
162 const BIGNUM
*r
= NULL
;
163 const BIGNUM
*s
= NULL
;
168 pt
= EC_POINT_new(group
);
175 x1
= BN_CTX_get(ctx
);
181 B1: verify whether r' in [1,n-1], verification failed if not
182 B2: vefify whether s' in [1,n-1], verification failed if not
184 B4: calculate e'=Hv(M'~)
185 B5: calculate t = (r' + s') modn, verification failed if t=0
186 B6: calculate the point (x1', y1')=[s']G + [t]PA
187 B7: calculate R=(e'+x1') modn, verfication pass if yes, otherwise failed
190 ECDSA_SIG_get0(sig
, &r
, &s
);
192 if (BN_cmp(r
, BN_value_one()) < 0)
194 if (BN_cmp(s
, BN_value_one()) < 0)
197 if (BN_cmp(order
, r
) <= 0)
199 if (BN_cmp(order
, s
) <= 0)
202 if (BN_mod_add(t
, r
, s
, order
, ctx
) == 0)
205 if (BN_is_zero(t
) == 1)
208 if (EC_POINT_mul(group
, pt
, s
, EC_KEY_get0_public_key(key
), t
, ctx
) == 0)
211 if (EC_POINT_get_affine_coordinates_GFp(group
, pt
, x1
, NULL
, ctx
) == 0)
214 if (BN_mod_add(t
, e
, x1
, order
, ctx
) == 0)
217 if (BN_cmp(r
, t
) == 0)
226 ECDSA_SIG
*SM2_do_sign(const EC_KEY
*key
,
227 const EVP_MD
*digest
,
228 const char *user_id
, const uint8_t *msg
, size_t msg_len
)
231 ECDSA_SIG
*sig
= NULL
;
233 e
= compute_msg_hash(digest
, key
, user_id
, msg
, msg_len
);
237 sig
= SM2_sig_gen(key
, e
);
244 int SM2_do_verify(const EC_KEY
*key
,
245 const EVP_MD
*digest
,
246 const ECDSA_SIG
*sig
,
247 const char *user_id
, const uint8_t *msg
, size_t msg_len
)
252 e
= compute_msg_hash(digest
, key
, user_id
, msg
, msg_len
);
256 ret
= SM2_sig_verify(key
, sig
, e
);
263 int SM2_sign(int type
, const unsigned char *dgst
, int dgstlen
,
264 unsigned char *sig
, unsigned int *siglen
, EC_KEY
*eckey
)
273 if (dgstlen
!= 32) /* expected length of SM3 hash */
276 e
= BN_bin2bn(dgst
, dgstlen
, NULL
);
278 s
= SM2_sig_gen(eckey
, e
);
280 *siglen
= i2d_ECDSA_SIG(s
, &sig
);
292 int SM2_verify(int type
, const unsigned char *dgst
, int dgstlen
,
293 const unsigned char *sig
, int sig_len
, EC_KEY
*eckey
)
297 const unsigned char *p
= sig
;
298 unsigned char *der
= NULL
;
308 if (d2i_ECDSA_SIG(&s
, &p
, sig_len
) == NULL
)
310 /* Ensure signature uses DER and doesn't have trailing garbage */
311 derlen
= i2d_ECDSA_SIG(s
, &der
);
312 if (derlen
!= sig_len
|| memcmp(sig
, der
, derlen
) != 0)
315 e
= BN_bin2bn(dgst
, dgstlen
, NULL
);
317 ret
= SM2_sig_verify(eckey
, s
, e
);