Saturday, June 12, 2010

[TRUECRYPT] How to encrypt multiple Windows system partitions in a multiboot setup


Background

TrueCrypt doesn't officially support encrypting more than one Windows system partition in a multi-boot setup, due to the limitations of its current boot loader design. This guide describes how to work around these limitations by leveraging a powerful boot manager like grub4dos to create a more secure multi-boot setup with multiple encrypted Windows system partitions. It’s roughly based on the original how-to I posted on the official TrueCrypt forum, which was later deleted by the forum administrators for some unknown reason. Since then, I have made several refinements to this process to make it a lot simpler than it originally was (the original method used a small bootstrap program that I had written for chainloading TrueCrypt boot loader, now grub4dos takes care of everything). For all purposes, this guide supersedes the original one, which has been archived here for reference (Thanks to Rudolf@WildersSecurity, who managed to create a local copy before the thread was deleted).

How this method works

When a windows system partition is encrypted with TrueCrypt, it stores its volume header in the last sector of Track 0 (LBA 0x3E) of the hard drive. If a second windows partition is encrypted similarly, this location is overwritten by the volume header corresponding to the second partition. Since TrueCrypt boot loader always reads the volume header from this location, it will no longer be able to decrypt the first partition. To get around this problem, we create file backups of the volume header and the MBR for each of the encrypted Windows partitions in a separate (unencrypted) boot partition. Then we setup the boot loader configuration in such a way that whenever the system boots up, it starts grub4dos installed in the unencrypted boot partition, which displays the primary boot menu. Depending on the user selection, grub4dos restores the correct volume header to LBA 0x3E, activates the relevant partition and chain loads the TrueCrypt MBR to continue the boot process with pre-boot authentication. All this can be done using official TrueCrypt distribution (no modifications required). Following are some of the features and limitations of this method:

  • One unencrypted partition (primary or logical) must be designated as "boot" partition, where grub4dos and the necessary boot files will reside. This can be setup with any filesystem supported by grub4dos such as ext3, fat, ntfs, etc.

  • Windows system partitions to be encrypted must be primary and must be completely independent. Due to the limit on the number of primary/extended partitions that can be created (4), a maximum of 3 Windows partitions can be encrypted this way (since we need one unencrypted boot partition).

  • Unlike WDE, there is no restriction on logical partitions - any number of logical partitions may be created. These logical partitions could be used to host Linux installations, data, partition based TrueCrypt volumes, etc and can even serve as the boot partition referenced above.

  • All windows partitions must be encrypted using the same symmetric encryption algorithm (the passphrase could be different) . Any encrypted instance of Windows will not be able to access data on the other encrypted system partitions.

TrueCrypt boot loader

The TrueCrypt boot loader roughly occupies the first 61 sectors (LBA 0x00-0x3C) of the hard drive, while the system volume header is stored in the last (63rd) sector of track 0 (LBA 0x3E). The first sector of the TrueCrypt boot loader residing in the MBR can be overwritten to transfer control to the primary boot manager instead and chainloaded later to continue the normal boot process with pre-boot authentication. Also, unless a cascaded encryption is being used, TrueCrypt creates two identical copies of the boot loader program in sectors 2-61. In this case, sectors 2-31 can be overwritten as well and the encrypted system will still be able to boot using the backup copy of the loader. But this should be avoided because some notorious programs are known to store activation data in this area and can cause corruption resulting in an unbootable system.

Additionally, because of the way TrueCrypt boot loader is designed, the Windows partition that’s to be decrypted using pre-boot authentication must be the active partition on that drive. Therefore, the boot code residing in the MBR should be able to transfer control to grub4dos regardless of which partition is currently active.
This tends to be a bit tricky, but I’ve described below three ways how this can be done:
  1. Use standard Windows fat/ntfs bootsector code to load grub4dos (grldr) and install custom MBR code to always bootstrap this partition. This is my preferred way because it supports ntfs boot partition and doesn’t touch sectors 2-61 where the TrueCrypt boot loader resides. All that’s required is to format the boot partition as fat/ntfs from within XP, Vista or 7 and copy “grldr” from grub4dos distribution to the root of this partition as “ntldr” for XP formatted partition or “bootmgr” for Vista/7 formatted partition. This method can also be extended to ext2/ext3 based boot partition by using bootlace.com tool provided as part of grub4dos distribution.

  2. Legacy grub provides a way to install stage1 code in the MBR that will load the main grub shell (stage2) from the boot partition, regardless of which partition is active. Once grub stage2 has been loaded, it can be used to chainload “grldr” also residing in the boot partition. Fortunately, the default location of the grub configuration file (menu.lst) is different for grub legacy and grub4dos, so it’s easy to make them co-exist. Using this approach, /boot/grub/menu.lst which is used by grub stage2 would contain one default entry to chainload “grldr” and /menu.lst which is read by “grldr” would contain the main boot menu.

  3. This is a variation of the above method, but instead of chainloading “grldr” from grub stage2, we replace the stage2 file with the grub4dos shell, so that stage1 code in MBR directly loads grub4dos. To replace grub stage2 with grub4dos shell, follow these steps:

    # Extract grub4dos shell from grldr
    dd if=grldr of=pre_stage2 bs=1 skip=8192
    # Extract stage2 loader from grub stage2
    dd if=stage2 of=start bs=1 count=512
    # Create stage2 for grub4dos
    cat start pre_stage2 > stage2

The last two methods don’t work with ntfs filesystem since it’s not supported by legacy grub. Additionally, if grub stage 1.5 (optional) is used during the installation, it will overwrite the sectors 2-31 of the track0. However, if grub stage 1.5 is not used, these sectors are left untouched, but the location of stage2 file within the boot partition filesystem must not change (by defragmentation, moving, etc) following the installation of stage1.

Putting it all together...

Here are step-by-step instructions on how to apply the above principles to create a multi-boot setup with multiple encrypted Windows system partitions. For simplicity, we’ll create a dual-boot system with 3 primary partitions (boot/data, WinXP & Win7). This setup was tested with:
  • TrueCrypt v6.3a
  • grub4dos-0.4.4-2009-06-20
  • Knoppix v6.2.1
  • Windows XP SP3
  • Windows 7

Step 1: Create partition layout

It's always better to create partitions upfront and make the Windows installation use the existing partitions. This also prevents Windows 7 installation from creating a separate boot partition (default setup). I prefer to use fdisk tool from Linux live CDs for this purpose (knoppix, slax, ubuntu, etc).

Go ahead and create three primary partitions of type ntfs: sda1(Boot), sda2 (WinXP) and sda3(Win7).

Assuming we would be installing Windows XP as the next step, activate sda2 and change sda3 to type 17 (hidden ntfs) - XP installation shouldn't see this partition. At this stage, the partition table would look something like this:

/dev/sda1 - type 7 (ntfs) - Boot
/dev/sda2 - type 7 (ntfs) - WinXP [ACTIVE]
/dev/sda3 - type 17 (hidden ntfs) - Win7

This completes the preparation phase: we have just created the partition layout on the hard drive, not created any file systems yet - this would be done in the next phase. Shut down and reboot with the XP installation CD...

Step 2: Setup Windows XP

Install Windows XP on sda2 (XP will use it as C:). Once the installation is completed, format the boot partition sda1 as ntfs from within XP (it will be assigned a drive letter such as D:). Next copy "grldr" from the grub4dos distribution to the root directory of the boot partition and rename it as “ntldr”. Also, create a folder named "boot" in the root directory to store the boot files (to be used later). Activate this partition from the Windows Disk Management console (diskmgmt.msc) and reboot. If everything was set up correctly, you should boot into grub4dos console. Once in grub console, re-activate sda2 and reboot into WinXP by issuing the following commands:

grub> rootnoverify (hd0,1)
grub> makeactive
grub> reboot

Now go through the normal process of TrueCrypt system encryption and encrypt the XP system partition sda2. Once the encryption process has been completed, boot up with the Linux live CD and mount the boot partition as ntfs. Next, backup the volume header and the first sector (MBR) of the TrueCrypt boot loader:

mount -t ntfs-3g /dev/sda1 /mnt/sda1
dd if=/dev/sda of=/mnt/sda1/boot/track0.winxp bs=512 count=63
dd if=/dev/sda of=/mnt/sda1/boot/tcmbr.winxp bs=512 count=1
dd if=/dev/sda of=/mnt/sda1/boot/vhdr.winxp bs=512 count=1 skip=62

Next, erase the TrueCrypt boot loader in preparation of Windows 7 installation

dd if=/dev/zero of=/dev/sda bs=512 count=62 seek=1
dd if=/dev/zero of=/dev/sda bs=440 count=1

This completes the XP setup phase. Assuming we would be installing Windows 7 as the next step, activate partition sda3, set it to type 7 (ntfs) and change sda2 to type 17 (hidden ntfs) - Windows 7 installation shouldn't see this partition. At this stage, the partition table would look something like this:

/dev/sda1 - type 7 (ntfs) - Boot
/dev/sda2 - type 17 (hidden ntfs) - WinXP
/dev/sda3 - type 7 (ntfs) - Win7 [ACTIVE]

Shut down and reboot with the Windows 7 installation CD...

Step 3: Setup Windows 7

Install Windows 7 on sda3 (Windows 7 will use it as C:), making sure that the Windows 7 installation doesn't touch the WinXP partition (sda2) in any way. The boot partition will probably be assigned a drive letter such as D:.

Now go through the normal process of TrueCrypt system encryption and encrypt the Windows 7 partition sda3. Once the encryption process has been completed, boot up with the Linux Live CD and mount the boot partition as ntfs. Next, backup the volume header and the first sector (MBR) of the TrueCrypt boot loader.

mount -t ntfs-3g /dev/sda1 /mnt/sda1
dd if=/dev/sda of=/mnt/sda1/boot/track0.win7 bs=512 count=63
dd if=/dev/sda of=/mnt/sda1/boot/tcmbr.win7 bs=512 count=1
dd if=/dev/sda of=/mnt/sda1/boot/vhdr.win7 bs=512 count=1 skip=62

This completes the Windows 7 setup phase. Next step is to configure grub for dual boot...

Step 4: Setup boot partition

We will use the custom MBR to start up grub4dos from the boot partition and leverage grub4dos “dd” command to update the sector where TrueCrypt stores the system volume header.

# Make sure all needed files are present (track0 files are optional)
ls /mnt/sda1/boot
mbr.bin
tcmbr.win7
tcmbr.winxp
track0.win7
track0.winxp
vhdr.win7
vhdr.winxp

# Install Custom MBR code
dd if=/mnt/sda1/boot/mbr.bin of=/dev/sda

Next, open the MBR (LBA 0x00) in a disk editor and change byte at offset 0x0195 from 0 to 1 (Partition number of the boot partition sda1).

Lastly, copy the following text to /mnt/sda1/menu.lst

default 0
timeout 10

title Windows XP
hide (hd0,2)
unhide (hd0,1)
rootnoverify (hd0,1)
makeactive
dd if=(hd0,0)/boot/vhdr.winxp of=(hd0) seek=62
chainloader (hd0,0)/boot/tcmbr.winxp

title Windows 7
hide (hd0,1)
unhide (hd0,2)
rootnoverify (hd0,2)
makeactive
dd if=(hd0,0)/boot/vhdr.win7 of=(hd0) seek=62
chainloader (hd0,0)/boot/tcmbr.win7

That's it! Reboot into a perfect dual-boot setup.
Any comments, please post here.

[Custom MBR] Ignore the "Active" flag, bootstrap a designated "boot" partition


Background

This is a versatile MBR boot code that I wrote to facilitate the use of grub4dos as a primary boot manager. In addition to the standard DOS/Windows MBR functionality (bootstrap the active primary partition), it can be configured to always bootstrap a designated "boot" partition (regardless of the status of the "Active" flag in the partition table). This enables a flexible grub4dos setup as primary boot manager, which:

  • Doesn't rely on the status of "Active" flag and supports booting from logical partitions (just like grub stage1 loader)

  • Doesn't write to the unused sectors of master boot track (LBA 0x01-0x3E, where grub usually embeds its stage1.5 code)

  • Doesn't use a block-list to load boot components (safe from defragmentation of the filesystem)

  • Supports NTFS/FAT/EXT3 (primary or logical) boot partitions (therefore, any existing NTFS/FAT data partition can be configured to serve as a boot partition)

[An alternate approach would be to install legacy grub as you'd normally do and use it to chainload grldr (grub4dos). However, aside from being slow and incompatible with NTFS, this method requires either writing intermediate stage1.5 boot code to the master boot track or loading stage2 as block-list, which is prone to corruption by defragmentation.]

Installation

Download mbr.bin from here. Make sure you backup your data and verify the md5 checksum before proceeding. From Linux, install the custom MBR using the "dd" command:

$ dd if=mbr.bin of=/dev/sda

where sda is the device (hard drive) where you want to install this MBR

Configuration

In its default configuration, the MBR boot code will chainload the volume boot sector the active primary partition just like traditional DOS/Windows MBR. However, this behavior can be overridden to always bootstrap a certain partition, by patching the control byte at offset 0x0195 (406th byte starting from 1, highlighted in red below) with the partition number of the that partition (1-4 for primary/extended partitions, 5 onwards for logical partitions). When this byte is non-zero, the MBR boot code will ignore the "Active" flag in the partition table and chainload the volume boot sector of the partition corresponding to this number.


477da2d302fe8cc16f05e3c5dba08d0c mbr.bin

0000000: fa31 c08e d88e d0bc 007c 89e6 0657 528e
0000010: c0fb fcbf 0006 b900 01f3 a5ea 2006 0000
0000020: 6631 c066 99bb be07 8a2e 9507 20ed 7555
0000030: b904 00f6 0780 7405 4266 8b47 0883 c310
0000040: e2f1 4a0f 84ee 0079 1ce8 3301 426f 6f74
0000050: 2070 6172 7469 7469 6f6e 206d 6973 7369
0000060: 6e67 2e0d 0ae8 1701 4d75 6c74 6970 6c65
0000070: 2061 6374 6976 6520 7061 7274 6974 696f
0000080: 6e73 2e0d 0a30 c9fe c18a 4704 38cd 741c
0000090: 3c05 740a 3c0f 7406 3c85 7402 eb04 668b
00000a0: 5708 80f9 0474 0f83 c310 ebdb 20c0 7499
00000b0: 668b 4708 eb7f 6621 d274 8e51 6689 d0e8
00000c0: 6200 5966 50bb be07 fec1 8a47 0438 cd74
00000d0: 2383 c310 8a47 043c 0574 0b3c 0f74 073c
00000e0: 8574 03e9 63ff 5166 8b47 0866 01d0 e833
00000f0: 0059 ebcf 20c0 0f84 4fff 6658 6603 4708
0000100: eb33 6660 6631 d2bb 007c 6652 6650 0653
0000110: 6a01 6a10 89e6 b442 8a16 fa7b cd13 8d64
0000120: 1066 61c3 e8db ff72 40be be7d bfbe 07b9
0000130: 2000 f3a5 c3e8 caff 722f 813e fe7d 55aa
0000140: 7509 bcfa 7b5a 5f07 faff e4e8 3100 4d69
0000150: 7373 696e 6720 4f70 6572 6174 696e 6720
0000160: 5379 7374 656d 2e0d 0ae8 1300 4572 726f
0000170: 7220 6c6f 6164 696e 6720 4f53 2e0d 0a5e
0000180: acb4 0e8a 3e62 04b3 07cd 103c 0a75 f1cd
0000190: 18f4 ebfd 0000 0000 0000 0000 0000 0000
00001a0: 0000 0000 0000 0000 0000 0000 0000 0000
00001b0: 0000 0000 0000 0000


The volume boot sector of the boot partition can be configured to load grub4dos (/grldr) either by using bootlace.com (bundled with grub4dos distribution) or, in case of ntfs/fat partition formatted by Windows, simply by renaming /grldr as /ntldr (for XP formatted partition) or /bootmgr (for Vista/7 formatted partition).

Note: To use the second method with logical partitions, you would additionally need to correct the HiddenSector parameter in the ntfs/fat volume boot sector to make the partition bootable, as described here.