diff --git a/Linux/make_npdata.c b/Linux/make_npdata.c
index c6eab2d..feaa70e 100644
--- a/Linux/make_npdata.c
+++ b/Linux/make_npdata.c
@@ -535,12 +535,26 @@ void validate_npd_hashes(const char* file_name, unsigned char *klicensee, NPD_HE
int file_name_length = strlen(file_name);
unsigned char *buf = (unsigned char *) malloc (0x30 + file_name_length);
+ unsigned char dev[0x60];
unsigned char key[0x10];
+ memset(dev, 0, 0x60);
+ memset(key, 0, 0x10);
- // Build the buffer (content_id + file_name).
+ // Build the title buffer (content_id + file_name).
memcpy(buf, npd->content_id, 0x30);
memcpy(buf + 0x30, file_name, file_name_length);
+ // Build the dev buffer (first 0x60 bytes of NPD header in big-endian).
+ memcpy(dev, npd, 0x60);
+
+ // Fix endianness.
+ int version = se32(npd->version);
+ int license = se32(npd->license);
+ int type = se32(npd->type);
+ memcpy(dev + 0x4, &version, 4);
+ memcpy(dev + 0x8, &license, 4);
+ memcpy(dev + 0xC, &type, 4);
+
// Hash with NPDRM_OMAC_KEY_3 and compare with title_hash.
title_hash_result = cmac_hash_compare(NPDRM_OMAC_KEY_3, 0x10, buf, 0x30 + file_name_length, npd->title_hash);
@@ -575,7 +589,7 @@ void validate_npd_hashes(const char* file_name, unsigned char *klicensee, NPD_HE
xor(key, klicensee, NPDRM_OMAC_KEY_2, 0x10);
// Hash with generated key and compare with dev_hash.
- dev_hash_result = cmac_hash_compare(key, 0x10, (unsigned char *)npd, 0x60, npd->dev_hash);
+ dev_hash_result = cmac_hash_compare(key, 0x10, dev, 0x60, npd->dev_hash);
if (verbose)
{
@@ -937,7 +951,7 @@ void forge_npd_title_hash(const char* file_name, NPD_HEADER *npd)
unsigned char title_hash[0x10];
memset(title_hash, 0, 0x10);
- // Build the buffer (content_id + file_name).
+ // Build the title buffer (content_id + file_name).
memcpy(buf, npd->content_id, 0x30);
memcpy(buf + 0x30, file_name, file_name_length);
@@ -953,15 +967,28 @@ void forge_npd_title_hash(const char* file_name, NPD_HEADER *npd)
void forge_npd_dev_hash(unsigned char *klicensee, NPD_HEADER *npd)
{
unsigned char key[0x10];
+ unsigned char dev[0x60];
unsigned char dev_hash[0x10];
memset(key, 0, 0x10);
+ memset(dev, 0, 0x60);
memset(dev_hash, 0, 0x10);
+ // Build the dev buffer (first 0x60 bytes of NPD header in big-endian).
+ memcpy(dev, npd, 0x60);
+
+ // Fix endianness.
+ int version = se32(npd->version);
+ int license = se32(npd->license);
+ int type = se32(npd->type);
+ memcpy(dev + 0x4, &version, 4);
+ memcpy(dev + 0x8, &license, 4);
+ memcpy(dev + 0xC, &type, 4);
+
// Generate klicensee xor key.
xor(key, klicensee, NPDRM_OMAC_KEY_2, 0x10);
// Forge with the generated key and create the dev hash.
- cmac_hash_forge(key, 0x10, (unsigned char *)npd, 0x60, dev_hash);
+ cmac_hash_forge(key, 0x10, dev, 0x60, dev_hash);
// Write the key in the NPD header.
memcpy(npd->dev_hash, dev_hash, 0x10);
@@ -1077,27 +1104,29 @@ bool pack_data(FILE *input, FILE *output, const char* input_file_name, unsigned
}
// Write forged NPD header.
- int version_le = se32(NPD->version);
- int license_le = se32(NPD->license);
- int type_le = se32(NPD->type);
+ int version_be = se32(NPD->version);
+ int license_be = se32(NPD->license);
+ int type_be = se32(NPD->type);
+ u64 unk1_be = se64(NPD->unk1);
+ u64 unk2_be = se64(NPD->unk2);
fwrite(NPD->magic, sizeof(NPD->magic), 1, output);
- fwrite(&version_le, sizeof(version_le), 1, output);
- fwrite(&license_le, sizeof(license_le), 1, output);
- fwrite(&type_le, sizeof(type_le), 1, output);
+ fwrite(&version_be, sizeof(version_be), 1, output);
+ fwrite(&license_be, sizeof(license_be), 1, output);
+ fwrite(&type_be, sizeof(type_be), 1, output);
fwrite(NPD->content_id, sizeof(NPD->content_id), 1, output);
fwrite(NPD->digest, sizeof(NPD->digest), 1, output);
fwrite(NPD->title_hash, sizeof(NPD->title_hash), 1, output);
fwrite(NPD->dev_hash, sizeof(NPD->dev_hash), 1, output);
- fwrite(&NPD->unk1, sizeof(NPD->unk1), 1, output);
- fwrite(&NPD->unk2, sizeof(NPD->unk2), 1, output);
+ fwrite(&unk1_be, sizeof(unk1_be), 1, output);
+ fwrite(&unk2_be, sizeof(unk2_be), 1, output);
// Write forged EDAT/SDAT header.
- int flags_le = se32(EDAT->flags);
- int block_size_le = se32(EDAT->block_size);
- u64 file_size_le = se64(EDAT->file_size);
- fwrite(&flags_le, sizeof(flags_le), 1, output);
- fwrite(&block_size_le, sizeof(block_size_le), 1, output);
- fwrite(&file_size_le, sizeof(file_size_le), 1, output);
+ int flags_be = se32(EDAT->flags);
+ int block_size_be = se32(EDAT->block_size);
+ u64 file_size_be = se64(EDAT->file_size);
+ fwrite(&flags_be, sizeof(flags_be), 1, output);
+ fwrite(&block_size_be, sizeof(block_size_be), 1, output);
+ fwrite(&file_size_be, sizeof(file_size_be), 1, output);
printf("Encrypting data...\n");
if (encrypt_data(input, output, EDAT, NPD, key, verbose))
@@ -1128,7 +1157,7 @@ void print_usage()
printf("Usage: make_npdata [-v] -e