From 5d44ef0af68865624e73428a200e7ff04ec6aa63 Mon Sep 17 00:00:00 2001
From: shchmue <shchmue@gmail.com>
Date: Fri, 25 Oct 2019 21:48:29 -0600
Subject: [PATCH] se: Hardcode internal se vars, add HMAC-SHA256

---
 source/sec/se.c      | 54 ++++++++++++++++++++++++++++++++++++--------
 source/sec/se.h      |  1 +
 source/sec/se_t210.h |  4 ++--
 3 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/source/sec/se.c b/source/sec/se.c
index fbd0d4c..bf76e16 100644
--- a/source/sec/se.c
+++ b/source/sec/se.c
@@ -94,17 +94,15 @@ static int _se_wait()
 
 static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size)
 {
-	se_ll_t *ll_dst = NULL, *ll_src = NULL;
+	se_ll_t *ll_dst = (se_ll_t *)0xECFFFFE0, *ll_src = (se_ll_t *)0xECFFFFF0;
 
 	if (dst)
 	{
-		ll_dst = (se_ll_t *)malloc(sizeof(se_ll_t));
 		_se_ll_init(ll_dst, (u32)dst, dst_size);
 	}
 
 	if (src)
 	{
-		ll_src = (se_ll_t *)malloc(sizeof(se_ll_t));
 		_se_ll_init(ll_src, (u32)src, src_size);
 	}
 
@@ -120,11 +118,6 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
 
 	bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
 
-	if (src)
-		free(ll_src);
-	if (dst)
-		free(ll_dst);
-
 	return res;
 }
 
@@ -428,7 +421,7 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size)
 	int res;
 	// Setup config for SHA256, size = BITS(src_size).
 	SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
-	SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_ENABLE;
+	SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_ENABLE;
 	SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3);
 	SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 1) = 0;
 	SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 2) = 0;
@@ -448,3 +441,46 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size)
 
 	return res;
 }
+
+int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size) {
+	int res = 0;
+	u8 *secret = (u8 *)malloc(0x40);
+	u8 *ipad = (u8 *)malloc(0x40 + src_size);
+	u8 *opad = (u8 *)malloc(0x60);
+
+	if (key_size > 0x40)
+	{
+		if (!se_calc_sha256(secret, key, key_size))
+			goto out;
+		memset(secret + 0x20, 0, 0x20);
+	}
+	else
+	{
+		memcpy(secret, key, key_size);
+		memset(secret + key_size, 0, 0x40 - key_size);
+	}
+
+	u32 *secret32 = (u32 *)secret;
+	u32 *ipad32 = (u32 *)ipad;
+	u32 *opad32 = (u32 *)opad;
+	for (u32 i = 0; i < 0x10; i++)
+	{
+		ipad32[i] = secret32[i] ^ 0x36363636;
+		opad32[i] = secret32[i] ^ 0x5C5C5C5C;
+	}
+
+	memcpy(ipad + 0x40, src, src_size);
+	if (!se_calc_sha256(dst, ipad, 0x40 + src_size))
+		goto out;
+	memcpy(opad + 0x40, dst, 0x20);
+	if (!se_calc_sha256(dst, opad, 0x60))
+		goto out;
+
+	res = 1;
+
+out:;
+	free(secret);
+	free(ipad);
+	free(opad);
+	return res;
+}
diff --git a/source/sec/se.h b/source/sec/se.h
index 434a97a..0d517c7 100644
--- a/source/sec/se.h
+++ b/source/sec/se.h
@@ -35,5 +35,6 @@ int se_aes_xts_crypt_sec(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, const vo
 int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, const void *src, u32 secsize, u32 num_secs);
 int se_aes_cmac(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size);
 int se_calc_sha256(void *dst, const void *src, u32 src_size);
+int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
 
 #endif
diff --git a/source/sec/se_t210.h b/source/sec/se_t210.h
index 760527d..7d93099 100644
--- a/source/sec/se_t210.h
+++ b/source/sec/se_t210.h
@@ -231,8 +231,8 @@
 #define SE_SPARE_0_REG_OFFSET		0x80c
 
 #define SE_SHA_CONFIG_REG_OFFSET	0x200
-#define SHA_DISABLE		0
-#define SHA_ENABLE		1
+#define SHA_INIT_DISABLE	0
+#define SHA_INIT_ENABLE		1
 
 #define SE_SHA_MSG_LENGTH_REG_OFFSET	0x204
 #define SE_SHA_MSG_LEFT_REG_OFFSET		0x214