1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
17 #include "bruteforce.h"
21 uint8_t charset_digits
[] = {
22 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
25 uint8_t charset_uppercase
[] = {
26 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
27 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'W',
31 smart_generator_t
*smart_generators
[] = {
32 smart_generator_byte_repeat
,
33 smart_generator_msb_byte_only
,
34 smart_generator_nibble_sequence
,
39 void bf_generator_init(generator_context_t
*ctx
, uint8_t mode
, uint8_t key_length
) {
40 memset(ctx
, 0, sizeof(generator_context_t
));
42 ctx
->key_length
= key_length
;
45 int bf_generator_set_charset(generator_context_t
*ctx
, uint8_t charsets
) {
46 if (ctx
->mode
!= BF_MODE_CHARSET
) {
50 if (charsets
& BF_CHARSET_DIGITS
) {
51 memcpy(ctx
->charset
, charset_digits
, sizeof(charset_digits
));
52 ctx
->charset_length
+= sizeof(charset_digits
);
55 if (charsets
& BF_CHARSET_UPPERCASE
) {
56 memcpy(ctx
->charset
+ ctx
->charset_length
, charset_uppercase
, sizeof(charset_uppercase
));
57 ctx
->charset_length
+= sizeof(charset_uppercase
);
63 int bf_generate(generator_context_t
*ctx
) {
67 return _bf_generate_mode_range(ctx
);
69 case BF_MODE_CHARSET
: {
70 return _bf_generate_mode_charset(ctx
);
73 return _bf_generate_mode_smart(ctx
);
77 return BF_GENERATOR_ERROR
;
81 // increments values in array with carryover using modulo limit for each byte
82 // this is used to iterate each byte in key over charset table
83 // returns -1 if incrementing reaches its end
84 int bf_array_increment(uint8_t *data
, uint8_t data_len
, uint8_t modulo
) {
86 // check if we reached max value already
88 for (i
= 0; i
< data_len
; i
++) {
89 if (data
[i
] < modulo
- 1) {
98 for (uint8_t pos
= data_len
- 1;; pos
--) {
100 uint8_t prev_value
= ++data
[pos
];
102 data
[pos
] = data
[pos
] % modulo
;
104 if (prev_value
== data
[pos
]) {
106 } else if (pos
== 0) {
107 // we cannot carryover to next byte
108 // with the max value check in place before, we should not reach this place
116 // get current key casted to 32 bit
117 uint32_t bf_get_key32(const generator_context_t
*ctx
) {
118 return ctx
->current_key
& 0xFFFFFFFF;
121 // get current key casted to 48 bit
122 uint64_t bf_get_key48(const generator_context_t
*ctx
) {
123 return ctx
->current_key
& 0xFFFFFFFFFFFF;
126 void bf_generator_clear(generator_context_t
*ctx
) {
134 int _bf_generate_mode_range(generator_context_t
*ctx
) {
136 if (ctx
->key_length
!= BF_KEY_SIZE_32
&& ctx
->key_length
!= BF_KEY_SIZE_48
) {
137 return BF_GENERATOR_ERROR
;
140 if (ctx
->current_key
>= ctx
->range_high
) {
141 return BF_GENERATOR_END
;
144 // we use flag1 as indicator if value of range_low was already emitted
145 // so the range generated is <range_low, range_high>
146 if (ctx
->current_key
<= ctx
->range_low
&& ctx
->flag1
== false) {
147 ctx
->current_key
= ctx
->range_low
;
149 return BF_GENERATOR_NEXT
;
153 return BF_GENERATOR_NEXT
;
156 int _bf_generate_mode_charset(generator_context_t
*ctx
) {
158 if (ctx
->key_length
!= BF_KEY_SIZE_32
&& ctx
->key_length
!= BF_KEY_SIZE_48
) {
159 return BF_GENERATOR_ERROR
;
163 return BF_GENERATOR_END
;
166 uint8_t key_byte
= 0;
167 ctx
->current_key
= 0;
169 for (key_byte
= 0; key_byte
< ctx
->key_length
; key_byte
++) {
170 ctx
->current_key
|= (uint64_t) ctx
->charset
[ctx
->pos
[key_byte
]] << ((ctx
->key_length
- key_byte
- 1) * 8);
173 if (bf_array_increment(ctx
->pos
, ctx
->key_length
, ctx
->charset_length
) == -1) {
174 // set flag1 to emit value last time and end generation on next call
178 return BF_GENERATOR_NEXT
;
181 int _bf_generate_mode_smart(generator_context_t
*ctx
) {
184 if (smart_generators
[ctx
->smart_mode_stage
] == NULL
) {
185 return BF_GENERATOR_END
;
188 int ret
= smart_generators
[ctx
->smart_mode_stage
](ctx
);
191 case BF_GENERATOR_NEXT
: {
194 case BF_GENERATOR_ERROR
: {
197 case BF_GENERATOR_END
: {
198 ctx
->smart_mode_stage
++;
199 bf_generator_clear(ctx
);
207 int smart_generator_byte_repeat(generator_context_t
*ctx
) {
208 // key consists of repeated single byte
209 uint32_t current_byte
= ctx
->counter1
;
211 if (current_byte
> 0xFF) {
212 return BF_GENERATOR_END
;
215 ctx
->current_key
= 0;
217 for (uint8_t key_byte
= 0; key_byte
< ctx
->key_length
; key_byte
++) {
218 ctx
->current_key
|= (uint64_t)current_byte
<< ((ctx
->key_length
- key_byte
- 1) * 8);
222 return BF_GENERATOR_NEXT
;
224 int smart_generator_msb_byte_only(generator_context_t
*ctx
) {
225 // key of one byte (most significant one) and all others being zero
226 uint32_t current_byte
= ctx
->counter1
;
228 if (current_byte
> 0xFF) {
229 return BF_GENERATOR_END
;
232 ctx
->current_key
= (uint64_t)current_byte
<< ((ctx
->key_length
- 1) * 8);
235 return BF_GENERATOR_NEXT
;
239 int smart_generator_nibble_sequence(generator_context_t
*ctx
) {
240 // patterns like A0A1A2A3...F0F1F2F3
241 // also with offsets - A1A2A3, A2A3A4, etc
242 // counter1 is high nibble (A, B, C), counter2 is low nibble (0,1, etc)
244 if (ctx
->counter1
== 0) { // init values on first generator call
245 ctx
->counter1
= 0x0A;
250 // we substract %2 value because max_offset must be even number
251 uint8_t max_offset
= 10 - (ctx
->key_length
/ 2) - (ctx
->key_length
/ 2) % 2;
253 if (ctx
->counter1
== 0x10) {
254 return BF_GENERATOR_END
;
257 ctx
->current_key
= 0;
259 for (key_byte
= 0; key_byte
< ctx
->key_length
; key_byte
++) {
260 ctx
->current_key
|= (uint64_t) ctx
->counter1
<< (((ctx
->key_length
- key_byte
- 1) * 8) + 4);
261 ctx
->current_key
|= (uint64_t)(key_byte
+ ctx
->counter2
) % 10 << ((ctx
->key_length
- key_byte
- 1) * 8);
264 // counter 2 is the offset
267 if (ctx
->counter2
== max_offset
) {
272 return BF_GENERATOR_NEXT
;