libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
wiiu_crypto.c File Reference
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <aaruformat.h>
#include "../lib/aes128.h"
#include "wiiu_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 * wiiu_get_sector_key (const WiiuPartitionRegion *regions, uint32_t region_count, uint64_t logical_sector)
 Get the encryption key for a given logical sector (2048-byte).
bool wiiu_is_sector_encrypted (const WiiuPartitionRegion *regions, uint32_t region_count, uint64_t logical_sector)
 Check if a logical sector (2048-byte) is in an encrypted region.
void wiiu_encrypt_physical_sector (const uint8_t key[16], uint8_t *data, uint32_t length)
 Encrypt a full 0x8000-byte physical sector in-place.
void wiiu_decrypt_physical_sector (const uint8_t key[16], uint8_t *data, uint32_t length)
 Decrypt a full 0x8000-byte physical sector in-place.
int32_t wiiu_serialize_partition_key_map (const WiiuPartitionRegion *regions, uint32_t count, uint8_t **out_data, uint32_t *out_len)
 Serialize a partition key map for storage as a media tag.
int32_t wiiu_deserialize_partition_key_map (const uint8_t *data, uint32_t data_len, WiiuPartitionRegion **regions, uint32_t *count)
 Deserialize a partition key map from a media tag buffer.
void wiiu_lazy_init (aaruformat_context *ctx)
 Lazy initialization: load disc key and partition key map from media tags.

Function Documentation

◆ read_le32()

uint32_t read_le32 ( const uint8_t * p)
static

Definition at line 31 of file wiiu_crypto.c.

References read_le32().

◆ wiiu_decrypt_physical_sector()

void wiiu_decrypt_physical_sector ( const uint8_t key[16],
uint8_t * data,
uint32_t length )

Decrypt a full 0x8000-byte physical sector in-place.

Uses AES-128-CBC with IV=0 (Wii U scheme).

Parameters
key16-byte AES-128 key.
dataBuffer to decrypt in-place (must be 0x8000 bytes).
lengthNumber of bytes (must be 0x8000).

Definition at line 79 of file wiiu_crypto.c.

References aes128_cbc_decrypt(), and wiiu_decrypt_physical_sector().

Referenced by wiiu_decrypt_physical_sector().

◆ wiiu_deserialize_partition_key_map()

int32_t wiiu_deserialize_partition_key_map ( const uint8_t * data,
uint32_t data_len,
WiiuPartitionRegion ** regions,
uint32_t * count )

Deserialize a partition key map from a media tag buffer.

Parameters
dataSerialized data buffer.
data_lenLength of the data buffer.
regionsOutput: malloc'd array of WiiuPartitionRegion (caller must free).
countOutput: number of regions.
Returns
0 on success, negative error code on failure.

< Maximum number of partitions supported.

Definition at line 112 of file wiiu_crypto.c.

References WiiuPartitionRegion::end_sector, read_le32(), WiiuPartitionRegion::start_sector, wiiu_deserialize_partition_key_map(), and WIIU_MAX_PARTITIONS.

Referenced by wiiu_deserialize_partition_key_map(), and wiiu_lazy_init().

◆ wiiu_encrypt_physical_sector()

void wiiu_encrypt_physical_sector ( const uint8_t key[16],
uint8_t * data,
uint32_t length )

Encrypt a full 0x8000-byte physical sector in-place.

Uses AES-128-CBC with IV=0 (Wii U scheme).

Parameters
key16-byte AES-128 key.
dataBuffer to encrypt in-place (must be 0x8000 bytes).
lengthNumber of bytes (must be 0x8000).

Definition at line 72 of file wiiu_crypto.c.

References aes128_cbc_encrypt(), and wiiu_encrypt_physical_sector().

Referenced by aaruf_read_sector(), and wiiu_encrypt_physical_sector().

◆ wiiu_get_sector_key()

const uint8_t * wiiu_get_sector_key ( const WiiuPartitionRegion * 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 the sector is encrypted, NULL if plaintext.

< Number of 2048-byte logical sectors per physical sector.

< Disc header occupies physical sectors 0-2 (plaintext).

Definition at line 43 of file wiiu_crypto.c.

References WiiuPartitionRegion::key, wiiu_get_sector_key(), WIIU_HEADER_PHYSICAL_SECTORS, and WIIU_LOGICAL_PER_PHYSICAL.

Referenced by aaruf_read_sector(), wiiu_get_sector_key(), and wiiu_is_sector_encrypted().

◆ wiiu_is_sector_encrypted()

bool wiiu_is_sector_encrypted ( const WiiuPartitionRegion * regions,
uint32_t region_count,
uint64_t logical_sector )

Check if a logical sector (2048-byte) is in an encrypted region.

Parameters
regionsArray of partition regions.
region_countNumber of partition regions.
logical_sectorLogical sector address (2048-byte units).
Returns
true if the sector is encrypted, false if plaintext.

Definition at line 69 of file wiiu_crypto.c.

References wiiu_get_sector_key(), and wiiu_is_sector_encrypted().

Referenced by wiiu_is_sector_encrypted().

◆ wiiu_lazy_init()

void wiiu_lazy_init ( aaruformat_context * ctx)

Lazy initialization: load disc key and partition key map from media tags.

Populates ctx->wiiu_disc_key and ctx->wiiu_partition_regions from media tags. Allocates ctx->wiiu_encrypted_block_cache if needed.

Parameters
ctxAaruFormat context.

< Wii U physical sector size (32 KiB).

Definition at line 155 of file wiiu_crypto.c.

References mediaTagEntry::data, kMediaTagWiiUDiscKey, kMediaTagWiiUPartitionKeyMap, mediaTagEntry::length, aaruformat_context::mediaTags, aaruformat_context::wiiu_cache_valid, WIIU_CRYPTO_SECTOR_SIZE, wiiu_deserialize_partition_key_map(), aaruformat_context::wiiu_disc_key, aaruformat_context::wiiu_encrypted_block_cache, wiiu_lazy_init(), aaruformat_context::wiiu_partition_region_count, and aaruformat_context::wiiu_partition_regions.

Referenced by aaruf_read_sector(), and wiiu_lazy_init().

◆ wiiu_serialize_partition_key_map()

int32_t wiiu_serialize_partition_key_map ( const WiiuPartitionRegion * regions,
uint32_t count,
uint8_t ** out_data,
uint32_t * out_len )

Serialize a partition key map for storage as a media tag.

Format (all little-endian): [4 bytes] partition_count For each partition (24 bytes): [4 bytes] start_sector [4 bytes] end_sector [16 bytes] key

Parameters
regionsArray of partition regions.
countNumber of regions.
out_dataOutput: malloc'd buffer (caller must free).
out_lenOutput: length of the buffer.
Returns
0 on success, negative error code on failure.

< Maximum number of partitions supported.

Definition at line 86 of file wiiu_crypto.c.

References WIIU_MAX_PARTITIONS, wiiu_serialize_partition_key_map(), and write_le32().

Referenced by wiiu_serialize_partition_key_map().

◆ write_le32()

void write_le32 ( uint8_t * p,
uint32_t v )
static

Definition at line 35 of file wiiu_crypto.c.

References write_le32().