[openssl-commits] [openssl] OpenSSL_1_1_0-stable update
Matt Caswell
matt at openssl.org
Wed Jan 25 15:09:48 UTC 2017
The branch OpenSSL_1_1_0-stable has been updated
via b8552dc80a611083754493283e72d51f3015753a (commit)
via 38a041a092fe50c5a9c76ea4f21be89ed086a8de (commit)
via 3258e29a385f4800440a96a16889035a83aff437 (commit)
via fd18736a6b970c9b772f9c1b3cda4adcd20c63e2 (commit)
via 6af62ee9af06d057f03ec2abc8b9dfd4ac11b16f (commit)
via d1257342e7dfcdb9e80d199396c58286c9056c1c (commit)
from 07cd2f84d1480ca714bc14233b3c023ba9874e9d (commit)
- Log -----------------------------------------------------------------
commit b8552dc80a611083754493283e72d51f3015753a
Author: Matt Caswell <matt at openssl.org>
Date: Wed Jan 25 15:01:43 2017 +0000
Remove assert from is_partially_overlapping()
This function is used to validate application supplied parameters. An
assert should be used to check for an error that is internal to OpenSSL.
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
(cherry picked from commit b153f0921bea38127de0b9440b0487db3004330d)
commit 38a041a092fe50c5a9c76ea4f21be89ed086a8de
Author: Matt Caswell <matt at openssl.org>
Date: Wed Jan 25 09:26:35 2017 +0000
Adjust in and in_len instead of donelen
Don't use the temp variable donelen in the non-aad fragmented code path.
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
(cherry picked from commit ef055ec536a3c6e698dd9f45b41d57a32366b4fa)
commit 3258e29a385f4800440a96a16889035a83aff437
Author: Matt Caswell <matt at openssl.org>
Date: Tue Jan 24 12:57:34 2017 +0000
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 at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
(cherry picked from commit 7141ba31969d0b378d08104a51f8f99b9187b9d5)
commit fd18736a6b970c9b772f9c1b3cda4adcd20c63e2
Author: Matt Caswell <matt at openssl.org>
Date: Mon Jan 23 12:45:33 2017 +0000
Update evp_test to make sure passing partial block to "Update" is ok
The previous commit fixed a bug where a partial block had been passed to
an "Update" function and it wasn't properly handled. We should catch this
type of error in evp_test.
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
(cherry picked from commit 0b96d77a62d8ac9a45ac1dda47560ced676b5b8d)
commit 6af62ee9af06d057f03ec2abc8b9dfd4ac11b16f
Author: Matt Caswell <matt at openssl.org>
Date: Mon Jan 23 12:44:48 2017 +0000
Properly handle a partial block in OCB mode
If we have previously been passed a partial block in an "Update" call then
make sure we properly increment the output buffer when we use it.
Fixes #2273
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
(cherry picked from commit 7c12c7b61c5b37c9dff930ccc68421fb7de00271)
commit d1257342e7dfcdb9e80d199396c58286c9056c1c
Author: Matt Caswell <matt at openssl.org>
Date: Mon Jan 23 12:43:59 2017 +0000
Don't use magic numbers in aes_ocb_cipher()
Lots of references to 16 replaced by AES_BLOCK_SIZE. Also a few other style
tweaks in that function
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2275)
(cherry picked from commit 0ba5a9eaa0a6ae7fc25ee70eefc1f4fbdaf09483)
-----------------------------------------------------------------------
Summary of changes:
crypto/evp/e_aes.c | 36 +++++++++++++------
crypto/evp/e_des3.c | 7 ++++
crypto/evp/evp_enc.c | 22 ++++++------
crypto/evp/evp_err.c | 3 ++
crypto/evp/evp_locl.h | 2 ++
include/openssl/evp.h | 3 ++
test/evp_test.c | 99 ++++++++++++++++++++++++++++++++++++++++++---------
7 files changed, 133 insertions(+), 39 deletions(-)
diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index f504c68..ab98150 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -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 */
@@ -2536,7 +2541,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (!octx->key_set)
return -1;
- if (in) {
+ if (in != NULL) {
/*
* Need to ensure we are only passing full blocks to low level OCB
* routines. We do it here rather than in EVP_EncryptUpdate/
@@ -2551,16 +2556,21 @@ 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;
+ }
}
/*
* If we've got a partially filled buffer from a previous call then
* use that data first
*/
- if (*buf_len) {
+ if (*buf_len > 0) {
unsigned int remaining;
- remaining = 16 - (*buf_len);
+ remaining = AES_BLOCK_SIZE - (*buf_len);
if (remaining > len) {
memcpy(buf + (*buf_len), in, len);
*(buf_len) += len;
@@ -2574,21 +2584,25 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
len -= remaining;
in += remaining;
if (out == NULL) {
- if (!CRYPTO_ocb128_aad(&octx->ocb, buf, 16))
+ if (!CRYPTO_ocb128_aad(&octx->ocb, buf, AES_BLOCK_SIZE))
return -1;
} else if (EVP_CIPHER_CTX_encrypting(ctx)) {
- if (!CRYPTO_ocb128_encrypt(&octx->ocb, buf, out, 16))
+ if (!CRYPTO_ocb128_encrypt(&octx->ocb, buf, out,
+ AES_BLOCK_SIZE))
return -1;
} else {
- if (!CRYPTO_ocb128_decrypt(&octx->ocb, buf, out, 16))
+ if (!CRYPTO_ocb128_decrypt(&octx->ocb, buf, out,
+ AES_BLOCK_SIZE))
return -1;
}
- written_len = 16;
+ written_len = AES_BLOCK_SIZE;
*buf_len = 0;
+ if (out != NULL)
+ out += AES_BLOCK_SIZE;
}
/* Do we have a partial block to handle at the end? */
- trailing_len = len % 16;
+ trailing_len = len % AES_BLOCK_SIZE;
/*
* If we've got some full blocks to handle, then process these first
@@ -2611,7 +2625,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
}
/* Handle any trailing partial block */
- if (trailing_len) {
+ if (trailing_len > 0) {
memcpy(buf, in, trailing_len);
*buf_len = trailing_len;
}
@@ -2622,7 +2636,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
* First of all empty the buffer of any partial block that we might
* have been provided - both for data and AAD
*/
- if (octx->data_buf_len) {
+ if (octx->data_buf_len > 0) {
if (EVP_CIPHER_CTX_encrypting(ctx)) {
if (!CRYPTO_ocb128_encrypt(&octx->ocb, octx->data_buf, out,
octx->data_buf_len))
@@ -2635,7 +2649,7 @@ static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
written_len = octx->data_buf_len;
octx->data_buf_len = 0;
}
- if (octx->aad_buf_len) {
+ if (octx->aad_buf_len > 0) {
if (!CRYPTO_ocb128_aad
(&octx->ocb, octx->aad_buf, octx->aad_buf_len))
return -1;
diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c
index a842913..da77936 100644
--- a/crypto/evp/e_des3.c
+++ b/crypto/evp/e_des3.c
@@ -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
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index bedc964..bb6dd67 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;
/*
@@ -287,7 +286,7 @@ static int is_partially_overlapping(const void *ptr1, const void *ptr2,
*/
int overlapped = (len > 0) & (diff != 0) & ((diff < (PTRDIFF_T)len) |
(diff > (0 - (PTRDIFF_T)len)));
- assert(!overlapped);
+
return overlapped;
}
@@ -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) {
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index 7fcbdcd..e32a1c0 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -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"},
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index 7f3526f..209577b 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -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);
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 8216a8f..01f51b7 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1455,11 +1455,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
diff --git a/test/evp_test.c b/test/evp_test.c
index e5d7c91..02ae0a5 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -880,12 +880,12 @@ static int cipher_test_parse(struct evp_test *t, const char *keyword,
}
static int cipher_test_enc(struct evp_test *t, int enc,
- size_t out_misalign, size_t inp_misalign)
+ size_t out_misalign, size_t inp_misalign, int frag)
{
struct cipher_data *cdat = t->data;
unsigned char *in, *out, *tmp = NULL;
- size_t in_len, out_len;
- int tmplen, tmpflen;
+ size_t in_len, out_len, donelen = 0;
+ int tmplen, chunklen, tmpflen;
EVP_CIPHER_CTX *ctx = NULL;
const char *err;
err = "INTERNAL_ERROR";
@@ -983,15 +983,63 @@ static int cipher_test_enc(struct evp_test *t, int enc,
}
}
if (cdat->aad) {
- if (!EVP_CipherUpdate(ctx, NULL, &tmplen, cdat->aad, cdat->aad_len)) {
- err = "AAD_SET_ERROR";
- goto err;
+ err = "AAD_SET_ERROR";
+ if (!frag) {
+ if (!EVP_CipherUpdate(ctx, NULL, &chunklen, cdat->aad,
+ cdat->aad_len))
+ goto err;
+ } else {
+ /*
+ * Supply the AAD in chunks less than the block size where possible
+ */
+ if (cdat->aad_len > 0) {
+ if (!EVP_CipherUpdate(ctx, NULL, &chunklen, cdat->aad, 1))
+ goto err;
+ donelen++;
+ }
+ if (cdat->aad_len > 2) {
+ if (!EVP_CipherUpdate(ctx, NULL, &chunklen, cdat->aad + donelen,
+ cdat->aad_len - 2))
+ goto err;
+ donelen += cdat->aad_len - 2;
+ }
+ if (cdat->aad_len > 1
+ && !EVP_CipherUpdate(ctx, NULL, &chunklen,
+ cdat->aad + donelen, 1))
+ goto err;
}
}
EVP_CIPHER_CTX_set_padding(ctx, 0);
err = "CIPHERUPDATE_ERROR";
- if (!EVP_CipherUpdate(ctx, tmp + out_misalign, &tmplen, in, in_len))
- goto err;
+ tmplen = 0;
+ if (!frag) {
+ /* We supply the data all in one go */
+ if (!EVP_CipherUpdate(ctx, tmp + out_misalign, &tmplen, in, in_len))
+ goto err;
+ } else {
+ /* Supply the data in chunks less than the block size where possible */
+ if (in_len > 0) {
+ if (!EVP_CipherUpdate(ctx, tmp + out_misalign, &chunklen, in, 1))
+ goto err;
+ tmplen += chunklen;
+ in++;
+ in_len--;
+ }
+ if (in_len > 1) {
+ if (!EVP_CipherUpdate(ctx, tmp + out_misalign + tmplen, &chunklen,
+ in, in_len - 1))
+ goto err;
+ tmplen += chunklen;
+ in += in_len - 1;
+ in_len = 1;
+ }
+ if (in_len > 0 ) {
+ if (!EVP_CipherUpdate(ctx, tmp + out_misalign + tmplen, &chunklen,
+ in, 1))
+ goto err;
+ tmplen += chunklen;
+ }
+ }
if (cdat->aead == EVP_CIPH_CCM_MODE)
tmpflen = 0;
else {
@@ -1032,7 +1080,7 @@ static int cipher_test_enc(struct evp_test *t, int enc,
static int cipher_test_run(struct evp_test *t)
{
struct cipher_data *cdat = t->data;
- int rv;
+ int rv, frag = 0;
size_t out_misalign, inp_misalign;
if (!cdat->key) {
@@ -1050,21 +1098,25 @@ static int cipher_test_run(struct evp_test *t)
t->err = "NO_TAG";
return 0;
}
- for (out_misalign = 0; out_misalign <= 1; out_misalign++) {
+ for (out_misalign = 0; out_misalign <= 1;) {
static char aux_err[64];
t->aux_err = aux_err;
for (inp_misalign = (size_t)-1; inp_misalign != 2; inp_misalign++) {
if (inp_misalign == (size_t)-1) {
/* kludge: inp_misalign == -1 means "exercise in-place" */
- BIO_snprintf(aux_err, sizeof(aux_err), "%s in-place",
- out_misalign ? "misaligned" : "aligned");
+ BIO_snprintf(aux_err, sizeof(aux_err),
+ "%s in-place, %sfragmented",
+ out_misalign ? "misaligned" : "aligned",
+ frag ? "" : "not ");
} else {
- BIO_snprintf(aux_err, sizeof(aux_err), "%s output and %s input",
+ BIO_snprintf(aux_err, sizeof(aux_err),
+ "%s output and %s input, %sfragmented",
out_misalign ? "misaligned" : "aligned",
- inp_misalign ? "misaligned" : "aligned");
+ inp_misalign ? "misaligned" : "aligned",
+ frag ? "" : "not ");
}
if (cdat->enc) {
- rv = cipher_test_enc(t, 1, out_misalign, inp_misalign);
+ rv = cipher_test_enc(t, 1, out_misalign, inp_misalign, frag);
/* Not fatal errors: return */
if (rv != 1) {
if (rv < 0)
@@ -1073,7 +1125,7 @@ static int cipher_test_run(struct evp_test *t)
}
}
if (cdat->enc != 1) {
- rv = cipher_test_enc(t, 0, out_misalign, inp_misalign);
+ rv = cipher_test_enc(t, 0, out_misalign, inp_misalign, frag);
/* Not fatal errors: return */
if (rv != 1) {
if (rv < 0)
@@ -1082,6 +1134,21 @@ static int cipher_test_run(struct evp_test *t)
}
}
}
+
+ if (out_misalign == 1 && frag == 0) {
+ /*
+ * XTS, CCM and Wrap modes have special requirements about input
+ * lengths so we don't fragment for those
+ */
+ if (cdat->aead == EVP_CIPH_CCM_MODE
+ || EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_XTS_MODE
+ || EVP_CIPHER_mode(cdat->cipher) == EVP_CIPH_WRAP_MODE)
+ break;
+ out_misalign = 0;
+ frag++;
+ } else {
+ out_misalign++;
+ }
}
t->aux_err = NULL;
More information about the openssl-commits
mailing list