diff -Nru openssl-1.1.1/debian/changelog openssl-1.1.1/debian/changelog --- openssl-1.1.1/debian/changelog 2021-03-22 12:42:42.000000000 +0100 +++ openssl-1.1.1/debian/changelog 2021-07-23 14:32:42.000000000 +0200 @@ -1,3 +1,9 @@ +openssl (1.1.1-1ubuntu2.1~18.04.10) bionic; urgency=medium + + * Cherry-pick an upstream patch to fix s390x AES code (LP: #1931994) + + -- Simon Chopin Fri, 23 Jul 2021 14:32:42 +0200 + openssl (1.1.1-1ubuntu2.1~18.04.9) bionic-security; urgency=medium * SECURITY UPDATE: NULL pointer deref in signature_algorithms processing diff -Nru openssl-1.1.1/debian/patches/lp1931994-s390x-evp-init-fix.patch openssl-1.1.1/debian/patches/lp1931994-s390x-evp-init-fix.patch --- openssl-1.1.1/debian/patches/lp1931994-s390x-evp-init-fix.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl-1.1.1/debian/patches/lp1931994-s390x-evp-init-fix.patch 2021-07-23 14:32:42.000000000 +0200 @@ -0,0 +1,399 @@ +From dc67210d909b5dd7a50f60a96f36f3f5a891b1c8 Mon Sep 17 00:00:00 2001 +From: Patrick Steuer +Date: Fri, 16 Apr 2021 15:09:46 +0000 +Subject: [PATCH] s390x: cipher must set EVP_CIPH_ALWAYS_CALL_INIT flag + +The s390x cipher implementations must call their init function +even if the key argument is NULL to allow initializing the +cipher operation's context in any order. + +Signed-off-by: Patrick Steuer + +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/14900) +--- + crypto/evp/e_aes.c | 166 ++++++++++++++++++++------------------------- + 1 file changed, 74 insertions(+), 92 deletions(-) + +--- a/crypto/evp/e_aes.c ++++ b/crypto/evp/e_aes.c +@@ -1138,9 +1138,9 @@ + static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +-# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */ +-# define S390X_aes_192_cbc_CAPABLE 1 +-# define S390X_aes_256_cbc_CAPABLE 1 ++# define S390X_aes_128_cbc_CAPABLE 0 /* checked by callee */ ++# define S390X_aes_192_cbc_CAPABLE 0 ++# define S390X_aes_256_cbc_CAPABLE 0 + # define S390X_AES_CBC_CTX EVP_AES_KEY + + # define s390x_aes_cbc_init_key aes_init_key +@@ -1160,11 +1160,11 @@ + S390X_AES_ECB_CTX *cctx = EVP_C_DATA(S390X_AES_ECB_CTX, ctx); + const int keylen = EVP_CIPHER_CTX_key_length(ctx); + +- cctx->fc = S390X_AES_FC(keylen); +- if (!enc) +- cctx->fc |= S390X_DECRYPT; ++ cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT); ++ ++ if (key != NULL) ++ memcpy(cctx->km.param.k, key, keylen); + +- memcpy(cctx->km.param.k, key, keylen); + return 1; + } + +@@ -1192,14 +1192,17 @@ + const unsigned char *ivec, int enc) + { + S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx); +- const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx); ++ const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx); + const int keylen = EVP_CIPHER_CTX_key_length(ctx); + const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + +- memcpy(cctx->kmo.param.cv, iv, ivlen); +- memcpy(cctx->kmo.param.k, key, keylen); + cctx->fc = S390X_AES_FC(keylen); ++ ++ if (key != NULL) ++ memcpy(cctx->kmo.param.k, key, keylen); ++ + cctx->res = 0; ++ memcpy(cctx->kmo.param.cv, oiv, ivlen); + return 1; + } + +@@ -1257,18 +1260,18 @@ + const unsigned char *ivec, int enc) + { + S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); +- const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx); ++ const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx); + const int keylen = EVP_CIPHER_CTX_key_length(ctx); + const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + +- cctx->fc = S390X_AES_FC(keylen); +- cctx->fc |= 16 << 24; /* 16 bytes cipher feedback */ +- if (!enc) +- cctx->fc |= S390X_DECRYPT; ++ cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT) ++ | (16 << 24); /* 16 bytes cipher feedback */ ++ ++ if (key != NULL) ++ memcpy(cctx->kmf.param.k, key, keylen); + + cctx->res = 0; +- memcpy(cctx->kmf.param.cv, iv, ivlen); +- memcpy(cctx->kmf.param.k, key, keylen); ++ memcpy(cctx->kmf.param.cv, oiv, ivlen); + return 1; + } + +@@ -1330,17 +1333,18 @@ + const unsigned char *ivec, int enc) + { + S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); +- const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx); ++ const unsigned char *oiv = EVP_CIPHER_CTX_original_iv(ctx); + const int keylen = EVP_CIPHER_CTX_key_length(ctx); + const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); + +- cctx->fc = S390X_AES_FC(keylen); +- cctx->fc |= 1 << 24; /* 1 byte cipher feedback */ +- if (!enc) +- cctx->fc |= S390X_DECRYPT; ++ cctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT) ++ | (1 << 24); /* 1 byte cipher feedback flag */ ++ ++ if (key != NULL) ++ memcpy(cctx->kmf.param.k, key, keylen); + +- memcpy(cctx->kmf.param.cv, iv, ivlen); +- memcpy(cctx->kmf.param.k, key, keylen); ++ cctx->res = 0; ++ memcpy(cctx->kmf.param.cv, oiv, ivlen); + return 1; + } + +@@ -1363,9 +1367,9 @@ + static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +-# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */ +-# define S390X_aes_192_ctr_CAPABLE 1 +-# define S390X_aes_256_ctr_CAPABLE 1 ++# define S390X_aes_128_ctr_CAPABLE 0 /* checked by callee */ ++# define S390X_aes_192_ctr_CAPABLE 0 ++# define S390X_aes_256_ctr_CAPABLE 0 + # define S390X_AES_CTR_CTX EVP_AES_KEY + + # define s390x_aes_ctr_init_key aes_init_key +@@ -1533,8 +1537,7 @@ + /*- + * Initialize context structure. Code is big-endian. + */ +-static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx, +- const unsigned char *iv) ++static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx) + { + ctx->kma.param.t.g[0] = 0; + ctx->kma.param.t.g[1] = 0; +@@ -1545,12 +1548,11 @@ + ctx->kreslen = 0; + + if (ctx->ivlen == 12) { +- memcpy(&ctx->kma.param.j0, iv, ctx->ivlen); ++ memcpy(&ctx->kma.param.j0, ctx->iv, ctx->ivlen); + ctx->kma.param.j0.w[3] = 1; + ctx->kma.param.cv.w = 1; + } else { + /* ctx->iv has the right size and is already padded. */ +- memcpy(ctx->iv, iv, ctx->ivlen); + s390x_kma(ctx->iv, S390X_gcm_ivpadlen(ctx->ivlen), NULL, 0, NULL, + ctx->fc, &ctx->kma.param); + ctx->fc |= S390X_KMA_HS; +@@ -1660,7 +1662,7 @@ + if (gctx->iv_gen == 0 || gctx->key_set == 0) + return 0; + +- s390x_aes_gcm_setiv(gctx, gctx->iv); ++ s390x_aes_gcm_setiv(gctx); + + if (arg <= 0 || arg > gctx->ivlen) + arg = gctx->ivlen; +@@ -1680,7 +1682,7 @@ + return 0; + + memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); +- s390x_aes_gcm_setiv(gctx, gctx->iv); ++ s390x_aes_gcm_setiv(gctx); + gctx->iv_set = 1; + return 1; + +@@ -1736,43 +1738,36 @@ + } + + /*- +- * Set key and/or iv. Returns 1 on success. Otherwise 0 is returned. ++ * Set key or iv or enc/dec. Returns 1 on success. Otherwise 0 is returned. + */ + static int s390x_aes_gcm_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) + { + S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, ctx); +- int keylen; ++ const int keylen = EVP_CIPHER_CTX_key_length(ctx); + +- if (iv == NULL && key == NULL) +- return 1; ++ gctx->fc = S390X_AES_FC(keylen) | (enc ? 0 : S390X_DECRYPT); + + if (key != NULL) { +- keylen = EVP_CIPHER_CTX_key_length(ctx); ++ gctx->fc &= ~S390X_KMA_HS; + memcpy(&gctx->kma.param.k, key, keylen); +- +- gctx->fc = S390X_AES_FC(keylen); +- if (!enc) +- gctx->fc |= S390X_DECRYPT; +- +- if (iv == NULL && gctx->iv_set) +- iv = gctx->iv; +- +- if (iv != NULL) { +- s390x_aes_gcm_setiv(gctx, iv); +- gctx->iv_set = 1; +- } + gctx->key_set = 1; +- } else { +- if (gctx->key_set) +- s390x_aes_gcm_setiv(gctx, iv); +- else +- memcpy(gctx->iv, iv, gctx->ivlen); ++ } + +- gctx->iv_set = 1; ++ if (iv != NULL) { ++ memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_gen = 0; ++ gctx->iv_set = 1; + } ++ ++ if (gctx->key_set && gctx->iv_set) ++ s390x_aes_gcm_setiv(gctx); ++ ++ gctx->fc &= ~(S390X_KMA_LPC | S390X_KMA_LAAD); ++ gctx->areslen = 0; ++ gctx->mreslen = 0; ++ gctx->kreslen = 0; + return 1; + } + +@@ -1861,7 +1856,6 @@ + /* recall that we already did en-/decrypt gctx->mres + * and returned it to caller... */ + OPENSSL_cleanse(tmp, gctx->mreslen); +- gctx->iv_set = 0; + + enc = EVP_CIPHER_CTX_encrypting(ctx); + if (enc) { +@@ -1895,8 +1889,8 @@ + } + + # define S390X_AES_XTS_CTX EVP_AES_XTS_CTX +-# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */ +-# define S390X_aes_256_xts_CAPABLE 1 ++# define S390X_aes_128_xts_CAPABLE 0 /* checked by callee */ ++# define S390X_aes_256_xts_CAPABLE 0 + + # define s390x_aes_xts_init_key aes_xts_init_key + static int s390x_aes_xts_init_key(EVP_CIPHER_CTX *ctx, +@@ -2100,9 +2094,10 @@ + const unsigned char *in, size_t len) + { + S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); +- unsigned char *ivec = EVP_CIPHER_CTX_iv_noconst(ctx); ++ const unsigned char *ivec = EVP_CIPHER_CTX_iv(ctx); + unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx); + const int enc = EVP_CIPHER_CTX_encrypting(ctx); ++ unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (out != in + || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->aes.ccm.m)) +@@ -2118,8 +2113,9 @@ + * Get explicit iv (sequence number). We already have fixed iv + * (server/client_write_iv) here. + */ +- memcpy(ivec + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); +- s390x_aes_ccm_setiv(cctx, ivec, len); ++ memcpy(iv, ivec, sizeof(iv)); ++ memcpy(iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); ++ s390x_aes_ccm_setiv(cctx, iv, len); + + /* Process aad (sequence number|type|version|length) */ + s390x_aes_ccm_aad(cctx, buf, cctx->aes.ccm.tls_aad_len); +@@ -2146,42 +2142,35 @@ + } + + /*- +- * Set key and flag field and/or iv. Returns 1 if successful. Otherwise 0 is +- * returned. ++ * Set key or iv or enc/dec. Returns 1 if successful. ++ * Otherwise 0 is returned. + */ + static int s390x_aes_ccm_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) + { + S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); +- unsigned char *ivec; +- int keylen; ++ const int keylen = EVP_CIPHER_CTX_key_length(ctx); ++ unsigned char *ivec = EVP_CIPHER_CTX_iv_noconst(ctx); + +- if (iv == NULL && key == NULL) +- return 1; ++ cctx->aes.ccm.fc = S390X_AES_FC(keylen); + + if (key != NULL) { +- keylen = EVP_CIPHER_CTX_key_length(ctx); +- cctx->aes.ccm.fc = S390X_AES_FC(keylen); + memcpy(cctx->aes.ccm.kmac_param.k, key, keylen); +- +- /* Store encoded m and l. */ +- cctx->aes.ccm.nonce.b[0] = ((cctx->aes.ccm.l - 1) & 0x7) +- | (((cctx->aes.ccm.m - 2) >> 1) & 0x7) << 3; +- memset(cctx->aes.ccm.nonce.b + 1, 0, +- sizeof(cctx->aes.ccm.nonce.b)); +- cctx->aes.ccm.blocks = 0; +- + cctx->aes.ccm.key_set = 1; + } +- + if (iv != NULL) { +- ivec = EVP_CIPHER_CTX_iv_noconst(ctx); + memcpy(ivec, iv, 15 - cctx->aes.ccm.l); +- + cctx->aes.ccm.iv_set = 1; + } + ++ /* Store encoded m and l. */ ++ cctx->aes.ccm.nonce.b[0] = ((cctx->aes.ccm.l - 1) & 0x7) ++ | (((cctx->aes.ccm.m - 2) >> 1) & 0x7) << 3; ++ memset(cctx->aes.ccm.nonce.b + 1, 0, sizeof(cctx->aes.ccm.nonce.b) - 1); ++ ++ cctx->aes.ccm.blocks = 0; ++ cctx->aes.ccm.len_set = 0; + return 1; + } + +@@ -2196,8 +2185,9 @@ + { + S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); + const int enc = EVP_CIPHER_CTX_encrypting(ctx); ++ const unsigned char *ivec = EVP_CIPHER_CTX_iv(ctx); ++ unsigned char *buf; + int rv; +- unsigned char *buf, *ivec; + + if (!cctx->aes.ccm.key_set) + return -1; +@@ -2222,7 +2212,6 @@ + if (out == NULL) { + /* Update(): Pass message length. */ + if (in == NULL) { +- ivec = EVP_CIPHER_CTX_iv_noconst(ctx); + s390x_aes_ccm_setiv(cctx, ivec, len); + + cctx->aes.ccm.len_set = 1; +@@ -2244,7 +2233,6 @@ + * In case message length was not previously set explicitely via + * Update(), set it now. + */ +- ivec = EVP_CIPHER_CTX_iv_noconst(ctx); + s390x_aes_ccm_setiv(cctx, ivec, len); + + cctx->aes.ccm.len_set = 1; +@@ -2269,9 +2257,6 @@ + if (rv == -1) + OPENSSL_cleanse(out, len); + +- cctx->aes.ccm.iv_set = 0; +- cctx->aes.ccm.tag_set = 0; +- cctx->aes.ccm.len_set = 0; + return rv; + } + } +@@ -2375,9 +2360,6 @@ + return 0; + + memcpy(ptr, cctx->aes.ccm.kmac_param.icv.b, cctx->aes.ccm.m); +- cctx->aes.ccm.tag_set = 0; +- cctx->aes.ccm.iv_set = 0; +- cctx->aes.ccm.len_set = 0; + return 1; + + case EVP_CTRL_COPY: +@@ -2414,7 +2396,7 @@ + nid##_##keylen##_##nmode,blocksize, \ + keylen / 8, \ + ivlen, \ +- flags | EVP_CIPH_##MODE##_MODE, \ ++ flags | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_##MODE##_MODE, \ + s390x_aes_##mode##_init_key, \ + s390x_aes_##mode##_cipher, \ + NULL, \ +@@ -2451,7 +2433,7 @@ + blocksize, \ + (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) * keylen / 8, \ + ivlen, \ +- flags | EVP_CIPH_##MODE##_MODE, \ ++ flags | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_##MODE##_MODE, \ + s390x_aes_##mode##_init_key, \ + s390x_aes_##mode##_cipher, \ + s390x_aes_##mode##_cleanup, \ diff -Nru openssl-1.1.1/debian/patches/series openssl-1.1.1/debian/patches/series --- openssl-1.1.1/debian/patches/series 2021-03-22 12:42:42.000000000 +0100 +++ openssl-1.1.1/debian/patches/series 2021-07-23 14:32:42.000000000 +0200 @@ -30,3 +30,4 @@ CVE-2021-3449-2.patch CVE-2021-3449-3.patch CVE-2021-3449-4.patch +lp1931994-s390x-evp-init-fix.patch