2 * Unix SMB/CIFS implementation.
4 * Copyright (C) 2019 Guenther Deschner <gd@samba.org>
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.
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.
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/>.
27 #include "libcli/auth/libcli_auth.h"
29 #include "lib/crypto/gnutls_helpers.h"
30 #include <gnutls/gnutls.h>
31 #include <gnutls/crypto.h>
33 #if defined(HAVE_GNUTLS_AES_CFB8) && GNUTLS_VERSION_NUMBER > 0x03060a
34 static void torture_gnutls_aes_128_cfb_flags(void **state,
35 const DATA_BLOB session_key,
36 const DATA_BLOB seq_num_initial,
37 const DATA_BLOB confounder_initial,
38 const DATA_BLOB confounder_expected,
39 const DATA_BLOB clear_initial,
40 const DATA_BLOB crypt_expected)
42 uint8_t confounder[8];
44 gnutls_cipher_hd_t cipher_hnd = NULL;
45 uint8_t sess_kf0[16] = {0};
46 gnutls_datum_t key = {
48 .size = sizeof(sess_kf0),
51 gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_CFB8);
60 assert_int_equal(session_key.length, 16);
61 assert_int_equal(seq_num_initial.length, 8);
62 assert_int_equal(confounder_initial.length, 8);
63 assert_int_equal(confounder_expected.length, 8);
64 assert_int_equal(clear_initial.length, crypt_expected.length);
66 DEBUG(0,("checking buffer size: %d\n", (int)clear_initial.length));
68 io = data_blob_dup_talloc(NULL, clear_initial);
69 assert_non_null(io.data);
70 assert_int_equal(io.length, clear_initial.length);
72 memcpy(confounder, confounder_initial.data, 8);
74 DEBUG(0,("confounder before crypt:\n"));
75 dump_data(0, confounder, 8);
76 DEBUG(0,("initial seq num:\n"));
77 dump_data(0, seq_num_initial.data, 8);
78 DEBUG(0,("io data before crypt:\n"));
79 dump_data(0, io.data, io.length);
81 for (i = 0; i < key.size; i++) {
82 key.data[i] = session_key.data[i] ^ 0xf0;
87 memcpy(iv.data + 0, seq_num_initial.data, 8);
88 memcpy(iv.data + 8, seq_num_initial.data, 8);
90 rc = gnutls_cipher_init(&cipher_hnd,
91 GNUTLS_CIPHER_AES_128_CFB8,
94 assert_int_equal(rc, 0);
96 rc = gnutls_cipher_encrypt(cipher_hnd,
99 assert_int_equal(rc, 0);
101 rc = gnutls_cipher_encrypt(cipher_hnd,
104 assert_int_equal(rc, 0);
106 DEBUG(0,("confounder after crypt:\n"));
107 dump_data(0, confounder, 8);
108 DEBUG(0,("initial seq num:\n"));
109 dump_data(0, seq_num_initial.data, 8);
110 DEBUG(0,("io data after crypt:\n"));
111 dump_data(0, io.data, io.length);
112 assert_memory_equal(io.data, crypt_expected.data, crypt_expected.length);
113 assert_memory_equal(confounder, confounder_expected.data, confounder_expected.length);
115 rc = gnutls_cipher_decrypt(cipher_hnd,
118 assert_int_equal(rc, 0);
120 rc = gnutls_cipher_decrypt(cipher_hnd,
123 assert_int_equal(rc, 0);
124 gnutls_cipher_deinit(cipher_hnd);
126 DEBUG(0,("confounder after decrypt:\n"));
127 dump_data(0, confounder, 8);
128 DEBUG(0,("initial seq num:\n"));
129 dump_data(0, seq_num_initial.data, 8);
130 DEBUG(0,("io data after decrypt:\n"));
131 dump_data(0, io.data, io.length);
132 assert_memory_equal(io.data, clear_initial.data, clear_initial.length);
133 assert_memory_equal(confounder, confounder_initial.data, confounder_initial.length);
137 static void torture_gnutls_aes_128_cfb(void **state)
139 #if defined(HAVE_GNUTLS_AES_CFB8) && GNUTLS_VERSION_NUMBER > 0x03060a
140 const uint8_t _session_key[16] = {
141 0x8E, 0xE8, 0x27, 0x85, 0x83, 0x41, 0x3C, 0x8D,
142 0xC9, 0x54, 0x70, 0x75, 0x8E, 0xC9, 0x69, 0x91
144 const DATA_BLOB session_key = data_blob_const(_session_key, 16);
145 const uint8_t _seq_num_initial[8] = {
146 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00
148 const DATA_BLOB seq_num_initial =
149 data_blob_const(_seq_num_initial, 8);
150 const uint8_t _confounder_initial[8] = {
151 0x6E, 0x09, 0x25, 0x94, 0x01, 0xA0, 0x09, 0x31
153 const DATA_BLOB confounder_initial =
154 data_blob_const(_confounder_initial, 8);
155 const uint8_t _confounder_expected[8] = {
156 0xCA, 0xFB, 0xAC, 0xFB, 0xA8, 0x26, 0x75, 0x2A
158 const DATA_BLOB confounder_expected =
159 data_blob_const(_confounder_expected, 8);
160 const uint8_t _clear_initial[] = {
161 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
162 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
163 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x8A, 0xE3, 0x13, 0x71, 0x02, 0xF4, 0x36, 0x71,
169 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00,
170 0x02, 0x40, 0x28, 0x00, 0x78, 0x57, 0x34, 0x12,
171 0x34, 0x12, 0xCD, 0xAB, 0xEF, 0x00, 0x01, 0x23,
172 0x45, 0x67, 0x89, 0xAB, 0x00, 0x00, 0x00, 0x00,
173 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11,
174 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60,
175 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
178 const DATA_BLOB clear_initial = data_blob_const(_clear_initial,
179 sizeof(_clear_initial));
180 const uint8_t crypt_buffer[] = {
181 0xE2, 0xE5, 0xE3, 0x26, 0x45, 0xFB, 0xFC, 0xF3,
182 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55,
183 0xED, 0x8F, 0xF4, 0x92, 0xA1, 0xBD, 0xDC, 0x40,
184 0x58, 0x6F, 0xD2, 0x5B, 0xF9, 0xC9, 0xA3, 0x87,
185 0x46, 0x4B, 0x7F, 0xB2, 0x03, 0xD2, 0x35, 0x22,
186 0x3E, 0x70, 0x9F, 0x1E, 0x3F, 0x1F, 0xDB, 0x7D,
187 0x79, 0x88, 0x5A, 0x3D, 0xD3, 0x40, 0x1E, 0x69,
188 0xD7, 0xE2, 0x1D, 0x5A, 0xE9, 0x3B, 0xE1, 0xE2,
189 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8,
190 0xCA, 0x02, 0x00, 0x99, 0x9F, 0x0C, 0x01, 0xE6,
191 0xD2, 0x00, 0xAF, 0xE0, 0x51, 0x88, 0x62, 0x50,
192 0xB7, 0xE8, 0x6D, 0x63, 0x4B, 0x97, 0x05, 0xC1,
193 0xD4, 0x83, 0x96, 0x29, 0x80, 0xAE, 0xD8, 0xA2,
194 0xED, 0xC9, 0x5D, 0x0D, 0x29, 0xFF, 0x2C, 0x23,
195 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01,
196 0x95, 0xDF, 0x80, 0x76, 0x0B, 0x17, 0x0E, 0xD8
198 const DATA_BLOB crypt_expected = data_blob_const(crypt_buffer,
199 sizeof(crypt_buffer));
200 int buffer_sizes[] = {
201 0, 1, 3, 7, 8, 9, 15, 16, 17
205 torture_gnutls_aes_128_cfb_flags(state,
213 /* repeat the test for varying buffer sizes */
215 for (i = 0; i < ARRAY_SIZE(buffer_sizes); i++) {
216 DATA_BLOB clear_initial_trunc =
217 data_blob_const(clear_initial.data, buffer_sizes[i]);
218 DATA_BLOB crypt_expected_trunc =
219 data_blob_const(crypt_expected.data, buffer_sizes[i]);
220 torture_gnutls_aes_128_cfb_flags(state,
226 crypt_expected_trunc);
231 static void torture_gnutls_des_crypt56(void **state)
233 static const uint8_t key[7] = {
234 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24
236 static const uint8_t clear[8] = {
237 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34
239 static const uint8_t crypt_expected[8] = {
240 0x54, 0x86, 0xCF, 0x51, 0x49, 0x3A, 0x53, 0x5B
247 des_crypt56(crypt, clear, key, 1);
248 assert_memory_equal(crypt, crypt_expected, 8);
250 des_crypt56(decrypt, crypt, key, 0);
251 assert_memory_equal(decrypt, clear, 8);
253 rc = des_crypt56_gnutls(crypt, clear, key, SAMBA_GNUTLS_ENCRYPT);
254 assert_int_equal(rc, 0);
255 assert_memory_equal(crypt, crypt_expected, 8);
257 rc = des_crypt56_gnutls(decrypt, crypt, key, SAMBA_GNUTLS_DECRYPT);
258 assert_int_equal(rc, 0);
259 assert_memory_equal(decrypt, clear, 8);
262 static void torture_gnutls_E_P16(void **state)
264 static const uint8_t key[14] = {
265 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8,
266 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A
268 uint8_t buffer[16] = {
269 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55,
270 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34
272 static const uint8_t crypt_expected[16] = {
273 0x41, 0x4A, 0x7B, 0xEA, 0xAB, 0xBB, 0x95, 0xCE,
274 0x1D, 0xEA, 0xD9, 0xFF, 0xB0, 0xA9, 0xA4, 0x05
279 rc = E_P16(key, buffer);
280 assert_int_equal(rc, 0);
281 assert_memory_equal(buffer, crypt_expected, 16);
284 static void torture_gnutls_E_P24(void **state)
286 static const uint8_t key[21] = {
287 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED,
288 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8,
289 0x69, 0x88, 0x96, 0x8E, 0x3A
291 const uint8_t c8[8] = {
292 0x44, 0xFB, 0xAC, 0xFB, 0x83, 0xB6, 0x75, 0x2A
294 static const uint8_t crypt_expected[24] = {
295 0x1A, 0x5E, 0x11, 0xA1, 0x59, 0xA9, 0x6B, 0x4E,
296 0x12, 0x5D, 0x81, 0x75, 0xA6, 0x62, 0x15, 0x6D,
297 0x5D, 0x20, 0x25, 0xC1, 0xA3, 0x92, 0xB3, 0x28
303 rc = E_P24(key, c8, crypt);
304 assert_int_equal(rc, 0);
305 assert_memory_equal(crypt, crypt_expected, 24);
308 static void torture_gnutls_SMBOWFencrypt(void **state)
310 static const uint8_t password[16] = {
311 'M', 'y', 'p', 'a', 's', 's', 'w', 'o',
312 'r', 'd', 'i', 's', '1', '1', '1', '1'
314 const uint8_t c8[8] = {
315 0x79, 0x88, 0x5A, 0x3D, 0xD3, 0x40, 0x1E, 0x69
317 static const uint8_t crypt_expected[24] = {
318 0x3F, 0xE3, 0x53, 0x75, 0x81, 0xB4, 0xF0, 0xE7,
319 0x0C, 0xDE, 0xCD, 0xAE, 0x39, 0x1F, 0x14, 0xB4,
320 0xA4, 0x2B, 0x3E, 0x39, 0x16, 0xFD, 0x1D, 0x62
326 rc = SMBOWFencrypt(password, c8, crypt);
327 assert_int_equal(rc, 0);
328 assert_memory_equal(crypt, crypt_expected, 24);
331 static void torture_gnutls_E_old_pw_hash(void **state)
333 static uint8_t key[14] = {
334 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8,
335 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A
337 uint8_t clear[16] = {
338 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55,
339 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34
341 static const uint8_t crypt_expected[16] = {
342 0x6A, 0xC7, 0x08, 0xCA, 0x2A, 0xC1, 0xAA, 0x64,
343 0x37, 0xEF, 0xBE, 0x58, 0xC2, 0x59, 0x33, 0xEC
348 rc = E_old_pw_hash(key, clear, crypt);
349 assert_int_equal(rc, 0);
350 assert_memory_equal(crypt, crypt_expected, 16);
353 static void torture_gnutls_des_crypt128(void **state)
355 static uint8_t key[16] = {
356 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8,
357 0xA9, 0x69, 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24
359 static const uint8_t clear[8] = {
360 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34
362 static const uint8_t crypt_expected[8] = {
363 0x4C, 0xB4, 0x4B, 0xD3, 0xC8, 0xC1, 0xA5, 0x50
369 rc = des_crypt128(crypt, clear, key);
370 assert_int_equal(rc, 0);
371 assert_memory_equal(crypt, crypt_expected, 8);
374 static void torture_gnutls_des_crypt112(void **state)
376 static uint8_t key[14] = {
377 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8,
378 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24
380 static const uint8_t clear[8] = {
381 0x2F, 0x49, 0x5B, 0x20, 0xD7, 0x84, 0xC2, 0x34
383 static const uint8_t crypt_expected[8] = {
384 0x87, 0x35, 0xFA, 0xA4, 0x5D, 0x7A, 0xA5, 0x05
391 rc = des_crypt112(crypt, clear, key, SAMBA_GNUTLS_ENCRYPT);
392 assert_int_equal(rc, 0);
393 assert_memory_equal(crypt, crypt_expected, 8);
395 rc = des_crypt112(decrypt, crypt, key, SAMBA_GNUTLS_DECRYPT);
396 assert_int_equal(rc, 0);
397 assert_memory_equal(decrypt, clear, 8);
400 static void torture_gnutls_des_crypt112_16(void **state)
402 static uint8_t key[14] = {
403 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB,
404 0x88, 0x96, 0x8E, 0xB5, 0x3A, 0x24
406 static const uint8_t clear[16] = {
407 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01,
408 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED
410 static const uint8_t crypt_expected[16] = {
411 0x3C, 0x10, 0x37, 0x67, 0x96, 0x95, 0xF7, 0x96,
412 0xAA, 0x03, 0xB9, 0xEA, 0xD6, 0xB3, 0xC3, 0x2D
419 rc = des_crypt112_16(crypt, clear, key, SAMBA_GNUTLS_ENCRYPT);
420 assert_int_equal(rc, 0);
421 assert_memory_equal(crypt, crypt_expected, 16);
423 rc = des_crypt112_16(decrypt, crypt, key, SAMBA_GNUTLS_DECRYPT);
424 assert_int_equal(rc, 0);
425 assert_memory_equal(decrypt, clear, 16);
428 static void torture_gnutls_sam_rid_crypt(void **state)
430 static const uint8_t clear[16] = {
431 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01,
432 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34
434 static const uint8_t crypt_expected[16] = {
435 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB,
436 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED
444 rc = sam_rid_crypt(rid, clear, crypt, SAMBA_GNUTLS_ENCRYPT);
445 assert_int_equal(rc, 0);
446 assert_memory_equal(crypt, crypt_expected, 16);
448 rc = sam_rid_crypt(rid, crypt, decrypt, SAMBA_GNUTLS_DECRYPT);
449 assert_int_equal(rc, 0);
450 assert_memory_equal(decrypt, clear, 16);
453 static void torture_gnutls_SMBsesskeygen_lm_sess_key(void **state)
455 static const uint8_t lm_hash[16] = {
456 0xFB, 0x67, 0x99, 0xA4, 0x83, 0xF3, 0xD4, 0xED,
457 0x9C, 0x14, 0xDD, 0xE1, 0x39, 0x23, 0xE0, 0x55
459 static const uint8_t lm_resp[24] = {
460 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01,
461 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01,
462 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB
464 static const uint8_t crypt_expected[16] = {
465 0x52, 0x8D, 0xB2, 0xD3, 0x89, 0x83, 0xFB, 0x9C,
466 0x96, 0x45, 0x15, 0x4B, 0xC3, 0xF5, 0xD5, 0x7F
469 uint8_t crypt_sess_key[16];
472 status = SMBsesskeygen_lm_sess_key(lm_hash, lm_resp, crypt_sess_key);
473 assert_true(NT_STATUS_IS_OK(status));
474 assert_memory_equal(crypt_sess_key, crypt_expected, 16);
477 static void torture_gnutls_sess_crypt_blob(void **state)
479 static uint8_t _key[16] = {
480 0x1E, 0x38, 0x27, 0x5B, 0x3B, 0xB8, 0x67, 0xEB,
481 0xFA, 0xEE, 0xE8, 0xBA, 0x06, 0x01, 0x2D, 0x95
483 DATA_BLOB key = data_blob_const(_key, 16);
484 static const uint8_t _clear[24] = {
485 0x98, 0xFD, 0xCB, 0x3A, 0xF7, 0xB5, 0x1C, 0xF8,
486 0x02, 0xFA, 0x3B, 0xEE, 0xE8, 0xBA, 0x06, 0x01,
487 0x3F, 0x49, 0x5B, 0x20, 0xA7, 0x84, 0xC2, 0x34
489 DATA_BLOB clear = data_blob_const(_clear, 24);
490 static const uint8_t crypt_expected[24] = {
491 0x2B, 0xDD, 0x3B, 0xFA, 0x48, 0xC9, 0x63, 0x56,
492 0xAE, 0x8B, 0x3E, 0xCF, 0xEF, 0xDF, 0x7A, 0x42,
493 0xB3, 0x00, 0x71, 0x7F, 0x5D, 0x1D, 0xE4, 0x70
495 DATA_BLOB crypt = data_blob(NULL, 24);
496 DATA_BLOB decrypt = data_blob(NULL, 24);
498 sess_crypt_blob(&crypt, &clear, &key, true);
499 assert_memory_equal(crypt.data, crypt_expected, 24);
501 sess_crypt_blob(&decrypt, &crypt, &key, false);
502 assert_memory_equal(decrypt.data, clear.data, 24);
505 int main(int argc, char *argv[])
508 const struct CMUnitTest tests[] = {
509 cmocka_unit_test(torture_gnutls_aes_128_cfb),
510 cmocka_unit_test(torture_gnutls_des_crypt56),
511 cmocka_unit_test(torture_gnutls_E_P16),
512 cmocka_unit_test(torture_gnutls_E_P24),
513 cmocka_unit_test(torture_gnutls_SMBOWFencrypt),
514 cmocka_unit_test(torture_gnutls_E_old_pw_hash),
515 cmocka_unit_test(torture_gnutls_des_crypt128),
516 cmocka_unit_test(torture_gnutls_des_crypt112),
517 cmocka_unit_test(torture_gnutls_des_crypt112_16),
518 cmocka_unit_test(torture_gnutls_sam_rid_crypt),
519 cmocka_unit_test(torture_gnutls_SMBsesskeygen_lm_sess_key),
520 cmocka_unit_test(torture_gnutls_sess_crypt_blob),
524 cmocka_set_test_filter(argv[1]);
526 cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
528 rc = cmocka_run_group_tests(tests, NULL, NULL);