mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-18 08:11:21 +00:00
90 lines
2.1 KiB
C
90 lines
2.1 KiB
C
#include <stdint.h>
|
|
|
|
#include "utils.h"
|
|
#include "smc_api.h"
|
|
#include "smc_user.h"
|
|
#include "se.h"
|
|
|
|
/* Globals. */
|
|
int g_crypt_aes_done = 0;
|
|
|
|
uint32_t user_load_aes_key(smc_args_t *args) {
|
|
uint64_t sealed_kek[2];
|
|
uint64_t wrapped_key[2];
|
|
|
|
uint32_t keyslot = (uint32_t)args->X[1];
|
|
if (keyslot > 3) {
|
|
return 2;
|
|
}
|
|
|
|
/* Copy keydata */
|
|
sealed_kek[0] = args->X[2];
|
|
sealed_kek[1] = args->X[3];
|
|
wrapped_key[0] = args->X[4];
|
|
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;
|
|
}
|
|
|
|
|
|
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;
|
|
} |