Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic if rc4 xor'ed buffer doesn't fit into output buffer #123

Merged
merged 2 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions rc4.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ func (c *RC4Cipher) XORKeyStream(dst, src []byte) {
if inexactOverlap(dst[:len(src)], src) {
panic("crypto/rc4: invalid buffer overlap")
}
// panic if len(dst) < len(src) with a runtime out of bound error,
// which is what crypto/rc4 does.
_ = dst[len(src)-1]
var outLen C.int
if C.go_openssl_EVP_EncryptUpdate(c.ctx, base(dst), &outLen, base(src), C.int(len(src))) != 1 {
panic("crypto/cipher: EncryptUpdate failed")
Expand Down
26 changes: 26 additions & 0 deletions rc4_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,32 @@ func TestRC4Block(t *testing.T) {
}
}

func TestRC4OutOfBoundsWrite(t *testing.T) {
if !openssl.SupportsRC4() {
t.Skip("RC4 is not supported")
}
// This cipherText is encrypted "0123456789"
cipherText := []byte{238, 41, 187, 114, 151, 2, 107, 13, 178, 63}
cipher, err := openssl.NewRC4Cipher([]byte{0})
if err != nil {
panic(err)
}
want := "abcdefghij"
plainText := []byte(want)
shorterLen := len(cipherText) / 2
defer func() {
err := recover()
if err == nil {
t.Error("XORKeyStream expected to panic on len(dst) < len(src), but didn't")
}
const plain = "0123456789"
if plainText[shorterLen] == plain[shorterLen] {
t.Errorf("XORKeyStream did out of bounds write, want %v, got %v", want, string(plainText))
}
}()
cipher.XORKeyStream(plainText[:shorterLen], cipherText)
}

func benchmarkRC4(b *testing.B, size int64) {
if !openssl.SupportsRC4() {
b.Skip("RC4 is not supported")
Expand Down