mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
99 lines
4.3 KiB
C
99 lines
4.3 KiB
C
/*
|
|
* This file is part of the Aaru Data Preservation Suite.
|
|
* Copyright (c) 2019-2025 Natalia Portillo.
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2.1 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef LIBAARUFORMAT_CHECKSUM_H
|
|
#define LIBAARUFORMAT_CHECKSUM_H
|
|
|
|
#include <stdint.h> // Fixed-width integer types for on-disk structures.
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
/**
|
|
* \file aaruformat/structs/checksum.h
|
|
* \brief On-disk layout definitions for the checksum block (BlockType::ChecksumBlock).
|
|
*
|
|
* A checksum block stores one or more whole-image (user data) checksums. For optical media the
|
|
* user data definition follows the format's raw sector rules (e.g. 2352-byte raw sector when available).
|
|
*
|
|
* Binary layout (all integers are little-endian, structure is packed):
|
|
*
|
|
* +------------------------------+-------------------------------+
|
|
* | Field | Size (bytes) |
|
|
* +==============================+===============================+
|
|
* | ChecksumHeader | sizeof(ChecksumHeader)=9 |
|
|
* | identifier | 4 (BlockType::ChecksumBlock) |
|
|
* | length | 4 (payload bytes that follow)|
|
|
* | entries | 1 (number of checksum entries)|
|
|
* +------------------------------+-------------------------------+
|
|
* | Repeated for each entry: |
|
|
* | ChecksumEntry | sizeof(ChecksumEntry)=5 |
|
|
* | type | 1 (ChecksumAlgorithm) |
|
|
* | length | 4 (digest length) |
|
|
* | digest bytes | length |
|
|
* +------------------------------+-------------------------------+
|
|
*
|
|
* Thus, the payload size (ChecksumHeader.length) MUST equal the sum over all entries of:
|
|
* sizeof(ChecksumEntry) + entry.length.
|
|
*
|
|
* Typical digest lengths:
|
|
* - Md5: 16 bytes
|
|
* - Sha1: 20 bytes
|
|
* - Sha256: 32 bytes
|
|
* - SpamSum: variable length ASCII, NOT null-terminated on disk (a terminating '\0' may be appended in memory).
|
|
*
|
|
* \warning The structures are packed; never rely on host compiler default padding or directly casting from a buffer
|
|
* without ensuring correct endianness if porting to big-endian systems (current implementation assumes LE).
|
|
*
|
|
* \see BlockType
|
|
* \see ChecksumAlgorithm
|
|
*/
|
|
|
|
/**
|
|
* \struct ChecksumHeader
|
|
* \brief Header that precedes the sequence of checksum entries for a checksum block.
|
|
*
|
|
* After this header, exactly \ref ChecksumHeader::length bytes follow containing \ref ChecksumHeader::entries
|
|
* consecutive \ref ChecksumEntry records, each immediately followed by its digest payload.
|
|
*/
|
|
typedef struct ChecksumHeader
|
|
{
|
|
uint32_t identifier; ///< Block identifier, must be BlockType::ChecksumBlock.
|
|
uint32_t length; ///< Length in bytes of the payload (all entries + their digest data, excluding this header).
|
|
uint8_t entries; ///< Number of checksum entries that follow in the payload.
|
|
} ChecksumHeader;
|
|
|
|
/**
|
|
* \struct ChecksumEntry
|
|
* \brief Per-checksum metadata immediately followed by the digest / signature bytes.
|
|
*
|
|
* For fixed-length algorithms the \ref length MUST match the known digest size. For SpamSum it is variable.
|
|
* The bytes immediately following this structure (not null-terminated) constitute the digest and are exactly
|
|
* \ref length bytes long.
|
|
*
|
|
* Order of entries is not mandated; readers should scan all entries and match by \ref type.
|
|
*/
|
|
typedef struct ChecksumEntry
|
|
{
|
|
uint8_t type; ///< Algorithm used (value from \ref ChecksumAlgorithm).
|
|
uint32_t length; ///< Length in bytes of the digest that immediately follows this structure.
|
|
} ChecksumEntry;
|
|
|
|
#pragma pack(pop)
|
|
|
|
#endif // LIBAARUFORMAT_CHECKSUM_H
|