mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 00:12:03 +00:00
Finish SE API operations other than context-saving.
This commit is contained in:
parent
5e1c137e26
commit
72da8dcf5a
2 changed files with 106 additions and 5 deletions
|
@ -332,6 +332,29 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal
|
|||
while (!(g_security_engine->INT_STATUS_REG & 2)) { /* Wait a while */ }
|
||||
}
|
||||
|
||||
void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
|
||||
uint8_t stack_buf[KEYSIZE_RSA_MAX];
|
||||
|
||||
if (g_security_engine == NULL || keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) {
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Endian swap the input. */
|
||||
for (size_t i = size; i > 0; i--) {
|
||||
stack_buf[i] = *((uint8_t *)buf + size - i);
|
||||
}
|
||||
|
||||
g_security_engine->CONFIG_REG = (ALG_RSA | DST_RSAREG);
|
||||
g_security_engine->RSA_CONFIG = keyslot << 24;
|
||||
g_security_engine->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1;
|
||||
g_security_engine->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2;
|
||||
|
||||
|
||||
flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX);
|
||||
trigger_se_blocking_op(1, NULL, 0, stack_buf, src_size);
|
||||
se_get_exp_mod_output(dst, dst_size);
|
||||
}
|
||||
|
||||
void se_get_exp_mod_output(void *buf, size_t size) {
|
||||
size_t num_dwords = (size >> 2);
|
||||
if (num_dwords < 1) {
|
||||
|
@ -529,7 +552,7 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con
|
|||
|
||||
/* Copy output CMAC. */
|
||||
for (unsigned int i = 0; i < (cmac_size >> 2); i++) {
|
||||
((uint32_t *)cmac)[i] = read32le(g_security_engine->HASH_OUTPUT, i << 2);
|
||||
((uint32_t *)cmac)[i] = read32le(g_security_engine->HASH_RESULT_REG, i << 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -540,4 +563,69 @@ void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size,
|
|||
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202);
|
||||
}
|
||||
|
||||
/* SHA256 Implementation. */
|
||||
void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
|
||||
if (g_security_engine == NULL) {
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Setup config for SHA256, size = BITS(src_size) */
|
||||
g_security_engine->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG);
|
||||
g_security_engine->SHA_CONFIG_REG = 1;
|
||||
g_security_engine->SHA_MSG_LENGTH_REG = (unsigned int)(src_size << 3);
|
||||
g_security_engine->_0x20C = 0;
|
||||
g_security_engine->_0x210 = 0;
|
||||
g_security_engine->SHA_MSG_LEFT_REG = 0;
|
||||
g_security_engine->_0x218 = (unsigned int)(src_size << 3);
|
||||
g_security_engine->_0x21C = 0;
|
||||
g_security_engine->_0x220 = 0;
|
||||
g_security_engine->_0x224 = 0;
|
||||
|
||||
/* Trigger the operation. */
|
||||
trigger_se_blocking_op(1, NULL, 0, src, src_size);
|
||||
|
||||
/* Copy output hash. */
|
||||
for (unsigned int i = 0; i < (0x20 >> 2); i++) {
|
||||
((uint32_t *)dst)[i] = read32be(g_security_engine->HASH_RESULT_REG, i << 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* RNG API */
|
||||
void se_initialize_rng(unsigned int keyslot) {
|
||||
if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) {
|
||||
panic();
|
||||
}
|
||||
|
||||
/* To initialize the RNG, we'll perform an RNG operation into an output buffer. */
|
||||
/* This will be discarded, when done. */
|
||||
uint8_t output_buf[0x10];
|
||||
|
||||
g_security_engine->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */
|
||||
g_security_engine->RNG_RESEED_INTERVAL_REG = 70001;
|
||||
g_security_engine->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
||||
g_security_engine->CRYPTO_REG = (keyslot << 24) | 0x108;
|
||||
g_security_engine->RNG_CONFIG_REG = 5;
|
||||
g_security_engine->BLOCK_COUNT_REG = 0;
|
||||
trigger_se_blocking_op(1, output_buf, 0x10, NULL, 0);
|
||||
}
|
||||
|
||||
void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
||||
if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) {
|
||||
panic();
|
||||
}
|
||||
|
||||
uint32_t num_blocks = size >> 4;
|
||||
size_t aligned_size = num_blocks << 4;
|
||||
g_security_engine->CONFIG_REG = (ALG_RNG | DST_MEMORY);
|
||||
g_security_engine->CRYPTO_REG = (keyslot << 24) | 0x108;
|
||||
g_security_engine->RNG_CONFIG_REG = 4;
|
||||
|
||||
if (num_blocks >= 1) {
|
||||
g_security_engine->BLOCK_COUNT_REG = num_blocks - 1;
|
||||
trigger_se_blocking_op(1, dst, aligned_size, NULL, 0);
|
||||
}
|
||||
if (size > aligned_size) {
|
||||
se_perform_aes_block_operation(dst + aligned_size, size - aligned_size, NULL, 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -40,6 +40,10 @@
|
|||
#define DST_SRK (3 << DST_SHIFT)
|
||||
#define DST_RSAREG (4 << DST_SHIFT)
|
||||
|
||||
#define ENCMODE_SHIFT (24)
|
||||
#define DECMODE_SHIFT (16)
|
||||
#define ENCMODE_SHA256 (5 << ENCMODE_SHIFT)
|
||||
|
||||
#define HASH_DISABLE (0x0)
|
||||
#define HASH_ENABLE (0x1)
|
||||
|
||||
|
@ -64,8 +68,18 @@ typedef struct security_engine {
|
|||
unsigned int OUT_LL_ADDR_REG;
|
||||
unsigned int _0x28;
|
||||
unsigned int _0x2C;
|
||||
unsigned char HASH_OUTPUT[0x10];
|
||||
unsigned char reserved0x40[0x240];
|
||||
unsigned char HASH_RESULT_REG[0x20];
|
||||
unsigned char _0x50[0x1B0];
|
||||
unsigned int SHA_CONFIG_REG;
|
||||
unsigned int SHA_MSG_LENGTH_REG;
|
||||
unsigned int _0x20C;
|
||||
unsigned int _0x210;
|
||||
unsigned int SHA_MSG_LEFT_REG;
|
||||
unsigned int _0x218;
|
||||
unsigned int _0x21C;
|
||||
unsigned int _0x220;
|
||||
unsigned int _0x224;
|
||||
unsigned char _0x228[0x5C];
|
||||
unsigned int AES_KEY_READ_DISABLE_REG;
|
||||
unsigned int AES_KEYSLOT_FLAGS[0x10];
|
||||
unsigned char _0x2C4[0x3C];
|
||||
|
@ -171,7 +185,6 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co
|
|||
void se_initialize_rng(unsigned int keyslot);
|
||||
void se_generate_random(unsigned int keyslot, void *dst, size_t size);
|
||||
|
||||
/* TODO: SE context save API, consider extending AES API for secure world vs non-secure world operations. */
|
||||
/* In particular, smc_crypt_aes takes in raw DMA lists, and we need to support that. */
|
||||
/* TODO: SE context save API. */
|
||||
|
||||
#endif /* EXOSPHERE_SE_H */
|
||||
|
|
Loading…
Reference in a new issue