diff --git a/exosphere/sealedkeys.h b/exosphere/sealedkeys.h index 7e4f2380b..78226c7e2 100644 --- a/exosphere/sealedkeys.h +++ b/exosphere/sealedkeys.h @@ -7,8 +7,8 @@ #define CRYPTOUSECASE_AES 0 #define CRYPTOUSECASE_RSAPRIVATE 1 -#define CRYPTOUSECASE_RSAOAEP 2 -#define CRYPTOUSECASE_RSATICKET 3 +#define CRYPTOUSECASE_SECUREEXPMOD 2 +#define CRYPTOUSECASE_RSAOAEP 3 #define CRYPTOUSECASE_MAX 4 diff --git a/exosphere/smc_api.c b/exosphere/smc_api.c index 5cbc9ec1d..88746dcf6 100644 --- a/exosphere/smc_api.c +++ b/exosphere/smc_api.c @@ -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_generate_specific_aes_key(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_rsa_oaep(smc_args_t *args); -uint32_t smc_unwrap_rsa_wrapped_titlekey(smc_args_t *args); +uint32_t smc_decrypt_rsa_private_key(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_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}, {0xC300000A, smc_generate_specific_aes_key}, {0xC300040B, smc_compute_cmac}, - {0xC300100C, smc_load_rsa_private_key}, + {0xC300100C, smc_load_rsa_oaep_key}, {0xC300100D, smc_decrypt_rsa_private_key}, - {0xC300100E, smc_load_rsa_oaep_key}, - {0xC300060F, smc_rsa_oaep}, - {0xC3000610, smc_unwrap_rsa_wrapped_titlekey}, + {0xC300100E, smc_load_secure_exp_mod_key}, + {0xC300060F, smc_secure_exp_mod}, + {0xC3000610, smc_unwrap_rsa_oaep_wrapped_titlekey}, {0xC3000011, smc_load_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); } -uint32_t smc_load_rsa_private_key(smc_args_t *args) { - return smc_wrapper_sync(args, user_load_rsa_private_key); +uint32_t smc_load_rsa_oaep_key(smc_args_t *args) { + return smc_wrapper_sync(args, user_load_rsa_oaep_key); } uint32_t smc_decrypt_rsa_private_key(smc_args_t *args) { return smc_wrapper_sync(args, user_decrypt_rsa_private_key); } -uint32_t smc_load_rsa_oaep_key(smc_args_t *args) { - return smc_wrapper_sync(args, user_load_rsa_oaep_key); +uint32_t smc_load_secure_exp_mod_key(smc_args_t *args) { + return smc_wrapper_sync(args, user_load_secure_exp_mod_key); } -uint32_t smc_rsa_oaep(smc_args_t *args) { - return smc_wrapper_async(args, user_rsa_oaep, smc_exp_mod_get_result); +uint32_t smc_secure_exp_mod(smc_args_t *args) { + 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; uint8_t rsa_wrapped_titlekey[0x100]; 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); - if (tkey_rsa_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) { - /* Failed to extract RSA wrapped key. */ + if (tkey_rsa_oaep_unwrap(aes_wrapped_titlekey, 0x10, rsa_wrapped_titlekey, 0x100) != 0x10) { + /* Failed to extract RSA OAEP wrapped key. */ g_is_smc_in_progress = 0; 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[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; return 0; } -uint32_t smc_unwrap_rsa_wrapped_titlekey(smc_args_t *args) { - return smc_wrapper_async(args, user_unwrap_rsa_wrapped_titlekey, smc_unwrap_rsa_wrapped_titlekey_get_result); +uint32_t smc_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) { + 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) { diff --git a/exosphere/smc_user.c b/exosphere/smc_user.c index b79fe0927..8d13452e4 100644 --- a/exosphere/smc_user.c +++ b/exosphere/smc_user.c @@ -15,8 +15,8 @@ int g_crypt_aes_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_private_exponent[0x100]; void set_exp_mod_done(int done) { @@ -355,7 +355,7 @@ uint32_t user_compute_cmac(smc_args_t *args) { 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 wrapped_key[2]; 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. */ - 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; } - memcpy(g_rsa_private_exponent, user_data, 0x100); + memcpy(g_rsa_oaep_exponent, user_data, 0x100); return 0; } @@ -450,7 +450,7 @@ uint32_t user_decrypt_rsa_private_key(smc_args_t *args) { 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 wrapped_key[2]; int is_personalized; @@ -487,21 +487,21 @@ uint32_t user_load_rsa_oaep_key(smc_args_t *args) { size_t out_size; /* 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; } /* Copy key to global. */ if (out_size <= 0x100) { - memcpy(g_rsa_oaep_exponent, user_data, out_size); + memcpy(g_secure_exp_mod_exponent, user_data, out_size); } else { - memcpy(g_rsa_oaep_exponent, user_data, 0x100); + memcpy(g_secure_exp_mod_exponent, user_data, 0x100); } 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 input[0x100]; @@ -523,13 +523,13 @@ uint32_t user_rsa_oaep(smc_args_t *args) { set_exp_mod_done(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); 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 wrapped_key[0x100]; @@ -556,13 +556,13 @@ uint32_t user_unwrap_rsa_wrapped_titlekey(smc_args_t *args) { set_exp_mod_done(0); - /* Expected db prefix occupies args->X[3] to args->X[6]. */ - tkey_set_expected_db_prefix(&args->X[3]); + /* Expected label_hash occupies args->X[3] to args->X[6]. */ + tkey_set_expected_label_hash(&args->X[3]); tkey_set_master_key_rev(master_key_rev); /* 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); return 0; diff --git a/exosphere/smc_user.h b/exosphere/smc_user.h index 0907be997..4c65d0b91 100644 --- a/exosphere/smc_user.h +++ b/exosphere/smc_user.h @@ -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_generate_specific_aes_key(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_rsa_oaep(smc_args_t *args); -uint32_t user_unwrap_rsa_wrapped_titlekey(smc_args_t *args); +uint32_t user_decrypt_rsa_private_key(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_unwrap_aes_wrapped_titlekey(smc_args_t *args); diff --git a/exosphere/titlekey.c b/exosphere/titlekey.c index 299683737..c4786a132 100644 --- a/exosphere/titlekey.c +++ b/exosphere/titlekey.c @@ -6,13 +6,13 @@ #include "masterkey.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; /* 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++) { - 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) { panic(); } - /* RSA Wrapped titlekeys butcher the RSA-PSS primitives. */ + /* RSA Wrapped titlekeys use RSA-OAEP. */ /* Message is of the form prefix || maskedSalt || maskedDB. */ /* maskedSalt = salt ^ MGF1(maskedDB) */ /* maskedDB = DB ^ MGF1(salt) */ /* Salt is random and not validated in any way. */ - /* DB is of the form expected_prefix || 00....01 || wrapped_titlekey. */ - /* expected_prefix is, in practice, a constant in es .rodata. */ + /* DB is of the form label_hash || 00....01 || wrapped_titlekey. */ + /* 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. */ - /* However, to keep their API we have to put up with their bizarre choices... */ 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 *db = message + 0x21; - /* This will be passed to smc_unwrap_rsa_wrapped_titlekey. */ - uint8_t *expected_db_prefix = (uint8_t *)(&g_tkey_expected_db_prefix[0]); + /* This will be passed to smc_unwrap_rsa_oaep_wrapped_titlekey. */ + uint8_t *expected_label_hash = (uint8_t *)(&g_tkey_expected_label_hash[0]); /* Unmask the salt. */ 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. */ for (unsigned int i = 0; i < 0x20; i++) { - if (expected_db_prefix[i] != db[i]) { + if (expected_label_hash[i] != db[i]) { return 0; } } diff --git a/exosphere/titlekey.h b/exosphere/titlekey.h index 195539844..a74949b8b 100644 --- a/exosphere/titlekey.h +++ b/exosphere/titlekey.h @@ -3,10 +3,10 @@ #include -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); -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);