From 9042cc406862e9577c70eebc3c1333ba33c83228 Mon Sep 17 00:00:00 2001 From: masterzorag Date: Wed, 23 Jul 2014 22:44:07 +0200 Subject: [PATCH 1/3] Update sce.cpp Last 2 bytes of IV gets altered, a deeper look is needed. Simply backup IV, run decryption and if IV has changed, restore back. This fixes the computed digest of data, that can succesfully validate a signature or not. Probably aes encrypt suffers the same. --- sce.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sce.cpp b/sce.cpp index dd647cf..1adbfbe 100644 --- a/sce.cpp +++ b/sce.cpp @@ -850,6 +850,10 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) if(ctxt->metai->key_pad[0] != 0x00 || ctxt->metai->iv_pad[0] != 0x00) return FALSE; + //Backup IV, next aes_crypt_ctr alters last 2 bytes + u8 biv[0x10]; + memcpy(&biv, ctxt->metai->iv, 0x10); + //Decrypt metadata header, metadata section headers and keys. nc_off = 0; aes_setkey_enc(&aes_ctxt, ctxt->metai->key, METADATA_INFO_KEYBITS); @@ -857,6 +861,10 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) ctxt->sceh->header_len - (sizeof(sce_header_t) + ctxt->sceh->metadata_offset + sizeof(metadata_info_t)), &nc_off, ctxt->metai->iv, sblk, (u8 *)ctxt->metah, (u8 *)ctxt->metah); + //Restore IV from its backup if changed + if(memcmp(ctxt->metai->iv, biv, 0x10) != 0) + memcpy(ctxt->metai->iv, &biv, 0x10); + //Fixup headers. _es_metadata_header(ctxt->metah); for(i = 0; i < ctxt->metah->section_count; i++) From f2d04c9da18f8a1a78daa4bba37d1a1172549c65 Mon Sep 17 00:00:00 2001 From: masterzorag Date: Wed, 23 Jul 2014 23:35:01 +0200 Subject: [PATCH 2/3] Update Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d9734a1..b2a1b0e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CC=gcc +CC=g++ CFLAGS=-g -O0 -Wall OS_TARGET=scetool LDFLAGS=-lz From 2350b05701da0904ad7a3908b44dcd16a05ac784 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Jul 2014 11:34:35 +0200 Subject: [PATCH 3/3] Deal with spkg_hdr.1 files --- frontend.cpp | 15 +++++++++++---- sce.cpp | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/frontend.cpp b/frontend.cpp index b06949e..c52da07 100644 --- a/frontend.cpp +++ b/frontend.cpp @@ -327,13 +327,19 @@ void frontend_print_infos(s8 *file) if(sce_decrypt_header(ctxt, meta_info, keyset)) { _LOG_VERBOSE("Header decrypted.\n"); - if(sce_decrypt_data(ctxt)) - _LOG_VERBOSE("Data decrypted.\n"); - else - printf("[*] Warning: Could not decrypt data.\n"); + + //Just deal with spkg_hdr.1 files now, no need to decrypt whole PKG. + if(ctxt->sceh->header_type != SCE_HEADER_TYPE_PKG) + { + if(sce_decrypt_data(ctxt)) + _LOG_VERBOSE("Data decrypted.\n"); + else + printf("[*] Warning: Could not decrypt data.\n"); + } } else printf("[*] Warning: Could not decrypt header.\n"); + sce_print_info(stdout, ctxt); if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SELF) self_print_info(stdout, ctxt); @@ -341,6 +347,7 @@ void frontend_print_infos(s8 *file) rvk_print(stdout, ctxt); else if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SPP && ctxt->mdec == TRUE) spp_print(stdout, ctxt); + free(ctxt); } else diff --git a/sce.cpp b/sce.cpp index 1adbfbe..ab3d377 100644 --- a/sce.cpp +++ b/sce.cpp @@ -26,7 +26,7 @@ void _print_sce_header(FILE *fp, sce_header_t *h) { const s8 *name; - const s8 *key_revision; + //const s8 *key_revision; fprintf(fp, "[*] SCE Header:\n"); fprintf(fp, " Magic 0x%08X [%s]\n", h->magic, (h->magic == SCE_HEADER_MAGIC ? "OK" : "ERROR")); @@ -320,7 +320,7 @@ void sce_compress_data(sce_buffer_ctxt_t *ctxt) else { free(buf); - _LOG_VERBOSE("Skipped compression of section %03d (0x%08X >= 0x%08X)\n", i, size_comp, sec->size); + _LOG_VERBOSE("Skipped compression of section %03d (0x%08lu >= 0x%08X)\n", i, size_comp, sec->size); } } else @@ -840,6 +840,9 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) aes_setkey_dec(&aes_ctxt, ks->erk, KEYBITS(ks->erklen)); memcpy(iv, ks->riv, 0x10); //!!! aes_crypt_cbc(&aes_ctxt, AES_DECRYPT, sizeof(metadata_info_t), iv, (u8 *)ctxt->metai, (u8 *)ctxt->metai); + + //Dump to file. + _write_buffer("metai_dec.bin", (u8 *) ctxt->metai, sizeof(metadata_info_t)); } else { @@ -865,8 +868,12 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) if(memcmp(ctxt->metai->iv, biv, 0x10) != 0) memcpy(ctxt->metai->iv, &biv, 0x10); + //Dump to file. + _write_buffer("metah_dec.bin", (u8 *) ctxt->metah, ctxt->sceh->header_len - (sizeof(sce_header_t) + ctxt->sceh->metadata_offset + sizeof(metadata_info_t))); + //Fixup headers. _es_metadata_header(ctxt->metah); + for(i = 0; i < ctxt->metah->section_count; i++) _es_metadata_section_header(&ctxt->metash[i]); @@ -877,6 +884,10 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) ctxt->keys = (u8 *)ctxt->metash + sizeof(metadata_section_header_t) * ctxt->metah->section_count; ctxt->keys_len = ctxt->metah->key_count * 0x10; + //Dump to file. + _write_buffer("keys_file.bin", (u8 *) ctxt->metash + sizeof(metadata_section_header_t) * ctxt->metah->section_count, ctxt->metah->key_count * 0x10); + _write_buffer("signature.bin", (u8 *) ctxt->keys + ctxt->metah->key_count * 0x10, 0x30); + //Set SELF only headers. if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SELF) {