keys: Use accurate logic for eticket keypair read

This commit is contained in:
shchmue 2022-02-09 10:54:01 -07:00
parent 54ed439cce
commit 64a6491309
5 changed files with 47 additions and 9 deletions

View file

@ -102,6 +102,27 @@ void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops)
base[ops[i].off] = ops[i].val; base[ops[i].off] = ops[i].val;
} }
u16 crc16_calc(const u8 *buf, u32 len)
{
const u8 *p, *q;
u16 crc = 0x55aa;
static u16 table[16] = {
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
};
q = buf + len;
for (p = buf; p < q; p++)
{
u8 oct = *p;
crc = (crc >> 4) ^ table[crc & 0xf] ^ table[(oct >> 0) & 0xf];
crc = (crc >> 4) ^ table[crc & 0xf] ^ table[(oct >> 4) & 0xf];
}
return crc;
}
u32 crc32_calc(u32 crc, const u8 *buf, u32 len) u32 crc32_calc(u32 crc, const u8 *buf, u32 len)
{ {
const u8 *p, *q; const u8 *p, *q;

View file

@ -83,6 +83,7 @@ u8 bit_count(u32 val);
u32 bit_count_mask(u8 bits); u32 bit_count_mask(u8 bits);
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
u16 crc16_calc(const u8 *buf, u32 len);
u32 crc32_calc(u32 crc, const u8 *buf, u32 len); u32 crc32_calc(u32 crc, const u8 *buf, u32 len);
u32 get_tmr_us(); u32 get_tmr_us();

View file

@ -461,8 +461,23 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
return false; return false;
} }
u32 keypair_generation = 0;
const void *eticket_device_key = NULL;
const void *eticket_iv = NULL;
if (cal0->ext_ecc_rsa2048_eticket_key_crc == crc16_calc(cal0->ext_ecc_rsa2048_eticket_key_iv, 0x24E)) {
eticket_device_key = cal0->ext_ecc_rsa2048_eticket_key;
eticket_iv = cal0->ext_ecc_rsa2048_eticket_key_iv;
// settings sysmodule manually zeroes this out below cal version 9 // settings sysmodule manually zeroes this out below cal version 9
u32 keypair_generation = cal0->version <= 8 ? 0 : cal0->ext_ecc_rsa2048_eticket_key_ver; keypair_generation = cal0->version <= 8 ? 0 : cal0->ext_ecc_rsa2048_eticket_key_ver;
} else if (cal0->rsa2048_eticket_key_crc == crc16_calc(cal0->rsa2048_eticket_key_iv, 0x22E)) {
eticket_device_key = cal0->rsa2048_eticket_key;
eticket_iv = cal0->rsa2048_eticket_key_iv;
} else {
EPRINTF("Crc16 error reading device key.");
return false;
}
if (keypair_generation) { if (keypair_generation) {
keypair_generation--; keypair_generation--;
@ -478,7 +493,7 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
} }
se_aes_key_set(6, keys->temp_key, sizeof(keys->temp_key)); se_aes_key_set(6, keys->temp_key, sizeof(keys->temp_key));
se_aes_crypt_ctr(6, &rsa_keypair, sizeof(rsa_keypair), cal0->ext_ecc_rsa2048_eticket_key, sizeof(cal0->ext_ecc_rsa2048_eticket_key), cal0->ext_ecc_rsa2048_eticket_key_iv); se_aes_crypt_ctr(6, &rsa_keypair, sizeof(rsa_keypair), eticket_device_key, sizeof(rsa_keypair), eticket_iv);
// Check public exponent is 65537 big endian // Check public exponent is 65537 big endian
if (_read_be_u32(rsa_keypair.public_exponent, 0) != 65537) { if (_read_be_u32(rsa_keypair.public_exponent, 0) != 65537) {

View file

@ -67,9 +67,7 @@ typedef struct {
u8 private_exponent[RSA_2048_KEY_SIZE]; u8 private_exponent[RSA_2048_KEY_SIZE];
u8 modulus[RSA_2048_KEY_SIZE]; u8 modulus[RSA_2048_KEY_SIZE];
u8 public_exponent[4]; u8 public_exponent[4];
u8 reserved[0x14]; u8 reserved[0xC];
u64 device_id;
u8 gmac[0x10];
} rsa_keypair_t; } rsa_keypair_t;
typedef struct { typedef struct {

View file

@ -124,8 +124,10 @@ typedef struct _nx_emmc_cal0_t
u8 crc16_pad20[0x10]; u8 crc16_pad20[0x10];
u8 gc_cert[0x400]; u8 gc_cert[0x400];
u8 gc_cert_sha256[0x20]; u8 gc_cert_sha256[0x20];
u8 rsa2048_eticket_key[0x220]; u8 rsa2048_eticket_key_iv[0x10];
u8 crc16_pad21[0x10]; u8 rsa2048_eticket_key[0x210];
u8 crc16_pad21[0xE];
u16 rsa2048_eticket_key_crc;
u8 rsa2048_eticket_cert[0x240]; u8 rsa2048_eticket_cert[0x240];
u8 crc16_pad22[0x10]; u8 crc16_pad22[0x10];
@ -166,7 +168,8 @@ typedef struct _nx_emmc_cal0_t
u8 ext_ecc_rsa2048_eticket_key_iv[0x10]; u8 ext_ecc_rsa2048_eticket_key_iv[0x10];
u8 ext_ecc_rsa2048_eticket_key[0x230]; u8 ext_ecc_rsa2048_eticket_key[0x230];
u32 ext_ecc_rsa2048_eticket_key_ver; u32 ext_ecc_rsa2048_eticket_key_ver;
u8 crc16_pad38[0xC]; u8 crc16_pad38[0xA];
u16 ext_ecc_rsa2048_eticket_key_crc;
u8 ext_ssl_key[0x130]; u8 ext_ssl_key[0x130];
u8 crc16_pad39[0x10]; u8 crc16_pad39[0x10];
u8 ext_gc_key[0x130]; u8 ext_gc_key[0x130];