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