Skip to content

Commit

Permalink
GH#582 Fix incorrect CBC decryption when in/out use the same buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Dec 3, 2021
1 parent 052f7de commit d8671b9
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 18 deletions.
4 changes: 1 addition & 3 deletions lib/Crypto/SelfTest/Cipher/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,7 @@ def make_stream_tests(module, module_name, test_data):
ByteArrayTest(module, params),
]

import sys
if sys.version[:3] != '2.6':
tests.append(MemoryviewTest(module, params))
tests.append(MemoryviewTest(module, params))
extra_tests_added = True

# Add the test to the test suite
Expand Down
28 changes: 14 additions & 14 deletions lib/Crypto/SelfTest/Cipher/test_CBC.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def test_data_must_be_bytes(self):
self.assertRaises(TypeError, cipher.decrypt, u'test1234567890-*')

def test_bytearray(self):
data = b"1" * 16
data = b"1" * 128
data_ba = bytearray(data)

# Encrypt
Expand Down Expand Up @@ -201,7 +201,7 @@ def test_bytearray(self):
self.assertEqual(ref3, ref4)

def test_memoryview(self):
data = b"1" * 16
data = b"1" * 128
data_mv = memoryview(bytearray(data))

# Encrypt
Expand Down Expand Up @@ -232,19 +232,19 @@ def test_memoryview(self):
ref4 = cipher4.decrypt(data_mv)

self.assertEqual(ref3, ref4)

def test_output_param(self):

pt = b'5' * 16
pt = b'5' * 128
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
ct = cipher.encrypt(pt)

output = bytearray(16)
output = bytearray(128)
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
res = cipher.encrypt(pt, output=output)
self.assertEqual(ct, output)
self.assertEqual(res, None)

cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
res = cipher.decrypt(ct, output=output)
self.assertEqual(pt, output)
Expand All @@ -253,7 +253,7 @@ def test_output_param(self):

def test_output_param_same_buffer(self):

pt = b'5' * 16
pt = b'5' * 128
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
ct = cipher.encrypt(pt)

Expand All @@ -262,7 +262,7 @@ def test_output_param_same_buffer(self):
res = cipher.encrypt(pt_ba, output=pt_ba)
self.assertEqual(ct, pt_ba)
self.assertEqual(res, None)

ct_ba = bytearray(ct)
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
res = cipher.decrypt(ct_ba, output=ct_ba)
Expand All @@ -271,29 +271,29 @@ def test_output_param_same_buffer(self):


def test_output_param_memoryview(self):
pt = b'5' * 16

pt = b'5' * 128
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
ct = cipher.encrypt(pt)

output = memoryview(bytearray(16))
output = memoryview(bytearray(128))
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
cipher.encrypt(pt, output=output)
self.assertEqual(ct, output)

cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
cipher.decrypt(ct, output=output)
self.assertEqual(pt, output)

def test_output_param_neg(self):

pt = b'5' * 16
pt = b'5' * 128
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
ct = cipher.encrypt(pt)

cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)

cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)

Expand Down
3 changes: 2 additions & 1 deletion src/raw_cbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,10 @@ EXPORT_SYM int CBC_decrypt(CbcModeState *cbcState,
return result;

for (i=0; i<block_len; i++)
out[i] = pt[i] ^ iv[i];
pt[i] = pt[i] ^ iv[i];

memcpy(iv, in, block_len);
memcpy(out, pt, block_len);

data_len -= block_len;
in += block_len;
Expand Down

0 comments on commit d8671b9

Please sign in to comment.