bridge(4): document net.link.bridge.pfil_onlyip
[dragonfly.git] / lib / libtcplay / hdr.c
blobb3d2f782bdac5005087e0e9ffeda6d84decabb6b
1 /*
2 * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
14 * distribution.
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
27 * SUCH DAMAGE.
30 #include <sys/types.h>
32 #if defined(__DragonFly__)
33 #include <sys/endian.h>
34 #elif defined(__linux__)
35 #include <endian.h>
36 #endif
37 #include <errno.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <inttypes.h>
41 #include <string.h>
43 #include "crc32.h"
44 #include "tcplay.h"
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)
52 struct sig_hdr_cfg {
53 const char *sig;
54 uint16_t min_ver;
57 struct sig_hdr_cfg sig_hdr_cfgs[] = {
58 { TC_SIG, 0x0007 },
59 { VC_SIG, 0x0b01 },
60 { NULL, 0x0000 }
63 static
64 const
65 struct sig_hdr_cfg *hdr_cfg_from_sig(const char *sig)
67 const struct sig_hdr_cfg *cfg;
69 for (cfg = &sig_hdr_cfgs[0]; cfg->sig != NULL; cfg++) {
70 if (strcmp(cfg->sig, sig) == 0)
71 return cfg;
74 return NULL;
77 struct tchdr_dec *
78 decrypt_hdr(struct tchdr_enc *ehdr, struct tc_cipher_chain *cipher_chain,
79 unsigned char *key)
81 struct tchdr_dec *dhdr;
82 unsigned char iv[128];
83 int error;
85 if ((dhdr = alloc_safe_mem(sizeof(struct tchdr_dec))) == NULL) {
86 tc_log(1, "Error allocating safe tchdr_dec memory\n");
87 return NULL;
90 memset(iv, 0, sizeof(iv));
92 error = tc_decrypt(cipher_chain, key, iv, ehdr->enc,
93 sizeof(struct tchdr_dec), (unsigned char *)dhdr);
94 if (error) {
95 tc_log(1, "Header decryption failed\n");
96 free_safe_mem(dhdr);
97 return NULL;
100 BE_TO_HOST(16, dhdr->tc_ver);
101 LE_TO_HOST(16, dhdr->tc_min_ver);
102 BE_TO_HOST(32, dhdr->crc_keys);
103 BE_TO_HOST(64, dhdr->vol_ctime);
104 BE_TO_HOST(64, dhdr->hdr_ctime);
105 BE_TO_HOST(64, dhdr->sz_hidvol);
106 BE_TO_HOST(64, dhdr->sz_vol);
107 BE_TO_HOST(64, dhdr->off_mk_scope);
108 BE_TO_HOST(64, dhdr->sz_mk_scope);
109 BE_TO_HOST(32, dhdr->flags);
110 BE_TO_HOST(32, dhdr->sec_sz);
111 BE_TO_HOST(32, dhdr->crc_dhdr);
113 return dhdr;
117 verify_hdr(struct tchdr_dec *hdr, struct pbkdf_prf_algo *prf_algo)
119 uint32_t crc;
121 if (memcmp(hdr->tc_str, prf_algo->sig, sizeof(hdr->tc_str)) != 0) {
122 #ifdef DEBUG
123 fprintf(stderr, "Signature mismatch\n");
124 #endif
125 return 0;
128 crc = crc32((void *)&hdr->keys, 256);
129 if (crc != hdr->crc_keys) {
130 #ifdef DEBUG
131 fprintf(stderr, "CRC32 mismatch (crc_keys)\n");
132 #endif
133 return 0;
136 switch(hdr->tc_ver) {
137 case 1:
138 case 2:
139 /* Unsupported header version */
140 tc_log(1, "Header version %d unsupported\n", hdr->tc_ver);
141 return 0;
143 case 3:
144 case 4:
145 hdr->sec_sz = 512;
146 break;
149 return 1;
152 struct tchdr_enc *
153 create_hdr(unsigned char *pass, int passlen, struct pbkdf_prf_algo *prf_algo,
154 struct tc_cipher_chain *cipher_chain, size_t sec_sz,
155 disksz_t total_blocks __unused,
156 off_t offset, disksz_t blocks, int hidden, int weak, struct tchdr_enc **backup_hdr)
158 struct tchdr_enc *ehdr, *ehdr_backup;
159 struct tchdr_dec *dhdr;
160 unsigned char *key, *key_backup;
161 unsigned char iv[128];
162 const struct sig_hdr_cfg *hdr_cfg;
163 int error;
165 key = key_backup = NULL;
166 dhdr = NULL;
167 ehdr = ehdr_backup = NULL;
169 if (backup_hdr != NULL)
170 *backup_hdr = NULL;
172 if ((dhdr = (struct tchdr_dec *)alloc_safe_mem(sizeof(*dhdr))) == NULL) {
173 tc_log(1, "could not allocate safe dhdr memory\n");
174 goto error;
177 if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) {
178 tc_log(1, "could not allocate safe ehdr memory\n");
179 goto error;
182 if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem
183 (sizeof(*ehdr_backup))) == NULL) {
184 tc_log(1, "could not allocate safe ehdr_backup memory\n");
185 goto error;
188 if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
189 tc_log(1, "could not allocate safe key memory\n");
190 goto error;
193 if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
194 tc_log(1, "could not allocate safe backup key memory\n");
195 goto error;
198 if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
199 tc_log(1, "could not get salt\n");
200 goto error;
203 if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak))
204 != 0) {
205 tc_log(1, "could not get salt for backup header\n");
206 goto error;
209 error = pbkdf2(prf_algo, (char *)pass, passlen,
210 ehdr->salt, sizeof(ehdr->salt),
211 MAX_KEYSZ, key);
212 if (error) {
213 tc_log(1, "could not derive key\n");
214 goto error;
217 error = pbkdf2(prf_algo, (char *)pass, passlen,
218 ehdr_backup->salt, sizeof(ehdr_backup->salt),
219 MAX_KEYSZ, key_backup);
220 if (error) {
221 tc_log(1, "could not derive backup key\n");
222 goto error;
225 memset(dhdr, 0, sizeof(*dhdr));
227 if ((error = get_random(dhdr->keys, sizeof(dhdr->keys), weak)) != 0) {
228 tc_log(1, "could not get key random bits\n");
229 goto error;
232 if ((hdr_cfg = hdr_cfg_from_sig(prf_algo->sig)) == NULL) {
233 tc_log(1, "could not find internal header configuration\n");
234 goto error;
237 memcpy(dhdr->tc_str, prf_algo->sig, 4);
238 dhdr->tc_ver = 5;
239 dhdr->tc_min_ver = hdr_cfg->min_ver;
240 dhdr->crc_keys = crc32((void *)&dhdr->keys, 256);
241 dhdr->sz_vol = blocks * sec_sz;
242 if (hidden)
243 dhdr->sz_hidvol = dhdr->sz_vol;
244 dhdr->off_mk_scope = offset * sec_sz;
245 dhdr->sz_mk_scope = blocks * sec_sz;
246 dhdr->sec_sz = sec_sz;
247 dhdr->flags = 0;
249 HOST_TO_BE(16, dhdr->tc_ver);
250 HOST_TO_LE(16, dhdr->tc_min_ver);
251 HOST_TO_BE(32, dhdr->crc_keys);
252 HOST_TO_BE(64, dhdr->sz_vol);
253 HOST_TO_BE(64, dhdr->sz_hidvol);
254 HOST_TO_BE(64, dhdr->off_mk_scope);
255 HOST_TO_BE(64, dhdr->sz_mk_scope);
256 HOST_TO_BE(32, dhdr->sec_sz);
257 HOST_TO_BE(32, dhdr->flags);
259 dhdr->crc_dhdr = crc32((void *)dhdr, 188);
260 HOST_TO_BE(32, dhdr->crc_dhdr);
262 memset(iv, 0, sizeof(iv));
263 error = tc_encrypt(cipher_chain, key, iv, (unsigned char *)dhdr,
264 sizeof(struct tchdr_dec), ehdr->enc);
265 if (error) {
266 tc_log(1, "Header encryption failed\n");
267 goto error;
270 memset(iv, 0, sizeof(iv));
271 error = tc_encrypt(cipher_chain, key_backup, iv,
272 (unsigned char *)dhdr,
273 sizeof(struct tchdr_dec), ehdr_backup->enc);
274 if (error) {
275 tc_log(1, "Backup header encryption failed\n");
276 goto error;
279 free_safe_mem(key);
280 free_safe_mem(key_backup);
281 free_safe_mem(dhdr);
283 if (backup_hdr != NULL)
284 *backup_hdr = ehdr_backup;
285 else
286 free_safe_mem(ehdr_backup);
288 return ehdr;
289 /* NOT REACHED */
291 error:
292 if (key)
293 free_safe_mem(key);
294 if (key_backup)
295 free_safe_mem(key_backup);
296 if (dhdr)
297 free_safe_mem(dhdr);
298 if (ehdr)
299 free_safe_mem(ehdr);
300 if (ehdr_backup)
301 free_safe_mem(ehdr_backup);
303 return NULL;
306 struct tchdr_enc *copy_reencrypt_hdr(unsigned char *pass, int passlen,
307 struct pbkdf_prf_algo *prf_algo, int weak, struct tcplay_info *info,
308 struct tchdr_enc **backup_hdr)
310 struct tchdr_enc *ehdr, *ehdr_backup;
311 unsigned char *key, *key_backup;
312 unsigned char iv[128];
313 const struct sig_hdr_cfg *hdr_cfg;
314 int error;
316 key = key_backup = NULL;
317 ehdr = ehdr_backup = NULL;
319 /* By default stick to current PRF algo */
320 if (prf_algo == NULL)
321 prf_algo = info->pbkdf_prf;
323 if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) {
324 tc_log(1, "could not allocate safe ehdr memory\n");
325 goto error;
328 if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem
329 (sizeof(*ehdr_backup))) == NULL) {
330 tc_log(1, "could not allocate safe ehdr_backup memory\n");
331 goto error;
334 if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
335 tc_log(1, "could not allocate safe key memory\n");
336 goto error;
339 if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
340 tc_log(1, "could not allocate safe backup key memory\n");
341 goto error;
344 if ((error = get_random(ehdr->salt, sizeof(ehdr->salt), weak)) != 0) {
345 tc_log(1, "could not get salt\n");
346 goto error;
349 if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt), weak))
350 != 0) {
351 tc_log(1, "could not get salt for backup header\n");
352 goto error;
355 error = pbkdf2(prf_algo, (char *)pass, passlen,
356 ehdr->salt, sizeof(ehdr->salt),
357 MAX_KEYSZ, key);
358 if (error) {
359 tc_log(1, "could not derive key\n");
360 goto error;
363 error = pbkdf2(prf_algo, (char *)pass, passlen,
364 ehdr_backup->salt, sizeof(ehdr_backup->salt),
365 MAX_KEYSZ, key_backup);
366 if (error) {
367 tc_log(1, "could not derive backup key\n");
368 goto error;
371 if ((hdr_cfg = hdr_cfg_from_sig(prf_algo->sig)) == NULL) {
372 tc_log(1, "could not find internal header configuration\n");
373 goto error;
376 /* Update signature and min_ver depending on selected PBKDF2 PRF algo */
377 memcpy(info->hdr->tc_str, prf_algo->sig, 4);
378 info->hdr->tc_min_ver = hdr_cfg->min_ver;
380 HOST_TO_BE(16, info->hdr->tc_ver);
381 HOST_TO_LE(16, info->hdr->tc_min_ver);
382 HOST_TO_BE(32, info->hdr->crc_keys);
383 HOST_TO_BE(64, info->hdr->vol_ctime);
384 HOST_TO_BE(64, info->hdr->hdr_ctime);
385 HOST_TO_BE(64, info->hdr->sz_vol);
386 HOST_TO_BE(64, info->hdr->sz_hidvol);
387 HOST_TO_BE(64, info->hdr->off_mk_scope);
388 HOST_TO_BE(64, info->hdr->sz_mk_scope);
389 HOST_TO_BE(32, info->hdr->sec_sz);
390 HOST_TO_BE(32, info->hdr->flags);
391 HOST_TO_BE(32, info->hdr->crc_dhdr);
393 memset(iv, 0, sizeof(iv));
394 error = tc_encrypt(info->cipher_chain, key, iv,
395 (unsigned char *)info->hdr, sizeof(struct tchdr_dec), ehdr->enc);
396 if (error) {
397 tc_log(1, "Header encryption failed\n");
398 goto error;
401 memset(iv, 0, sizeof(iv));
402 error = tc_encrypt(info->cipher_chain, key_backup, iv,
403 (unsigned char *)info->hdr,
404 sizeof(struct tchdr_dec), ehdr_backup->enc);
405 if (error) {
406 tc_log(1, "Backup header encryption failed\n");
407 goto error;
410 free_safe_mem(key);
411 free_safe_mem(key_backup);
413 if (backup_hdr != NULL)
414 *backup_hdr = ehdr_backup;
415 else
416 free_safe_mem(ehdr_backup);
418 return ehdr;
419 /* NOT REACHED */
421 error:
422 if (key)
423 free_safe_mem(key);
424 if (key_backup)
425 free_safe_mem(key_backup);
426 if (ehdr)
427 free_safe_mem(ehdr);
428 if (ehdr_backup)
429 free_safe_mem(ehdr_backup);
431 return NULL;