SMCCryptAes + Skeleton blocking AES API

This commit is contained in:
Michael Scire 2018-02-19 13:26:37 -08:00
parent 21c2405f15
commit d0beae376f
5 changed files with 96 additions and 1 deletions

View file

@ -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_security_engine_callback(callback);
/* Enable SE Interrupt firing for async op. */
g_security_engine->INT_ENABLE_REG = 0x10;
/* Setup Input/Output lists */
g_security_engine->IN_LL_ADDR_REG = in_ll_paddr;
g_security_engine->OUT_LL_ADDR_REG = out_ll_paddr;
@ -284,6 +287,9 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal
g_security_engine->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
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);
trigger_se_rsa_op(stack_buf, size);

View file

@ -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);
/* 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_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));
/* 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));

View file

@ -180,6 +180,8 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *),
if (result == 0) {
/* Pass the status check key back to userland. */
args->X[1] = key;
/* Early return, leaving g_is_smc_in_progress == 1 */
return result;
} else {
/* No status to check. */
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);
}
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) {
return cpu_on((uint32_t)args->X[1], args->X[2], args->X[3]);

View file

@ -5,6 +5,9 @@
#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];
@ -27,3 +30,61 @@ uint32_t user_load_aes_key(smc_args_t *args) {
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;
}

View file

@ -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_unwrap_aes_wrapped_titlekey(smc_args_t *args);
void set_crypt_aes_done(int done);
int get_crypt_aes_done(void);
#endif