2 * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/types.h>
32 #if defined(__DragonFly__)
33 #include <sys/endian.h>
34 #elif defined(__linux__)
46 /* Endianess macros */
47 #define BE_TO_HOST(n, v) v = be ## n ## toh(v)
48 #define LE_TO_HOST(n, v) v = le ## n ## toh(v)
49 #define HOST_TO_BE(n, v) v = htobe ## n (v)
50 #define HOST_TO_LE(n, v) v = htole ## n (v)
53 decrypt_hdr(struct tchdr_enc
*ehdr
, struct tc_cipher_chain
*cipher_chain
,
56 struct tchdr_dec
*dhdr
;
57 unsigned char iv
[128];
60 if ((dhdr
= alloc_safe_mem(sizeof(struct tchdr_dec
))) == NULL
) {
61 tc_log(1, "Error allocating safe tchdr_dec memory\n");
65 memset(iv
, 0, sizeof(iv
));
67 error
= tc_decrypt(cipher_chain
, key
, iv
, ehdr
->enc
,
68 sizeof(struct tchdr_dec
), (unsigned char *)dhdr
);
70 tc_log(1, "Header decryption failed\n");
75 BE_TO_HOST(16, dhdr
->tc_ver
);
76 LE_TO_HOST(16, dhdr
->tc_min_ver
);
77 BE_TO_HOST(32, dhdr
->crc_keys
);
78 BE_TO_HOST(64, dhdr
->vol_ctime
);
79 BE_TO_HOST(64, dhdr
->hdr_ctime
);
80 BE_TO_HOST(64, dhdr
->sz_hidvol
);
81 BE_TO_HOST(64, dhdr
->sz_vol
);
82 BE_TO_HOST(64, dhdr
->off_mk_scope
);
83 BE_TO_HOST(64, dhdr
->sz_mk_scope
);
84 BE_TO_HOST(32, dhdr
->flags
);
85 BE_TO_HOST(32, dhdr
->sec_sz
);
86 BE_TO_HOST(32, dhdr
->crc_dhdr
);
92 verify_hdr(struct tchdr_dec
*hdr
)
96 if (memcmp(hdr
->tc_str
, TC_SIG
, sizeof(hdr
->tc_str
)) != 0) {
98 fprintf(stderr
, "Signature mismatch\n");
103 crc
= crc32(&hdr
->keys
, 256);
104 if (crc
!= hdr
->crc_keys
) {
106 fprintf(stderr
, "CRC32 mismatch (crc_keys)\n");
111 switch(hdr
->tc_ver
) {
114 /* Unsupported header version */
115 tc_log(1, "Header version %d unsupported\n", hdr
->tc_ver
);
128 create_hdr(unsigned char *pass
, int passlen
, struct pbkdf_prf_algo
*prf_algo
,
129 struct tc_cipher_chain
*cipher_chain
, size_t sec_sz
,
130 size_t total_blocks __unused
,
131 off_t offset
, size_t blocks
, int hidden
, struct tchdr_enc
**backup_hdr
)
133 struct tchdr_enc
*ehdr
, *ehdr_backup
;
134 struct tchdr_dec
*dhdr
;
135 unsigned char *key
, *key_backup
;
136 unsigned char iv
[128];
139 key
= key_backup
= NULL
;
141 ehdr
= ehdr_backup
= NULL
;
143 if (backup_hdr
!= NULL
)
146 if ((dhdr
= (struct tchdr_dec
*)alloc_safe_mem(sizeof(*dhdr
))) == NULL
) {
147 tc_log(1, "could not allocate safe dhdr memory\n");
151 if ((ehdr
= (struct tchdr_enc
*)alloc_safe_mem(sizeof(*ehdr
))) == NULL
) {
152 tc_log(1, "could not allocate safe ehdr memory\n");
156 if ((ehdr_backup
= (struct tchdr_enc
*)alloc_safe_mem
157 (sizeof(*ehdr_backup
))) == NULL
) {
158 tc_log(1, "could not allocate safe ehdr_backup memory\n");
162 if ((key
= alloc_safe_mem(MAX_KEYSZ
)) == NULL
) {
163 tc_log(1, "could not allocate safe key memory\n");
167 if ((key_backup
= alloc_safe_mem(MAX_KEYSZ
)) == NULL
) {
168 tc_log(1, "could not allocate safe backup key memory\n");
172 if ((error
= get_random(ehdr
->salt
, sizeof(ehdr
->salt
))) != 0) {
173 tc_log(1, "could not get salt\n");
177 if ((error
= get_random(ehdr_backup
->salt
, sizeof(ehdr_backup
->salt
)))
179 tc_log(1, "could not get salt for backup header\n");
183 error
= pbkdf2(prf_algo
, (char *)pass
, passlen
,
184 ehdr
->salt
, sizeof(ehdr
->salt
),
187 tc_log(1, "could not derive key\n");
191 error
= pbkdf2(prf_algo
, (char *)pass
, passlen
,
192 ehdr_backup
->salt
, sizeof(ehdr_backup
->salt
),
193 MAX_KEYSZ
, key_backup
);
195 tc_log(1, "could not derive backup key\n");
199 memset(dhdr
, 0, sizeof(*dhdr
));
201 if ((error
= get_random(dhdr
->keys
, sizeof(dhdr
->keys
))) != 0) {
202 tc_log(1, "could not get key random bits\n");
206 memcpy(dhdr
->tc_str
, "TRUE", 4);
208 dhdr
->tc_min_ver
= 7;
209 dhdr
->crc_keys
= crc32((void *)&dhdr
->keys
, 256);
210 dhdr
->sz_vol
= blocks
* sec_sz
;
212 dhdr
->sz_hidvol
= dhdr
->sz_vol
;
213 dhdr
->off_mk_scope
= offset
* sec_sz
;
214 dhdr
->sz_mk_scope
= blocks
* sec_sz
;
215 dhdr
->sec_sz
= sec_sz
;
218 HOST_TO_BE(16, dhdr
->tc_ver
);
219 HOST_TO_LE(16, dhdr
->tc_min_ver
);
220 HOST_TO_BE(32, dhdr
->crc_keys
);
221 HOST_TO_BE(64, dhdr
->sz_vol
);
222 HOST_TO_BE(64, dhdr
->sz_hidvol
);
223 HOST_TO_BE(64, dhdr
->off_mk_scope
);
224 HOST_TO_BE(64, dhdr
->sz_mk_scope
);
225 HOST_TO_BE(32, dhdr
->sec_sz
);
226 HOST_TO_BE(32, dhdr
->flags
);
228 dhdr
->crc_dhdr
= crc32((void *)dhdr
, 188);
229 HOST_TO_BE(32, dhdr
->crc_dhdr
);
231 memset(iv
, 0, sizeof(iv
));
232 error
= tc_encrypt(cipher_chain
, key
, iv
, (unsigned char *)dhdr
,
233 sizeof(struct tchdr_dec
), ehdr
->enc
);
235 tc_log(1, "Header encryption failed\n");
239 memset(iv
, 0, sizeof(iv
));
240 error
= tc_encrypt(cipher_chain
, key_backup
, iv
,
241 (unsigned char *)dhdr
,
242 sizeof(struct tchdr_dec
), ehdr_backup
->enc
);
244 tc_log(1, "Backup header encryption failed\n");
249 free_safe_mem(key_backup
);
252 if (backup_hdr
!= NULL
)
253 *backup_hdr
= ehdr_backup
;
255 free_safe_mem(ehdr_backup
);
264 free_safe_mem(key_backup
);
270 free_safe_mem(ehdr_backup
);