return 0;
}
- switch (EVP_CIPHER_mode(ctx->cipher)) {
- case EVP_CIPH_CFB_MODE:
- case EVP_CIPH_OFB_MODE:
- case EVP_CIPH_CBC_MODE:
- /* For these modes we remember the original IV for later use */
- if (!ossl_assert(EVP_CIPHER_CTX_iv_length(ctx) <= (int)sizeof(ctx->oiv))) {
- EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
- return 0;
- }
- if (iv != NULL)
- memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
- }
-
if (enc) {
if (ctx->cipher->einit == NULL) {
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
{
int i = 0;
unsigned int j;
+ unsigned char *oiv = NULL;
if (type != NULL) {
+ oiv = (unsigned char *)EVP_CIPHER_CTX_original_iv(c);
j = EVP_CIPHER_CTX_iv_length(c);
OPENSSL_assert(j <= sizeof(c->iv));
- i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
+ i = ASN1_TYPE_set_octetstring(type, oiv, j);
}
return i;
}
const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
{
- return ctx->oiv;
+ int ok;
+ const unsigned char *v = ctx->oiv;
+ OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+ params[0] =
+ OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV,
+ (void **)&v, sizeof(ctx->oiv));
+ ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
+
+ return ok != 0 ? v : NULL;
}
/*
{
PROV_AES_CCM_CTX *ctx = (PROV_AES_CCM_CTX *)vctx;
- ccm_finalctx((PROV_CCM_CTX *)ctx);
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
{
PROV_AES_GCM_CTX *ctx = (PROV_AES_GCM_CTX *)vctx;
- gcm_deinitctx((PROV_GCM_CTX *)ctx);
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
OSSL_UNION_ALIGN;
AES_KEY ks;
} ks;
- unsigned int iv_set : 1;
aeswrap_fn wrapfn;
} PROV_AES_WRAP_CTX;
static void aes_wrap_freectx(void *vctx)
{
PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx;
- PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
- OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
OPENSSL_clear_free(wctx, sizeof(*wctx));
}
wctx->wrapfn = enc ? CRYPTO_128_wrap : CRYPTO_128_unwrap;
if (iv != NULL) {
- ctx->ivlen = ivlen;
- memcpy(ctx->iv, iv, ivlen);
- wctx->iv_set = 1;
+ if (!cipher_generic_initiv(ctx, iv, ivlen))
+ return 0;
}
if (key != NULL) {
if (keylen != ctx->keylen) {
}
}
- rv = wctx->wrapfn(&wctx->ks.ks, wctx->iv_set ? ctx->iv : NULL, out, in,
+ rv = wctx->wrapfn(&wctx->ks.ks, ctx->iv_set ? ctx->iv : NULL, out, in,
inlen, ctx->block);
return rv ? (int)rv : -1;
}
ctx->enc = enc;
if (iv != NULL) {
- if (ivlen != ctx->ivlen) {
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
+ if (!cipher_generic_initiv(vctx, iv, ivlen))
return 0;
- }
- memcpy(ctx->iv, iv, ivlen);
- xctx->iv_set = 1;
}
if (key != NULL) {
if (keylen != ctx->keylen) {
if (ctx->xts.key1 == NULL
|| ctx->xts.key2 == NULL
- || !ctx->iv_set
+ || !ctx->base.iv_set
|| out == NULL
|| in == NULL
|| inl < AES_BLOCK_SIZE)
} ks1, ks2; /* AES key schedules to use */
XTS128_CONTEXT xts;
OSSL_xts_stream_fn stream;
- unsigned int iv_set : 1; /* Set if an iv is set */
} PROV_AES_XTS_CTX;
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_xts(size_t keybits);
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
return 0;
}
-
memcpy(ctx->iv, iv, ivlen);
ctx->iv_set = 1;
}
ctx->hw = hw;
}
-void ccm_finalctx(PROV_CCM_CTX *ctx)
-{
- OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
-}
ctx->enc = enc ? 1 : 0;
if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
- if (ivlen != ctx->ivlen) {
- ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
+ if (!cipher_generic_initiv(ctx, iv, ivlen))
return 0;
- }
- memcpy(ctx->iv, iv, ctx->ivlen);
}
if (key != NULL) {
if ((ctx->flags & EVP_CIPH_VARIABLE_LENGTH) == 0) {
}
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
if (p != NULL
- && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)
- && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) {
+ && !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen)
+ && !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
-
return 1;
}
return 1;
}
+int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
+ size_t ivlen)
+{
+ if (ivlen != ctx->ivlen
+ || ivlen > sizeof(ctx->iv)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
+ return 0;
+ }
+ ctx->iv_set = 1;
+ memcpy(ctx->iv, iv, ivlen);
+ memcpy(ctx->oiv, iv, ivlen);
+ return 1;
+}
+
void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
size_t ivbits, unsigned int mode, uint64_t flags,
const PROV_CIPHER_HW *hw, void *provctx)
ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
}
-void gcm_deinitctx(PROV_GCM_CTX *ctx)
-{
- OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
-}
-
static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
const unsigned char *iv, size_t ivlen, int enc)
{
return 0;
}
ctx->ivlen = ivlen;
- memcpy(ctx->iv, iv, ctx->ivlen);
+ memcpy(ctx->iv, iv, ivlen);
ctx->iv_state = IV_STATE_BUFFERED;
}
void tdes_freectx(void *vctx)
{
- PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+ PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx;
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
ctx->enc = enc;
if (iv != NULL) {
- if (ivlen != TDES_IVLEN) {
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
+ if (!cipher_generic_initiv(ctx, iv, ivlen))
return 0;
- }
- memcpy(ctx->iv, iv, TDES_IVLEN);
}
if (key != NULL) {
OSSL_OP_cipher_final_fn ccm_stream_final;
OSSL_OP_cipher_cipher_fn ccm_cipher;
void ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw);
-void ccm_finalctx(PROV_CCM_CTX *ctx);
int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
size_t nlen, size_t mlen);
OSSL_OP_cipher_cipher_fn gcm_cipher;
OSSL_OP_cipher_update_fn gcm_stream_update;
OSSL_OP_cipher_final_fn gcm_stream_final;
-void gcm_deinitctx(PROV_GCM_CTX *ctx);
void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
const PROV_GCM_HW *hw, size_t ivlen_min);
} stream;
unsigned int mode;
- size_t keylen; /* key size (in bytes) */
+ size_t keylen; /* key size (in bytes) */
size_t ivlen;
size_t blocksize;
- size_t bufsz; /* Number of bytes in buf */
- unsigned int pad : 1; /* Whether padding should be used or not */
- unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */
+ size_t bufsz; /* Number of bytes in buf */
+ unsigned int pad : 1; /* Whether padding should be used or not */
+ unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */
+ unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */
/*
* num contains the number of bytes of |iv| which are valid for modes that
unsigned int num;
uint64_t flags;
+ /* The original value of the iv */
+ unsigned char oiv[GENERIC_BLOCK_SIZE];
/* Buffer of partial blocks processed via update calls */
unsigned char buf[GENERIC_BLOCK_SIZE];
unsigned char iv[GENERIC_BLOCK_SIZE];
return name##_known_settable_ctx_params; \
}
+int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
+ size_t ivlen);
+
size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
const unsigned char **in, size_t *inlen);
int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
}
ctx->base.ivlen = ivlen;
}
- memcpy(ctx->base.iv, iv, ivlen);
+ if (!cipher_generic_initiv(&ctx->base, iv, ivlen))
+ return 0;
ctx->iv_state = IV_STATE_BUFFERED;
}
if (key != NULL) {
if (ctx != NULL) {
aes_generic_ocb_cleanup(ctx);
- OPENSSL_cleanse(ctx->base.iv, sizeof(ctx->base.iv));
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
}
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
return 0;
}
- if (!OSSL_PARAM_set_octet_string(p, ctx->base.iv, ctx->base.ivlen)) {
+ if (!OSSL_PARAM_set_octet_string(p, ctx->base.oiv, ctx->base.ivlen)) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
return 0;
}
{
PROV_ARIA_CCM_CTX *ctx = (PROV_ARIA_CCM_CTX *)vctx;
- ccm_finalctx((PROV_CCM_CTX *)ctx);
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
{
PROV_ARIA_GCM_CTX *ctx = (PROV_ARIA_GCM_CTX *)vctx;
- gcm_deinitctx((PROV_GCM_CTX *)ctx);
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
static void des_freectx(void *vctx)
{
- PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
+ PROV_DES_CTX *ctx = (PROV_DES_CTX *)vctx;
OPENSSL_clear_free(ctx, sizeof(*ctx));
}
ctx->enc = enc;
if (iv != NULL) {
- if (ivlen != ctx->ivlen) {
- ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
+ if (!cipher_generic_initiv(ctx, iv, ivlen))
return 0;
- }
- memcpy(ctx->iv, iv, ivlen);
}
if (key != NULL) {