diff --git a/fusee/fusee-secondary/src/package1.c b/fusee/fusee-secondary/src/package1.c new file mode 100644 index 000000000..44e7c5dbb --- /dev/null +++ b/fusee/fusee-secondary/src/package1.c @@ -0,0 +1,64 @@ +#include +#include +#include "package1.h" +#include "bct.h" + +int package1_parse_boot0(void **package1, size_t *package1_size, nx_keyblob_t *keyblobs, uint32_t *version, FILE *boot0) { + static nvboot_config_table bct = {0}; /* Normal firmware BCT, primary. TODO: check? */ + nv_bootloader_info *pk1_info = &bct.bootloader[0]; /* TODO: check? */ + + size_t fpos, pk1_offset; + + if (package1 == NULL || package1_size != NULL || keyblobs == NULL || version == NULL || boot0 == NULL) { + errno = EINVAL; + return -1; + } + + fpos = ftell(boot0); + + /* Read the BCT. */ + if (fread(&bct, sizeof(nvboot_config_table), 1, boot0) == 0) { + return -1; + } + if (bct.bootloader_used < 1) { + errno = EILSEQ; + return -1; + } + + *version = pk1_info->attribute; + *package1_size = pk1_info->length; + + pk1_offset = 0x4000 * pk1_info->start_blk + 0x200 * pk1_info->start_page; + + (*package1) = malloc(*package1_size); + + if (*package1 == NULL) { + errno = ENOMEM; + return -1; + } + + /* Read the pk1/pk1l. */ + if (fseek(boot0, fpos + pk1_offset, SEEK_SET) != 0) { + return -1; + } + if (fread(*package1, *package1_size, 1, boot0) == 0) { + return -1; + } + + /* Skip the backup pk1/pk1l. */ + if (fseek(boot0, *package1_size, SEEK_CUR) != 0) { + return -1; + } + + /* Read the full keyblob area.*/ + for (size_t i = 0; i < 32; i++) { + if (fread(&keyblobs[i], sizeof(nx_keyblob_t), 1, boot0) == 0) { + return -1; + } + if (fseek(boot0, 0x200 - sizeof(nx_keyblob_t), SEEK_CUR)) { + return -1; + } + } + + return 0; +} diff --git a/fusee/fusee-secondary/src/package1.h b/fusee/fusee-secondary/src/package1.h new file mode 100644 index 000000000..cdd18183c --- /dev/null +++ b/fusee/fusee-secondary/src/package1.h @@ -0,0 +1,9 @@ +#ifndef FUSEE_PACKAGE1_H +#define FUSEE_PACKAGE1_H + +#include +#include "key_derivation.h" + +int package1_parse_boot0(void **package1, size_t *package1_size, nx_keyblob_t *keyblobs, uint32_t *version, FILE *boot0); + +#endif