IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup, u32 _VolumeNum) { IBlobReader* pReader = CreateBlobReader(_rFilename.c_str()); if (pReader == NULL) return NULL; switch (GetDiscType(*pReader)) { case DISC_TYPE_WII: case DISC_TYPE_GC: return new CVolumeGC(pReader); case DISC_TYPE_WAD: return new CVolumeWAD(pReader); case DISC_TYPE_WII_CONTAINER: { u8 region; pReader->Read(0x3,1,®ion); IVolume* pVolume = CreateVolumeFromCryptedWiiImage(*pReader, _PartitionGroup, 0, _VolumeNum, region == 'K'); if (pVolume == NULL) { delete pReader; } return pVolume; } break; case DISC_TYPE_UNK: default: std::string Filename, ext; SplitPath(_rFilename, NULL, &Filename, &ext); Filename += ext; NOTICE_LOG(DISCIO, "%s does not have the Magic word for a gcm, wiidisc or wad file\n" "Set Log Verbosity to Warning and attempt to load the game again to view the values", Filename.c_str()); delete pReader; return NULL; } // unreachable code return NULL; }
void VolumeKeyForPartition(IBlobReader& _rReader, u64 offset, u8* VolumeKey) { CBlobBigEndianReader Reader(_rReader); u8 SubKey[16]; _rReader.Read(offset + 0x1bf, 16, SubKey); u8 IV[16]; memset(IV, 0, 16); _rReader.Read(offset + 0x44c, 8, IV); bool usingKoreanKey = false; // Issue: 6813 // Magic value is at partition's offset + 0x1f1 (1byte) // If encrypted with the Korean key, the magic value would be 1 // Otherwise it is zero if (Reader.Read8(0x3) == 'K' && Reader.Read8(offset + 0x1f1) == 1) usingKoreanKey = true; mbedtls_aes_context AES_ctx; mbedtls_aes_setkey_dec(&AES_ctx, (usingKoreanKey ? s_master_key_korean : s_master_key), 128); mbedtls_aes_crypt_cbc(&AES_ctx, MBEDTLS_AES_DECRYPT, 16, IV, SubKey, VolumeKey); }