libaaruformat
1.0
Aaru Data Preservation Suite - Format Library
Toggle main menu visibility
Loading...
Searching...
No Matches
ps3_encryption_map.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; version 2.1 of the License.
8
*
9
* This library is distributed in the hope that it will be useful, but
10
* WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
13
*
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, see
16
* <https://www.gnu.org/licenses/>.
17
*
18
* PS3 encryption map: plaintext region parsing, serialization, and lookup.
19
*/
20
21
#include <stdint.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#include "
ps3_encryption_map.h
"
26
27
/* Read a big-endian uint32 from a byte buffer. */
28
static
uint32_t
read_be32
(
const
uint8_t *p)
29
{
30
return
((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
31
}
32
33
/* Read a little-endian uint32 from a byte buffer. */
34
static
uint32_t
read_le32
(
const
uint8_t *p)
35
{
36
return
(uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
37
}
38
39
/* Write a little-endian uint32 to a byte buffer. */
40
static
void
write_le32
(uint8_t *p, uint32_t v)
41
{
42
p[0] = (uint8_t)(v & 0xFF);
43
p[1] = (uint8_t)((v >> 8) & 0xFF);
44
p[2] = (uint8_t)((v >> 16) & 0xFF);
45
p[3] = (uint8_t)((v >> 24) & 0xFF);
46
}
47
48
int32_t
ps3_parse_encryption_map
(
const
uint8_t *sector0, uint32_t length,
Ps3PlaintextRegion
**regions,
49
uint32_t *count)
50
{
51
if
(sector0 == NULL || regions == NULL || count == NULL)
return
-1;
52
53
/* Minimum required: 4 (region_count) + 4 (unknown) = 8 bytes */
54
if
(length < 8)
return
-2;
55
56
uint32_t region_count =
read_be32
(sector0);
57
58
if
(region_count >
PS3_MAX_PLAINTEXT_REGIONS
)
return
-3;
59
60
if
(region_count == 0)
61
{
62
*regions = NULL;
63
*count = 0;
64
return
0;
65
}
66
67
/* Need 8 + region_count * 8 bytes */
68
uint32_t required = 8 + region_count * 8;
69
if
(length < required)
return
-2;
70
71
Ps3PlaintextRegion
*r = (
Ps3PlaintextRegion
*)malloc(region_count *
sizeof
(
Ps3PlaintextRegion
));
72
if
(r == NULL)
return
-4;
73
74
const
uint8_t *ptr = sector0 + 8;
/* skip region_count (4) + unknown (4) */
75
76
for
(uint32_t i = 0; i < region_count; i++)
77
{
78
r[i].
start_sector
=
read_be32
(ptr);
79
r[i].
end_sector
=
read_be32
(ptr + 4);
80
ptr += 8;
81
82
if
(r[i].start_sector > r[i].end_sector)
83
{
84
free(r);
85
return
-5;
86
}
87
}
88
89
*regions = r;
90
*count = region_count;
91
return
0;
92
}
93
94
int32_t
ps3_serialize_encryption_map
(
const
Ps3PlaintextRegion
*regions, uint32_t count, uint8_t **out_data,
95
uint32_t *out_length)
96
{
97
if
(out_data == NULL || out_length == NULL)
return
-1;
98
if
(count >
PS3_MAX_PLAINTEXT_REGIONS
)
return
-3;
99
100
uint32_t size = 4 + count * 8;
101
uint8_t *buf = (uint8_t *)malloc(size);
102
if
(buf == NULL)
return
-4;
103
104
write_le32
(buf, count);
105
106
for
(uint32_t i = 0; i < count; i++)
107
{
108
write_le32
(buf + 4 + i * 8, regions[i].start_sector);
109
write_le32
(buf + 4 + i * 8 + 4, regions[i].end_sector);
110
}
111
112
*out_data = buf;
113
*out_length = size;
114
return
0;
115
}
116
117
int32_t
ps3_deserialize_encryption_map
(
const
uint8_t *data, uint32_t length,
Ps3PlaintextRegion
**regions,
118
uint32_t *count)
119
{
120
if
(data == NULL || regions == NULL || count == NULL)
return
-1;
121
if
(length < 4)
return
-2;
122
123
uint32_t region_count =
read_le32
(data);
124
125
if
(region_count >
PS3_MAX_PLAINTEXT_REGIONS
)
return
-3;
126
127
if
(region_count == 0)
128
{
129
*regions = NULL;
130
*count = 0;
131
return
0;
132
}
133
134
uint32_t required = 4 + region_count * 8;
135
if
(length < required)
return
-2;
136
137
Ps3PlaintextRegion
*r = (
Ps3PlaintextRegion
*)malloc(region_count *
sizeof
(
Ps3PlaintextRegion
));
138
if
(r == NULL)
return
-4;
139
140
for
(uint32_t i = 0; i < region_count; i++)
141
{
142
r[i].
start_sector
=
read_le32
(data + 4 + i * 8);
143
r[i].
end_sector
=
read_le32
(data + 4 + i * 8 + 4);
144
}
145
146
*regions = r;
147
*count = region_count;
148
return
0;
149
}
150
151
bool
ps3_is_sector_encrypted
(
const
Ps3PlaintextRegion
*plaintext_regions, uint32_t region_count,
152
uint64_t sector_address)
153
{
154
if
(plaintext_regions == NULL || region_count == 0)
return
true
;
155
156
for
(uint32_t i = 0; i < region_count; i++)
157
if
(sector_address >= plaintext_regions[i].start_sector && sector_address <= plaintext_regions[i].end_sector)
158
return
false
;
159
160
return
true
;
161
}
read_le32
static uint32_t read_le32(const uint8_t *p)
Definition
ngcw_junk.c:32
write_le32
static void write_le32(uint8_t *p, uint32_t v)
Definition
ngcw_junk.c:43
ps3_is_sector_encrypted
bool ps3_is_sector_encrypted(const Ps3PlaintextRegion *plaintext_regions, uint32_t region_count, uint64_t sector_address)
Check whether a sector is encrypted (i.e., not in any plaintext region).
Definition
ps3_encryption_map.c:151
read_be32
static uint32_t read_be32(const uint8_t *p)
Definition
ps3_encryption_map.c:28
ps3_deserialize_encryption_map
int32_t ps3_deserialize_encryption_map(const uint8_t *data, uint32_t length, Ps3PlaintextRegion **regions, uint32_t *count)
Deserialize plaintext regions from little-endian binary (media tag format).
Definition
ps3_encryption_map.c:117
ps3_parse_encryption_map
int32_t ps3_parse_encryption_map(const uint8_t *sector0, uint32_t length, Ps3PlaintextRegion **regions, uint32_t *count)
Parse the encryption map from PS3 disc sector 0 (big-endian on disc).
Definition
ps3_encryption_map.c:48
ps3_serialize_encryption_map
int32_t ps3_serialize_encryption_map(const Ps3PlaintextRegion *regions, uint32_t count, uint8_t **out_data, uint32_t *out_length)
Serialize plaintext regions to little-endian binary for storage as a media tag.
Definition
ps3_encryption_map.c:94
ps3_encryption_map.h
PS3_MAX_PLAINTEXT_REGIONS
#define PS3_MAX_PLAINTEXT_REGIONS
Definition
ps3_encryption_map.h:39
Ps3PlaintextRegion
A plaintext (unencrypted) region on a PS3 disc.
Definition
ps3_encryption_map.h:34
Ps3PlaintextRegion::start_sector
uint32_t start_sector
First sector of plaintext region (inclusive).
Definition
ps3_encryption_map.h:35
Ps3PlaintextRegion::end_sector
uint32_t end_sector
Last sector of plaintext region (inclusive).
Definition
ps3_encryption_map.h:36
src
ps3
ps3_encryption_map.c
Generated by
1.18.0