diff options
author | Adam Langley <agl@google.com> | 2015-05-21 22:25:01 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2015-05-21 23:27:37 +0300 |
commit | 3d59e04bce96474099ba76786a2337e99ae14505 (patch) | |
tree | c19bede45d7474d319e193c6f3b2f1c1bc7d754a /crypto/modes | |
parent | 5f387e38fc406d6e341248865df61dd9d957171f (diff) |
Fix test used for not-in-place CBC mode.
With NO_ASM defined, the recent AEAD changes broke the tests. The
problem is that the generic CBC mode code tests whether in != out and
omits to save the IV, assuming that it'll be able to read the old
ciphertext block.
However, consider the case where out = in - 16:
1 2 3 4
|-------|-------|------|-------|
^ ^
| |
out in
First time around, 1 = decrypt(2) ^ iv and everything is fine, because
the IV was preconfigured. However, the next iteration of the loop sets
2 = decrypt(3) and tries to XOR it with the contents of the previous
ciphertext blockā¦ from 2.
Change-Id: Ibabff430704fad246de132b4d6d514f6a0362734
Diffstat (limited to 'crypto/modes')
-rw-r--r-- | crypto/modes/cbc.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/crypto/modes/cbc.c b/crypto/modes/cbc.c index ba4805b7..f0889ef4 100644 --- a/crypto/modes/cbc.c +++ b/crypto/modes/cbc.c @@ -121,7 +121,10 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, assert(in && out && key && ivec); - if (in != out) { + const uintptr_t inptr = (uintptr_t) in; + const uintptr_t outptr = (uintptr_t) out; + + if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) { const uint8_t *iv = ivec; if (STRICT_ALIGNMENT && |