33{
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); }
37 p[0] = (uint8_t)(v & 0xFF);
38 p[1] = (uint8_t)((v >> 8) & 0xFF);
39 p[2] = (uint8_t)((v >> 16) & 0xFF);
40 p[3] = (uint8_t)((v >> 24) & 0xFF);
47 if(regions == NULL || region_count == 0)
return NULL;
52 for(uint32_t i = 0; i < region_count; i++)
54 if(phys_group >= regions[i].start_sector && phys_group < regions[i].end_sector)
58 return regions[i].
key;
71void wii_encrypt_group(
const uint8_t key[16],
const uint8_t *hash_block,
const uint8_t *data_in, uint8_t *out)
75 memset(iv, 0,
sizeof(iv));
82 memcpy(data_iv, out + 0x3D0, 16);
87void wii_decrypt_group(
const uint8_t key[16],
const uint8_t *in, uint8_t *hash_block, uint8_t *data_out)
91 memset(iv, 0,
sizeof(iv));
98 memcpy(data_iv, in + 0x3D0, 16);
108 if(out_data == NULL || out_len == NULL)
return -1;
112 uint32_t size = 4 + count * 24;
113 uint8_t *buf = (uint8_t *)malloc(size);
115 if(buf == NULL)
return -4;
119 for(uint32_t i = 0; i < count; i++)
121 uint32_t offset = 4 + i * 24;
122 write_le32(buf + offset, regions[i].start_sector);
123 write_le32(buf + offset + 4, regions[i].end_sector);
124 memcpy(buf + offset + 8, regions[i].key, 16);
135 if(data == NULL || regions == NULL || count == NULL)
return -1;
137 if(data_len < 4)
return -2;
143 if(region_count == 0)
150 uint32_t required = 4 + region_count * 24;
152 if(data_len < required)
return -2;
156 if(r == NULL)
return -4;
158 for(uint32_t i = 0; i < region_count; i++)
160 uint32_t offset = 4 + i * 24;
163 memcpy(r[i].key, data + offset + 8, 16);
165 if(r[i].start_sector >= r[i].end_sector)
174 *count = region_count;
182 if(ctx == NULL)
return;
189 HASH_FIND_INT(ctx->
mediaTags, &tag, item);
191 if(item != NULL && item->
length >= 4)
void aes128_cbc_decrypt(const uint8_t key[16], const uint8_t iv[16], uint8_t *data, uint32_t length)
AES-128 CBC decrypt data in-place.
void aes128_cbc_encrypt(const uint8_t key[16], const uint8_t iv[16], uint8_t *data, uint32_t length)
AES-128 CBC encrypt data in-place.
A Wii partition region entry (in-memory representation).
uint32_t start_sector
First physical sector of partition.
uint8_t key[16]
AES-128 partition key.
uint32_t end_sector
End physical sector (exclusive).
Master context representing an open or in‑creation Aaru image.
mediaTagEntry * mediaTags
Hash table of extra media tags (uthash root).
uint32_t wii_partition_region_count
Number of partition regions.
void * wii_partition_regions
Parsed WiiPartitionRegion array, NULL if not loaded.
bool wii_cache_valid
Whether the encrypted group cache is valid.
uint8_t * wii_encrypted_group_cache
Cached re-encrypted 0x8000-byte group.
Hash table entry for an arbitrary media tag (e.g., proprietary drive/medium descriptor).
uint8_t * data
Tag data blob (opaque to library core); length bytes long.
uint32_t length
Length in bytes of data.
const uint8_t * wii_get_sector_key(const WiiPartitionRegion *regions, uint32_t region_count, uint64_t logical_sector)
Get the encryption key for a given logical sector (2048-byte).
int32_t wii_deserialize_partition_key_map(const uint8_t *data, uint32_t data_len, WiiPartitionRegion **regions, uint32_t *count)
Deserialize a Wii partition key map from a media tag buffer.
static uint32_t read_le32(const uint8_t *p)
static void write_le32(uint8_t *p, uint32_t v)
int32_t wii_serialize_partition_key_map(const WiiPartitionRegion *regions, uint32_t count, uint8_t **out_data, uint32_t *out_len)
Serialize a Wii partition key map for storage as a media tag.
void wii_encrypt_group(const uint8_t key[16], const uint8_t *hash_block, const uint8_t *data_in, uint8_t *out)
Encrypt a Wii group (0x8000 bytes) from separate hash_block + data.
bool wii_is_sector_encrypted(const WiiPartitionRegion *regions, uint32_t region_count, uint64_t logical_sector)
Check if a logical sector is in an encrypted region.
void wii_decrypt_group(const uint8_t key[16], const uint8_t *in, uint8_t *hash_block, uint8_t *data_out)
Decrypt a Wii group (0x8000 bytes) into separate hash_block + data.
void wii_lazy_init(aaruformat_context *ctx)
Lazy initialization: load partition key map from media tags.
#define WII_GROUP_SIZE
Wii physical group size (32 KiB).
#define WII_MAX_PARTITIONS
Maximum number of partitions supported.
#define WII_GROUP_DATA_SIZE
User data size within a group (31 KiB).
#define WII_GROUP_HASH_SIZE
Hash block size within a group (1 KiB).
#define WII_LOGICAL_PER_GROUP
Number of 2048-byte logical sectors per group.