diff options
author | David Benjamin <davidben@chromium.org> | 2015-05-22 00:18:53 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2015-05-28 00:48:36 +0300 |
commit | 91af02a9dbaad24dd94236f0729116484cc974fb (patch) | |
tree | b6f72e508bfad60344490f736d2f36116ad2346b | |
parent | 74d8bc2503bf7dcb20f4358e50dd09f0a8e787cf (diff) |
Add some comments and tweak assertions for cbc.c.
See https://boringssl-review.googlesource.com/#/c/4832/.
Change-Id: Icf457a2b47bc2d5b84dddc454d5ca8ec328b5169
Reviewed-on: https://boringssl-review.googlesource.com/4860
Reviewed-by: Adam Langley <agl@google.com>
-rw-r--r-- | crypto/modes/cbc.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/crypto/modes/cbc.c b/crypto/modes/cbc.c index f0889ef4..931b718d 100644 --- a/crypto/modes/cbc.c +++ b/crypto/modes/cbc.c @@ -63,7 +63,8 @@ void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, size_t n; const uint8_t *iv = ivec; - assert(in && out && key && ivec); + assert(key != NULL && ivec != NULL); + assert(len == 0 || (in != NULL && out != NULL)); if (STRICT_ALIGNMENT && ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { @@ -119,12 +120,17 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, uint8_t c[16]; } tmp; - assert(in && out && key && ivec); + assert(key != NULL && ivec != NULL); + assert(len == 0 || (in != NULL && out != NULL)); const uintptr_t inptr = (uintptr_t) in; const uintptr_t outptr = (uintptr_t) out; + /* If |in| and |out| alias, |in| must be ahead. */ + assert(inptr >= outptr || inptr + len <= outptr); if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) { + /* If |out| is at least two blocks behind |in| or completely disjoint, there + * is no need to decrypt to a temporary block. */ const uint8_t *iv = ivec; if (STRICT_ALIGNMENT && @@ -155,6 +161,9 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, } memcpy(ivec, iv, 16); } else { + /* |out| is less than two blocks behind |in|. Decrypting an input block + * directly to |out| would overwrite a ciphertext block before it is used as + * the next block's IV. Decrypt to a temporary block instead. */ if (STRICT_ALIGNMENT && ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { uint8_t c; |