mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 00:12:03 +00:00
Example SMC implementation (load_aes_key)
This commit is contained in:
parent
49e1e6f41e
commit
5c24f58402
3 changed files with 98 additions and 3 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "smc_api.h"
|
#include "smc_api.h"
|
||||||
|
#include "smc_user.h"
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
|
|
||||||
#define SMC_USER_HANDLERS 0x13
|
#define SMC_USER_HANDLERS 0x13
|
||||||
|
@ -93,10 +94,10 @@ smc_table_t g_smc_tables[2] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
int g_is_smc_in_progress = 0;
|
int g_is_smc_in_progress = 0;
|
||||||
uint32_t (*g_smc_callback)(uint64_t, uint64_t) = NULL;
|
uint32_t (*g_smc_callback)(void *, uint64_t) = NULL;
|
||||||
uint64_t g_smc_callback_key = 0;
|
uint64_t g_smc_callback_key = 0;
|
||||||
|
|
||||||
uint64_t try_set_smc_callback(uint32_t (*callback)(uint64_t, uint64_t)) {
|
uint64_t try_set_smc_callback(uint32_t (*callback)(void *, uint64_t)) {
|
||||||
uint64_t key;
|
uint64_t key;
|
||||||
/* TODO: Atomics... */
|
/* TODO: Atomics... */
|
||||||
if (g_smc_callback_key) {
|
if (g_smc_callback_key) {
|
||||||
|
@ -158,7 +159,7 @@ uint32_t smc_wrapper_sync(smc_args_t *args, uint32_t (*handler)(smc_args_t *)) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *), uint32_t (*callback)(uint64_t, uint64_t)) {
|
uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *), uint32_t (*callback)(void *, uint64_t)) {
|
||||||
uint32_t result;
|
uint32_t result;
|
||||||
uint64_t key;
|
uint64_t key;
|
||||||
/* TODO: Make g_is_smc_in_progress atomic. */
|
/* TODO: Make g_is_smc_in_progress atomic. */
|
||||||
|
@ -181,4 +182,46 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *),
|
||||||
}
|
}
|
||||||
g_is_smc_in_progress = 0;
|
g_is_smc_in_progress = 0;
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t smc_check_status(smc_args_t *args) {
|
||||||
|
if (g_smc_callback_key == 0) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->X[1] != g_smc_callback_key) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
args->X[1] = g_smc_callback(NULL, 0);
|
||||||
|
|
||||||
|
g_smc_callback_key = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t smc_get_result(smc_args_t *) {
|
||||||
|
uint32_t status;
|
||||||
|
unsigned char result_buf[0x400];
|
||||||
|
if (g_smc_callback_key == 0) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->X[1] != g_smc_callback_key) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check result size */
|
||||||
|
if (args->X[3] > 0x400) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
args->X[1] = g_smc_callback(result_buf, args->X[3]);
|
||||||
|
g_smc_callback_key = 0;
|
||||||
|
|
||||||
|
/* TODO: Copy result from result_buf into output in args->X[2] */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t smc_load_aes_key(smc_args_t *args) {
|
||||||
|
smc_wrapper_sync(args, user_load_aes_key);
|
||||||
}
|
}
|
31
exosphere/smc_user.c
Normal file
31
exosphere/smc_user.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "smc_api.h"
|
||||||
|
#include "smc_user.h"
|
||||||
|
#include "se.h"
|
||||||
|
|
||||||
|
uint32_t user_load_aes_key(smc_args_t *args) {
|
||||||
|
unsigned char sealed_kek[0x10];
|
||||||
|
unsigned char wrapped_key[0x10];
|
||||||
|
uint64_t *p_sealed_kek = (uint64_t *)(&sealed_kek[0]);
|
||||||
|
uint64_t *p_wrapped_key = (uint64_t *)(&wrapped_key[0]);
|
||||||
|
|
||||||
|
uint32_t keyslot = (uint32_t)args->X[1];
|
||||||
|
if (keyslot > 3) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy keydata */
|
||||||
|
p_sealed_kek[0] = args->X[2];
|
||||||
|
p_sealed_kek[1] = args->X[3];
|
||||||
|
p_wrapped_key[0] = args->X[4];
|
||||||
|
p_wrapped_key[1] = args->X[5];
|
||||||
|
|
||||||
|
/* TODO: Unseal the kek. */
|
||||||
|
set_aes_keyslot(9, sealed_kek, 0x10);
|
||||||
|
|
||||||
|
/* Unwrap the key. */
|
||||||
|
decrypt_data_into_keyslot(keyslot, 9, wrapped_key, 0x10);
|
||||||
|
return 0;
|
||||||
|
}
|
21
exosphere/smc_user.h
Normal file
21
exosphere/smc_user.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef EXOSPHERE_SMC_USER_H
|
||||||
|
#define EXOSPHERE_SMC_USER_H
|
||||||
|
|
||||||
|
#include "smc_api.h"
|
||||||
|
|
||||||
|
uint32_t user_exp_mod(smc_args_t *args);
|
||||||
|
uint32_t user_get_random_bytes(smc_args_t *args);
|
||||||
|
uint32_t user_generate_aes_kek(smc_args_t *args);
|
||||||
|
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_load_titlekey(smc_args_t *args);
|
||||||
|
uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue