summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--providers/implementations/ciphers/cipher_aes_ocb.c2
-rw-r--r--providers/implementations/ciphers/cipher_des.c1
-rw-r--r--providers/implementations/ciphers/cipher_tdes_common.c1
-rw-r--r--providers/implementations/ciphers/ciphercommon.c1
-rw-r--r--test/evp_libctx_test.c78
5 files changed, 83 insertions, 0 deletions
diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c
index 2f30b7ffdf..230b353c50 100644
--- a/providers/implementations/ciphers/cipher_aes_ocb.c
+++ b/providers/implementations/ciphers/cipher_aes_ocb.c
@@ -103,6 +103,8 @@ static int aes_ocb_init(void *vctx, const unsigned char *key, size_t keylen,
{
PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx;
+ ctx->aad_buf_len = 0;
+ ctx->data_buf_len = 0;
ctx->base.enc = enc;
if (iv != NULL) {
diff --git a/providers/implementations/ciphers/cipher_des.c b/providers/implementations/ciphers/cipher_des.c
index 9a7c13902f..4974234efd 100644
--- a/providers/implementations/ciphers/cipher_des.c
+++ b/providers/implementations/ciphers/cipher_des.c
@@ -68,6 +68,7 @@ static int des_init(void *vctx, const unsigned char *key, size_t keylen,
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
ctx->num = 0;
+ ctx->bufsz = 0;
ctx->enc = enc;
if (iv != NULL) {
diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c
index d2379f741b..a226e2aac4 100644
--- a/providers/implementations/ciphers/cipher_tdes_common.c
+++ b/providers/implementations/ciphers/cipher_tdes_common.c
@@ -58,6 +58,7 @@ static int tdes_init(void *vctx, const unsigned char *key, size_t keylen,
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
ctx->num = 0;
+ ctx->bufsz = 0;
ctx->enc = enc;
if (iv != NULL) {
diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c
index a3ebd3f7e7..2d119a7b39 100644
--- a/providers/implementations/ciphers/ciphercommon.c
+++ b/providers/implementations/ciphers/ciphercommon.c
@@ -150,6 +150,7 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
int enc)
{
ctx->num = 0;
+ ctx->bufsz = 0;
ctx->updated = 0;
ctx->enc = enc ? 1 : 0;
diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c
index 395c5d99b5..7421e1e3ca 100644
--- a/test/evp_libctx_test.c
+++ b/test/evp_libctx_test.c
@@ -268,6 +268,82 @@ err:
return ret;
}
+/*
+ * This test only uses a partial block (half the block size) of input for each
+ * EVP_EncryptUpdate() in order to test that the second init/update is not using
+ * a leftover buffer from the first init/update.
+ * Note: some ciphers don't need a full block to produce output.
+ */
+static int test_cipher_reinit_partialupdate(int test_id)
+{
+ int ret = 0, out1_len = 0, out2_len = 0, in_len;
+ EVP_CIPHER *cipher = NULL;
+ EVP_CIPHER_CTX *ctx = NULL;
+ unsigned char out1[256];
+ unsigned char out2[256];
+ static const unsigned char in[32] = {
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0xba, 0xbe, 0xba, 0xbe, 0x00, 0x00, 0xba, 0xbe,
+ 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ };
+ static const unsigned char key[64] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ };
+ static const unsigned char iv[16] = {
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
+ };
+ const char *name = sk_OPENSSL_CSTRING_value(cipher_names, test_id);
+
+ if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()))
+ goto err;
+
+ TEST_note("Fetching %s\n", name);
+ if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, name, NULL)))
+ goto err;
+
+ in_len = EVP_CIPHER_block_size(cipher) / 2;
+
+ /* skip any ciphers that don't allow partial updates */
+ if (((EVP_CIPHER_flags(cipher)
+ & (EVP_CIPH_FLAG_CTS | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) != 0)
+ || EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE
+ || EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE
+ || EVP_CIPHER_mode(cipher) == EVP_CIPH_WRAP_MODE) {
+ ret = 1;
+ goto err;
+ }
+
+ if (!TEST_true(EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv))
+ || !TEST_true(EVP_EncryptUpdate(ctx, out1, &out1_len, in, in_len))
+ || !TEST_true(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
+ || !TEST_true(EVP_EncryptUpdate(ctx, out2, &out2_len, in, in_len)))
+ goto err;
+
+ /* DES3-WRAP uses random every update - so it will give a different value */
+ if (EVP_CIPHER_is_a(cipher, "DES3-WRAP")) {
+ if (!TEST_mem_ne(out1, out1_len, out2, out2_len))
+ goto err;
+ } else {
+ if (!TEST_mem_eq(out1, out1_len, out2, out2_len))
+ goto err;
+ }
+ ret = 1;
+err:
+ EVP_CIPHER_free(cipher);
+ EVP_CIPHER_CTX_free(ctx);
+ return ret;
+}
+
+
static int name_cmp(const char * const *a, const char * const *b)
{
return strcasecmp(*a, *b);
@@ -332,6 +408,8 @@ int setup_tests(void)
EVP_CIPHER_do_all_provided(libctx, collect_cipher_names, cipher_names);
ADD_ALL_TESTS(test_cipher_reinit, sk_OPENSSL_CSTRING_num(cipher_names));
+ ADD_ALL_TESTS(test_cipher_reinit_partialupdate,
+ sk_OPENSSL_CSTRING_num(cipher_names));
return 1;
}