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