1 // Copyright 2010 Sven Peter <svenpeter@gmail.com>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
13 static u8
*ptr
= NULL
;
17 static u32 meta_offset
;
18 static u64 info_offset
;
21 static u64 header_len
;
22 static int did_fail
= 0;
24 static struct keylist
*klist
= NULL
;
26 static struct keylist
*self_load_keys(void)
50 fail("invalid type: %08x", app_type
);
56 static void read_self_header(void)
58 flags
= be16(ptr
+ 0x08);
59 meta_offset
= be32(ptr
+ 0x0c);
60 header_len
= be64(ptr
+ 0x10);
61 filesize
= be64(ptr
+ 0x18);
62 info_offset
= be64(ptr
+ 0x28);
64 app_type
= be32(ptr
+ info_offset
+ 0x0c);
66 klist
= self_load_keys();
69 static void read_pkg_header(void)
71 flags
= be16(ptr
+ 0x08);
72 meta_offset
= be32(ptr
+ 0x0c);
73 header_len
= be64(ptr
+ 0x10);
74 filesize
= be64(ptr
+ 0x18);
76 klist
= keys_get(KEY_PKG
);
79 static void read_spp_header(void)
81 flags
= be16(ptr
+ 0x08);
82 meta_offset
= be32(ptr
+ 0x0c);
83 header_len
= be64(ptr
+ 0x10);
84 filesize
= be64(ptr
+ 0x18);
86 klist
= keys_get(KEY_SPP
);
89 static void decrypt(void)
93 keyid
= sce_decrypt_header(ptr
, klist
);
96 fail("sce_decrypt_header failed");
98 if (sce_decrypt_data(ptr
) < 0)
99 fail("sce_decrypt_data failed");
101 if (klist
->keys
[keyid
].pub_avail
< 0)
102 fail("no public key available");
104 if (ecdsa_set_curve(klist
->keys
[keyid
].ctype
) < 0)
105 fail("ecdsa_set_curve failed");
107 ecdsa_set_pub(klist
->keys
[keyid
].pub
);
110 static void verify_signature(void)
116 sig_len
= be64(ptr
+ meta_offset
+ 0x60);
120 sha1(ptr
, sig_len
, hash
);
122 printf("Signature\n");
123 if (ecdsa_verify(hash
, r
, s
))
124 printf(" Status: OK\n");
126 printf(" Status: FAIL\n");
131 static int verify_hash(u8
*p
, u8
*hashes
)
139 offset
= be64(p
+ 0x00);
140 size
= be64(p
+ 0x08);
143 if (id
== 0xffffffff)
146 hash
= hashes
+ id
* 0x10;
149 // XXX: possible integer overflow here
150 if (offset
> (filesize
+ header_len
))
153 // XXX: possible integer overflow here
154 if ((offset
+ size
) > (filesize
+ header_len
))
157 sha1_hmac(key
, ptr
+ offset
, size
, result
);
159 if (memcmp(result
, hash
, 20) == 0)
165 static void verify_hashes(void)
172 meta_n_hdr
= be32(ptr
+ meta_offset
+ 0x60 + 0xc);
173 hashes
= ptr
+ meta_offset
+ 0x80 + 0x30 * meta_n_hdr
;
177 for (i
= 0; i
< meta_n_hdr
; i
++) {
178 printf(" Section #%02d: ", i
);
179 res
= verify_hash(ptr
+ meta_offset
+ 0x80 + 0x30 * i
, hashes
);
183 } else if (res
> 0) {
193 int main(int argc
, char *argv
[])
196 fail("usage: sceverify filename");
198 ptr
= mmap_file(argv
[1]);
200 type
= be16(ptr
+ 0x0a);
209 fail("Unknown type: %d", type
);
212 fail("devkit file; nothing to verify");
215 fail("no key found");
222 printf(" * please not that the hash will always fail for "
223 "unaligned non-LOAD phdrs\n");