From f6208bde4630571ae75a43ea39a25a746f08bcfb Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sun, 17 Apr 2011 01:43:44 +0000 Subject: Rename sbinfo to sbtools and sbinfo.c to sbtoelf.c; preparing for future elftosb git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29733 a1c6a512-1295-4272-9138-f99709370657 --- utils/sbinfo/Makefile | 9 - utils/sbinfo/aes128.c | 284 ------------------- utils/sbinfo/crc.c | 78 ----- utils/sbinfo/crypto.h | 57 ---- utils/sbinfo/elf.c | 237 ---------------- utils/sbinfo/elf.h | 179 ------------ utils/sbinfo/fuze+_key_file.txt | 1 - utils/sbinfo/sb.h | 118 -------- utils/sbinfo/sbinfo.c | 596 --------------------------------------- utils/sbinfo/sha1.c | 150 ---------- utils/sbtools/Makefile | 9 + utils/sbtools/aes128.c | 284 +++++++++++++++++++ utils/sbtools/crc.c | 78 +++++ utils/sbtools/crypto.h | 57 ++++ utils/sbtools/elf.c | 237 ++++++++++++++++ utils/sbtools/elf.h | 179 ++++++++++++ utils/sbtools/fuze+_key_file.txt | 1 + utils/sbtools/sb.h | 118 ++++++++ utils/sbtools/sbtoelf.c | 596 +++++++++++++++++++++++++++++++++++++++ utils/sbtools/sha1.c | 150 ++++++++++ 20 files changed, 1709 insertions(+), 1709 deletions(-) delete mode 100644 utils/sbinfo/Makefile delete mode 100644 utils/sbinfo/aes128.c delete mode 100644 utils/sbinfo/crc.c delete mode 100644 utils/sbinfo/crypto.h delete mode 100644 utils/sbinfo/elf.c delete mode 100644 utils/sbinfo/elf.h delete mode 100644 utils/sbinfo/fuze+_key_file.txt delete mode 100644 utils/sbinfo/sb.h delete mode 100644 utils/sbinfo/sbinfo.c delete mode 100644 utils/sbinfo/sha1.c create mode 100644 utils/sbtools/Makefile create mode 100644 utils/sbtools/aes128.c create mode 100644 utils/sbtools/crc.c create mode 100644 utils/sbtools/crypto.h create mode 100644 utils/sbtools/elf.c create mode 100644 utils/sbtools/elf.h create mode 100644 utils/sbtools/fuze+_key_file.txt create mode 100644 utils/sbtools/sb.h create mode 100644 utils/sbtools/sbtoelf.c create mode 100644 utils/sbtools/sha1.c diff --git a/utils/sbinfo/Makefile b/utils/sbinfo/Makefile deleted file mode 100644 index 9427eaf875..0000000000 --- a/utils/sbinfo/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -TGT = sbinfo - -all: $(TGT) - -$(TGT): sbinfo.c crc.c crypto.h aes128.c sha1.c elf.c - $(CC) -g -std=c99 -o $(TGT) -W -Wall sbinfo.c aes128.c crc.c sha1.c elf.c - -clean: - rm -fr $(TGT) diff --git a/utils/sbinfo/aes128.c b/utils/sbinfo/aes128.c deleted file mode 100644 index d435009a14..0000000000 --- a/utils/sbinfo/aes128.c +++ /dev/null @@ -1,284 +0,0 @@ -// Simple, thoroughly commented implementation of 128-bit AES / Rijndael using C -// Chris Hulbert - chris.hulbert@gmail.com - http://splinter.com.au/blog -// References: -// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard -// http://en.wikipedia.org/wiki/Rijndael_key_schedule -// http://en.wikipeia.org/wiki/Rijndael_mix_columns -// http://en.wikipedia.org/wiki/Rijndael_S-box -// This code is public domain, or any OSI-approved license, your choice. No warranty. -#include "crypto.h" - -// Here are all the lookup tables for the row shifts, rcon, s-boxes, and galois field multiplications -byte shift_rows_table[] = {0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11}; -byte shift_rows_table_inv[] = {0,13,10,7,4,1,14,11,8,5,2,15,12,9,6,3}; -byte lookup_rcon[]={0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a}; -byte lookup_sbox[]={0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16}; -byte lookup_sbox_inv[]={0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d}; -byte lookup_g2 []={0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe,0x1b,0x19,0x1f,0x1d,0x13,0x11,0x17,0x15,0x0b,0x09,0x0f,0x0d,0x03,0x01,0x07,0x05,0x3b,0x39,0x3f,0x3d,0x33,0x31,0x37,0x35,0x2b,0x29,0x2f,0x2d,0x23,0x21,0x27,0x25,0x5b,0x59,0x5f,0x5d,0x53,0x51,0x57,0x55,0x4b,0x49,0x4f,0x4d,0x43,0x41,0x47,0x45,0x7b,0x79,0x7f,0x7d,0x73,0x71,0x77,0x75,0x6b,0x69,0x6f,0x6d,0x63,0x61,0x67,0x65,0x9b,0x99,0x9f,0x9d,0x93,0x91,0x97,0x95,0x8b,0x89,0x8f,0x8d,0x83,0x81,0x87,0x85,0xbb,0xb9,0xbf,0xbd,0xb3,0xb1,0xb7,0xb5,0xab,0xa9,0xaf,0xad,0xa3,0xa1,0xa7,0xa5,0xdb,0xd9,0xdf,0xdd,0xd3,0xd1,0xd7,0xd5,0xcb,0xc9,0xcf,0xcd,0xc3,0xc1,0xc7,0xc5,0xfb,0xf9,0xff,0xfd,0xf3,0xf1,0xf7,0xf5,0xeb,0xe9,0xef,0xed,0xe3,0xe1,0xe7,0xe5}; -byte lookup_g3 []={0x00,0x03,0x06,0x05,0x0c,0x0f,0x0a,0x09,0x18,0x1b,0x1e,0x1d,0x14,0x17,0x12,0x11,0x30,0x33,0x36,0x35,0x3c,0x3f,0x3a,0x39,0x28,0x2b,0x2e,0x2d,0x24,0x27,0x22,0x21,0x60,0x63,0x66,0x65,0x6c,0x6f,0x6a,0x69,0x78,0x7b,0x7e,0x7d,0x74,0x77,0x72,0x71,0x50,0x53,0x56,0x55,0x5c,0x5f,0x5a,0x59,0x48,0x4b,0x4e,0x4d,0x44,0x47,0x42,0x41,0xc0,0xc3,0xc6,0xc5,0xcc,0xcf,0xca,0xc9,0xd8,0xdb,0xde,0xdd,0xd4,0xd7,0xd2,0xd1,0xf0,0xf3,0xf6,0xf5,0xfc,0xff,0xfa,0xf9,0xe8,0xeb,0xee,0xed,0xe4,0xe7,0xe2,0xe1,0xa0,0xa3,0xa6,0xa5,0xac,0xaf,0xaa,0xa9,0xb8,0xbb,0xbe,0xbd,0xb4,0xb7,0xb2,0xb1,0x90,0x93,0x96,0x95,0x9c,0x9f,0x9a,0x99,0x88,0x8b,0x8e,0x8d,0x84,0x87,0x82,0x81,0x9b,0x98,0x9d,0x9e,0x97,0x94,0x91,0x92,0x83,0x80,0x85,0x86,0x8f,0x8c,0x89,0x8a,0xab,0xa8,0xad,0xae,0xa7,0xa4,0xa1,0xa2,0xb3,0xb0,0xb5,0xb6,0xbf,0xbc,0xb9,0xba,0xfb,0xf8,0xfd,0xfe,0xf7,0xf4,0xf1,0xf2,0xe3,0xe0,0xe5,0xe6,0xef,0xec,0xe9,0xea,0xcb,0xc8,0xcd,0xce,0xc7,0xc4,0xc1,0xc2,0xd3,0xd0,0xd5,0xd6,0xdf,0xdc,0xd9,0xda,0x5b,0x58,0x5d,0x5e,0x57,0x54,0x51,0x52,0x43,0x40,0x45,0x46,0x4f,0x4c,0x49,0x4a,0x6b,0x68,0x6d,0x6e,0x67,0x64,0x61,0x62,0x73,0x70,0x75,0x76,0x7f,0x7c,0x79,0x7a,0x3b,0x38,0x3d,0x3e,0x37,0x34,0x31,0x32,0x23,0x20,0x25,0x26,0x2f,0x2c,0x29,0x2a,0x0b,0x08,0x0d,0x0e,0x07,0x04,0x01,0x02,0x13,0x10,0x15,0x16,0x1f,0x1c,0x19,0x1a}; -byte lookup_g9 []={0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77,0x90,0x99,0x82,0x8b,0xb4,0xbd,0xa6,0xaf,0xd8,0xd1,0xca,0xc3,0xfc,0xf5,0xee,0xe7,0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c,0xab,0xa2,0xb9,0xb0,0x8f,0x86,0x9d,0x94,0xe3,0xea,0xf1,0xf8,0xc7,0xce,0xd5,0xdc,0x76,0x7f,0x64,0x6d,0x52,0x5b,0x40,0x49,0x3e,0x37,0x2c,0x25,0x1a,0x13,0x08,0x01,0xe6,0xef,0xf4,0xfd,0xc2,0xcb,0xd0,0xd9,0xae,0xa7,0xbc,0xb5,0x8a,0x83,0x98,0x91,0x4d,0x44,0x5f,0x56,0x69,0x60,0x7b,0x72,0x05,0x0c,0x17,0x1e,0x21,0x28,0x33,0x3a,0xdd,0xd4,0xcf,0xc6,0xf9,0xf0,0xeb,0xe2,0x95,0x9c,0x87,0x8e,0xb1,0xb8,0xa3,0xaa,0xec,0xe5,0xfe,0xf7,0xc8,0xc1,0xda,0xd3,0xa4,0xad,0xb6,0xbf,0x80,0x89,0x92,0x9b,0x7c,0x75,0x6e,0x67,0x58,0x51,0x4a,0x43,0x34,0x3d,0x26,0x2f,0x10,0x19,0x02,0x0b,0xd7,0xde,0xc5,0xcc,0xf3,0xfa,0xe1,0xe8,0x9f,0x96,0x8d,0x84,0xbb,0xb2,0xa9,0xa0,0x47,0x4e,0x55,0x5c,0x63,0x6a,0x71,0x78,0x0f,0x06,0x1d,0x14,0x2b,0x22,0x39,0x30,0x9a,0x93,0x88,0x81,0xbe,0xb7,0xac,0xa5,0xd2,0xdb,0xc0,0xc9,0xf6,0xff,0xe4,0xed,0x0a,0x03,0x18,0x11,0x2e,0x27,0x3c,0x35,0x42,0x4b,0x50,0x59,0x66,0x6f,0x74,0x7d,0xa1,0xa8,0xb3,0xba,0x85,0x8c,0x97,0x9e,0xe9,0xe0,0xfb,0xf2,0xcd,0xc4,0xdf,0xd6,0x31,0x38,0x23,0x2a,0x15,0x1c,0x07,0x0e,0x79,0x70,0x6b,0x62,0x5d,0x54,0x4f,0x46}; -byte lookup_g11 []={0x00,0x0b,0x16,0x1d,0x2c,0x27,0x3a,0x31,0x58,0x53,0x4e,0x45,0x74,0x7f,0x62,0x69,0xb0,0xbb,0xa6,0xad,0x9c,0x97,0x8a,0x81,0xe8,0xe3,0xfe,0xf5,0xc4,0xcf,0xd2,0xd9,0x7b,0x70,0x6d,0x66,0x57,0x5c,0x41,0x4a,0x23,0x28,0x35,0x3e,0x0f,0x04,0x19,0x12,0xcb,0xc0,0xdd,0xd6,0xe7,0xec,0xf1,0xfa,0x93,0x98,0x85,0x8e,0xbf,0xb4,0xa9,0xa2,0xf6,0xfd,0xe0,0xeb,0xda,0xd1,0xcc,0xc7,0xae,0xa5,0xb8,0xb3,0x82,0x89,0x94,0x9f,0x46,0x4d,0x50,0x5b,0x6a,0x61,0x7c,0x77,0x1e,0x15,0x08,0x03,0x32,0x39,0x24,0x2f,0x8d,0x86,0x9b,0x90,0xa1,0xaa,0xb7,0xbc,0xd5,0xde,0xc3,0xc8,0xf9,0xf2,0xef,0xe4,0x3d,0x36,0x2b,0x20,0x11,0x1a,0x07,0x0c,0x65,0x6e,0x73,0x78,0x49,0x42,0x5f,0x54,0xf7,0xfc,0xe1,0xea,0xdb,0xd0,0xcd,0xc6,0xaf,0xa4,0xb9,0xb2,0x83,0x88,0x95,0x9e,0x47,0x4c,0x51,0x5a,0x6b,0x60,0x7d,0x76,0x1f,0x14,0x09,0x02,0x33,0x38,0x25,0x2e,0x8c,0x87,0x9a,0x91,0xa0,0xab,0xb6,0xbd,0xd4,0xdf,0xc2,0xc9,0xf8,0xf3,0xee,0xe5,0x3c,0x37,0x2a,0x21,0x10,0x1b,0x06,0x0d,0x64,0x6f,0x72,0x79,0x48,0x43,0x5e,0x55,0x01,0x0a,0x17,0x1c,0x2d,0x26,0x3b,0x30,0x59,0x52,0x4f,0x44,0x75,0x7e,0x63,0x68,0xb1,0xba,0xa7,0xac,0x9d,0x96,0x8b,0x80,0xe9,0xe2,0xff,0xf4,0xc5,0xce,0xd3,0xd8,0x7a,0x71,0x6c,0x67,0x56,0x5d,0x40,0x4b,0x22,0x29,0x34,0x3f,0x0e,0x05,0x18,0x13,0xca,0xc1,0xdc,0xd7,0xe6,0xed,0xf0,0xfb,0x92,0x99,0x84,0x8f,0xbe,0xb5,0xa8,0xa3}; -byte lookup_g13 []={0x00,0x0d,0x1a,0x17,0x34,0x39,0x2e,0x23,0x68,0x65,0x72,0x7f,0x5c,0x51,0x46,0x4b,0xd0,0xdd,0xca,0xc7,0xe4,0xe9,0xfe,0xf3,0xb8,0xb5,0xa2,0xaf,0x8c,0x81,0x96,0x9b,0xbb,0xb6,0xa1,0xac,0x8f,0x82,0x95,0x98,0xd3,0xde,0xc9,0xc4,0xe7,0xea,0xfd,0xf0,0x6b,0x66,0x71,0x7c,0x5f,0x52,0x45,0x48,0x03,0x0e,0x19,0x14,0x37,0x3a,0x2d,0x20,0x6d,0x60,0x77,0x7a,0x59,0x54,0x43,0x4e,0x05,0x08,0x1f,0x12,0x31,0x3c,0x2b,0x26,0xbd,0xb0,0xa7,0xaa,0x89,0x84,0x93,0x9e,0xd5,0xd8,0xcf,0xc2,0xe1,0xec,0xfb,0xf6,0xd6,0xdb,0xcc,0xc1,0xe2,0xef,0xf8,0xf5,0xbe,0xb3,0xa4,0xa9,0x8a,0x87,0x90,0x9d,0x06,0x0b,0x1c,0x11,0x32,0x3f,0x28,0x25,0x6e,0x63,0x74,0x79,0x5a,0x57,0x40,0x4d,0xda,0xd7,0xc0,0xcd,0xee,0xe3,0xf4,0xf9,0xb2,0xbf,0xa8,0xa5,0x86,0x8b,0x9c,0x91,0x0a,0x07,0x10,0x1d,0x3e,0x33,0x24,0x29,0x62,0x6f,0x78,0x75,0x56,0x5b,0x4c,0x41,0x61,0x6c,0x7b,0x76,0x55,0x58,0x4f,0x42,0x09,0x04,0x13,0x1e,0x3d,0x30,0x27,0x2a,0xb1,0xbc,0xab,0xa6,0x85,0x88,0x9f,0x92,0xd9,0xd4,0xc3,0xce,0xed,0xe0,0xf7,0xfa,0xb7,0xba,0xad,0xa0,0x83,0x8e,0x99,0x94,0xdf,0xd2,0xc5,0xc8,0xeb,0xe6,0xf1,0xfc,0x67,0x6a,0x7d,0x70,0x53,0x5e,0x49,0x44,0x0f,0x02,0x15,0x18,0x3b,0x36,0x21,0x2c,0x0c,0x01,0x16,0x1b,0x38,0x35,0x22,0x2f,0x64,0x69,0x7e,0x73,0x50,0x5d,0x4a,0x47,0xdc,0xd1,0xc6,0xcb,0xe8,0xe5,0xf2,0xff,0xb4,0xb9,0xae,0xa3,0x80,0x8d,0x9a,0x97}; -byte lookup_g14 []={0x00,0x0e,0x1c,0x12,0x38,0x36,0x24,0x2a,0x70,0x7e,0x6c,0x62,0x48,0x46,0x54,0x5a,0xe0,0xee,0xfc,0xf2,0xd8,0xd6,0xc4,0xca,0x90,0x9e,0x8c,0x82,0xa8,0xa6,0xb4,0xba,0xdb,0xd5,0xc7,0xc9,0xe3,0xed,0xff,0xf1,0xab,0xa5,0xb7,0xb9,0x93,0x9d,0x8f,0x81,0x3b,0x35,0x27,0x29,0x03,0x0d,0x1f,0x11,0x4b,0x45,0x57,0x59,0x73,0x7d,0x6f,0x61,0xad,0xa3,0xb1,0xbf,0x95,0x9b,0x89,0x87,0xdd,0xd3,0xc1,0xcf,0xe5,0xeb,0xf9,0xf7,0x4d,0x43,0x51,0x5f,0x75,0x7b,0x69,0x67,0x3d,0x33,0x21,0x2f,0x05,0x0b,0x19,0x17,0x76,0x78,0x6a,0x64,0x4e,0x40,0x52,0x5c,0x06,0x08,0x1a,0x14,0x3e,0x30,0x22,0x2c,0x96,0x98,0x8a,0x84,0xae,0xa0,0xb2,0xbc,0xe6,0xe8,0xfa,0xf4,0xde,0xd0,0xc2,0xcc,0x41,0x4f,0x5d,0x53,0x79,0x77,0x65,0x6b,0x31,0x3f,0x2d,0x23,0x09,0x07,0x15,0x1b,0xa1,0xaf,0xbd,0xb3,0x99,0x97,0x85,0x8b,0xd1,0xdf,0xcd,0xc3,0xe9,0xe7,0xf5,0xfb,0x9a,0x94,0x86,0x88,0xa2,0xac,0xbe,0xb0,0xea,0xe4,0xf6,0xf8,0xd2,0xdc,0xce,0xc0,0x7a,0x74,0x66,0x68,0x42,0x4c,0x5e,0x50,0x0a,0x04,0x16,0x18,0x32,0x3c,0x2e,0x20,0xec,0xe2,0xf0,0xfe,0xd4,0xda,0xc8,0xc6,0x9c,0x92,0x80,0x8e,0xa4,0xaa,0xb8,0xb6,0x0c,0x02,0x10,0x1e,0x34,0x3a,0x28,0x26,0x7c,0x72,0x60,0x6e,0x44,0x4a,0x58,0x56,0x37,0x39,0x2b,0x25,0x0f,0x01,0x13,0x1d,0x47,0x49,0x5b,0x55,0x7f,0x71,0x63,0x6d,0xd7,0xd9,0xcb,0xc5,0xef,0xe1,0xf3,0xfd,0xa7,0xa9,0xbb,0xb5,0x9f,0x91,0x83,0x8d}; - -// Xor's all elements in a n byte array a by b -void xor_(byte *a, byte *b, int n) { - int i; - for (i=0;i ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Amaury Pouly - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "crypto.h" - -/* Table extracted from firmware, don't know if this is regular CRC32 */ - -static uint32_t crc_table[256] = { - 0x0, 0x4C11DB7, 0x9823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, - 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, - 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, - 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, - 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, - 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, 0x8B27C03C, - 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0x0BE2B5B58, 0x0BAEA46EF, 0x0B7A96036, - 0x0B3687D81, 0x0AD2F2D84, 0x0A9EE3033, 0x0A4AD16EA, 0x0A06C0B5D, 0x0D4326D90, - 0x0D0F37027, 0x0DDB056FE, 0x0D9714B49, 0x0C7361B4C, 0x0C3F706FB, 0x0CEB42022, - 0x0CA753D95, 0x0F23A8028, 0x0F6FB9D9F, 0x0FBB8BB46, 0x0FF79A6F1, 0x0E13EF6F4, - 0x0E5FFEB43, 0x0E8BCCD9A, 0x0EC7DD02D, 0x34867077, 0x30476DC0, 0x3D044B19, - 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072, 0x128E9DCF, - 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x18AEB13, 0x54BF6A4, 0x808D07D, - 0x0CC9CDCA, 0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, - 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, - 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA, 0x0ACA5C697, - 0x0A864DB20, 0x0A527FDF9, 0x0A1E6E04E, 0x0BFA1B04B, 0x0BB60ADFC, 0x0B6238B25, - 0x0B2E29692, 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, 0x99A95DF3, - 0x9D684044, 0x902B669D, 0x94EA7B2A, 0x0E0B41DE7, 0x0E4750050, 0x0E9362689, - 0x0EDF73B3E, 0x0F3B06B3B, 0x0F771768C, 0x0FA325055, 0x0FEF34DE2, 0x0C6BCF05F, - 0x0C27DEDE8, 0x0CF3ECB31, 0x0CBFFD686, 0x0D5B88683, 0x0D1799B34, 0x0DC3ABDED, - 0x0D8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, 0x7A089632, - 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, 0x4F040D56, 0x4BC510E1, 0x46863638, - 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, - 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, - 0x3B5A6B9B, 0x315D626, 0x7D4CB91, 0x0A97ED48, 0x0E56F0FF, 0x1011A0FA, - 0x14D0BD4D, 0x19939B94, 0x1D528623, 0x0F12F560E, 0x0F5EE4BB9, 0x0F8AD6D60, - 0x0FC6C70D7, 0x0E22B20D2, 0x0E6EA3D65, 0x0EBA91BBC, 0x0EF68060B, 0x0D727BBB6, - 0x0D3E6A601, 0x0DEA580D8, 0x0DA649D6F, 0x0C423CD6A, 0x0C0E2D0DD, 0x0CDA1F604, - 0x0C960EBB3, 0x0BD3E8D7E, 0x0B9FF90C9, 0x0B4BCB610, 0x0B07DABA7, 0x0AE3AFBA2, - 0x0AAFBE615, 0x0A7B8C0CC, 0x0A379DD7B, 0x9B3660C6, 0x9FF77D71, 0x92B45BA8, - 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3, 0x5D8A9099, - 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, - 0x43CDC09C, 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, - 0x6C47164A, 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087, - 0x1CD86D30, 0x29F3D35, 0x65E2082, 0x0B1D065B, 0x0FDC1BEC, 0x3793A651, - 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, - 0x29D4F654, 0x0C5A92679, 0x0C1683BCE, 0x0CC2B1D17, 0x0C8EA00A0, 0x0D6AD50A5, - 0x0D26C4D12, 0x0DF2F6BCB, 0x0DBEE767C, 0x0E3A1CBC1, 0x0E760D676, 0x0EA23F0AF, - 0x0EEE2ED18, 0x0F0A5BD1D, 0x0F464A0AA, 0x0F9278673, 0x0FDE69BC4, 0x89B8FD09, - 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, - 0x97FFAD0C, 0x0AFB010B1, 0x0AB710D06, 0x0A6322BDF, 0x0A2F33668, 0x0BCB4666D, - 0x0B8757BDA, 0x0B5365D03, 0x0B1F740B4 -}; - -uint32_t crc(byte *data, int size) -{ - uint32_t c = 0xffffffff; - /* normal CRC */ - for(int i = 0; i < size; i++) - c = crc_table[data[i] ^ (c >> 24)] ^ (c << 8); - return c; -} diff --git a/utils/sbinfo/crypto.h b/utils/sbinfo/crypto.h deleted file mode 100644 index e36900df47..0000000000 --- a/utils/sbinfo/crypto.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Amaury Pouly - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include -#include -#include - -typedef uint8_t byte; - -/* aes128.c */ -void xor_(byte *a, byte *b, int n); -void EncryptAES(byte *msg, byte *key, byte *c); -void DecryptAES(byte *c, byte *key, byte *m); -void Pretty(byte* b,int len,const char* label); -void cbc_mac( - byte *in_data, /* Input data */ - byte *out_data, /* Output data (or NULL) */ - int nr_blocks, /* Number of blocks to encrypt/decrypt (one block=16 bytes) */ - byte key[16], /* Key */ - byte iv[16], /* Initialisation Vector */ - byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */ - int encrypt /* 1 to encrypt, 0 to decrypt */ - ); - -/* crc.c */ -uint32_t crc(byte *data, int size); - -/* sha1.c */ -struct sha_1_params_t -{ - uint32_t hash[5]; - uint64_t buffer_nr_bits; - uint32_t w[80]; -}; - -void sha_1_init(struct sha_1_params_t *params); -void sha_1_block(struct sha_1_params_t *params, uint32_t cur_hash[5], byte *data); -void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size); -void sha_1_finish(struct sha_1_params_t *params); -void sha_1_output(struct sha_1_params_t *params, byte *out); diff --git a/utils/sbinfo/elf.c b/utils/sbinfo/elf.c deleted file mode 100644 index f146bcc111..0000000000 --- a/utils/sbinfo/elf.c +++ /dev/null @@ -1,237 +0,0 @@ -#include "elf.h" - -void elf_init(struct elf_params_t *params) -{ - params->has_start_addr = false; - params->start_addr = 0; - params->first_section = NULL; - params->last_section = NULL; -} - -extern void *xmalloc(size_t s); - -static struct elf_section_t *elf_add_section(struct elf_params_t *params) -{ - struct elf_section_t *sec = xmalloc(sizeof(struct elf_section_t)); - if(params->first_section == NULL) - params->first_section = params->last_section = sec; - else - { - params->last_section->next = sec; - params->last_section = sec; - } - sec->next = NULL; - - return sec; -} - -void elf_add_load_section(struct elf_params_t *params, - uint32_t load_addr, uint32_t size, const void *section) -{ - struct elf_section_t *sec = elf_add_section(params); - - sec->type = EST_LOAD; - sec->addr = load_addr; - sec->size = size; - sec->section = xmalloc(size); - memcpy(sec->section, section, size); -} - -void elf_add_fill_section(struct elf_params_t *params, - uint32_t fill_addr, uint32_t size, uint32_t pattern) -{ - if(pattern != 0x00) - { - printf("oops, non-zero filling, ignore fill section\n"); - return; - } - - struct elf_section_t *sec = elf_add_section(params); - - sec->type = EST_FILL; - sec->addr = fill_addr; - sec->size = size; - sec->pattern = pattern; -} - -void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user) -{ - Elf32_Ehdr ehdr; - uint32_t phnum = 0; - struct elf_section_t *sec = params->first_section; - uint32_t offset = 0; - Elf32_Phdr phdr; - Elf32_Shdr shdr; - memset(&ehdr, 0, EI_NIDENT); - - uint32_t bss_strtbl = 0; - uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1; - uint32_t strtbl_size = text_strtbl + strlen(".text") + 1; - - while(sec) - { - if(sec->type == EST_LOAD) - { - sec->offset = offset; - offset += sec->size; - } - - phnum++; - sec = sec->next; - } - - uint32_t strtbl_offset = offset; - - ehdr.e_ident[EI_MAG0] = ELFMAG0; - ehdr.e_ident[EI_MAG1] = ELFMAG1; - ehdr.e_ident[EI_MAG2] = ELFMAG2; - ehdr.e_ident[EI_MAG3] = ELFMAG3; - ehdr.e_ident[EI_CLASS] = ELFCLASS32; - ehdr.e_ident[EI_DATA] = ELFDATA2LSB; - ehdr.e_ident[EI_VERSION] = EV_CURRENT; - ehdr.e_ident[EI_OSABI] = ELFOSABI_NONE; - ehdr.e_ident[EI_ABIVERSION] = 0; - ehdr.e_type = ET_EXEC; - ehdr.e_machine = EM_ARM; - ehdr.e_version = EV_CURRENT; - ehdr.e_entry = params->start_addr; - ehdr.e_flags = 0; - if(params->has_start_addr) - ehdr.e_flags |= EF_ARM_HASENTRY; - ehdr.e_ehsize = sizeof ehdr; - ehdr.e_phentsize = sizeof phdr; - ehdr.e_phnum = phnum; - ehdr.e_shentsize = sizeof shdr; - ehdr.e_shnum = phnum + 2; /* one for section 0 and one for string table */ - ehdr.e_shstrndx = ehdr.e_shnum - 1; - ehdr.e_phoff = ehdr.e_ehsize; - ehdr.e_shoff = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize; - - write(user, 0, &ehdr, sizeof ehdr); - - uint32_t data_offset = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize + - ehdr.e_shnum * ehdr.e_shentsize; - - sec = params->first_section; - offset = ehdr.e_phoff; - while(sec) - { - sec->offset += data_offset; - - phdr.p_type = PT_LOAD; - if(sec->type == EST_LOAD) - phdr.p_offset = sec->offset; - else - phdr.p_offset = 0; - phdr.p_paddr = sec->addr; - phdr.p_vaddr = phdr.p_paddr; /* assume identity map ? */ - phdr.p_memsz = sec->size; - if(sec->type == EST_LOAD) - phdr.p_filesz = phdr.p_memsz; - else - phdr.p_filesz = 0; - phdr.p_flags = PF_X | PF_W | PF_R; - phdr.p_align = 0; - - write(user, offset, &phdr, sizeof phdr); - - offset += sizeof(Elf32_Phdr); - sec = sec->next; - } - - sec = params->first_section; - offset = ehdr.e_shoff; - - { - shdr.sh_name = 0; - shdr.sh_type = SHT_NULL; - shdr.sh_flags = 0; - shdr.sh_addr = 0; - shdr.sh_offset = 0; - shdr.sh_size = 0; - shdr.sh_link = SHN_UNDEF; - shdr.sh_info = 0; - shdr.sh_addralign = 0; - shdr.sh_entsize = 0; - - write(user, offset, &shdr, sizeof shdr); - - offset += sizeof(Elf32_Shdr); - } - - while(sec) - { - shdr.sh_name = text_strtbl; - if(sec->type == EST_LOAD) - shdr.sh_type = SHT_PROGBITS; - else - shdr.sh_type = SHT_NOBITS; - shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; - shdr.sh_addr = sec->addr; - shdr.sh_offset = sec->offset; - shdr.sh_size = sec->size; - shdr.sh_link = SHN_UNDEF; - shdr.sh_info = 0; - shdr.sh_addralign = 1; - shdr.sh_entsize = 0; - - write(user, offset, &shdr, sizeof shdr); - - offset += sizeof(Elf32_Shdr); - sec = sec->next; - } - - { - shdr.sh_name = bss_strtbl; - shdr.sh_type = SHT_STRTAB; - shdr.sh_flags = 0; - shdr.sh_addr = 0; - shdr.sh_offset = strtbl_offset + data_offset; - shdr.sh_size = strtbl_size; - shdr.sh_link = SHN_UNDEF; - shdr.sh_info = 0; - shdr.sh_addralign = 1; - shdr.sh_entsize = 0; - - write(user, offset, &shdr, sizeof shdr); - - offset += sizeof(Elf32_Shdr); - } - - sec = params->first_section; - while(sec) - { - if(sec->type == EST_LOAD) - write(user, sec->offset, sec->section, sec->size); - sec = sec->next; - } - - write(user, strtbl_offset + data_offset, ".bss\0.text\0", strtbl_size); -} - -bool elf_is_empty(struct elf_params_t *params) -{ - return params->first_section == NULL; -} - -void elf_set_start_addr(struct elf_params_t *params, uint32_t addr) -{ - params->has_start_addr = true; - params->start_addr = addr; -} - -void elf_release(struct elf_params_t *params) -{ - struct elf_section_t *sec, *next_sec; - sec = params->first_section; - while(sec) - { - next_sec = sec->next; - if(sec->type == EST_LOAD) - free(sec->section); - free(sec); - sec = next_sec; - } - params->first_section = NULL; - params->last_section = NULL; -} diff --git a/utils/sbinfo/elf.h b/utils/sbinfo/elf.h deleted file mode 100644 index d2bf210c5c..0000000000 --- a/utils/sbinfo/elf.h +++ /dev/null @@ -1,179 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/** - * Definitions - * taken from elf.h linux header - * based on ELF specification - * based on ARM ELF specification - */ -typedef uint16_t Elf32_Half; - -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint32_t Elf32_Addr; -typedef uint32_t Elf32_Off; -typedef uint16_t Elf32_Section; - -#define EI_NIDENT 16 - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ -}Elf32_Ehdr; - -#define EI_MAG0 0 /* File identification byte 0 index */ -#define ELFMAG0 0x7f /* Magic number byte 0 */ - -#define EI_MAG1 1 /* File identification byte 1 index */ -#define ELFMAG1 'E' /* Magic number byte 1 */ - -#define EI_MAG2 2 /* File identification byte 2 index */ -#define ELFMAG2 'L' /* Magic number byte 2 */ - -#define EI_MAG3 3 /* File identification byte 3 index */ -#define ELFMAG3 'F' /* Magic number byte 3 */ - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASS32 1 /* 32-bit objects */ - -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ - -#define EI_VERSION 6 /* File version byte index, Value must be EV_CURRENT */ - -#define EI_OSABI 7 /* OS ABI identification */ -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -#define ELFOSABI_ARM 97 /* ARM */ - -#define EI_ABIVERSION 8 /* ABI version */ - -#define EI_PAD 9 /* Byte index of padding bytes */ - -#define ET_EXEC 2 /* Executable file */ - -#define EM_ARM 40 /* ARM */ - -#define EV_CURRENT 1 /* Current version */ - -#define EF_ARM_HASENTRY 0x00000002 - -#define SHN_UNDEF 0 /* Undefined section */ - -typedef struct -{ - Elf32_Word sh_name; /* Section name (string tbl index) */ - Elf32_Word sh_type; /* Section type */ - Elf32_Word sh_flags; /* Section flags */ - Elf32_Addr sh_addr; /* Section virtual addr at execution */ - Elf32_Off sh_offset; /* Section file offset */ - Elf32_Word sh_size; /* Section size in bytes */ - Elf32_Word sh_link; /* Link to another section */ - Elf32_Word sh_info; /* Additional section information */ - Elf32_Word sh_addralign; /* Section alignment */ - Elf32_Word sh_entsize; /* Entry size if section holds table */ -}Elf32_Shdr; - -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program data */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Dynamic linking information */ -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_INIT_ARRAY 14 /* Array of constructors */ -#define SHT_FINI_ARRAY 15 /* Array of destructors */ -#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -#define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -#define SHT_NUM 19 /* Number of defined types. */ - -#define SHF_WRITE (1 << 0) /* Writable */ -#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -#define SHF_EXECINSTR (1 << 2) /* Executable */ -#define SHF_MERGE (1 << 4) /* Might be merged */ -#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ - -typedef struct -{ - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Word p_filesz; /* Segment size in file */ - Elf32_Word p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Word p_align; /* Segment alignment */ -}Elf32_Phdr; - -#define PT_LOAD 1 /* Loadable program segment */ - -#define PF_X (1 << 0) /* Segment is executable */ -#define PF_W (1 << 1) /* Segment is writable */ -#define PF_R (1 << 2) /* Segment is readable */ - -/** - * API - */ -enum elf_section_type_t -{ - EST_LOAD, - EST_FILL -}; - -struct elf_section_t -{ - uint32_t addr; - uint32_t size; - enum elf_section_type_t type; - /* */ - void *section; - uint32_t pattern; - /* */ - struct elf_section_t *next; - /* Internal to elf_output */ - uint32_t offset; -}; - -struct elf_params_t -{ - bool has_start_addr; - uint32_t start_addr; - struct elf_section_t *first_section; - struct elf_section_t *last_section; -}; - -typedef void (*elf_write_fn_t)(void *user, uint32_t addr, const void *buf, size_t count); - -void elf_init(struct elf_params_t *params); -void elf_add_load_section(struct elf_params_t *params, - uint32_t load_addr, uint32_t size, const void *section); -void elf_add_fill_section(struct elf_params_t *params, - uint32_t fill_addr, uint32_t size, uint32_t pattern); -void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user); -bool elf_is_empty(struct elf_params_t *params); -void elf_set_start_addr(struct elf_params_t *params, uint32_t addr); -void elf_release(struct elf_params_t *params); diff --git a/utils/sbinfo/fuze+_key_file.txt b/utils/sbinfo/fuze+_key_file.txt deleted file mode 100644 index a965e715f7..0000000000 --- a/utils/sbinfo/fuze+_key_file.txt +++ /dev/null @@ -1 +0,0 @@ -00000000000000000000000000000000 diff --git a/utils/sbinfo/sb.h b/utils/sbinfo/sb.h deleted file mode 100644 index 29b7d7d894..0000000000 --- a/utils/sbinfo/sb.h +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2011 Amaury Pouly - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#define _ISOC99_SOURCE /* snprintf() */ -#include -#include - -#define BLOCK_SIZE 16 - -struct sb_version_t -{ - uint16_t major; - uint16_t pad0; - uint16_t minor; - uint16_t pad1; - uint16_t revision; - uint16_t pad2; -}; - -struct sb_header_t -{ - uint8_t sha1_header[20]; /* SHA-1 of the rest of the header */ - uint8_t signature[4]; /* Signature "STMP" */ - uint8_t major_ver; /* Should be 1 */ - uint8_t minor_ver; /* Should be 1 */ - uint16_t flags; - uint32_t image_size; /* In blocks (=16bytes) */ - uint32_t first_boot_tag_off; /* Offset in blocks */ - uint32_t first_boot_sec_id; /* First bootable section ID */ - uint16_t nr_keys; /* Number of encryption keys */ - uint16_t key_dict_off; /* Offset to key dictionary (in blocks) */ - uint16_t header_size; /* In blocks */ - uint16_t nr_sections; /* Number of sections */ - uint16_t sec_hdr_size; /* Section header size (in blocks) */ - uint8_t rand_pad0[6]; /* Random padding */ - uint64_t timestamp; /* In microseconds since 2000/1/1 00:00:00 */ - struct sb_version_t product_ver; - struct sb_version_t component_ver; - uint16_t drive_tag; /* Unknown meaning */ - uint8_t rand_pad1[6]; /* Random padding */ -} __attribute__((packed)); - -struct sb_section_header_t -{ - uint32_t identifier; - uint32_t offset; /* In blocks */ - uint32_t size; /* In blocks */ - uint32_t flags; -} __attribute__((packed)); - -struct sb_key_dictionary_entry_t -{ - uint8_t hdr_cbc_mac[16]; /* CBC-MAC of the header */ - uint8_t key[16]; /* Actual AES Key (encrypted by the global key) */ -} __attribute__((packed)); - -#define IMAGE_MAJOR_VERSION 1 -#define IMAGE_MINOR_VERSION 1 - -#define SECTION_BOOTABLE (1 << 0) -#define SECTION_CLEARTEXT (1 << 1) - -#define SB_INST_NOP 0x0 -#define SB_INST_TAG 0x1 -#define SB_INST_LOAD 0x2 -#define SB_INST_FILL 0x3 -#define SB_INST_JUMP 0x4 -#define SB_INST_CALL 0x5 -#define SB_INST_MODE 0x6 - -struct sb_instruction_header_t -{ - uint8_t checksum; - uint8_t opcode; - uint16_t zero_except_for_tag; -} __attribute__((packed)); - -struct sb_instruction_load_t -{ - struct sb_instruction_header_t hdr; - uint32_t addr; - uint32_t len; - uint32_t crc; -} __attribute__((packed)); - -struct sb_instruction_fill_t -{ - struct sb_instruction_header_t hdr; - uint32_t addr; - uint32_t len; - uint32_t pattern; -} __attribute__((packed)); - -struct sb_instruction_call_t -{ - struct sb_instruction_header_t hdr; - uint32_t addr; - uint32_t zero; - uint32_t arg; -} __attribute__((packed)); diff --git a/utils/sbinfo/sbinfo.c b/utils/sbinfo/sbinfo.c deleted file mode 100644 index 632c4b3eb9..0000000000 --- a/utils/sbinfo/sbinfo.c +++ /dev/null @@ -1,596 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Bertrik Sikken - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -/* - * .sb file parser and chunk extractor - * - * Based on amsinfo, which is - * Copyright © 2008 Rafaël Carré - */ - -#define _ISOC99_SOURCE /* snprintf() */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "crypto.h" -#include "elf.h" -#include "sb.h" - -#if 1 /* ANSI colors */ - -# define color(a) printf("%s",a) -char OFF[] = { 0x1b, 0x5b, 0x31, 0x3b, '0', '0', 0x6d, '\0' }; - -char GREY[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '0', 0x6d, '\0' }; -char RED[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '1', 0x6d, '\0' }; -char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' }; -char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' }; -char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' }; - -#else - /* disable colors */ -# define color(a) -#endif - -#define bug(...) do { fprintf(stderr,"ERROR: "__VA_ARGS__); exit(1); } while(0) -#define bugp(a) do { perror("ERROR: "a); exit(1); } while(0) - -/* all blocks are sized as a multiple of 0x1ff */ -#define PAD_TO_BOUNDARY(x) (((x) + 0x1ff) & ~0x1ff) - -/* If you find a firmware that breaks the known format ^^ */ -#define assert(a) do { if(!(a)) { fprintf(stderr,"Assertion \"%s\" failed in %s() line %d!\n\nPlease send us your firmware!\n",#a,__func__,__LINE__); exit(1); } } while(0) - -/* globals */ - -size_t g_sz; /* file size */ -uint8_t *g_buf; /* file content */ -#define PREFIX_SIZE 128 -char out_prefix[PREFIX_SIZE]; -const char *key_file; - -void *xmalloc(size_t s) /* malloc helper, used in elf.c */ -{ - void * r = malloc(s); - if(!r) bugp("malloc"); - return r; -} - -static void print_hex(byte *data, int len, bool newline) -{ - for(int i = 0; i < len; i++) - printf("%02X ", data[i]); - if(newline) - printf("\n"); -} - -int convxdigit(char digit, byte *val) -{ - if(digit >= '0' && digit <= '9') - { - *val = digit - '0'; - return 0; - } - else if(digit >= 'A' && digit <= 'F') - { - *val = digit - 'A' + 10; - return 0; - } - else if(digit >= 'a' && digit <= 'f') - { - *val = digit - 'a' + 10; - return 0; - } - else - return 1; -} - -typedef byte (*key_array_t)[16]; - -static key_array_t read_keys(int num_keys) -{ - int size; - struct stat st; - int fd = open(key_file,O_RDONLY); - if(fd == -1) - bugp("opening key file failed"); - if(fstat(fd,&st) == -1) - bugp("key file stat() failed"); - size = st.st_size; - char *buf = xmalloc(size); - if(read(fd, buf, size) != (ssize_t)size) - bugp("reading key file"); - close(fd); - - key_array_t keys = xmalloc(sizeof(byte[16]) * num_keys); - int pos = 0; - for(int i = 0; i < num_keys; i++) - { - /* skip ws */ - while(pos < size && isspace(buf[pos])) - pos++; - /* enough space ? */ - if((pos + 32) > size) - bugp("invalid key file (not enough keys)"); - for(int j = 0; j < 16; j++) - { - byte a, b; - if(convxdigit(buf[pos + 2 * j], &a) || convxdigit(buf[pos + 2 * j + 1], &b)) - bugp(" invalid key, it should be a 128-bit key written in hexadecimal\n"); - keys[i][j] = (a << 4) | b; - } - pos += 32; - } - free(buf); - - return keys; -} - -#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round)) - -static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr) -{ - uint8_t sum = 90; - byte *ptr = (byte *)hdr; - for(int i = 1; i < 16; i++) - sum += ptr[i]; - return sum; -} - -static void elf_write(void *user, uint32_t addr, const void *buf, size_t count) -{ - FILE *f = user; - fseek(f, addr, SEEK_SET); - fwrite(buf, count, 1, f); -} - -static void extract_elf_section(struct elf_params_t *elf, int count, const char *prefix, - const char *indent) -{ - char *filename = xmalloc(strlen(prefix) + 32); - sprintf(filename, "%s.%d.elf", prefix, count); - printf("%swrite %s\n", indent, filename); - - FILE *fd = fopen(filename, "wb"); - free(filename); - - if(fd == NULL) - return ; - elf_output(elf, elf_write, fd); - fclose(fd); -} - -static void extract_section(int data_sec, char name[5], byte *buf, int size, const char *indent) -{ - char filename[PREFIX_SIZE + 32]; - snprintf(filename, sizeof filename, "%s%s.bin", out_prefix, name); - FILE *fd = fopen(filename, "wb"); - if (fd != NULL) { - fwrite(buf, size, 1, fd); - fclose(fd); - } - if(data_sec) - return; - - snprintf(filename, sizeof filename, "%s%s", out_prefix, name); - - /* elf construction */ - struct elf_params_t elf; - elf_init(&elf); - int elf_count = 0; - /* Pretty print the content */ - int pos = 0; - while(pos < size) - { - struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)&buf[pos]; - printf("%s", indent); - uint8_t checksum = instruction_checksum(hdr); - if(checksum != hdr->checksum) - { - color(GREY); - printf("[Bad checksum]"); - } - - if(hdr->opcode == SB_INST_LOAD) - { - struct sb_instruction_load_t *load = (struct sb_instruction_load_t *)&buf[pos]; - color(RED); - printf("LOAD"); - color(OFF);printf(" | "); - color(BLUE); - printf("addr=0x%08x", load->addr); - color(OFF);printf(" | "); - color(GREEN); - printf("len=0x%08x", load->len); - color(OFF);printf(" | "); - color(YELLOW); - printf("crc=0x%08x", load->crc); - /* data is padded to 16-byte boundary with random data and crc'ed with it */ - uint32_t computed_crc = crc(&buf[pos + sizeof(struct sb_instruction_load_t)], - ROUND_UP(load->len, 16)); - color(RED); - if(load->crc == computed_crc) - printf(" Ok\n"); - else - printf(" Failed (crc=0x%08x)\n", computed_crc); - - /* elf construction */ - elf_add_load_section(&elf, load->addr, load->len, - &buf[pos + sizeof(struct sb_instruction_load_t)]); - - pos += load->len + sizeof(struct sb_instruction_load_t); - // unsure about rounding - pos = ROUND_UP(pos, 16); - } - else if(hdr->opcode == SB_INST_FILL) - { - struct sb_instruction_fill_t *fill = (struct sb_instruction_fill_t *)&buf[pos]; - color(RED); - printf("FILL"); - color(OFF);printf(" | "); - color(BLUE); - printf("addr=0x%08x", fill->addr); - color(OFF);printf(" | "); - color(GREEN); - printf("len=0x%08x", fill->len); - color(OFF);printf(" | "); - color(YELLOW); - printf("pattern=0x%08x\n", fill->pattern); - color(OFF); - - /* elf construction */ - elf_add_fill_section(&elf, fill->addr, fill->len, fill->pattern); - - pos += sizeof(struct sb_instruction_fill_t); - // fixme: useless as pos is a multiple of 16 and fill struct is 4-bytes wide ? - pos = ROUND_UP(pos, 16); - } - else if(hdr->opcode == SB_INST_CALL || - hdr->opcode == SB_INST_JUMP) - { - int is_call = (hdr->opcode == SB_INST_CALL); - struct sb_instruction_call_t *call = (struct sb_instruction_call_t *)&buf[pos]; - color(RED); - if(is_call) - printf("CALL"); - else - printf("JUMP"); - color(OFF);printf(" | "); - color(BLUE); - printf("addr=0x%08x", call->addr); - color(OFF);printf(" | "); - color(GREEN); - printf("arg=0x%08x\n", call->arg); - color(OFF); - - /* elf construction */ - elf_set_start_addr(&elf, call->addr); - extract_elf_section(&elf, elf_count++, filename, indent); - elf_release(&elf); - elf_init(&elf); - - pos += sizeof(struct sb_instruction_call_t); - // fixme: useless as pos is a multiple of 16 and call struct is 4-bytes wide ? - pos = ROUND_UP(pos, 16); - } - else - { - color(RED); - printf("Unknown instruction %d at address 0x%08lx\n", hdr->opcode, (unsigned long)pos); - break; - } - } - - if(!elf_is_empty(&elf)) - extract_elf_section(&elf, elf_count++, filename, indent); - elf_release(&elf); -} - -static void extract(unsigned long filesize) -{ - struct sha_1_params_t sha_1_params; - /* Basic header info */ - struct sb_header_t *sb_header = (struct sb_header_t *)g_buf; - - if(memcmp(sb_header->signature, "STMP", 4) != 0) - bugp("Bad signature"); - if(sb_header->image_size * BLOCK_SIZE != filesize) - bugp("File size mismatch"); - if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t)) - bugp("Bad header size"); - if(sb_header->major_ver != IMAGE_MAJOR_VERSION || - sb_header->minor_ver != IMAGE_MINOR_VERSION) - bugp("Bad file format version"); - if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t)) - bugp("Bad section header size"); - - color(BLUE); - printf("Basic info:\n"); - color(GREEN); - printf(" Header SHA-1: "); - byte *hdr_sha1 = sb_header->sha1_header; - color(YELLOW); - print_hex(hdr_sha1, 20, false); - /* Check SHA1 sum */ - byte computed_sha1[20]; - sha_1_init(&sha_1_params); - sha_1_update(&sha_1_params, &sb_header->signature[0], - sizeof(struct sb_header_t) - sizeof(sb_header->sha1_header)); - sha_1_finish(&sha_1_params); - sha_1_output(&sha_1_params, computed_sha1); - color(RED); - if(memcmp(hdr_sha1, computed_sha1, 20) == 0) - printf(" Ok\n"); - else - printf(" Failed\n"); - color(GREEN); - printf(" Flags: "); - color(YELLOW); - printf("%x\n", sb_header->flags); - color(GREEN); - printf(" Total file size : "); - color(YELLOW); - printf("%ld\n", filesize); - - /* Sizes and offsets */ - color(BLUE); - printf("Sizes and offsets:\n"); - color(GREEN); - printf(" # of encryption keys = "); - color(YELLOW); - printf("%d\n", sb_header->nr_keys); - color(GREEN); - printf(" # of sections = "); - color(YELLOW); - printf("%d\n", sb_header->nr_sections); - - /* Versions */ - color(BLUE); - printf("Versions\n"); - color(GREEN); - - printf(" Random 1: "); - color(YELLOW); - print_hex(sb_header->rand_pad0, sizeof(sb_header->rand_pad0), true); - color(GREEN); - printf(" Random 2: "); - color(YELLOW); - print_hex(sb_header->rand_pad1, sizeof(sb_header->rand_pad1), true); - - uint64_t micros = sb_header->timestamp; - time_t seconds = (micros / (uint64_t)1000000L); - struct tm tm_base = {0, 0, 0, 1, 0, 100, 0, 0, 1, 0, NULL}; /* 2000/1/1 0:00:00 */ - seconds += mktime(&tm_base); - struct tm *time = gmtime(&seconds); - color(GREEN); - printf(" Creation date/time = "); - color(YELLOW); - printf("%s", asctime(time)); - - color(GREEN); - printf(" Product version = "); - color(YELLOW); - printf("%X.%X.%X\n", sb_header->product_ver.major, - sb_header->product_ver.minor, sb_header->product_ver.revision); - color(GREEN); - printf(" Component version = "); - color(YELLOW); - printf("%X.%X.%X\n", sb_header->component_ver.major, - sb_header->component_ver.minor, sb_header->component_ver.revision); - - /* encryption cbc-mac */ - key_array_t keys = NULL; /* array of 16-bytes keys */ - byte real_key[16]; - if(sb_header->nr_keys > 0) - { - keys = read_keys(sb_header->nr_keys); - color(BLUE); - printf("Encryption data\n"); - for(int i = 0; i < sb_header->nr_keys; i++) - { - color(RED); - printf(" Key %d: ", i); - print_hex(keys[i], 16, true); - color(GREEN); - printf(" CBC-MAC of headers: "); - - uint32_t ofs = sizeof(struct sb_header_t) - + sizeof(struct sb_section_header_t) * sb_header->nr_sections - + sizeof(struct sb_key_dictionary_entry_t) * i; - struct sb_key_dictionary_entry_t *dict_entry = - (struct sb_key_dictionary_entry_t *)&g_buf[ofs]; - /* cbc mac */ - color(YELLOW); - print_hex(dict_entry->hdr_cbc_mac, 16, false); - /* check it */ - byte computed_cbc_mac[16]; - byte zero[16]; - memset(zero, 0, 16); - cbc_mac(g_buf, NULL, sb_header->header_size + sb_header->nr_sections, - keys[i], zero, &computed_cbc_mac, 1); - color(RED); - if(memcmp(dict_entry->hdr_cbc_mac, computed_cbc_mac, 16) == 0) - printf(" Ok\n"); - else - printf(" Failed\n"); - color(GREEN); - - printf(" Encrypted key : "); - color(YELLOW); - print_hex(dict_entry->key, 16, true); - color(GREEN); - /* decrypt */ - byte decrypted_key[16]; - byte iv[16]; - memcpy(iv, g_buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ - cbc_mac(dict_entry->key, decrypted_key, 1, keys[i], iv, NULL, 0); - printf(" Decrypted key : "); - color(YELLOW); - print_hex(decrypted_key, 16, false); - /* cross-check or copy */ - if(i == 0) - memcpy(real_key, decrypted_key, 16); - else if(memcmp(real_key, decrypted_key, 16) == 0) - { - color(RED); - printf(" Cross-Check Ok"); - } - else - { - color(RED); - printf(" Cross-Check Failed"); - } - printf("\n"); - } - } - - /* sections */ - color(BLUE); - printf("Sections\n"); - - for(int i = 0; i < sb_header->nr_sections; i++) - { - uint32_t ofs = sb_header->header_size * BLOCK_SIZE + i * sizeof(struct sb_section_header_t); - struct sb_section_header_t *sec_hdr = (struct sb_section_header_t *)&g_buf[ofs]; - - char name[5]; - name[0] = (sec_hdr->identifier >> 24) & 0xff; - name[1] = (sec_hdr->identifier >> 16) & 0xff; - name[2] = (sec_hdr->identifier >> 8) & 0xff; - name[3] = sec_hdr->identifier & 0xff; - for(int i = 0; i < 4; i++) - if(!isprint(name[i])) - name[i] = '_'; - name[4] = 0; - int pos = sec_hdr->offset * BLOCK_SIZE; - int size = sec_hdr->size * BLOCK_SIZE; - int data_sec = !(sec_hdr->flags & SECTION_BOOTABLE); - int encrypted = !(sec_hdr->flags & SECTION_CLEARTEXT); - - color(GREEN); - printf(" Chunk "); - color(YELLOW); - printf("'%s'\n", name); - color(GREEN); - printf(" pos = "); - color(YELLOW); - printf("%8x - %8x\n", pos, pos+size); - color(GREEN); - printf(" len = "); - color(YELLOW); - printf("%8x\n", size); - color(GREEN); - printf(" flags = "); - color(YELLOW); - printf("%8x", sec_hdr->flags); - color(RED); - if(data_sec) - printf(" Data Section"); - else - printf(" Boot Section"); - if(encrypted) - printf(" (Encrypted)"); - printf("\n"); - - /* save it */ - byte *sec = xmalloc(size); - if(encrypted) - cbc_mac(g_buf + pos, sec, size / BLOCK_SIZE, real_key, g_buf, NULL, 0); - else - memcpy(sec, g_buf + pos, size); - - extract_section(data_sec, name, sec, size, " "); - free(sec); - } - - /* final signature */ - color(BLUE); - printf("Final signature:\n"); - color(GREEN); - printf(" Encrypted signature:\n"); - color(YELLOW); - byte *encrypted_block = &g_buf[filesize - 32]; - printf(" "); - print_hex(encrypted_block, 16, true); - printf(" "); - print_hex(encrypted_block + 16, 16, true); - /* decrypt it */ - byte decrypted_block[32]; - cbc_mac(encrypted_block, decrypted_block, 2, real_key, g_buf, NULL, 0); - color(GREEN); - printf(" Decrypted SHA-1:\n "); - color(YELLOW); - print_hex(decrypted_block, 20, false); - /* check it */ - sha_1_init(&sha_1_params); - sha_1_update(&sha_1_params, g_buf, filesize - 32); - sha_1_finish(&sha_1_params); - sha_1_output(&sha_1_params, computed_sha1); - color(RED); - if(memcmp(decrypted_block, computed_sha1, 20) == 0) - printf(" Ok\n"); - else - printf(" Failed\n"); -} - -int main(int argc, const char **argv) -{ - int fd; - struct stat st; - if(argc != 3 && argc != 4) - bug("Usage: %s []\n",*argv); - - if(argc == 4) - snprintf(out_prefix, PREFIX_SIZE, "%s", argv[3]); - else - strcpy(out_prefix, ""); - - if( (fd = open(argv[1], O_RDONLY)) == -1 ) - bugp("opening firmware failed"); - - key_file = argv[2]; - - if(fstat(fd, &st) == -1) - bugp("firmware stat() failed"); - g_sz = st.st_size; - - g_buf = xmalloc(g_sz); - if(read(fd, g_buf, g_sz) != (ssize_t)g_sz) /* load the whole file into memory */ - bugp("reading firmware"); - - close(fd); - - extract(st.st_size); - - color(OFF); - - free(g_buf); - return 0; -} diff --git a/utils/sbinfo/sha1.c b/utils/sbinfo/sha1.c deleted file mode 100644 index 99657fb14a..0000000000 --- a/utils/sbinfo/sha1.c +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Amaury Pouly - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -/* Based on http://en.wikipedia.org/wiki/SHA-1 */ -#include "crypto.h" - -static uint32_t rot_left(uint32_t val, int rot) -{ - return (val << rot) | (val >> (32 - rot)); -} - -static inline void byte_swapxx(byte *ptr, int size) -{ - for(int i = 0; i < size / 2; i++) - { - byte c = ptr[i]; - ptr[i] = ptr[size - i - 1]; - ptr[size - i - 1] = c; - } -} - -static void byte_swap32(uint32_t *v) -{ - byte_swapxx((byte *)v, 4); -} - -void sha_1_init(struct sha_1_params_t *params) -{ - params->hash[0] = 0x67452301; - params->hash[1] = 0xEFCDAB89; - params->hash[2] = 0x98BADCFE; - params->hash[3] = 0x10325476; - params->hash[4] = 0xC3D2E1F0; - params->buffer_nr_bits = 0; -} - -void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size) -{ - int buffer_nr_bytes = (params->buffer_nr_bits / 8) % 64; - params->buffer_nr_bits += 8 * size; - int pos = 0; - if(buffer_nr_bytes + size >= 64) - { - pos = 64 - buffer_nr_bytes; - memcpy((byte *)(params->w) + buffer_nr_bytes, buffer, 64 - buffer_nr_bytes); - sha_1_block(params, params->hash, (byte *)params->w); - for(; pos + 64 <= size; pos += 64) - sha_1_block(params, params->hash, buffer + pos); - buffer_nr_bytes = 0; - } - memcpy((byte *)(params->w) + buffer_nr_bytes, buffer + pos, size - pos); -} - -void sha_1_finish(struct sha_1_params_t *params) -{ - /* length (in bits) in big endian BEFORE preprocessing */ - byte length_big_endian[8]; - memcpy(length_big_endian, ¶ms->buffer_nr_bits, 8); - byte_swapxx(length_big_endian, 8); - /* append '1' and then '0's to the message to get 448 bit length for the last block */ - byte b = 0x80; - sha_1_update(params, &b, 1); - b = 0; - while((params->buffer_nr_bits % 512) != 448) - sha_1_update(params, &b, 1); - /* append length */ - sha_1_update(params, length_big_endian, 8); - /* go back to big endian */ - for(int i = 0; i < 5; i++) - byte_swap32(¶ms->hash[i]); -} - -void sha_1_output(struct sha_1_params_t *params, byte *out) -{ - memcpy(out, params->hash, 20); -} - -void sha_1_block(struct sha_1_params_t *params, uint32_t cur_hash[5], byte *data) -{ - uint32_t a, b, c, d, e; - a = cur_hash[0]; - b = cur_hash[1]; - c = cur_hash[2]; - d = cur_hash[3]; - e = cur_hash[4]; - - #define w params->w - - memcpy(w, data, 64); - for(int i = 0; i < 16; i++) - byte_swap32(&w[i]); - - for(int i = 16; i <= 79; i++) - w[i] = rot_left(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); - - for(int i = 0; i<= 79; i++) - { - uint32_t f, k; - if(i <= 19) - { - f = (b & c) | ((~b) & d); - k = 0x5A827999; - } - else if(i <= 39) - { - f = b ^ c ^ d; - k = 0x6ED9EBA1; - } - else if(i <= 59) - { - f = (b & c) | (b & d) | (c & d); - k = 0x8F1BBCDC; - } - else - { - f = b ^ c ^ d; - k = 0xCA62C1D6; - } - uint32_t temp = rot_left(a, 5) + f + e + k + w[i]; - e = d; - d = c; - c = rot_left(b, 30); - b = a; - a = temp; - } - #undef w - - cur_hash[0] += a; - cur_hash[1] += b; - cur_hash[2] += c; - cur_hash[3] += d; - cur_hash[4] += e; -} diff --git a/utils/sbtools/Makefile b/utils/sbtools/Makefile new file mode 100644 index 0000000000..9427eaf875 --- /dev/null +++ b/utils/sbtools/Makefile @@ -0,0 +1,9 @@ +TGT = sbinfo + +all: $(TGT) + +$(TGT): sbinfo.c crc.c crypto.h aes128.c sha1.c elf.c + $(CC) -g -std=c99 -o $(TGT) -W -Wall sbinfo.c aes128.c crc.c sha1.c elf.c + +clean: + rm -fr $(TGT) diff --git a/utils/sbtools/aes128.c b/utils/sbtools/aes128.c new file mode 100644 index 0000000000..d435009a14 --- /dev/null +++ b/utils/sbtools/aes128.c @@ -0,0 +1,284 @@ +// Simple, thoroughly commented implementation of 128-bit AES / Rijndael using C +// Chris Hulbert - chris.hulbert@gmail.com - http://splinter.com.au/blog +// References: +// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard +// http://en.wikipedia.org/wiki/Rijndael_key_schedule +// http://en.wikipeia.org/wiki/Rijndael_mix_columns +// http://en.wikipedia.org/wiki/Rijndael_S-box +// This code is public domain, or any OSI-approved license, your choice. No warranty. +#include "crypto.h" + +// Here are all the lookup tables for the row shifts, rcon, s-boxes, and galois field multiplications +byte shift_rows_table[] = {0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11}; +byte shift_rows_table_inv[] = {0,13,10,7,4,1,14,11,8,5,2,15,12,9,6,3}; +byte lookup_rcon[]={0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a}; +byte lookup_sbox[]={0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16}; +byte lookup_sbox_inv[]={0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d}; +byte lookup_g2 []={0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe,0x1b,0x19,0x1f,0x1d,0x13,0x11,0x17,0x15,0x0b,0x09,0x0f,0x0d,0x03,0x01,0x07,0x05,0x3b,0x39,0x3f,0x3d,0x33,0x31,0x37,0x35,0x2b,0x29,0x2f,0x2d,0x23,0x21,0x27,0x25,0x5b,0x59,0x5f,0x5d,0x53,0x51,0x57,0x55,0x4b,0x49,0x4f,0x4d,0x43,0x41,0x47,0x45,0x7b,0x79,0x7f,0x7d,0x73,0x71,0x77,0x75,0x6b,0x69,0x6f,0x6d,0x63,0x61,0x67,0x65,0x9b,0x99,0x9f,0x9d,0x93,0x91,0x97,0x95,0x8b,0x89,0x8f,0x8d,0x83,0x81,0x87,0x85,0xbb,0xb9,0xbf,0xbd,0xb3,0xb1,0xb7,0xb5,0xab,0xa9,0xaf,0xad,0xa3,0xa1,0xa7,0xa5,0xdb,0xd9,0xdf,0xdd,0xd3,0xd1,0xd7,0xd5,0xcb,0xc9,0xcf,0xcd,0xc3,0xc1,0xc7,0xc5,0xfb,0xf9,0xff,0xfd,0xf3,0xf1,0xf7,0xf5,0xeb,0xe9,0xef,0xed,0xe3,0xe1,0xe7,0xe5}; +byte lookup_g3 []={0x00,0x03,0x06,0x05,0x0c,0x0f,0x0a,0x09,0x18,0x1b,0x1e,0x1d,0x14,0x17,0x12,0x11,0x30,0x33,0x36,0x35,0x3c,0x3f,0x3a,0x39,0x28,0x2b,0x2e,0x2d,0x24,0x27,0x22,0x21,0x60,0x63,0x66,0x65,0x6c,0x6f,0x6a,0x69,0x78,0x7b,0x7e,0x7d,0x74,0x77,0x72,0x71,0x50,0x53,0x56,0x55,0x5c,0x5f,0x5a,0x59,0x48,0x4b,0x4e,0x4d,0x44,0x47,0x42,0x41,0xc0,0xc3,0xc6,0xc5,0xcc,0xcf,0xca,0xc9,0xd8,0xdb,0xde,0xdd,0xd4,0xd7,0xd2,0xd1,0xf0,0xf3,0xf6,0xf5,0xfc,0xff,0xfa,0xf9,0xe8,0xeb,0xee,0xed,0xe4,0xe7,0xe2,0xe1,0xa0,0xa3,0xa6,0xa5,0xac,0xaf,0xaa,0xa9,0xb8,0xbb,0xbe,0xbd,0xb4,0xb7,0xb2,0xb1,0x90,0x93,0x96,0x95,0x9c,0x9f,0x9a,0x99,0x88,0x8b,0x8e,0x8d,0x84,0x87,0x82,0x81,0x9b,0x98,0x9d,0x9e,0x97,0x94,0x91,0x92,0x83,0x80,0x85,0x86,0x8f,0x8c,0x89,0x8a,0xab,0xa8,0xad,0xae,0xa7,0xa4,0xa1,0xa2,0xb3,0xb0,0xb5,0xb6,0xbf,0xbc,0xb9,0xba,0xfb,0xf8,0xfd,0xfe,0xf7,0xf4,0xf1,0xf2,0xe3,0xe0,0xe5,0xe6,0xef,0xec,0xe9,0xea,0xcb,0xc8,0xcd,0xce,0xc7,0xc4,0xc1,0xc2,0xd3,0xd0,0xd5,0xd6,0xdf,0xdc,0xd9,0xda,0x5b,0x58,0x5d,0x5e,0x57,0x54,0x51,0x52,0x43,0x40,0x45,0x46,0x4f,0x4c,0x49,0x4a,0x6b,0x68,0x6d,0x6e,0x67,0x64,0x61,0x62,0x73,0x70,0x75,0x76,0x7f,0x7c,0x79,0x7a,0x3b,0x38,0x3d,0x3e,0x37,0x34,0x31,0x32,0x23,0x20,0x25,0x26,0x2f,0x2c,0x29,0x2a,0x0b,0x08,0x0d,0x0e,0x07,0x04,0x01,0x02,0x13,0x10,0x15,0x16,0x1f,0x1c,0x19,0x1a}; +byte lookup_g9 []={0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77,0x90,0x99,0x82,0x8b,0xb4,0xbd,0xa6,0xaf,0xd8,0xd1,0xca,0xc3,0xfc,0xf5,0xee,0xe7,0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c,0xab,0xa2,0xb9,0xb0,0x8f,0x86,0x9d,0x94,0xe3,0xea,0xf1,0xf8,0xc7,0xce,0xd5,0xdc,0x76,0x7f,0x64,0x6d,0x52,0x5b,0x40,0x49,0x3e,0x37,0x2c,0x25,0x1a,0x13,0x08,0x01,0xe6,0xef,0xf4,0xfd,0xc2,0xcb,0xd0,0xd9,0xae,0xa7,0xbc,0xb5,0x8a,0x83,0x98,0x91,0x4d,0x44,0x5f,0x56,0x69,0x60,0x7b,0x72,0x05,0x0c,0x17,0x1e,0x21,0x28,0x33,0x3a,0xdd,0xd4,0xcf,0xc6,0xf9,0xf0,0xeb,0xe2,0x95,0x9c,0x87,0x8e,0xb1,0xb8,0xa3,0xaa,0xec,0xe5,0xfe,0xf7,0xc8,0xc1,0xda,0xd3,0xa4,0xad,0xb6,0xbf,0x80,0x89,0x92,0x9b,0x7c,0x75,0x6e,0x67,0x58,0x51,0x4a,0x43,0x34,0x3d,0x26,0x2f,0x10,0x19,0x02,0x0b,0xd7,0xde,0xc5,0xcc,0xf3,0xfa,0xe1,0xe8,0x9f,0x96,0x8d,0x84,0xbb,0xb2,0xa9,0xa0,0x47,0x4e,0x55,0x5c,0x63,0x6a,0x71,0x78,0x0f,0x06,0x1d,0x14,0x2b,0x22,0x39,0x30,0x9a,0x93,0x88,0x81,0xbe,0xb7,0xac,0xa5,0xd2,0xdb,0xc0,0xc9,0xf6,0xff,0xe4,0xed,0x0a,0x03,0x18,0x11,0x2e,0x27,0x3c,0x35,0x42,0x4b,0x50,0x59,0x66,0x6f,0x74,0x7d,0xa1,0xa8,0xb3,0xba,0x85,0x8c,0x97,0x9e,0xe9,0xe0,0xfb,0xf2,0xcd,0xc4,0xdf,0xd6,0x31,0x38,0x23,0x2a,0x15,0x1c,0x07,0x0e,0x79,0x70,0x6b,0x62,0x5d,0x54,0x4f,0x46}; +byte lookup_g11 []={0x00,0x0b,0x16,0x1d,0x2c,0x27,0x3a,0x31,0x58,0x53,0x4e,0x45,0x74,0x7f,0x62,0x69,0xb0,0xbb,0xa6,0xad,0x9c,0x97,0x8a,0x81,0xe8,0xe3,0xfe,0xf5,0xc4,0xcf,0xd2,0xd9,0x7b,0x70,0x6d,0x66,0x57,0x5c,0x41,0x4a,0x23,0x28,0x35,0x3e,0x0f,0x04,0x19,0x12,0xcb,0xc0,0xdd,0xd6,0xe7,0xec,0xf1,0xfa,0x93,0x98,0x85,0x8e,0xbf,0xb4,0xa9,0xa2,0xf6,0xfd,0xe0,0xeb,0xda,0xd1,0xcc,0xc7,0xae,0xa5,0xb8,0xb3,0x82,0x89,0x94,0x9f,0x46,0x4d,0x50,0x5b,0x6a,0x61,0x7c,0x77,0x1e,0x15,0x08,0x03,0x32,0x39,0x24,0x2f,0x8d,0x86,0x9b,0x90,0xa1,0xaa,0xb7,0xbc,0xd5,0xde,0xc3,0xc8,0xf9,0xf2,0xef,0xe4,0x3d,0x36,0x2b,0x20,0x11,0x1a,0x07,0x0c,0x65,0x6e,0x73,0x78,0x49,0x42,0x5f,0x54,0xf7,0xfc,0xe1,0xea,0xdb,0xd0,0xcd,0xc6,0xaf,0xa4,0xb9,0xb2,0x83,0x88,0x95,0x9e,0x47,0x4c,0x51,0x5a,0x6b,0x60,0x7d,0x76,0x1f,0x14,0x09,0x02,0x33,0x38,0x25,0x2e,0x8c,0x87,0x9a,0x91,0xa0,0xab,0xb6,0xbd,0xd4,0xdf,0xc2,0xc9,0xf8,0xf3,0xee,0xe5,0x3c,0x37,0x2a,0x21,0x10,0x1b,0x06,0x0d,0x64,0x6f,0x72,0x79,0x48,0x43,0x5e,0x55,0x01,0x0a,0x17,0x1c,0x2d,0x26,0x3b,0x30,0x59,0x52,0x4f,0x44,0x75,0x7e,0x63,0x68,0xb1,0xba,0xa7,0xac,0x9d,0x96,0x8b,0x80,0xe9,0xe2,0xff,0xf4,0xc5,0xce,0xd3,0xd8,0x7a,0x71,0x6c,0x67,0x56,0x5d,0x40,0x4b,0x22,0x29,0x34,0x3f,0x0e,0x05,0x18,0x13,0xca,0xc1,0xdc,0xd7,0xe6,0xed,0xf0,0xfb,0x92,0x99,0x84,0x8f,0xbe,0xb5,0xa8,0xa3}; +byte lookup_g13 []={0x00,0x0d,0x1a,0x17,0x34,0x39,0x2e,0x23,0x68,0x65,0x72,0x7f,0x5c,0x51,0x46,0x4b,0xd0,0xdd,0xca,0xc7,0xe4,0xe9,0xfe,0xf3,0xb8,0xb5,0xa2,0xaf,0x8c,0x81,0x96,0x9b,0xbb,0xb6,0xa1,0xac,0x8f,0x82,0x95,0x98,0xd3,0xde,0xc9,0xc4,0xe7,0xea,0xfd,0xf0,0x6b,0x66,0x71,0x7c,0x5f,0x52,0x45,0x48,0x03,0x0e,0x19,0x14,0x37,0x3a,0x2d,0x20,0x6d,0x60,0x77,0x7a,0x59,0x54,0x43,0x4e,0x05,0x08,0x1f,0x12,0x31,0x3c,0x2b,0x26,0xbd,0xb0,0xa7,0xaa,0x89,0x84,0x93,0x9e,0xd5,0xd8,0xcf,0xc2,0xe1,0xec,0xfb,0xf6,0xd6,0xdb,0xcc,0xc1,0xe2,0xef,0xf8,0xf5,0xbe,0xb3,0xa4,0xa9,0x8a,0x87,0x90,0x9d,0x06,0x0b,0x1c,0x11,0x32,0x3f,0x28,0x25,0x6e,0x63,0x74,0x79,0x5a,0x57,0x40,0x4d,0xda,0xd7,0xc0,0xcd,0xee,0xe3,0xf4,0xf9,0xb2,0xbf,0xa8,0xa5,0x86,0x8b,0x9c,0x91,0x0a,0x07,0x10,0x1d,0x3e,0x33,0x24,0x29,0x62,0x6f,0x78,0x75,0x56,0x5b,0x4c,0x41,0x61,0x6c,0x7b,0x76,0x55,0x58,0x4f,0x42,0x09,0x04,0x13,0x1e,0x3d,0x30,0x27,0x2a,0xb1,0xbc,0xab,0xa6,0x85,0x88,0x9f,0x92,0xd9,0xd4,0xc3,0xce,0xed,0xe0,0xf7,0xfa,0xb7,0xba,0xad,0xa0,0x83,0x8e,0x99,0x94,0xdf,0xd2,0xc5,0xc8,0xeb,0xe6,0xf1,0xfc,0x67,0x6a,0x7d,0x70,0x53,0x5e,0x49,0x44,0x0f,0x02,0x15,0x18,0x3b,0x36,0x21,0x2c,0x0c,0x01,0x16,0x1b,0x38,0x35,0x22,0x2f,0x64,0x69,0x7e,0x73,0x50,0x5d,0x4a,0x47,0xdc,0xd1,0xc6,0xcb,0xe8,0xe5,0xf2,0xff,0xb4,0xb9,0xae,0xa3,0x80,0x8d,0x9a,0x97}; +byte lookup_g14 []={0x00,0x0e,0x1c,0x12,0x38,0x36,0x24,0x2a,0x70,0x7e,0x6c,0x62,0x48,0x46,0x54,0x5a,0xe0,0xee,0xfc,0xf2,0xd8,0xd6,0xc4,0xca,0x90,0x9e,0x8c,0x82,0xa8,0xa6,0xb4,0xba,0xdb,0xd5,0xc7,0xc9,0xe3,0xed,0xff,0xf1,0xab,0xa5,0xb7,0xb9,0x93,0x9d,0x8f,0x81,0x3b,0x35,0x27,0x29,0x03,0x0d,0x1f,0x11,0x4b,0x45,0x57,0x59,0x73,0x7d,0x6f,0x61,0xad,0xa3,0xb1,0xbf,0x95,0x9b,0x89,0x87,0xdd,0xd3,0xc1,0xcf,0xe5,0xeb,0xf9,0xf7,0x4d,0x43,0x51,0x5f,0x75,0x7b,0x69,0x67,0x3d,0x33,0x21,0x2f,0x05,0x0b,0x19,0x17,0x76,0x78,0x6a,0x64,0x4e,0x40,0x52,0x5c,0x06,0x08,0x1a,0x14,0x3e,0x30,0x22,0x2c,0x96,0x98,0x8a,0x84,0xae,0xa0,0xb2,0xbc,0xe6,0xe8,0xfa,0xf4,0xde,0xd0,0xc2,0xcc,0x41,0x4f,0x5d,0x53,0x79,0x77,0x65,0x6b,0x31,0x3f,0x2d,0x23,0x09,0x07,0x15,0x1b,0xa1,0xaf,0xbd,0xb3,0x99,0x97,0x85,0x8b,0xd1,0xdf,0xcd,0xc3,0xe9,0xe7,0xf5,0xfb,0x9a,0x94,0x86,0x88,0xa2,0xac,0xbe,0xb0,0xea,0xe4,0xf6,0xf8,0xd2,0xdc,0xce,0xc0,0x7a,0x74,0x66,0x68,0x42,0x4c,0x5e,0x50,0x0a,0x04,0x16,0x18,0x32,0x3c,0x2e,0x20,0xec,0xe2,0xf0,0xfe,0xd4,0xda,0xc8,0xc6,0x9c,0x92,0x80,0x8e,0xa4,0xaa,0xb8,0xb6,0x0c,0x02,0x10,0x1e,0x34,0x3a,0x28,0x26,0x7c,0x72,0x60,0x6e,0x44,0x4a,0x58,0x56,0x37,0x39,0x2b,0x25,0x0f,0x01,0x13,0x1d,0x47,0x49,0x5b,0x55,0x7f,0x71,0x63,0x6d,0xd7,0xd9,0xcb,0xc5,0xef,0xe1,0xf3,0xfd,0xa7,0xa9,0xbb,0xb5,0x9f,0x91,0x83,0x8d}; + +// Xor's all elements in a n byte array a by b +void xor_(byte *a, byte *b, int n) { + int i; + for (i=0;i ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "crypto.h" + +/* Table extracted from firmware, don't know if this is regular CRC32 */ + +static uint32_t crc_table[256] = { + 0x0, 0x4C11DB7, 0x9823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, + 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, + 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, + 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, + 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, + 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, 0x8B27C03C, + 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0x0BE2B5B58, 0x0BAEA46EF, 0x0B7A96036, + 0x0B3687D81, 0x0AD2F2D84, 0x0A9EE3033, 0x0A4AD16EA, 0x0A06C0B5D, 0x0D4326D90, + 0x0D0F37027, 0x0DDB056FE, 0x0D9714B49, 0x0C7361B4C, 0x0C3F706FB, 0x0CEB42022, + 0x0CA753D95, 0x0F23A8028, 0x0F6FB9D9F, 0x0FBB8BB46, 0x0FF79A6F1, 0x0E13EF6F4, + 0x0E5FFEB43, 0x0E8BCCD9A, 0x0EC7DD02D, 0x34867077, 0x30476DC0, 0x3D044B19, + 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072, 0x128E9DCF, + 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x18AEB13, 0x54BF6A4, 0x808D07D, + 0x0CC9CDCA, 0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, + 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, + 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA, 0x0ACA5C697, + 0x0A864DB20, 0x0A527FDF9, 0x0A1E6E04E, 0x0BFA1B04B, 0x0BB60ADFC, 0x0B6238B25, + 0x0B2E29692, 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, 0x99A95DF3, + 0x9D684044, 0x902B669D, 0x94EA7B2A, 0x0E0B41DE7, 0x0E4750050, 0x0E9362689, + 0x0EDF73B3E, 0x0F3B06B3B, 0x0F771768C, 0x0FA325055, 0x0FEF34DE2, 0x0C6BCF05F, + 0x0C27DEDE8, 0x0CF3ECB31, 0x0CBFFD686, 0x0D5B88683, 0x0D1799B34, 0x0DC3ABDED, + 0x0D8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, 0x7A089632, + 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, 0x4F040D56, 0x4BC510E1, 0x46863638, + 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, + 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, + 0x3B5A6B9B, 0x315D626, 0x7D4CB91, 0x0A97ED48, 0x0E56F0FF, 0x1011A0FA, + 0x14D0BD4D, 0x19939B94, 0x1D528623, 0x0F12F560E, 0x0F5EE4BB9, 0x0F8AD6D60, + 0x0FC6C70D7, 0x0E22B20D2, 0x0E6EA3D65, 0x0EBA91BBC, 0x0EF68060B, 0x0D727BBB6, + 0x0D3E6A601, 0x0DEA580D8, 0x0DA649D6F, 0x0C423CD6A, 0x0C0E2D0DD, 0x0CDA1F604, + 0x0C960EBB3, 0x0BD3E8D7E, 0x0B9FF90C9, 0x0B4BCB610, 0x0B07DABA7, 0x0AE3AFBA2, + 0x0AAFBE615, 0x0A7B8C0CC, 0x0A379DD7B, 0x9B3660C6, 0x9FF77D71, 0x92B45BA8, + 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3, 0x5D8A9099, + 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, + 0x43CDC09C, 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, + 0x6C47164A, 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087, + 0x1CD86D30, 0x29F3D35, 0x65E2082, 0x0B1D065B, 0x0FDC1BEC, 0x3793A651, + 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, + 0x29D4F654, 0x0C5A92679, 0x0C1683BCE, 0x0CC2B1D17, 0x0C8EA00A0, 0x0D6AD50A5, + 0x0D26C4D12, 0x0DF2F6BCB, 0x0DBEE767C, 0x0E3A1CBC1, 0x0E760D676, 0x0EA23F0AF, + 0x0EEE2ED18, 0x0F0A5BD1D, 0x0F464A0AA, 0x0F9278673, 0x0FDE69BC4, 0x89B8FD09, + 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, + 0x97FFAD0C, 0x0AFB010B1, 0x0AB710D06, 0x0A6322BDF, 0x0A2F33668, 0x0BCB4666D, + 0x0B8757BDA, 0x0B5365D03, 0x0B1F740B4 +}; + +uint32_t crc(byte *data, int size) +{ + uint32_t c = 0xffffffff; + /* normal CRC */ + for(int i = 0; i < size; i++) + c = crc_table[data[i] ^ (c >> 24)] ^ (c << 8); + return c; +} diff --git a/utils/sbtools/crypto.h b/utils/sbtools/crypto.h new file mode 100644 index 0000000000..e36900df47 --- /dev/null +++ b/utils/sbtools/crypto.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include + +typedef uint8_t byte; + +/* aes128.c */ +void xor_(byte *a, byte *b, int n); +void EncryptAES(byte *msg, byte *key, byte *c); +void DecryptAES(byte *c, byte *key, byte *m); +void Pretty(byte* b,int len,const char* label); +void cbc_mac( + byte *in_data, /* Input data */ + byte *out_data, /* Output data (or NULL) */ + int nr_blocks, /* Number of blocks to encrypt/decrypt (one block=16 bytes) */ + byte key[16], /* Key */ + byte iv[16], /* Initialisation Vector */ + byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */ + int encrypt /* 1 to encrypt, 0 to decrypt */ + ); + +/* crc.c */ +uint32_t crc(byte *data, int size); + +/* sha1.c */ +struct sha_1_params_t +{ + uint32_t hash[5]; + uint64_t buffer_nr_bits; + uint32_t w[80]; +}; + +void sha_1_init(struct sha_1_params_t *params); +void sha_1_block(struct sha_1_params_t *params, uint32_t cur_hash[5], byte *data); +void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size); +void sha_1_finish(struct sha_1_params_t *params); +void sha_1_output(struct sha_1_params_t *params, byte *out); diff --git a/utils/sbtools/elf.c b/utils/sbtools/elf.c new file mode 100644 index 0000000000..f146bcc111 --- /dev/null +++ b/utils/sbtools/elf.c @@ -0,0 +1,237 @@ +#include "elf.h" + +void elf_init(struct elf_params_t *params) +{ + params->has_start_addr = false; + params->start_addr = 0; + params->first_section = NULL; + params->last_section = NULL; +} + +extern void *xmalloc(size_t s); + +static struct elf_section_t *elf_add_section(struct elf_params_t *params) +{ + struct elf_section_t *sec = xmalloc(sizeof(struct elf_section_t)); + if(params->first_section == NULL) + params->first_section = params->last_section = sec; + else + { + params->last_section->next = sec; + params->last_section = sec; + } + sec->next = NULL; + + return sec; +} + +void elf_add_load_section(struct elf_params_t *params, + uint32_t load_addr, uint32_t size, const void *section) +{ + struct elf_section_t *sec = elf_add_section(params); + + sec->type = EST_LOAD; + sec->addr = load_addr; + sec->size = size; + sec->section = xmalloc(size); + memcpy(sec->section, section, size); +} + +void elf_add_fill_section(struct elf_params_t *params, + uint32_t fill_addr, uint32_t size, uint32_t pattern) +{ + if(pattern != 0x00) + { + printf("oops, non-zero filling, ignore fill section\n"); + return; + } + + struct elf_section_t *sec = elf_add_section(params); + + sec->type = EST_FILL; + sec->addr = fill_addr; + sec->size = size; + sec->pattern = pattern; +} + +void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user) +{ + Elf32_Ehdr ehdr; + uint32_t phnum = 0; + struct elf_section_t *sec = params->first_section; + uint32_t offset = 0; + Elf32_Phdr phdr; + Elf32_Shdr shdr; + memset(&ehdr, 0, EI_NIDENT); + + uint32_t bss_strtbl = 0; + uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1; + uint32_t strtbl_size = text_strtbl + strlen(".text") + 1; + + while(sec) + { + if(sec->type == EST_LOAD) + { + sec->offset = offset; + offset += sec->size; + } + + phnum++; + sec = sec->next; + } + + uint32_t strtbl_offset = offset; + + ehdr.e_ident[EI_MAG0] = ELFMAG0; + ehdr.e_ident[EI_MAG1] = ELFMAG1; + ehdr.e_ident[EI_MAG2] = ELFMAG2; + ehdr.e_ident[EI_MAG3] = ELFMAG3; + ehdr.e_ident[EI_CLASS] = ELFCLASS32; + ehdr.e_ident[EI_DATA] = ELFDATA2LSB; + ehdr.e_ident[EI_VERSION] = EV_CURRENT; + ehdr.e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr.e_ident[EI_ABIVERSION] = 0; + ehdr.e_type = ET_EXEC; + ehdr.e_machine = EM_ARM; + ehdr.e_version = EV_CURRENT; + ehdr.e_entry = params->start_addr; + ehdr.e_flags = 0; + if(params->has_start_addr) + ehdr.e_flags |= EF_ARM_HASENTRY; + ehdr.e_ehsize = sizeof ehdr; + ehdr.e_phentsize = sizeof phdr; + ehdr.e_phnum = phnum; + ehdr.e_shentsize = sizeof shdr; + ehdr.e_shnum = phnum + 2; /* one for section 0 and one for string table */ + ehdr.e_shstrndx = ehdr.e_shnum - 1; + ehdr.e_phoff = ehdr.e_ehsize; + ehdr.e_shoff = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize; + + write(user, 0, &ehdr, sizeof ehdr); + + uint32_t data_offset = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize + + ehdr.e_shnum * ehdr.e_shentsize; + + sec = params->first_section; + offset = ehdr.e_phoff; + while(sec) + { + sec->offset += data_offset; + + phdr.p_type = PT_LOAD; + if(sec->type == EST_LOAD) + phdr.p_offset = sec->offset; + else + phdr.p_offset = 0; + phdr.p_paddr = sec->addr; + phdr.p_vaddr = phdr.p_paddr; /* assume identity map ? */ + phdr.p_memsz = sec->size; + if(sec->type == EST_LOAD) + phdr.p_filesz = phdr.p_memsz; + else + phdr.p_filesz = 0; + phdr.p_flags = PF_X | PF_W | PF_R; + phdr.p_align = 0; + + write(user, offset, &phdr, sizeof phdr); + + offset += sizeof(Elf32_Phdr); + sec = sec->next; + } + + sec = params->first_section; + offset = ehdr.e_shoff; + + { + shdr.sh_name = 0; + shdr.sh_type = SHT_NULL; + shdr.sh_flags = 0; + shdr.sh_addr = 0; + shdr.sh_offset = 0; + shdr.sh_size = 0; + shdr.sh_link = SHN_UNDEF; + shdr.sh_info = 0; + shdr.sh_addralign = 0; + shdr.sh_entsize = 0; + + write(user, offset, &shdr, sizeof shdr); + + offset += sizeof(Elf32_Shdr); + } + + while(sec) + { + shdr.sh_name = text_strtbl; + if(sec->type == EST_LOAD) + shdr.sh_type = SHT_PROGBITS; + else + shdr.sh_type = SHT_NOBITS; + shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR; + shdr.sh_addr = sec->addr; + shdr.sh_offset = sec->offset; + shdr.sh_size = sec->size; + shdr.sh_link = SHN_UNDEF; + shdr.sh_info = 0; + shdr.sh_addralign = 1; + shdr.sh_entsize = 0; + + write(user, offset, &shdr, sizeof shdr); + + offset += sizeof(Elf32_Shdr); + sec = sec->next; + } + + { + shdr.sh_name = bss_strtbl; + shdr.sh_type = SHT_STRTAB; + shdr.sh_flags = 0; + shdr.sh_addr = 0; + shdr.sh_offset = strtbl_offset + data_offset; + shdr.sh_size = strtbl_size; + shdr.sh_link = SHN_UNDEF; + shdr.sh_info = 0; + shdr.sh_addralign = 1; + shdr.sh_entsize = 0; + + write(user, offset, &shdr, sizeof shdr); + + offset += sizeof(Elf32_Shdr); + } + + sec = params->first_section; + while(sec) + { + if(sec->type == EST_LOAD) + write(user, sec->offset, sec->section, sec->size); + sec = sec->next; + } + + write(user, strtbl_offset + data_offset, ".bss\0.text\0", strtbl_size); +} + +bool elf_is_empty(struct elf_params_t *params) +{ + return params->first_section == NULL; +} + +void elf_set_start_addr(struct elf_params_t *params, uint32_t addr) +{ + params->has_start_addr = true; + params->start_addr = addr; +} + +void elf_release(struct elf_params_t *params) +{ + struct elf_section_t *sec, *next_sec; + sec = params->first_section; + while(sec) + { + next_sec = sec->next; + if(sec->type == EST_LOAD) + free(sec->section); + free(sec); + sec = next_sec; + } + params->first_section = NULL; + params->last_section = NULL; +} diff --git a/utils/sbtools/elf.h b/utils/sbtools/elf.h new file mode 100644 index 0000000000..d2bf210c5c --- /dev/null +++ b/utils/sbtools/elf.h @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#include + +/** + * Definitions + * taken from elf.h linux header + * based on ELF specification + * based on ARM ELF specification + */ +typedef uint16_t Elf32_Half; + +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf32_Addr; +typedef uint32_t Elf32_Off; +typedef uint16_t Elf32_Section; + +#define EI_NIDENT 16 + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +}Elf32_Ehdr; + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASS32 1 /* 32-bit objects */ + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ + +#define EI_VERSION 6 /* File version byte index, Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ +#define ELFOSABI_ARM 97 /* ARM */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +#define ET_EXEC 2 /* Executable file */ + +#define EM_ARM 40 /* ARM */ + +#define EV_CURRENT 1 /* Current version */ + +#define EF_ARM_HASENTRY 0x00000002 + +#define SHN_UNDEF 0 /* Undefined section */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +}Elf32_Shdr; + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* Number of defined types. */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +}Elf32_Phdr; + +#define PT_LOAD 1 /* Loadable program segment */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ + +/** + * API + */ +enum elf_section_type_t +{ + EST_LOAD, + EST_FILL +}; + +struct elf_section_t +{ + uint32_t addr; + uint32_t size; + enum elf_section_type_t type; + /* */ + void *section; + uint32_t pattern; + /* */ + struct elf_section_t *next; + /* Internal to elf_output */ + uint32_t offset; +}; + +struct elf_params_t +{ + bool has_start_addr; + uint32_t start_addr; + struct elf_section_t *first_section; + struct elf_section_t *last_section; +}; + +typedef void (*elf_write_fn_t)(void *user, uint32_t addr, const void *buf, size_t count); + +void elf_init(struct elf_params_t *params); +void elf_add_load_section(struct elf_params_t *params, + uint32_t load_addr, uint32_t size, const void *section); +void elf_add_fill_section(struct elf_params_t *params, + uint32_t fill_addr, uint32_t size, uint32_t pattern); +void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user); +bool elf_is_empty(struct elf_params_t *params); +void elf_set_start_addr(struct elf_params_t *params, uint32_t addr); +void elf_release(struct elf_params_t *params); diff --git a/utils/sbtools/fuze+_key_file.txt b/utils/sbtools/fuze+_key_file.txt new file mode 100644 index 0000000000..a965e715f7 --- /dev/null +++ b/utils/sbtools/fuze+_key_file.txt @@ -0,0 +1 @@ +00000000000000000000000000000000 diff --git a/utils/sbtools/sb.h b/utils/sbtools/sb.h new file mode 100644 index 0000000000..29b7d7d894 --- /dev/null +++ b/utils/sbtools/sb.h @@ -0,0 +1,118 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#define _ISOC99_SOURCE /* snprintf() */ +#include +#include + +#define BLOCK_SIZE 16 + +struct sb_version_t +{ + uint16_t major; + uint16_t pad0; + uint16_t minor; + uint16_t pad1; + uint16_t revision; + uint16_t pad2; +}; + +struct sb_header_t +{ + uint8_t sha1_header[20]; /* SHA-1 of the rest of the header */ + uint8_t signature[4]; /* Signature "STMP" */ + uint8_t major_ver; /* Should be 1 */ + uint8_t minor_ver; /* Should be 1 */ + uint16_t flags; + uint32_t image_size; /* In blocks (=16bytes) */ + uint32_t first_boot_tag_off; /* Offset in blocks */ + uint32_t first_boot_sec_id; /* First bootable section ID */ + uint16_t nr_keys; /* Number of encryption keys */ + uint16_t key_dict_off; /* Offset to key dictionary (in blocks) */ + uint16_t header_size; /* In blocks */ + uint16_t nr_sections; /* Number of sections */ + uint16_t sec_hdr_size; /* Section header size (in blocks) */ + uint8_t rand_pad0[6]; /* Random padding */ + uint64_t timestamp; /* In microseconds since 2000/1/1 00:00:00 */ + struct sb_version_t product_ver; + struct sb_version_t component_ver; + uint16_t drive_tag; /* Unknown meaning */ + uint8_t rand_pad1[6]; /* Random padding */ +} __attribute__((packed)); + +struct sb_section_header_t +{ + uint32_t identifier; + uint32_t offset; /* In blocks */ + uint32_t size; /* In blocks */ + uint32_t flags; +} __attribute__((packed)); + +struct sb_key_dictionary_entry_t +{ + uint8_t hdr_cbc_mac[16]; /* CBC-MAC of the header */ + uint8_t key[16]; /* Actual AES Key (encrypted by the global key) */ +} __attribute__((packed)); + +#define IMAGE_MAJOR_VERSION 1 +#define IMAGE_MINOR_VERSION 1 + +#define SECTION_BOOTABLE (1 << 0) +#define SECTION_CLEARTEXT (1 << 1) + +#define SB_INST_NOP 0x0 +#define SB_INST_TAG 0x1 +#define SB_INST_LOAD 0x2 +#define SB_INST_FILL 0x3 +#define SB_INST_JUMP 0x4 +#define SB_INST_CALL 0x5 +#define SB_INST_MODE 0x6 + +struct sb_instruction_header_t +{ + uint8_t checksum; + uint8_t opcode; + uint16_t zero_except_for_tag; +} __attribute__((packed)); + +struct sb_instruction_load_t +{ + struct sb_instruction_header_t hdr; + uint32_t addr; + uint32_t len; + uint32_t crc; +} __attribute__((packed)); + +struct sb_instruction_fill_t +{ + struct sb_instruction_header_t hdr; + uint32_t addr; + uint32_t len; + uint32_t pattern; +} __attribute__((packed)); + +struct sb_instruction_call_t +{ + struct sb_instruction_header_t hdr; + uint32_t addr; + uint32_t zero; + uint32_t arg; +} __attribute__((packed)); diff --git a/utils/sbtools/sbtoelf.c b/utils/sbtools/sbtoelf.c new file mode 100644 index 0000000000..632c4b3eb9 --- /dev/null +++ b/utils/sbtools/sbtoelf.c @@ -0,0 +1,596 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Bertrik Sikken + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* + * .sb file parser and chunk extractor + * + * Based on amsinfo, which is + * Copyright © 2008 Rafaël Carré + */ + +#define _ISOC99_SOURCE /* snprintf() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crypto.h" +#include "elf.h" +#include "sb.h" + +#if 1 /* ANSI colors */ + +# define color(a) printf("%s",a) +char OFF[] = { 0x1b, 0x5b, 0x31, 0x3b, '0', '0', 0x6d, '\0' }; + +char GREY[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '0', 0x6d, '\0' }; +char RED[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '1', 0x6d, '\0' }; +char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' }; +char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' }; +char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' }; + +#else + /* disable colors */ +# define color(a) +#endif + +#define bug(...) do { fprintf(stderr,"ERROR: "__VA_ARGS__); exit(1); } while(0) +#define bugp(a) do { perror("ERROR: "a); exit(1); } while(0) + +/* all blocks are sized as a multiple of 0x1ff */ +#define PAD_TO_BOUNDARY(x) (((x) + 0x1ff) & ~0x1ff) + +/* If you find a firmware that breaks the known format ^^ */ +#define assert(a) do { if(!(a)) { fprintf(stderr,"Assertion \"%s\" failed in %s() line %d!\n\nPlease send us your firmware!\n",#a,__func__,__LINE__); exit(1); } } while(0) + +/* globals */ + +size_t g_sz; /* file size */ +uint8_t *g_buf; /* file content */ +#define PREFIX_SIZE 128 +char out_prefix[PREFIX_SIZE]; +const char *key_file; + +void *xmalloc(size_t s) /* malloc helper, used in elf.c */ +{ + void * r = malloc(s); + if(!r) bugp("malloc"); + return r; +} + +static void print_hex(byte *data, int len, bool newline) +{ + for(int i = 0; i < len; i++) + printf("%02X ", data[i]); + if(newline) + printf("\n"); +} + +int convxdigit(char digit, byte *val) +{ + if(digit >= '0' && digit <= '9') + { + *val = digit - '0'; + return 0; + } + else if(digit >= 'A' && digit <= 'F') + { + *val = digit - 'A' + 10; + return 0; + } + else if(digit >= 'a' && digit <= 'f') + { + *val = digit - 'a' + 10; + return 0; + } + else + return 1; +} + +typedef byte (*key_array_t)[16]; + +static key_array_t read_keys(int num_keys) +{ + int size; + struct stat st; + int fd = open(key_file,O_RDONLY); + if(fd == -1) + bugp("opening key file failed"); + if(fstat(fd,&st) == -1) + bugp("key file stat() failed"); + size = st.st_size; + char *buf = xmalloc(size); + if(read(fd, buf, size) != (ssize_t)size) + bugp("reading key file"); + close(fd); + + key_array_t keys = xmalloc(sizeof(byte[16]) * num_keys); + int pos = 0; + for(int i = 0; i < num_keys; i++) + { + /* skip ws */ + while(pos < size && isspace(buf[pos])) + pos++; + /* enough space ? */ + if((pos + 32) > size) + bugp("invalid key file (not enough keys)"); + for(int j = 0; j < 16; j++) + { + byte a, b; + if(convxdigit(buf[pos + 2 * j], &a) || convxdigit(buf[pos + 2 * j + 1], &b)) + bugp(" invalid key, it should be a 128-bit key written in hexadecimal\n"); + keys[i][j] = (a << 4) | b; + } + pos += 32; + } + free(buf); + + return keys; +} + +#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round)) + +static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr) +{ + uint8_t sum = 90; + byte *ptr = (byte *)hdr; + for(int i = 1; i < 16; i++) + sum += ptr[i]; + return sum; +} + +static void elf_write(void *user, uint32_t addr, const void *buf, size_t count) +{ + FILE *f = user; + fseek(f, addr, SEEK_SET); + fwrite(buf, count, 1, f); +} + +static void extract_elf_section(struct elf_params_t *elf, int count, const char *prefix, + const char *indent) +{ + char *filename = xmalloc(strlen(prefix) + 32); + sprintf(filename, "%s.%d.elf", prefix, count); + printf("%swrite %s\n", indent, filename); + + FILE *fd = fopen(filename, "wb"); + free(filename); + + if(fd == NULL) + return ; + elf_output(elf, elf_write, fd); + fclose(fd); +} + +static void extract_section(int data_sec, char name[5], byte *buf, int size, const char *indent) +{ + char filename[PREFIX_SIZE + 32]; + snprintf(filename, sizeof filename, "%s%s.bin", out_prefix, name); + FILE *fd = fopen(filename, "wb"); + if (fd != NULL) { + fwrite(buf, size, 1, fd); + fclose(fd); + } + if(data_sec) + return; + + snprintf(filename, sizeof filename, "%s%s", out_prefix, name); + + /* elf construction */ + struct elf_params_t elf; + elf_init(&elf); + int elf_count = 0; + /* Pretty print the content */ + int pos = 0; + while(pos < size) + { + struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)&buf[pos]; + printf("%s", indent); + uint8_t checksum = instruction_checksum(hdr); + if(checksum != hdr->checksum) + { + color(GREY); + printf("[Bad checksum]"); + } + + if(hdr->opcode == SB_INST_LOAD) + { + struct sb_instruction_load_t *load = (struct sb_instruction_load_t *)&buf[pos]; + color(RED); + printf("LOAD"); + color(OFF);printf(" | "); + color(BLUE); + printf("addr=0x%08x", load->addr); + color(OFF);printf(" | "); + color(GREEN); + printf("len=0x%08x", load->len); + color(OFF);printf(" | "); + color(YELLOW); + printf("crc=0x%08x", load->crc); + /* data is padded to 16-byte boundary with random data and crc'ed with it */ + uint32_t computed_crc = crc(&buf[pos + sizeof(struct sb_instruction_load_t)], + ROUND_UP(load->len, 16)); + color(RED); + if(load->crc == computed_crc) + printf(" Ok\n"); + else + printf(" Failed (crc=0x%08x)\n", computed_crc); + + /* elf construction */ + elf_add_load_section(&elf, load->addr, load->len, + &buf[pos + sizeof(struct sb_instruction_load_t)]); + + pos += load->len + sizeof(struct sb_instruction_load_t); + // unsure about rounding + pos = ROUND_UP(pos, 16); + } + else if(hdr->opcode == SB_INST_FILL) + { + struct sb_instruction_fill_t *fill = (struct sb_instruction_fill_t *)&buf[pos]; + color(RED); + printf("FILL"); + color(OFF);printf(" | "); + color(BLUE); + printf("addr=0x%08x", fill->addr); + color(OFF);printf(" | "); + color(GREEN); + printf("len=0x%08x", fill->len); + color(OFF);printf(" | "); + color(YELLOW); + printf("pattern=0x%08x\n", fill->pattern); + color(OFF); + + /* elf construction */ + elf_add_fill_section(&elf, fill->addr, fill->len, fill->pattern); + + pos += sizeof(struct sb_instruction_fill_t); + // fixme: useless as pos is a multiple of 16 and fill struct is 4-bytes wide ? + pos = ROUND_UP(pos, 16); + } + else if(hdr->opcode == SB_INST_CALL || + hdr->opcode == SB_INST_JUMP) + { + int is_call = (hdr->opcode == SB_INST_CALL); + struct sb_instruction_call_t *call = (struct sb_instruction_call_t *)&buf[pos]; + color(RED); + if(is_call) + printf("CALL"); + else + printf("JUMP"); + color(OFF);printf(" | "); + color(BLUE); + printf("addr=0x%08x", call->addr); + color(OFF);printf(" | "); + color(GREEN); + printf("arg=0x%08x\n", call->arg); + color(OFF); + + /* elf construction */ + elf_set_start_addr(&elf, call->addr); + extract_elf_section(&elf, elf_count++, filename, indent); + elf_release(&elf); + elf_init(&elf); + + pos += sizeof(struct sb_instruction_call_t); + // fixme: useless as pos is a multiple of 16 and call struct is 4-bytes wide ? + pos = ROUND_UP(pos, 16); + } + else + { + color(RED); + printf("Unknown instruction %d at address 0x%08lx\n", hdr->opcode, (unsigned long)pos); + break; + } + } + + if(!elf_is_empty(&elf)) + extract_elf_section(&elf, elf_count++, filename, indent); + elf_release(&elf); +} + +static void extract(unsigned long filesize) +{ + struct sha_1_params_t sha_1_params; + /* Basic header info */ + struct sb_header_t *sb_header = (struct sb_header_t *)g_buf; + + if(memcmp(sb_header->signature, "STMP", 4) != 0) + bugp("Bad signature"); + if(sb_header->image_size * BLOCK_SIZE != filesize) + bugp("File size mismatch"); + if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t)) + bugp("Bad header size"); + if(sb_header->major_ver != IMAGE_MAJOR_VERSION || + sb_header->minor_ver != IMAGE_MINOR_VERSION) + bugp("Bad file format version"); + if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t)) + bugp("Bad section header size"); + + color(BLUE); + printf("Basic info:\n"); + color(GREEN); + printf(" Header SHA-1: "); + byte *hdr_sha1 = sb_header->sha1_header; + color(YELLOW); + print_hex(hdr_sha1, 20, false); + /* Check SHA1 sum */ + byte computed_sha1[20]; + sha_1_init(&sha_1_params); + sha_1_update(&sha_1_params, &sb_header->signature[0], + sizeof(struct sb_header_t) - sizeof(sb_header->sha1_header)); + sha_1_finish(&sha_1_params); + sha_1_output(&sha_1_params, computed_sha1); + color(RED); + if(memcmp(hdr_sha1, computed_sha1, 20) == 0) + printf(" Ok\n"); + else + printf(" Failed\n"); + color(GREEN); + printf(" Flags: "); + color(YELLOW); + printf("%x\n", sb_header->flags); + color(GREEN); + printf(" Total file size : "); + color(YELLOW); + printf("%ld\n", filesize); + + /* Sizes and offsets */ + color(BLUE); + printf("Sizes and offsets:\n"); + color(GREEN); + printf(" # of encryption keys = "); + color(YELLOW); + printf("%d\n", sb_header->nr_keys); + color(GREEN); + printf(" # of sections = "); + color(YELLOW); + printf("%d\n", sb_header->nr_sections); + + /* Versions */ + color(BLUE); + printf("Versions\n"); + color(GREEN); + + printf(" Random 1: "); + color(YELLOW); + print_hex(sb_header->rand_pad0, sizeof(sb_header->rand_pad0), true); + color(GREEN); + printf(" Random 2: "); + color(YELLOW); + print_hex(sb_header->rand_pad1, sizeof(sb_header->rand_pad1), true); + + uint64_t micros = sb_header->timestamp; + time_t seconds = (micros / (uint64_t)1000000L); + struct tm tm_base = {0, 0, 0, 1, 0, 100, 0, 0, 1, 0, NULL}; /* 2000/1/1 0:00:00 */ + seconds += mktime(&tm_base); + struct tm *time = gmtime(&seconds); + color(GREEN); + printf(" Creation date/time = "); + color(YELLOW); + printf("%s", asctime(time)); + + color(GREEN); + printf(" Product version = "); + color(YELLOW); + printf("%X.%X.%X\n", sb_header->product_ver.major, + sb_header->product_ver.minor, sb_header->product_ver.revision); + color(GREEN); + printf(" Component version = "); + color(YELLOW); + printf("%X.%X.%X\n", sb_header->component_ver.major, + sb_header->component_ver.minor, sb_header->component_ver.revision); + + /* encryption cbc-mac */ + key_array_t keys = NULL; /* array of 16-bytes keys */ + byte real_key[16]; + if(sb_header->nr_keys > 0) + { + keys = read_keys(sb_header->nr_keys); + color(BLUE); + printf("Encryption data\n"); + for(int i = 0; i < sb_header->nr_keys; i++) + { + color(RED); + printf(" Key %d: ", i); + print_hex(keys[i], 16, true); + color(GREEN); + printf(" CBC-MAC of headers: "); + + uint32_t ofs = sizeof(struct sb_header_t) + + sizeof(struct sb_section_header_t) * sb_header->nr_sections + + sizeof(struct sb_key_dictionary_entry_t) * i; + struct sb_key_dictionary_entry_t *dict_entry = + (struct sb_key_dictionary_entry_t *)&g_buf[ofs]; + /* cbc mac */ + color(YELLOW); + print_hex(dict_entry->hdr_cbc_mac, 16, false); + /* check it */ + byte computed_cbc_mac[16]; + byte zero[16]; + memset(zero, 0, 16); + cbc_mac(g_buf, NULL, sb_header->header_size + sb_header->nr_sections, + keys[i], zero, &computed_cbc_mac, 1); + color(RED); + if(memcmp(dict_entry->hdr_cbc_mac, computed_cbc_mac, 16) == 0) + printf(" Ok\n"); + else + printf(" Failed\n"); + color(GREEN); + + printf(" Encrypted key : "); + color(YELLOW); + print_hex(dict_entry->key, 16, true); + color(GREEN); + /* decrypt */ + byte decrypted_key[16]; + byte iv[16]; + memcpy(iv, g_buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ + cbc_mac(dict_entry->key, decrypted_key, 1, keys[i], iv, NULL, 0); + printf(" Decrypted key : "); + color(YELLOW); + print_hex(decrypted_key, 16, false); + /* cross-check or copy */ + if(i == 0) + memcpy(real_key, decrypted_key, 16); + else if(memcmp(real_key, decrypted_key, 16) == 0) + { + color(RED); + printf(" Cross-Check Ok"); + } + else + { + color(RED); + printf(" Cross-Check Failed"); + } + printf("\n"); + } + } + + /* sections */ + color(BLUE); + printf("Sections\n"); + + for(int i = 0; i < sb_header->nr_sections; i++) + { + uint32_t ofs = sb_header->header_size * BLOCK_SIZE + i * sizeof(struct sb_section_header_t); + struct sb_section_header_t *sec_hdr = (struct sb_section_header_t *)&g_buf[ofs]; + + char name[5]; + name[0] = (sec_hdr->identifier >> 24) & 0xff; + name[1] = (sec_hdr->identifier >> 16) & 0xff; + name[2] = (sec_hdr->identifier >> 8) & 0xff; + name[3] = sec_hdr->identifier & 0xff; + for(int i = 0; i < 4; i++) + if(!isprint(name[i])) + name[i] = '_'; + name[4] = 0; + int pos = sec_hdr->offset * BLOCK_SIZE; + int size = sec_hdr->size * BLOCK_SIZE; + int data_sec = !(sec_hdr->flags & SECTION_BOOTABLE); + int encrypted = !(sec_hdr->flags & SECTION_CLEARTEXT); + + color(GREEN); + printf(" Chunk "); + color(YELLOW); + printf("'%s'\n", name); + color(GREEN); + printf(" pos = "); + color(YELLOW); + printf("%8x - %8x\n", pos, pos+size); + color(GREEN); + printf(" len = "); + color(YELLOW); + printf("%8x\n", size); + color(GREEN); + printf(" flags = "); + color(YELLOW); + printf("%8x", sec_hdr->flags); + color(RED); + if(data_sec) + printf(" Data Section"); + else + printf(" Boot Section"); + if(encrypted) + printf(" (Encrypted)"); + printf("\n"); + + /* save it */ + byte *sec = xmalloc(size); + if(encrypted) + cbc_mac(g_buf + pos, sec, size / BLOCK_SIZE, real_key, g_buf, NULL, 0); + else + memcpy(sec, g_buf + pos, size); + + extract_section(data_sec, name, sec, size, " "); + free(sec); + } + + /* final signature */ + color(BLUE); + printf("Final signature:\n"); + color(GREEN); + printf(" Encrypted signature:\n"); + color(YELLOW); + byte *encrypted_block = &g_buf[filesize - 32]; + printf(" "); + print_hex(encrypted_block, 16, true); + printf(" "); + print_hex(encrypted_block + 16, 16, true); + /* decrypt it */ + byte decrypted_block[32]; + cbc_mac(encrypted_block, decrypted_block, 2, real_key, g_buf, NULL, 0); + color(GREEN); + printf(" Decrypted SHA-1:\n "); + color(YELLOW); + print_hex(decrypted_block, 20, false); + /* check it */ + sha_1_init(&sha_1_params); + sha_1_update(&sha_1_params, g_buf, filesize - 32); + sha_1_finish(&sha_1_params); + sha_1_output(&sha_1_params, computed_sha1); + color(RED); + if(memcmp(decrypted_block, computed_sha1, 20) == 0) + printf(" Ok\n"); + else + printf(" Failed\n"); +} + +int main(int argc, const char **argv) +{ + int fd; + struct stat st; + if(argc != 3 && argc != 4) + bug("Usage: %s []\n",*argv); + + if(argc == 4) + snprintf(out_prefix, PREFIX_SIZE, "%s", argv[3]); + else + strcpy(out_prefix, ""); + + if( (fd = open(argv[1], O_RDONLY)) == -1 ) + bugp("opening firmware failed"); + + key_file = argv[2]; + + if(fstat(fd, &st) == -1) + bugp("firmware stat() failed"); + g_sz = st.st_size; + + g_buf = xmalloc(g_sz); + if(read(fd, g_buf, g_sz) != (ssize_t)g_sz) /* load the whole file into memory */ + bugp("reading firmware"); + + close(fd); + + extract(st.st_size); + + color(OFF); + + free(g_buf); + return 0; +} diff --git a/utils/sbtools/sha1.c b/utils/sbtools/sha1.c new file mode 100644 index 0000000000..99657fb14a --- /dev/null +++ b/utils/sbtools/sha1.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +/* Based on http://en.wikipedia.org/wiki/SHA-1 */ +#include "crypto.h" + +static uint32_t rot_left(uint32_t val, int rot) +{ + return (val << rot) | (val >> (32 - rot)); +} + +static inline void byte_swapxx(byte *ptr, int size) +{ + for(int i = 0; i < size / 2; i++) + { + byte c = ptr[i]; + ptr[i] = ptr[size - i - 1]; + ptr[size - i - 1] = c; + } +} + +static void byte_swap32(uint32_t *v) +{ + byte_swapxx((byte *)v, 4); +} + +void sha_1_init(struct sha_1_params_t *params) +{ + params->hash[0] = 0x67452301; + params->hash[1] = 0xEFCDAB89; + params->hash[2] = 0x98BADCFE; + params->hash[3] = 0x10325476; + params->hash[4] = 0xC3D2E1F0; + params->buffer_nr_bits = 0; +} + +void sha_1_update(struct sha_1_params_t *params, byte *buffer, int size) +{ + int buffer_nr_bytes = (params->buffer_nr_bits / 8) % 64; + params->buffer_nr_bits += 8 * size; + int pos = 0; + if(buffer_nr_bytes + size >= 64) + { + pos = 64 - buffer_nr_bytes; + memcpy((byte *)(params->w) + buffer_nr_bytes, buffer, 64 - buffer_nr_bytes); + sha_1_block(params, params->hash, (byte *)params->w); + for(; pos + 64 <= size; pos += 64) + sha_1_block(params, params->hash, buffer + pos); + buffer_nr_bytes = 0; + } + memcpy((byte *)(params->w) + buffer_nr_bytes, buffer + pos, size - pos); +} + +void sha_1_finish(struct sha_1_params_t *params) +{ + /* length (in bits) in big endian BEFORE preprocessing */ + byte length_big_endian[8]; + memcpy(length_big_endian, ¶ms->buffer_nr_bits, 8); + byte_swapxx(length_big_endian, 8); + /* append '1' and then '0's to the message to get 448 bit length for the last block */ + byte b = 0x80; + sha_1_update(params, &b, 1); + b = 0; + while((params->buffer_nr_bits % 512) != 448) + sha_1_update(params, &b, 1); + /* append length */ + sha_1_update(params, length_big_endian, 8); + /* go back to big endian */ + for(int i = 0; i < 5; i++) + byte_swap32(¶ms->hash[i]); +} + +void sha_1_output(struct sha_1_params_t *params, byte *out) +{ + memcpy(out, params->hash, 20); +} + +void sha_1_block(struct sha_1_params_t *params, uint32_t cur_hash[5], byte *data) +{ + uint32_t a, b, c, d, e; + a = cur_hash[0]; + b = cur_hash[1]; + c = cur_hash[2]; + d = cur_hash[3]; + e = cur_hash[4]; + + #define w params->w + + memcpy(w, data, 64); + for(int i = 0; i < 16; i++) + byte_swap32(&w[i]); + + for(int i = 16; i <= 79; i++) + w[i] = rot_left(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); + + for(int i = 0; i<= 79; i++) + { + uint32_t f, k; + if(i <= 19) + { + f = (b & c) | ((~b) & d); + k = 0x5A827999; + } + else if(i <= 39) + { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } + else if(i <= 59) + { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } + else + { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + uint32_t temp = rot_left(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = rot_left(b, 30); + b = a; + a = temp; + } + #undef w + + cur_hash[0] += a; + cur_hash[1] += b; + cur_hash[2] += c; + cur_hash[3] += d; + cur_hash[4] += e; +} -- cgit v1.2.3