1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Amaury Pouly 2011-04-17 01:43:44 +00:00
parent 02118edb99
commit f6208bde46
10 changed files with 0 additions and 0 deletions

9
utils/sbtools/Makefile Normal file
View file

@ -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)

284
utils/sbtools/aes128.c Normal file
View file

@ -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<n;i++)
a[i] ^= b[i];
}
// Xor the current cipher state by a specific round key
static void xor_round_key(byte *state, byte *keys, int round) {
xor_(state,keys+round*16,16);
}
// Apply and reverse the rijndael s-box to all elements in an array
// http://en.wikipedia.org/wiki/Rijndael_S-box
static void sub_bytes(byte *a,int n) {
int i;
for (i=0;i<n;i++)
a[i] = lookup_sbox[a[i]];
}
static void sub_bytes_inv(byte *a,int n) {
int i;
for (i=0;i<n;i++)
a[i] = lookup_sbox_inv[a[i]];
}
// Perform the core key schedule transform on 4 bytes, as part of the key expansion process
// http://en.wikipedia.org/wiki/Rijndael_key_schedule#Key_schedule_core
static void key_schedule_core(byte *a, int i) {
byte temp = a[0]; // Rotate the output eight bits to the left
a[0]=a[1];
a[1]=a[2];
a[2]=a[3];
a[3]=temp;
sub_bytes(a,4); // Apply Rijndael's S-box on all four individual bytes in the output word
a[0]^=lookup_rcon[i]; // On just the first (leftmost) byte of the output word, perform the rcon operation with i
// as the input, and exclusive or the rcon output with the first byte of the output word
}
// Expand the 16-byte key to 11 round keys (176 bytes)
// http://en.wikipedia.org/wiki/Rijndael_key_schedule#The_key_schedule
static void expand_key(byte *key, byte *keys) {
int bytes=16; // The count of how many bytes we've created so far
int i=1; // The rcon iteration value i is set to 1
int j; // For repeating the second stage 3 times
byte t[4]; // Temporary working area known as 't' in the Wiki article
memcpy(keys,key,16); // The first 16 bytes of the expanded key are simply the encryption key
while (bytes<176) { // Until we have 176 bytes of expanded key, we do the following:
memcpy(t,keys+bytes-4,4); // We assign the value of the previous four bytes in the expanded key to t
key_schedule_core(t, i); // We perform the key schedule core on t, with i as the rcon iteration value
i++; // We increment i by 1
xor_(t,keys+bytes-16,4); // We exclusive-or t with the four-byte block 16 bytes before the new expanded key.
memcpy(keys+bytes,t,4); // This becomes the next 4 bytes in the expanded key
bytes+=4; // Keep track of how many expanded key bytes we've added
// We then do the following three times to create the next twelve bytes
for (j=0;j<3;j++) {
memcpy(t,keys+bytes-4,4); // We assign the value of the previous 4 bytes in the expanded key to t
xor_(t,keys+bytes-16,4); // We exclusive-or t with the four-byte block n bytes before
memcpy(keys+bytes,t,4); // This becomes the next 4 bytes in the expanded key
bytes+=4; // Keep track of how many expanded key bytes we've added
}
}
}
// Apply / reverse the shift rows step on the 16 byte cipher state
// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard#The_ShiftRows_step
static void shift_rows(byte *state) {
int i;
byte temp[16];
memcpy(temp,state,16);
for (i=0;i<16;i++)
state[i]=temp[shift_rows_table[i]];
}
static void shift_rows_inv(byte *state) {
int i;
byte temp[16];
memcpy(temp,state,16);
for (i=0;i<16;i++)
state[i]=temp[shift_rows_table_inv[i]];
}
// Perform the mix columns matrix on one column of 4 bytes
// http://en.wikipedia.org/wiki/Rijndael_mix_columns
static void mix_col (byte *state) {
byte a0 = state[0];
byte a1 = state[1];
byte a2 = state[2];
byte a3 = state[3];
state[0] = lookup_g2[a0] ^ lookup_g3[a1] ^ a2 ^ a3;
state[1] = lookup_g2[a1] ^ lookup_g3[a2] ^ a3 ^ a0;
state[2] = lookup_g2[a2] ^ lookup_g3[a3] ^ a0 ^ a1;
state[3] = lookup_g2[a3] ^ lookup_g3[a0] ^ a1 ^ a2;
}
// Perform the mix columns matrix on each column of the 16 bytes
static void mix_cols (byte *state) {
mix_col(state);
mix_col(state+4);
mix_col(state+8);
mix_col(state+12);
}
// Perform the inverse mix columns matrix on one column of 4 bytes
// http://en.wikipedia.org/wiki/Rijndael_mix_columns
static void mix_col_inv (byte *state) {
byte a0 = state[0];
byte a1 = state[1];
byte a2 = state[2];
byte a3 = state[3];
state[0] = lookup_g14[a0] ^ lookup_g9[a3] ^ lookup_g13[a2] ^ lookup_g11[a1];
state[1] = lookup_g14[a1] ^ lookup_g9[a0] ^ lookup_g13[a3] ^ lookup_g11[a2];
state[2] = lookup_g14[a2] ^ lookup_g9[a1] ^ lookup_g13[a0] ^ lookup_g11[a3];
state[3] = lookup_g14[a3] ^ lookup_g9[a2] ^ lookup_g13[a1] ^ lookup_g11[a0];
}
// Perform the inverse mix columns matrix on each column of the 16 bytes
static void mix_cols_inv (byte *state) {
mix_col_inv(state);
mix_col_inv(state+4);
mix_col_inv(state+8);
mix_col_inv(state+12);
}
// Encrypt a single 128 bit block by a 128 bit key using AES
// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
void EncryptAES(byte *msg, byte *key, byte *c) {
int i; // To count the rounds
// Key expansion
byte keys[176];
expand_key(key,keys);
// First Round
memcpy(c, msg, 16);
xor_round_key(c,keys,0);
// Middle rounds
for(i=0; i<9; i++) {
sub_bytes(c,16);
shift_rows(c);
mix_cols(c);
xor_round_key(c, keys, i+1);
}
// Final Round
sub_bytes(c,16);
shift_rows(c);
xor_round_key(c, keys, 10);
}
// Decrypt a single 128 bit block by a 128 bit key using AES
// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
void DecryptAES(byte *c, byte *key, byte *m) {
int i; // To count the rounds
// Key expansion
byte keys[176];
expand_key(key,keys);
// Reverse the final Round
memcpy(m,c,16);
xor_round_key(m,keys,10);
shift_rows_inv(m);
sub_bytes_inv(m, 16);
// Reverse the middle rounds
for (i=0; i<9; i++) {
xor_round_key(m,keys,9-i);
mix_cols_inv(m);
shift_rows_inv(m);
sub_bytes_inv(m, 16);
}
// Reverse the first Round
xor_round_key(m, keys, 0);
}
/*
// Pretty-print a key (or any smallish buffer) onto screen as hex
void Pretty(byte* b,int len,const char* label)
{
char out[100];
int i;
for (i=0;i<len;i++)
sprintf(out+i*2,"%02x",b[i]);
printf("%s%s",label, out);
}
*/
/*
// Test AES
int main(void)
{
byte key[] = {0x12,0x34,0x56,0x12,0x34,0x56,0x12,0x34,0x56,0x12,0x34,0x56,0x12,0x34,0x56,0x12};
byte msg[] = {0xab,0xcd,0xef,0xab,0xcd,0xef,0xab,0xcd,0xef,0xab,0xcd,0xef,0xab,0xcd,0xef,0xab};
byte encrypted[16], decrypted[16];
printf("Test AES\r\n\n");
Pretty(key,16,"Key: ");
Pretty(msg,16,"Original: ");
EncryptAES(msg,key,encrypted);
printf("Encrypted should be: 85E5A3D7356A61E29A8AFA559AD67102\r\n");
Pretty(encrypted,16,"Encrypted: ");
DecryptAES(encrypted,key,decrypted);
Pretty(decrypted,16,"Decrypted: ");
return 0;
}
*/
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 */
)
{
byte feedback[16];
memcpy(feedback, iv, 16);
if(encrypt)
{
/* for each block */
for(int i = 0; i < nr_blocks; i++)
{
/* xor it with feedback */
xor_(feedback, &in_data[i * 16], 16);
/* encrypt it using aes */
EncryptAES(feedback, key, feedback);
/* write cipher to output */
if(out_data)
memcpy(&out_data[i * 16], feedback, 16);
}
if(out_cbc_mac)
memcpy(out_cbc_mac, feedback, 16);
}
else
{
/* nothing to do ? */
if(out_data == NULL)
return;
/* for each block */
for(int i = 0; i < nr_blocks; i++)
{
/* decrypt it using aes */
DecryptAES(&in_data[i * 16], key, &out_data[i * 16]);
/* xor it with iv */
xor_(&out_data[i * 16], feedback, 16);
/* copy cipher to iv */
memcpy(feedback, &in_data[i * 16], 16);
}
}
}

78
utils/sbtools/crc.c Normal file
View file

@ -0,0 +1,78 @@
/***************************************************************************
* __________ __ ___.
* 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 "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;
}

57
utils/sbtools/crypto.h Normal file
View file

@ -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 <stdio.h>
#include <stdint.h>
#include <string.h>
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);

237
utils/sbtools/elf.c Normal file
View file

@ -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;
}

179
utils/sbtools/elf.h Normal file
View file

@ -0,0 +1,179 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
/**
* 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;
/* <union> */
void *section;
uint32_t pattern;
/* </union> */
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);

View file

@ -0,0 +1 @@
00000000000000000000000000000000

118
utils/sbtools/sb.h Normal file
View file

@ -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 <sys/types.h>
#include <sys/stat.h>
#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));

596
utils/sbtools/sbtoelf.c Normal file
View file

@ -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é <rafael.carre@gmail.com>
*/
#define _ISOC99_SOURCE /* snprintf() */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#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 <firmware> <key file> [<out prefix>]\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;
}

150
utils/sbtools/sha1.c Normal file
View file

@ -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, &params->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(&params->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;
}