diff options
author | Matt Caswell <matt@openssl.org> | 2017-01-24 12:57:34 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2017-01-25 15:02:44 +0000 |
commit | 7141ba31969d0b378d08104a51f8f99b9187b9d5 (patch) | |
tree | 58735ecf1d4e9b266e2b928f13d018d2118f05c3 /crypto/evp/evp_enc.c | |
parent | 0b96d77a62d8ac9a45ac1dda47560ced676b5b8d (diff) |
Fix the overlapping check for fragmented "Update" operations
When doing in place encryption the overlapping buffer check can fail
incorrectly where we have done a partial block "Update" operation. This
fixes things to take account of any pending partial blocks.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
Diffstat (limited to 'crypto/evp/evp_enc.c')
-rw-r--r-- | crypto/evp/evp_enc.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index bedc964361..ef66cb1de5 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -276,8 +276,7 @@ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, # define PTRDIFF_T size_t #endif -static int is_partially_overlapping(const void *ptr1, const void *ptr2, - int len) +int is_partially_overlapping(const void *ptr1, const void *ptr2, int len) { PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2; /* @@ -296,8 +295,11 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, { int i, j, bl; + bl = ctx->cipher->block_size; + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - if (is_partially_overlapping(out, in, inl)) { + /* If block size > 1 then the cipher will have to do this check */ + if (bl == 1 && is_partially_overlapping(out, in, inl)) { EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -314,7 +316,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, *outl = 0; return inl == 0; } - if (is_partially_overlapping(out, in, inl)) { + if (is_partially_overlapping(out + ctx->buf_len, in, inl)) { EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -329,7 +331,6 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, } } i = ctx->buf_len; - bl = ctx->cipher->block_size; OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); if (i != 0) { if (bl - i > inl) { @@ -342,10 +343,6 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, memcpy(&(ctx->buf[i]), in, j); inl -= j; in += j; - if (is_partially_overlapping(out, in, bl)) { - EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); - return 0; - } if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl)) return 0; out += bl; @@ -422,8 +419,10 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, int fix_len; unsigned int b; + b = ctx->cipher->block_size; + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - if (is_partially_overlapping(out, in, inl)) { + if (b == 1 && is_partially_overlapping(out, in, inl)) { EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING); return 0; } @@ -445,7 +444,6 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, if (ctx->flags & EVP_CIPH_NO_PADDING) return EVP_EncryptUpdate(ctx, out, outl, in, inl); - b = ctx->cipher->block_size; OPENSSL_assert(b <= sizeof ctx->final); if (ctx->final_used) { |