提交 7141ba31 编写于 作者: M Matt Caswell

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: NRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
上级 0b96d77a
......@@ -17,6 +17,7 @@
#include "internal/evp_int.h"
#include "modes_lcl.h"
#include <openssl/rand.h>
#include "evp_locl.h"
typedef struct {
union {
......@@ -2233,6 +2234,10 @@ static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
/* If not padding input must be multiple of 8 */
if (!pad && inlen & 0x7)
return -1;
if (is_partially_overlapping(out, in, inlen)) {
EVPerr(EVP_F_AES_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
if (!out) {
if (EVP_CIPHER_CTX_encrypting(ctx)) {
/* If padding round up to multiple of 8 */
......@@ -2551,6 +2556,11 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
} else {
buf = octx->data_buf;
buf_len = &(octx->data_buf_len);
if (is_partially_overlapping(out + *buf_len, in, len)) {
EVPerr(EVP_F_AES_OCB_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
}
/*
......
......@@ -15,6 +15,7 @@
# include "internal/evp_int.h"
# include <openssl/des.h>
# include <openssl/rand.h>
# include "evp_locl.h"
typedef struct {
union {
......@@ -392,6 +393,12 @@ static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
*/
if (inl >= EVP_MAXCHUNK || inl % 8)
return -1;
if (is_partially_overlapping(out, in, inl)) {
EVPerr(EVP_F_DES_EDE3_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
return 0;
}
if (EVP_CIPHER_CTX_encrypting(ctx))
return des_ede3_wrap(ctx, out, in, inl);
else
......
......@@ -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) {
......
......@@ -21,11 +21,14 @@
static ERR_STRING_DATA EVP_str_functs[] = {
{ERR_FUNC(EVP_F_AESNI_INIT_KEY), "aesni_init_key"},
{ERR_FUNC(EVP_F_AES_INIT_KEY), "aes_init_key"},
{ERR_FUNC(EVP_F_AES_OCB_CIPHER), "aes_ocb_cipher"},
{ERR_FUNC(EVP_F_AES_T4_INIT_KEY), "aes_t4_init_key"},
{ERR_FUNC(EVP_F_AES_WRAP_CIPHER), "aes_wrap_cipher"},
{ERR_FUNC(EVP_F_ALG_MODULE_INIT), "alg_module_init"},
{ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "camellia_init_key"},
{ERR_FUNC(EVP_F_CHACHA20_POLY1305_CTRL), "chacha20_poly1305_ctrl"},
{ERR_FUNC(EVP_F_CMLL_T4_INIT_KEY), "cmll_t4_init_key"},
{ERR_FUNC(EVP_F_DES_EDE3_WRAP_CIPHER), "des_ede3_wrap_cipher"},
{ERR_FUNC(EVP_F_DO_SIGVER_INIT), "do_sigver_init"},
{ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"},
{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"},
......
......@@ -64,3 +64,5 @@ struct evp_Encode_Ctx_st {
typedef struct evp_pbe_st EVP_PBE_CTL;
DEFINE_STACK_OF(EVP_PBE_CTL)
int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
......@@ -1467,11 +1467,14 @@ int ERR_load_EVP_strings(void);
/* Function codes. */
# define EVP_F_AESNI_INIT_KEY 165
# define EVP_F_AES_INIT_KEY 133
# define EVP_F_AES_OCB_CIPHER 169
# define EVP_F_AES_T4_INIT_KEY 178
# define EVP_F_AES_WRAP_CIPHER 170
# define EVP_F_ALG_MODULE_INIT 177
# define EVP_F_CAMELLIA_INIT_KEY 159
# define EVP_F_CHACHA20_POLY1305_CTRL 182
# define EVP_F_CMLL_T4_INIT_KEY 179
# define EVP_F_DES_EDE3_WRAP_CIPHER 171
# define EVP_F_DO_SIGVER_INIT 161
# define EVP_F_EVP_CIPHERINIT_EX 123
# define EVP_F_EVP_CIPHER_CTX_COPY 163
......
......@@ -1101,9 +1101,6 @@ static int cipher_test_run(struct evp_test *t)
static char aux_err[64];
t->aux_err = aux_err;
for (inp_misalign = (size_t)-1; inp_misalign != 2; inp_misalign++) {
if (frag && inp_misalign == (size_t)-1)
continue;
if (inp_misalign == (size_t)-1) {
/* kludge: inp_misalign == -1 means "exercise in-place" */
BIO_snprintf(aux_err, sizeof(aux_err),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册