| 
									
										
										
										
											2009-07-28 21:32:10 +00:00
										 |  |  | // Copyright (C) 2003 Dolphin Project.
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, version 2.0.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU General Public License 2.0 for more details.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // A copy of the GPL 2.0 should have been included with the program.
 | 
					
						
							|  |  |  | // If not, see http://www.gnu.org/licenses/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Official SVN repository and contact information can be found at
 | 
					
						
							|  |  |  | // http://code.google.com/p/dolphin-emu/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "VolumeWiiCrypted.h"
 | 
					
						
							|  |  |  | #include "StringUtil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace DiscIO | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | CVolumeWiiCrypted::CVolumeWiiCrypted(IBlobReader* _pReader, u64 _VolumeOffset, | 
					
						
							|  |  |  | 									 const unsigned char* _pVolumeKey) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	: m_pReader(_pReader), | 
					
						
							|  |  |  | 	m_pBuffer(0), | 
					
						
							|  |  |  | 	m_VolumeOffset(_VolumeOffset), | 
					
						
							| 
									
										
										
										
											2010-09-08 00:20:19 +00:00
										 |  |  | 	dataOffset(0x20000), | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	m_LastDecryptedBlockOffset(-1) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	AES_set_decrypt_key(_pVolumeKey, 128, &m_AES_KEY); | 
					
						
							|  |  |  | 	m_pBuffer = new u8[0x8000]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CVolumeWiiCrypted::~CVolumeWiiCrypted() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	delete m_pReader; // is this really our responsibility?
 | 
					
						
							|  |  |  | 	m_pReader = NULL; | 
					
						
							|  |  |  | 	delete[] m_pBuffer; | 
					
						
							|  |  |  | 	m_pBuffer = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-22 13:59:06 +00:00
										 |  |  | bool CVolumeWiiCrypted::RAWRead( u64 _Offset, u64 _Length, u8* _pBuffer ) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// HyperIris: hack for DVDLowUnencryptedRead
 | 
					
						
							|  |  |  | 	// Medal Of Honor Heroes 2 read this DVD offset for PartitionsInfo
 | 
					
						
							|  |  |  | 	// and, PartitionsInfo is not encrypted, let's read it directly.
 | 
					
						
							|  |  |  | 	if (!m_pReader->Read(_Offset, _Length, _pBuffer)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return(false); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | bool CVolumeWiiCrypted::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer) const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (m_pReader == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return(false); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (_Length > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		static unsigned char IV[16]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// math block offset
 | 
					
						
							|  |  |  | 		u64 Block  = _ReadOffset / 0x7C00; | 
					
						
							|  |  |  | 		u64 Offset = _ReadOffset % 0x7C00; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// read current block
 | 
					
						
							| 
									
										
										
										
											2010-09-08 00:20:19 +00:00
										 |  |  | 		if (!m_pReader->Read(m_VolumeOffset + dataOffset + Block * 0x8000, 0x8000, m_pBuffer)) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			return(false); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (m_LastDecryptedBlockOffset != Block) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			memcpy(IV, m_pBuffer + 0x3d0, 16); | 
					
						
							|  |  |  | 			AES_cbc_encrypt(m_pBuffer + 0x400, m_LastDecryptedBlock, 0x7C00, &m_AES_KEY, IV, AES_DECRYPT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			m_LastDecryptedBlockOffset = Block; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// copy the encrypted data
 | 
					
						
							|  |  |  | 		u64 MaxSizeToCopy = 0x7C00 - Offset; | 
					
						
							|  |  |  | 		u64 CopySize = (_Length > MaxSizeToCopy) ? MaxSizeToCopy : _Length; | 
					
						
							|  |  |  | 		memcpy(_pBuffer, &m_LastDecryptedBlock[Offset], (size_t)CopySize); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// increase buffers
 | 
					
						
							|  |  |  | 		_Length -= CopySize; | 
					
						
							| 
									
										
										
										
											2009-03-07 18:03:53 +00:00
										 |  |  | 		_pBuffer	+= CopySize; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 		_ReadOffset += CopySize; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 07:19:10 +00:00
										 |  |  | bool CVolumeWiiCrypted::GetTitleID(u8* _pBuffer) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-08 00:20:19 +00:00
										 |  |  | 	// Tik is at m_VolumeOffset size 0x2A4
 | 
					
						
							|  |  |  | 	// TitleID offset in tik is 0x1DC
 | 
					
						
							|  |  |  | 	return RAWRead(m_VolumeOffset + 0x1DC, 8, _pBuffer); | 
					
						
							| 
									
										
										
										
											2010-01-14 07:19:10 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-09-08 00:20:19 +00:00
										 |  |  | void CVolumeWiiCrypted::GetTMD(u8* _pBuffer, u32 * _sz) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*_sz = 0; | 
					
						
							|  |  |  | 	u32 tmdSz, | 
					
						
							|  |  |  | 		tmdAddr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	RAWRead(m_VolumeOffset + 0x2a4, sizeof(u32), (u8*)&tmdSz); | 
					
						
							|  |  |  | 	RAWRead(m_VolumeOffset + 0x2a8, sizeof(u32), (u8*)&tmdAddr); | 
					
						
							|  |  |  | 	tmdSz = Common::swap32(tmdSz); | 
					
						
							|  |  |  | 	tmdAddr = Common::swap32(tmdAddr) << 2; | 
					
						
							|  |  |  | 	RAWRead(m_VolumeOffset + tmdAddr, tmdSz, _pBuffer); | 
					
						
							|  |  |  | 	*_sz = tmdSz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | std::string CVolumeWiiCrypted::GetUniqueID() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (m_pReader == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char ID[7]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!Read(0, 6, (u8*)ID)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	ID[6] = '\0'; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	return ID; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | IVolume::ECountry CVolumeWiiCrypted::GetCountry() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (!m_pReader) | 
					
						
							| 
									
										
										
										
											2009-07-03 22:34:51 +00:00
										 |  |  | 		return COUNTRY_UNKNOWN; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	u8 CountryCode; | 
					
						
							|  |  |  | 	m_pReader->Read(3, 1, &CountryCode); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-03 22:34:51 +00:00
										 |  |  | 	return CountrySwitch(CountryCode); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | std::string CVolumeWiiCrypted::GetMakerID() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (m_pReader == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char makerID[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!Read(0x4, 0x2, (u8*)&makerID)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	makerID[2] = '\0'; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	return makerID; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | std::string CVolumeWiiCrypted::GetName() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (m_pReader == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char name[0xFF]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!Read(0x20, 0x60, (u8*)&name)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	return name; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | u32 CVolumeWiiCrypted::GetFSTSize() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (m_pReader == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	u32 size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!Read(0x428, 0x4, (u8*)&size)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	return size; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | std::string CVolumeWiiCrypted::GetApploaderDate() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (m_pReader == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char date[16]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!Read(0x2440, 0x10, (u8*)&date)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return std::string(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	date[10] = '\0'; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 	return date; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 19:19:15 +00:00
										 |  |  | u64 CVolumeWiiCrypted::GetSize() const | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (m_pReader) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return m_pReader->GetDataSize(); | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-13 19:07:59 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-22 13:59:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | } // namespace
 |