summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVencislav Atanasov <user890104@freemyipod.org>2024-12-11 00:04:07 +0200
committerVencislav Atanasov <user890104@freemyipod.org>2024-12-11 00:04:26 +0200
commit4d632a1774d88b8f1d3f96a578a0c376fb5944bb (patch)
treebaed7d95457d0298185f99c6467b319d482dfe1b
parent68c51456ff8e85795a69acbd11e8eb9b0c64da10 (diff)
downloadrockbox-4d632a1774.tar.gz
rockbox-4d632a1774.zip
S5L8702: Move IM3 sign/crypt functions from norboot to crypto
Also adds support for IM3 functions and SHA-1 on S5L8720. Tested on ipod6g (normal and bootloader builds) This is a part of the large iPod Nano 3G and iPod Nano 4G support patch. Credit: Cástor Muñoz <cmvidal@gmail.com> Change-Id: Ic5e6f5a3321d4b1ec4efd753a4c30e29d83fd7c2
-rw-r--r--firmware/target/arm/s5l8702/crypto-s5l8702.c32
-rw-r--r--firmware/target/arm/s5l8702/crypto-s5l8702.h51
-rw-r--r--firmware/target/arm/s5l8702/norboot-s5l8702.c23
-rw-r--r--firmware/target/arm/s5l8702/norboot-target.h39
4 files changed, 86 insertions, 59 deletions
diff --git a/firmware/target/arm/s5l8702/crypto-s5l8702.c b/firmware/target/arm/s5l8702/crypto-s5l8702.c
index 0788177de7..a6f148112f 100644
--- a/firmware/target/arm/s5l8702/crypto-s5l8702.c
+++ b/firmware/target/arm/s5l8702/crypto-s5l8702.c
@@ -68,6 +68,10 @@ void sha1(void* data, uint32_t size, void* hash)
while (SHA1CONFIG & 1);
SHA1RESET = 0;
SHA1CONFIG = 0;
+#if CONFIG_CPU == S5L8720
+ SHA1UNK10 = 0;
+ SHA1UNK80 = 0;
+#endif
while (!done)
{
space = ((uint32_t)databuf) - ((uint32_t)data) - size + 64;
@@ -100,3 +104,31 @@ void sha1(void* data, uint32_t size, void* hash)
for (i = 0; i < 5; i++) *hashbuf++ = SHA1RESULT[i];
clockgate_enable(CLOCKGATE_SHA, false);
}
+
+
+/*
+ * IM3
+ */
+static inline uint32_t get_uint32le(unsigned char *p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+/* calculates SHA1, truncate the result to 128 bits, and encrypt it */
+void im3_sign(uint32_t keyidx, void* data, uint32_t size, void* sign)
+{
+ unsigned char hash[SHA1_SZ];
+ sha1(data, size, hash);
+ memcpy(sign, hash, SIGN_SZ);
+ hwkeyaes(HWKEYAES_ENCRYPT, keyidx, sign, SIGN_SZ);
+}
+
+/* only supports enc_type 1 and 2 (UKEY) */
+void im3_crypt(enum hwkeyaes_direction direction,
+ struct Im3Info *hinfo, void *fw_addr)
+{
+ uint32_t fw_size = get_uint32le(hinfo->data_sz);
+ hinfo->enc_type = (direction == HWKEYAES_ENCRYPT) ? 1 : 2;
+ im3_sign(HWKEYAES_UKEY, hinfo, IM3INFOSIGN_SZ, hinfo->info_sign);
+ hwkeyaes(direction, HWKEYAES_UKEY, fw_addr, fw_size);
+}
diff --git a/firmware/target/arm/s5l8702/crypto-s5l8702.h b/firmware/target/arm/s5l8702/crypto-s5l8702.h
index 541a67889c..e9f923589c 100644
--- a/firmware/target/arm/s5l8702/crypto-s5l8702.h
+++ b/firmware/target/arm/s5l8702/crypto-s5l8702.h
@@ -25,7 +25,52 @@
#include "config.h"
+
+/* IM3 */
+#if CONFIG_CPU == S5L8702
+#define IM3_IDENT "8702"
+#define IM3_VERSION "1.0"
+#define IM3HDR_SZ 0x800
+#elif CONFIG_CPU == S5L8720
+#define IM3_IDENT "8720"
+#define IM3_VERSION "2.0"
+#define IM3HDR_SZ 0x600
+#endif
+
#define SHA1_SZ 20 /* bytes */
+#define SIGN_SZ 16
+
+#ifndef ASM
+#define IM3INFO_SZ (sizeof(struct Im3Info))
+#define IM3INFOSIGN_SZ (offsetof(struct Im3Info, info_sign))
+
+struct Im3Info
+{
+ uint8_t ident[4];
+ uint8_t version[3];
+ uint8_t enc_type;
+ uint8_t entry[4]; /* LE */
+ uint8_t data_sz[4]; /* LE */
+ union {
+ struct {
+ uint8_t data_sign[SIGN_SZ];
+ uint8_t _reserved[32];
+ } enc12;
+ struct {
+ uint8_t sign_off[4]; /* LE */
+ uint8_t cert_off[4]; /* LE */
+ uint8_t cert_sz[4]; /* LE */
+ uint8_t _reserved[36];
+ } enc34;
+ } u;
+ uint8_t info_sign[SIGN_SZ];
+} __attribute__ ((packed));
+
+struct Im3Hdr
+{
+ struct Im3Info info;
+ uint8_t _zero[IM3HDR_SZ - sizeof(struct Im3Info)];
+} __attribute__ ((packed));
enum hwkeyaes_direction
{
@@ -43,4 +88,10 @@ void hwkeyaes(enum hwkeyaes_direction direction,
uint32_t keyidx, void* data, uint32_t size);
void sha1(void* data, uint32_t size, void* hash);
+void im3_sign(uint32_t keyidx, void* data, uint32_t size, void* sign);
+void im3_crypt(enum hwkeyaes_direction direction,
+ struct Im3Info *hinfo, void *fw_addr);
+
+#endif /* ASM */
+
#endif /* __CRYPTO_S5L8702_H__ */
diff --git a/firmware/target/arm/s5l8702/norboot-s5l8702.c b/firmware/target/arm/s5l8702/norboot-s5l8702.c
index f0175a02af..21dc178995 100644
--- a/firmware/target/arm/s5l8702/norboot-s5l8702.c
+++ b/firmware/target/arm/s5l8702/norboot-s5l8702.c
@@ -206,36 +206,19 @@ void bootflash_write(int port, int offset, void* addr, int size)
/*
* IM3
*/
-static uint32_t get_uint32le(unsigned char *p)
+static inline uint32_t get_uint32le(unsigned char *p)
{
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}
+// TODO: rename to bootflash_im3_sz(), norboot_im3_sz() or nb_im3_sz()
/* return full IM3 size aligned to NOR sector size */
unsigned im3_nor_sz(struct Im3Info* hinfo)
{
return ALIGN_UP(IM3HDR_SZ + get_uint32le(hinfo->data_sz), 0x1000);
}
-/* calculates SHA1, truncate the result to 128 bits, and encrypt it */
-void im3_sign(uint32_t keyidx, void* data, uint32_t size, void* sign)
-{
- unsigned char hash[SHA1_SZ];
- sha1(data, size, hash);
- memcpy(sign, hash, SIGN_SZ);
- hwkeyaes(HWKEYAES_ENCRYPT, keyidx, sign, SIGN_SZ);
-}
-
-/* only supports enc_type 1 and 2 (UKEY) */
-void im3_crypt(enum hwkeyaes_direction direction,
- struct Im3Info *hinfo, void *fw_addr)
-{
- uint32_t fw_size = get_uint32le(hinfo->data_sz);
- hinfo->enc_type = (direction == HWKEYAES_ENCRYPT) ? 1 : 2;
- im3_sign(HWKEYAES_UKEY, hinfo, IM3INFOSIGN_SZ, hinfo->info_sign);
- hwkeyaes(direction, HWKEYAES_UKEY, fw_addr, fw_size);
-}
-
+// TODO: norboot_im3_read(), on s5l8720 we could set nandboot_im3_read(), then norboot_ and nandboot_ could go to boot-s5l8702.c
int im3_read(uint32_t offset, struct Im3Info *hinfo, void *fw_addr)
{
unsigned char hash[SIGN_SZ];
diff --git a/firmware/target/arm/s5l8702/norboot-target.h b/firmware/target/arm/s5l8702/norboot-target.h
index 3d2790d123..36b8643d0f 100644
--- a/firmware/target/arm/s5l8702/norboot-target.h
+++ b/firmware/target/arm/s5l8702/norboot-target.h
@@ -119,46 +119,7 @@ struct SysCfgEntry {
/*
* IM3
*/
-#define IM3_IDENT "8702"
-#define IM3_VERSION "1.0"
-#define IM3HDR_SZ 0x800
-#define IM3INFO_SZ (sizeof(struct Im3Info))
-#define IM3INFOSIGN_SZ (offsetof(struct Im3Info, info_sign))
-
-#define SIGN_SZ 16
-
-struct Im3Info
-{
- uint8_t ident[4];
- uint8_t version[3];
- uint8_t enc_type;
- uint8_t entry[4]; /* LE */
- uint8_t data_sz[4]; /* LE */
- union {
- struct {
- uint8_t data_sign[SIGN_SZ];
- uint8_t _reserved[32];
- } enc12;
- struct {
- uint8_t sign_off[4]; /* LE */
- uint8_t cert_off[4]; /* LE */
- uint8_t cert_sz[4]; /* LE */
- uint8_t _reserved[36];
- } enc34;
- } u;
- uint8_t info_sign[SIGN_SZ];
-} __attribute__ ((packed));
-
-struct Im3Hdr
-{
- struct Im3Info info;
- uint8_t _zero[IM3HDR_SZ - sizeof(struct Im3Info)];
-} __attribute__ ((packed));
-
unsigned im3_nor_sz(struct Im3Info* hinfo);
-void im3_sign(uint32_t keyidx, void* data, uint32_t size, void* sign);
-void im3_crypt(enum hwkeyaes_direction direction,
- struct Im3Info *hinfo, void *fw_addr);
int im3_read(uint32_t offset, struct Im3Info *hinfo, void *fw_addr);
bool im3_write(int offset, void *im3_addr);