fusee: fix support for mariko key derivation/package1 parsing
This commit is contained in:
@@ -13,15 +13,43 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include "../../../fusee/common/log.h"
|
||||
#include "package1.h"
|
||||
#include "bct.h"
|
||||
#include "se.h"
|
||||
|
||||
static const uint8_t custom_public_key[0x100] = {
|
||||
0x59, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
|
||||
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0xFF,
|
||||
};
|
||||
|
||||
static bool is_custom_public_key_erista(const void *bct) {
|
||||
return memcmp((const uint8_t *)bct + 0x210, custom_public_key, sizeof(custom_public_key)) == 0;
|
||||
}
|
||||
|
||||
//static bool is_custom_public_key_mariko(const void *bct) {
|
||||
// return memcmp((const uint8_t *)bct + 0x10, custom_public_key, sizeof(custom_public_key)) == 0;
|
||||
//}
|
||||
|
||||
int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0) {
|
||||
nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */
|
||||
nv_bootloader_info *pk1l_info; /* TODO: check? */
|
||||
@@ -50,6 +78,19 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
|
||||
free(bct);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If custom public key, use bct-2 instead of bct 0. */
|
||||
if (is_custom_public_key_erista(bct)) {
|
||||
if (fseek(boot0, fpos + 0x4000 * 2, SEEK_SET) != 0) {
|
||||
free(bct);
|
||||
return -1;
|
||||
}
|
||||
if (fread(bct, sizeof(nvboot_config_table), 1, boot0) == 0) {
|
||||
free(bct);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bct->bootloader_used < 1 || pk1l_info->version < 1) {
|
||||
free(bct);
|
||||
errno = EILSEQ;
|
||||
@@ -91,7 +132,59 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1
|
||||
}
|
||||
|
||||
int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, FILE *boot0) {
|
||||
/* TODO */
|
||||
/* TODO: Actually parse BOOT0 to locate package1ldr. */
|
||||
size_t fpos, pk1l_offset;
|
||||
|
||||
fpos = ftell(boot0);
|
||||
pk1l_offset = 0x100000;
|
||||
|
||||
/* Read the OEM header. */
|
||||
pk11_mariko_oem_header_t oem_header;
|
||||
if (fseek(boot0, fpos + pk1l_offset, SEEK_SET) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (fread(&oem_header, sizeof(oem_header), 1, boot0) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Sanity check the size. */
|
||||
if (oem_header.bl_size < 2 * sizeof(package1loader_header_t)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the size. */
|
||||
*package1loader_size = oem_header.bl_size;
|
||||
|
||||
/* Allocate pk11. */
|
||||
(*package1loader) = memalign(0x10000, *package1loader_size);
|
||||
|
||||
if (*package1loader == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read pk11. */
|
||||
if (fread(*package1loader, *package1loader_size, 1, boot0) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the plaintext header. */
|
||||
package1loader_header_t dec_header;
|
||||
memcpy(&dec_header, *package1loader, sizeof(dec_header));
|
||||
|
||||
/* Decrypt the binary. */
|
||||
const uint8_t __attribute__((aligned(16))) iv[16] = {0};
|
||||
se_aes_128_cbc_decrypt(KEYSLOT_SWITCH_BEK_MARIKO, *package1loader, *package1loader_size, *package1loader, *package1loader_size, iv);
|
||||
|
||||
/* Validate the decryption. */
|
||||
if (memcmp(&dec_header, (const uint8_t *)*package1loader + sizeof(dec_header), sizeof(dec_header)) != 0) {
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Decrypted package1loader is invalid...\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy out the first header. */
|
||||
memcpy(*package1loader, &dec_header, sizeof(dec_header));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -106,7 +199,7 @@ bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t pac
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -129,7 +222,7 @@ bool package1_decrypt(package1_header_t *package1, size_t package1_size, const u
|
||||
}
|
||||
|
||||
void *package1_get_warmboot_fw(const package1_header_t *package1) {
|
||||
/*
|
||||
/*
|
||||
The layout of pk1 changes between versions.
|
||||
|
||||
However, the secmon always starts by this erratum code:
|
||||
|
||||
Reference in New Issue
Block a user