1
0
mirror of https://github.com/golang/go synced 2024-11-23 00:10:07 -07:00

crypto/rsa: check for minimal PKCS#1 v1.5 padding.

The PKCS#1 spec requires that the PS padding in an RSA message be at
least 8 bytes long. We were not previously checking this. This isn't
important in the most common situation (session key encryption), but
the impact is unclear in other cases.

This change enforces the specified minimum size.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/9222045
This commit is contained in:
Adam Langley 2013-05-15 10:27:34 -04:00
parent a1dbfee15b
commit e85e678899
4 changed files with 41 additions and 1 deletions

View File

@ -124,7 +124,11 @@ func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid
lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
}
valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1)
// The PS padding must be at least 8 bytes long, and it starts two
// bytes into em.
validPS := subtle.ConstantTimeLessOrEq(2+8, index)
valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
msg = em[index+1:]
return
}

View File

@ -197,6 +197,14 @@ func TestVerifyPKCS1v15(t *testing.T) {
}
}
func TestOverlongMessagePKCS1v15(t *testing.T) {
ciphertext := decodeBase64("fjOVdirUzFoLlukv80dBllMLjXythIf22feqPrNo0YoIjzyzyoMFiLjAc/Y4krkeZ11XFThIrEvw\nkRiZcCq5ng==")
_, err := DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext)
if err == nil {
t.Error("RSA decrypted a message that was too long.")
}
}
// In order to generate new test vectors you'll need the PEM form of this key:
// -----BEGIN RSA PRIVATE KEY-----
// MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0

View File

@ -55,3 +55,11 @@ func ConstantTimeCopy(v int, x, y []byte) {
}
return
}
// ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise.
// Its behavior is undefined if x or y are negative or > 2**31 - 1.
func ConstantTimeLessOrEq(x, y int) int {
x32 := int32(x)
y32 := int32(y)
return int(((x32 - y32 - 1) >> 31) & 1)
}

View File

@ -103,3 +103,23 @@ func TestConstantTimeCopy(t *testing.T) {
t.Error(err)
}
}
var lessOrEqTests = []struct {
x, y, result int
}{
{0, 0, 1},
{1, 0, 0},
{0, 1, 1},
{10, 20, 1},
{20, 10, 0},
{10, 10, 1},
}
func TestConstantTimeLessOrEq(t *testing.T) {
for i, test := range lessOrEqTests {
result := ConstantTimeLessOrEq(test.x, test.y)
if result != test.result {
t.Errorf("#%d: %d <= %d gave %d, expected %d", i, test.x, test.y, result, test.result)
}
}
}