]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
auth/gensec: fix AES schannel seal and unseal
authorGünther Deschner <gd@samba.org>
Tue, 17 Sep 2019 20:37:06 +0000 (22:37 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Mon, 7 Oct 2019 08:13:44 +0000 (08:13 +0000)
Workaround bug present in gnutls 3.6.8:

gnutls_cipher_decrypt() uses an optimization
internally that breaks decryption when processing
buffers with their length not being a multiple
of the blocksize.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Pair-Programmed-With: Guenther Deschner <gd@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
auth/gensec/schannel.c
selftest/knownfail

index b5e6289ef3f8cfa273b90a5ea3b890781930d88e..0cdae141ead1767b9cbeee41c4e8da83315f8652 100644 (file)
@@ -306,11 +306,6 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state,
                                return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
                        }
 
-                       /*
-                        * Looks like we have to reuse the initial IV which is
-                        * cryptographically wrong!
-                        */
-                       gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size);
                        rc = gnutls_cipher_encrypt(cipher_hnd,
                                                   data,
                                                   length);
@@ -319,26 +314,44 @@ static NTSTATUS netsec_do_seal(struct schannel_state *state,
                                return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
                        }
                } else {
-                       rc = gnutls_cipher_decrypt(cipher_hnd,
-                                                  confounder,
-                                                  8);
-                       if (rc < 0) {
-                               gnutls_cipher_deinit(cipher_hnd);
-                               return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
-                       }
 
                        /*
-                        * Looks like we have to reuse the initial IV which is
-                        * cryptographically wrong!
+                        * Workaround bug present in gnutls 3.6.8:
+                        *
+                        * gnutls_cipher_decrypt() uses an optimization
+                        * internally that breaks decryption when processing
+                        * buffers with their length not being a multiple
+                        * of the blocksize.
                         */
-                       gnutls_cipher_set_iv(cipher_hnd, iv.data, iv.size);
+
+                       uint8_t tmp[16] = { 0, };
+                       uint32_t tmp_dlength = MIN(length, sizeof(tmp) - 8);
+
+                       memcpy(tmp, confounder, 8);
+                       memcpy(tmp + 8, data, tmp_dlength);
+
                        rc = gnutls_cipher_decrypt(cipher_hnd,
-                                                  data,
-                                                  length);
+                                                  tmp,
+                                                  8 + tmp_dlength);
                        if (rc < 0) {
+                               ZERO_STRUCT(tmp);
                                gnutls_cipher_deinit(cipher_hnd);
                                return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
                        }
+
+                       memcpy(confounder, tmp, 8);
+                       memcpy(data, tmp + 8, tmp_dlength);
+                       ZERO_STRUCT(tmp);
+
+                       if (length > tmp_dlength) {
+                               rc = gnutls_cipher_decrypt(cipher_hnd,
+                                                          data + tmp_dlength,
+                                                          length - tmp_dlength);
+                               if (rc < 0) {
+                                       gnutls_cipher_deinit(cipher_hnd);
+                                       return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
+                               }
+                       }
                }
                gnutls_cipher_deinit(cipher_hnd);
 #else /* NOT HAVE_GNUTLS_AES_CFB8 */
index 6d229192e013ea8b912ac9d28107cc9dc10b9b1e..82259dcfe907a6f71db6b61cf56a0cccf15e9c2c 100644 (file)
 ^samba.tests.ntlmdisabled.python\(ktest\).python2.ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\)
 ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python3.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\)
 ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).python2.ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\)
-^samba.unittests.schannel.torture_schannel_seal_aes