0c50f5
diff -up openssl-1.1.1k/crypto/evp/e_aes.c.s390x-aes openssl-1.1.1k/crypto/evp/e_aes.c
0c50f5
--- openssl-1.1.1k/crypto/evp/e_aes.c.s390x-aes	2021-07-16 11:03:14.362127435 +0200
0c50f5
+++ openssl-1.1.1k/crypto/evp/e_aes.c	2021-07-16 15:00:42.531477251 +0200
0c50f5
@@ -1168,9 +1168,9 @@ typedef struct {
0c50f5
 static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
0c50f5
                               const unsigned char *iv, int enc);
0c50f5
 
0c50f5
-# define S390X_aes_128_cbc_CAPABLE	1	/* checked by callee */
0c50f5
-# define S390X_aes_192_cbc_CAPABLE	1
0c50f5
-# define S390X_aes_256_cbc_CAPABLE	1
0c50f5
+# define S390X_aes_128_cbc_CAPABLE	0	/* checked by callee */
0c50f5
+# define S390X_aes_192_cbc_CAPABLE	0
0c50f5
+# define S390X_aes_256_cbc_CAPABLE	0
0c50f5
 # define S390X_AES_CBC_CTX		EVP_AES_KEY
0c50f5
 
0c50f5
 # define s390x_aes_cbc_init_key aes_init_key
0c50f5
@@ -1190,11 +1190,10 @@ static int s390x_aes_ecb_init_key(EVP_CI
0c50f5
     S390X_AES_ECB_CTX *cctx = EVP_C_DATA(S390X_AES_ECB_CTX, ctx);
0c50f5
     const int keylen = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
 
0c50f5
-    cctx->fc = S390X_AES_FC(keylen);
0c50f5
-    if (!enc)
0c50f5
-        cctx->fc |= S390X_DECRYPT;
0c50f5
+    cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT);
0c50f5
 
0c50f5
-    memcpy(cctx->km.param.k, key, keylen);
0c50f5
+    if (key != NULL)
0c50f5
+        memcpy(cctx->km.param.k, key, keylen);
0c50f5
     return 1;
0c50f5
 }
0c50f5
 
0c50f5
@@ -1222,14 +1221,17 @@ static int s390x_aes_ofb_init_key(EVP_CI
0c50f5
                                   const unsigned char *ivec, int enc)
0c50f5
 {
0c50f5
     S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx);
0c50f5
-    const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx);
0c50f5
+    const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx);
0c50f5
     const int keylen = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
     const int ivlen = EVP_CIPHER_CTX_iv_length(ctx);
0c50f5
 
0c50f5
-    memcpy(cctx->kmo.param.cv, iv, ivlen);
0c50f5
-    memcpy(cctx->kmo.param.k, key, keylen);
0c50f5
     cctx->fc = S390X_AES_FC(keylen);
0c50f5
+
0c50f5
+    if (key != NULL)
0c50f5
+        memcpy(cctx->kmo.param.k, key, keylen);
0c50f5
+
0c50f5
     cctx->res = 0;
0c50f5
+	memcpy(cctx->kmo.param.cv, oiv, ivlen);
0c50f5
     return 1;
0c50f5
 }
0c50f5
 
0c50f5
@@ -1287,18 +1289,18 @@ static int s390x_aes_cfb_init_key(EVP_CI
0c50f5
                                   const unsigned char *ivec, int enc)
0c50f5
 {
0c50f5
     S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
0c50f5
-    const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx);
0c50f5
+    const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx);
0c50f5
     const int keylen = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
     const int ivlen = EVP_CIPHER_CTX_iv_length(ctx);
0c50f5
 
0c50f5
-    cctx->fc = S390X_AES_FC(keylen);
0c50f5
-    cctx->fc |= 16 << 24;   /* 16 bytes cipher feedback */
0c50f5
-    if (!enc)
0c50f5
-        cctx->fc |= S390X_DECRYPT;
0c50f5
+    cctx->fc = S390X_AES_FC(keylen)| (enc ? 0 : S390X_DECRYPT)
0c50f5
+               | (16 << 24); /* 16 bytes cipher feedback */
0c50f5
+
0c50f5
+    if (key != NULL)
0c50f5
+         memcpy(cctx->kmf.param.k, key, keylen);
0c50f5
 
0c50f5
     cctx->res = 0;
0c50f5
-    memcpy(cctx->kmf.param.cv, iv, ivlen);
0c50f5
-    memcpy(cctx->kmf.param.k, key, keylen);
0c50f5
+	memcpy(cctx->kmf.param.cv, oiv, ivlen);
0c50f5
     return 1;
0c50f5
 }
0c50f5
 
0c50f5
@@ -1360,17 +1362,18 @@ static int s390x_aes_cfb8_init_key(EVP_C
0c50f5
                                    const unsigned char *ivec, int enc)
0c50f5
 {
0c50f5
     S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx);
0c50f5
-    const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx);
0c50f5
+    const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx);
0c50f5
     const int keylen = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
     const int ivlen = EVP_CIPHER_CTX_iv_length(ctx);
0c50f5
 
0c50f5
-    cctx->fc = S390X_AES_FC(keylen);
0c50f5
-    cctx->fc |= 1 << 24;   /* 1 byte cipher feedback */
0c50f5
-    if (!enc)
0c50f5
-        cctx->fc |= S390X_DECRYPT;
0c50f5
+    cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT)
0c50f5
+		       | (1 << 24); /* 1 byte cipher feedback flag */
0c50f5
+
0c50f5
+    if (key != NULL)
0c50f5
+        memcpy(cctx->kmf.param.k, key, keylen);
0c50f5
 
0c50f5
-    memcpy(cctx->kmf.param.cv, iv, ivlen);
0c50f5
-    memcpy(cctx->kmf.param.k, key, keylen);
0c50f5
+    cctx->res = 0;
0c50f5
+	 memcpy(cctx->kmf.param.cv, oiv, ivlen);
0c50f5
     return 1;
0c50f5
 }
0c50f5
 
0c50f5
@@ -1393,9 +1396,9 @@ static int s390x_aes_cfb8_cipher(EVP_CIP
0c50f5
 static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
0c50f5
                                  const unsigned char *in, size_t len);
0c50f5
 
0c50f5
-# define S390X_aes_128_ctr_CAPABLE	1	/* checked by callee */
0c50f5
-# define S390X_aes_192_ctr_CAPABLE	1
0c50f5
-# define S390X_aes_256_ctr_CAPABLE	1
0c50f5
+# define S390X_aes_128_ctr_CAPABLE	0	/* checked by callee */
0c50f5
+# define S390X_aes_192_ctr_CAPABLE	0
0c50f5
+# define S390X_aes_256_ctr_CAPABLE	0
0c50f5
 # define S390X_AES_CTR_CTX		EVP_AES_KEY
0c50f5
 
0c50f5
 # define s390x_aes_ctr_init_key aes_init_key
0c50f5
@@ -1563,8 +1566,7 @@ static int s390x_aes_gcm(S390X_AES_GCM_C
0c50f5
 /*-
0c50f5
  * Initialize context structure. Code is big-endian.
0c50f5
  */
0c50f5
-static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx,
0c50f5
-                                const unsigned char *iv)
0c50f5
+static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx)
0c50f5
 {
0c50f5
     ctx->kma.param.t.g[0] = 0;
0c50f5
     ctx->kma.param.t.g[1] = 0;
0c50f5
@@ -1575,12 +1577,11 @@ static void s390x_aes_gcm_setiv(S390X_AE
0c50f5
     ctx->kreslen = 0;
0c50f5
 
0c50f5
     if (ctx->ivlen == 12) {
0c50f5
-        memcpy(&ctx->kma.param.j0, iv, ctx->ivlen);
0c50f5
+        memcpy(&ctx->kma.param.j0, ctx->iv, ctx->ivlen);
0c50f5
         ctx->kma.param.j0.w[3] = 1;
0c50f5
         ctx->kma.param.cv.w = 1;
0c50f5
     } else {
0c50f5
         /* ctx->iv has the right size and is already padded. */
0c50f5
-        memcpy(ctx->iv, iv, ctx->ivlen);
0c50f5
         s390x_kma(ctx->iv, S390X_gcm_ivpadlen(ctx->ivlen), NULL, 0, NULL,
0c50f5
                   ctx->fc, &ctx->kma.param);
0c50f5
         ctx->fc |= S390X_KMA_HS;
0c50f5
@@ -1694,7 +1695,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER
0c50f5
         if (gctx->iv_gen == 0 || gctx->key_set == 0)
0c50f5
             return 0;
0c50f5
 
0c50f5
-        s390x_aes_gcm_setiv(gctx, gctx->iv);
0c50f5
+        s390x_aes_gcm_setiv(gctx);
0c50f5
 
0c50f5
         if (arg <= 0 || arg > gctx->ivlen)
0c50f5
             arg = gctx->ivlen;
0c50f5
@@ -1714,7 +1715,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER
0c50f5
             return 0;
0c50f5
 
0c50f5
         memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
0c50f5
-        s390x_aes_gcm_setiv(gctx, gctx->iv);
0c50f5
+        s390x_aes_gcm_setiv(gctx);
0c50f5
         gctx->iv_set = 1;
0c50f5
         return 1;
0c50f5
 
0c50f5
@@ -1770,43 +1771,35 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER
0c50f5
 }
0c50f5
 
0c50f5
 /*-
0c50f5
- * Set key and/or iv. Returns 1 on success. Otherwise 0 is returned.
0c50f5
+ * Set key or iv or enc/dec. Returns 1 on success. Otherwise 0 is returned.
0c50f5
  */
0c50f5
 static int s390x_aes_gcm_init_key(EVP_CIPHER_CTX *ctx,
0c50f5
                                   const unsigned char *key,
0c50f5
                                   const unsigned char *iv, int enc)
0c50f5
 {
0c50f5
     S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, ctx);
0c50f5
-    int keylen;
0c50f5
+    const int keylen = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
 
0c50f5
-    if (iv == NULL && key == NULL)
0c50f5
-        return 1;
0c50f5
+	 gctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT);
0c50f5
 
0c50f5
     if (key != NULL) {
0c50f5
-        keylen = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
+		 gctx->fc &= ~S390X_KMA_HS;
0c50f5
         memcpy(&gctx->kma.param.k, key, keylen);
0c50f5
-
0c50f5
-        gctx->fc = S390X_AES_FC(keylen);
0c50f5
-        if (!enc)
0c50f5
-            gctx->fc |= S390X_DECRYPT;
0c50f5
-
0c50f5
-        if (iv == NULL && gctx->iv_set)
0c50f5
-            iv = gctx->iv;
0c50f5
-
0c50f5
-        if (iv != NULL) {
0c50f5
-            s390x_aes_gcm_setiv(gctx, iv);
0c50f5
-            gctx->iv_set = 1;
0c50f5
-        }
0c50f5
         gctx->key_set = 1;
0c50f5
-    } else {
0c50f5
-        if (gctx->key_set)
0c50f5
-            s390x_aes_gcm_setiv(gctx, iv);
0c50f5
-        else
0c50f5
-            memcpy(gctx->iv, iv, gctx->ivlen);
0c50f5
-
0c50f5
-        gctx->iv_set = 1;
0c50f5
+    }
0c50f5
+    if (iv != NULL) {
0c50f5
+		memcpy(gctx->iv, iv, gctx->ivlen);
0c50f5
         gctx->iv_gen = 0;
0c50f5
+        gctx->iv_set = 1;
0c50f5
     }
0c50f5
+
0c50f5
+    if (gctx->key_set && gctx->iv_set)
0c50f5
+                 s390x_aes_gcm_setiv(gctx);
0c50f5
+
0c50f5
+    gctx->fc &= ~(S390X_KMA_LPC | S390X_KMA_LAAD);
0c50f5
+    gctx->areslen = 0;
0c50f5
+    gctx->mreslen = 0;
0c50f5
+    gctx->kreslen = 0;
0c50f5
     return 1;
0c50f5
 }
0c50f5
 
0c50f5
@@ -1895,7 +1888,6 @@ static int s390x_aes_gcm_cipher(EVP_CIPH
0c50f5
         /* recall that we already did en-/decrypt gctx->mres
0c50f5
          * and returned it to caller... */
0c50f5
         OPENSSL_cleanse(tmp, gctx->mreslen);
0c50f5
-        gctx->iv_set = 0;
0c50f5
 
0c50f5
         enc = EVP_CIPHER_CTX_encrypting(ctx);
0c50f5
         if (enc) {
0c50f5
@@ -1929,8 +1921,8 @@ static int s390x_aes_gcm_cleanup(EVP_CIP
0c50f5
 }
0c50f5
 
0c50f5
 # define S390X_AES_XTS_CTX		EVP_AES_XTS_CTX
0c50f5
-# define S390X_aes_128_xts_CAPABLE	1	/* checked by callee */
0c50f5
-# define S390X_aes_256_xts_CAPABLE	1
0c50f5
+# define S390X_aes_128_xts_CAPABLE	0	/* checked by callee */
0c50f5
+# define S390X_aes_256_xts_CAPABLE	0
0c50f5
 
0c50f5
 # define s390x_aes_xts_init_key aes_xts_init_key
0c50f5
 static int s390x_aes_xts_init_key(EVP_CIPHER_CTX *ctx,
0c50f5
@@ -2134,9 +2126,10 @@ static int s390x_aes_ccm_tls_cipher(EVP_
0c50f5
                                     const unsigned char *in, size_t len)
0c50f5
 {
0c50f5
     S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx);
0c50f5
-    unsigned char *ivec = EVP_CIPHER_CTX_iv_noconst(ctx);
0c50f5
+    const unsigned char *ivec = EVP_CIPHER_CTX_iv(ctx);
0c50f5
     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
0c50f5
     const int enc = EVP_CIPHER_CTX_encrypting(ctx);
0c50f5
+	 unsigned char iv[EVP_MAX_IV_LENGTH];
0c50f5
 
0c50f5
     if (out != in
0c50f5
             || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->aes.ccm.m))
0c50f5
@@ -2152,8 +2145,9 @@ static int s390x_aes_ccm_tls_cipher(EVP_
0c50f5
      * Get explicit iv (sequence number). We already have fixed iv
0c50f5
      * (server/client_write_iv) here.
0c50f5
      */
0c50f5
-    memcpy(ivec + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN);
0c50f5
-    s390x_aes_ccm_setiv(cctx, ivec, len);
0c50f5
+    memcpy(iv, ivec, sizeof(iv));
0c50f5
+    memcpy(iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN);
0c50f5
+    s390x_aes_ccm_setiv(cctx, iv, len);
0c50f5
 
0c50f5
     /* Process aad (sequence number|type|version|length) */
0c50f5
     s390x_aes_ccm_aad(cctx, buf, cctx->aes.ccm.tls_aad_len);
0c50f5
@@ -2180,42 +2174,34 @@ static int s390x_aes_ccm_tls_cipher(EVP_
0c50f5
 }
0c50f5
 
0c50f5
 /*-
0c50f5
- * Set key and flag field and/or iv. Returns 1 if successful. Otherwise 0 is
0c50f5
- * returned.
0c50f5
+ * Set key or iv or enc/dec. Returns 1 if successful.
0c50f5
+ * Otherwise 0 is returned.
0c50f5
  */
0c50f5
 static int s390x_aes_ccm_init_key(EVP_CIPHER_CTX *ctx,
0c50f5
                                   const unsigned char *key,
0c50f5
                                   const unsigned char *iv, int enc)
0c50f5
 {
0c50f5
     S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx);
0c50f5
-    unsigned char *ivec;
0c50f5
-    int keylen;
0c50f5
+    const int keylen  = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
+    unsigned char *ivec = EVP_CIPHER_CTX_iv_noconst(ctx);
0c50f5
 
0c50f5
-    if (iv == NULL && key == NULL)
0c50f5
-        return 1;
0c50f5
+    cctx->aes.ccm.fc = S390X_AES_FC(keylen);
0c50f5
 
0c50f5
     if (key != NULL) {
0c50f5
-        keylen = EVP_CIPHER_CTX_key_length(ctx);
0c50f5
-        cctx->aes.ccm.fc = S390X_AES_FC(keylen);
0c50f5
         memcpy(cctx->aes.ccm.kmac_param.k, key, keylen);
0c50f5
-
0c50f5
-        /* Store encoded m and l. */
0c50f5
-        cctx->aes.ccm.nonce.b[0] = ((cctx->aes.ccm.l - 1) & 0x7)
0c50f5
-                                 | (((cctx->aes.ccm.m - 2) >> 1) & 0x7) << 3;
0c50f5
-        memset(cctx->aes.ccm.nonce.b + 1, 0,
0c50f5
-               sizeof(cctx->aes.ccm.nonce.b));
0c50f5
-        cctx->aes.ccm.blocks = 0;
0c50f5
-
0c50f5
         cctx->aes.ccm.key_set = 1;
0c50f5
     }
0c50f5
-
0c50f5
     if (iv != NULL) {
0c50f5
-        ivec = EVP_CIPHER_CTX_iv_noconst(ctx);
0c50f5
         memcpy(ivec, iv, 15 - cctx->aes.ccm.l);
0c50f5
-
0c50f5
         cctx->aes.ccm.iv_set = 1;
0c50f5
     }
0c50f5
+    /* Store encoded m and l. */
0c50f5
+    cctx->aes.ccm.nonce.b[0] = ((cctx->aes.ccm.l - 1) & 0x7)
0c50f5
+			                 | (((cctx->aes.ccm.m - 2) >> 1) & 0x7) << 3;
0c50f5
+    memset(cctx->aes.ccm.nonce.b + 1, 0, sizeof(cctx->aes.ccm.nonce.b) - 1);
0c50f5
 
0c50f5
+    cctx->aes.ccm.blocks = 0;
0c50f5
+    cctx->aes.ccm.len_set = 0;
0c50f5
     return 1;
0c50f5
 }
0c50f5
 
0c50f5
@@ -2230,8 +2216,9 @@ static int s390x_aes_ccm_cipher(EVP_CIPH
0c50f5
 {
0c50f5
     S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx);
0c50f5
     const int enc = EVP_CIPHER_CTX_encrypting(ctx);
0c50f5
+    const unsigned char *ivec = EVP_CIPHER_CTX_iv(ctx);
0c50f5
+    unsigned char *buf;
0c50f5
     int rv;
0c50f5
-    unsigned char *buf, *ivec;
0c50f5
 
0c50f5
     if (!cctx->aes.ccm.key_set)
0c50f5
         return -1;
0c50f5
@@ -2253,7 +2240,6 @@ static int s390x_aes_ccm_cipher(EVP_CIPH
0c50f5
     if (out == NULL) {
0c50f5
         /* Update(): Pass message length. */
0c50f5
         if (in == NULL) {
0c50f5
-            ivec = EVP_CIPHER_CTX_iv_noconst(ctx);
0c50f5
             s390x_aes_ccm_setiv(cctx, ivec, len);
0c50f5
 
0c50f5
             cctx->aes.ccm.len_set = 1;
0c50f5
@@ -2279,7 +2265,6 @@ static int s390x_aes_ccm_cipher(EVP_CIPH
0c50f5
          * In case message length was not previously set explicitly via
0c50f5
          * Update(), set it now.
0c50f5
          */
0c50f5
-        ivec = EVP_CIPHER_CTX_iv_noconst(ctx);
0c50f5
         s390x_aes_ccm_setiv(cctx, ivec, len);
0c50f5
 
0c50f5
         cctx->aes.ccm.len_set = 1;
0c50f5
@@ -2304,9 +2289,6 @@ static int s390x_aes_ccm_cipher(EVP_CIPH
0c50f5
         if (rv == -1)
0c50f5
             OPENSSL_cleanse(out, len);
0c50f5
 
0c50f5
-        cctx->aes.ccm.iv_set = 0;
0c50f5
-        cctx->aes.ccm.tag_set = 0;
0c50f5
-        cctx->aes.ccm.len_set = 0;
0c50f5
         return rv;
0c50f5
     }
0c50f5
 }
0c50f5
@@ -2414,9 +2396,6 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER
0c50f5
             return 0;
0c50f5
 
0c50f5
         memcpy(ptr, cctx->aes.ccm.kmac_param.icv.b, cctx->aes.ccm.m);
0c50f5
-        cctx->aes.ccm.tag_set = 0;
0c50f5
-        cctx->aes.ccm.iv_set = 0;
0c50f5
-        cctx->aes.ccm.len_set = 0;
0c50f5
         return 1;
0c50f5
 
0c50f5
     case EVP_CTRL_COPY:
0c50f5
@@ -2453,7 +2432,7 @@ static const EVP_CIPHER s390x_aes_##keyl
0c50f5
     nid##_##keylen##_##nmode,blocksize,					\
0c50f5
     keylen / 8,								\
0c50f5
     ivlen,								\
0c50f5
-    flags | EVP_CIPH_##MODE##_MODE,					\
0c50f5
+    flags | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_##MODE##_MODE,		\
0c50f5
     s390x_aes_##mode##_init_key,					\
0c50f5
     s390x_aes_##mode##_cipher,						\
0c50f5
     NULL,								\
0c50f5
@@ -2490,7 +2469,7 @@ static const EVP_CIPHER s390x_aes_##keyl
0c50f5
     blocksize,								\
0c50f5
     (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) * keylen / 8,	\
0c50f5
     ivlen,								\
0c50f5
-    flags | EVP_CIPH_##MODE##_MODE,					\
0c50f5
+    flags | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_##MODE##_MODE,		\
0c50f5
     s390x_aes_##mode##_init_key,					\
0c50f5
     s390x_aes_##mode##_cipher,						\
0c50f5
     s390x_aes_##mode##_cleanup,						\