diff --git a/ctrtool/ivfc.c b/ctrtool/ivfc.c index 90df381..fb7a5f0 100644 --- a/ctrtool/ivfc.c +++ b/ctrtool/ivfc.c @@ -31,11 +31,47 @@ void ivfc_set_file(ivfc_context* ctx, FILE* file) ctx->file = file; } +void ivfc_set_encrypted(ivfc_context* ctx, u32 encrypted) +{ + ctx->encrypted = encrypted; +} + +void ivfc_set_key(ivfc_context* ctx, u8 key[16]) +{ + memcpy(ctx->key, key, 16); +} + +void ivfc_set_counter(ivfc_context* ctx, u8 counter[16]) +{ + memcpy(ctx->counter, counter, 16); +} + +void ivfc_fseek(ivfc_context* ctx, u64 offset) +{ + u64 data_pos = offset - ctx->offset; + fseeko64(ctx->file, offset, SEEK_SET); + ctr_init_counter(&ctx->aes, ctx->key, ctx->counter); + ctr_add_counter(&ctx->aes, data_pos / 0x10); +} + +size_t ivfc_fread(ivfc_context* ctx, void* buffer, size_t size, size_t count) +{ + size_t read; + if ((read = fread(buffer, size, count, ctx->file)) != count) { + //printf("ivfc_fread() fail\n"); + return read; + } + if (ctx->encrypted) { + ctr_crypt_counter(&ctx->aes, buffer, buffer, size*read); + } + return read; +} + void ivfc_process(ivfc_context* ctx, u32 actions) { - fseeko64(ctx->file, ctx->offset, SEEK_SET); - fread(&ctx->header, 1, sizeof(ivfc_header), ctx->file); + ivfc_fseek(ctx, ctx->offset); + ivfc_fread(ctx, &ctx->header, 1, sizeof(ivfc_header)); if (getle32(ctx->header.magic) != MAGIC_IVFC) { @@ -45,25 +81,23 @@ void ivfc_process(ivfc_context* ctx, u32 actions) if (getle32(ctx->header.id) == 0x10000) { - fread(&ctx->romfsheader, 1, sizeof(ivfc_header_romfs), ctx->file); - ctx->levelcount = 3; - ctx->level[2].hashblocksize = 1 << getle32(ctx->romfsheader.level3.blocksize); - ctx->level[1].hashblocksize = 1 << getle32(ctx->romfsheader.level2.blocksize); - ctx->level[0].hashblocksize = 1 << getle32(ctx->romfsheader.level1.blocksize); + ctx->level[2].hashblocksize = 1 << getle32(ctx->header.level3.blocksize); + ctx->level[1].hashblocksize = 1 << getle32(ctx->header.level2.blocksize); + ctx->level[0].hashblocksize = 1 << getle32(ctx->header.level1.blocksize); - ctx->bodyoffset = align64(IVFC_HEADER_SIZE + getle32(ctx->romfsheader.masterhashsize), ctx->level[2].hashblocksize); - ctx->bodysize = getle64(ctx->romfsheader.level3.hashdatasize); + ctx->bodyoffset = align64(IVFC_HEADER_SIZE + getle32(ctx->header.masterhashsize), ctx->level[2].hashblocksize); + ctx->bodysize = getle64(ctx->header.level3.hashdatasize); ctx->level[2].dataoffset = ctx->bodyoffset; ctx->level[2].datasize = align64(ctx->bodysize, ctx->level[2].hashblocksize); ctx->level[0].dataoffset = ctx->level[2].dataoffset + ctx->level[2].datasize; - ctx->level[0].datasize = align64(getle64(ctx->romfsheader.level1.hashdatasize), ctx->level[0].hashblocksize); + ctx->level[0].datasize = align64(getle64(ctx->header.level1.hashdatasize), ctx->level[0].hashblocksize); ctx->level[1].dataoffset = ctx->level[0].dataoffset + ctx->level[0].datasize; - ctx->level[1].datasize = align64(getle64(ctx->romfsheader.level2.hashdatasize), ctx->level[1].hashblocksize); + ctx->level[1].datasize = align64(getle64(ctx->header.level2.hashdatasize), ctx->level[1].hashblocksize); ctx->level[0].hashoffset = IVFC_HEADER_SIZE; ctx->level[1].hashoffset = ctx->level[0].dataoffset; @@ -125,8 +159,8 @@ void ivfc_read(ivfc_context* ctx, u64 offset, u64 size, u8* buffer) return; } - fseeko64(ctx->file, ctx->offset + offset, SEEK_SET); - if (size != fread(buffer, 1, size, ctx->file)) + ivfc_fseek(ctx, ctx->offset + offset); + if (size != ivfc_fread(ctx, buffer, 1, size)) { fprintf(stderr, "Error, IVFC could not read file\n"); return; diff --git a/ctrtool/ivfc.h b/ctrtool/ivfc.h index 5c0aa1b..9662f45 100644 --- a/ctrtool/ivfc.h +++ b/ctrtool/ivfc.h @@ -2,18 +2,13 @@ #define __IVFC_H__ #include "types.h" +#include "ctr.h" #include "settings.h" #define IVFC_HEADER_SIZE 0x60 #define IVFC_MAX_LEVEL 4 #define IVFC_MAX_BUFFERSIZE 0x4000 -typedef struct -{ - u8 magic[4]; - u8 id[4]; -} ivfc_header; - typedef struct { u8 logicaloffset[8]; @@ -33,13 +28,15 @@ typedef struct typedef struct { + u8 magic[4]; + u8 id[4]; u8 masterhashsize[4]; ivfc_levelheader level1; ivfc_levelheader level2; ivfc_levelheader level3; u8 reserved[4]; u8 optionalsize[4]; -} ivfc_header_romfs; +} ivfc_header; typedef struct { @@ -47,9 +44,12 @@ typedef struct u64 offset; u64 size; settings* usersettings; + u8 counter[16]; + u8 key[16]; + ctr_aes_context aes; + int encrypted; ivfc_header header; - ivfc_header_romfs romfsheader; u32 levelcount; ivfc_level level[IVFC_MAX_LEVEL]; @@ -64,6 +64,12 @@ void ivfc_set_offset(ivfc_context* ctx, u64 offset); void ivfc_set_size(ivfc_context* ctx, u64 size); void ivfc_set_file(ivfc_context* ctx, FILE* file); void ivfc_set_usersettings(ivfc_context* ctx, settings* usersettings); +void ivfc_set_encrypted(ivfc_context* ctx, u32 encrypted); +void ivfc_set_key(ivfc_context* ctx, u8 key[16]); +void ivfc_set_counter(ivfc_context* ctx, u8 counter[16]); +void ivfc_fseek(ivfc_context* ctx, u64 offset); +size_t ivfc_fread(ivfc_context* ctx, void* buffer, size_t size, size_t count); + void ivfc_verify(ivfc_context* ctx, u32 flags); void ivfc_print(ivfc_context* ctx); diff --git a/ctrtool/main.c b/ctrtool/main.c index 25b688d..4a7199b 100644 --- a/ctrtool/main.c +++ b/ctrtool/main.c @@ -64,11 +64,14 @@ static void usage(const char *argv0) " --lzssout=file Specify lzss output file\n" "CXI/CCI options:\n" " -n, --ncch=index Specify NCCH partition index.\n" + " --exheader=file Specify Extended Header file path.\n" + " --logo=file Specify Logo file path.\n" + " --plainrgn=file Specify Plain region file path" " --exefs=file Specify ExeFS file path.\n" " --exefsdir=dir Specify ExeFS directory path.\n" " --romfs=file Specify RomFS file path.\n" - " --exheader=file Specify Extended Header file path.\n" - " --logo=file Specify Logo file path.\n" + " --romfsdir=dir Specify RomFS directory path.\n" + " --listromfs List files in RomFS.\n" "CIA options:\n" " --certs=file Specify Certificate chain file path.\n" " --tik=file Specify Ticket file path.\n" @@ -83,9 +86,6 @@ static void usage(const char *argv0) "EXEFS options:\n" " --decompresscode Decompress .code section\n" " (only needed when using raw EXEFS file)\n" - "ROMFS options:\n" - " --romfsdir=dir Specify RomFS directory path.\n" - " --listromfs List files in RomFS.\n" "\n", __TIME__, __DATE__, argv0); exit(1); @@ -149,6 +149,7 @@ int main(int argc, char* argv[]) {"logo", 1, NULL, 20}, {"decompresscode", 0, NULL, 21}, {"titlekey", 1, NULL, 22}, + {"plainrgn", 1, NULL, 23}, {NULL}, }; @@ -237,6 +238,7 @@ int main(int argc, char* argv[]) case 20: settings_set_logo_path(&ctx.usersettings, optarg); break; case 21: ctx.actions |= DecompressCodeFlag; break; case 22: keyset_parse_titlekey(&tmpkeys, optarg, strlen(optarg)); break; + case 23: settings_set_plainrgn_path(&ctx.usersettings, optarg); break; default: usage(argv[0]); @@ -452,6 +454,7 @@ int main(int argc, char* argv[]) romfs_set_file(&romfsctx, ctx.infile); romfs_set_size(&romfsctx, ctx.infilesize); romfs_set_usersettings(&romfsctx, &ctx.usersettings); + romfs_set_encrypted(&romfsctx, 0); romfs_process(&romfsctx, ctx.actions); break; diff --git a/ctrtool/ncch.c b/ctrtool/ncch.c index 991afc3..7c06b23 100644 --- a/ctrtool/ncch.c +++ b/ctrtool/ncch.c @@ -116,6 +116,13 @@ int ncch_extract_prepare(ncch_context* ctx, u32 type, u32 flags) } break; + case NCCHTYPE_PLAINRGN: + { + offset = ncch_get_plainrgn_offset(ctx); + size = ncch_get_plainrgn_size(ctx); + } + break; + default: { fprintf(stderr, "Error invalid NCCH type\n"); @@ -181,6 +188,7 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags) case NCCHTYPE_ROMFS: path = settings_get_romfs_path(ctx->usersettings); break; case NCCHTYPE_EXHEADER: path = settings_get_exheader_path(ctx->usersettings); break; case NCCHTYPE_LOGO: path = settings_get_logo_path(ctx->usersettings); break; + case NCCHTYPE_PLAINRGN: path = settings_get_plainrgn_path(ctx->usersettings); break; } if (path == 0 || path->valid == 0) @@ -199,13 +207,14 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags) case NCCHTYPE_ROMFS: fprintf(stdout, "Saving RomFS...\n"); break; case NCCHTYPE_EXHEADER: fprintf(stdout, "Saving Extended Header...\n"); break; case NCCHTYPE_LOGO: fprintf(stdout, "Saving Logo...\n"); break; + case NCCHTYPE_PLAINRGN: fprintf(stdout, "Saving Plain Region...\n"); break; } while(1) { u32 read_len; - if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &read_len, type == NCCHTYPE_LOGO)) + if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &read_len, type == NCCHTYPE_LOGO || type == NCCHTYPE_PLAINRGN)) goto clean; if (read_len == 0) @@ -304,6 +313,7 @@ void ncch_process(ncch_context* ctx, u32 actions) { u8 exheadercounter[16]; u8 exefscounter[16]; + u8 romfscounter[16]; int result = 1; @@ -320,6 +330,7 @@ void ncch_process(ncch_context* ctx, u32 actions) ncch_get_counter(ctx, exheadercounter, NCCHTYPE_EXHEADER); ncch_get_counter(ctx, exefscounter, NCCHTYPE_EXEFS); + ncch_get_counter(ctx, romfscounter, NCCHTYPE_ROMFS); exheader_set_file(&ctx->exheader, ctx->file); @@ -342,6 +353,14 @@ void ncch_process(ncch_context* ctx, u32 actions) exefs_set_key(&ctx->exefs, ctx->key); exefs_set_encrypted(&ctx->exefs, ctx->encrypted); + romfs_set_file(&ctx->romfs, ctx->file); + romfs_set_offset(&ctx->romfs, ncch_get_romfs_offset(ctx)); + romfs_set_size(&ctx->romfs, ncch_get_romfs_size(ctx)); + romfs_set_usersettings(&ctx->romfs, ctx->usersettings); + romfs_set_counter(&ctx->romfs, romfscounter); + romfs_set_key(&ctx->romfs, ctx->key); + romfs_set_encrypted(&ctx->romfs, ctx->encrypted); + exheader_read(&ctx->exheader, actions); @@ -357,6 +376,7 @@ void ncch_process(ncch_context* ctx, u32 actions) ncch_save(ctx, NCCHTYPE_ROMFS, actions); ncch_save(ctx, NCCHTYPE_EXHEADER, actions); ncch_save(ctx, NCCHTYPE_LOGO, actions); + ncch_save(ctx, NCCHTYPE_PLAINRGN, actions); } @@ -374,6 +394,11 @@ void ncch_process(ncch_context* ctx, u32 actions) exefs_set_compressedflag(&ctx->exefs, exheader_get_compressedflag(&ctx->exheader)); exefs_process(&ctx->exefs, actions); } + + if (result && ncch_get_romfs_size(ctx)) + { + romfs_process(&ctx->romfs, actions); + } } int ncch_signature_verify(ncch_context* ctx, rsakey2048* key) @@ -425,6 +450,17 @@ u64 ncch_get_logo_size(ncch_context* ctx) return getle32(ctx->header.logosize) * ncch_get_mediaunit_size(ctx); } +u64 ncch_get_plainrgn_offset(ncch_context* ctx) +{ + return ctx->offset + getle32(ctx->header.plainregionoffset) * ncch_get_mediaunit_size(ctx); +} + +u64 ncch_get_plainrgn_size(ncch_context* ctx) +{ + return getle32(ctx->header.plainregionsize) * ncch_get_mediaunit_size(ctx); +} + + u64 ncch_get_mediaunit_size(ncch_context* ctx) { unsigned int mediaunitsize = settings_get_mediaunit_size(ctx->usersettings); diff --git a/ctrtool/ncch.h b/ctrtool/ncch.h index 4bad2be..64dc490 100644 --- a/ctrtool/ncch.h +++ b/ctrtool/ncch.h @@ -7,6 +7,7 @@ #include "filepath.h" #include "ctr.h" #include "exefs.h" +#include "romfs.h" #include "exheader.h" #include "settings.h" @@ -16,6 +17,7 @@ typedef enum NCCHTYPE_EXEFS = 2, NCCHTYPE_ROMFS = 3, NCCHTYPE_LOGO = 4, + NCCHTYPE_PLAINRGN = 5, } ctr_ncchtypes; typedef struct @@ -63,6 +65,7 @@ typedef struct ctr_ncchheader header; ctr_aes_context aes; exefs_context exefs; + romfs_context romfs; exheader_context exheader; int exefshashcheck; int romfshashcheck; @@ -87,6 +90,8 @@ u64 ncch_get_exheader_offset(ncch_context* ctx); u64 ncch_get_exheader_size(ncch_context* ctx); u64 ncch_get_logo_offset(ncch_context* ctx); u64 ncch_get_logo_size(ncch_context* ctx); +u64 ncch_get_plainrgn_offset(ncch_context* ctx); +u64 ncch_get_plainrgn_size(ncch_context* ctx); void ncch_print(ncch_context* ctx); int ncch_signature_verify(ncch_context* ctx, rsakey2048* key); void ncch_verify(ncch_context* ctx, u32 flags); diff --git a/ctrtool/romfs.c b/ctrtool/romfs.c index 05ce5c6..5889bdc 100644 --- a/ctrtool/romfs.c +++ b/ctrtool/romfs.c @@ -30,7 +30,41 @@ void romfs_set_usersettings(romfs_context* ctx, settings* usersettings) ctx->usersettings = usersettings; } +void romfs_set_encrypted(romfs_context* ctx, u32 encrypted) +{ + ctx->encrypted = encrypted; +} +void romfs_set_key(romfs_context* ctx, u8 key[16]) +{ + memcpy(ctx->key, key, 16); +} + +void romfs_set_counter(romfs_context* ctx, u8 counter[16]) +{ + memcpy(ctx->counter, counter, 16); +} + +void romfs_fseek(romfs_context* ctx, u64 offset) +{ + u64 data_pos = offset - ctx->offset; + fseeko64(ctx->file, offset, SEEK_SET); + ctr_init_counter(&ctx->aes, ctx->key, ctx->counter); + ctr_add_counter(&ctx->aes, data_pos / 0x10); +} + +size_t romfs_fread(romfs_context* ctx, void* buffer, size_t size, size_t count) +{ + size_t read; + if ((read = fread(buffer, size, count, ctx->file)) != count) { + //printf("romfs_fread() fail\n"); + return read; + } + if (ctx->encrypted) { + ctr_crypt_counter(&ctx->aes, buffer, buffer, size*read); + } + return read; +} void romfs_process(romfs_context* ctx, u32 actions) { @@ -39,15 +73,17 @@ void romfs_process(romfs_context* ctx, u32 actions) u32 fileblockoffset = 0; u32 fileblocksize = 0; - ivfc_set_offset(&ctx->ivfc, ctx->offset); ivfc_set_size(&ctx->ivfc, ctx->size); ivfc_set_file(&ctx->ivfc, ctx->file); ivfc_set_usersettings(&ctx->ivfc, ctx->usersettings); + ivfc_set_counter(&ctx->ivfc, ctx->counter); + ivfc_set_key(&ctx->ivfc, ctx->key); + ivfc_set_encrypted(&ctx->ivfc, ctx->encrypted); ivfc_process(&ctx->ivfc, actions); - fseeko64(ctx->file, ctx->offset, SEEK_SET); - fread(&ctx->header, 1, sizeof(romfs_header), ctx->file); + romfs_fseek(ctx, ctx->offset); + romfs_fread(ctx, &ctx->header, 1, sizeof(romfs_header)); if (getle32(ctx->header.magic) != MAGIC_IVFC) { @@ -57,8 +93,8 @@ void romfs_process(romfs_context* ctx, u32 actions) ctx->infoblockoffset = ctx->offset + 0x1000; - fseeko64(ctx->file, ctx->infoblockoffset, SEEK_SET); - fread(&ctx->infoheader, 1, sizeof(romfs_infoheader), ctx->file); + romfs_fseek(ctx, ctx->infoblockoffset); + romfs_fread(ctx, &ctx->infoheader, 1, sizeof(romfs_infoheader)); if (getle32(ctx->infoheader.headersize) != sizeof(romfs_infoheader)) { @@ -71,25 +107,25 @@ void romfs_process(romfs_context* ctx, u32 actions) fileblockoffset = ctx->infoblockoffset + getle32(ctx->infoheader.section[3].offset); fileblocksize = getle32(ctx->infoheader.section[3].size); + u32 hdrsize = getle32(ctx->infoheader.dataoffset); + u8 *block = malloc(hdrsize); + romfs_fseek(ctx, ctx->infoblockoffset); + romfs_fread(ctx, block, hdrsize, 1); + ctx->dirblock = malloc(dirblocksize); ctx->dirblocksize = dirblocksize; + if(ctx->dirblock) + memcpy(ctx->dirblock, block + getle32(ctx->infoheader.section[1].offset), dirblocksize); + ctx->fileblock = malloc(fileblocksize); ctx->fileblocksize = fileblocksize; + if (ctx->fileblock) + memcpy(ctx->fileblock, block + getle32(ctx->infoheader.section[3].offset), fileblocksize); + + free(block); ctx->datablockoffset = ctx->infoblockoffset + getle32(ctx->infoheader.dataoffset); - if (ctx->dirblock) - { - fseeko64(ctx->file, dirblockoffset, SEEK_SET); - fread(ctx->dirblock, 1, dirblocksize, ctx->file); - } - - if (ctx->fileblock) - { - fseeko64(ctx->file, fileblockoffset, SEEK_SET); - fread(ctx->fileblock, 1, fileblocksize, ctx->file); - } - if (actions & InfoFlag) romfs_print(ctx); @@ -315,7 +351,7 @@ void romfs_extract_datafile(romfs_context* ctx, u64 offset, u64 size, const osch offset += ctx->datablockoffset; - fseeko64(ctx->file, offset, SEEK_SET); + romfs_fseek(ctx, offset); outfile = os_fopen(path, OS_MODE_WRITE); if (outfile == NULL) { @@ -329,7 +365,7 @@ void romfs_extract_datafile(romfs_context* ctx, u64 offset, u64 size, const osch if (max > size) max = size; - if (max != fread(buffer, 1, max, ctx->file)) + if (max != romfs_fread(ctx, buffer, 1, max)) { fprintf(stderr, "Error reading file\n"); goto clean; diff --git a/ctrtool/romfs.h b/ctrtool/romfs.h index c560ab4..7706be5 100644 --- a/ctrtool/romfs.h +++ b/ctrtool/romfs.h @@ -57,6 +57,8 @@ typedef struct FILE* file; oschar_t* extractdir; settings* usersettings; + u8 counter[16]; + u8 key[16]; u64 offset; u64 size; romfs_header header; @@ -70,6 +72,8 @@ typedef struct romfs_direntry direntry; romfs_fileentry fileentry; ivfc_context ivfc; + ctr_aes_context aes; + int encrypted; } romfs_context; void romfs_init(romfs_context* ctx); @@ -77,7 +81,11 @@ void romfs_set_file(romfs_context* ctx, FILE* file); void romfs_set_offset(romfs_context* ctx, u64 offset); void romfs_set_size(romfs_context* ctx, u64 size); void romfs_set_usersettings(romfs_context* ctx, settings* usersettings); -void romfs_test(romfs_context* ctx); +void romfs_set_encrypted(romfs_context* ctx, u32 encrypted); +void romfs_set_key(romfs_context* ctx, u8 key[16]); +void romfs_set_counter(romfs_context* ctx, u8 counter[16]); +void romfs_fseek(romfs_context* ctx, u64 offset); +size_t romfs_fread(romfs_context* ctx, void* buffer, size_t size, size_t count); int romfs_dirblock_read(romfs_context* ctx, u32 diroffset, u32 dirsize, void* buffer); int romfs_dirblock_readentry(romfs_context* ctx, u32 diroffset, romfs_direntry* entry); int romfs_fileblock_read(romfs_context* ctx, u32 fileoffset, u32 filesize, void* buffer); diff --git a/ctrtool/settings.c b/ctrtool/settings.c index cbc7aec..7888d54 100644 --- a/ctrtool/settings.c +++ b/ctrtool/settings.c @@ -120,6 +120,14 @@ filepath* settings_get_content_path(settings* usersettings) return 0; } +filepath* settings_get_plainrgn_path(settings* usersettings) +{ + if (usersettings) + return &usersettings->plainrgnpath; + else + return 0; +} + unsigned int settings_get_mediaunit_size(settings* usersettings) { if (usersettings) @@ -255,6 +263,11 @@ void settings_set_romfs_dir_path(settings* usersettings, const char* path) filepath_set(&usersettings->romfsdirpath, path); } +void settings_set_plainrgn_path(settings* usersettings, const char* path) +{ + filepath_set(&usersettings->plainrgnpath, path); +} + void settings_set_mediaunit_size(settings* usersettings, unsigned int size) { usersettings->mediaunitsize = size; diff --git a/ctrtool/settings.h b/ctrtool/settings.h index c75bb94..30b42d2 100644 --- a/ctrtool/settings.h +++ b/ctrtool/settings.h @@ -15,6 +15,7 @@ typedef struct filepath romfsdirpath; filepath exheaderpath; filepath logopath; + filepath plainrgnpath; filepath certspath; filepath contentpath; filepath tikpath; @@ -43,6 +44,7 @@ filepath* settings_get_exefs_dir_path(settings* usersettings); filepath* settings_get_romfs_dir_path(settings* usersettings); filepath* settings_get_firm_dir_path(settings* usersettings); filepath* settings_get_wav_path(settings* usersettings); +filepath* settings_get_plainrgn_path(settings* usersettings); unsigned int settings_get_mediaunit_size(settings* usersettings); unsigned char* settings_get_ncch_key(settings* usersettings); unsigned char* settings_get_ncch_fixedsystemkey(settings* usersettings); @@ -66,6 +68,7 @@ void settings_set_exefs_dir_path(settings* usersettings, const char* path); void settings_set_romfs_dir_path(settings* usersettings, const char* path); void settings_set_firm_dir_path(settings* usersettings, const char* path); void settings_set_wav_path(settings* usersettings, const char* path); +void settings_set_plainrgn_path(settings* usersettings, const char* path); void settings_set_mediaunit_size(settings* usersettings, unsigned int size); void settings_set_ignore_programid(settings* usersettings, int enable); void settings_set_list_romfs_files(settings* usersettings, int enable); diff --git a/ctrtool/utils.c b/ctrtool/utils.c index d2d4adb..cfaf184 100644 --- a/ctrtool/utils.c +++ b/ctrtool/utils.c @@ -84,6 +84,43 @@ void putle32(u8* p, u32 n) p[3] = n>>24; } +void putle64(u8* p, u64 n) +{ + p[0] = n; + p[1] = n >> 8; + p[2] = n >> 16; + p[3] = n >> 24; + p[4] = n >> 32; + p[5] = n >> 40; + p[6] = n >> 48; + p[7] = n >> 56; +} + +void putbe16(u8* p, u16 n) +{ + p[1] = n; + p[0] = n >> 8; +} + +void putbe32(u8* p, u32 n) +{ + p[3] = n; + p[2] = n >> 8; + p[1] = n >> 16; + p[0] = n >> 24; +} + +void putbe64(u8* p, u64 n) +{ + p[7] = n; + p[6] = n >> 8; + p[5] = n >> 16; + p[4] = n >> 24; + p[3] = n >> 32; + p[2] = n >> 40; + p[1] = n >> 48; + p[0] = n >> 56; +} void readkeyfile(u8* key, const char* keyfname) { diff --git a/ctrtool/utils.h b/ctrtool/utils.h index 519a95e..4d766aa 100644 --- a/ctrtool/utils.h +++ b/ctrtool/utils.h @@ -27,6 +27,10 @@ u32 getbe32(const u8* p); u32 getbe16(const u8* p); void putle16(u8* p, u16 n); void putle32(u8* p, u32 n); +void putle64(u8* p, u64 n); +void putbe16(u8* p, u16 n); +void putbe32(u8* p, u32 n); +void putbe64(u8* p, u64 n); void readkeyfile(u8* key, const char* keyfname); void memdump(FILE* fout, const char* prefix, const u8* data, u32 size);