summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbtools/sb1.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-02-16 20:47:07 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2013-02-16 20:49:07 +0100
commitb05b762ed45c6c8967fce098c598ec1a6ed7a533 (patch)
treeca704d48a3ac5acd8097d8485208f2f328766650 /utils/imxtools/sbtools/sb1.c
parent4db4985f21bd8f36533f8e71db916e6d3d5d2249 (diff)
downloadrockbox-b05b762ed45c6c8967fce098c598ec1a6ed7a533.tar.gz
rockbox-b05b762ed45c6c8967fce098c598ec1a6ed7a533.zip
sbtools: add brute force option for sb1 in sbtoelf
After some reverse engineering, it appears that the keys of the sb1 format are very weak: the 128 bytes are generated from the laserfuse words 4,5 and 6 but in a weird manner: 4 and 5 are simply ORed and 6 is only half used (somehow), making it "only" a 48 bit word to find. Change-Id: I40702e19d0924ef51c01894efce3cb65bd664456
Diffstat (limited to 'utils/imxtools/sbtools/sb1.c')
-rw-r--r--utils/imxtools/sbtools/sb1.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/utils/imxtools/sbtools/sb1.c b/utils/imxtools/sbtools/sb1.c
index e4eb470e99..deb09a51e1 100644
--- a/utils/imxtools/sbtools/sb1.c
+++ b/utils/imxtools/sbtools/sb1.c
@@ -252,6 +252,109 @@ static const char *sb1_datatype_name(int cmd)
252 } 252 }
253} 253}
254 254
255bool sb1_is_key_valid_fast(void *buffer, size_t size, union xorcrypt_key_t _key[2])
256{
257 struct sb1_header_t *header = (struct sb1_header_t *)buffer;
258
259 union xorcrypt_key_t key[2];
260
261 uint8_t sector[SECTOR_SIZE];
262 /* copy key and data because it's modified by the crypto code */
263 memcpy(key, _key, sizeof(key));
264 memcpy(sector, header + 1, SECTOR_SIZE - header->header_size);
265 /* try to decrypt the first sector */
266 uint32_t mark = xor_decrypt(key, sector, SECTOR_SIZE - 4 - header->header_size);
267 /* copy key again it's modified by the crypto code */
268 return mark == *(uint32_t *)&sector[SECTOR_SIZE - 4 - header->header_size];
269}
270
271bool sb1_brute_force(const char *filename, void *u, sb1_color_printf cprintf,
272 enum sb1_error_t *err, struct crypto_key_t *key)
273{
274 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
275 uint8_t sector[SECTOR_SIZE];
276 FILE *f = fopen(filename, "rb");
277 if(f == NULL)
278 {
279 printf("Cannot open file '%s' for reading: %m\n", filename);
280 *err = SB1_OPEN_ERROR;
281 return false;
282 }
283 if(fread(sector, sizeof(sector), 1, f) != 1)
284 {
285 printf("Cannot read file '%s': %m\n", filename);
286 *err = SB1_READ_ERROR;
287 fclose(f);
288 return false;
289 }
290 fclose(f);
291
292 printf(BLUE, "Brute forcing key...\n");
293 time_t start_time = time(NULL);
294 uint32_t laserfuse[3] = {0, 0, 0};
295 unsigned last_print = 0;
296 do
297 {
298 for(int i = 0; i < 0x10000; i++)
299 {
300 laserfuse[2] = (i & 0xff00) << 8 | (i & 0xff);
301 xor_generate_key(laserfuse, key->u.xor_key);
302 if(g_debug)
303 {
304 printf(GREEN, "Trying key");
305 printf(GREEN, "[");
306 printf(RED, "%08x", laserfuse[0]);
307 printf(GREEN, ",");
308 printf(RED, "%08x", laserfuse[1]);
309 printf(GREEN, ",");
310 printf(RED, "%08x", laserfuse[2]);
311 printf(GREEN, "]:");
312 for(int j = 0; j < 32; j++)
313 printf(YELLOW, " %08x", key->u.xor_key[j / 16].k[j % 16]);
314 }
315 if(sb1_is_key_valid_fast(sector, SECTOR_SIZE, key->u.xor_key))
316 {
317 if(g_debug)
318 printf(RED, " Ok\n");
319 return true;
320 }
321 else
322 {
323 if(g_debug)
324 printf(RED, " No\n");
325 }
326 }
327 laserfuse[0]++;
328
329 if(laserfuse[0] / 1000 != last_print)
330 {
331 time_t cur_time = time(NULL);
332 float key_per_sec = laserfuse[0] / (float)(cur_time - start_time);
333 float tot = 0x1000000LL / key_per_sec;
334 time_t eta_time = start_time + tot;
335
336 printf(YELLOW, "%llu", laserfuse[0] * 0x10000LL);
337 printf(GREEN, " out of ");
338 printf(BLUE, "%llu", 0x1000000LL * 0x10000LL);
339 printf(GREEN, " tested (");
340 printf(RED, "%f%%", laserfuse[0] / (float)0x1000000LL * 100.0);
341 printf(GREEN, "), ");
342 printf(YELLOW, "%d", cur_time - start_time);
343 printf(GREEN, " seconds elapsed, ");
344 printf(BLUE, "%d", eta_time - cur_time);
345 printf(GREEN, " seconds remaining, [");
346 printf(RED, "%f", key_per_sec);
347 printf(GREEN, " keys/s], ETA ");
348 printf(YELLOW, "%s", ctime(&eta_time));
349 last_print = laserfuse[0] / 1000;
350 }
351 }while(laserfuse[0] != 0);
352
353 *err = SB1_NO_VALID_KEY;
354 return false;
355 #undef printf
356}
357
255struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u, 358struct sb1_file_t *sb1_read_memory(void *_buf, size_t filesize, void *u,
256 sb1_color_printf cprintf, enum sb1_error_t *err) 359 sb1_color_printf cprintf, enum sb1_error_t *err)
257{ 360{