1 /*
2  * JtR format to crack iWork '09, and '13 / '14 files.
3  *
4  * This software is Copyright (c) 2015, Dhiru Kholia <kholia at kth.se> and
5  * Maxime Hulliger <hulliger at kth.se>, and it is hereby released to the
6  * general public under the following terms:
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted.
10  *
11  * This code may be freely used and modified for any purpose.
12  *
13  * Big thanks to Sean Patrick O'Brien for making this format possible.
14  */
15 
16 #if FMT_EXTERNS_H
17 extern struct fmt_main fmt_iwork;
18 #elif FMT_REGISTERS_H
19 john_register_one(&fmt_iwork);
20 #else
21 
22 #include <string.h>
23 #include <openssl/des.h>
24 
25 #ifdef _OPENMP
26 #include <omp.h>
27 #endif
28 
29 #include "arch.h"
30 #include "misc.h"
31 #include "common.h"
32 #include "jumbo.h"
33 #include "formats.h"
34 #include "params.h"
35 #include "options.h"
36 #include "johnswap.h"
37 #include "iwork_common.h"
38 #include "pbkdf2_hmac_sha1.h"
39 
40 #define FORMAT_LABEL            "iwork"
41 #ifdef SIMD_COEF_32
42 #define ALGORITHM_NAME          "PBKDF2-SHA1 AES " SHA1_ALGORITHM_NAME
43 #else
44 #define ALGORITHM_NAME          "PBKDF2-SHA1 AES 32/" ARCH_BITS_STR
45 #endif
46 #define BENCHMARK_COMMENT       ""
47 #define BENCHMARK_LENGTH        0x107
48 #define BINARY_SIZE             0
49 #define PLAINTEXT_LENGTH        125
50 #define SALT_SIZE               sizeof(*fctx)
51 #define BINARY_ALIGN            1
52 #define SALT_ALIGN              sizeof(int)
53 
54 #ifndef OMP_SCALE
55 #define OMP_SCALE               4
56 #endif
57 
58 #ifdef SIMD_COEF_32
59 #define MIN_KEYS_PER_CRYPT      SSE_GROUP_SZ_SHA1
60 #define MAX_KEYS_PER_CRYPT      SSE_GROUP_SZ_SHA1
61 #else
62 #define MIN_KEYS_PER_CRYPT      1
63 #define MAX_KEYS_PER_CRYPT      1
64 #endif
65 
66 static char (*saved_key)[PLAINTEXT_LENGTH + 1];
67 static int *cracked, cracked_count;
68 static struct format_context *fctx;
69 
init(struct fmt_main * self)70 static void init(struct fmt_main *self)
71 {
72 	omp_autotune(self, OMP_SCALE);
73 
74 	saved_key = mem_calloc(sizeof(*saved_key),  self->params.max_keys_per_crypt);
75 	cracked = mem_calloc(sizeof(*cracked), self->params.max_keys_per_crypt);
76 	cracked_count = self->params.max_keys_per_crypt;
77 }
78 
done(void)79 static void done(void)
80 {
81 	MEM_FREE(cracked);
82 	MEM_FREE(saved_key);
83 }
84 
set_salt(void * salt)85 static void set_salt(void *salt)
86 {
87 	fctx = (struct format_context *)salt;
88 }
89 
iwork_set_key(char * key,int index)90 static void iwork_set_key(char *key, int index)
91 {
92 	strnzcpy(saved_key[index], key, sizeof(*saved_key));
93 }
94 
get_key(int index)95 static char *get_key(int index)
96 {
97 	return saved_key[index];
98 }
99 
iwork_decrypt(struct format_context * fctx,unsigned char * key,unsigned char * iv,unsigned char * data)100 static int iwork_decrypt(struct format_context *fctx, unsigned char *key, unsigned char *iv, unsigned char *data)
101 {
102 	unsigned char out[BLOBLEN];
103 	unsigned char ivec[IVLEN];
104 	uint8_t hash[32];
105 	SHA256_CTX ctx;
106 	AES_KEY aes_decrypt_key;
107 
108 	AES_set_decrypt_key(key, 128, &aes_decrypt_key);
109 	memcpy(ivec, iv, 16);
110 	AES_cbc_encrypt(fctx->blob, out, BLOBLEN, &aes_decrypt_key, ivec, AES_DECRYPT);
111 
112 	// The last 32 bytes should be equal to the SHA256 of the first 32 bytes (IWPasswordVerifier.m)
113 	SHA256_Init(&ctx);
114 	SHA256_Update(&ctx, out, 32);
115 	SHA256_Final(hash, &ctx);
116 
117 	return memcmp(hash, &out[32], 32) == 0;
118 }
119 
crypt_all(int * pcount,struct db_salt * salt)120 static int crypt_all(int *pcount, struct db_salt *salt)
121 {
122 	const int count = *pcount;
123 	int index = 0;
124 
125 	memset(cracked, 0, sizeof(cracked[0])*cracked_count);
126 
127 #ifdef _OPENMP
128 #pragma omp parallel for
129 #endif
130 	for (index = 0; index < count; index += MIN_KEYS_PER_CRYPT) {
131 		unsigned char master[MIN_KEYS_PER_CRYPT][16];
132 		int i;
133 #ifdef SIMD_COEF_32
134 		int lens[MIN_KEYS_PER_CRYPT];
135 		unsigned char *pin[MIN_KEYS_PER_CRYPT], *pout[MIN_KEYS_PER_CRYPT];
136 		for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i) {
137 			lens[i] = strlen(saved_key[index+i]);
138 			pin[i] = (unsigned char*)saved_key[index+i];
139 			pout[i] = master[i];
140 		}
141 		pbkdf2_sha1_sse((const unsigned char**)pin, lens, fctx->salt, fctx->salt_length, fctx->iterations, pout, 16, 0);
142 #else
143 		for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i)
144 			pbkdf2_sha1((unsigned char *)saved_key[index+i], strlen(saved_key[index+i]), fctx->salt, fctx->salt_length, fctx->iterations, master[i], 16, 0);
145 #endif
146 		for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i) {
147 			cracked[index+i] = iwork_decrypt(fctx, master[i], fctx->iv, fctx->blob);
148 		}
149 	}
150 
151 	return count;
152 }
153 
cmp_all(void * binary,int count)154 static int cmp_all(void *binary, int count)
155 {
156 	int index;
157 
158 	for (index = 0; index < count; index++)
159 		if (cracked[index])
160 			return 1;
161 	return 0;
162 }
163 
cmp_one(void * binary,int index)164 static int cmp_one(void *binary, int index)
165 {
166 	return cracked[index];
167 }
168 
cmp_exact(char * source,int index)169 static int cmp_exact(char *source, int index)
170 {
171 	return 1;
172 }
173 
174 struct fmt_main fmt_iwork = {
175 	{
176 		FORMAT_LABEL,
177 		FORMAT_NAME,
178 		ALGORITHM_NAME,
179 		BENCHMARK_COMMENT,
180 		BENCHMARK_LENGTH,
181 		0,
182 		PLAINTEXT_LENGTH,
183 		BINARY_SIZE,
184 		BINARY_ALIGN,
185 		SALT_SIZE,
186 		SALT_ALIGN,
187 		MIN_KEYS_PER_CRYPT,
188 		MAX_KEYS_PER_CRYPT,
189 		FMT_CASE | FMT_8_BIT | FMT_OMP,
190 		{
191 			"iteration count",
192 		},
193 		{ FORMAT_TAG },
194 		iwork_tests
195 	}, {
196 		init,
197 		done,
198 		fmt_default_reset,
199 		fmt_default_prepare,
200 		iwork_common_valid,
201 		fmt_default_split,
202 		fmt_default_binary,
203 		iwork_common_get_salt,
204 		{
205 			iwork_common_iteration_count,
206 		},
207 		fmt_default_source,
208 		{
209 			fmt_default_binary_hash
210 		},
211 		fmt_default_salt_hash,
212 		NULL,
213 		set_salt,
214 		iwork_set_key,
215 		get_key,
216 		fmt_default_clear_keys,
217 		crypt_all,
218 		{
219 			fmt_default_get_hash
220 		},
221 		cmp_all,
222 		cmp_one,
223 		cmp_exact
224 	}
225 };
226 
227 #endif /* plugin stanza */
228