Ensure TLS padding is added during encryption on the provider side

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12288)
This commit is contained in:
Matt Caswell 2020-06-26 18:22:18 +01:00
parent b558817823
commit 2d9f56e999
2 changed files with 58 additions and 6 deletions

View File

@ -11,6 +11,8 @@
* Generic dispatch table functions for ciphers.
*/
/* For SSL3_VERSION */
#include <openssl/ssl.h>
#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);

View File

@ -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;