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