case NID_aes_256_cbc:
case NID_aes_192_cbc:
case NID_aes_128_cbc:
+ case NID_aes_256_ofb128:
+ case NID_aes_192_ofb128:
+ case NID_aes_128_ofb128:
+ case NID_aes_256_cfb128:
+ case NID_aes_192_cfb128:
+ case NID_aes_128_cfb128:
+ case NID_aes_256_cfb1:
+ case NID_aes_192_cfb1:
+ case NID_aes_128_cfb1:
+ case NID_aes_256_cfb8:
+ case NID_aes_192_cfb8:
+ case NID_aes_128_cfb8:
+ case NID_aes_256_ctr:
+ case NID_aes_192_ctr:
+ case NID_aes_128_ctr:
break;
default:
goto legacy;
ctx->cipher = cipher;
if (ctx->provctx == NULL) {
- ctx->provctx = ctx->cipher->newctx();
+ ctx->provctx = ctx->cipher->newctx(ossl_provider_ctx(cipher->prov));
if (ctx->provctx == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
return 0;
}
- return ctx->cipher->einit(ctx->provctx, key, iv);
+ return ctx->cipher->einit(ctx->provctx,
+ key,
+ key == NULL ? 0
+ : EVP_CIPHER_CTX_key_length(ctx),
+ iv,
+ iv == NULL ? 0
+ : EVP_CIPHER_CTX_iv_length(ctx));
}
if (ctx->cipher->dinit == NULL) {
return 0;
}
- return ctx->cipher->dinit(ctx->provctx, key, iv);
+ return ctx->cipher->dinit(ctx->provctx,
+ key,
+ key == NULL ? 0
+ : EVP_CIPHER_CTX_key_length(ctx),
+ iv,
+ iv == NULL ? 0
+ : EVP_CIPHER_CTX_iv_length(ctx));
/* TODO(3.0): Remove legacy code below */
legacy:
#ifndef OPENSSL_NO_ENGINE
skip_to_init:
#endif
+ if (ctx->cipher == NULL)
+ return 0;
+
/* we assume block size is a power of 2 in *cryptUpdate */
OPENSSL_assert(ctx->cipher->block_size == 1
|| ctx->cipher->block_size == 8
{
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) {
return 0;
}
- if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
+ if (ctx->cipher == NULL) {
+ EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_NO_CIPHER_SET);
+ return 0;
+ }
+ if (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) {
return 0;
}
- if (ctx->cipher == NULL || ctx->cipher->prov == NULL)
+ if (ctx->cipher == NULL) {
+ EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_NO_CIPHER_SET);
+ return 0;
+ }
+ if (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) {
legacy:
*outl = 0;
+ if (ctx->cipher == NULL) {
+ EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_NO_CIPHER_SET);
+ return 0;
+ }
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
{
+ int kl;
if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
- if (RAND_priv_bytes(key, ctx->key_len) <= 0)
+ kl = EVP_CIPHER_CTX_key_length(ctx);
+ if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0)
return 0;
return 1;
}
}
if ((fnciphcnt != 0 && fnciphcnt != 3 && fnciphcnt != 4)
|| (fnciphcnt == 0 && cipher->ccipher == NULL)
- || fnctxcnt != 2) {
+ || fnctxcnt != 2
+ || cipher->blocksize == NULL
+ || cipher->iv_length == NULL
+ || cipher->key_length == NULL) {
/*
* In order to be a consistent set of functions we must have at least
* a complete set of "encrypt" functions, or a complete set of "decrypt"
* functions, or a single "cipher" function. In all cases we need a
- * complete set of context management functions
+ * complete set of context management functions, as well as the
+ * blocksize, iv_length and key_length functions.
*/
EVP_CIPHER_meth_free(cipher);
EVPerr(EVP_F_EVP_CIPHER_FROM_DISPATCH, EVP_R_INVALID_PROVIDER_FUNCTIONS);