1 /*
2  * JtR format to crack Dashlane Password Manager files.
3  *
4  * This software is Copyright (c) 2017, Dhiru Kholia <kholia at kth.se> and it
5  * is hereby released to the general public under the following terms:
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted.
9  *
10  * Special thanks goes to Robin Lambertz for making this work possible.
11  */
12 
13 #include "arch.h"
14 #if !AC_BUILT
15 #define HAVE_LIBZ 1 /* legacy build has -lz in LDFLAGS */
16 #endif
17 #if HAVE_LIBZ
18 
19 #if FMT_EXTERNS_H
20 extern struct fmt_main fmt_dashlane;
21 #elif FMT_REGISTERS_H
22 john_register_one(&fmt_dashlane);
23 #else
24 
25 #include <string.h>
26 #include <zlib.h>
27 
28 #ifdef _OPENMP
29 #include <omp.h>
30 #endif
31 
32 #include "misc.h"
33 #include "common.h"
34 #include "formats.h"
35 #include "params.h"
36 #include "options.h"
37 #include "aes.h"
38 #include "sha2.h"
39 #include "jumbo.h"
40 #include "pbkdf2_hmac_sha1.h"
41 #include "dashlane_common.h"
42 #include "openssl_code.h"
43 #include "hmac_sha.h"
44 
45 #define FORMAT_NAME             "Dashlane Password Manager"
46 #define FORMAT_LABEL            "dashlane"
47 #define FORMAT_TAG              "$dashlane$"
48 #define TAG_LENGTH              (sizeof(FORMAT_TAG) - 1)
49 #ifdef SIMD_COEF_64
50 #define ALGORITHM_NAME          "AES PBKDF2-SHA1 " SHA1_ALGORITHM_NAME
51 #else
52 #define ALGORITHM_NAME          "AES PBKDF2-SHA1 32/" ARCH_BITS_STR
53 #endif
54 #define BENCHMARK_COMMENT       ""
55 #define BENCHMARK_LENGTH        0x107
56 #define BINARY_SIZE             0
57 #define BINARY_ALIGN            1
58 #define SALT_SIZE               sizeof(struct custom_salt)
59 #define SALT_ALIGN              sizeof(uint32_t)
60 #define PLAINTEXT_LENGTH        125
61 #ifdef SIMD_COEF_32
62 #define MIN_KEYS_PER_CRYPT      SSE_GROUP_SZ_SHA1
63 #define MAX_KEYS_PER_CRYPT      (SSE_GROUP_SZ_SHA1 * 4)
64 #else
65 #define MIN_KEYS_PER_CRYPT      1
66 #define MAX_KEYS_PER_CRYPT      4
67 #endif
68 
69 #ifndef OMP_SCALE
70 #define OMP_SCALE               4 // Tuned w/ MKPC for core i7
71 #endif
72 
73 static char (*saved_key)[PLAINTEXT_LENGTH + 1];
74 static int *cracked, cracked_count;
75 
76 static struct custom_salt *cur_salt;
77 
init(struct fmt_main * self)78 static void init(struct fmt_main *self)
79 {
80 	omp_autotune(self, OMP_SCALE);
81 
82 	saved_key = mem_calloc(sizeof(*saved_key), self->params.max_keys_per_crypt);
83 	cracked = mem_calloc(sizeof(*cracked), self->params.max_keys_per_crypt);
84 	cracked_count = self->params.max_keys_per_crypt;
85 }
86 
done(void)87 static void done(void)
88 {
89 	MEM_FREE(cracked);
90 	MEM_FREE(saved_key);
91 }
92 
set_salt(void * salt)93 static void set_salt(void *salt)
94 {
95 	cur_salt = (struct custom_salt *)salt;
96 }
97 
dashlane_set_key(char * key,int index)98 static void dashlane_set_key(char *key, int index)
99 {
100 	strnzcpy(saved_key[index], key, PLAINTEXT_LENGTH + 1);
101 }
102 
get_key(int index)103 static char *get_key(int index)
104 {
105 	return saved_key[index];
106 }
107 
crypt_all(int * pcount,struct db_salt * salt)108 static int crypt_all(int *pcount, struct db_salt *salt)
109 {
110 	const int count = *pcount;
111 	int index = 0;
112 
113 	memset(cracked, 0, sizeof(cracked[0]) * cracked_count);
114 
115 #ifdef _OPENMP
116 #pragma omp parallel for
117 #endif
118 	for (index = 0; index < count; index += MIN_KEYS_PER_CRYPT) {
119 		unsigned char pkey[MIN_KEYS_PER_CRYPT][32];
120 		int i;
121 #ifdef SIMD_COEF_32
122 		int len[MIN_KEYS_PER_CRYPT];
123 		unsigned char *pin[MIN_KEYS_PER_CRYPT], *pout[MIN_KEYS_PER_CRYPT];
124 		for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i) {
125 			len[i] = strlen(saved_key[i+index]);
126 			pin[i] = (unsigned char*)saved_key[i+index];
127 			pout[i] = pkey[i];
128 		}
129 		pbkdf2_sha1_sse((const unsigned char **)pin, len, cur_salt->salt, 32, 10204, pout, 32, 0);
130 #else
131 		for (i = 0; i < MIN_KEYS_PER_CRYPT; i++) {
132 			pbkdf2_sha1((unsigned char *)saved_key[index+i],
133 					strlen(saved_key[index+i]),
134 					cur_salt->salt, 32, 10204,
135 					pkey[i], 32, 0);
136 		}
137 #endif
138 
139 		for (i = 0; i < MIN_KEYS_PER_CRYPT; i++) {
140 			if (dashlane_verify(cur_salt, pkey[i]))
141 				cracked[index+i] = 1;
142 			else
143 				cracked[index+i] = 0;
144 		}
145 	}
146 
147 	return count;
148 }
149 
cmp_all(void * binary,int count)150 static int cmp_all(void *binary, int count)
151 {
152 	int index;
153 	for (index = 0; index < count; index++)
154 		if (cracked[index])
155 			return 1;
156 	return 0;
157 }
158 
cmp_one(void * binary,int index)159 static int cmp_one(void *binary, int index)
160 {
161 	return cracked[index];
162 }
163 
cmp_exact(char * source,int index)164 static int cmp_exact(char *source, int index)
165 {
166 	return 1;
167 }
168 
169 struct fmt_main fmt_dashlane = {
170 	{
171 		FORMAT_LABEL,
172 		FORMAT_NAME,
173 		ALGORITHM_NAME,
174 		BENCHMARK_COMMENT,
175 		BENCHMARK_LENGTH,
176 		0,
177 		PLAINTEXT_LENGTH,
178 		BINARY_SIZE,
179 		BINARY_ALIGN,
180 		SALT_SIZE,
181 		SALT_ALIGN,
182 		MIN_KEYS_PER_CRYPT,
183 		MAX_KEYS_PER_CRYPT,
184 		FMT_CASE | FMT_8_BIT | FMT_OMP | FMT_HUGE_INPUT,
185 		{ NULL },
186 		{ FORMAT_TAG },
187 		dashlane_tests
188 	}, {
189 		init,
190 		done,
191 		fmt_default_reset,
192 		fmt_default_prepare,
193 		dashlane_valid,
194 		fmt_default_split,
195 		fmt_default_binary,
196 		dashlane_get_salt,
197 		{ NULL },
198 		fmt_default_source,
199 		{
200 			fmt_default_binary_hash
201 		},
202 		fmt_default_salt_hash,
203 		NULL,
204 		set_salt,
205 		dashlane_set_key,
206 		get_key,
207 		fmt_default_clear_keys,
208 		crypt_all,
209 		{
210 			fmt_default_get_hash
211 		},
212 		cmp_all,
213 		cmp_one,
214 		cmp_exact
215 	}
216 };
217 
218 #endif /* plugin stanza */
219 
220 #endif /* HAVE_LIBZ */
221