summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorIngo Franzki <ifranzki@linux.ibm.com>2021-08-11 09:39:46 +0200
committerTomas Mraz <tomas@openssl.org>2021-08-16 13:02:50 +0200
commitc719ea171ce16a919014e5ca2f5217ae35219bdd (patch)
tree095074349f31903ed1aec48bbbabc3e210f9eb6b /crypto/evp
parent0449702abc95a3af24c049cb02c01ca6a8015cef (diff)
s390x: AES OFB/CFB: Maintain running IV from cipher context
Copy the current IV from the cipher context into the kmo/kmf param before the operation, and copy the modified IV back to the context afterwards. Without this, an application that obtains the running IV from the context would still get the original IV, but not the updated one. This implementation in e_aes.c now matches the code in cipher_aes_hw_s390x.inc that is used for the provider implementation. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/16291)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/e_aes.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index 6d5506056e..52b9e87c1e 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -1010,9 +1010,12 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx);
+ const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
+ unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
int n = cctx->res;
int rem;
+ memcpy(cctx->kmo.param.cv, iv, ivlen);
while (n && len) {
*out = *in ^ cctx->kmo.param.cv[n];
n = (n + 1) & 0xf;
@@ -1041,6 +1044,7 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
}
}
+ memcpy(iv, cctx->kmo.param.cv, ivlen);
cctx->res = n;
return 1;
}
@@ -1071,10 +1075,13 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
const int keylen = EVP_CIPHER_CTX_get_key_length(ctx);
const int enc = EVP_CIPHER_CTX_is_encrypting(ctx);
+ const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
+ unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
int n = cctx->res;
int rem;
unsigned char tmp;
+ memcpy(cctx->kmf.param.cv, iv, ivlen);
while (n && len) {
tmp = *in;
*out = cctx->kmf.param.cv[n] ^ tmp;
@@ -1107,6 +1114,7 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
}
}
+ memcpy(iv, cctx->kmf.param.cv, ivlen);
cctx->res = n;
return 1;
}
@@ -1134,8 +1142,12 @@ static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t len)
{
S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
+ const int ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
+ unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
+ memcpy(cctx->kmf.param.cv, iv, ivlen);
s390x_kmf(in, len, out, cctx->fc, &cctx->kmf.param);
+ memcpy(iv, cctx->kmf.param.cv, ivlen);
return 1;
}