Skip to content

Commit a15e0f3

Browse files
committed
Add ECDSA with curve P-256
for TLS testing
1 parent 05ba2f8 commit a15e0f3

File tree

20 files changed

+3663
-31
lines changed

20 files changed

+3663
-31
lines changed

CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ option(ENABLE_SM4_CBC_MAC "Enable SM4-CBC-MAC" ON)
5454

5555
option(ENABLE_SM2_EXTS "Enable SM2 Extensions" OFF)
5656

57+
option(ENABLE_SECP256R1 "Enable ECDH/ECDSA on curve secp256r1" ON)
58+
5759
option(ENABLE_LMS "Enable LMS/HSS signature" ON)
5860
option(ENABLE_XMSS "Enable XMSS/XMSS^MT signature" ON)
5961
option(ENABLE_SPHINCS "Enable SPHINCS+ signature" ON)
@@ -108,6 +110,7 @@ set(src
108110
src/sm4_cbc_sm3_hmac.c
109111
src/sm4_ctr_sm3_hmac.c
110112
src/pkcs8.c
113+
src/bn.c
111114
src/ec.c
112115
src/rsa.c
113116
src/asn1.c
@@ -128,6 +131,7 @@ set(src
128131
src/tls_trace.c
129132
src/tlcp.c
130133
src/tls12.c
134+
src/tls12_handshake.c
131135
src/tls13.c
132136
src/file.c
133137
src/file.c
@@ -203,6 +207,7 @@ set(tests
203207
gf128
204208
ghash
205209
pkcs8
210+
bn
206211
ec
207212
asn1
208213
hex
@@ -419,6 +424,14 @@ if (ENABLE_SM2_EXTS)
419424
endif()
420425

421426

427+
if (ENABLE_SECP256R1)
428+
message(STATUS "ENABLE_SECP256R1 is ON")
429+
add_definitions(-DENABLE_SECP256R1)
430+
list(APPEND src src/secp256r1.c src/secp256r1_key.c src/ecdsa.c)
431+
list(APPEND tests secp256r1 secp256r1_key ecdsa)
432+
endif()
433+
434+
422435
if (ENABLE_LMS)
423436
message(STATUS "ENABLE_LMS is ON")
424437
add_definitions(-DENABLE_LMS)

include/gmssl/bn.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
10+
11+
12+
#ifndef GMSSL_BN_H
13+
#define GMSSL_BN_H
14+
15+
16+
#include <stdio.h>
17+
#include <stdint.h>
18+
#include <stdlib.h>
19+
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
26+
void bn_set_word(uint32_t *r, uint32_t a, size_t k);
27+
void bn_copy(uint32_t *r, const uint32_t *a, size_t k);
28+
int bn_cmp(const uint32_t *a, const uint32_t *b, size_t k);
29+
int bn_is_zero(const uint32_t *a, size_t k);
30+
int bn_is_one(const uint32_t *a, size_t k);
31+
int bn_add(uint32_t *r, const uint32_t *a, const uint32_t *b, size_t k);
32+
int bn_sub(uint32_t *r, const uint32_t *a, const uint32_t *b, size_t k);
33+
void bn_mul(uint32_t *r, const uint32_t *a, const uint32_t *b, size_t k);
34+
void bn_mul_lo(uint32_t *r, const uint32_t *a, const uint32_t *b, size_t k);
35+
void bn_to_bytes(const uint32_t *a, size_t k, uint8_t *out);
36+
void bn_from_bytes(uint32_t *a, size_t k, const uint8_t *in);
37+
int bn_print(FILE *fp, int fmt, int ind, const char *label, const uint32_t *a, size_t k);
38+
39+
void bn_mod_add(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *p, size_t k);
40+
void bn_mod_sub(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *p, size_t k);
41+
void bn_mod_neg(uint32_t *r, const uint32_t *a, const uint32_t *p, size_t k);
42+
43+
// multiplication with barrett reduction, need caller prepare temp values
44+
// u = floor(2^512 / p) for bn256
45+
void bn_barrett_mod_mul(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *p,
46+
const uint32_t *u, // uint32_t u[k + 1]
47+
uint32_t *tmp, // uint32_t tmp[6*k + 4]
48+
size_t k);
49+
void bn_barrett_mod_sqr(uint32_t *r, const uint32_t *a, const uint32_t *p,
50+
const uint32_t *u, // uint32_t u[k + 1]
51+
uint32_t *tmp, // uint32_t tmp[6*k + 4]
52+
size_t k);
53+
void bn_barrett_mod_exp(uint32_t *r, const uint32_t *a, const uint32_t *e, const uint32_t *p,
54+
const uint32_t *u, // uint32_t u[k + 1]
55+
uint32_t *tmp, // uint32_t tmp[7*k + 4]
56+
size_t k);
57+
void bn_barrett_mod_inv(uint32_t *r, const uint32_t *a, const uint32_t *p,
58+
const uint32_t *u, // uint32_t u[k + 1]
59+
uint32_t *tmp, // uint32_t tmp[8*k + 4]
60+
size_t k);
61+
62+
// montgomery multiplication, all values in montgomery format, need caller prepare temp values
63+
void bn_mont_mod_mul(uint32_t *r, const uint32_t *a, const uint32_t *b, const uint32_t *p, const uint32_t *p_inv_neg,
64+
uint32_t *tmp, // uint32_t tmp[5 * k]
65+
size_t k);
66+
void bn_mont_mod_sqr(uint32_t *r, const uint32_t *a, const uint32_t *p, const uint32_t *p_inv_neg,
67+
uint32_t *tmp, // uint32_t tmp[5 * k]
68+
size_t k);
69+
void bn_mont_mod_exp(uint32_t *r, const uint32_t *a, const uint32_t *e, const uint32_t *p, const uint32_t *p_inv_neg,
70+
uint32_t *tmp, // uint32_t tmp[6 * k]
71+
size_t k);
72+
void bn_mont_mod_inv(uint32_t *r, const uint32_t *a, const uint32_t *p, const uint32_t *p_inv_neg,
73+
uint32_t *tmp, // uint32_t tmp[7 * k]
74+
size_t k);
75+
void bn_mont_set(uint32_t *r, const uint32_t *a, const uint32_t *one_sqr, const uint32_t *p, const uint32_t *p_inv_neg,
76+
uint32_t *tmp, // uint32_t tmp[5 * k]
77+
size_t k);
78+
void bn_mont_get(uint32_t *r, const uint32_t *a, const uint32_t *p, const uint32_t *p_inv_neg,
79+
uint32_t *tmp, // uint32_t tmp[5 * k]
80+
size_t k);
81+
82+
83+
#ifdef __cplusplus
84+
}
85+
#endif
86+
#endif

include/gmssl/ecdsa.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
10+
11+
#ifndef GMSSL_ECDSA_H
12+
#define GMSSL_ECDSA_H
13+
14+
15+
#include <string.h>
16+
#include <stdint.h>
17+
#include <stdlib.h>
18+
#include <gmssl/sha2.h>
19+
#include <gmssl/secp256r1_key.h>
20+
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
27+
typedef struct {
28+
secp256r1_t r;
29+
secp256r1_t s;
30+
} ECDSA_SIGNATURE;
31+
32+
#define ECDSA_SIGNATURE_COMPACT_SIZE 70
33+
#define ECDSA_SIGNATURE_TYPICAL_SIZE 71
34+
#define ECDSA_SIGNATURE_MAX_SIZE 72
35+
36+
int ecdsa_signature_to_der(const ECDSA_SIGNATURE *sig, uint8_t **out, size_t *outlen);
37+
int ecdsa_signature_from_der(ECDSA_SIGNATURE *sig, const uint8_t **in, size_t *inlen);
38+
int ecdsa_signature_print_ex(FILE *fp, int fmt, int ind, const char *label, const ECDSA_SIGNATURE *sig);
39+
int ecdsa_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
40+
41+
int ecdsa_do_sign_ex(const SECP256R1_KEY *key, const secp256r1_t k, const uint8_t dgst[32], ECDSA_SIGNATURE *sig);
42+
int ecdsa_do_sign(const SECP256R1_KEY *key, const uint8_t dgst[32], ECDSA_SIGNATURE *sig);
43+
int ecdsa_do_verify(const SECP256R1_KEY *key, const uint8_t dgst[32], const ECDSA_SIGNATURE *sig);
44+
int ecdsa_sign(const SECP256R1_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen);
45+
int ecdsa_sign_fixlen(const SECP256R1_KEY *key, const uint8_t dgst[32], size_t siglen, uint8_t *sig);
46+
int ecdsa_verify(const SECP256R1_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen);
47+
48+
49+
typedef struct {
50+
SHA256_CTX sha256_ctx;
51+
SECP256R1_KEY key;
52+
ECDSA_SIGNATURE sig;
53+
} ECDSA_SIGN_CTX;
54+
55+
int ecdsa_sign_init(ECDSA_SIGN_CTX *ctx, const SECP256R1_KEY *key);
56+
int ecdsa_sign_update(ECDSA_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
57+
int ecdsa_sign_finish(ECDSA_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen);
58+
int ecdsa_sign_finish_fixlen(ECDSA_SIGN_CTX *ctx, size_t siglen, uint8_t *sig);
59+
int ecdsa_verify_init(ECDSA_SIGN_CTX *ctx, const SECP256R1_KEY *key, const uint8_t *sig, size_t siglen);
60+
int ecdsa_verify_update(ECDSA_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
61+
int ecdsa_verify_finish(ECDSA_SIGN_CTX *ctx);
62+
63+
64+
65+
#ifdef __cplusplus
66+
}
67+
#endif
68+
#endif

include/gmssl/oid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ enum {
210210

211211

212212

213+
#define OID_secp256r1 OID_prime256v1
213214

214215

215216
#define oid_cnt(nodes) (sizeof(nodes)/sizeof((nodes)[0]))

include/gmssl/secp256r1.h

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
10+
11+
12+
#ifndef GMSSL_SECP256R1_H
13+
#define GMSSL_SECP256R1_H
14+
15+
16+
#include <stdio.h>
17+
#include <stdint.h>
18+
#include <stdlib.h>
19+
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
26+
// p = 2^256 - 2^224 + 2^192 + 2^96 - 1
27+
// = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
28+
// a = -3
29+
// b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
30+
// x = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
31+
// y = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5
32+
// n = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551
33+
// h = 1
34+
35+
36+
typedef uint32_t secp256r1_t[8];
37+
38+
#define SECP256R1_K (sizeof(secp256r1_t)/sizeof(uint32_t))
39+
40+
extern const secp256r1_t SECP256R1_P;
41+
extern const secp256r1_t SECP256R1_B;
42+
extern const secp256r1_t SECP256R1_N;
43+
extern const uint32_t SECP256R1_U_P[9];
44+
extern const uint32_t SECP256R1_U_N[9];
45+
46+
int secp256r1_is_zero(const secp256r1_t a);
47+
int secp256r1_is_one(const secp256r1_t a);
48+
int secp256r1_cmp(const secp256r1_t a, const secp256r1_t b);
49+
void secp256r1_set_zero(secp256r1_t r);
50+
void secp256r1_set_one(secp256r1_t r);
51+
void secp256r1_copy(secp256r1_t r, const secp256r1_t a);
52+
void secp256r1_to_32bytes(const secp256r1_t a, uint8_t out[32]);
53+
void secp256r1_from_32bytes(secp256r1_t r, const uint8_t in[32]);
54+
int secp256r1_print(FILE *fp, int fmt, int ind, const char *label, const secp256r1_t a);
55+
56+
void secp256r1_modp_add(secp256r1_t r, const secp256r1_t a, const secp256r1_t b);
57+
void secp256r1_modp_dbl(secp256r1_t r, const secp256r1_t a);
58+
void secp256r1_modp_tri(secp256r1_t r, const secp256r1_t a);
59+
void secp256r1_modp_sub(secp256r1_t r, const secp256r1_t a, const secp256r1_t b);
60+
void secp256r1_modp_neg(secp256r1_t r, const secp256r1_t a);
61+
void secp256r1_modp_haf(secp256r1_t r, const secp256r1_t a);
62+
void secp256r1_modp_mul(secp256r1_t r, const secp256r1_t a, const secp256r1_t b);
63+
void secp256r1_modp_sqr(secp256r1_t r, const secp256r1_t a);
64+
void secp256r1_modp_exp(secp256r1_t r, const secp256r1_t a, const secp256r1_t e);
65+
void secp256r1_modp_inv(secp256r1_t r, const secp256r1_t a);
66+
67+
void secp256r1_modn(secp256r1_t r, const secp256r1_t a);
68+
void secp256r1_modn_add(secp256r1_t r, const secp256r1_t a, const secp256r1_t b);
69+
void secp256r1_modn_dbl(secp256r1_t r, const secp256r1_t a);
70+
void secp256r1_modn_tri(secp256r1_t r, const secp256r1_t a);
71+
void secp256r1_modn_sub(secp256r1_t r, const secp256r1_t a, const secp256r1_t b);
72+
void secp256r1_modn_neg(secp256r1_t r, const secp256r1_t a);
73+
void secp256r1_modn_mul(secp256r1_t r, const secp256r1_t a, const secp256r1_t b);
74+
void secp256r1_modn_sqr(secp256r1_t r, const secp256r1_t a);
75+
void secp256r1_modn_exp(secp256r1_t r, const secp256r1_t a, const secp256r1_t e);
76+
void secp256r1_modn_inv(secp256r1_t r, const secp256r1_t a);
77+
78+
79+
typedef struct {
80+
secp256r1_t X;
81+
secp256r1_t Y;
82+
secp256r1_t Z;
83+
} SECP256R1_POINT;
84+
85+
extern const SECP256R1_POINT SECP256R1_POINT_G;
86+
87+
void secp256r1_point_set_infinity(SECP256R1_POINT *R);
88+
int secp256r1_point_is_at_infinity(const SECP256R1_POINT *P);
89+
int secp256r1_point_is_on_curve(const SECP256R1_POINT *P);
90+
int secp256r1_point_equ(const SECP256R1_POINT *P, const SECP256R1_POINT *Q);
91+
int secp256r1_point_set_xy(SECP256R1_POINT *R, const secp256r1_t x, const secp256r1_t y);
92+
int secp256r1_point_get_xy(const SECP256R1_POINT *P, secp256r1_t x, secp256r1_t y);
93+
void secp256r1_point_copy(SECP256R1_POINT *R, const SECP256R1_POINT *P);
94+
void secp256r1_point_dbl(SECP256R1_POINT *R, const SECP256R1_POINT *P);
95+
void secp256r1_point_add(SECP256R1_POINT *R, const SECP256R1_POINT *P, const SECP256R1_POINT *Q);
96+
void secp256r1_point_neg(SECP256R1_POINT *R, const SECP256R1_POINT *P);
97+
void secp256r1_point_sub(SECP256R1_POINT *R, const SECP256R1_POINT *P, const SECP256R1_POINT *Q);
98+
void secp256r1_point_mul(SECP256R1_POINT *R, const secp256r1_t k, const SECP256R1_POINT *P);
99+
void secp256r1_point_mul_generator(SECP256R1_POINT *R, const secp256r1_t k);
100+
int secp256r1_point_print(FILE *fp, int fmt, int ind, const char *label, const SECP256R1_POINT *P);
101+
int secp256r1_point_to_uncompressed_octets(const SECP256R1_POINT *P, uint8_t octets[65]);
102+
int secp256r1_point_from_uncompressed_octets(SECP256R1_POINT *P, const uint8_t octets[65]);
103+
104+
105+
#ifdef __cplusplus
106+
}
107+
#endif
108+
#endif

include/gmssl/secp256r1_key.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*/
9+
10+
#ifndef GMSSL_SECP256R1_KEY_H
11+
#define GMSSL_SECP256R1_KEY_H
12+
13+
14+
#include <stdio.h>
15+
#include <stdint.h>
16+
#include <stdlib.h>
17+
#include <gmssl/secp256r1.h>
18+
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
typedef struct {
25+
SECP256R1_POINT public_key;
26+
secp256r1_t private_key;
27+
} SECP256R1_KEY;
28+
29+
int secp256r1_key_generate(SECP256R1_KEY *key);
30+
int secp256r1_key_set_private_key(SECP256R1_KEY *key, const secp256r1_t private_key);
31+
int secp256r1_public_key_equ(const SECP256R1_KEY *key, const SECP256R1_KEY *pub);
32+
void secp256r1_key_cleanup(SECP256R1_KEY *key);
33+
34+
int secp256r1_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SECP256R1_KEY *key);
35+
int secp256r1_private_key_print(FILE *fp, int fmt, int ind, const char *label, const SECP256R1_KEY *key);
36+
37+
int secp256r1_public_key_to_bytes(const SECP256R1_KEY *key, uint8_t **out, size_t *outlen);
38+
int secp256r1_public_key_from_bytes(SECP256R1_KEY *key, const uint8_t **in, size_t *inlen);
39+
int secp256r1_public_key_to_der(const SECP256R1_KEY *key, uint8_t **out, size_t *outlen);
40+
int secp256r1_public_key_from_der(SECP256R1_KEY *key, const uint8_t **in, size_t *inlen);
41+
int secp256r1_private_key_to_der(const SECP256R1_KEY *key, uint8_t **out, size_t *outlen);
42+
int secp256r1_private_key_from_der(SECP256R1_KEY *key, const uint8_t **in, size_t *inlen);
43+
int secp256r1_private_key_info_to_der(const SECP256R1_KEY *key, uint8_t **out, size_t *outlen);
44+
int secp256r1_private_key_info_from_der(SECP256R1_KEY *key, const uint8_t **attrs, size_t *attrslen,
45+
const uint8_t **in, size_t *inlen);
46+
int secp256r1_private_key_info_encrypt_to_der(const SECP256R1_KEY *ec_key, const char *pass,
47+
uint8_t **out, size_t *outlen);
48+
int secp256r1_private_key_info_decrypt_from_der(SECP256R1_KEY *ec_key,
49+
const uint8_t **attrs, size_t *attrs_len,
50+
const char *pass, const uint8_t **in, size_t *inlen);
51+
52+
53+
#ifdef __cplusplus
54+
}
55+
#endif
56+
#endif

include/gmssl/tls.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,11 @@ typedef struct {
752752
BLOCK_CIPHER_KEY server_write_key;
753753

754754
int quiet;
755+
756+
// handshake state for state machine
757+
int state;
758+
SM3_CTX sm3_ctx;
759+
SM2_SIGN_CTX sign_ctx;
755760
} TLS_CONNECT;
756761

757762

0 commit comments

Comments
 (0)