1 /*---------------------------------------------------------------------------* 2 Project: TwlSDK - CARD - include 3 File: hash.h 4 5 Copyright 2007-2008 Nintendo. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Date:: 2008-09-17#$ 14 $Rev: 8556 $ 15 $Author: okubata_ryoma $ 16 17 *---------------------------------------------------------------------------*/ 18 #ifndef NITRO_CARD_HASH_H_ 19 #define NITRO_CARD_HASH_H_ 20 21 22 #include <nitro/misc.h> 23 #include <nitro/types.h> 24 #include <nitro/card/types.h> 25 #include <nitro/mi/device.h> 26 27 28 #ifdef __cplusplus 29 extern "C" 30 { 31 #endif 32 33 34 /*---------------------------------------------------------------------------*/ 35 /* Constants */ 36 37 #define CARD_ROM_HASH_SIZE 20 38 39 40 /*---------------------------------------------------------------------------*/ 41 /* Declarations */ 42 43 struct CARDRomHashSector; 44 struct CARDRomHashBlock; 45 struct CARDRomHashContext; 46 47 // This structure manages the image cache for various sectors. 48 typedef struct CARDRomHashSector 49 { 50 struct CARDRomHashSector *next; 51 u32 index; 52 u32 offset; 53 void *image; 54 } 55 CARDRomHashSector; 56 57 // This block structure manages the hash and image cache for various sectors. 58 // If the final block size of the NTR region is an odd number, the start of the LTD region will follow consecutively. You must therefore note that no more than a single block may exist in both regions. 59 // 60 typedef struct CARDRomHashBlock 61 { 62 struct CARDRomHashBlock *next; 63 u32 index; 64 u32 offset; 65 u8 *hash; 66 u8 *hash_aligned; 67 } 68 CARDRomHashBlock; 69 70 // This structure manages SRL file hashes. 71 // Each program has different size requirements that cannot be calculated statically. As a result, the plan is to dynamically allocate only the appropriate amount from the arena. 72 // 73 // Memory requirements are as follows. 74 // - The master hash table: 75 // A ROM header must be compared with its hash to determine if it is valid, so we will load it all at once from ROM and make it resident during initialization. 76 // 77 // Calculate the number of bytes required as follows: (ROM size / sector size / number of sectors) * 20 bytes (for SHA1). If the ROM size is 1 gigabit, the sector size is 1024 bytes, and there are 32 sectors, this will be approximately 80 KB. 78 // 79 // - The block cache: 80 // Manages the ROM image cache and its hash in blocks. 81 // A list structure that can always manage multiple blocks is necessary because discrete accesses may span block boundaries. 82 // 83 // Memory is required only for the total list count, with 20 structures per sector + a. 84 // - The sector cache: 85 // Maintains the actual image cache. 86 // Blocks will not necessarily access all sectors universally, so a separate list structure is required to manage sectors, as well. 87 // 88 typedef struct CARDRomHashContext 89 { 90 // Basic settings obtained from the ROM header 91 CARDRomRegion area_ntr; 92 CARDRomRegion area_ltd; 93 CARDRomRegion sector_hash; 94 CARDRomRegion block_hash; 95 u32 bytes_per_sector; 96 u32 sectors_per_block; 97 u32 block_max; 98 u32 sector_max; 99 100 // Device interface to load data and its hash 101 void *userdata; 102 MIDeviceReadFunction ReadSync; 103 MIDeviceReadFunction ReadAsync; 104 105 // Thread that is currently loading data. 106 OSThread *loader; 107 void *recent_load; 108 109 // Sector and block cache 110 CARDRomHashSector *loading_sector; // Sector waiting for media to load 111 CARDRomHashSector *loaded_sector; // Sector waiting for hash verification 112 CARDRomHashSector *valid_sector; // Sector that has already been verified 113 CARDRomHashBlock *loading_block; // Block waiting for media to load 114 CARDRomHashBlock *loaded_block; // Block waiting for hash verification 115 CARDRomHashBlock *valid_block; // Block that has already been verified 116 // Array allocated from an arena 117 u8 *master_hash; // A block hash array 118 u8 *images; // Sector image 119 u8 *hashes; // The hash array within a block 120 CARDRomHashSector *sectors; // Sector data 121 CARDRomHashBlock *blocks; // Block data 122 } 123 CARDRomHashContext; 124 125 126 /*---------------------------------------------------------------------------*/ 127 /* Functions */ 128 129 /*---------------------------------------------------------------------------* 130 Name: CARD_InitRomHashContext 131 132 Description: Initializes a ROM hash context. 133 134 Arguments: context: The CARDRomHashContext structure that should be initialized 135 header: A ROM header buffer with ROM data that should be managed 136 (This is only used within this function and does not need to be maintained) 137 buffer: Buffer for management data to use within a context 138 length: Buffer size for management data 139 (This can be calculated with the CARD_CalcRomHashBufferLength function) 140 sync: Synchronous callback function for device reads 141 async: Asynchronous callback function for device reads (NULL if unsupported) 142 userdata: Arbitrary user-defined argument to pass to the device read callback 143 144 Returns: None. 145 *---------------------------------------------------------------------------*/ 146 void CARD_InitRomHashContext(CARDRomHashContext *context, const CARDRomHeaderTWL *header, 147 void *buffer, u32 length, 148 MIDeviceReadFunction sync, MIDeviceReadFunction async, 149 void *userdata); 150 151 /*---------------------------------------------------------------------------* 152 Name: CARD_CalcRomHashBufferLength 153 154 Description: Gets the buffer size required for the ROM hash context. 155 156 Arguments: header: A ROM header buffer with ROM data that should be managed 157 158 Returns: The buffer size required for the ROM hash context. 159 *---------------------------------------------------------------------------*/ 160 u32 CARD_CalcRomHashBufferLength(const CARDRomHeaderTWL *header); 161 162 /*---------------------------------------------------------------------------* 163 Name: CARDi_NotifyRomHashReadAsync 164 165 Description: Notifies a hash context that an asynchronous device read has finished. 166 167 Arguments: context: CARDRomHashContext structure. 168 169 Returns: None. 170 *---------------------------------------------------------------------------*/ 171 void CARD_NotifyRomHashReadAsync(CARDRomHashContext *context); 172 173 /*---------------------------------------------------------------------------* 174 Name: CARD_ReadRomHashImage 175 176 Description: Loads a ROM image with a verified hash from the specified offset. 177 178 Arguments: context: CARDRomHashContext structure. 179 offset: The ROM offset to access. 180 181 Returns: None. 182 *---------------------------------------------------------------------------*/ 183 void CARD_ReadRomHashImage(CARDRomHashContext *context, void *buffer, u32 offset, u32 length); 184 185 186 #ifdef __cplusplus 187 } // extern "C" 188 #endif 189 190 191 #endif // NITRO_CARD_HASH_H_ 192