|
|
b6b438 |
From 279d31dfa642126ce7670292390e02b2e33ea36e Mon Sep 17 00:00:00 2001
|
|
|
b6b438 |
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
|
|
|
b6b438 |
Date: Tue, 17 Sep 2019 22:37:06 +0200
|
|
|
b6b438 |
Subject: [PATCH 133/187] auth/gensec: fix AES schannel seal and unseal
|
|
|
b6b438 |
|
|
|
b6b438 |
Workaround bug present in gnutls 3.6.8:
|
|
|
b6b438 |
|
|
|
b6b438 |
gnutls_cipher_decrypt() uses an optimization
|
|
|
b6b438 |
internally that breaks decryption when processing
|
|
|
b6b438 |
buffers with their length not being a multiple
|
|
|
b6b438 |
of the blocksize.
|
|
|
b6b438 |
|
|
|
b6b438 |
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
|
|
b6b438 |
Pair-Programmed-With: Guenther Deschner <gd@samba.org>
|
|
|
b6b438 |
Reviewed-by: Andreas Schneider <asn@samba.org>
|
|
|
b6b438 |
(cherry picked from commit f988756599c2f7253989f2ca1dea2975dd89e6ea)
|
|
|
b6b438 |
---
|
|
|
b6b438 |
auth/gensec/schannel.c | 47 +++++++++++++++++++++++++++---------------
|
|
|
b6b438 |
selftest/knownfail | 1 -
|
|
|
b6b438 |
2 files changed, 30 insertions(+), 18 deletions(-)
|
|
|
b6b438 |
|
|
|
b6b438 |
diff --git a/auth/gensec/schannel.c b/auth/gensec/schannel.c
|
|
|
b6b438 |
index 9f2611e5f04..ea2a8b201ce 100644
|
|
|
b6b438 |
--- a/auth/gensec/schannel.c
|
|
|
b6b438 |
+++ b/auth/gensec/schannel.c
|
|
|
b6b438 |
@@ -306,11 +306,6 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state,
|
|
|
b6b438 |
return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
|
|
|
b6b438 |
}
|
|
|
b6b438 |
|
|
|
b6b438 |
- /*
|
|
|
b6b438 |
- * Looks like we have to reuse the initial IV which is
|
|
|
b6b438 |
- * cryptographically wrong!
|
|
|
b6b438 |
- */
|
|
|
b6b438 |
- gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size);
|
|
|
b6b438 |
rc = gnutls_cipher_encrypt(cipher_hnd,
|
|
|
b6b438 |
data,
|
|
|
b6b438 |
length);
|
|
|
b6b438 |
@@ -319,26 +314,44 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state,
|
|
|
b6b438 |
return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
|
|
|
b6b438 |
}
|
|
|
b6b438 |
} else {
|
|
|
b6b438 |
- rc = gnutls_cipher_decrypt(cipher_hnd,
|
|
|
b6b438 |
- confounder,
|
|
|
b6b438 |
- 8);
|
|
|
b6b438 |
- if (rc < 0) {
|
|
|
b6b438 |
- gnutls_cipher_deinit(cipher_hnd);
|
|
|
b6b438 |
- return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
|
|
|
b6b438 |
- }
|
|
|
b6b438 |
|
|
|
b6b438 |
/*
|
|
|
b6b438 |
- * Looks like we have to reuse the initial IV which is
|
|
|
b6b438 |
- * cryptographically wrong!
|
|
|
b6b438 |
+ * Workaround bug present in gnutls 3.6.8:
|
|
|
b6b438 |
+ *
|
|
|
b6b438 |
+ * gnutls_cipher_decrypt() uses an optimization
|
|
|
b6b438 |
+ * internally that breaks decryption when processing
|
|
|
b6b438 |
+ * buffers with their length not being a multiple
|
|
|
b6b438 |
+ * of the blocksize.
|
|
|
b6b438 |
*/
|
|
|
b6b438 |
- gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size);
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ uint8_t tmp[16] = { 0, };
|
|
|
b6b438 |
+ uint32_t tmp_dlength = MIN(length, sizeof(tmp) - 8);
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ memcpy(tmp, confounder, 8);
|
|
|
b6b438 |
+ memcpy(tmp + 8, data, tmp_dlength);
|
|
|
b6b438 |
+
|
|
|
b6b438 |
rc = gnutls_cipher_decrypt(cipher_hnd,
|
|
|
b6b438 |
- data,
|
|
|
b6b438 |
- length);
|
|
|
b6b438 |
+ tmp,
|
|
|
b6b438 |
+ 8 + tmp_dlength);
|
|
|
b6b438 |
if (rc < 0) {
|
|
|
b6b438 |
+ ZERO_STRUCT(tmp);
|
|
|
b6b438 |
gnutls_cipher_deinit(cipher_hnd);
|
|
|
b6b438 |
return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
|
|
|
b6b438 |
}
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ memcpy(confounder, tmp, 8);
|
|
|
b6b438 |
+ memcpy(data, tmp + 8, tmp_dlength);
|
|
|
b6b438 |
+ ZERO_STRUCT(tmp);
|
|
|
b6b438 |
+
|
|
|
b6b438 |
+ if (length > tmp_dlength) {
|
|
|
b6b438 |
+ rc = gnutls_cipher_decrypt(cipher_hnd,
|
|
|
b6b438 |
+ data + tmp_dlength,
|
|
|
b6b438 |
+ length - tmp_dlength);
|
|
|
b6b438 |
+ if (rc < 0) {
|
|
|
b6b438 |
+ gnutls_cipher_deinit(cipher_hnd);
|
|
|
b6b438 |
+ return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
+ }
|
|
|
b6b438 |
}
|
|
|
b6b438 |
gnutls_cipher_deinit(cipher_hnd);
|
|
|
b6b438 |
#else /* NOT HAVE_GNUTLS_AES_CFB8 */
|
|
|
b6b438 |
diff --git a/selftest/knownfail b/selftest/knownfail
|
|
|
b6b438 |
index 95db97a44e0..7b54b77a708 100644
|
|
|
b6b438 |
--- a/selftest/knownfail
|
|
|
b6b438 |
+++ b/selftest/knownfail
|
|
|
b6b438 |
@@ -374,4 +374,3 @@
|
|
|
b6b438 |
^samba.tests.ntlmdisabled.python\(ktest\).python2.ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\)
|
|
|
b6b438 |
^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python3.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\)
|
|
|
b6b438 |
^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python2.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\)
|
|
|
b6b438 |
-^samba.unittests.schannel.torture_schannel_seal_aes
|
|
|
b6b438 |
--
|
|
|
b6b438 |
2.23.0
|
|
|
b6b438 |
|