Implement the rest of smcCpuSuspend with skeleton SE API calls.

This commit is contained in:
Michael Scire 2018-02-27 17:07:30 -08:00
parent a90a431d61
commit 924d469344
7 changed files with 92 additions and 5 deletions

View file

@ -11,8 +11,7 @@ static struct {
} g_registered_interrupts[MAX_REGISTERED_INTERRUPTS] = { {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL} };
static unsigned int get_interrupt_id(void) {
return 0;
/* TODO */
return GICC_IAR;
}
/* Initializes the GIC. TODO: This must be called during wakeup. */

View file

@ -22,8 +22,55 @@ extern const uint32_t bpmpfw_bin_size;
/* Save security engine, and go to sleep. */
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();
/* 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) {

View file

@ -5,6 +5,8 @@
/* 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);
#endif

View file

@ -81,7 +81,7 @@
#define MMIO_DEVID_EXCEPTION_VECTORS 17
#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_CURRENT_TZRAM 2
#define LP0_ENTRY_RAM_SEGMENT_ID_MAX 3

View file

@ -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_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

View file

@ -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) {
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);
}
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. */
void se_calculate_sha256(void *dst, const void *src, size_t 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 */
}

View file

@ -1,6 +1,7 @@
#ifndef EXOSPHERE_SE_H
#define EXOSPHERE_SE_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
@ -8,6 +9,8 @@
/* 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_TEMPKEY 0x9
#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. */
void se_operation_completed(void);
void se_check_error_status_reg(void);
void se_check_for_error(void);
void se_trigger_interrupt(void);
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_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_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv);
/* Hash API */
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_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 */