mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-14 00:56:35 +00:00
SMCCryptAes + Skeleton blocking AES API
This commit is contained in:
parent
21c2405f15
commit
d0beae376f
5 changed files with 96 additions and 1 deletions
|
@ -222,6 +222,9 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr,
|
||||||
/* Set the callback, for after the async operation. */
|
/* Set the callback, for after the async operation. */
|
||||||
set_security_engine_callback(callback);
|
set_security_engine_callback(callback);
|
||||||
|
|
||||||
|
/* Enable SE Interrupt firing for async op. */
|
||||||
|
g_security_engine->INT_ENABLE_REG = 0x10;
|
||||||
|
|
||||||
/* Setup Input/Output lists */
|
/* Setup Input/Output lists */
|
||||||
g_security_engine->IN_LL_ADDR_REG = in_ll_paddr;
|
g_security_engine->IN_LL_ADDR_REG = in_ll_paddr;
|
||||||
g_security_engine->OUT_LL_ADDR_REG = out_ll_paddr;
|
g_security_engine->OUT_LL_ADDR_REG = out_ll_paddr;
|
||||||
|
@ -285,6 +288,9 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal
|
||||||
|
|
||||||
set_security_engine_callback(callback);
|
set_security_engine_callback(callback);
|
||||||
|
|
||||||
|
/* Enable SE Interrupt firing for async op. */
|
||||||
|
g_security_engine->INT_ENABLE_REG = 0x10;
|
||||||
|
|
||||||
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
||||||
trigger_se_rsa_op(stack_buf, size);
|
trigger_se_rsa_op(stack_buf, size);
|
||||||
|
|
||||||
|
|
|
@ -125,11 +125,18 @@ void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size);
|
||||||
void set_se_ctr(const void *ctr);
|
void set_se_ctr(const void *ctr);
|
||||||
|
|
||||||
|
|
||||||
/* AES API */
|
/* Insecure AES API */
|
||||||
void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void));
|
void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void));
|
||||||
void se_aes_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void));
|
void se_aes_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void));
|
||||||
void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void));
|
void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void));
|
||||||
|
|
||||||
|
/* Secure AES API */
|
||||||
|
void se_compute_aes_128_cmac(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||||
|
void se_compute_aes_256_cmac(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||||
|
void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size);
|
||||||
|
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||||
|
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||||
|
|
||||||
|
|
||||||
void se_crypt_aes(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config, unsigned int mode, unsigned int (*callback)(void));
|
void se_crypt_aes(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config, unsigned int mode, unsigned int (*callback)(void));
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,8 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *),
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
/* Pass the status check key back to userland. */
|
/* Pass the status check key back to userland. */
|
||||||
args->X[1] = key;
|
args->X[1] = key;
|
||||||
|
/* Early return, leaving g_is_smc_in_progress == 1 */
|
||||||
|
return result;
|
||||||
} else {
|
} else {
|
||||||
/* No status to check. */
|
/* No status to check. */
|
||||||
clear_smc_callback(key);
|
clear_smc_callback(key);
|
||||||
|
@ -247,6 +249,21 @@ 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) {
|
||||||
|
/* Buf and size are unused. */
|
||||||
|
if (get_crypt_aes_done() == 0) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
/* smc_crypt_aes is done now. */
|
||||||
|
g_is_smc_in_progress = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t smc_crypt_aes(smc_args_t *args) {
|
||||||
|
return smc_wrapper_async(args, user_crypt_aes, smc_crypt_aes_status_check);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t smc_cpu_on(smc_args_t *args) {
|
uint32_t smc_cpu_on(smc_args_t *args) {
|
||||||
return cpu_on((uint32_t)args->X[1], args->X[2], args->X[3]);
|
return cpu_on((uint32_t)args->X[1], args->X[2], args->X[3]);
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include "smc_user.h"
|
#include "smc_user.h"
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
|
|
||||||
|
/* Globals. */
|
||||||
|
int g_crypt_aes_done = 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];
|
||||||
uint64_t wrapped_key[2];
|
uint64_t wrapped_key[2];
|
||||||
|
@ -27,3 +30,61 @@ uint32_t user_load_aes_key(smc_args_t *args) {
|
||||||
decrypt_data_into_keyslot(keyslot, 9, wrapped_key, 0x10);
|
decrypt_data_into_keyslot(keyslot, 9, wrapped_key, 0x10);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void set_crypt_aes_done(int done) {
|
||||||
|
g_crypt_aes_done = done & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_crypt_aes_done(void) {
|
||||||
|
return g_crypt_aes_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t crypt_aes_done_handler(void) {
|
||||||
|
se_check_for_error();
|
||||||
|
|
||||||
|
set_crypt_aes_done(1);
|
||||||
|
|
||||||
|
/* TODO: Manually trigger an SE interrupt (0x2C) */
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t user_crypt_aes(smc_args_t *args) {
|
||||||
|
uint32_t keyslot = args->X[1] & 3;
|
||||||
|
uint32_t mode = (args->X[1] >> 4) & 3;
|
||||||
|
|
||||||
|
uint64_t iv_ctr[2];
|
||||||
|
iv_ctr[0] = args->X[2];
|
||||||
|
iv_ctr[1] = args->X[3];
|
||||||
|
|
||||||
|
uint32_t in_ll_paddr = (uint32_t)(args->X[4]);
|
||||||
|
uint32_t out_ll_paddr = (uint32_t)(args->X[5]);
|
||||||
|
|
||||||
|
size_t size = args->X[6];
|
||||||
|
if (size & 0xF) {
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
set_crypt_aes_done(0);
|
||||||
|
|
||||||
|
uint64_t result = 0;
|
||||||
|
switch (mode) {
|
||||||
|
case 0: /* CBC Encryption */
|
||||||
|
se_aes_cbc_encrypt_insecure(keyslot, out_ll_paddr, in_ll_paddr, size, iv_ctr, crypt_aes_done_handler);
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
case 1: /* CBC Decryption */
|
||||||
|
se_aes_cbc_decrypt_insecure(keyslot, out_ll_paddr, in_ll_paddr, size, iv_ctr, crypt_aes_done_handler);
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
case 2: /* CTR "Encryption" */
|
||||||
|
se_aes_ctr_crypt_insecure(keyslot, out_ll_paddr, in_ll_paddr, size, iv_ctr, crypt_aes_done_handler);
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -18,4 +18,8 @@ uint32_t user_unwrap_rsa_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);
|
||||||
|
|
||||||
|
|
||||||
|
void set_crypt_aes_done(int done);
|
||||||
|
int get_crypt_aes_done(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in a new issue