exo2: suspend fixes (sleep/wake now works on hardware)

This commit is contained in:
Michael Scire
2020-06-08 03:53:40 -07:00
committed by SciresM
parent 2fb363dcf0
commit 95d38a1a94
10 changed files with 77 additions and 18 deletions

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EXOSPHERE_WARMBOOT_BIN_PMC_H
#define EXOSPHERE_WARMBOOT_BIN_PMC_H
@@ -39,6 +39,10 @@
#define APBDEV_PMC_SEC_DISABLE2_0 MAKE_PMC_REG(0x2C4)
#define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8)
#define APBDEV_PMC_SECURE_SCRATCH21_0 MAKE_PMC_REG(0x334)
#define APBDEV_PMC_SECURE_SCRATCH24_0 MAKE_PMC_REG(0x340)
#define APBDEV_PMC_SECURE_SCRATCH25_0 MAKE_PMC_REG(0x344)
#define APBDEV_PMC_SECURE_SCRATCH26_0 MAKE_PMC_REG(0x348)
#define APBDEV_PMC_SECURE_SCRATCH27_0 MAKE_PMC_REG(0x34C)
#define APBDEV_PMC_SECURE_SCRATCH32_0 MAKE_PMC_REG(0x360)
#define APBDEV_PMC_SECURE_SCRATCH34_0 MAKE_PMC_REG(0x368)
#define APBDEV_PMC_SECURE_SCRATCH35_0 MAKE_PMC_REG(0x36C)

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "utils.h"
@@ -56,7 +56,7 @@ void se_verify_flags_cleared(void) {
void clear_aes_keyslot(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
reboot();
}
@@ -70,7 +70,7 @@ void clear_aes_keyslot(unsigned int keyslot) {
void clear_rsa_keyslot(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_RSA_MAX) {
reboot();
}
@@ -90,7 +90,7 @@ void clear_rsa_keyslot(unsigned int keyslot) {
void clear_aes_keyslot_iv(unsigned int keyslot) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
reboot();
}
@@ -101,6 +101,20 @@ void clear_aes_keyslot_iv(unsigned int keyslot) {
}
}
void decrypt_data_into_keyslot_256(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSLOT_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) {
reboot();
}
se->SE_CONFIG = (0x202 << 16) | (ALG_AES_DEC | DST_KEYTAB);
se->SE_CRYPTO_CONFIG = keyslot_src << 24;
se->SE_CRYPTO_LAST_BLOCK = 0;
se->SE_CRYPTO_KEYTABLE_DST = keyslot_dst << 8;
trigger_se_blocking_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
}
void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs();
@@ -148,7 +162,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src,
void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
reboot();
}
@@ -161,7 +175,7 @@ void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size,
void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) {
reboot();
}
@@ -185,7 +199,7 @@ void shift_left_xor_rb(uint8_t *key) {
void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX) {
reboot();
}
@@ -239,7 +253,7 @@ void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size,
void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) {
volatile tegra_se_t *se = se_get_regs();
if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) {
reboot();
}

View File

@@ -13,14 +13,15 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EXOSPHERE_WARMBOOT_BIN_SE_H
#define EXOSPHERE_WARMBOOT_BIN_SE_H
#define SE_BASE 0x70012000
#define MAKE_SE_REG(n) MAKE_REG32(SE_BASE + n)
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x2
#define KEYSLOT_SWITCH_LP0TZRAMKEK 0x2
#define KEYSLOT_SWITCH_LP0TZRAMKEY 0x3
#define KEYSLOT_SWITCH_SRKGENKEY 0x8
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
#define KEYSLOT_SWITCH_TEMPKEY 0x9
@@ -170,6 +171,8 @@ void clear_aes_keyslot(unsigned int keyslot);
void clear_rsa_keyslot(unsigned int keyslot);
void clear_aes_keyslot_iv(unsigned int keyslot);
void decrypt_data_into_keyslot_256(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size);
void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size);
void se_aes_256_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size);

View File

@@ -57,6 +57,20 @@ void secmon_restore_to_tzram(const uint32_t target_firmware) {
}
void secmon_decrypt_saved_image(void *dst, const void *src, size_t size) {
/* Derive the key used for context save. */
{
const uint32_t key_source[4] = { APBDEV_PMC_SECURE_SCRATCH24_0, APBDEV_PMC_SECURE_SCRATCH25_0, APBDEV_PMC_SECURE_SCRATCH26_0, APBDEV_PMC_SECURE_SCRATCH27_0 };
clear_aes_keyslot(KEYSLOT_SWITCH_LP0TZRAMKEY);
decrypt_data_into_keyslot_256(KEYSLOT_SWITCH_LP0TZRAMKEY, KEYSLOT_SWITCH_LP0TZRAMKEK, key_source, sizeof(key_source));
clear_aes_keyslot(KEYSLOT_SWITCH_LP0TZRAMKEK);
APBDEV_PMC_SECURE_SCRATCH24_0 = 0;
APBDEV_PMC_SECURE_SCRATCH25_0 = 0;
APBDEV_PMC_SECURE_SCRATCH26_0 = 0;
APBDEV_PMC_SECURE_SCRATCH27_0 = 0;
}
/* First, AES-256-CBC decrypt the image into TZRAM. */
se_aes_256_cbc_decrypt(KEYSLOT_SWITCH_LP0TZRAMKEY, dst, size, src, size);
@@ -85,7 +99,7 @@ void secmon_decrypt_saved_image(void *dst, const void *src, size_t size) {
bool secmon_should_clear_aes_keyslot(unsigned int keyslot) {
/* We'll just compare keyslot against a hardcoded list of keys. */
static const uint8_t saved_keyslots[6] = {
KEYSLOT_SWITCH_LP0TZRAMKEY,
KEYSLOT_SWITCH_LP0TZRAMKEK,
KEYSLOT_SWITCH_SESSIONKEY,
KEYSLOT_SWITCH_RNGKEY,
KEYSLOT_SWITCH_MASTERKEY,