1
2
3
4
5 package ecdh
6
7 import (
8 "bytes"
9 "crypto/internal/boring"
10 "crypto/internal/fips140/ecdh"
11 "crypto/internal/fips140only"
12 "errors"
13 "io"
14 )
15
16 type nistCurve struct {
17 name string
18 generate func(io.Reader) (*ecdh.PrivateKey, error)
19 newPrivateKey func([]byte) (*ecdh.PrivateKey, error)
20 newPublicKey func(publicKey []byte) (*ecdh.PublicKey, error)
21 sharedSecret func(*ecdh.PrivateKey, *ecdh.PublicKey) (sharedSecret []byte, err error)
22 }
23
24 func (c *nistCurve) String() string {
25 return c.name
26 }
27
28 func (c *nistCurve) GenerateKey(rand io.Reader) (*PrivateKey, error) {
29 if boring.Enabled && rand == boring.RandReader {
30 key, bytes, err := boring.GenerateKeyECDH(c.name)
31 if err != nil {
32 return nil, err
33 }
34 pub, err := key.PublicKey()
35 if err != nil {
36 return nil, err
37 }
38 k := &PrivateKey{
39 curve: c,
40 privateKey: bytes,
41 publicKey: &PublicKey{curve: c, publicKey: pub.Bytes(), boring: pub},
42 boring: key,
43 }
44 return k, nil
45 }
46
47 if fips140only.Enabled && !fips140only.ApprovedRandomReader(rand) {
48 return nil, errors.New("crypto/ecdh: only crypto/rand.Reader is allowed in FIPS 140-only mode")
49 }
50
51 privateKey, err := c.generate(rand)
52 if err != nil {
53 return nil, err
54 }
55
56 k := &PrivateKey{
57 curve: c,
58 privateKey: privateKey.Bytes(),
59 fips: privateKey,
60 publicKey: &PublicKey{
61 curve: c,
62 publicKey: privateKey.PublicKey().Bytes(),
63 fips: privateKey.PublicKey(),
64 },
65 }
66 if boring.Enabled {
67 bk, err := boring.NewPrivateKeyECDH(c.name, k.privateKey)
68 if err != nil {
69 return nil, err
70 }
71 pub, err := bk.PublicKey()
72 if err != nil {
73 return nil, err
74 }
75 k.boring = bk
76 k.publicKey.boring = pub
77 }
78 return k, nil
79 }
80
81 func (c *nistCurve) NewPrivateKey(key []byte) (*PrivateKey, error) {
82 if boring.Enabled {
83 bk, err := boring.NewPrivateKeyECDH(c.name, key)
84 if err != nil {
85 return nil, errors.New("crypto/ecdh: invalid private key")
86 }
87 pub, err := bk.PublicKey()
88 if err != nil {
89 return nil, errors.New("crypto/ecdh: invalid private key")
90 }
91 k := &PrivateKey{
92 curve: c,
93 privateKey: bytes.Clone(key),
94 publicKey: &PublicKey{curve: c, publicKey: pub.Bytes(), boring: pub},
95 boring: bk,
96 }
97 return k, nil
98 }
99
100 fk, err := c.newPrivateKey(key)
101 if err != nil {
102 return nil, err
103 }
104 k := &PrivateKey{
105 curve: c,
106 privateKey: bytes.Clone(key),
107 fips: fk,
108 publicKey: &PublicKey{
109 curve: c,
110 publicKey: fk.PublicKey().Bytes(),
111 fips: fk.PublicKey(),
112 },
113 }
114 return k, nil
115 }
116
117 func (c *nistCurve) NewPublicKey(key []byte) (*PublicKey, error) {
118
119
120 if len(key) == 0 || key[0] != 4 {
121 return nil, errors.New("crypto/ecdh: invalid public key")
122 }
123 k := &PublicKey{
124 curve: c,
125 publicKey: bytes.Clone(key),
126 }
127 if boring.Enabled {
128 bk, err := boring.NewPublicKeyECDH(c.name, k.publicKey)
129 if err != nil {
130 return nil, errors.New("crypto/ecdh: invalid public key")
131 }
132 k.boring = bk
133 } else {
134 fk, err := c.newPublicKey(key)
135 if err != nil {
136 return nil, err
137 }
138 k.fips = fk
139 }
140 return k, nil
141 }
142
143 func (c *nistCurve) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) {
144
145
146
147
148
149
150
151 if boring.Enabled {
152 return boring.ECDH(local.boring, remote.boring)
153 }
154 return c.sharedSecret(local.fips, remote.fips)
155 }
156
157
158
159
160
161
162 func P256() Curve { return p256 }
163
164 var p256 = &nistCurve{
165 name: "P-256",
166 generate: func(r io.Reader) (*ecdh.PrivateKey, error) {
167 return ecdh.GenerateKey(ecdh.P256(), r)
168 },
169 newPrivateKey: func(b []byte) (*ecdh.PrivateKey, error) {
170 return ecdh.NewPrivateKey(ecdh.P256(), b)
171 },
172 newPublicKey: func(publicKey []byte) (*ecdh.PublicKey, error) {
173 return ecdh.NewPublicKey(ecdh.P256(), publicKey)
174 },
175 sharedSecret: func(priv *ecdh.PrivateKey, pub *ecdh.PublicKey) (sharedSecret []byte, err error) {
176 return ecdh.ECDH(ecdh.P256(), priv, pub)
177 },
178 }
179
180
181
182
183
184
185 func P384() Curve { return p384 }
186
187 var p384 = &nistCurve{
188 name: "P-384",
189 generate: func(r io.Reader) (*ecdh.PrivateKey, error) {
190 return ecdh.GenerateKey(ecdh.P384(), r)
191 },
192 newPrivateKey: func(b []byte) (*ecdh.PrivateKey, error) {
193 return ecdh.NewPrivateKey(ecdh.P384(), b)
194 },
195 newPublicKey: func(publicKey []byte) (*ecdh.PublicKey, error) {
196 return ecdh.NewPublicKey(ecdh.P384(), publicKey)
197 },
198 sharedSecret: func(priv *ecdh.PrivateKey, pub *ecdh.PublicKey) (sharedSecret []byte, err error) {
199 return ecdh.ECDH(ecdh.P384(), priv, pub)
200 },
201 }
202
203
204
205
206
207
208 func P521() Curve { return p521 }
209
210 var p521 = &nistCurve{
211 name: "P-521",
212 generate: func(r io.Reader) (*ecdh.PrivateKey, error) {
213 return ecdh.GenerateKey(ecdh.P521(), r)
214 },
215 newPrivateKey: func(b []byte) (*ecdh.PrivateKey, error) {
216 return ecdh.NewPrivateKey(ecdh.P521(), b)
217 },
218 newPublicKey: func(publicKey []byte) (*ecdh.PublicKey, error) {
219 return ecdh.NewPublicKey(ecdh.P521(), publicKey)
220 },
221 sharedSecret: func(priv *ecdh.PrivateKey, pub *ecdh.PublicKey) (sharedSecret []byte, err error) {
222 return ecdh.ECDH(ecdh.P521(), priv, pub)
223 },
224 }
225
View as plain text