1 /*
2
3 File: luks.c
4
5 Copyright (C) 2007 Christophe GRENIER <grenier@cgsecurity.org>
6
7 This software is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write the Free Software Foundation, Inc., 51
19 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #ifdef HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #ifdef HAVE_STRING_H
29 #include <string.h>
30 #endif
31 #include <stdio.h>
32 #include "types.h"
33 #include "common.h"
34 #include "luks.h"
35 #include "fnctdsk.h"
36 #include "log.h"
37 #include "guid_cpy.h"
38
39 static int test_LUKS(disk_t *disk_car, const struct luks_phdr *sb, const partition_t *partition, const int dump_ind);
40 static void set_LUKS_info(const struct luks_phdr *sb, partition_t *partition);
41
check_LUKS(disk_t * disk_car,partition_t * partition)42 int check_LUKS(disk_t *disk_car,partition_t *partition)
43 {
44 unsigned char *buffer=(unsigned char*)MALLOC(DEFAULT_SECTOR_SIZE);
45 if(disk_car->pread(disk_car, buffer, DEFAULT_SECTOR_SIZE, partition->part_offset) != DEFAULT_SECTOR_SIZE)
46 {
47 free(buffer);
48 return 1;
49 }
50 if(test_LUKS(disk_car, (struct luks_phdr*)buffer, partition, 0)!=0)
51 {
52 free(buffer);
53 return 1;
54 }
55 set_LUKS_info((struct luks_phdr*)buffer, partition);
56 free(buffer);
57 return 0;
58 }
59
set_LUKS_info(const struct luks_phdr * sb,partition_t * partition)60 static void set_LUKS_info(const struct luks_phdr *sb, partition_t *partition)
61 {
62 partition->upart_type=UP_LUKS;
63 if(partition->part_size > 0)
64 sprintf(partition->info,"LUKS %u", be16(sb->version));
65 else
66 sprintf(partition->info,"LUKS %u (Data size unknown)", be16(sb->version));
67 }
68
recover_LUKS(disk_t * disk_car,const struct luks_phdr * sb,partition_t * partition,const int verbose,const int dump_ind)69 int recover_LUKS(disk_t *disk_car, const struct luks_phdr *sb,partition_t *partition,const int verbose, const int dump_ind)
70 {
71 if(test_LUKS(disk_car, sb, partition, dump_ind)!=0)
72 return 1;
73 if(partition==NULL)
74 return 0;
75 set_LUKS_info(sb, partition);
76 partition->part_type_i386=P_LINUX;
77 partition->part_type_mac=PMAC_LINUX;
78 partition->part_type_sun=PSUN_LINUX;
79 partition->part_type_gpt=GPT_ENT_TYPE_LINUX_DATA;
80 partition->part_size=(uint64_t)be32(sb->payloadOffset)*disk_car->sector_size;
81 partition->blocksize=0;
82 partition->sborg_offset=0;
83 partition->sb_offset=0;
84 /* sb->uuid is bigger than part_uuid */
85 guid_cpy(&partition->part_uuid, (const efi_guid_t *)&sb->uuid);
86 if(verbose>0)
87 {
88 log_info("\n");
89 }
90 return 0;
91 }
92
test_LUKS(disk_t * disk_car,const struct luks_phdr * sb,const partition_t * partition,const int dump_ind)93 static int test_LUKS(disk_t *disk_car, const struct luks_phdr *sb, const partition_t *partition, const int dump_ind)
94 {
95 static const uint8_t LUKS_MAGIC[LUKS_MAGIC_L] = {'L','U','K','S', 0xba, 0xbe};
96 if(memcmp(sb->magic, LUKS_MAGIC, LUKS_MAGIC_L)!=0)
97 return 1;
98 if(dump_ind!=0)
99 {
100 if(partition!=NULL && disk_car!=NULL)
101 log_info("\nLUKS magic value at %u/%u/%u\n",
102 offset2cylinder(disk_car,partition->part_offset),
103 offset2head(disk_car,partition->part_offset),
104 offset2sector(disk_car,partition->part_offset));
105 dump_log(sb,DEFAULT_SECTOR_SIZE);
106 }
107 return 0;
108 }
109