[openssl] master update
Richard Levitte
levitte at openssl.org
Fri Oct 11 13:59:39 UTC 2019
The branch master has been updated
via 5b084ca0492cee7aeca63e0a50dbff7487e3ee41 (commit)
via ff33581c67928d2c21f1e853bca3a561335d4c3e (commit)
via f7397f0d58ce7ddf4c5366cd1846f16b341fbe43 (commit)
from bb82531f6592f0e9af28d3502346191a465374a3 (commit)
- Log -----------------------------------------------------------------
commit 5b084ca0492cee7aeca63e0a50dbff7487e3ee41
Author: Richard Levitte <levitte at openssl.org>
Date: Thu Oct 10 18:16:19 2019 +0200
Remove EVP_CIPH_FLAG_CUSTOM_CIPHER in all our providers
Not needed any more, since the presence of the OSSL_FUNC_CIPHER_CIPHER
function is enough to tell that there's a custom cipher function.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10137)
commit ff33581c67928d2c21f1e853bca3a561335d4c3e
Author: Richard Levitte <levitte at openssl.org>
Date: Thu Oct 10 18:14:33 2019 +0200
Providers: fix OSSL_FUNC_CIPHER_CIPHER functions
This involves gcm_cipher() (providers/common/ciphers/cipher_gcm.c),
ccm_cipher() (providers/common/ciphers/cipher_ccm.c), and
tdes_wrap_cipher() (providers/common/ciphers/cipher_tdes_wrap.c)
These are generic implementations of the OSSL_FUNC_CIPHER_CIPHER
function, which returned -1 on error when they should return 0.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10137)
commit f7397f0d58ce7ddf4c5366cd1846f16b341fbe43
Author: Richard Levitte <levitte at openssl.org>
Date: Thu Oct 10 18:04:06 2019 +0200
Fix EVP_Cipher() for provided cipher implementations
EVP_Cipher() would return whatever ctx->cipher->ccipher() returned
with no regard for historical semantics.
We change this to first look if there is a ctx->cipher->ccipher(), and
in that case we treat the implementation as one with a custom cipher,
and "translate" it's return value like this: 0 => -1, 1 => outl, where
|outl| is the output length.
If there is no ctx->cipher->ccipher, we treat the implementation as
one without a custom cipher, call ctx->cipher->cupdate or
ctx->cipher->cfinal depending on input, and return whatever they
return (0 or 1).
Furthermore, we add a small hack in EVP_CIPHER_flags() to check if the
cipher is a provided one, and add EVP_CIPH_FLAG_CUSTOM_CIPHER to the
flags to be returned if there is a cipher->ccipher. That way,
provided implementations never have to set that flag themselves, all
they need to do is to include a OSSL_FUNC_CIPHER_CIPHER function.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10137)
-----------------------------------------------------------------------
Summary of changes:
crypto/evp/evp_lib.c | 34 +++++++++++++++++-----
doc/man3/EVP_EncryptInit.pod | 18 ++++++++++++
providers/common/ciphers/cipher_ccm.c | 4 +--
providers/common/ciphers/cipher_gcm.c | 4 +--
providers/common/include/prov/cipher_aead.h | 1 -
providers/implementations/ciphers/cipher_aes_wrp.c | 5 ++--
.../implementations/ciphers/cipher_tdes_wrap.c | 6 ++--
7 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index 3a3eec615f..c567b2efee 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -298,15 +298,31 @@ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int inl)
{
if (ctx->cipher->prov != NULL) {
- size_t outl = 0; /* ignored */
- int blocksize = EVP_CIPHER_CTX_block_size(ctx);
+ /*
+ * If the provided implementation has a ccipher function, we use it,
+ * and translate its return value like this: 0 => -1, 1 => outlen
+ *
+ * Otherwise, we call the cupdate function if in != NULL, or cfinal
+ * if in == NULL. Regardless of which, we return what we got.
+ */
+ int ret = -1;
+ size_t outl = 0;
+ size_t blocksize = EVP_CIPHER_CTX_block_size(ctx);
if (ctx->cipher->ccipher != NULL)
- return
- ctx->cipher->ccipher(ctx->provctx, out, &outl,
- inl + (blocksize == 1 ? 0 : blocksize),
- in, (size_t)inl);
- return 0;
+ ret = ctx->cipher->ccipher(ctx->provctx, out, &outl,
+ inl + (blocksize == 1 ? 0 : blocksize),
+ in, (size_t)inl)
+ ? (int)outl : -1;
+ else if (in != NULL)
+ ret = ctx->cipher->cupdate(ctx->provctx, out, &outl,
+ inl + (blocksize == 1 ? 0 : blocksize),
+ in, (size_t)inl);
+ else
+ ret = ctx->cipher->cfinal(ctx->provctx, out, &outl,
+ blocksize == 1 ? 0 : blocksize);
+
+ return ret;
}
return ctx->cipher->do_cipher(ctx, out, in, inl);
@@ -331,6 +347,10 @@ unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
params[0] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &v);
ok = evp_do_ciph_getparams(cipher, params);
+ /* Provided implementations may have a custom cipher_cipher */
+ if (cipher->prov != NULL && cipher->ccipher != NULL)
+ v |= EVP_CIPH_FLAG_CUSTOM_CIPHER;
+
return ok != 0 ? v : 0;
}
diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod
index 3e668206b1..722a8e3d36 100644
--- a/doc/man3/EVP_EncryptInit.pod
+++ b/doc/man3/EVP_EncryptInit.pod
@@ -25,6 +25,7 @@ EVP_DecryptInit,
EVP_DecryptFinal,
EVP_CipherInit,
EVP_CipherFinal,
+EVP_Cipher,
EVP_get_cipherbyname,
EVP_get_cipherbynid,
EVP_get_cipherbyobj,
@@ -107,6 +108,9 @@ EVP_CIPHER_do_all_ex
const unsigned char *key, const unsigned char *iv, int enc);
int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, unsigned int inl);
+
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
@@ -251,6 +255,15 @@ EVP_CipherFinal_ex(). In previous releases they also cleaned up
the B<ctx>, but this is no longer done and EVP_CIPHER_CTX_clean()
must be called to free any context resources.
+EVP_Cipher() encrypts or decrypts a maximum I<inl> amount of bytes from
+I<in> and leaves the result in I<out>.
+If the cipher doesn't have the flag B<EVP_CIPH_FLAG_CUSTOM_CIPHER> set,
+then I<inl> must be a multiple of EVP_CIPHER_block_size(). If it isn't,
+the result is undefined. If the cipher has that flag set, then I<inl>
+can be any size.
+This function is historic and shouldn't be used in an application, please
+consider using EVP_CipherUpdate() and EVP_CipherFinal_ex instead.
+
EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
return an EVP_CIPHER structure when passed a cipher name, a NID or an
ASN1_OBJECT structure.
@@ -388,6 +401,11 @@ EVP_DecryptFinal_ex() returns 0 if the decrypt failed or 1 for success.
EVP_CipherInit_ex() and EVP_CipherUpdate() return 1 for success and 0 for failure.
EVP_CipherFinal_ex() returns 0 for a decryption failure or 1 for success.
+EVP_Cipher() returns the amount of encrypted / decrypted bytes, or -1
+on failure, if the flag B<EVP_CIPH_FLAG_CUSTOM_CIPHER> is set for the
+cipher. EVP_Cipher() returns 1 on success or 0 on failure, if the flag
+B<EVP_CIPH_FLAG_CUSTOM_CIPHER> is not set for the cipher.
+
EVP_CIPHER_CTX_reset() returns 1 for success and 0 for failure.
EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj()
diff --git a/providers/common/ciphers/cipher_ccm.c b/providers/common/ciphers/cipher_ccm.c
index 904af3a5e0..021a004276 100644
--- a/providers/common/ciphers/cipher_ccm.c
+++ b/providers/common/ciphers/cipher_ccm.c
@@ -278,11 +278,11 @@ int ccm_cipher(void *vctx,
if (outsize < inl) {
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
- return -1;
+ return 0;
}
if (ccm_cipher_internal(ctx, out, outl, in, inl) <= 0)
- return -1;
+ return 0;
*outl = inl;
return 1;
diff --git a/providers/common/ciphers/cipher_gcm.c b/providers/common/ciphers/cipher_gcm.c
index 580928fdde..d7c67e8b6b 100644
--- a/providers/common/ciphers/cipher_gcm.c
+++ b/providers/common/ciphers/cipher_gcm.c
@@ -263,11 +263,11 @@ int gcm_cipher(void *vctx,
if (outsize < inl) {
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
- return -1;
+ return 0;
}
if (gcm_cipher_internal(ctx, out, outl, in, inl) <= 0)
- return -1;
+ return 0;
*outl = inl;
return 1;
diff --git a/providers/common/include/prov/cipher_aead.h b/providers/common/include/prov/cipher_aead.h
index 0b7d595b7d..db938d7fbe 100644
--- a/providers/common/include/prov/cipher_aead.h
+++ b/providers/common/include/prov/cipher_aead.h
@@ -12,7 +12,6 @@
/* TODO(3.0) Figure out what flags are really needed */
#define AEAD_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER \
| EVP_CIPH_CUSTOM_IV \
- | EVP_CIPH_FLAG_CUSTOM_CIPHER \
| EVP_CIPH_ALWAYS_CALL_INIT \
| EVP_CIPH_CTRL_INIT \
| EVP_CIPH_CUSTOM_COPY)
diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c
index 9eaec16318..028676943e 100644
--- a/providers/implementations/ciphers/cipher_aes_wrp.c
+++ b/providers/implementations/ciphers/cipher_aes_wrp.c
@@ -16,9 +16,8 @@
#define AES_WRAP_NOPAD_IVLEN 8
/* TODO(3.0) Figure out what flags need to be passed */
-#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \
- | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
- | EVP_CIPH_ALWAYS_CALL_INIT)
+#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV \
+ | EVP_CIPH_ALWAYS_CALL_INIT)
typedef size_t (*aeswrap_fn)(void *key, const unsigned char *iv,
unsigned char *out, const unsigned char *in,
diff --git a/providers/implementations/ciphers/cipher_tdes_wrap.c b/providers/implementations/ciphers/cipher_tdes_wrap.c
index 75cc25df06..d899985202 100644
--- a/providers/implementations/ciphers/cipher_tdes_wrap.c
+++ b/providers/implementations/ciphers/cipher_tdes_wrap.c
@@ -15,9 +15,7 @@
#include "prov/providercommonerr.h"
/* TODO (3.0) Figure out what flags are requred */
-#define TDES_WRAP_FLAGS (EVP_CIPH_WRAP_MODE \
- | EVP_CIPH_CUSTOM_IV \
- | EVP_CIPH_FLAG_CUSTOM_CIPHER)
+#define TDES_WRAP_FLAGS (EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV)
static OSSL_OP_cipher_update_fn tdes_wrap_update;
@@ -131,7 +129,7 @@ static int tdes_wrap_cipher(void *vctx,
*outl = 0;
if (outsize < inl) {
PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
- return -1;
+ return 0;
}
ret = tdes_wrap_cipher_internal(ctx, out, in, inl);
More information about the openssl-commits
mailing list