mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 00:12:03 +00:00
Implement the rest of smcCpuSuspend with skeleton SE API calls.
This commit is contained in:
parent
a90a431d61
commit
924d469344
7 changed files with 92 additions and 5 deletions
|
@ -11,8 +11,7 @@ static struct {
|
||||||
} g_registered_interrupts[MAX_REGISTERED_INTERRUPTS] = { {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL} };
|
} g_registered_interrupts[MAX_REGISTERED_INTERRUPTS] = { {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL} };
|
||||||
|
|
||||||
static unsigned int get_interrupt_id(void) {
|
static unsigned int get_interrupt_id(void) {
|
||||||
return 0;
|
return GICC_IAR;
|
||||||
/* TODO */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initializes the GIC. TODO: This must be called during wakeup. */
|
/* Initializes the GIC. TODO: This must be called during wakeup. */
|
||||||
|
|
|
@ -22,8 +22,55 @@ extern const uint32_t bpmpfw_bin_size;
|
||||||
|
|
||||||
/* Save security engine, and go to sleep. */
|
/* Save security engine, and go to sleep. */
|
||||||
void save_se_and_power_down_cpu(void) {
|
void save_se_and_power_down_cpu(void) {
|
||||||
|
uint32_t tzram_cmac[0x4] = {0};
|
||||||
|
|
||||||
|
uint8_t *tzram_encryption_src = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM));
|
||||||
|
uint8_t *tzram_encryption_dst = (uint8_t *)(LP0_ENTRY_GET_RAM_SEGMENT_ADDRESS(LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM));
|
||||||
|
uint8_t *tzram_store_address = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_TZRAM));
|
||||||
clear_priv_smc_in_progress();
|
clear_priv_smc_in_progress();
|
||||||
/* TODO. */
|
|
||||||
|
/* Flush cache. */
|
||||||
|
flush_dcache_all();
|
||||||
|
|
||||||
|
/* Encrypt and save TZRAM into DRAM using a random aes-256 key. */
|
||||||
|
se_generate_random_key(KEYSLOT_SWITCH_LP0TZRAMKEY, KEYSLOT_SWITCH_RNGKEY);
|
||||||
|
|
||||||
|
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
|
||||||
|
flush_dcache_range(tzram_encryption_src, tzram_encryption_src + LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
|
/* Use the all-zero cmac buffer as an IV. */
|
||||||
|
se_aes_256_cbc_encrypt(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_encryption_dst, LP0_TZRAM_SAVE_SIZE, tzram_encryption_src, LP0_TZRAM_SAVE_SIZE, tzram_cmac);
|
||||||
|
flush_dcache_range(tzram_encryption_dst, tzram_encryption_dst + LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
|
/* Copy encrypted TZRAM from IRAM to DRAM. */
|
||||||
|
memcpy(tzram_store_address, tzram_encryption_dst, LP0_TZRAM_SAVE_SIZE);
|
||||||
|
flush_dcache_range(tzram_store_address, tzram_store_address + LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
|
/* Compute CMAC. */
|
||||||
|
se_compute_aes_256_cmac(KEYSLOT_SWITCH_LP0TZRAMKEY, tzram_cmac, sizeof(tzram_cmac), tzram_encryption_dst, LP0_TZRAM_SAVE_SIZE);
|
||||||
|
|
||||||
|
/* Write CMAC, lock registers. */
|
||||||
|
APBDEV_PMC_SECURE_SCRATCH112_0 = tzram_cmac[0];
|
||||||
|
APBDEV_PMC_SECURE_SCRATCH113_0 = tzram_cmac[1];
|
||||||
|
APBDEV_PMC_SECURE_SCRATCH114_0 = tzram_cmac[2];
|
||||||
|
APBDEV_PMC_SECURE_SCRATCH115_0 = tzram_cmac[3];
|
||||||
|
APBDEV_PMC_SEC_DISABLE8_0 = 0x550000;
|
||||||
|
|
||||||
|
/* Save security engine state. */
|
||||||
|
uint8_t *se_state_dst = (uint8_t *)(WARMBOOT_GET_RAM_SEGMENT_ADDRESS(WARMBOOT_RAM_SEGMENT_ID_SE_STATE));
|
||||||
|
se_check_error_status_reg();
|
||||||
|
se_set_in_context_save_mode(true);
|
||||||
|
se_save_context(KEYSLOT_SWITCH_SRKKEY, KEYSLOT_SWITCH_RNGKEY, se_state_dst);
|
||||||
|
flush_dcache_range(se_state_dst, se_state_dst + 0x840);
|
||||||
|
APBDEV_PMC_SCRATCH43_0 = (uint32_t)(WARMBOOT_GET_RAM_SEGMENT_PA(WARMBOOT_RAM_SEGMENT_ID_SE_STATE));
|
||||||
|
se_set_in_context_save_mode(false);
|
||||||
|
se_check_error_status_reg();
|
||||||
|
|
||||||
|
if (!configitem_is_retail()) {
|
||||||
|
/* TODO: uart_log("OYASUMI"); */
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize_powerdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument) {
|
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument) {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
/* Exosphere Deep Sleep Entry implementation. */
|
/* Exosphere Deep Sleep Entry implementation. */
|
||||||
|
|
||||||
|
#define LP0_TZRAM_SAVE_SIZE 0xE000
|
||||||
|
|
||||||
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument);
|
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint, uint64_t argument);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -81,7 +81,7 @@
|
||||||
#define MMIO_DEVID_EXCEPTION_VECTORS 17
|
#define MMIO_DEVID_EXCEPTION_VECTORS 17
|
||||||
#define MMIO_DEVID_MAX 18
|
#define MMIO_DEVID_MAX 18
|
||||||
|
|
||||||
#define LP0_ENTRY_RAM_SEGMENT_ID_DECRYPTED_TZRAM 0
|
#define LP0_ENTRY_RAM_SEGMENT_ID_ENCRYPTED_TZRAM 0
|
||||||
#define LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE 1
|
#define LP0_ENTRY_RAM_SEGMENT_ID_LP0_ENTRY_CODE 1
|
||||||
#define LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM 2
|
#define LP0_ENTRY_RAM_SEGMENT_ID_CURRENT_TZRAM 2
|
||||||
#define LP0_ENTRY_RAM_SEGMENT_ID_MAX 3
|
#define LP0_ENTRY_RAM_SEGMENT_ID_MAX 3
|
||||||
|
|
|
@ -23,4 +23,12 @@ static inline uintptr_t get_pmc_base(void) {
|
||||||
#define APBDEV_PMC_WAKE2_STATUS_0 (*((volatile uint32_t *)(PMC_BASE + 0x168)))
|
#define APBDEV_PMC_WAKE2_STATUS_0 (*((volatile uint32_t *)(PMC_BASE + 0x168)))
|
||||||
#define APBDEV_PMC_CNTRL2_0 (*((volatile uint32_t *)(PMC_BASE + 0x440)))
|
#define APBDEV_PMC_CNTRL2_0 (*((volatile uint32_t *)(PMC_BASE + 0x440)))
|
||||||
|
|
||||||
|
#define APBDEV_PMC_SCRATCH43_0 (*((volatile uint32_t *)(PMC_BASE + 0x22C)))
|
||||||
|
#define APBDEV_PMC_SEC_DISABLE8_0 (*((volatile uint32_t *)(PMC_BASE + 0x5C0)))
|
||||||
|
#define APBDEV_PMC_SECURE_SCRATCH112_0 (*((volatile uint32_t *)(PMC_BASE + 0xB18)))
|
||||||
|
#define APBDEV_PMC_SECURE_SCRATCH113_0 (*((volatile uint32_t *)(PMC_BASE + 0xB1C)))
|
||||||
|
#define APBDEV_PMC_SECURE_SCRATCH114_0 (*((volatile uint32_t *)(PMC_BASE + 0xB20)))
|
||||||
|
#define APBDEV_PMC_SECURE_SCRATCH115_0 (*((volatile uint32_t *)(PMC_BASE + 0xB24)))
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,6 +49,11 @@ void se_operation_completed(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void se_check_error_status_reg(void) {
|
||||||
|
if (SECURITY_ENGINE->ERR_STATUS_REG) {
|
||||||
|
generic_panic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void se_check_for_error(void) {
|
void se_check_for_error(void) {
|
||||||
if (SECURITY_ENGINE->INT_STATUS_REG & 0x10000 || SECURITY_ENGINE->FLAGS_REG & 3 || SECURITY_ENGINE->ERR_STATUS_REG) {
|
if (SECURITY_ENGINE->INT_STATUS_REG & 0x10000 || SECURITY_ENGINE->FLAGS_REG & 3 || SECURITY_ENGINE->ERR_STATUS_REG) {
|
||||||
|
@ -528,6 +533,10 @@ 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);
|
se_compute_aes_cmac(keyslot, cmac, cmac_size, data, data_size, 0x202);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
/* SHA256 Implementation. */
|
/* SHA256 Implementation. */
|
||||||
void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
|
void se_calculate_sha256(void *dst, const void *src, size_t src_size) {
|
||||||
/* Setup config for SHA256, size = BITS(src_size) */
|
/* Setup config for SHA256, size = BITS(src_size) */
|
||||||
|
@ -590,3 +599,17 @@ void se_generate_random(unsigned int keyslot, void *dst, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* SE context save API. */
|
||||||
|
void se_set_in_context_save_mode(bool is_context_save_mode) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
void se_save_context(unsigned int srk_keyslot, unsigned int rng_keyslot, void *dst) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef EXOSPHERE_SE_H
|
#ifndef EXOSPHERE_SE_H
|
||||||
#define EXOSPHERE_SE_H
|
#define EXOSPHERE_SE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
@ -8,6 +9,8 @@
|
||||||
|
|
||||||
/* Exosphere driver for the Tegra X1 security engine. */
|
/* Exosphere driver for the Tegra X1 security engine. */
|
||||||
|
|
||||||
|
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
|
||||||
|
#define KEYSLOT_SWITCH_SRKKEY 0x8
|
||||||
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
|
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
|
||||||
#define KEYSLOT_SWITCH_TEMPKEY 0x9
|
#define KEYSLOT_SWITCH_TEMPKEY 0x9
|
||||||
#define KEYSLOT_SWITCH_SESSIONKEY 0xA
|
#define KEYSLOT_SWITCH_SESSIONKEY 0xA
|
||||||
|
@ -146,6 +149,7 @@ static inline volatile security_engine_t *get_security_engine(void) {
|
||||||
/* This function MUST be registered to fire on the appropriate interrupt. */
|
/* This function MUST be registered to fire on the appropriate interrupt. */
|
||||||
void se_operation_completed(void);
|
void se_operation_completed(void);
|
||||||
|
|
||||||
|
void se_check_error_status_reg(void);
|
||||||
void se_check_for_error(void);
|
void se_check_for_error(void);
|
||||||
void se_trigger_interrupt(void);
|
void se_trigger_interrupt(void);
|
||||||
void se_clear_interrupts(void); /* TODO */
|
void se_clear_interrupts(void); /* TODO */
|
||||||
|
@ -176,6 +180,7 @@ void se_aes_128_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_si
|
||||||
void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);
|
void se_aes_256_ecb_encrypt_block(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_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_decrypt_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_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv);
|
||||||
|
|
||||||
/* Hash API */
|
/* Hash API */
|
||||||
void se_calculate_sha256(void *dst, const void *src, size_t src_size);
|
void se_calculate_sha256(void *dst, const void *src, size_t src_size);
|
||||||
|
@ -189,6 +194,9 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co
|
||||||
void se_initialize_rng(unsigned int keyslot);
|
void se_initialize_rng(unsigned int keyslot);
|
||||||
void se_generate_random(unsigned int keyslot, void *dst, size_t size);
|
void se_generate_random(unsigned int keyslot, void *dst, size_t size);
|
||||||
|
|
||||||
/* TODO: SE context save API. */
|
/* SE context save API. */
|
||||||
|
void se_set_in_context_save_mode(bool is_context_save_mode);
|
||||||
|
void se_generate_random_key(unsigned int dst_keyslot, unsigned int rng_keyslot);
|
||||||
|
void se_save_context(unsigned int srk_keyslot, unsigned int rng_keyslot, void *dst);
|
||||||
|
|
||||||
#endif /* EXOSPHERE_SE_H */
|
#endif /* EXOSPHERE_SE_H */
|
||||||
|
|
Loading…
Reference in a new issue