Allow hardcoding keys

... the required file will not be provided
This commit is contained in:
d0k3 2017-08-09 01:39:23 +02:00
parent 96054a8406
commit a9badfee9c
4 changed files with 70 additions and 37 deletions

3
.gitignore vendored
View File

@ -36,4 +36,7 @@
/build /build
/output /output
/release /release
# User additions
/data/aeskeydb.bin
/zzz_backup /zzz_backup

View File

@ -58,6 +58,10 @@ ifeq ($(SWITCH_SCREENS),1)
CFLAGS += -DSWITCH_SCREENS CFLAGS += -DSWITCH_SCREENS
endif endif
ifneq ("$(wildcard $(CURDIR)/data/aeskeydb.bin)","")
CFLAGS += -DHARDCODE_KEYS
endif
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH) ASFLAGS := -g $(ARCH)
@ -90,9 +94,11 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/gm9*.*))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/gm9*.*))) \
$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/aeskeydb.bin)))
ifeq ($(SAFEMODE),1) ifeq ($(SAFEMODE),1)
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/sm9*.*))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/sm9*.*))) \
$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/aeskeydb.bin)))
endif endif
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -178,6 +184,11 @@ $(OUTPUT).elf : $(OFILES)
# you need a rule like this for each extension you use as binary data # you need a rule like this for each extension you use as binary data
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%_qlz.h %.qlz.o: %.qlz %_qlz.h %.qlz.o: %.qlz
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
%_bin.h %.bin.o: %.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@echo $(notdir $<) @echo $(notdir $<)
@$(bin2o) @$(bin2o)

1
data/aeskeydb.bin.here Normal file
View File

@ -0,0 +1 @@
MD5: A5B28945A7C051D7A0CD18AF0E580D1B

View File

@ -2,6 +2,9 @@
#include "aes.h" #include "aes.h"
#include "sha.h" #include "sha.h"
#include "ff.h" #include "ff.h"
#ifdef HARDCODE_KEYS
#include "aeskeydb_bin.h"
#endif
typedef struct { typedef struct {
u8 slot; // keyslot, 0x00...0x39 u8 slot; // keyslot, 0x00...0x39
@ -109,6 +112,41 @@ u32 CheckKeySlot(u32 keyslot, char type)
return 1; return 1;
} }
u32 LoadKeyDb(const char* path_db, AesKeyInfo* keydb, u32 bsize) {
UINT fsize = 0;
FIL fp;
if (path_db) {
if (f_open(&fp, path_db, FA_READ | FA_OPEN_EXISTING) == FR_OK) {
if ((f_read(&fp, keydb, bsize, &fsize) != FR_OK) || (fsize >= bsize))
fsize = 0;
f_close(&fp);
}
} else {
#ifdef HARDCODE_KEYS
fsize = (aeskeydb_bin_size <= bsize) ? aeskeydb_bin_size : 0;
if (fsize) memcpy(keydb, aeskeydb_bin, aeskeydb_bin_size);
#else
// try to load aeskeydb.bin file
const char* base[] = { SUPPORT_PATHS };
for (u32 i = 0; i < (sizeof(base)/sizeof(char*)); i++) {
char path[64];
snprintf(path, 64, "%s/%s", base[i], KEYDB_NAME);
if (f_open(&fp, path, FA_READ | FA_OPEN_EXISTING) == FR_OK) {
if ((f_read(&fp, keydb, bsize, &fsize) != FR_OK) || (fsize >= bsize)) fsize = 0;
f_close(&fp);
break;
}
}
#endif
}
u32 nkeys = 0;
if (fsize && !(fsize % sizeof(AesKeyInfo)))
nkeys = fsize / sizeof(AesKeyInfo);
return nkeys;
}
u32 LoadKeyFromFile(void* key, u32 keyslot, char type, char* id) u32 LoadKeyFromFile(void* key, u32 keyslot, char type, char* id)
{ {
const char* base[] = { SUPPORT_PATHS }; const char* base[] = { SUPPORT_PATHS };
@ -126,26 +164,20 @@ u32 LoadKeyFromFile(void* key, u32 keyslot, char type, char* id)
if (!key) key = keystore; if (!key) key = keystore;
// try to get key from 'aeskeydb.bin' file // try to get key from 'aeskeydb.bin' file
for (u32 i = 0; !found && (i < (sizeof(base)/sizeof(char*))); i++) { AesKeyInfo* keydb = (AesKeyInfo*) TEMP_BUFFER;
FIL fp; u32 nkeys = LoadKeyDb(NULL, keydb, TEMP_BUFFER_SIZE);
char path[64]; for (u32 i = 0; i < nkeys; i++) {
AesKeyInfo info; AesKeyInfo* info = &(keydb[i]);
UINT btr; if (!((info->slot == keyslot) && (info->type == type) &&
snprintf(path, 64, "%s/%s", base[i], KEYDB_NAME); ((!id && !(info->id[0])) || (id && (strncmp(id, info->id, 10) == 0))) &&
if (f_open(&fp, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) continue; (!info->keyUnitType || (info->keyUnitType == GetUnitKeysType()))))
while ((f_read(&fp, &info, sizeof(AesKeyInfo), &btr) == FR_OK) && (btr == sizeof(AesKeyInfo))) { continue;
if ((info.slot == keyslot) && (info.type == type) &&
((!id && !(info.id[0])) || (id && (strncmp(id, info.id, 10) == 0))) &&
(!info.keyUnitType || (info.keyUnitType == GetUnitKeysType()))) {
found = true; found = true;
if (info.isEncrypted) if (info->isEncrypted)
CryptAesKeyInfo(&info); CryptAesKeyInfo(info);
memcpy(key, info.key, 16); memcpy(key, info->key, 16);
break; break;
} }
}
f_close(&fp);
}
// load legacy slot0x??Key?.bin file instead // load legacy slot0x??Key?.bin file instead
if (!found && (type != 'I')) { if (!found && (type != 'I')) {
@ -191,24 +223,10 @@ u32 InitKeyDb( void )
// use this to quickly initialize all applicable keys in aeskeydb.bin // use this to quickly initialize all applicable keys in aeskeydb.bin
static const u64 keyslot_whitelist = (1ull<<0x02)|(1ull<<0x03)|(1ull<<0x05)|(1ull<<0x18)|(1ull<<0x19)|(1ull<<0x1A)|(1ull<<0x1B)| static const u64 keyslot_whitelist = (1ull<<0x02)|(1ull<<0x03)|(1ull<<0x05)|(1ull<<0x18)|(1ull<<0x19)|(1ull<<0x1A)|(1ull<<0x1B)|
(1ull<<0x1C)|(1ull<<0x1D)|(1ull<<0x1E)|(1ull<<0x1F)|(1ull<<0x24)|(1ull<<0x25)|(1ull<<0x2F); (1ull<<0x1C)|(1ull<<0x1D)|(1ull<<0x1E)|(1ull<<0x1F)|(1ull<<0x24)|(1ull<<0x25)|(1ull<<0x2F);
AesKeyInfo* keydb = (AesKeyInfo*) (void*) TEMP_BUFFER;
u32 nkeys = 0;
// try to load aeskeydb.bin file // try to load aeskeydb.bin file
const char* base[] = { SUPPORT_PATHS }; AesKeyInfo* keydb = (AesKeyInfo*) (void*) TEMP_BUFFER;
for (u32 i = 0; !nkeys && (i < (sizeof(base)/sizeof(char*))); i++) { u32 nkeys = LoadKeyDb(NULL, keydb, TEMP_BUFFER_SIZE);
FIL fp;
UINT btr;
char path[64];
snprintf(path, 64, "%s/%s", base[i], KEYDB_NAME);
if (f_open(&fp, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) continue;
if ((f_read(&fp, keydb, TEMP_BUFFER_SIZE, &btr) == FR_OK) &&
(btr > 0) && (btr < TEMP_BUFFER_SIZE) && !(btr % sizeof(AesKeyInfo)))
nkeys = btr / sizeof(AesKeyInfo);
f_close(&fp);
}
// failed if arriving here with empty hands
if (!nkeys) return 1; if (!nkeys) return 1;
// apply all applicable keys // apply all applicable keys