1 /*
2 * This software is Copyright (c) 2016 Denis Burykin
3 * [denis_burykin yahoo com], [denis-burykin2014 yandex ru]
4 * and it is hereby released to the general public under the following terms:
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted.
7 *
8 */
9 #include <stdlib.h>
10
11 #include "../mask_ext.h"
12
13 #include "jtr_mask.h"
14 #include "pkt_comm/word_gen.h"
15
16 /*
17 * Word generator configuration - used by devices
18 */
19 struct word_gen word_gen;
20
21
22 /*
23 static int static_gpu_locations[MASK_FMT_INT_PLHDR];
24
25 // Got the following code from some opencl_* implementations.
26 // Could not discover when any of static_gpu_locations are other than -1.
27 // Some opencl_* implementation operate without static_gpu_locations.
28 //
29 int i;
30 for (i = 0; i < MASK_FMT_INT_PLHDR; i++)
31 if (mask_skip_ranges && mask_skip_ranges[i] != -1)
32 static_gpu_locations[i] = mask_int_cand.int_cpu_mask_ctx->
33 ranges[mask_skip_ranges[i]].pos;
34 else
35 static_gpu_locations[i] = -1;
36
37 for (i = 0; i < MASK_FMT_INT_PLHDR; i++)
38 if (static_gpu_locations[i] != -1) {
39 fprintf(stderr,"!=> Unexpected mask data: static_gpu_locations: ");
40 int j;
41 for (j = 0; j < MASK_FMT_INT_PLHDR; j++)
42 fprintf(stderr,"%d ", static_gpu_locations[j]);
43 fprintf(stderr,"\n");
44 break;
45 }
46 */
47
48
mask_print()49 void mask_print()
50 {
51 fprintf(stderr, "==========\n> num_int_cand:%d static:%d\n",
52 mask_int_cand.num_int_cand, mask_gpu_is_static);
53
54 mask_cpu_context *mask = mask_int_cand.int_cpu_mask_ctx;
55 fprintf(stderr, "> ps1:%d count:%d cpu_count:%d offset:%d\n",
56 mask->ps1, mask->count, mask->cpu_count, mask->offset);
57
58 int i;
59 for (i = 0; i < MAX_NUM_MASK_PLHDR; i++) {
60 mask_range *range = mask->ranges + i;
61 if (!range->count)
62 break;
63 fprintf(stderr, "> Range %d: count %d, pos %d, offset %d\n",
64 i, range->count, range->pos, range->offset);
65 }
66
67 for (i = 0; i < MASK_FMT_INT_PLHDR; i++) {
68 if (mask_skip_ranges[i] == -1)
69 continue;
70 mask_range *range = mask_int_cand.int_cpu_mask_ctx->ranges
71 + mask_skip_ranges[i];
72 fprintf(stderr, "i:%d\tskip_ranges[i]:%d\toff:%d\tpos:%d\n",
73 i,mask_skip_ranges[i], range->offset, range->pos);
74 }
75 }
76
77
mask_set_range_info(unsigned char * range_info)78 void mask_set_range_info(unsigned char *range_info)
79 {
80 // In mask_mode, it inserts placeholders into the key.
81 // Such as if the key is 'pwd', mask is '?d?w?d?d' then
82 // set_key() gets '#pwd##' as an argument ('#' signs used).
83 // Some mask data, such as int_cpu_mask_ctx->ranges[i].offset
84 // is updated at every set_key() invocation.
85 //
86 // *-opencl implementations grab mask data and adds 4 bytes
87 // of data (MASK_FMT_INT_PLHDR is 4) to every key.
88 // Example follows.
89 //
90 // int i;
91 // saved_int_key_loc[index] = 0;
92 // for (i = 0; i < MASK_FMT_INT_PLHDR; i++) {
93 // if (mask_skip_ranges[i] != -1) {
94 // saved_int_key_loc[index] |= ((mask_int_cand.
95 // int_cpu_mask_ctx->ranges[mask_skip_ranges[i]].offset +
96 // mask_int_cand.int_cpu_mask_ctx->
97 // ranges[mask_skip_ranges[i]].pos) & 0xff) << (i << 3);
98 // }
99 // else
100 // saved_int_key_loc[index] |= 0x80 << (i << 3);
101 // }
102
103 // OK. Devices with pkt_comm_v2 use same approach.
104 //
105 int i;
106 for (i = 0; i < MASK_FMT_INT_PLHDR; i++) {
107 int range_num = mask_skip_ranges[i];
108 if (range_num == -1)
109 break;
110
111 // This range isn't unrolled on CPU, template key contains '#'
112 mask_range *range = mask_int_cand.int_cpu_mask_ctx->ranges + range_num;
113
114 // Device takes new position for the range.
115 // That shouldn't be less than range's original position.
116 // If 2+ ranges are moved to the same position
117 // (shouldn't happen) then the result is undefined.
118 int new_pos = range->pos + range->offset;
119 if (new_pos > 0x7f) {
120 fprintf(stderr, "Error: Mask placeholder in position %d\n",
121 new_pos);
122 error();
123 }
124
125 // Bit 7 indicates range is active.
126 range_info[i] = 0x80 | new_pos;
127 }
128
129 // If less than MASK_FMT_INT_PLHDR ranges are active
130 // then range_info bytes are terminated with '\0'.
131 if (i < MASK_FMT_INT_PLHDR)
132 range_info[i] = 0;
133 }
134
135
136 // Creates configuration for on-board word generator
137 // using mask data
mask_convert_to_word_gen()138 struct word_gen *mask_convert_to_word_gen()
139 {
140 if (mask_is_inactive())
141 return &word_gen_words_pass_by;
142
143 int dst_range_num = 0;
144 int i;
145 for (i = 0; i < MASK_FMT_INT_PLHDR; i++) {
146 int range_num = mask_skip_ranges[i];
147 if (range_num == -1)
148 break;
149
150 mask_range *range = mask_int_cand.int_cpu_mask_ctx->ranges + range_num;
151 word_gen.ranges[dst_range_num].num_chars = range->count;
152 word_gen.ranges[dst_range_num].start_idx = 0;
153 memcpy(word_gen.ranges[dst_range_num].chars,
154 range->chars, range->count);
155 dst_range_num++;
156 }
157
158 if (!dst_range_num) {
159 fprintf(stderr, "mask_convert_to_word_gen: failed\n");
160 exit(-1);
161 }
162
163 word_gen.num_ranges = dst_range_num;
164
165 return &word_gen;
166 }
167
168 // Reconstructs plaintext out of template key, range_info and
169 // ID of generated candidate.
170 // Assuming global mask didn't change since that.
171 // Designed for use in get_key(). 'key' is modified in place.
172 // If mask is not used or was deinitialized, then 'key'
173 // is not modified.
174 //
175 // This must be a good alternative to bitmap-like implementation,
176 // providing reasonable memory-to-CPU tradeoff.
177 //
mask_reconstruct_plaintext(char * key,unsigned char * range_info,unsigned int gen_id)178 void mask_reconstruct_plaintext(
179 char *key,
180 unsigned char *range_info,
181 unsigned int gen_id)
182 {
183 if (mask_is_inactive() || !mask_skip_ranges)
184 return;
185
186 unsigned int total_count = gen_id;
187 int i;
188 for (i = MASK_FMT_INT_PLHDR - 1; i >= 0; i--) {
189 int range_num = mask_skip_ranges[i];
190 if (range_num == -1)
191 continue;
192
193 mask_range *range = mask_int_cand.int_cpu_mask_ctx->ranges + range_num;
194 int char_index = total_count % range->count;
195 total_count /= range->count;
196
197 if (!range_info[i]) {
198 // This shouldn't happen
199 fprintf(stderr, "mask_reconstruct_plaintext: inconsistent data,"
200 " key: '%s', gen_id=%d\n", key, gen_id);
201 mask_print();
202 break;
203 }
204 unsigned char new_pos = range_info[i] & 0x7f;
205 key[new_pos] = range->chars[char_index];
206 }
207 }
208