diff options
Diffstat (limited to 'utils/nwztools/upgtools/keysig_search.c')
-rw-r--r-- | utils/nwztools/upgtools/keysig_search.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/utils/nwztools/upgtools/keysig_search.c b/utils/nwztools/upgtools/keysig_search.c new file mode 100644 index 0000000000..6054ea43ba --- /dev/null +++ b/utils/nwztools/upgtools/keysig_search.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2012 Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "keysig_search.h" | ||
22 | #include "misc.h" | ||
23 | #include "mg.h" | ||
24 | #include <string.h> | ||
25 | |||
26 | #define HEX_MAJ | ||
27 | |||
28 | static uint8_t g_cipher[8]; | ||
29 | static keysig_notify_fn_t g_notify; | ||
30 | static uint8_t g_key[8]; | ||
31 | static void *g_user; | ||
32 | static bool is_hex[256]; | ||
33 | static bool is_init = false; | ||
34 | #ifdef HEX_MAJ | ||
35 | static char hex_digits[] = "02468ABEF"; | ||
36 | #else | ||
37 | static char hex_digits[] = "02468abef"; | ||
38 | #endif | ||
39 | |||
40 | static void keysig_search_init() | ||
41 | { | ||
42 | if(is_init) return; | ||
43 | is_init = true; | ||
44 | memset(is_hex, 0, sizeof(is_hex)); | ||
45 | for(int i = '0'; i <= '9'; i++) | ||
46 | is_hex[i] = true; | ||
47 | #ifdef HEX_MAJ | ||
48 | for(int i = 'A'; i <= 'F'; i++) | ||
49 | #else | ||
50 | for(int i = 'a'; i <= 'f'; i++) | ||
51 | #endif | ||
52 | is_hex[i] = true; | ||
53 | } | ||
54 | |||
55 | static inline bool is_full_ascii(uint8_t *arr) | ||
56 | { | ||
57 | for(int i = 0; i < 8; i++) | ||
58 | if(!is_hex[arr[i]]) | ||
59 | return false; | ||
60 | return true; | ||
61 | } | ||
62 | |||
63 | static inline bool check_stupid() | ||
64 | { | ||
65 | uint8_t res[8]; | ||
66 | mg_decrypt_fw(g_cipher, 8, res, g_key); | ||
67 | if(is_full_ascii(res)) | ||
68 | return g_notify(g_user, g_key, res); | ||
69 | return false; | ||
70 | } | ||
71 | |||
72 | static bool search_stupid_rec(int rem_digit, int rem_letter, int pos) | ||
73 | { | ||
74 | if(pos == 8) | ||
75 | return check_stupid(); | ||
76 | if(rem_digit > 0) | ||
77 | { | ||
78 | for(int i = '0'; i <= '9'; i += 2) | ||
79 | { | ||
80 | g_key[pos] = i; | ||
81 | if(search_stupid_rec(rem_digit - 1, rem_letter, pos + 1)) | ||
82 | return true; | ||
83 | } | ||
84 | } | ||
85 | if(rem_letter > 0) | ||
86 | { | ||
87 | #ifdef HEX_MAJ | ||
88 | for(int i = 'a' - 1; i <= 'f'; i += 2) | ||
89 | #else | ||
90 | for(int i = 'A' - 1; i <= 'F'; i += 2) | ||
91 | #endif | ||
92 | { | ||
93 | g_key[pos] = i; | ||
94 | if(search_stupid_rec(rem_digit, rem_letter - 1, pos + 1)) | ||
95 | return true; | ||
96 | } | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | static bool search_stupid(int rem_digit, int rem_letter) | ||
102 | { | ||
103 | return search_stupid_rec(rem_digit, rem_letter, 0); | ||
104 | } | ||
105 | |||
106 | bool keysig_search_ascii_stupid(uint8_t *cipher, keysig_notify_fn_t notify, void *user) | ||
107 | { | ||
108 | keysig_search_init(); | ||
109 | memcpy(g_cipher, cipher, 8); | ||
110 | g_notify = notify; | ||
111 | g_user = user; | ||
112 | #if 1 | ||
113 | return search_stupid(4, 4) || | ||
114 | search_stupid(3, 5) || search_stupid(5, 3) || | ||
115 | search_stupid(2, 6) || search_stupid(6, 2) || | ||
116 | search_stupid(1, 7) || search_stupid(7, 1) || | ||
117 | search_stupid(0, 8) || search_stupid(8, 0); | ||
118 | #else | ||
119 | #define do(i) for(int a##i = 0; a##i < sizeof(hex_digits); a##i++) { g_key[i] = hex_digits[a##i]; | ||
120 | #define od() } | ||
121 | |||
122 | do(0)do(1)do(2)do(3)do(4)do(5)do(6)do(7) | ||
123 | if(check_stupid()) return true; | ||
124 | od()od()od()od()od()od()od()od() | ||
125 | #undef do | ||
126 | #undef od | ||
127 | return false; | ||
128 | #endif | ||
129 | } | ||
130 | |||
131 | bool keysig_search_ascii_brute(uint8_t *cipher, keysig_notify_fn_t notify, void *user) | ||
132 | { | ||
133 | keysig_search_init(); | ||
134 | return false; | ||
135 | } | ||
136 | |||
137 | struct keysig_search_desc_t keysig_search_desc[KEYSIG_SEARCH_LAST] = | ||
138 | { | ||
139 | [KEYSIG_SEARCH_NONE] = | ||
140 | { | ||
141 | .name = "none", | ||
142 | .fn = NULL, | ||
143 | .comment = "don't use", | ||
144 | }, | ||
145 | [KEYSIG_SEARCH_ASCII_STUPID] = | ||
146 | { | ||
147 | .name = "ascii-stupid", | ||
148 | .fn = keysig_search_ascii_stupid, | ||
149 | .comment = "Try to find a balance ascii key ignoring lsb" | ||
150 | }, | ||
151 | [KEYSIG_SEARCH_ASCII_BRUTE] = | ||
152 | { | ||
153 | .name = "ascii-brute", | ||
154 | .fn = keysig_search_ascii_brute, | ||
155 | .comment = "Brute force all ASCII keys" | ||
156 | }, | ||
157 | }; | ||