1 /*
2  * Description from Nicolas Ruff:
3  * - Salt value is hashed as an hexadecimal string, not bytes.
4  * - The trailing NULL byte of password string is taken into account during
5  *   hashing.
6  * - The leading '1' is actually the string length
7  *   '1' = 49 = len('1') + len(hex_salt) + len(hex_sha1)
8  *
9  * ---------------------------------------
10  * import hashlib
11  *
12  * def netscaler_hash( rand_bytes, pwd ):
13  *    s = hashlib.sha1()
14  *    s.update( rand_bytes )
15  *    s.update( pwd )
16  *    return "1" + rand_bytes + s.hexdigest()
17  *
18  * # TEST VECTOR
19  * # 14dfca1e6c0f5f3d96526c3ce70849992b7fad3e324cf6b0f
20  *
21  * rand_bytes = "4dfca1e6"
22  * pwd = "nsroot\x00"
23  * print netscaler_hash( rand_bytes, pwd )
24  * ---------------------------------------
25  *
26  * This software is Copyright (c) 2013 magnum, and it is hereby released to the
27  * general public under the following terms:  Redistribution and use in source
28  * and binary forms, with or without modification, are permitted.
29  *
30  * This version is hard coded for salt length 8 (for speed).
31  */
32 
33 #if FMT_EXTERNS_H
34 extern struct fmt_main fmt_ctrxns;
35 #elif FMT_REGISTERS_H
36 john_register_one(&fmt_ctrxns);
37 #else
38 
39 #include <string.h>
40 
41 #ifdef _OPENMP
42 #include <omp.h>
43 #endif
44 
45 #include "arch.h"
46 #include "misc.h"
47 #include "formats.h"
48 #include "options.h"
49 #include "johnswap.h"
50 
51 #ifdef SIMD_COEF_32
52 #define NBKEYS  (SIMD_COEF_32 * SIMD_PARA_SHA1)
53 #endif
54 #include "simd-intrinsics.h"
55 #include "common.h"
56 #include "sha.h"
57 
58 #define FORMAT_LABEL                    "Citrix_NS10"
59 #define FORMAT_NAME                     "Netscaler 10"
60 
61 #define ALGORITHM_NAME                  "SHA1 " SHA1_ALGORITHM_NAME
62 
63 #define BENCHMARK_COMMENT               ""
64 #define BENCHMARK_LENGTH                7
65 
66 #define PLAINTEXT_LENGTH                (55 - SALT_SIZE - 1)
67 
68 #define BINARY_SIZE                     20
69 #define BINARY_ALIGN                    4
70 #define SALT_SIZE                       8
71 #define SALT_ALIGN                      4
72 
73 #ifdef SIMD_COEF_32
74 #define MIN_KEYS_PER_CRYPT              NBKEYS
75 #define MAX_KEYS_PER_CRYPT              (NBKEYS * 256)
76 #define FMT_IS_BE
77 #include "common-simd-getpos.h"
78 #else
79 #define MIN_KEYS_PER_CRYPT              1
80 #define MAX_KEYS_PER_CRYPT              256
81 #endif
82 
83 #ifndef OMP_SCALE
84 #define OMP_SCALE                       4	// Tuned w/ MKPC for core i7
85 #endif
86 
87 static struct fmt_tests tests[] = {
88 	{"100000000f1dc96f425971ba590a076fd0f8bccbf25c1ba0c", ""},
89 	{"14623718525fe334bbd9c0704e06ce134ef17b51f6b33548c", " "},
90 	{"15c5c5c5c6ccd884f6383f55a6aeba5f847775e57ab012675", "Tw"},
91 	{"13333333319143136ba9ff9e18d1cb022b63df0926de9509e", "333"},
92 	{"144434241d7ce89a7484cd202400639692258dde37efc29c5", "four"},
93 	{"100010203e09cefed1847b7a2a5e7a5d2cdc67e8a56ed0bdd", "fiver"},
94 	{"14dfca1e6c0f5f3d96526c3ce70849992b7fad3e324cf6b0f", "nsroot"},
95 	{"1deadcafe7587ea23b25a6ccf3fd53192e36ad3e9a2553b20", "magnum!"},
96 	{NULL}
97 };
98 
99 #ifdef SIMD_COEF_32
100 static unsigned char (*saved_key)[SHA_BUF_SIZ * 4 * NBKEYS];
101 static unsigned char (*crypt_key)[BINARY_SIZE * NBKEYS];
102 static unsigned int kpc;
103 #else
104 static char saved_salt[SALT_SIZE];
105 static char (*saved_key)[PLAINTEXT_LENGTH + 1];
106 static uint32_t (*crypt_key)[BINARY_SIZE / 4];
107 #endif
108 
init(struct fmt_main * self)109 static void init(struct fmt_main *self)
110 {
111 	omp_autotune(self, OMP_SCALE);
112 
113 #ifdef SIMD_COEF_32
114 	saved_key = mem_calloc_align(self->params.max_keys_per_crypt / NBKEYS,
115 	                       sizeof(*saved_key), MEM_ALIGN_SIMD);
116 	crypt_key = mem_calloc_align(self->params.max_keys_per_crypt / NBKEYS,
117 	                       sizeof(*crypt_key), MEM_ALIGN_SIMD);
118 	kpc = self->params.max_keys_per_crypt;
119 #else
120 	saved_key = mem_calloc(self->params.max_keys_per_crypt,
121 	                       sizeof(*saved_key));
122 	crypt_key = mem_calloc(self->params.max_keys_per_crypt,
123 	                       sizeof(*crypt_key));
124 #endif
125 }
126 
done(void)127 static void done(void)
128 {
129 	MEM_FREE(crypt_key);
130 	MEM_FREE(saved_key);
131 }
132 
get_binary(char * ciphertext)133 static void *get_binary(char *ciphertext)
134 {
135 	static unsigned char *realcipher;
136 	int i, len;
137 
138 	if (!realcipher)
139 		realcipher = mem_alloc_tiny(BINARY_SIZE, MEM_ALIGN_WORD);
140 
141 	len = *ciphertext;
142 
143 	ciphertext += len - 2 * BINARY_SIZE;
144 
145 	for (i = 0; i < BINARY_SIZE; i++)
146 	{
147 		realcipher[i] = atoi16[ARCH_INDEX(ciphertext[i * 2])] * 16
148 			+ atoi16[ARCH_INDEX(ciphertext[i * 2 + 1])];
149 	}
150 #if defined(SIMD_COEF_32) && ARCH_LITTLE_ENDIAN==1
151 	alter_endianity(realcipher, BINARY_SIZE);
152 #endif
153 	return (void*)realcipher;
154 }
155 
valid(char * ciphertext,struct fmt_main * self)156 static int valid(char *ciphertext, struct fmt_main *self)
157 {
158 	int len;
159 
160 	len = *ciphertext;
161 
162 	if (len != (int)'1')
163 		return 0;
164 
165 	if (strlen(ciphertext) != len)
166 		return 0;
167 
168 	if (len != strspn(ciphertext, HEXCHARS_lc))
169 		return 0;
170 
171 	return 1;
172 }
173 
174 // this is a salt appended format. It also 'keeps' the trailing null byte.
175 #define SALT_PREPENDED SALT_SIZE
176 #define INCLUDE_TRAILING_NULL
177 #include "common-simd-setkey32.h"
178 
get_salt(char * ciphertext)179 static void *get_salt(char *ciphertext)
180 {
181 	static union {
182 		unsigned char c[SALT_SIZE];
183 		uint32_t w;
184 	} out;
185 
186 	ciphertext++;
187 	memcpy(out.c, ciphertext, SALT_SIZE);
188 
189 	return (void*)out.c;
190 }
191 
set_salt(void * salt)192 static void set_salt(void *salt)
193 {
194 #ifdef SIMD_COEF_32
195 	int i, index;
196 
197 	for (index = 0; index < kpc; index++) {
198 		int idx = index % NBKEYS;
199 		unsigned char *sk = saved_key[index/NBKEYS];
200 		for (i = 0; i < SALT_SIZE; i++)
201 			sk[GETPOS(i, idx)] = ((unsigned char*)salt)[i];
202 	}
203 #else
204 	memcpy(saved_salt, salt, SALT_SIZE);
205 #endif
206 }
207 
cmp_all(void * binary,int count)208 static int cmp_all(void *binary, int count)
209 {
210 #ifdef SIMD_COEF_32
211 	unsigned int x, y;
212 
213 	for (y = 0; y < kpc/SIMD_COEF_32; y++) {
214 		for (x = 0; x < SIMD_COEF_32; x++) {
215 			if (((uint32_t*)binary)[0] ==
216 			   ((uint32_t*)crypt_key)[x + y * SIMD_COEF_32*5])
217 				return 1;
218 		}
219 	}
220 
221 	return 0;
222 #else
223 	int index;
224 
225 	for (index = 0; index < count; index++)
226 		if (((uint32_t*)binary)[0] == crypt_key[index][0])
227 			return 1;
228 
229 	return 0;
230 #endif
231 }
232 
cmp_one(void * binary,int index)233 static int cmp_one(void *binary, int index)
234 {
235 #ifdef SIMD_COEF_32
236 	unsigned int x, y;
237 	x = index & (SIMD_COEF_32-1);
238 	y = (unsigned int)index / SIMD_COEF_32;
239 
240 	if (((uint32_t*)binary)[0] != ((uint32_t*)crypt_key)[x + y * SIMD_COEF_32*5])
241 		return 0;
242 	if (((uint32_t*)binary)[1] != ((uint32_t*)crypt_key)[x + y * SIMD_COEF_32*5+SIMD_COEF_32*1])
243 		return 0;
244 	if (((uint32_t*)binary)[2] != ((uint32_t*)crypt_key)[x + y * SIMD_COEF_32*5+SIMD_COEF_32*2])
245 		return 0;
246 	if (((uint32_t*)binary)[3] != ((uint32_t*)crypt_key)[x + y * SIMD_COEF_32*5+SIMD_COEF_32*3])
247 		return 0;
248 	if (((uint32_t*)binary)[4] != ((uint32_t*)crypt_key)[x + y * SIMD_COEF_32*5+SIMD_COEF_32*4])
249 		return 0;
250 	return 1;
251 #else
252 	return !memcmp(binary, crypt_key[index], BINARY_SIZE);
253 #endif
254 }
255 
cmp_exact(char * source,int index)256 static int cmp_exact(char *source, int index)
257 {
258 	return 1;
259 }
260 
crypt_all(int * pcount,struct db_salt * salt)261 static int crypt_all(int *pcount, struct db_salt *salt)
262 {
263 	const int count = *pcount;
264 	int index;
265 	int loops = (count + MIN_KEYS_PER_CRYPT - 1) / MIN_KEYS_PER_CRYPT;
266 
267 #ifdef _OPENMP
268 #pragma omp parallel for
269 #endif
270 	for (index = 0; index < loops; ++index) {
271 #ifdef SIMD_COEF_32
272 		SIMDSHA1body(saved_key[index], (unsigned int*)crypt_key[index], NULL, SSEi_MIXED_IN);
273 #else
274 		SHA_CTX ctx;
275 
276 		SHA1_Init(&ctx);
277 		SHA1_Update(&ctx, (unsigned char*)saved_salt, SALT_SIZE);
278 		SHA1_Update(&ctx, (unsigned char*)saved_key[index], strlen(saved_key[index]) + 1);
279 		SHA1_Final((unsigned char*)crypt_key[index], &ctx);
280 #endif
281 	}
282 
283 	return count;
284 }
285 
286 #define COMMON_GET_HASH_SIMD32 5
287 #define COMMON_GET_HASH_VAR crypt_key
288 #include "common-get-hash.h"
289 
salt_hash(void * salt)290 static int salt_hash(void *salt)
291 {
292 	return *(uint32_t*)salt & (SALT_HASH_SIZE - 1);
293 }
294 
295 struct fmt_main fmt_ctrxns = {
296 	{
297 		FORMAT_LABEL,
298 		FORMAT_NAME,
299 		ALGORITHM_NAME,
300 		BENCHMARK_COMMENT,
301 		BENCHMARK_LENGTH,
302 		0,
303 		PLAINTEXT_LENGTH,
304 		BINARY_SIZE,
305 		BINARY_ALIGN,
306 		SALT_SIZE,
307 		SALT_ALIGN,
308 		MIN_KEYS_PER_CRYPT,
309 		MAX_KEYS_PER_CRYPT,
310 		FMT_CASE | FMT_8_BIT | FMT_OMP | FMT_OMP_BAD,
311 		{ NULL },
312 		{ NULL },
313 		tests
314 	}, {
315 		init,
316 		done,
317 		fmt_default_reset,
318 		fmt_default_prepare,
319 		valid,
320 		fmt_default_split,
321 		get_binary,
322 		get_salt,
323 		{ NULL },
324 		fmt_default_source,
325 		{
326 			fmt_default_binary_hash_0,
327 			fmt_default_binary_hash_1,
328 			fmt_default_binary_hash_2,
329 			fmt_default_binary_hash_3,
330 			fmt_default_binary_hash_4,
331 			fmt_default_binary_hash_5,
332 			fmt_default_binary_hash_6
333 		},
334 		salt_hash,
335 		NULL,
336 		set_salt,
337 		set_key,
338 		get_key,
339 		fmt_default_clear_keys,
340 		crypt_all,
341 		{
342 #define COMMON_GET_HASH_LINK
343 #include "common-get-hash.h"
344 		},
345 		cmp_all,
346 		cmp_one,
347 		cmp_exact
348 	}
349 };
350 
351 #endif /* plugin stanza */
352