In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

Difference between revisions of "Title metadata"

From WiiBrew
Jump to navigation Jump to search
(Undo revision 44996 by IMacros (Talk) (vandalism?))
Line 1: Line 1:
これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック
+
'''Title metadata''' is a format used to store information about a title (a single standalone game, channel, etc.) and all its installed contents, including which contents they consist of and their SHA1 hashes.
 +
 +
Many operations are done in terms of 64-byte blocks, which means you will often see padding out to the nearest 64-byte boundary at the end of a field.
  
=これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック=
+
== Structure ==
==これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック==
+
=== Header ===
===これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック===
+
{| class="wikitable"
これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック
+
|- style="background-color: #ddd;"
====これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック=====
+
! Start
 +
! Length
 +
! Description
 +
|-
 +
| 0x000
 +
| 4
 +
| Signature type
 +
|-
 +
| 0x004
 +
| 256
 +
| Signature
 +
|-
 +
| 0x104
 +
| 60
 +
| Padding modulo 64
 +
|-
 +
| 0x140
 +
| 64
 +
| Issuer
 +
|-
 +
| 0x180
 +
| 1
 +
| Version
 +
|-
 +
| 0x181
 +
| 1
 +
| ca_crl_version
 +
|-
 +
| 0x182
 +
| 1
 +
| signer_crl_version
 +
|-
 +
| 0x183
 +
| 1
 +
| Padding modulo 64
 +
|-
 +
| 0x184
 +
| 8
 +
| System Version
 +
|-
 +
| 0x18C
 +
| 8
 +
| Title ID
 +
|-
 +
| 0x194
 +
| 4
 +
| Title type
 +
|-
 +
| 0x198
 +
| 2
 +
| Group ID
 +
|-
 +
| 0x19A
 +
| 62
 +
| reserved
 +
|-
 +
| 0x1D8
 +
| 4
 +
| Access rights
 +
|-
 +
| 0x1DC
 +
| 2
 +
| Title version
 +
|-
 +
| 0x1DE
 +
| 2
 +
| Number of contents (nbr_cont)
 +
|-
 +
| 0x1E0
 +
| 2
 +
| boot index
 +
|-
 +
| 0x1E2
 +
| 2
 +
| Padding modulo 64
 +
|-
 +
| 0x1E4
 +
| 36*nbr_cont
 +
| Contents
 +
|}
  
これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック
+
=== Content ===
 +
{| class="wikitable"
 +
|-
 +
! Start
 +
! Length
 +
! Description
 +
|-
 +
| 0x00
 +
| 4
 +
| Content ID
 +
|-
 +
| 0x04
 +
| 2
 +
| Index
 +
|-
 +
| 0x06
 +
| 2
 +
| Type
 +
|-
 +
| 0x08
 +
| 8
 +
| Size
 +
|-
 +
| 0x10
 +
| 20
 +
| SHA1 hash
 +
|}
  
[[これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック]]
+
=== Certificates ===
 +
{| class="wikitable"
 +
|-
 +
! Start
 +
! Length
 +
! Description
 +
|-
 +
| 0x000
 +
| 4
 +
| Signature type
 +
|-
 +
| 0x004
 +
| 256
 +
| Signature
 +
|-
 +
| 0x104
 +
| 32
 +
| Issuer
 +
|-
 +
| 0x124
 +
| 4
 +
| Tag
 +
|-
 +
| 0x128
 +
| 64
 +
| Name
 +
|-
 +
| 0x168
 +
|
 +
| Key
 +
|}
  
[これは日本のニンテンドーfucking !私は神のCEOは、午前くそー!お客様の製品やfucking私fucking私のfuckingの雌ロバが改造停止を訴える!あなたファック]
+
== Example code application ==
 +
<source lang="c">
 +
typedef unsigned char  u8;
 +
typedef unsigned short u16;
 +
typedef unsigned int  u32;
 +
/* On a 32bit system, long is only 4 bytes- use long long instead */
 +
typedef unsigned long u64;
 +
</source>
 +
<source lang="c">
 +
typedef struct {
 +
  u32 cid; // content id
 +
  u16 index; // # number of the file
 +
  u16  type;
 +
  u64 size;
 +
  u8  hash [20]; //  SHA1 hash content
 +
} content_record; // size: 0x24 bytes
 +
</source>
 +
<source lang="c">
 +
enum sig_type {
 +
      RSA_2048 = 0x00010001,
 +
      RSA_4096 = 0x00010000
 +
};
 +
</source>
 +
<source lang="c">
 +
typedef struct {
 +
        u32 sig_type;
 +
        u8 sig[256];
 +
        u8 fill1[60];
 +
        u8 issuer[64]; // Root-CA%08x-CP%08x
 +
        u8 version;
 +
        u8 ca_crl_version;
 +
        u8 signer_crl_version;
 +
        u8 fill2;
 +
        u64 sys_version;
 +
        u64 title_id;
 +
        u32 title_type;
 +
        u16 group_id; // publisher
 +
        u8 reserved[62];
 +
        u32 access_rights;
 +
        u16 title_version;
 +
        u16 num_contents;
 +
        u16 boot_index;
 +
        u16 fill3;
 +
        content_record contents[num_contents];
 +
} tmd;
 +
</source>
 +
The tmd is then followed by a chain of certificates, where each certificate is of the general form
 +
<source lang="c">
 +
  u32 sig_type;  //
 +
  u8 sig[256];  // 256 for RSA_2048, 512 for RSA_4096
 +
  u8 issuer[32];
 +
  u32 tag;  // identifies what is being signed
 +
  u8 name[64]; // name of thing being signed
 +
  u8 key[...];
 +
</source>

Revision as of 18:30, 5 March 2009

Title metadata is a format used to store information about a title (a single standalone game, channel, etc.) and all its installed contents, including which contents they consist of and their SHA1 hashes.

Many operations are done in terms of 64-byte blocks, which means you will often see padding out to the nearest 64-byte boundary at the end of a field.

Structure

Header

Start Length Description
0x000 4 Signature type
0x004 256 Signature
0x104 60 Padding modulo 64
0x140 64 Issuer
0x180 1 Version
0x181 1 ca_crl_version
0x182 1 signer_crl_version
0x183 1 Padding modulo 64
0x184 8 System Version
0x18C 8 Title ID
0x194 4 Title type
0x198 2 Group ID
0x19A 62 reserved
0x1D8 4 Access rights
0x1DC 2 Title version
0x1DE 2 Number of contents (nbr_cont)
0x1E0 2 boot index
0x1E2 2 Padding modulo 64
0x1E4 36*nbr_cont Contents

Content

Start Length Description
0x00 4 Content ID
0x04 2 Index
0x06 2 Type
0x08 8 Size
0x10 20 SHA1 hash

Certificates

Start Length Description
0x000 4 Signature type
0x004 256 Signature
0x104 32 Issuer
0x124 4 Tag
0x128 64 Name
0x168 Key

Example code application

 typedef unsigned char  u8;
 typedef unsigned short u16;
 typedef unsigned int   u32; 
/* On a 32bit system, long is only 4 bytes- use long long instead */
 typedef unsigned long u64;
 typedef struct {
   u32 cid;		// content id
   u16 index;		// # number of the file
   u16  type;
   u64 size;
   u8  hash [20]; 		//  SHA1 hash content
 } content_record; 			// size: 0x24 bytes
 enum sig_type {
      RSA_2048 = 0x00010001,
      RSA_4096 = 0x00010000
 };
 typedef struct {
        u32 sig_type; 
        u8 sig[256];
        u8 fill1[60];
        u8 issuer[64]; // Root-CA%08x-CP%08x
        u8 version;
        u8 ca_crl_version;
        u8 signer_crl_version;
        u8 fill2;
        u64 sys_version;
        u64 title_id;
        u32 title_type;
        u16 group_id; // publisher
        u8 reserved[62];
        u32 access_rights;
        u16 title_version;
        u16 num_contents;
        u16 boot_index;
        u16 fill3;
        content_record contents[num_contents];
 } tmd;

The tmd is then followed by a chain of certificates, where each certificate is of the general form

  u32 sig_type;  //
  u8 sig[256];   // 256 for RSA_2048, 512 for RSA_4096
  u8 issuer[32];
  u32 tag;  // identifies what is being signed
  u8 name[64]; // name of thing being signed
  u8 key[...];