se: Ensure aligned key/iv/ctr/hash copy

This commit is contained in:
CTCaer 2020-12-05 20:39:17 +02:00
parent 4a152504cb
commit 8249d9e1a2
3 changed files with 42 additions and 22 deletions

View file

@ -21,6 +21,7 @@
#include "se_t210.h" #include "se_t210.h"
#include <mem/heap.h> #include <mem/heap.h>
#include <soc/bpmp.h> #include <soc/bpmp.h>
#include <soc/pmc.h>
#include <soc/t210.h> #include <soc/t210.h>
#include <utils/util.h> #include <utils/util.h>
@ -160,9 +161,11 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr
static void _se_aes_ctr_set(void *ctr) static void _se_aes_ctr_set(void *ctr)
{ {
u32 *data = (u32 *)ctr; u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
for (u32 i = 0; i < 4; i++) memcpy(data, ctr, TEGRA_SE_AES_BLOCK_SIZE);
SE(SE_CRYPTO_CTR_REG_OFFSET + 4 * i) = data[i];
for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
SE(SE_CRYPTO_CTR_REG_OFFSET + (4 * i)) = data[i];
} }
void se_rsa_acc_ctrl(u32 rs, u32 flags) void se_rsa_acc_ctrl(u32 rs, u32 flags)
@ -190,8 +193,10 @@ u32 se_key_acc_ctrl_get(u32 ks)
void se_aes_key_set(u32 ks, void *key, u32 size) void se_aes_key_set(u32 ks, void *key, u32 size)
{ {
u32 *data = (u32 *)key; u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
for (u32 i = 0; i < size / 4; i++) memcpy(data, key, size);
for (u32 i = 0; i < (size / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
@ -200,9 +205,10 @@ void se_aes_key_set(u32 ks, void *key, u32 size)
void se_aes_iv_set(u32 ks, void *iv) void se_aes_iv_set(u32 ks, void *iv)
{ {
u32 *data = (u32 *)iv; u32 data[TEGRA_SE_AES_BLOCK_SIZE / 4];
memcpy(data, iv, TEGRA_SE_AES_BLOCK_SIZE);
for (u32 i = 0; i < TEGRA_SE_AES_MIN_KEY_SIZE / 4; i++) for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i]; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = data[i];
@ -211,17 +217,20 @@ void se_aes_iv_set(u32 ks, void *iv)
void se_aes_key_get(u32 ks, void *key, u32 size) void se_aes_key_get(u32 ks, void *key, u32 size)
{ {
u32 *data = (u32 *)key; u32 data[TEGRA_SE_AES_MAX_KEY_SIZE / 4];
for (u32 i = 0; i < size / 4; i++)
for (u32 i = 0; i < (size / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET); data[i] = SE(SE_KEYTABLE_DATA0_REG_OFFSET);
} }
memcpy(key, data, size);
} }
void se_aes_key_clear(u32 ks) void se_aes_key_clear(u32 ks)
{ {
for (u32 i = 0; i < TEGRA_SE_AES_MAX_KEY_SIZE / 4; i++) for (u32 i = 0; i < (TEGRA_SE_AES_MAX_KEY_SIZE / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
@ -230,7 +239,7 @@ void se_aes_key_clear(u32 ks)
void se_aes_iv_clear(u32 ks) void se_aes_iv_clear(u32 ks)
{ {
for (u32 i = 0; i < TEGRA_SE_AES_MIN_KEY_SIZE / 4; i++) for (u32 i = 0; i < (TEGRA_SE_AES_BLOCK_SIZE / 4); i++)
{ {
SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i; SE(SE_KEYTABLE_REG_OFFSET) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(QUAD_ORG_IV) | i;
SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0; SE(SE_KEYTABLE_DATA0_REG_OFFSET) = 0;
@ -365,10 +374,10 @@ int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u
int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot) int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot)
{ {
int res; int res;
u32 *hash32 = (u32 *)hash; u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
//! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256. //! TODO: src_size must be 512 bit aligned if continuing and not last block for SHA256.
if (src_size > 0xFFFFFF || (u32)hash % 4 || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer. if (src_size > 0xFFFFFF || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer.
return 0; return 0;
// Setup config for SHA256. // Setup config for SHA256.
@ -400,7 +409,8 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1]; SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1];
// Restore hash reg. // Restore hash reg.
for (u32 i = 0; i < 8; i++) memcpy(hash32, hash, TEGRA_SE_SHA_256_SIZE);
for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]); SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]);
} }
@ -417,8 +427,9 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
} }
// Copy output hash. // Copy output hash.
for (u32 i = 0; i < 8; i++) for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
} }
return res; return res;
@ -431,7 +442,7 @@ int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size)
int se_calc_sha256_finalize(void *hash, u32 *msg_left) int se_calc_sha256_finalize(void *hash, u32 *msg_left)
{ {
u32 *hash32 = (u32 *)hash; u32 hash32[TEGRA_SE_SHA_256_SIZE / 4];
int res = _se_execute_finalize(); int res = _se_execute_finalize();
// Backup message left. // Backup message left.
@ -442,8 +453,9 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left)
} }
// Copy output hash. // Copy output hash.
for (u32 i = 0; i < 8; i++) for (u32 i = 0; i < (TEGRA_SE_SHA_256_SIZE / 4); i++)
hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)));
memcpy(hash, hash32, TEGRA_SE_SHA_256_SIZE);
return res; return res;
} }
@ -501,7 +513,7 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
// Save SRK to PMC secure scratches. // Save SRK to PMC secure scratches.
SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK); SE(SE_CONTEXT_SAVE_CONFIG_REG_OFFSET) = SE_CONTEXT_SAVE_SRC(SRK);
SE(0x80) = 0; // SE_CRYPTO_LAST_BLOCK SE(SE_CRYPTO_LAST_BLOCK) = 0;
_se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0); _se_execute_oneshot(OP_CTX_SAVE, NULL, 0, NULL, 0);
// End context save. // End context save.
@ -510,10 +522,10 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
// Get SRK. // Get SRK.
u32 srk[4]; u32 srk[4];
srk[0] = PMC(0xC0); srk[0] = PMC(APBDEV_PMC_SECURE_SCRATCH4);
srk[1] = PMC(0xC4); srk[1] = PMC(APBDEV_PMC_SECURE_SCRATCH5);
srk[2] = PMC(0x224); srk[2] = PMC(APBDEV_PMC_SECURE_SCRATCH6);
srk[3] = PMC(0x228); srk[3] = PMC(APBDEV_PMC_SECURE_SCRATCH7);
// Decrypt context. // Decrypt context.
se_aes_key_clear(3); se_aes_key_clear(3);

View file

@ -265,6 +265,10 @@
#define TEGRA_SE_AES_MIN_KEY_SIZE 16 #define TEGRA_SE_AES_MIN_KEY_SIZE 16
#define TEGRA_SE_AES_MAX_KEY_SIZE 32 #define TEGRA_SE_AES_MAX_KEY_SIZE 32
#define TEGRA_SE_AES_IV_SIZE 16 #define TEGRA_SE_AES_IV_SIZE 16
#define TEGRA_SE_SHA_512_SIZE 64
#define TEGRA_SE_SHA_384_SIZE 48
#define TEGRA_SE_SHA_256_SIZE 32
#define TEGRA_SE_SHA_192_SIZE 24
#define TEGRA_SE_RNG_IV_SIZE 16 #define TEGRA_SE_RNG_IV_SIZE 16
#define TEGRA_SE_RNG_DT_SIZE 16 #define TEGRA_SE_RNG_DT_SIZE 16
#define TEGRA_SE_RNG_KEY_SIZE 16 #define TEGRA_SE_RNG_KEY_SIZE 16

View file

@ -40,6 +40,8 @@
#define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD) #define PMC_SCRATCH0_MODE_CUSTOM_ALL (PMC_SCRATCH0_MODE_RECOVERY | PMC_SCRATCH0_MODE_FASTBOOT | PMC_SCRATCH0_MODE_PAYLOAD)
#define APBDEV_PMC_SCRATCH1 0x54 #define APBDEV_PMC_SCRATCH1 0x54
#define APBDEV_PMC_SCRATCH20 0xA0 #define APBDEV_PMC_SCRATCH20 0xA0
#define APBDEV_PMC_SECURE_SCRATCH4 0xC0
#define APBDEV_PMC_SECURE_SCRATCH5 0xC4
#define APBDEV_PMC_PWR_DET_VAL 0xE4 #define APBDEV_PMC_PWR_DET_VAL 0xE4
#define PMC_PWR_DET_SDMMC1_IO_EN BIT(12) #define PMC_PWR_DET_SDMMC1_IO_EN BIT(12)
#define PMC_PWR_DET_AUDIO_HV BIT(18) #define PMC_PWR_DET_AUDIO_HV BIT(18)
@ -63,6 +65,8 @@
#define APBDEV_PMC_IO_DPD2_REQ 0x1C0 #define APBDEV_PMC_IO_DPD2_REQ 0x1C0
#define APBDEV_PMC_VDDP_SEL 0x1CC #define APBDEV_PMC_VDDP_SEL 0x1CC
#define APBDEV_PMC_DDR_CFG 0x1D0 #define APBDEV_PMC_DDR_CFG 0x1D0
#define APBDEV_PMC_SECURE_SCRATCH6 0x224
#define APBDEV_PMC_SECURE_SCRATCH7 0x228
#define APBDEV_PMC_SCRATCH45 0x234 #define APBDEV_PMC_SCRATCH45 0x234
#define APBDEV_PMC_SCRATCH46 0x238 #define APBDEV_PMC_SCRATCH46 0x238
#define APBDEV_PMC_SCRATCH49 0x244 #define APBDEV_PMC_SCRATCH49 0x244