diff options
Diffstat (limited to 'meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre2.patch')
-rw-r--r-- | meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre2.patch | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre2.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre2.patch new file mode 100644 index 0000000000..1327b44545 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre2.patch | |||
@@ -0,0 +1,401 @@ | |||
1 | From c9d5f60eaa4450ccf1ce878d55b4c6a12843f2f3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Filippo Valsorda <filippo@golang.org> | ||
3 | Date: Mon, 27 Apr 2020 21:52:38 -0400 | ||
4 | Subject: [PATCH] math/big: add (*Int).FillBytes | ||
5 | |||
6 | Replaced almost every use of Bytes with FillBytes. | ||
7 | |||
8 | Note that the approved proposal was for | ||
9 | |||
10 | func (*Int) FillBytes(buf []byte) | ||
11 | |||
12 | while this implements | ||
13 | |||
14 | func (*Int) FillBytes(buf []byte) []byte | ||
15 | |||
16 | because the latter was far nicer to use in all callsites. | ||
17 | |||
18 | Fixes #35833 | ||
19 | |||
20 | Change-Id: Ia912df123e5d79b763845312ea3d9a8051343c0a | ||
21 | Reviewed-on: https://go-review.googlesource.com/c/go/+/230397 | ||
22 | Reviewed-by: Robert Griesemer <gri@golang.org> | ||
23 | |||
24 | Upstream-Status: Backport [https://github.com/golang/go/commit/c9d5f60eaa4450ccf1ce878d55b4c6a12843f2f3] | ||
25 | CVE: CVE-2023-45287 #Dependency Patch2 | ||
26 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
27 | --- | ||
28 | src/crypto/elliptic/elliptic.go | 13 ++++---- | ||
29 | src/crypto/rsa/pkcs1v15.go | 20 +++--------- | ||
30 | src/crypto/rsa/pss.go | 17 +++++------ | ||
31 | src/crypto/rsa/rsa.go | 32 +++---------------- | ||
32 | src/crypto/tls/key_schedule.go | 7 ++--- | ||
33 | src/crypto/x509/sec1.go | 7 ++--- | ||
34 | src/math/big/int.go | 15 +++++++++ | ||
35 | src/math/big/int_test.go | 54 +++++++++++++++++++++++++++++++++ | ||
36 | src/math/big/nat.go | 15 ++++++--- | ||
37 | 9 files changed, 106 insertions(+), 74 deletions(-) | ||
38 | |||
39 | diff --git a/src/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go | ||
40 | index e2f71cdb63bab..bd5168c5fd842 100644 | ||
41 | --- a/src/crypto/elliptic/elliptic.go | ||
42 | +++ b/src/crypto/elliptic/elliptic.go | ||
43 | @@ -277,7 +277,7 @@ var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f} | ||
44 | func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) { | ||
45 | N := curve.Params().N | ||
46 | bitSize := N.BitLen() | ||
47 | - byteLen := (bitSize + 7) >> 3 | ||
48 | + byteLen := (bitSize + 7) / 8 | ||
49 | priv = make([]byte, byteLen) | ||
50 | |||
51 | for x == nil { | ||
52 | @@ -304,15 +304,14 @@ func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err e | ||
53 | |||
54 | // Marshal converts a point into the uncompressed form specified in section 4.3.6 of ANSI X9.62. | ||
55 | func Marshal(curve Curve, x, y *big.Int) []byte { | ||
56 | - byteLen := (curve.Params().BitSize + 7) >> 3 | ||
57 | + byteLen := (curve.Params().BitSize + 7) / 8 | ||
58 | |||
59 | ret := make([]byte, 1+2*byteLen) | ||
60 | ret[0] = 4 // uncompressed point | ||
61 | |||
62 | - xBytes := x.Bytes() | ||
63 | - copy(ret[1+byteLen-len(xBytes):], xBytes) | ||
64 | - yBytes := y.Bytes() | ||
65 | - copy(ret[1+2*byteLen-len(yBytes):], yBytes) | ||
66 | + x.FillBytes(ret[1 : 1+byteLen]) | ||
67 | + y.FillBytes(ret[1+byteLen : 1+2*byteLen]) | ||
68 | + | ||
69 | return ret | ||
70 | } | ||
71 | |||
72 | @@ -320,7 +319,7 @@ func Marshal(curve Curve, x, y *big.Int) []byte { | ||
73 | // It is an error if the point is not in uncompressed form or is not on the curve. | ||
74 | // On error, x = nil. | ||
75 | func Unmarshal(curve Curve, data []byte) (x, y *big.Int) { | ||
76 | - byteLen := (curve.Params().BitSize + 7) >> 3 | ||
77 | + byteLen := (curve.Params().BitSize + 7) / 8 | ||
78 | if len(data) != 1+2*byteLen { | ||
79 | return | ||
80 | } | ||
81 | diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go | ||
82 | index 499242ffc5b57..3208119ae1ff4 100644 | ||
83 | --- a/src/crypto/rsa/pkcs1v15.go | ||
84 | +++ b/src/crypto/rsa/pkcs1v15.go | ||
85 | @@ -61,8 +61,7 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error) | ||
86 | m := new(big.Int).SetBytes(em) | ||
87 | c := encrypt(new(big.Int), pub, m) | ||
88 | |||
89 | - copyWithLeftPad(em, c.Bytes()) | ||
90 | - return em, nil | ||
91 | + return c.FillBytes(em), nil | ||
92 | } | ||
93 | |||
94 | // DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5. | ||
95 | @@ -150,7 +149,7 @@ func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid | ||
96 | return | ||
97 | } | ||
98 | |||
99 | - em = leftPad(m.Bytes(), k) | ||
100 | + em = m.FillBytes(make([]byte, k)) | ||
101 | firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0) | ||
102 | secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2) | ||
103 | |||
104 | @@ -256,8 +255,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b | ||
105 | return nil, err | ||
106 | } | ||
107 | |||
108 | - copyWithLeftPad(em, c.Bytes()) | ||
109 | - return em, nil | ||
110 | + return c.FillBytes(em), nil | ||
111 | } | ||
112 | |||
113 | // VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature. | ||
114 | @@ -286,7 +284,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) | ||
115 | |||
116 | c := new(big.Int).SetBytes(sig) | ||
117 | m := encrypt(new(big.Int), pub, c) | ||
118 | - em := leftPad(m.Bytes(), k) | ||
119 | + em := m.FillBytes(make([]byte, k)) | ||
120 | // EM = 0x00 || 0x01 || PS || 0x00 || T | ||
121 | |||
122 | ok := subtle.ConstantTimeByteEq(em[0], 0) | ||
123 | @@ -323,13 +321,3 @@ func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, | ||
124 | } | ||
125 | return | ||
126 | } | ||
127 | - | ||
128 | -// copyWithLeftPad copies src to the end of dest, padding with zero bytes as | ||
129 | -// needed. | ||
130 | -func copyWithLeftPad(dest, src []byte) { | ||
131 | - numPaddingBytes := len(dest) - len(src) | ||
132 | - for i := 0; i < numPaddingBytes; i++ { | ||
133 | - dest[i] = 0 | ||
134 | - } | ||
135 | - copy(dest[numPaddingBytes:], src) | ||
136 | -} | ||
137 | diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go | ||
138 | index f9844d87329a8..b2adbedb28fa8 100644 | ||
139 | --- a/src/crypto/rsa/pss.go | ||
140 | +++ b/src/crypto/rsa/pss.go | ||
141 | @@ -207,20 +207,19 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error { | ||
142 | // Note that hashed must be the result of hashing the input message using the | ||
143 | // given hash function. salt is a random sequence of bytes whose length will be | ||
144 | // later used to verify the signature. | ||
145 | -func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) { | ||
146 | +func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([]byte, error) { | ||
147 | emBits := priv.N.BitLen() - 1 | ||
148 | em, err := emsaPSSEncode(hashed, emBits, salt, hash.New()) | ||
149 | if err != nil { | ||
150 | - return | ||
151 | + return nil, err | ||
152 | } | ||
153 | m := new(big.Int).SetBytes(em) | ||
154 | c, err := decryptAndCheck(rand, priv, m) | ||
155 | if err != nil { | ||
156 | - return | ||
157 | + return nil, err | ||
158 | } | ||
159 | - s = make([]byte, priv.Size()) | ||
160 | - copyWithLeftPad(s, c.Bytes()) | ||
161 | - return | ||
162 | + s := make([]byte, priv.Size()) | ||
163 | + return c.FillBytes(s), nil | ||
164 | } | ||
165 | |||
166 | const ( | ||
167 | @@ -296,11 +295,9 @@ func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts | ||
168 | m := encrypt(new(big.Int), pub, s) | ||
169 | emBits := pub.N.BitLen() - 1 | ||
170 | emLen := (emBits + 7) / 8 | ||
171 | - emBytes := m.Bytes() | ||
172 | - if emLen < len(emBytes) { | ||
173 | + if m.BitLen() > emLen*8 { | ||
174 | return ErrVerification | ||
175 | } | ||
176 | - em := make([]byte, emLen) | ||
177 | - copyWithLeftPad(em, emBytes) | ||
178 | + em := m.FillBytes(make([]byte, emLen)) | ||
179 | return emsaPSSVerify(digest, em, emBits, opts.saltLength(), hash.New()) | ||
180 | } | ||
181 | diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go | ||
182 | index b4bfa13defbdf..28eb5926c1a54 100644 | ||
183 | --- a/src/crypto/rsa/rsa.go | ||
184 | +++ b/src/crypto/rsa/rsa.go | ||
185 | @@ -416,16 +416,9 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l | ||
186 | m := new(big.Int) | ||
187 | m.SetBytes(em) | ||
188 | c := encrypt(new(big.Int), pub, m) | ||
189 | - out := c.Bytes() | ||
190 | |||
191 | - if len(out) < k { | ||
192 | - // If the output is too small, we need to left-pad with zeros. | ||
193 | - t := make([]byte, k) | ||
194 | - copy(t[k-len(out):], out) | ||
195 | - out = t | ||
196 | - } | ||
197 | - | ||
198 | - return out, nil | ||
199 | + out := make([]byte, k) | ||
200 | + return c.FillBytes(out), nil | ||
201 | } | ||
202 | |||
203 | // ErrDecryption represents a failure to decrypt a message. | ||
204 | @@ -597,12 +590,9 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext | ||
205 | lHash := hash.Sum(nil) | ||
206 | hash.Reset() | ||
207 | |||
208 | - // Converting the plaintext number to bytes will strip any | ||
209 | - // leading zeros so we may have to left pad. We do this unconditionally | ||
210 | - // to avoid leaking timing information. (Although we still probably | ||
211 | - // leak the number of leading zeros. It's not clear that we can do | ||
212 | - // anything about this.) | ||
213 | - em := leftPad(m.Bytes(), k) | ||
214 | + // We probably leak the number of leading zeros. | ||
215 | + // It's not clear that we can do anything about this. | ||
216 | + em := m.FillBytes(make([]byte, k)) | ||
217 | |||
218 | firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0) | ||
219 | |||
220 | @@ -643,15 +633,3 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext | ||
221 | |||
222 | return rest[index+1:], nil | ||
223 | } | ||
224 | - | ||
225 | -// leftPad returns a new slice of length size. The contents of input are right | ||
226 | -// aligned in the new slice. | ||
227 | -func leftPad(input []byte, size int) (out []byte) { | ||
228 | - n := len(input) | ||
229 | - if n > size { | ||
230 | - n = size | ||
231 | - } | ||
232 | - out = make([]byte, size) | ||
233 | - copy(out[len(out)-n:], input) | ||
234 | - return | ||
235 | -} | ||
236 | diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go | ||
237 | index 2aab323202f7d..314016979afb8 100644 | ||
238 | --- a/src/crypto/tls/key_schedule.go | ||
239 | +++ b/src/crypto/tls/key_schedule.go | ||
240 | @@ -173,11 +173,8 @@ func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte { | ||
241 | } | ||
242 | |||
243 | xShared, _ := curve.ScalarMult(x, y, p.privateKey) | ||
244 | - sharedKey := make([]byte, (curve.Params().BitSize+7)>>3) | ||
245 | - xBytes := xShared.Bytes() | ||
246 | - copy(sharedKey[len(sharedKey)-len(xBytes):], xBytes) | ||
247 | - | ||
248 | - return sharedKey | ||
249 | + sharedKey := make([]byte, (curve.Params().BitSize+7)/8) | ||
250 | + return xShared.FillBytes(sharedKey) | ||
251 | } | ||
252 | |||
253 | type x25519Parameters struct { | ||
254 | diff --git a/src/crypto/x509/sec1.go b/src/crypto/x509/sec1.go | ||
255 | index 0bfb90cd5464a..52c108ff1d624 100644 | ||
256 | --- a/src/crypto/x509/sec1.go | ||
257 | +++ b/src/crypto/x509/sec1.go | ||
258 | @@ -52,13 +52,10 @@ func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { | ||
259 | // marshalECPrivateKey marshals an EC private key into ASN.1, DER format and | ||
260 | // sets the curve ID to the given OID, or omits it if OID is nil. | ||
261 | func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) { | ||
262 | - privateKeyBytes := key.D.Bytes() | ||
263 | - paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) | ||
264 | - copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes) | ||
265 | - | ||
266 | + privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) | ||
267 | return asn1.Marshal(ecPrivateKey{ | ||
268 | Version: 1, | ||
269 | - PrivateKey: paddedPrivateKey, | ||
270 | + PrivateKey: key.D.FillBytes(privateKey), | ||
271 | NamedCurveOID: oid, | ||
272 | PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, | ||
273 | }) | ||
274 | diff --git a/src/math/big/int.go b/src/math/big/int.go | ||
275 | index 8816cf5266cc4..65f32487b58c0 100644 | ||
276 | --- a/src/math/big/int.go | ||
277 | +++ b/src/math/big/int.go | ||
278 | @@ -447,11 +447,26 @@ func (z *Int) SetBytes(buf []byte) *Int { | ||
279 | } | ||
280 | |||
281 | // Bytes returns the absolute value of x as a big-endian byte slice. | ||
282 | +// | ||
283 | +// To use a fixed length slice, or a preallocated one, use FillBytes. | ||
284 | func (x *Int) Bytes() []byte { | ||
285 | buf := make([]byte, len(x.abs)*_S) | ||
286 | return buf[x.abs.bytes(buf):] | ||
287 | } | ||
288 | |||
289 | +// FillBytes sets buf to the absolute value of x, storing it as a zero-extended | ||
290 | +// big-endian byte slice, and returns buf. | ||
291 | +// | ||
292 | +// If the absolute value of x doesn't fit in buf, FillBytes will panic. | ||
293 | +func (x *Int) FillBytes(buf []byte) []byte { | ||
294 | + // Clear whole buffer. (This gets optimized into a memclr.) | ||
295 | + for i := range buf { | ||
296 | + buf[i] = 0 | ||
297 | + } | ||
298 | + x.abs.bytes(buf) | ||
299 | + return buf | ||
300 | +} | ||
301 | + | ||
302 | // BitLen returns the length of the absolute value of x in bits. | ||
303 | // The bit length of 0 is 0. | ||
304 | func (x *Int) BitLen() int { | ||
305 | diff --git a/src/math/big/int_test.go b/src/math/big/int_test.go | ||
306 | index e3a1587b3f0ad..3c8557323a032 100644 | ||
307 | --- a/src/math/big/int_test.go | ||
308 | +++ b/src/math/big/int_test.go | ||
309 | @@ -1840,3 +1840,57 @@ func BenchmarkDiv(b *testing.B) { | ||
310 | }) | ||
311 | } | ||
312 | } | ||
313 | + | ||
314 | +func TestFillBytes(t *testing.T) { | ||
315 | + checkResult := func(t *testing.T, buf []byte, want *Int) { | ||
316 | + t.Helper() | ||
317 | + got := new(Int).SetBytes(buf) | ||
318 | + if got.CmpAbs(want) != 0 { | ||
319 | + t.Errorf("got 0x%x, want 0x%x: %x", got, want, buf) | ||
320 | + } | ||
321 | + } | ||
322 | + panics := func(f func()) (panic bool) { | ||
323 | + defer func() { panic = recover() != nil }() | ||
324 | + f() | ||
325 | + return | ||
326 | + } | ||
327 | + | ||
328 | + for _, n := range []string{ | ||
329 | + "0", | ||
330 | + "1000", | ||
331 | + "0xffffffff", | ||
332 | + "-0xffffffff", | ||
333 | + "0xffffffffffffffff", | ||
334 | + "0x10000000000000000", | ||
335 | + "0xabababababababababababababababababababababababababa", | ||
336 | + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", | ||
337 | + } { | ||
338 | + t.Run(n, func(t *testing.T) { | ||
339 | + t.Logf(n) | ||
340 | + x, ok := new(Int).SetString(n, 0) | ||
341 | + if !ok { | ||
342 | + panic("invalid test entry") | ||
343 | + } | ||
344 | + | ||
345 | + // Perfectly sized buffer. | ||
346 | + byteLen := (x.BitLen() + 7) / 8 | ||
347 | + buf := make([]byte, byteLen) | ||
348 | + checkResult(t, x.FillBytes(buf), x) | ||
349 | + | ||
350 | + // Way larger, checking all bytes get zeroed. | ||
351 | + buf = make([]byte, 100) | ||
352 | + for i := range buf { | ||
353 | + buf[i] = 0xff | ||
354 | + } | ||
355 | + checkResult(t, x.FillBytes(buf), x) | ||
356 | + | ||
357 | + // Too small. | ||
358 | + if byteLen > 0 { | ||
359 | + buf = make([]byte, byteLen-1) | ||
360 | + if !panics(func() { x.FillBytes(buf) }) { | ||
361 | + t.Errorf("expected panic for small buffer and value %x", x) | ||
362 | + } | ||
363 | + } | ||
364 | + }) | ||
365 | + } | ||
366 | +} | ||
367 | diff --git a/src/math/big/nat.go b/src/math/big/nat.go | ||
368 | index c31ec5156b81d..6a3989bf9d82b 100644 | ||
369 | --- a/src/math/big/nat.go | ||
370 | +++ b/src/math/big/nat.go | ||
371 | @@ -1476,19 +1476,26 @@ func (z nat) expNNMontgomery(x, y, m nat) nat { | ||
372 | } | ||
373 | |||
374 | // bytes writes the value of z into buf using big-endian encoding. | ||
375 | -// len(buf) must be >= len(z)*_S. The value of z is encoded in the | ||
376 | -// slice buf[i:]. The number i of unused bytes at the beginning of | ||
377 | -// buf is returned as result. | ||
378 | +// The value of z is encoded in the slice buf[i:]. If the value of z | ||
379 | +// cannot be represented in buf, bytes panics. The number i of unused | ||
380 | +// bytes at the beginning of buf is returned as result. | ||
381 | func (z nat) bytes(buf []byte) (i int) { | ||
382 | i = len(buf) | ||
383 | for _, d := range z { | ||
384 | for j := 0; j < _S; j++ { | ||
385 | i-- | ||
386 | - buf[i] = byte(d) | ||
387 | + if i >= 0 { | ||
388 | + buf[i] = byte(d) | ||
389 | + } else if byte(d) != 0 { | ||
390 | + panic("math/big: buffer too small to fit value") | ||
391 | + } | ||
392 | d >>= 8 | ||
393 | } | ||
394 | } | ||
395 | |||
396 | + if i < 0 { | ||
397 | + i = 0 | ||
398 | + } | ||
399 | for i < len(buf) && buf[i] == 0 { | ||
400 | i++ | ||
401 | } | ||