{
int ret;
size_t soutl;
+ int blocksize;
/* Prevent accidental use of decryption context when encrypting */
if (!ctx->encrypt) {
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
- if (ctx->cipher->cupdate == NULL) {
+ blocksize = EVP_CIPHER_CTX_block_size(ctx);
+
+ if (ctx->cipher->cupdate == NULL || blocksize < 1) {
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
}
- ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl, in, (size_t)inl);
+ ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl,
+ inl + (blocksize == 1 ? 0 : blocksize), in,
+ (size_t)inl);
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_UPDATE_ERROR);
int n, ret;
unsigned int i, b, bl;
size_t soutl;
+ int blocksize;
/* Prevent accidental use of decryption context when encrypting */
if (!ctx->encrypt) {
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
- if (ctx->cipher->cfinal == NULL) {
+ blocksize = EVP_CIPHER_CTX_block_size(ctx);
+
+ if (blocksize < 1 || ctx->cipher->cfinal == NULL) {
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
}
- ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl);
+ ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
+ blocksize == 1 ? 0 : blocksize);
if (soutl > INT_MAX) {
EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_FINAL_ERROR);
int fix_len, cmpl = inl, ret;
unsigned int b;
size_t soutl;
+ int blocksize;
/* Prevent accidental use of encryption context when decrypting */
if (ctx->encrypt) {
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
- if (ctx->cipher->cupdate == NULL) {
+ blocksize = EVP_CIPHER_CTX_block_size(ctx);
+
+ if (ctx->cipher->cupdate == NULL || blocksize < 1) {
EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_UPDATE_ERROR);
return 0;
}
- ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl, in, (size_t)inl);
+ ret = ctx->cipher->cupdate(ctx->provctx, out, &soutl,
+ inl + (blocksize == 1 ? 0 : blocksize), in,
+ (size_t)inl);
if (ret) {
if (soutl > INT_MAX) {
unsigned int b;
size_t soutl;
int ret;
+ int blocksize;
/* Prevent accidental use of encryption context when decrypting */
if (ctx->encrypt) {
if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
goto legacy;
- if (ctx->cipher->cfinal == NULL) {
+ blocksize = EVP_CIPHER_CTX_block_size(ctx);
+
+ if (blocksize < 1 || ctx->cipher->cfinal == NULL) {
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_FINAL_ERROR);
return 0;
}
- ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl);
+ ret = ctx->cipher->cfinal(ctx->provctx, out, &soutl,
+ blocksize == 1 ? 0 : blocksize);
if (ret) {
if (soutl > INT_MAX) {
const unsigned char *iv,
size_t ivlen))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_update,
- (void *, unsigned char *out, size_t *outl,
+ (void *, unsigned char *out, size_t *outl, size_t outsize,
const unsigned char *in, size_t inl))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_final,
- (void *, unsigned char *out, size_t *outl))
+ (void *, unsigned char *out, size_t *outl, size_t outsize))
OSSL_CORE_MAKE_FUNC(int, OP_cipher_cipher,
(void *, unsigned char *out, const unsigned char *in,
size_t inl))
}
static int aes_block_update(void *vctx, unsigned char *out, size_t *outl,
- const unsigned char *in, size_t inl)
+ size_t outsize, const unsigned char *in, size_t inl)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in,
*/
if (ctx->bufsz == AES_BLOCK_SIZE
&& (ctx->enc || inl > 0 || !ctx->pad)) {
+ if (outsize < AES_BLOCK_SIZE)
+ return 0;
if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE))
return 0;
ctx->bufsz = 0;
return 0;
nextblocks -= AES_BLOCK_SIZE;
}
+ outlint += nextblocks;
+ if (outsize < outlint)
+ return 0;
if (!ctx->ciph->cipher(ctx, out, in, nextblocks))
return 0;
in += nextblocks;
inl -= nextblocks;
- outlint += nextblocks;
}
if (!trailingdata(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE, &in, &inl))
return 0;
return inl == 0;
}
-static int aes_block_final(void *vctx, unsigned char *out, size_t *outl)
+static int aes_block_final(void *vctx, unsigned char *out, size_t *outl,
+ size_t outsize)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
return 0;
}
+ if (outsize < AES_BLOCK_SIZE)
+ return 0;
if (!ctx->ciph->cipher(ctx, out, ctx->buf, AES_BLOCK_SIZE))
return 0;
ctx->bufsz = 0;
if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, AES_BLOCK_SIZE))
return 0;
+ if (outsize < ctx->bufsz)
+ return 0;
memcpy(out, ctx->buf, ctx->bufsz);
*outl = ctx->bufsz;
ctx->bufsz = 0;
}
static int aes_stream_update(void *vctx, unsigned char *out, size_t *outl,
- const unsigned char *in, size_t inl)
+ size_t outsize, const unsigned char *in,
+ size_t inl)
{
PROV_AES_KEY *ctx = (PROV_AES_KEY *)vctx;
+ if (outsize < inl)
+ return 0;
+
if (!ctx->ciph->cipher(ctx, out, in, inl))
return 0;
*outl = inl;
return 1;
}
-static int aes_stream_final(void *vctx, unsigned char *out, size_t *outl)
+static int aes_stream_final(void *vctx, unsigned char *out, size_t *outl,
+ size_t outsize)
{
*outl = 0;
return 1;