mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
Implement smcExpMod.
This commit is contained in:
parent
9b54bc536b
commit
f1c521a5d6
4 changed files with 87 additions and 3 deletions
|
@ -112,6 +112,7 @@ void set_security_engine_address(security_engine_t *security_engine);
|
||||||
security_engine_t *get_security_engine_address(void);
|
security_engine_t *get_security_engine_address(void);
|
||||||
|
|
||||||
void se_check_for_error(void);
|
void se_check_for_error(void);
|
||||||
|
void se_trigger_interrupt(void);
|
||||||
|
|
||||||
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
||||||
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags);
|
||||||
|
|
|
@ -259,13 +259,33 @@ uint32_t smc_get_result(smc_args_t *) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t smc_exp_mod_get_result(void *buf, uint64_t size) {
|
||||||
|
if (get_exp_mod_done() != 1) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size != 0x100) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
se_get_exp_mod_output(buf, 0x100);
|
||||||
|
|
||||||
|
/* smc_exp_mod is done now. */
|
||||||
|
g_is_smc_in_progress = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t smc_exp_mod(smc_args_t *args) {
|
||||||
|
return smc_wrapper_async(args, user_exp_mod, smc_exp_mod_get_result);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t smc_load_aes_key(smc_args_t *args) {
|
uint32_t smc_load_aes_key(smc_args_t *args) {
|
||||||
return smc_wrapper_sync(args, user_load_aes_key);
|
return smc_wrapper_sync(args, user_load_aes_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_crypt_aes_status_check(void *buf, uint64_t size) {
|
uint32_t smc_crypt_aes_status_check(void *buf, uint64_t size) {
|
||||||
/* Buf and size are unused. */
|
/* Buf and size are unused. */
|
||||||
if (get_crypt_aes_done() == 0) {
|
if (get_crypt_aes_done() != 1) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
/* smc_crypt_aes is done now. */
|
/* smc_crypt_aes is done now. */
|
||||||
|
|
|
@ -9,6 +9,64 @@
|
||||||
|
|
||||||
/* Globals. */
|
/* Globals. */
|
||||||
int g_crypt_aes_done = 0;
|
int g_crypt_aes_done = 0;
|
||||||
|
int g_exp_mod_done = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void set_exp_mod_done(int done) {
|
||||||
|
g_exp_mod_done = done & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_exp_mod_done(void) {
|
||||||
|
return g_exp_mod_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t exp_mod_done_handler(void) {
|
||||||
|
set_exp_mod_done(1);
|
||||||
|
|
||||||
|
se_trigger_interrupt();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t user_exp_mod(smc_args_t *args) {
|
||||||
|
uint8_t modulus[0x100];
|
||||||
|
uint8_t exponent[0x100];
|
||||||
|
uint8_t input[0x100];
|
||||||
|
|
||||||
|
upage_ref_t page_ref;
|
||||||
|
|
||||||
|
/* Validate size. */
|
||||||
|
if (args->X[4] == 0 || args->X[4] > 0x100 || (args->X[4] & 3) != 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t exponent_size = (size_t)args->X[4];
|
||||||
|
|
||||||
|
void *user_input = (void *)args->X[1];
|
||||||
|
void *user_exponent = (void *)args->X[2];
|
||||||
|
void *user_modulus = (void *)args->X[3];
|
||||||
|
|
||||||
|
/* Copy user data into secure memory. */
|
||||||
|
if (upage_init(&page_ref, user_input) == 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (user_copy_to_secure(&page_ref, input, user_input, 0x100) == 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (user_copy_to_secure(&page_ref, exponent, user_exponent, exponent_size) == 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (user_copy_to_secure(&page_ref, modulus, user_modulus, 0x100) == 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_exp_mod_done(0);
|
||||||
|
/* Hardcode RSA keyslot 0. */
|
||||||
|
set_rsa_keyslot(0, modulus, 0x100, exponent, exponent_size);
|
||||||
|
se_exp_mod(0, input, 0x100, exp_mod_done_handler);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t user_load_aes_key(smc_args_t *args) {
|
uint32_t user_load_aes_key(smc_args_t *args) {
|
||||||
uint64_t sealed_kek[2];
|
uint64_t sealed_kek[2];
|
||||||
|
@ -47,7 +105,9 @@ uint32_t crypt_aes_done_handler(void) {
|
||||||
|
|
||||||
set_crypt_aes_done(1);
|
set_crypt_aes_done(1);
|
||||||
|
|
||||||
/* TODO: Manually trigger an SE interrupt (0x2C) */
|
se_trigger_interrupt();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t user_crypt_aes(smc_args_t *args) {
|
uint32_t user_crypt_aes(smc_args_t *args) {
|
||||||
|
@ -105,7 +165,7 @@ uint32_t user_compute_cmac(smc_args_t *args) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upage_init(&page_ref, (void *)user_address) == 0 || user_copy_to_secure(&page_ref, user_data, user_address, size) == 0) {
|
if (upage_init(&page_ref, user_address) == 0 || user_copy_to_secure(&page_ref, user_data, user_address, size) == 0) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,4 +22,7 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args);
|
||||||
void set_crypt_aes_done(int done);
|
void set_crypt_aes_done(int done);
|
||||||
int get_crypt_aes_done(void);
|
int get_crypt_aes_done(void);
|
||||||
|
|
||||||
|
void set_exp_mod_done(int done);
|
||||||
|
int get_exp_mod_done(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in a new issue