crypto: Rely on GnuTLS 3.6.13 and gnutls_pbkdf2()
[samba.git] / lib / crypto / tests / test_gnutls_aead_aes_256_cbc_hmac_sha512.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * Copyright (C) 2021-2022 Andreas Schneider <asn@samba.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <setjmp.h>
24 #include <cmocka.h>
25
26 #include <talloc.h>
27
28 #include "lib/replace/replace.h"
29 #include "lib/util/discard.h"
30 #include "lib/util/genrand.h"
31 #include "lib/util/data_blob.h"
32 #include "lib/util/talloc_stack.h"
33 #include "lib/crypto/gnutls_helpers.h"
34 #include "librpc/rpc/dcerpc_samr.h"
35
36 #include <gnutls/gnutls.h>
37 #include <gnutls/crypto.h>
38
39 #include "lib/crypto/gnutls_aead_aes_256_cbc_hmac_sha512.c"
40
41 /* The following hexdumps are from a Windows Server 2022 time trace */
42 static const uint8_t session_key[] = {
43         0x96, 0x17, 0x39, 0x9c, 0xa7, 0x54, 0x9e, 0x41,
44         0xc4, 0x79, 0x71, 0x4b, 0xa0, 0x89, 0x5b, 0x0a
45 };
46
47 static const uint8_t salt_data[] = {
48         0xac, 0x9c, 0xad, 0xcb, 0x66, 0xed, 0x2d, 0x05,
49         0x55, 0x13, 0x18, 0xa9, 0xa5, 0x6b, 0xf9, 0x6f
50 };
51
52 static const uint8_t plaintext_data[] = {
53         0x14, 0x00, 0x50, 0x00, 0x61, 0x00, 0x24, 0x00,
54         0x24, 0x00, 0x77, 0x00, 0x30, 0x00, 0x72, 0x00,
55         0x64, 0x00, 0x40, 0x00, 0x32, 0x00, 0xc2, 0x34,
56         0x7d, 0x21, 0x79, 0x05, 0xef, 0x88, 0xd7, 0x11,
57         0xec, 0xe2, 0xce, 0xb5, 0xd4, 0x4d, 0x64, 0x2d,
58         0x15, 0x79, 0x01, 0x39, 0xb8, 0xb9, 0x89, 0x5c,
59         0x4e, 0x71, 0xbd, 0xf0, 0x14, 0x0c, 0x87, 0x72,
60         0xa5, 0xfa, 0x90, 0xbe, 0x62, 0x55, 0xad, 0x7f,
61         0xe9, 0x7f, 0x0d, 0x20, 0x19, 0x3a, 0x76, 0xbe,
62         0xb2, 0x14, 0x6d, 0x5b, 0x25, 0x1c, 0x67, 0x3a,
63         0x23, 0x45, 0x1f, 0x7e, 0x36, 0xa0, 0x95, 0xb7,
64         0xa7, 0xb1, 0x33, 0xe1, 0xc4, 0xb6, 0xe6, 0x2d,
65         0xd8, 0x2f, 0xe7, 0xdf, 0x01, 0xe8, 0xba, 0x02,
66         0x54, 0x36, 0xe9, 0xb6, 0x5e, 0x00, 0x52, 0x9e,
67         0x64, 0x00, 0xcb, 0x3c, 0x6d, 0x05, 0x43, 0x7d,
68         0x01, 0x9c, 0x22, 0x18, 0x92, 0xe7, 0xa3, 0x55,
69         0x65, 0x6d, 0x2e, 0xa3, 0x53, 0x6e, 0xc0, 0x67,
70         0x26, 0xac, 0xaa, 0x98, 0xa4, 0xcb, 0xb4, 0x49,
71         0x13, 0x60, 0xd4, 0x33, 0x2c, 0x77, 0x58, 0x5e,
72         0x50, 0x45, 0xaa, 0x1e, 0x05, 0x15, 0x18, 0x59,
73         0x55, 0xca, 0x14, 0x37, 0x31, 0xac, 0x63, 0xfc,
74         0x63, 0xa8, 0x2a, 0xa9, 0x99, 0xec, 0x49, 0x87,
75         0x64, 0x1d, 0x4e, 0xdd, 0xa3, 0xd0, 0xdc, 0x08,
76         0x00, 0x17, 0xf4, 0x2f, 0x9c, 0x4a, 0x17, 0xc7,
77         0xbd, 0x30, 0xb7, 0x0e, 0x81, 0xe4, 0xd5, 0x94,
78         0x31, 0xff, 0xd6, 0xcc, 0xc6, 0xbb, 0x39, 0xcd,
79         0x72, 0xfe, 0xa6, 0x3d, 0x0d, 0x88, 0x68, 0x40,
80         0xf8, 0x51, 0x2b, 0xe6, 0xc9, 0xaa, 0x84, 0xf3,
81         0xf4, 0x6e, 0x55, 0x37, 0xbf, 0x5d, 0x87, 0xce,
82         0xa6, 0x80, 0x4f, 0x8f, 0x8f, 0x7b, 0xe8, 0x30,
83         0xc3, 0x2e, 0x24, 0xc7, 0x3e, 0xf1, 0x9f, 0xa6,
84         0x77, 0xca, 0x04, 0xbe, 0xb5, 0xe1, 0x40, 0x59,
85         0x43, 0xc5, 0x30, 0xc8, 0xe7, 0xbf, 0xab, 0xfa,
86         0x86, 0x62, 0xd9, 0x3a, 0x8e, 0xa9, 0x34, 0x73,
87         0x20, 0x7b, 0x61, 0x1b, 0x0e, 0xca, 0x98, 0xec,
88         0xa1, 0xc1, 0x78, 0xa9, 0xa7, 0x6c, 0x8c, 0xe3,
89         0x21, 0x7d, 0xb9, 0x90, 0xe2, 0x73, 0x1a, 0x99,
90         0x1d, 0x44, 0xa8, 0xd5, 0x7f, 0x0a, 0x59, 0x47,
91         0xd0, 0xf5, 0x6c, 0x14, 0xff, 0x4a, 0x29, 0x20,
92         0xb5, 0xfc, 0xe9, 0xf0, 0xa5, 0x35, 0x9e, 0x1c,
93         0xa1, 0x4c, 0xec, 0xb5, 0x7d, 0x2d, 0x27, 0xff,
94         0x7a, 0x42, 0x18, 0xb8, 0x53, 0x4e, 0xfb, 0xec,
95         0xb1, 0xc1, 0x65, 0x2d, 0xa4, 0x69, 0x85, 0x56,
96         0x61, 0x6d, 0x21, 0x66, 0x88, 0x31, 0xdf, 0xba,
97         0x28, 0xc6, 0x9a, 0xf8, 0xb7, 0xf6, 0x2a, 0x43,
98         0xba, 0x9b, 0x84, 0x14, 0xce, 0xa9, 0xc9, 0xf5,
99         0x85, 0x6f, 0x31, 0x89, 0x8d, 0xfc, 0x25, 0x2e,
100         0x98, 0x25, 0x5a, 0x03, 0xf0, 0xb8, 0x5d, 0x4a,
101         0xd4, 0x4c, 0xc8, 0x62, 0x4e, 0xeb, 0x07, 0xc8,
102         0x5c, 0x9e, 0x63, 0x30, 0xfe, 0x9f, 0x0f, 0x96,
103         0xd0, 0xd7, 0x70, 0xad, 0xcd, 0x84, 0xbc, 0x1e,
104         0x48, 0xa0, 0x20, 0x14, 0x10, 0xa4, 0xb1, 0x5b,
105         0x05, 0x36, 0x9a, 0x6d, 0xb0, 0x10, 0x98, 0xbd,
106         0x8d, 0xa2, 0xd1, 0xb2, 0xfa, 0x23, 0x37, 0xeb,
107         0xb0, 0x04, 0x53, 0xcb, 0xa1, 0xa9, 0xc4, 0x88,
108         0xdd, 0xf9, 0x80, 0xf5, 0xa9, 0xcd, 0x7b, 0xf8,
109         0x77, 0x0b, 0x19, 0x84, 0x4c, 0xef, 0x2c, 0x14,
110         0xa1, 0xdc, 0x9f, 0x2f, 0x41, 0xd0, 0xd0, 0x33,
111         0x29, 0x8a, 0xb9, 0x39, 0x7e, 0xc9, 0x7f, 0xe7,
112         0x63, 0x64, 0xa4, 0x7b, 0x4a, 0x6a, 0x33, 0xa7,
113         0xaa, 0xf6, 0xca, 0x98, 0xc4, 0x9b, 0x62, 0x5b,
114         0xcd, 0x53, 0x82, 0xbf, 0xf0, 0x0b, 0x9c, 0xe7,
115         0xb2, 0x44, 0x1b, 0x88, 0x71, 0x61, 0xa1, 0x36,
116         0x9e, 0x7a, 0x0a, 0x3c, 0x20, 0xd8, 0xff, 0xa1,
117         0x23, 0x66
118 };
119
120 static const uint8_t expected_enc_key[] = {
121         0xd9, 0xb2, 0x8b, 0xa1, 0x15, 0x74, 0xf6, 0x5a,
122         0x73, 0xea, 0x82, 0xba, 0x99, 0x37, 0x54, 0x25,
123         0x1b, 0x27, 0x20, 0xaa, 0xa3, 0xf7, 0xd5, 0x23,
124         0x8f, 0x02, 0xe6, 0xe7, 0x21, 0x5b, 0xd2, 0xa9
125 };
126
127 static const uint8_t expected_mac_key[] = {
128         0x8a, 0x04, 0x46, 0x6d, 0x5e, 0xe6, 0x2d, 0xb8,
129         0x32, 0x9e, 0xab, 0xbe, 0xa4, 0x8b, 0x3f, 0x6c,
130         0x3c, 0x1c, 0xa1, 0xaa, 0xb8, 0xec, 0x9c, 0x43,
131         0xbc, 0x4b, 0x91, 0x35, 0x6f, 0x3a, 0xc4, 0xe2,
132         0x62, 0x9b, 0xe8, 0x12, 0x63, 0x73, 0x94, 0x2a,
133         0x59, 0x47, 0xfc, 0xd8, 0x78, 0x5d, 0x6d, 0x68,
134         0x1b, 0x9f, 0x35, 0x31, 0x90, 0x27, 0xc8, 0xab,
135         0x88, 0x8d, 0x80, 0xad, 0x7b, 0xea, 0xcd, 0xf5
136 };
137
138 static const uint8_t expected_auth_tag[] = {
139         0x0a, 0x7a, 0xaf, 0x9e, 0xc1, 0x6e, 0x03, 0x12,
140         0x51, 0x76, 0x04, 0xb2, 0x01, 0x17, 0xeb, 0x04,
141         0xf3, 0xdd, 0xe3, 0xa7, 0x90, 0xfd, 0xc0, 0xca,
142         0x96, 0x31, 0xbf, 0x30, 0x9e, 0xc5, 0x05, 0x5a,
143         0xbc, 0xa8, 0xc1, 0xba, 0x56, 0x8f, 0x97, 0x5a,
144         0x4e, 0x2a, 0x14, 0x0e, 0x4b, 0xf3, 0x6d, 0x9a,
145         0x2a, 0x6e, 0xc3, 0x5e, 0x9d, 0x51, 0x0a, 0xf6,
146         0xb2, 0x1b, 0xee, 0xe7, 0xf3, 0x09, 0x30, 0xc9,
147 };
148
149 static void torture_enc_key(void **state)
150 {
151         DATA_BLOB key = data_blob_const(session_key, sizeof(session_key));
152         uint8_t enc_key[32] = {0};
153         NTSTATUS status;
154
155         status = calculate_enc_key(&key, &samr_aes256_enc_key_salt, enc_key);
156         assert_true(NT_STATUS_IS_OK(status));
157
158         assert_memory_equal(expected_enc_key, enc_key, sizeof(enc_key));
159 }
160
161 static void torture_mac_key(void **state)
162 {
163         DATA_BLOB key = data_blob_const(session_key, sizeof(session_key));
164         uint8_t mac_key[64] = {0};
165         NTSTATUS status;
166
167         status = calculate_mac_key(&key, &samr_aes256_mac_key_salt, mac_key);
168         assert_true(NT_STATUS_IS_OK(status));
169
170         assert_memory_equal(expected_mac_key, mac_key, sizeof(mac_key));
171 }
172
173 static void torture_encrypt(void **state)
174 {
175         NTSTATUS status;
176         TALLOC_CTX *frame = talloc_stackframe();
177         DATA_BLOB cek = {
178                 .data = discard_const_p(uint8_t, session_key),
179                 .length = sizeof(session_key),
180         };
181         const DATA_BLOB plaintext = {
182                 .data = discard_const_p(uint8_t, plaintext_data),
183                 .length = sizeof(plaintext_data),
184         };
185         DATA_BLOB iv = {
186                 .data = discard_const_p(uint8_t, salt_data),
187                 .length = sizeof(salt_data),
188         };
189         DATA_BLOB ctext;
190         uint8_t auth_tag[64] = {0};
191
192         assert_int_equal(iv.length, 16);
193
194         status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
195                 frame,
196                 &plaintext,
197                 &cek,
198                 &samr_aes256_enc_key_salt,
199                 &samr_aes256_mac_key_salt,
200                 &iv,
201                 &ctext,
202                 auth_tag);
203         assert_true(NT_STATUS_IS_OK(status));
204         assert_int_equal(ctext.length, 528);
205         assert_non_null(ctext.data);
206
207         assert_memory_equal(expected_auth_tag, auth_tag, sizeof(auth_tag));
208
209         TALLOC_FREE(frame);
210 }
211
212 static void torture_encrypt_decrypt(void **state)
213 {
214         NTSTATUS status;
215         TALLOC_CTX *frame = talloc_stackframe();
216         DATA_BLOB cek = data_blob_const(session_key, sizeof(session_key));
217         const DATA_BLOB plaintext =
218                 data_blob_const(plaintext_data, sizeof(plaintext_data));
219         DATA_BLOB iv = data_blob_const(salt_data, sizeof(salt_data));
220         DATA_BLOB cipher_text;
221         uint8_t auth_tag[64] = {0};
222         DATA_BLOB plaintext_decrypted;
223
224         status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
225                 frame,
226                 &plaintext,
227                 &cek,
228                 &samr_aes256_enc_key_salt,
229                 &samr_aes256_mac_key_salt,
230                 &iv,
231                 &cipher_text,
232                 auth_tag);
233         assert_true(NT_STATUS_IS_OK(status));
234         assert_int_equal(cipher_text.length, 528);
235         assert_in_range(cipher_text.length,
236                         plaintext.length,
237                         plaintext.length + 16);
238         assert_non_null(cipher_text.data);
239
240         status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
241                 frame,
242                 &cipher_text,
243                 &cek,
244                 &samr_aes256_enc_key_salt,
245                 &samr_aes256_mac_key_salt,
246                 &iv,
247                 auth_tag,
248                 &plaintext_decrypted);
249         assert_true(NT_STATUS_IS_OK(status));
250         assert_non_null(plaintext_decrypted.data);
251         assert_int_equal(plaintext_decrypted.length, plaintext.length);
252         assert_memory_equal(plaintext_decrypted.data,
253                             plaintext.data,
254                             plaintext.length);
255
256         TALLOC_FREE(frame);
257 }
258
259 /* The following hexdumps are from a Windows Server 2022 time trace */
260 static uint8_t pbkdf2_nt_hash[] = {
261         0xf8, 0x48, 0x54, 0xde, 0xb8, 0x36, 0x10, 0x33,
262         0xca, 0xea, 0x5c, 0x95, 0x96, 0x66, 0x99, 0x38
263 };
264
265 static uint8_t pbkdf2_iv[] = {
266         0xd5, 0xbe, 0x4f, 0xd7, 0xb6, 0x85, 0xd1, 0xea,
267         0xfd, 0x3b, 0xf4, 0x29, 0x83, 0xce, 0x10, 0x44
268 };
269
270 static uint8_t expected_pbkdf2_derived_key[] = {
271         0xf1, 0xe6, 0xb2, 0x6a, 0x78, 0x28, 0x63, 0x05,
272         0x77, 0x38, 0xc9, 0x71, 0xd2, 0x05, 0x88, 0x58
273 };
274
275 static void torture_pbkdf2(void **state)
276 {
277         gnutls_datum_t nt_key = {
278                 .data = pbkdf2_nt_hash,
279                 .size = sizeof(pbkdf2_nt_hash),
280         };
281         gnutls_datum_t iv_datum = {
282                 .data = pbkdf2_iv,
283                 .size = sizeof(pbkdf2_iv),
284         };
285         uint64_t pbkdf2_iterations = 23533;
286         uint8_t derived_key[16] = {0};
287         int rc;
288
289         rc = gnutls_pbkdf2(GNUTLS_MAC_SHA512,
290                            &nt_key,
291                            &iv_datum,
292                            pbkdf2_iterations,
293                            derived_key,
294                            sizeof(derived_key));
295         assert_int_equal(rc, 0);
296         assert_memory_equal(derived_key,
297                             expected_pbkdf2_derived_key,
298                             sizeof(derived_key));
299 }
300
301 int main(int argc, char *argv[])
302 {
303         int rc;
304         const struct CMUnitTest tests[] = {
305                 cmocka_unit_test(torture_enc_key),
306                 cmocka_unit_test(torture_mac_key),
307                 cmocka_unit_test(torture_encrypt),
308                 cmocka_unit_test(torture_encrypt_decrypt),
309                 cmocka_unit_test(torture_pbkdf2),
310         };
311
312         if (argc == 2) {
313                 cmocka_set_test_filter(argv[1]);
314         }
315         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
316
317         rc = cmocka_run_group_tests(tests, NULL, NULL);
318
319         return rc;
320 }