libaaruformat
1.0
Aaru Data Preservation Suite - Format Library
Toggle main menu visibility
Loading...
Searching...
No Matches
checksum.c
Go to the documentation of this file.
1
/*
2
* This file is part of the Aaru Data Preservation Suite.
3
* Copyright (c) 2019-2026 Natalia Portillo.
4
*
5
* This library is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU Lesser General Public License as
7
* published by the Free Software Foundation; either version 2.1 of the
8
* License, or (at your option) any later version.
9
*
10
* This library is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <inttypes.h>
20
#include <stdint.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#include "
aaruformat/context.h
"
26
#include "
aaruformat/enums.h
"
27
#include "
aaruformat/structs/checksum.h
"
28
#include "
aaruformat/structs/index.h
"
29
#include "
internal.h
"
30
#include "
log.h
"
31
40
void
process_checksum_block
(
aaruformat_context
*ctx,
const
IndexEntry
*entry)
41
{
42
TRACE
(
"Entering process_checksum_block(%p, %p)"
, ctx, entry);
43
44
int
seek_result = 0;
45
size_t
read_bytes = 0;
46
ChecksumHeader
checksum_header;
47
ChecksumEntry
const
*checksum_entry = NULL;
48
uint8_t *data = NULL;
49
int
j = 0;
50
size_t
payload_pos = 0;
51
52
// Check if the context and image stream are valid
53
if
(ctx == NULL || ctx->
imageStream
== NULL)
54
{
55
FATAL
(
"Invalid context or image stream."
);
56
return
;
57
}
58
59
// Seek to block
60
seek_result =
aaruf_fseek
(ctx->
imageStream
, (
aaru_off_t
)entry->
offset
, SEEK_SET);
61
if
(seek_result < 0 ||
aaruf_ftell
(ctx->
imageStream
) != (
aaru_off_t
)entry->
offset
)
62
{
63
FATAL
(
"Could not seek to %"
PRIu64
" as indicated by index entry..."
, entry->
offset
);
64
65
return
;
66
}
67
68
// Even if those two checks shall have been done before
69
TRACE
(
"Reading checksum block header at position %"
PRIu64, entry->
offset
);
70
read_bytes = fread(&checksum_header, 1,
sizeof
(
ChecksumHeader
), ctx->
imageStream
);
71
72
if
(read_bytes !=
sizeof
(
ChecksumHeader
))
73
{
74
memset(&checksum_header, 0,
sizeof
(
ChecksumHeader
));
75
FATAL
(
"Could not read checksums block header, continuing...\n"
);
76
return
;
77
}
78
79
if
(checksum_header.
identifier
!=
ChecksumBlock
)
80
{
81
memset(&checksum_header, 0,
sizeof
(
ChecksumHeader
));
82
FATAL
(
"Incorrect identifier for checksum block at position %"
PRIu64
"\n"
, entry->
offset
);
83
return
;
84
}
85
86
TRACE
(
"Allocating %u bytes for checksum block"
, checksum_header.
length
);
87
data = (uint8_t *)malloc(checksum_header.
length
);
88
89
if
(data == NULL)
90
{
91
memset(&checksum_header, 0,
sizeof
(
ChecksumHeader
));
92
FATAL
(
"Could not allocate memory for checksum block, continuing...\n"
);
93
return
;
94
}
95
96
TRACE
(
"Reading checksum block data at position %"
PRIu64, entry->
offset
+
sizeof
(
ChecksumHeader
));
97
read_bytes = fread(data, 1, checksum_header.
length
, ctx->
imageStream
);
98
99
if
(read_bytes != checksum_header.
length
)
100
{
101
memset(&checksum_header, 0,
sizeof
(
ChecksumHeader
));
102
free(data);
103
FATAL
(
"Could not read checksums block, continuing...\n"
);
104
return
;
105
}
106
107
payload_pos = 0;
108
TRACE
(
"Processing %u checksum entries"
, checksum_header.
entries
);
109
for
(j = 0; j < checksum_header.
entries
; j++)
110
{
111
if
(payload_pos +
sizeof
(
ChecksumEntry
) > checksum_header.
length
)
112
{
113
FATAL
(
"Checksum entry %d exceeds block payload size"
, j);
114
break
;
115
}
116
117
checksum_entry = (
const
ChecksumEntry
*)&data[payload_pos];
118
payload_pos +=
sizeof
(
ChecksumEntry
);
119
120
if
(payload_pos + checksum_entry->
length
> checksum_header.
length
)
121
{
122
FATAL
(
"Checksum payload for entry %d exceeds block payload size"
, j);
123
break
;
124
}
125
126
switch
(checksum_entry->
type
)
127
{
128
case
Md5
:
129
if
(checksum_entry->
length
!=
MD5_DIGEST_LENGTH
)
130
{
131
FATAL
(
"MD5 checksum entry has invalid length %u"
, checksum_entry->
length
);
132
break
;
133
}
134
135
TRACE
(
"Found MD5 checksum"
);
136
memcpy(ctx->
checksums
.
md5
, &data[payload_pos],
MD5_DIGEST_LENGTH
);
137
ctx->
checksums
.
hasMd5
=
true
;
138
break
;
139
case
Sha1
:
140
if
(checksum_entry->
length
!=
SHA1_DIGEST_LENGTH
)
141
{
142
FATAL
(
"SHA1 checksum entry has invalid length %u"
, checksum_entry->
length
);
143
break
;
144
}
145
146
TRACE
(
"Found SHA1 checksum"
);
147
memcpy(ctx->
checksums
.
sha1
, &data[payload_pos],
SHA1_DIGEST_LENGTH
);
148
ctx->
checksums
.
hasSha1
=
true
;
149
break
;
150
case
Sha256
:
151
if
(checksum_entry->
length
!=
SHA256_DIGEST_LENGTH
)
152
{
153
FATAL
(
"SHA256 checksum entry has invalid length %u"
, checksum_entry->
length
);
154
break
;
155
}
156
157
TRACE
(
"Found SHA256 checksum"
);
158
memcpy(ctx->
checksums
.
sha256
, &data[payload_pos],
SHA256_DIGEST_LENGTH
);
159
ctx->
checksums
.
hasSha256
=
true
;
160
break
;
161
case
SpamSum
:
162
TRACE
(
"Found SpamSum checksum of size %u"
, checksum_entry->
length
);
163
free(ctx->
checksums
.
spamsum
);
164
ctx->
checksums
.
spamsum
= NULL;
165
166
ctx->
checksums
.
spamsum
= malloc(checksum_entry->
length
+ 1);
167
168
if
(ctx->
checksums
.
spamsum
== NULL)
169
{
170
FATAL
(
"Could not allocate memory for SpamSum digest"
);
171
break
;
172
}
173
174
memcpy(ctx->
checksums
.
spamsum
, &data[payload_pos], checksum_entry->
length
);
175
ctx->
checksums
.
spamsum
[checksum_entry->
length
] =
'\0'
;
176
ctx->
checksums
.
hasSpamSum
=
true
;
177
break
;
178
default
:
179
TRACE
(
"Unknown checksum type %u, skipping"
, checksum_entry->
type
);
180
break
;
181
}
182
183
payload_pos += checksum_entry->
length
;
184
}
185
186
checksum_entry = NULL;
187
free(data);
188
189
TRACE
(
"Exiting process_checksum_block()"
);
190
}
checksum.h
On-disk layout definitions for the checksum block (BlockType::ChecksumBlock).
context.h
Central runtime context structures for libaaruformat (image state, caches, checksum buffers).
MD5_DIGEST_LENGTH
#define MD5_DIGEST_LENGTH
Definition
context.h:75
enums.h
ChecksumBlock
@ ChecksumBlock
Block containing contents checksums.
Definition
enums.h:176
Sha1
@ Sha1
SHA-1 hash.
Definition
enums.h:198
Md5
@ Md5
MD5 hash.
Definition
enums.h:197
Sha256
@ Sha256
SHA-256 hash.
Definition
enums.h:199
SpamSum
@ SpamSum
SpamSum (context-triggered piecewise hash).
Definition
enums.h:200
index.h
On‑disk index block header and entry structures (versions 1, 2 and 3).
internal.h
process_checksum_block
void process_checksum_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a checksum block from the image stream.
Definition
checksum.c:40
aaruf_fseek
static int aaruf_fseek(FILE *stream, aaru_off_t offset, int origin)
Definition
internal.h:46
aaruf_ftell
static aaru_off_t aaruf_ftell(FILE *stream)
Definition
internal.h:52
aaru_off_t
int64_t aaru_off_t
Definition
internal.h:42
log.h
FATAL
#define FATAL(fmt,...)
Definition
log.h:40
TRACE
#define TRACE(fmt,...)
Definition
log.h:25
SHA1_DIGEST_LENGTH
#define SHA1_DIGEST_LENGTH
Definition
sha1.h:39
SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH
Definition
sha256.h:38
ChecksumEntry
Per-checksum metadata immediately followed by the digest / signature bytes.
Definition
checksum.h:91
ChecksumEntry::length
uint32_t length
Length in bytes of the digest that immediately follows this structure.
Definition
checksum.h:93
ChecksumEntry::type
uint8_t type
Algorithm used (value from ChecksumAlgorithm).
Definition
checksum.h:92
ChecksumHeader
Header that precedes the sequence of checksum entries for a checksum block.
Definition
checksum.h:74
ChecksumHeader::identifier
uint32_t identifier
Block identifier, must be BlockType::ChecksumBlock.
Definition
checksum.h:75
ChecksumHeader::length
uint32_t length
Length in bytes of the payload (all entries + their digest data, excluding this header).
Definition
checksum.h:76
ChecksumHeader::entries
uint8_t entries
Number of checksum entries that follow in the payload.
Definition
checksum.h:77
Checksums::spamsum
uint8_t * spamsum
SpamSum fuzzy hash (ASCII), allocated length+1 with trailing 0.
Definition
context.h:116
Checksums::hasSha256
bool hasSha256
True if sha256[] buffer populated.
Definition
context.h:109
Checksums::sha1
uint8_t sha1[20]
SHA-1 digest (20 bytes).
Definition
context.h:113
Checksums::sha256
uint8_t sha256[32]
SHA-256 digest (32 bytes).
Definition
context.h:114
Checksums::md5
uint8_t md5[16]
MD5 digest (16 bytes).
Definition
context.h:112
Checksums::hasSpamSum
bool hasSpamSum
True if spamsum pointer allocated and signature read.
Definition
context.h:111
Checksums::hasSha1
bool hasSha1
True if sha1[] buffer populated.
Definition
context.h:108
Checksums::hasMd5
bool hasMd5
True if md5[] buffer populated.
Definition
context.h:107
IndexEntry
Single index entry describing a block's type, (optional) data classification, and file offset.
Definition
index.h:109
IndexEntry::offset
uint64_t offset
Absolute byte offset in the image where the referenced block header begins.
Definition
index.h:112
aaruformat_context
Master context representing an open or in‑creation Aaru image.
Definition
context.h:178
aaruformat_context::checksums
Checksums checksums
Whole-image checksums discovered.
Definition
context.h:279
aaruformat_context::imageStream
FILE * imageStream
Underlying FILE* stream (binary mode).
Definition
context.h:182
src
blocks
checksum.c
Generated by
1.18.0