1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "volume_id_internal.h"
22
23#define LUKS_MAGIC_L 6
24#define UUID_STRING_L 40
25#define LUKS_CIPHERNAME_L 32
26#define LUKS_CIPHERMODE_L 32
27#define LUKS_HASHSPEC_L 32
28#define LUKS_DIGESTSIZE 20
29#define LUKS_SALTSIZE 32
30#define LUKS_NUMKEYS 8
31
32static const uint8_t LUKS_MAGIC[] = { 'L','U','K','S', 0xba, 0xbe };
33
34struct luks_phdr {
35 uint8_t magic[LUKS_MAGIC_L];
36 uint16_t version;
37 uint8_t cipherName[LUKS_CIPHERNAME_L];
38 uint8_t cipherMode[LUKS_CIPHERMODE_L];
39 uint8_t hashSpec[LUKS_HASHSPEC_L];
40 uint32_t payloadOffset;
41 uint32_t keyBytes;
42 uint8_t mkDigest[LUKS_DIGESTSIZE];
43 uint8_t mkDigestSalt[LUKS_SALTSIZE];
44 uint32_t mkDigestIterations;
45 uint8_t uuid[UUID_STRING_L];
46 struct {
47 uint32_t active;
48 uint32_t passwordIterations;
49 uint8_t passwordSalt[LUKS_SALTSIZE];
50 uint32_t keyMaterialOffset;
51 uint32_t stripes;
52 } keyblock[LUKS_NUMKEYS];
53};
54
55enum {
56 EXPECTED_SIZE_luks_phdr = 0
57 + 1 * LUKS_MAGIC_L
58 + 2
59 + 1 * LUKS_CIPHERNAME_L
60 + 1 * LUKS_CIPHERMODE_L
61 + 1 * LUKS_HASHSPEC_L
62 + 4
63 + 4
64 + 1 * LUKS_DIGESTSIZE
65 + 1 * LUKS_SALTSIZE
66 + 4
67 + 1 * UUID_STRING_L
68 + LUKS_NUMKEYS * (0
69 + 4
70 + 4
71 + 1 * LUKS_SALTSIZE
72 + 4
73 + 4
74 )
75};
76
77struct BUG_bad_size_luks_phdr {
78 char BUG_bad_size_luks_phdr[
79 sizeof(struct luks_phdr) == EXPECTED_SIZE_luks_phdr ?
80 1 : -1];
81};
82
83int FAST_FUNC volume_id_probe_luks(struct volume_id *id )
84{
85#define off ((uint64_t)0)
86 struct luks_phdr *header;
87
88 header = volume_id_get_buffer(id, off, sizeof(*header));
89 if (header == NULL)
90 return -1;
91
92 if (memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L))
93 return -1;
94
95
96 volume_id_set_uuid(id, header->uuid, UUID_DCE_STRING);
97
98
99 return 0;
100}
101