mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
Fix SMC names.
This commit is contained in:
parent
663c446439
commit
330f8a0f8b
6 changed files with 52 additions and 53 deletions
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
#define CRYPTOUSECASE_AES 0
|
#define CRYPTOUSECASE_AES 0
|
||||||
#define CRYPTOUSECASE_RSAPRIVATE 1
|
#define CRYPTOUSECASE_RSAPRIVATE 1
|
||||||
#define CRYPTOUSECASE_RSAOAEP 2
|
#define CRYPTOUSECASE_SECUREEXPMOD 2
|
||||||
#define CRYPTOUSECASE_RSATICKET 3
|
#define CRYPTOUSECASE_RSAOAEP 3
|
||||||
|
|
||||||
#define CRYPTOUSECASE_MAX 4
|
#define CRYPTOUSECASE_MAX 4
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,11 @@ uint32_t smc_load_aes_key(smc_args_t *args);
|
||||||
uint32_t smc_crypt_aes(smc_args_t *args);
|
uint32_t smc_crypt_aes(smc_args_t *args);
|
||||||
uint32_t smc_generate_specific_aes_key(smc_args_t *args);
|
uint32_t smc_generate_specific_aes_key(smc_args_t *args);
|
||||||
uint32_t smc_compute_cmac(smc_args_t *args);
|
uint32_t smc_compute_cmac(smc_args_t *args);
|
||||||
uint32_t smc_load_rsa_private_key(smc_args_t *args);
|
|
||||||
uint32_t smc_decrypt_rsa_private_key(smc_args_t *args);
|
|
||||||
uint32_t smc_load_rsa_oaep_key(smc_args_t *args);
|
uint32_t smc_load_rsa_oaep_key(smc_args_t *args);
|
||||||
uint32_t smc_rsa_oaep(smc_args_t *args);
|
uint32_t smc_decrypt_rsa_private_key(smc_args_t *args);
|
||||||
uint32_t smc_unwrap_rsa_wrapped_titlekey(smc_args_t *args);
|
uint32_t smc_load_secure_exp_mod_key(smc_args_t *args);
|
||||||
|
uint32_t smc_secure_exp_mod(smc_args_t *args);
|
||||||
|
uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args);
|
||||||
uint32_t smc_load_titlekey(smc_args_t *args);
|
uint32_t smc_load_titlekey(smc_args_t *args);
|
||||||
uint32_t smc_unwrap_aes_wrapped_titlekey(smc_args_t *args);
|
uint32_t smc_unwrap_aes_wrapped_titlekey(smc_args_t *args);
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@ smc_table_entry_t g_smc_user_table[SMC_USER_HANDLERS] = {
|
||||||
{0xC3000009, smc_crypt_aes},
|
{0xC3000009, smc_crypt_aes},
|
||||||
{0xC300000A, smc_generate_specific_aes_key},
|
{0xC300000A, smc_generate_specific_aes_key},
|
||||||
{0xC300040B, smc_compute_cmac},
|
{0xC300040B, smc_compute_cmac},
|
||||||
{0xC300100C, smc_load_rsa_private_key},
|
{0xC300100C, smc_load_rsa_oaep_key},
|
||||||
{0xC300100D, smc_decrypt_rsa_private_key},
|
{0xC300100D, smc_decrypt_rsa_private_key},
|
||||||
{0xC300100E, smc_load_rsa_oaep_key},
|
{0xC300100E, smc_load_secure_exp_mod_key},
|
||||||
{0xC300060F, smc_rsa_oaep},
|
{0xC300060F, smc_secure_exp_mod},
|
||||||
{0xC3000610, smc_unwrap_rsa_wrapped_titlekey},
|
{0xC3000610, smc_unwrap_rsa_oaep_wrapped_titlekey},
|
||||||
{0xC3000011, smc_load_titlekey},
|
{0xC3000011, smc_load_titlekey},
|
||||||
{0xC3000012, smc_unwrap_aes_wrapped_titlekey}
|
{0xC3000012, smc_unwrap_aes_wrapped_titlekey}
|
||||||
};
|
};
|
||||||
|
@ -313,23 +313,23 @@ uint32_t smc_compute_cmac(smc_args_t *args) {
|
||||||
return smc_wrapper_sync(args, user_compute_cmac);
|
return smc_wrapper_sync(args, user_compute_cmac);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_load_rsa_private_key(smc_args_t *args) {
|
uint32_t smc_load_rsa_oaep_key(smc_args_t *args) {
|
||||||
return smc_wrapper_sync(args, user_load_rsa_private_key);
|
return smc_wrapper_sync(args, user_load_rsa_oaep_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_decrypt_rsa_private_key(smc_args_t *args) {
|
uint32_t smc_decrypt_rsa_private_key(smc_args_t *args) {
|
||||||
return smc_wrapper_sync(args, user_decrypt_rsa_private_key);
|
return smc_wrapper_sync(args, user_decrypt_rsa_private_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_load_rsa_oaep_key(smc_args_t *args) {
|
uint32_t smc_load_secure_exp_mod_key(smc_args_t *args) {
|
||||||
return smc_wrapper_sync(args, user_load_rsa_oaep_key);
|
return smc_wrapper_sync(args, user_load_secure_exp_mod_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_rsa_oaep(smc_args_t *args) {
|
uint32_t smc_secure_exp_mod(smc_args_t *args) {
|
||||||
return smc_wrapper_async(args, user_rsa_oaep, smc_exp_mod_get_result);
|
return smc_wrapper_async(args, user_secure_exp_mod, smc_exp_mod_get_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_unwrap_rsa_wrapped_titlekey_get_result(void *buf, uint64_t size) {
|
uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey_get_result(void *buf, uint64_t size) {
|
||||||
uint64_t *p_sealed_key = (uint64_t *)buf;
|
uint64_t *p_sealed_key = (uint64_t *)buf;
|
||||||
uint8_t rsa_wrapped_titlekey[0x100];
|
uint8_t rsa_wrapped_titlekey[0x100];
|
||||||
uint8_t aes_wrapped_titlekey[0x10];
|
uint8_t aes_wrapped_titlekey[0x10];
|
||||||
|
@ -344,8 +344,8 @@ uint32_t smc_unwrap_rsa_wrapped_titlekey_get_result(void *buf, uint64_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
se_get_exp_mod_output(wrapped_titlekey, 0x100);
|
se_get_exp_mod_output(wrapped_titlekey, 0x100);
|
||||||
if (tkey_rsa_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) {
|
if (tkey_rsa_oaep_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) {
|
||||||
/* Failed to extract RSA wrapped key. */
|
/* Failed to extract RSA OAEP wrapped key. */
|
||||||
g_is_smc_in_progress = 0;
|
g_is_smc_in_progress = 0;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -356,13 +356,13 @@ uint32_t smc_unwrap_rsa_wrapped_titlekey_get_result(void *buf, uint64_t size) {
|
||||||
p_sealed_key[0] = sealed_titlekey[0];
|
p_sealed_key[0] = sealed_titlekey[0];
|
||||||
p_sealed_key[1] = sealed_titlekey[1];
|
p_sealed_key[1] = sealed_titlekey[1];
|
||||||
|
|
||||||
/* smc_unwrap_aes_wrapped_titlekey is done now. */
|
/* smc_unwrap_rsa_oaep_wrapped_titlekey is done now. */
|
||||||
g_is_smc_in_progress = 0;
|
g_is_smc_in_progress = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_unwrap_rsa_wrapped_titlekey(smc_args_t *args) {
|
uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
|
||||||
return smc_wrapper_async(args, user_unwrap_rsa_wrapped_titlekey, smc_unwrap_rsa_wrapped_titlekey_get_result);
|
return smc_wrapper_async(args, user_unwrap_rsa_oaep_wrapped_titlekey, smc_unwrap_rsa_oaep_wrapped_titlekey_get_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_load_titlekey(smc_args_t *args) {
|
uint32_t smc_load_titlekey(smc_args_t *args) {
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
int g_crypt_aes_done = 0;
|
int g_crypt_aes_done = 0;
|
||||||
int g_exp_mod_done = 0;
|
int g_exp_mod_done = 0;
|
||||||
|
|
||||||
|
uint8_t g_secure_exp_mod_exponent[0x100];
|
||||||
uint8_t g_rsa_oaep_exponent[0x100];
|
uint8_t g_rsa_oaep_exponent[0x100];
|
||||||
uint8_t g_rsa_private_exponent[0x100];
|
|
||||||
|
|
||||||
|
|
||||||
void set_exp_mod_done(int done) {
|
void set_exp_mod_done(int done) {
|
||||||
|
@ -355,7 +355,7 @@ uint32_t user_compute_cmac(smc_args_t *args) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t user_load_rsa_private_key(smc_args_t *args) {
|
uint32_t user_load_rsa_oaep_key(smc_args_t *args) {
|
||||||
uint64_t sealed_kek[2];
|
uint64_t sealed_kek[2];
|
||||||
uint64_t wrapped_key[2];
|
uint64_t wrapped_key[2];
|
||||||
int is_personalized;
|
int is_personalized;
|
||||||
|
@ -390,11 +390,11 @@ uint32_t user_load_rsa_private_key(smc_args_t *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure that our private key is 0x100 bytes. */
|
/* Ensure that our private key is 0x100 bytes. */
|
||||||
if (gcm_decrypt_key(user_data, size, user_data, size, sealed_kek, 0x10, wrapped_key, 0x10, CRYPTOUSECASE_RSATICKET, is_personalized) < 0x100) {
|
if (gcm_decrypt_key(user_data, size, user_data, size, sealed_kek, 0x10, wrapped_key, 0x10, CRYPTOUSECASE_RSAOAEP, is_personalized) < 0x100) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(g_rsa_private_exponent, user_data, 0x100);
|
memcpy(g_rsa_oaep_exponent, user_data, 0x100);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t user_load_rsa_oaep_key(smc_args_t *args) {
|
uint32_t user_load_secure_exp_mod_key(smc_args_t *args) {
|
||||||
uint64_t sealed_kek[2];
|
uint64_t sealed_kek[2];
|
||||||
uint64_t wrapped_key[2];
|
uint64_t wrapped_key[2];
|
||||||
int is_personalized;
|
int is_personalized;
|
||||||
|
@ -487,21 +487,21 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) {
|
||||||
size_t out_size;
|
size_t out_size;
|
||||||
|
|
||||||
/* Ensure that our key is non-zero bytes. */
|
/* Ensure that our key is non-zero bytes. */
|
||||||
if ((out_size = gcm_decrypt_key(user_data, size, user_data, size, sealed_kek, 0x10, wrapped_key, 0x10, CRYPTOUSECASE_RSAOAEP, is_personalized)) == 0) {
|
if ((out_size = gcm_decrypt_key(user_data, size, user_data, size, sealed_kek, 0x10, wrapped_key, 0x10, CRYPTOUSECASE_SECUREEXPMOD, is_personalized)) == 0) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy key to global. */
|
/* Copy key to global. */
|
||||||
if (out_size <= 0x100) {
|
if (out_size <= 0x100) {
|
||||||
memcpy(g_rsa_oaep_exponent, user_data, out_size);
|
memcpy(g_secure_exp_mod_exponent, user_data, out_size);
|
||||||
} else {
|
} else {
|
||||||
memcpy(g_rsa_oaep_exponent, user_data, 0x100);
|
memcpy(g_secure_exp_mod_exponent, user_data, 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t user_rsa_oaep(smc_args_t *args) {
|
uint32_t user_secure_exp_mod(smc_args_t *args) {
|
||||||
uint8_t modulus[0x100];
|
uint8_t modulus[0x100];
|
||||||
uint8_t input[0x100];
|
uint8_t input[0x100];
|
||||||
|
|
||||||
|
@ -523,13 +523,13 @@ uint32_t user_rsa_oaep(smc_args_t *args) {
|
||||||
|
|
||||||
set_exp_mod_done(0);
|
set_exp_mod_done(0);
|
||||||
/* Hardcode RSA keyslot 0. */
|
/* Hardcode RSA keyslot 0. */
|
||||||
set_rsa_keyslot(0, modulus, 0x100, g_rsa_oaep_exponent, 0x100);
|
set_rsa_keyslot(0, modulus, 0x100, g_secure_exp_mod_exponent, 0x100);
|
||||||
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
|
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t user_unwrap_rsa_wrapped_titlekey(smc_args_t *args) {
|
uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
|
||||||
uint8_t modulus[0x100];
|
uint8_t modulus[0x100];
|
||||||
uint8_t wrapped_key[0x100];
|
uint8_t wrapped_key[0x100];
|
||||||
|
|
||||||
|
@ -556,13 +556,13 @@ uint32_t user_unwrap_rsa_wrapped_titlekey(smc_args_t *args) {
|
||||||
|
|
||||||
set_exp_mod_done(0);
|
set_exp_mod_done(0);
|
||||||
|
|
||||||
/* Expected db prefix occupies args->X[3] to args->X[6]. */
|
/* Expected label_hash occupies args->X[3] to args->X[6]. */
|
||||||
tkey_set_expected_db_prefix(&args->X[3]);
|
tkey_set_expected_label_hash(&args->X[3]);
|
||||||
|
|
||||||
tkey_set_master_key_rev(master_key_rev);
|
tkey_set_master_key_rev(master_key_rev);
|
||||||
|
|
||||||
/* Hardcode RSA keyslot 0. */
|
/* Hardcode RSA keyslot 0. */
|
||||||
set_rsa_keyslot(0, modulus, 0x100, g_rsa_private_exponent, 0x100);
|
set_rsa_keyslot(0, modulus, 0x100, g_rsa_oaep_exponent, 0x100);
|
||||||
se_exp_mod(0, wrapped_key, 0x100, exp_mod_done_handler);
|
se_exp_mod(0, wrapped_key, 0x100, exp_mod_done_handler);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -10,11 +10,11 @@ uint32_t user_load_aes_key(smc_args_t *args);
|
||||||
uint32_t user_crypt_aes(smc_args_t *args);
|
uint32_t user_crypt_aes(smc_args_t *args);
|
||||||
uint32_t user_generate_specific_aes_key(smc_args_t *args);
|
uint32_t user_generate_specific_aes_key(smc_args_t *args);
|
||||||
uint32_t user_compute_cmac(smc_args_t *args);
|
uint32_t user_compute_cmac(smc_args_t *args);
|
||||||
uint32_t user_load_rsa_private_key(smc_args_t *args);
|
|
||||||
uint32_t user_decrypt_rsa_private_key(smc_args_t *args);
|
|
||||||
uint32_t user_load_rsa_oaep_key(smc_args_t *args);
|
uint32_t user_load_rsa_oaep_key(smc_args_t *args);
|
||||||
uint32_t user_rsa_oaep(smc_args_t *args);
|
uint32_t user_decrypt_rsa_private_key(smc_args_t *args);
|
||||||
uint32_t user_unwrap_rsa_wrapped_titlekey(smc_args_t *args);
|
uint32_t user_load_secure_exp_mod_key(smc_args_t *args);
|
||||||
|
uint32_t user_secure_exp_mod(smc_args_t *args);
|
||||||
|
uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args);
|
||||||
uint32_t user_load_titlekey(smc_args_t *args);
|
uint32_t user_load_titlekey(smc_args_t *args);
|
||||||
uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args);
|
uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args);
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
#include "masterkey.h"
|
#include "masterkey.h"
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
|
|
||||||
uint64_t g_tkey_expected_db_prefix[4];
|
uint64_t g_tkey_expected_label_hash[4];
|
||||||
unsigned int g_tkey_master_key_rev = MASTERKEY_REVISION_MAX;
|
unsigned int g_tkey_master_key_rev = MASTERKEY_REVISION_MAX;
|
||||||
|
|
||||||
/* Set the expected db prefix. */
|
/* Set the expected db prefix. */
|
||||||
void tkey_set_expected_db_prefix(uint64_t *db_prefix) {
|
void tkey_set_expected_label_hash(uint64_t *label_hash) {
|
||||||
for (unsigned int i = 0; i < 4; i++) {
|
for (unsigned int i = 0; i < 4; i++) {
|
||||||
g_tkey_expected_db_prefix[i] = db_prefix[i];
|
g_tkey_expected_label_hash[i] = label_hash[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,20 +61,19 @@ void calculate_mgf1_and_xor(void *masked, size_t masked_size, const void *seed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t tkey_rsa_unwrap(void *dst, size_t dst_size, void *src, size_t src_size) {
|
size_t tkey_rsa_oaep_unwrap(void *dst, size_t dst_size, void *src, size_t src_size) {
|
||||||
if (src_size != 0x100) {
|
if (src_size != 0x100) {
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RSA Wrapped titlekeys butcher the RSA-PSS primitives. */
|
/* RSA Wrapped titlekeys use RSA-OAEP. */
|
||||||
/* Message is of the form prefix || maskedSalt || maskedDB. */
|
/* Message is of the form prefix || maskedSalt || maskedDB. */
|
||||||
/* maskedSalt = salt ^ MGF1(maskedDB) */
|
/* maskedSalt = salt ^ MGF1(maskedDB) */
|
||||||
/* maskedDB = DB ^ MGF1(salt) */
|
/* maskedDB = DB ^ MGF1(salt) */
|
||||||
/* Salt is random and not validated in any way. */
|
/* Salt is random and not validated in any way. */
|
||||||
/* DB is of the form expected_prefix || 00....01 || wrapped_titlekey. */
|
/* DB is of the form label_hash || 00....01 || wrapped_titlekey. */
|
||||||
/* expected_prefix is, in practice, a constant in es .rodata. */
|
/* label_hash is, in practice, a constant in es .rodata. */
|
||||||
/* I have no idea why Nintendo did this, it should be either nonconstant (in tik) or in tz .rodata. */
|
/* I have no idea why Nintendo did this, it should be either nonconstant (in tik) or in tz .rodata. */
|
||||||
/* However, to keep their API we have to put up with their bizarre choices... */
|
|
||||||
|
|
||||||
uint8_t *message = (uint8_t *)src;
|
uint8_t *message = (uint8_t *)src;
|
||||||
|
|
||||||
|
@ -87,8 +86,8 @@ size_t tkey_rsa_unwrap(void *dst, size_t dst_size, void *src, size_t src_size) {
|
||||||
uint8_t *salt = message + 1;
|
uint8_t *salt = message + 1;
|
||||||
uint8_t *db = message + 0x21;
|
uint8_t *db = message + 0x21;
|
||||||
|
|
||||||
/* This will be passed to smc_unwrap_rsa_wrapped_titlekey. */
|
/* This will be passed to smc_unwrap_rsa_oaep_wrapped_titlekey. */
|
||||||
uint8_t *expected_db_prefix = (uint8_t *)(&g_tkey_expected_db_prefix[0]);
|
uint8_t *expected_label_hash = (uint8_t *)(&g_tkey_expected_label_hash[0]);
|
||||||
|
|
||||||
/* Unmask the salt. */
|
/* Unmask the salt. */
|
||||||
calculate_mgf1_and_xor(salt, 0x20, db, 0xDF);
|
calculate_mgf1_and_xor(salt, 0x20, db, 0xDF);
|
||||||
|
@ -97,7 +96,7 @@ size_t tkey_rsa_unwrap(void *dst, size_t dst_size, void *src, size_t src_size) {
|
||||||
|
|
||||||
/* Validate expected salt. */
|
/* Validate expected salt. */
|
||||||
for (unsigned int i = 0; i < 0x20; i++) {
|
for (unsigned int i = 0; i < 0x20; i++) {
|
||||||
if (expected_db_prefix[i] != db[i]) {
|
if (expected_label_hash[i] != db[i]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void tkey_set_expected_db_prefix(uint64_t *db_prefix);
|
void tkey_set_expected_label_hash(uint64_t *label_hash);
|
||||||
void tkey_set_master_key_rev(unsigned int master_key_rev);
|
void tkey_set_master_key_rev(unsigned int master_key_rev);
|
||||||
|
|
||||||
size_t tkey_rsa_unwrap(void *dst, size_t dst_size, void *src, size_t src_size);
|
size_t tkey_rsa_oaep_unwrap(void *dst, size_t dst_size, void *src, size_t src_size);
|
||||||
|
|
||||||
void tkey_aes_unwrap(void *dst, size_t dst_size, const void *src, size_t src_size);
|
void tkey_aes_unwrap(void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue