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