* 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"
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)
*/
/* Sanity check inputs */
- if (in == 0
- || (inl % blksz) != 0
+ if (in == NULL
|| in != out
|| outsize < inl
|| !ctx->pad) {
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);
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 */
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) {
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 */
}
}
- if (EVP_CIPHER_provider(enc) != NULL) {
+ if (provided) {
int outlen;
/* Provided cipher - we do not support pipelining on this path */
: 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;