1 /*
2 * JtR format to crack password protected FreeBSD GELI volumes.
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
11 #if FMT_EXTERNS_H
12 extern struct fmt_main fmt_geli;
13 #elif FMT_REGISTERS_H
14 john_register_one(&fmt_geli);
15 #else
16
17 #include <string.h>
18
19 #ifdef _OPENMP
20 #include <omp.h>
21 #endif
22
23 #include "arch.h"
24 #include "misc.h"
25 #include "common.h"
26 #include "formats.h"
27 #include "params.h"
28 #include "options.h"
29 #include "hmac_sha.h"
30 #include "aes.h"
31 #include "pbkdf2_hmac_sha512.h"
32 #include "jumbo.h"
33 #include "geli_common.h"
34
35 #define FORMAT_LABEL "geli"
36 #define FORMAT_NAME "FreeBSD GELI"
37 #ifdef SIMD_COEF_64
38 #define ALGORITHM_NAME "PBKDF2-SHA512 " SHA1_ALGORITHM_NAME
39 #else
40 #define ALGORITHM_NAME "PBKDF2-SHA512 32/" ARCH_BITS_STR
41 #endif
42 #define BENCHMARK_COMMENT ""
43 #define BENCHMARK_LENGTH 0x107
44 #define BINARY_SIZE 0
45 #define PLAINTEXT_LENGTH 125
46 #define SALT_SIZE sizeof(*cur_salt)
47 #define BINARY_ALIGN 1
48 #define SALT_ALIGN sizeof(int)
49 #ifdef SIMD_COEF_64
50 #define MIN_KEYS_PER_CRYPT SSE_GROUP_SZ_SHA512
51 #define MAX_KEYS_PER_CRYPT (SSE_GROUP_SZ_SHA512 * 4)
52 #else
53 #define MIN_KEYS_PER_CRYPT 1
54 #define MAX_KEYS_PER_CRYPT 4
55 #endif
56
57 #ifndef OMP_SCALE
58 #define OMP_SCALE 4 // Tuned w/ MKPC for core i7
59 #endif
60
61 static char (*saved_key)[PLAINTEXT_LENGTH + 1];
62 static int *cracked, cracked_count;
63 static custom_salt *cur_salt;
64
init(struct fmt_main * self)65 static void init(struct fmt_main *self)
66 {
67 omp_autotune(self, OMP_SCALE);
68
69 saved_key = mem_calloc(sizeof(*saved_key), self->params.max_keys_per_crypt);
70 cracked = mem_calloc(sizeof(*cracked), self->params.max_keys_per_crypt);
71 cracked_count = self->params.max_keys_per_crypt;
72 }
73
done(void)74 static void done(void)
75 {
76 MEM_FREE(cracked);
77 MEM_FREE(saved_key);
78 }
79
set_salt(void * salt)80 static void set_salt(void *salt)
81 {
82 cur_salt = (custom_salt *)salt;
83 }
84
geli_set_key(char * key,int index)85 static void geli_set_key(char *key, int index)
86 {
87 strnzcpy(saved_key[index], key, sizeof(*saved_key));
88 }
89
get_key(int index)90 static char *get_key(int index)
91 {
92 return saved_key[index];
93 }
94
crypt_all(int * pcount,struct db_salt * salt)95 static int crypt_all(int *pcount, struct db_salt *salt)
96 {
97 const int count = *pcount;
98 int index = 0;
99
100 memset(cracked, 0, sizeof(cracked[0])*cracked_count);
101
102 #ifdef _OPENMP
103 #pragma omp parallel for
104 #endif
105 for (index = 0; index < count; index += MIN_KEYS_PER_CRYPT) {
106 unsigned char master[MIN_KEYS_PER_CRYPT][G_ELI_USERKEYLEN];
107 unsigned char key[MIN_KEYS_PER_CRYPT][G_ELI_USERKEYLEN];
108 int i;
109 #ifdef SIMD_COEF_64
110 int lens[MIN_KEYS_PER_CRYPT];
111 unsigned char *pin[MIN_KEYS_PER_CRYPT], *pout[MIN_KEYS_PER_CRYPT];
112 for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i) {
113 lens[i] = strlen(saved_key[index+i]);
114 pin[i] = (unsigned char*)saved_key[index+i];
115 pout[i] = master[i];
116 }
117 pbkdf2_sha512_sse((const unsigned char**)pin, lens, cur_salt->md_salt, G_ELI_SALTLEN, cur_salt->md_iterations, pout, G_ELI_USERKEYLEN, 0);
118 #else
119 for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i)
120 pbkdf2_sha512((unsigned char *)saved_key[index+i], strlen(saved_key[index+i]), cur_salt->md_salt, G_ELI_SALTLEN, cur_salt->md_iterations, master[i], G_ELI_USERKEYLEN, 0);
121 #endif
122 for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i) {
123 JTR_hmac_sha512((const unsigned char*)"", 0, master[i], G_ELI_USERKEYLEN, key[i], G_ELI_USERKEYLEN);
124 cracked[index+i] = geli_decrypt_verify(cur_salt, key[i]);
125 }
126 }
127
128 return count;
129 }
130
cmp_all(void * binary,int count)131 static int cmp_all(void *binary, int count)
132 {
133 int index;
134
135 for (index = 0; index < count; index++)
136 if (cracked[index])
137 return 1;
138 return 0;
139 }
140
cmp_one(void * binary,int index)141 static int cmp_one(void *binary, int index)
142 {
143 return cracked[index];
144 }
145
cmp_exact(char * source,int index)146 static int cmp_exact(char *source, int index)
147 {
148 return 1;
149 }
150
151 struct fmt_main fmt_geli = {
152 {
153 FORMAT_LABEL,
154 FORMAT_NAME,
155 ALGORITHM_NAME,
156 BENCHMARK_COMMENT,
157 BENCHMARK_LENGTH,
158 0,
159 PLAINTEXT_LENGTH,
160 BINARY_SIZE,
161 BINARY_ALIGN,
162 SALT_SIZE,
163 SALT_ALIGN,
164 MIN_KEYS_PER_CRYPT,
165 MAX_KEYS_PER_CRYPT,
166 FMT_CASE | FMT_8_BIT | FMT_OMP | FMT_HUGE_INPUT,
167 {
168 "iteration count",
169 },
170 { FORMAT_TAG },
171 geli_tests
172 }, {
173 init,
174 done,
175 fmt_default_reset,
176 fmt_default_prepare,
177 geli_common_valid,
178 fmt_default_split,
179 fmt_default_binary,
180 geli_common_get_salt,
181 {
182 geli_common_iteration_count,
183 },
184 fmt_default_source,
185 {
186 fmt_default_binary_hash
187 },
188 fmt_default_salt_hash,
189 NULL,
190 set_salt,
191 geli_set_key,
192 get_key,
193 fmt_default_clear_keys,
194 crypt_all,
195 {
196 fmt_default_get_hash
197 },
198 cmp_all,
199 cmp_one,
200 cmp_exact
201 }
202 };
203
204 #endif /* plugin stanza */
205