From: Matt Caswell Date: Fri, 26 Jun 2020 17:22:18 +0000 (+0100) Subject: Ensure TLS padding is added during encryption on the provider side X-Git-Tag: openssl-3.0.0-alpha5~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d9f56e9992ef3725b87a0a8e6165a18d038b784;p=thirdparty%2Fopenssl.git Ensure TLS padding is added during encryption on the provider side Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/12288) --- diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c index 2cd5b6f571b..a8905d1242c 100644 --- a/providers/implementations/ciphers/ciphercommon.c +++ b/providers/implementations/ciphers/ciphercommon.c @@ -11,6 +11,8 @@ * Generic dispatch table functions for ciphers. */ +/* For SSL3_VERSION */ +#include #include "ciphercommon_local.h" #include "prov/provider_ctx.h" #include "prov/providercommonerr.h" @@ -181,6 +183,9 @@ int cipher_generic_dinit(void *vctx, const unsigned char *key, size_t keylen, iv, ivlen, 0); } +/* Max padding including padding length byte */ +#define MAX_PADDING 256 + int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) @@ -197,8 +202,7 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, */ /* Sanity check inputs */ - if (in == 0 - || (inl % blksz) != 0 + if (in == NULL || in != out || outsize < inl || !ctx->pad) { @@ -206,6 +210,42 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, return 0; } + if (ctx->enc) { + unsigned char padval; + size_t padnum, loop; + + /* Add padding */ + + padnum = blksz - (inl % blksz); + + if (outsize < inl + padnum) { + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); + return 0; + } + + if (padnum > MAX_PADDING) { + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); + return 0; + } + padval = (unsigned char)(padnum - 1); + if (ctx->tlsversion == SSL3_VERSION) { + if (padnum > 1) + memset(out + inl, 0, padnum - 1); + *(out + inl + padnum - 1) = padval; + } else { + /* we need to add 'padnum' padding bytes of value padval */ + for (loop = inl; loop < inl + padnum; loop++) + out[loop] = padval; + } + inl += padnum; + } + + if ((inl % blksz) != 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); + return 0; + } + + /* Shouldn't normally fail */ if (!ctx->hw->cipher(ctx, out, in, inl)) { ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 6359c79bb16..80990e82966 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -869,13 +869,19 @@ int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int sending, memmove(rec->data, rec->input, rec->length); rec->input = rec->data; } else { + int provided = (EVP_CIPHER_provider(enc) != NULL); + l = rec->length; /* TODO(size_t): Convert this call */ bs = EVP_CIPHER_CTX_block_size(ds); /* COMPRESS */ - if ((bs != 1) && sending) { + if ((bs != 1) && sending && !provided) { + /* + * We only do this for legacy ciphers. Provided ciphers add the + * padding on the provider side. + */ i = bs - (l % bs); /* we need to add 'i-1' padding bytes */ @@ -1038,6 +1044,8 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, recs[ctr].input = recs[ctr].data; } } else { + int provided = (EVP_CIPHER_provider(enc) != NULL); + bs = EVP_CIPHER_block_size(EVP_CIPHER_CTX_cipher(ds)); if (n_recs > 1) { @@ -1097,7 +1105,11 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, recs[ctr].length += pad; } - } else if ((bs != 1) && sending) { + } else if ((bs != 1) && sending && !provided) { + /* + * We only do this for legacy ciphers. Provided ciphers add the + * padding on the provider side. + */ padnum = bs - (reclen[ctr] % bs); /* Add weird padding of up to 256 bytes */ @@ -1170,7 +1182,7 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, } } - if (EVP_CIPHER_provider(enc) != NULL) { + if (provided) { int outlen; /* Provided cipher - we do not support pipelining on this path */ @@ -1275,7 +1287,7 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, : NULL, bs, macsize, - (EVP_CIPHER_CTX_flags(s->enc_read_ctx) + (EVP_CIPHER_flags(enc) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0, s->ctx->libctx)) return 0;