libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
wii_crypto.c File Reference
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <aaruformat.h>
#include "../lib/aes128.h"
#include "wii_crypto.h"

Go to the source code of this file.

Functions

static uint32_t read_le32 (const uint8_t *p)
static void write_le32 (uint8_t *p, uint32_t v)
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).
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_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.
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.
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.
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.
void wii_lazy_init (aaruformat_context *ctx)
 Lazy initialization: load partition key map from media tags.

Function Documentation

◆ read_le32()

uint32_t read_le32 ( const uint8_t * p)
static

Definition at line 32 of file wii_crypto.c.

References read_le32().

◆ wii_decrypt_group()

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.

Parameters
key16-byte AES-128 partition key.
in0x8000-byte encrypted input.
hash_block0x400-byte output for hash block.
data_out0x7C00-byte output for user data.

< Hash block size within a group (1 KiB).

< Hash block size within a group (1 KiB).

< Hash block size within a group (1 KiB).

< User data size within a group (31 KiB).

< User data size within a group (31 KiB).

Definition at line 87 of file wii_crypto.c.

References aes128_cbc_decrypt(), wii_decrypt_group(), WII_GROUP_DATA_SIZE, and WII_GROUP_HASH_SIZE.

Referenced by wii_decrypt_group().

◆ wii_deserialize_partition_key_map()

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.

< Maximum number of partitions supported.

Definition at line 132 of file wii_crypto.c.

References WiiPartitionRegion::end_sector, read_le32(), WiiPartitionRegion::start_sector, wii_deserialize_partition_key_map(), and WII_MAX_PARTITIONS.

Referenced by wii_deserialize_partition_key_map(), and wii_lazy_init().

◆ wii_encrypt_group()

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.

The hash block IV is all zeros. The data IV is bytes 0x3D0..0x3DF of the encrypted hash block output (matching Dolphin's VolumeWii::EncryptBlock).

Parameters
key16-byte AES-128 partition key.
hash_block0x400-byte hash block (plaintext input).
data_in0x7C00-byte user data (plaintext input).
out0x8000-byte output buffer (encrypted).

< Hash block size within a group (1 KiB).

< Hash block size within a group (1 KiB).

< Hash block size within a group (1 KiB).

< User data size within a group (31 KiB).

< Hash block size within a group (1 KiB).

< User data size within a group (31 KiB).

Definition at line 71 of file wii_crypto.c.

References aes128_cbc_encrypt(), wii_encrypt_group(), WII_GROUP_DATA_SIZE, and WII_GROUP_HASH_SIZE.

Referenced by aaruf_read_sector(), and wii_encrypt_group().

◆ wii_get_sector_key()

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).

Converts the logical sector address to a physical sector address, then looks up which partition it belongs to and whether it is encrypted.

Parameters
regionsArray of partition regions.
region_countNumber of partition regions.
logical_sectorLogical sector address (2048-byte units).
Returns
Pointer to the 16-byte key if encrypted, NULL if plaintext.

< Number of 2048-byte logical sectors per group.

Definition at line 45 of file wii_crypto.c.

References WiiPartitionRegion::key, wii_get_sector_key(), and WII_LOGICAL_PER_GROUP.

Referenced by aaruf_read_sector(), wii_get_sector_key(), and wii_is_sector_encrypted().

◆ wii_is_sector_encrypted()

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.

Definition at line 66 of file wii_crypto.c.

References wii_get_sector_key(), and wii_is_sector_encrypted().

Referenced by wii_is_sector_encrypted().

◆ wii_lazy_init()

void wii_lazy_init ( aaruformat_context * ctx)

Lazy initialization: load partition key map from media tags.

Populates ctx->wii_partition_regions and allocates the group cache.

Parameters
ctxAaruFormat context.

< Wii physical group size (32 KiB).

Definition at line 180 of file wii_crypto.c.

References mediaTagEntry::data, kMediaTagWiiPartitionKeyMap, mediaTagEntry::length, aaruformat_context::mediaTags, aaruformat_context::wii_cache_valid, wii_deserialize_partition_key_map(), aaruformat_context::wii_encrypted_group_cache, WII_GROUP_SIZE, wii_lazy_init(), aaruformat_context::wii_partition_region_count, and aaruformat_context::wii_partition_regions.

Referenced by aaruf_read_sector(), and wii_lazy_init().

◆ wii_serialize_partition_key_map()

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.

Same format as Wii U partition key map: [4 bytes] partition_count (uint32 LE) Per partition (24 bytes): start_sector (LE), end_sector (LE), key[16]

< Maximum number of partitions supported.

Definition at line 105 of file wii_crypto.c.

References WII_MAX_PARTITIONS, wii_serialize_partition_key_map(), and write_le32().

Referenced by wii_serialize_partition_key_map().

◆ write_le32()

void write_le32 ( uint8_t * p,
uint32_t v )
static

Definition at line 35 of file wii_crypto.c.

References write_le32().