Line 18:
Line 18:
== Encryption ==
== Encryption ==
−
The icon database is encrypted with AES128 CBC. There's a two byte header:
+
nn_idbe contains hardcoded keys in one 0x50 sized block (0x10 * 5), consisting of the 16-byte hardcoded IV, and 4 hardcoded 16-byte AES-128 keys.
−
0: (unknown, usually zero?)
+
In OSv10 (000500101000400A), the keys are located at $.rodata+0x4c of nn_idbe.rpl.
−
1: key index
−
followed by encrypted data.
+
Here are the keys:
−
nn_idbe contains hardcoded keys in one 0x50 sized block, consisting of the 16-byte hardcoded IV, and 4 hardcoded 16-byte AES128 keys.
+
<syntaxhighlight lang="Python">
−
In version 11464 of OSv11 (000500101000400A), the keys are located at $DATA+0x4c of nn_idbe.rpl.
+
IV = "A46987AE47D82BB4FA8ABC0450285FA4"
−
== Decrypted icon format ==
+
K0 = "4AB9A40E146975A84BB1B4F3ECEFC47B"
+
K1 = "90A0BB1E0E864AE87D13A6A03D28C9B8"
+
K2 = "FFBB57C14E98EC6975B384FCF40786B5"
+
K3 = "80923799B41F36A6A75FB8B48C95F66F"
−
There's a SHA256 of the data at the beginning of the file. After the sha, there's some stuff that contains UTF-16 text of the game name and publisher, then image data begins.
+
AES_KEYS = [K0, K1, K2, K3]
−
The image data is given as Truevision TGA and usually starts 0x2050 bytes into the decrypted buffer.
+
</syntaxhighlight>
+
+
== Icon format ==
+
+
=== Encrypted ===
+
+
{| class="wikitable"
+
! Offset
+
! Length
+
! Description
+
|-
+
| 0x0
+
| 0x1
+
| Always 0
+
|-
+
| 0x1
+
| 0x1
+
| AES key index
+
|-
+
| 0x2
+
| Remainder
+
| Encrypted file contents
+
|}
+
+
=== Decrypted ===
+
+
{| class="wikitable"
+
! Offset
+
! Length
+
! Description
+
|-
+
| 0x0
+
| 0x20
+
| SHA256 hash of the rest of the data
+
|-
+
| 0x20
+
| 0x8
+
| Title ID
+
|-
+
| 0x28
+
| 0x18
+
| Unknown (See note 1 below)
+
|-
+
| 0x40
+
| 0x4
+
| Magic (ÀÀÀÀ)
+
|-
+
| 0x44
+
| 0xC
+
| Padding?
+
|-
+
| 0x50
+
| 0x200*16
+
| Title Info (See note 2 below)
+
|-
+
| 0x2050
+
| Remainder
+
| Original TGA
+
|}
+
+
=== Title Info ===
+
+
{| class="wikitable"
+
! Offset
+
! Length
+
! Description
+
|-
+
| 0x0
+
| 0x80
+
| Short title name
+
|-
+
| 0x80
+
| 0x100
+
| Full title name
+
|-
+
| 0x180
+
| 0x80
+
| Publisher
+
|}
+
+
'''Note 1:'''
+
The first 8 bytes of this section seem to always be relatively empty, where as the last 16 seem to always been some combination of the characters € and À.
+
+
'''Examples:'''
+
+
# Breath of The Wild: https://i.imgur.com/qI9ehUQ.png
+
# Super Mario Maker: https://i.imgur.com/lNfcAM5.png
+
# Tekken Tag Tournament 2: https://i.imgur.com/8bJeD56.png
+
# Minecraft WiiU: https://i.imgur.com/fiC840J.png
+
+
+
'''Note 2:'''
+
Each of the 16 0x200-length groups has 3 UTF-16-BE text blocks. There is always 3 blocks, even if the string does not take up the entire (or any of the) block. Each group is for a different language/region. The first group is for Japanese, the order of the other languages is unknown.
+
+
'''Examples:'''
+
+
# New SUPER MARIO BROS. U + New SUPER LUIGI U: https://i.imgur.com/IeAAKuZ.png
+
# Super Mario Maker: https://i.imgur.com/Q6yWYiO.png
+
# Tekken Tag Tournament 2: https://i.imgur.com/f4ENuT5.png
+
# Minecraft WiiU: https://i.imgur.com/xZPCbdQ.png
+
+
+
Example decryptor here: https://github.com/NexoDevelopment/idbe_decrypt/