s390x: AES OFB/CFB: Maintain running IV from cipher context
authorIngo Franzki <ifranzki@linux.ibm.com>
Wed, 11 Aug 2021 07:39:46 +0000 (09:39 +0200)
committerTomas Mraz <tomas@openssl.org>
Mon, 16 Aug 2021 10:59:31 +0000 (12:59 +0200)
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.

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/16292)

crypto/evp/e_aes.c

index b5ea4032fd9597e91e8f6bdc73ac88a14c0bd6e4..73cadbf59366bee928cda889739f0f9d7d8e9d44 100644 (file)
@@ -1240,9 +1240,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_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;
@@ -1271,6 +1274,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;
 }
@@ -1311,10 +1315,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_key_length(ctx);
     const int enc = EVP_CIPHER_CTX_encrypting(ctx);
+    const int ivlen = EVP_CIPHER_CTX_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;
@@ -1347,6 +1354,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;
 }
@@ -1382,8 +1390,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_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;
 }