1
2
3
4
5
6
7 package boring
8
9
10 import "C"
11 import (
12 "errors"
13 "runtime"
14 )
15
16 type ecdsaSignature struct {
17 R, S BigInt
18 }
19
20 type PrivateKeyECDSA struct {
21 key *C.GO_EC_KEY
22 }
23
24 func (k *PrivateKeyECDSA) finalize() {
25 C._goboringcrypto_EC_KEY_free(k.key)
26 }
27
28 type PublicKeyECDSA struct {
29 key *C.GO_EC_KEY
30 }
31
32 func (k *PublicKeyECDSA) finalize() {
33 C._goboringcrypto_EC_KEY_free(k.key)
34 }
35
36 var errUnknownCurve = errors.New("boringcrypto: unknown elliptic curve")
37
38 func curveNID(curve string) (C.int, error) {
39 switch curve {
40 case "P-224":
41 return C.GO_NID_secp224r1, nil
42 case "P-256":
43 return C.GO_NID_X9_62_prime256v1, nil
44 case "P-384":
45 return C.GO_NID_secp384r1, nil
46 case "P-521":
47 return C.GO_NID_secp521r1, nil
48 }
49 return 0, errUnknownCurve
50 }
51
52 func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) {
53 key, err := newECKey(curve, X, Y)
54 if err != nil {
55 return nil, err
56 }
57 k := &PublicKeyECDSA{key}
58
59
60
61
62 runtime.SetFinalizer(k, (*PublicKeyECDSA).finalize)
63 return k, nil
64 }
65
66 func newECKey(curve string, X, Y BigInt) (*C.GO_EC_KEY, error) {
67 nid, err := curveNID(curve)
68 if err != nil {
69 return nil, err
70 }
71 key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
72 if key == nil {
73 return nil, fail("EC_KEY_new_by_curve_name")
74 }
75 group := C._goboringcrypto_EC_KEY_get0_group(key)
76 pt := C._goboringcrypto_EC_POINT_new(group)
77 if pt == nil {
78 C._goboringcrypto_EC_KEY_free(key)
79 return nil, fail("EC_POINT_new")
80 }
81 bx := bigToBN(X)
82 by := bigToBN(Y)
83 ok := bx != nil && by != nil && C._goboringcrypto_EC_POINT_set_affine_coordinates_GFp(group, pt, bx, by, nil) != 0 &&
84 C._goboringcrypto_EC_KEY_set_public_key(key, pt) != 0
85 if bx != nil {
86 C._goboringcrypto_BN_free(bx)
87 }
88 if by != nil {
89 C._goboringcrypto_BN_free(by)
90 }
91 C._goboringcrypto_EC_POINT_free(pt)
92 if !ok {
93 C._goboringcrypto_EC_KEY_free(key)
94 return nil, fail("EC_POINT_set_affine_coordinates_GFp")
95 }
96 return key, nil
97 }
98
99 func NewPrivateKeyECDSA(curve string, X, Y BigInt, D BigInt) (*PrivateKeyECDSA, error) {
100 key, err := newECKey(curve, X, Y)
101 if err != nil {
102 return nil, err
103 }
104 bd := bigToBN(D)
105 ok := bd != nil && C._goboringcrypto_EC_KEY_set_private_key(key, bd) != 0
106 if bd != nil {
107 C._goboringcrypto_BN_free(bd)
108 }
109 if !ok {
110 C._goboringcrypto_EC_KEY_free(key)
111 return nil, fail("EC_KEY_set_private_key")
112 }
113 k := &PrivateKeyECDSA{key}
114
115
116
117
118 runtime.SetFinalizer(k, (*PrivateKeyECDSA).finalize)
119 return k, nil
120 }
121
122 func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
123 size := C._goboringcrypto_ECDSA_size(priv.key)
124 sig := make([]byte, size)
125 var sigLen C.uint
126 if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), base(sig), &sigLen, priv.key) == 0 {
127 return nil, fail("ECDSA_sign")
128 }
129 runtime.KeepAlive(priv)
130 return sig[:sigLen], nil
131 }
132
133 func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool {
134 ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), base(sig), C.size_t(len(sig)), pub.key) != 0
135 runtime.KeepAlive(pub)
136 return ok
137 }
138
139 func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) {
140 nid, err := curveNID(curve)
141 if err != nil {
142 return nil, nil, nil, err
143 }
144 key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
145 if key == nil {
146 return nil, nil, nil, fail("EC_KEY_new_by_curve_name")
147 }
148 defer C._goboringcrypto_EC_KEY_free(key)
149 if C._goboringcrypto_EC_KEY_generate_key_fips(key) == 0 {
150 return nil, nil, nil, fail("EC_KEY_generate_key_fips")
151 }
152 group := C._goboringcrypto_EC_KEY_get0_group(key)
153 pt := C._goboringcrypto_EC_KEY_get0_public_key(key)
154 bd := C._goboringcrypto_EC_KEY_get0_private_key(key)
155 if pt == nil || bd == nil {
156 return nil, nil, nil, fail("EC_KEY_get0_private_key")
157 }
158 bx := C._goboringcrypto_BN_new()
159 if bx == nil {
160 return nil, nil, nil, fail("BN_new")
161 }
162 defer C._goboringcrypto_BN_free(bx)
163 by := C._goboringcrypto_BN_new()
164 if by == nil {
165 return nil, nil, nil, fail("BN_new")
166 }
167 defer C._goboringcrypto_BN_free(by)
168 if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 {
169 return nil, nil, nil, fail("EC_POINT_get_affine_coordinates_GFp")
170 }
171 return bnToBig(bx), bnToBig(by), bnToBig(bd), nil
172 }
173
View as plain text