1 /*
2 * PEM (PKCS #8) cracker.
3 *
4 * This software is Copyright (c) 2015, Dhiru Kholia <kholia at kth.se>,
5 * and it is hereby released to the general public under the following terms:
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted.
8 *
9 * This code may be freely used and modified for any purpose.
10 *
11 * Big thanks to Martin Kleppmann, and Lapo Luchini for making this format
12 * possible.
13 */
14
15 #if FMT_EXTERNS_H
16 extern struct fmt_main fmt_pem;
17 #elif FMT_REGISTERS_H
18 john_register_one(&fmt_pem);
19 #else
20
21 #ifdef _OPENMP
22 #include <omp.h>
23 #endif
24
25 #define OMP_SCALE 2 // MKPC and OMP_SCALE tuned on Core i5-6500
26
27 #include "arch.h"
28 #include "misc.h"
29 #include "common.h"
30 #include "formats.h"
31 #include "params.h"
32 #include "options.h"
33 #include "pem_common.h"
34 #include "pbkdf2_hmac_sha1.h"
35 #include "jumbo.h"
36
37 #define FORMAT_LABEL "PEM"
38 #ifdef SIMD_COEF_32
39 #define ALGORITHM_NAME "PBKDF2-SHA1 " SHA1_ALGORITHM_NAME " 3DES/AES"
40 #else
41 #define ALGORITHM_NAME "PBKDF2-SHA1 32/" ARCH_BITS_STR " 3DES/AES"
42 #endif
43 #define BENCHMARK_COMMENT ""
44 #define BENCHMARK_LENGTH 0x107
45 #define BINARY_SIZE 0
46 #define PLAINTEXT_LENGTH 125
47 #define SALT_SIZE sizeof(*cur_salt)
48 #define BINARY_ALIGN 1
49 #define SALT_ALIGN sizeof(int)
50 #ifdef SIMD_COEF_32
51 #define MIN_KEYS_PER_CRYPT SSE_GROUP_SZ_SHA1
52 #define MAX_KEYS_PER_CRYPT (SSE_GROUP_SZ_SHA1 * 8)
53 #else
54 #define MIN_KEYS_PER_CRYPT 1
55 #define MAX_KEYS_PER_CRYPT 64
56 #endif
57
58 static char (*saved_key)[PLAINTEXT_LENGTH + 1];
59 static int *cracked, cracked_count;
60
61 static struct custom_salt *cur_salt;
62
init(struct fmt_main * self)63 static void init(struct fmt_main *self)
64 {
65 omp_autotune(self, OMP_SCALE);
66 saved_key = mem_calloc(sizeof(*saved_key), self->params.max_keys_per_crypt);
67 cracked = mem_calloc(sizeof(*cracked), self->params.max_keys_per_crypt);
68 cracked_count = self->params.max_keys_per_crypt;
69 }
70
done(void)71 static void done(void)
72 {
73 MEM_FREE(cracked);
74 MEM_FREE(saved_key);
75 }
76
set_salt(void * salt)77 static void set_salt(void *salt)
78 {
79 cur_salt = (struct custom_salt *)salt;
80 }
81
PEM_set_key(char * key,int index)82 static void PEM_set_key(char *key, int index)
83 {
84 strnzcpy(saved_key[index], key, sizeof(*saved_key));
85 }
86
get_key(int index)87 static char *get_key(int index)
88 {
89 return saved_key[index];
90 }
91
crypt_all(int * pcount,struct db_salt * salt)92 static int crypt_all(int *pcount, struct db_salt *salt)
93 {
94 const int count = *pcount;
95 int index = 0;
96
97 memset(cracked, 0, sizeof(cracked[0])*cracked_count);
98
99 #ifdef _OPENMP
100 #pragma omp parallel for
101 #endif
102 for (index = 0; index < count; index += MIN_KEYS_PER_CRYPT) {
103 unsigned char master[MIN_KEYS_PER_CRYPT][32];
104 int i;
105 #ifdef SIMD_COEF_32
106 int lens[MIN_KEYS_PER_CRYPT];
107 unsigned char *pin[MIN_KEYS_PER_CRYPT], *pout[MIN_KEYS_PER_CRYPT];
108 for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i) {
109 lens[i] = strlen(saved_key[index+i]);
110 pin[i] = (unsigned char*)saved_key[index+i];
111 pout[i] = master[i];
112 }
113 pbkdf2_sha1_sse((const unsigned char**)pin, lens, cur_salt->salt, SALTLEN, cur_salt->iterations, pout, cur_salt->key_length, 0);
114 #else
115 pbkdf2_sha1((unsigned char *)saved_key[index], strlen(saved_key[index]), cur_salt->salt, SALTLEN, cur_salt->iterations, master[0], cur_salt->key_length, 0);
116 #endif
117 for (i = 0; i < MIN_KEYS_PER_CRYPT; ++i) {
118 if (pem_decrypt(master[i], cur_salt->iv, cur_salt->ciphertext, cur_salt) == 0)
119 cracked[index+i] = 1;
120 else
121 cracked[index+i] = 0;
122 }
123 }
124
125 return count;
126 }
127
cmp_all(void * binary,int count)128 static int cmp_all(void *binary, int count)
129 {
130 int index;
131
132 for (index = 0; index < count; index++)
133 if (cracked[index])
134 return 1;
135 return 0;
136 }
137
cmp_one(void * binary,int index)138 static int cmp_one(void *binary, int index)
139 {
140 return cracked[index];
141 }
142
cmp_exact(char * source,int index)143 static int cmp_exact(char *source, int index)
144 {
145 return 1;
146 }
147
148 struct fmt_main fmt_pem = {
149 {
150 FORMAT_LABEL,
151 FORMAT_NAME,
152 ALGORITHM_NAME,
153 BENCHMARK_COMMENT,
154 BENCHMARK_LENGTH,
155 0,
156 PLAINTEXT_LENGTH,
157 BINARY_SIZE,
158 BINARY_ALIGN,
159 SALT_SIZE,
160 SALT_ALIGN,
161 MIN_KEYS_PER_CRYPT,
162 MAX_KEYS_PER_CRYPT,
163 FMT_CASE | FMT_8_BIT | FMT_OMP | FMT_HUGE_INPUT,
164 {
165 "iteration count",
166 "cipher [1=3DES, 2/3/4=AES-128/192/256]",
167 },
168 { FORMAT_TAG },
169 pem_tests
170 }, {
171 init,
172 done,
173 fmt_default_reset,
174 fmt_default_prepare,
175 pem_valid,
176 fmt_default_split,
177 fmt_default_binary,
178 pem_get_salt,
179 {
180 pem_iteration_count,
181 pem_cipher,
182 },
183 fmt_default_source,
184 {
185 fmt_default_binary_hash
186 },
187 fmt_default_salt_hash,
188 NULL,
189 set_salt,
190 PEM_set_key,
191 get_key,
192 fmt_default_clear_keys,
193 crypt_all,
194 {
195 fmt_default_get_hash
196 },
197 cmp_all,
198 cmp_one,
199 cmp_exact
200 }
201 };
202
203 #endif /* plugin stanza */
204