Skip to content

Commit

Permalink
Merge branch 'fix_420'
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Jun 22, 2020
2 parents f239e44 + ac4a565 commit c10d729
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
20 changes: 20 additions & 0 deletions lib/Crypto/SelfTest/Cipher/test_CBC.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,26 @@ def test_output_param(self):
self.assertEqual(pt, output)
self.assertEqual(res, None)


def test_output_param_same_buffer(self):

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

pt_ba = bytearray(pt)
cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
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)
self.assertEqual(pt, ct_ba)
self.assertEqual(res, None)


def test_output_param_memoryview(self):

pt = b'5' * 16
Expand Down
3 changes: 3 additions & 0 deletions lib/Crypto/SelfTest/Cipher/test_OpenPGP.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ def test_unaligned_data_64(self):
def test_output_param(self):
pass

def test_output_param_same_buffer(self):
pass

def test_output_param_memoryview(self):
pass

Expand Down
30 changes: 26 additions & 4 deletions src/raw_cfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,44 @@ static int CFB_transcrypt(CfbModeState *cfbState,
if (0 != result)
return result;

/* Reset */
/* The next input to the cipher is:
* - the old input shifted left by the segment length
* - filled on the right with the enough ciphertext
*
* If the segment length equals the block length,
* the next input is simply the ciphertext block.
*
* If the segment length equals 1, only the leftmost
* byte of the ciphertext block is used.
*/
memmove(next_iv, next_iv + segment_len, block_len - segment_len);

/*
* The rest of the next input is copied when enough ciphertext is
* available (we need segment_len bytes).
*/
cfbState->usedKeyStream = 0;
}

keyStream = cfbState->keyStream + cfbState->usedKeyStream;
segment = next_iv + block_len - segment_len + cfbState->usedKeyStream;
keyStreamToUse = MIN(segment_len - cfbState->usedKeyStream, data_len);

for (i=0; i<keyStreamToUse; i++, cfbState->usedKeyStream++) {
segment = next_iv + (block_len - (segment_len - cfbState->usedKeyStream));

if (direction == DirDecrypt) {
memcpy(segment, in, keyStreamToUse);
}

for (i=0; i<keyStreamToUse; i++) {
*out++ = *keyStream++ ^ *in++;
}

memcpy(segment, (direction == DirEncrypt ? out : in) - keyStreamToUse, keyStreamToUse);
if (direction == DirEncrypt) {
memcpy(segment, out - keyStreamToUse, keyStreamToUse);
}

data_len -= keyStreamToUse;
cfbState->usedKeyStream += keyStreamToUse;
}

return 0;
Expand Down

0 comments on commit c10d729

Please sign in to comment.