1 /*
2  * This software is Copyright (c) 2015 Sayantan Datta <std2048 at gmail dot com>
3  * and it is hereby released to the general public under the following terms:
4  * Redistribution and use in source and binary forms, with or without modification, are permitted.
5  * Based on Solar Designer implementation of DES_bs_b.c in jtr-v1.7.9
6  */
7 
8 #if HAVE_OPENCL
9 
10 #include <string.h>
11 
12 #include "opencl_lm.h"
13 #include "arch.h"
14 #include "common.h"
15 #include "opencl_lm_hst_dev_shared.h"
16 #include "unicode.h"
17 #include "mask_ext.h"
18 
19 opencl_lm_combined *opencl_lm_all;
20 opencl_lm_transfer *opencl_lm_keys;
21 unsigned int *opencl_lm_int_key_loc = NULL;
22 unsigned int CC_CACHE_ALIGN opencl_lm_index768[0x300];
23 unsigned char opencl_lm_u[0x100];
24 
25 static unsigned char LM_KP[56] = {
26 	1, 2, 3, 4, 5, 6, 7,
27 	10, 11, 12, 13, 14, 15, 0,
28 	19, 20, 21, 22, 23, 8, 9,
29 	28, 29, 30, 31, 16, 17, 18,
30 	37, 38, 39, 24, 25, 26, 27,
31 	46, 47, 32, 33, 34, 35, 36,
32 	55, 40, 41, 42, 43, 44, 45,
33 	48, 49, 50, 51, 52, 53, 54
34 };
35 
36 static unsigned char LM_reverse[16] = {
37 	0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
38 };
39 
40 static  unsigned char LM_IP[64] = {
41 	57, 49, 41, 33, 25, 17, 9, 1,
42 	59, 51, 43, 35, 27, 19, 11, 3,
43 	61, 53, 45, 37, 29, 21, 13, 5,
44 	63, 55, 47, 39, 31, 23, 15, 7,
45 	56, 48, 40, 32, 24, 16, 8, 0,
46 	58, 50, 42, 34, 26, 18, 10, 2,
47 	60, 52, 44, 36, 28, 20, 12, 4,
48 	62, 54, 46, 38, 30, 22, 14, 6
49 };
50 
51 static unsigned char opencl_LM_PC1[56] = {
52 	56, 48, 40, 32, 24, 16, 8,
53 	0, 57, 49, 41, 33, 25, 17,
54 	9, 1, 58, 50, 42, 34, 26,
55 	18, 10, 2, 59, 51, 43, 35,
56 	62, 54, 46, 38, 30, 22, 14,
57 	6, 61, 53, 45, 37, 29, 21,
58 	13, 5, 60, 52, 44, 36, 28,
59 	20, 12, 4, 27, 19, 11, 3
60 };
61 
62 static unsigned char opencl_LM_ROT[16] = {
63 	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
64 };
65 
66 static unsigned char opencl_LM_PC2[48] = {
67 	13, 16, 10, 23, 0, 4,
68 	2, 27, 14, 5, 20, 9,
69 	22, 18, 11, 3, 25, 7,
70 	15, 6, 26, 19, 12, 1,
71 	40, 51, 30, 36, 46, 54,
72 	29, 39, 50, 44, 32, 47,
73 	43, 48, 38, 55, 33, 52,
74 	45, 41, 49, 35, 28, 31
75 };
76 
opencl_lm_init_index()77 void opencl_lm_init_index()
78 {
79 	int p,q,s,t ;
80 	int round, index, bit;
81 
82 	s = 0;
83 	t = 0;
84 	for (round = 0; round < 16; round++) {
85 		s += opencl_LM_ROT[round];
86 		for (index = 0; index < 48; index++) {
87 			p = opencl_LM_PC2[index];
88 			q = p < 28 ? 0 : 28;
89 			p += s;
90 			while (p >= 28) p -= 28;
91 			bit = opencl_LM_PC1[p + q];
92 			bit ^= 070;
93 			bit -= bit >> 3;
94 			bit = 55 - bit;
95 			bit = LM_KP[bit];
96 			opencl_lm_index768[t++] = bit;
97 		}
98 	}
99 
100 	for (p = 0; p < 0x100; p++)
101 		opencl_lm_u[p] = CP_up[p];
102 }
103 
opencl_lm_init(int block)104 void opencl_lm_init(int block)
105 {
106 	int index;
107 
108 	for (index = 0; index < LM_DEPTH; index++)
109 		opencl_lm_all[block].pxkeys[index] =
110 			&opencl_lm_keys[block].xkeys.c[0][index & 7][index >> 3];
111 }
112 
opencl_lm_set_key(char * key,int index)113 void opencl_lm_set_key(char *key, int index)
114 {
115 	unsigned long c;
116 	unsigned char *dst;
117 	unsigned int section, key_index;
118 
119 	section = index >> LM_LOG_DEPTH;
120 	key_index = index & (LM_DEPTH - 1);
121 	dst = opencl_lm_all[section].pxkeys[key_index];
122 
123 	c = (unsigned char)key[0];
124 	if (!c) goto fill7;
125 	*dst = opencl_lm_u[c];
126 	c = (unsigned char)key[1];
127 	if (!c) goto fill6;
128 	*(dst + sizeof(lm_vector) * 8) = opencl_lm_u[c];
129 	c = (unsigned char)key[2];
130 	if (!c) goto fill5;
131 	*(dst + sizeof(lm_vector) * 8 * 2) = opencl_lm_u[c];
132 	c = (unsigned char)key[3];
133 	if (!c) goto fill4;
134 	*(dst + sizeof(lm_vector) * 8 * 3) = opencl_lm_u[c];
135 	c = (unsigned char)key[4];
136 	if (!c) goto fill3;
137 	*(dst + sizeof(lm_vector) * 8 * 4) = opencl_lm_u[c];
138 	c = (unsigned char)key[5];
139 	if (!c) goto fill2;
140 	*(dst + sizeof(lm_vector) * 8 * 5) = opencl_lm_u[c];
141 	c = (unsigned char)key[6];
142 	*(dst + sizeof(lm_vector) * 8 * 6) = opencl_lm_u[c];
143 	return;
144 fill7:
145 	dst[0] = 0;
146 fill6:
147 	dst[sizeof(lm_vector) * 8] = 0;
148 fill5:
149 	dst[sizeof(lm_vector) * 8 * 2] = 0;
150 fill4:
151 	dst[sizeof(lm_vector) * 8 * 3] = 0;
152 fill3:
153 	dst[sizeof(lm_vector) * 8 * 4] = 0;
154 fill2:
155 	dst[sizeof(lm_vector) * 8 * 5] = 0;
156 	dst[sizeof(lm_vector) * 8 * 6] = 0;
157 }
158 
opencl_lm_set_key_mm(char * key,int index)159 void opencl_lm_set_key_mm(char *key, int index)
160 {
161 	unsigned int len = strlen(key);
162 	unsigned int i;
163 	unsigned long c;
164 
165 	for (i = 0; i < len; i++) {
166 		c = (unsigned char) key[i];
167 		memset(opencl_lm_keys[index].xkeys.v[i], opencl_lm_u[c], 8 * sizeof(lm_vector));
168 	}
169 
170 	for (i = len; i < PLAINTEXT_LENGTH; i++)
171 		memset(opencl_lm_keys[index].xkeys.v[i], 0, 8 * sizeof(lm_vector));
172 
173 	if (!mask_gpu_is_static) {
174 		opencl_lm_int_key_loc[index] = 0;
175 		for (i = 0; i < MASK_FMT_INT_PLHDR; i++) {
176 			if (mask_skip_ranges[i] != -1)  {
177 				opencl_lm_int_key_loc[index] |= ((mask_int_cand.
178 				int_cpu_mask_ctx->ranges[mask_skip_ranges[i]].offset +
179 				mask_int_cand.int_cpu_mask_ctx->
180 				ranges[mask_skip_ranges[i]].pos) & 0xff) << (i << 3);
181 			}
182 			else
183 				opencl_lm_int_key_loc[index] |= 0x80 << (i << 3);
184 		}
185 	}
186 }
187 
lm_get_binary_raw(WORD * raw,int count)188 static WORD *lm_get_binary_raw(WORD *raw, int count)
189 {
190 	static WORD out[2];
191 
192 /* For odd iteration counts, swap L and R here instead of doing it one
193  * more time in lm_crypt(). */
194 	count &= 1;
195 	out[count] = raw[0];
196 	out[count ^ 1] = raw[1];
197 
198 	return out;
199 }
200 
opencl_lm_do_IP(WORD in[2])201 static WORD *opencl_lm_do_IP(WORD in[2])
202 {
203 	static WORD out[2];
204 	int src, dst;
205 
206 	out[0] = out[1] = 0;
207 	for (dst = 0; dst < 64; dst++) {
208 		src = LM_IP[dst ^ 0x20];
209 
210 		if (in[src >> 5] & (1 << (src & 0x1F)))
211 			out[dst >> 5] |= 1 << (dst & 0x1F);
212 	}
213 
214 	return out;
215 }
216 
opencl_lm_get_binary(char * ciphertext)217 WORD *opencl_lm_get_binary(char *ciphertext)
218 {
219 	WORD block[2], value;
220 	int l, h;
221 	int index;
222 
223 	block[0] = block[1] = 0;
224 	for (index = 0; index < 16; index += 2) {
225 		l = atoi16[ARCH_INDEX(ciphertext[index])];
226 		h = atoi16[ARCH_INDEX(ciphertext[index + 1])];
227 		value = LM_reverse[l] | (LM_reverse[h] << 4);
228 		block[index >> 3] |= value << ((index << 2) & 0x18);
229 	}
230 
231 	return lm_get_binary_raw(opencl_lm_do_IP(block), 1);
232 }
233 
opencl_lm_do_FP(WORD in[2])234 static WORD *opencl_lm_do_FP(WORD in[2])
235 {
236 	static WORD out[2];
237 	int src, dst;
238 
239 	out[0] = out[1] = 0;
240 	for (src = 0; src < 64; src++) {
241 		dst = LM_IP[src ^ 0x20];
242 
243 		if (in[src >> 5] & ((unsigned WORD)1 << (src & 0x1F)))
244 			out[dst >> 5] |= (unsigned WORD)1 << (dst & 0x1F);
245 	}
246 
247 	return out;
248 }
249 
opencl_lm_get_source(WORD * raw)250 char *opencl_lm_get_source(WORD *raw)
251 {
252 	static char out[17];
253 	char *p;
254 	WORD swapped[2], *block, value;
255 	int l, h;
256 	int index;
257 
258 	swapped[0] = raw[1];
259 	swapped[1] = raw[0];
260 
261 	block = opencl_lm_do_FP(swapped);
262 
263 	p = out;
264 	for (index = 0; index < 16; index += 2) {
265 		value = (block[index >> 3] >> ((index << 2) & 0x18)) & 0xff;
266 		l = LM_reverse[value & 0xf];
267 		h = LM_reverse[value >> 4];
268 		*p++ = itoa16[l];
269 		*p++ = itoa16[h];
270 	}
271 	*p = 0;
272 
273 	return out;
274 }
275 
276 #endif /* #if HAVE_OPENCL */
277