HOWTO_Burn_Encrypted_Optical_Media_With_Luks
| Installation • Kernel & Hardware • Networks • Portage • Software • System • X Server • Gaming • Non-x86 • Emulators • Misc |
Contents |
Introduction
The purpose of this HOWTO is to learn how to burn encrypted optical media disc using Device Mapper and Cryptsetup-Luks.
Why Luks?
- compatiblity via standardization,
- secure against low entropy attacks,
- support for multiple keys,
- effective passphrase revocation,
- free
more information about Luks can be found here..
Alternatives
Visit HOWTO Burn Encrypted DVDs, just remember that using the Crypto-Loop method is not safe for journaling file systems like ext3/reiserfs.
Minimum Requirements
- Kernel: >= 2.6.10
- sys-fs/cryptsetup
- app-cdr/cdrkit - replacement for cdrtools.
- app-cdr/dvd+rw-tools - used to burn Dual Layer Media.
- The ability to follow instructions
- Patience
- Some blank cdr/dvdr disc (s)
You can use zgrep <CONFIG> /proc/config.gz or grep <CONFIG> /usr/src/linux-$(uname -r)/.config to check whether your kernel meets the requirements. Look for the following options.
- CONFIG_BLK_DEV_DM=y or CONFIG_BLK_DEV_DM=M
- CONFIG_DM_CRYPT=y or CONFIG_DM_CRYPT=M
- Kernel >= 2.6.19: pay attention to the new SATA configs and enable CONFIG_CRYPTO_CBC=y
You can see the available ciphers by doing cat /proc/crypto.
Require Kernel Modules
| Linux Kernel Configuration: Required |
Each and all kernel options do not need to be build-in and can be setup as modules to avoid a reboot. Device Drivers --->
Multi-device support (RAID and LVM) --->
<*> Device mapper support
<*> Crypt target support
Don't forget to include support for the ciphers you want to use. Cryptographic options --->
<M> SHA256 digest algorithm
<M> AES cipher algorithms (x86_64)
|
Installing Needed Packages
emerge cryptsetup-luks device-mapper
Loading necessary modules
The modules you need to load depend on the ciphers you plan to use. Please see this subsection for some information about different available ciphers, and of course edit the commands accordingly.
| Code: Loading modules |
modprobe dm-crypt # required modprobe dm-mod # required modprobe aes_x86_64 # for amd64 users only, otherwise use aes modprobe sha256 modprobe blowfish # we use this to encrypt our swap file |
| Tip! Loading the modules, Bash one-liner for i in dm-crypt dm-mod serpent sha256 blowfish;do modprobe $i;done |
| Tip! cat /proc/crypto will show you the loaded modules.</tt> |
Encrypting swap to be safer.
First you will encrypt swap. This is important because you don't want the encryption keys swapped to an unencrypted disk. (Optional)
| Code: Encrypting swap for installation (not for suspend2 users) |
cryptsetup -c blowfish -h sha256 -d /dev/urandom create swap /dev/sdaX # X being your swap partition mkswap /dev/mapper/swap swapon /dev/mapper/swap |
Start
Now let's begin with the encryption :)
Creating container
| Code: Create an empty container large enough for the iso image |
dd if=/dev/urandom of=cryptocd.iso bs=512 count=2048 dd if=/dev/urandom of=cryptocd.iso bs=512 count=1 seek=1M |
Loop Device
| Code: check for a free loop device for our image file: |
losetup -f |
Create a blockdevice from image file
losetup /dev/loop0 cryptocd.iso
Format loop device using luks
cryptsetup luksFormat /dev/loop0
Remember this password or you'll be SOL.
Create Luks Mapping
cryptsetup luksOpen /dev/loop0 cryptocd
Create ISO
Now create your iso file system using mkisofs and write it to the mapped device change -lots-of-options to something compatible. for example i use. -allow-leading-dots -joliet-long -iso-level 3 -l -J -r -V volume_ID for CD/DVD data files. -udf -v for Dual Layer Media & -dvd-video for DVD movies
| Code: Create ISO |
genisoimage -lots-of-options /my/data/ -o burnme.iso |
| Tip! (The number dd reports is important for further calculations!) |
Copy ISO Image into device mapper
| Code: Now we will pipe the burnme.iso image into the luks device mapper. |
dd if=burnme.iso of=/dev/mapper/cryptocd bs=512 2>&1 | grep "records out" | cut -f1 -d+ |
Calculate Overhead
| Code: Now calculate the overhead of the luks container. |
blockdev --getsize /dev/loop0 blockdev --getsize /dev/mapper/cryptocd |
| Tip! Now add the size dd reported and you know where to truncate (used as $SIZE later) |
Remove Mapping
For safety reasons, remove mapping and loopdevice. cryptsetup luksClose cryptocd ; losetup -d /dev/loop0
Replacing size of overhead
| Code: replace $SIZE with sum of size dd reported and the luks overhead. |
dd if=cryptocd.iso of=cryptocd.iso bs=512 count=0 skip=$SIZE seek=$SIZE |
Test Encrypted Image
| Code: Mount the loop image and open it with luks |
losetup /dev/loop0 cryptocd.iso cryptsetup luksOpen /dev/loop0 cryptocd |
Finished
Now unmap again then burn the image with cdrecord or any other tool which you burn your isos with.
WARNING: Do not burn a CD in Track At Once mode (TAO) - this will destroy at minimum the last 2 sectors (q.v.: Burning encrypted ISO image to CD / readahead bug)!
Automation
I wrote a couple scripts to automate this process, read it before using it and modify it to your needs.
| File: cryptocd |
#!/bin/bash -x
# CryptoCD - Optical Media Backup 0.3 - burn encrypted backup CD/DVDs
# Created: Mon Oct 01 4:20:00 2007
# Copyright 2007 Tim Niemueller [www.niemueller.de]
# Based on work copyright by Gentoo Wiki User likewhoa
# Revised by likewhoa on 20071001 4:20:00
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
# C h a n g e L o g
# 2007-09-12 tim 0.1 initial revision for publication
# 2007-09-17 tim 0.2 added -G, added -f, fixed mkisofs param and copy iso bug
# 2007-10-01 likewhoa 0.3
# 1. Code cleanup
# 2. Max data limits updated
# 3. Dependency checks
# 4. Minor code additions
# 2007-10-11 likewhoa 0.3-r1 - fixed free loop device line
# 2007-10-15 likewhoa 0.3-r2 - added flags for burn speed and fixed minor code bugs.
# 2007-10-19 likewhoa 0.3-r5 - minor tweaks and code adjustments.
# End C h a n g e L o g
export LANG=C
if [ $(whoami) != root ]; then echo "this script must be run as root."; exit 1; fi
# check dependencies.
for i in wodim genisoimage; do
if ! which $i &>/dev/null; then
echo "ERROR: $i must be in your $PATH path!" $
exit 1
fi
done
declare -a SRCDIRA
declare -i SRCDIRI SRCDIRNUM
SRCDIRS=/mnt/crypto
SRCDIRI=0
VOLUMEID=${VOLUMEID:-420}
PRODUCER=${PRODUCER:-likewhoa}
GRAFTPOINTS=
DUALLAYER=0
GRAFTPOINTING=0
SHORT_GRAFTPOINTING=0
KEEPISO=0
SHOWUSAGE=0
CUSTOMISO=
FORCE=0
while getopts "V:P:d:DgGkhis:f" options; do
case $options in
V) VOLUMEID=$OPTARG;;
P) PRODUCER=$OPTARG;;
d) SRCDIRA[$SRCDIRI]="$OPTARG"; SRCDIRI+=1;;
D) DUALLAYER=1;;
g) GRAFTPOINTING=1;;
G) GRAFTPOINTING=1; SHORT_GRAFTPOINTING=1;;
k) KEEPISO=1;;
h) SHOWUSAGE=1;;
i) CUSTOMISO=$OPTARG;;
s) BURNSPEED="$OPTARG";;
f) FORCE=1;;
*) echo "Unknown option '$options'";;
esac
done
if [ $SHOWUSAGE == 1 ]; then
cat << EOF
Usage: $0 [options]
Options:
-s 16 This tells $0 to burn at 16x speed. (Default 8)
-i img.iso Use given existing ISO image and put it into an
encrypted container. -d/-V/-P/-g are ignored.
-V volid ISO volume ID
-P publisher ISO publisher
-d dir Directory to backup, may be used multiple times
if not given, current directory is backed up.
-D Use dual layer DVD (used for size check)
-g Use graft-pointing (see man genisoimage)
-G Use short graft-points (basedir of source dir as dir on DVD)
-k Keep ISO image after burning
-f Force creation, delete crypto ISO image if it exists
-h This help message
EOF
exit 0
fi
if [[ $SRCDIRNUM = 0 ]]; then
SRCDIRS=$(pwd)
SRCDIRNUM=1
if [ $GRAFTPOINTING = 1 ]; then
if [ $SHORT_GRAFTPOINTING = 1 ]; then
GRAFTPOINTS="$(echo $(basename $PWD) | sed -e 's/\\/\\\\/g' -e 's/=/\\=/g')=$PWD"
else
GRAFTPOINTS="$(echo $PWD | sed -e 's/\\/\\\\/g' -e 's/=/\\=/g')=$PWD"
fi
fi
else
for (( i=0; $i < ${SRCDIRNUM:-0}; i += 1 )); do
if [[ ${SRCDIRA[$i]} =~ " " ]]; then
echo "Path may not contain spaces for now"
exit -1
fi
SRCDIRS="$SRCDIRS ${SRCDIRA[$i]}"
if [ $GRAFTPOINTING = 1 ]; then
if [ $SHORT_GRAFTPOINTING = 1 ]; then
GRAFTPOINTS="$GRAFTPOINTS $(echo $(basename ${SRCDIRA[$i]}) | sed -e 's/\\/\\\\/g' -e 's/=/\\=/g')=${SRCDIRA[$i]}"
else
GRAFTPOINTS="$GRAFTPOINTS $(echo ${SRCDIRA[$i]} | sed -e 's/\\/\\\\/g' -e 's/=/\\=/g')=${SRCDIRA[$i]}"
fi
fi
done
fi
GENISOIMAGE_ARGS_DATA="-allow-leading-dots -joliet-long -iso-level 3 -l -J -R -D -v" # Default arguments for genisoimage for data DVDs
GENISOIMAGE_ARGS_VIDEO="-dvd-video" # Default arguments for genisoimage for video DVDs
MOUNTDIR=/mnt/cdrom # Directory to mount iso data
CDRECORDER=/dev/dvd1 # Optional path to your cdburner, set only if $BURNMEDIA equals 1
ISO=/mnt/dvdimage.iso # Name of the iso image (enough space needed there!)
TMPISO=/mnt/tmp.iso
CRYPT="-y -c aes-cbc-essiv:sha256 -h 256" # Encryption options for cryptsetup
MAPPER="cryptodvd" # Name for mapped volume
LOOP=
SIZE=
SIZE_VOL1=
SIZE_LOOP=
if [ "$DUALLAYER" = "0" ]; then
echo "Burning to regular DVD (4.7GB)"
MAXSIZE=$(( 4700 *2 ))k # Number of 512 blocks (can you see the k? ;-)
b=4585590 # Safe size limit for DVDr media 4.4G
else
echo "Burning to dual layer DVD (8.5 GB)"
MAXSIZE=$(( 8500 *2 ))k # Number of 512 blocks (can you see the k? ;-)
b=8298400 # Safe size limit for DVD-R DL media 8.5G
GENISOIMAGE_ARGS_DATA="${GENISOIMAGE_ARGS_DATA} -udf" # UDF filesystem option set for DL media.
fi
if [[ "$SRCDIRNUM" == "1" && $(find $SRCDIRS -type d -name 'VIDEO_TS') ]]; then
echo "detected dvd-video data structure"
GENISOIMAGE=$GENISOIMAGE_ARGS_VIDEO
else
GENISOIMAGE=$GENISOIMAGE_ARGS_DATA
fi
if [ "$PRODUCER" != "" ]; then
GENISOIMAGE="$GENISOIMAGE -publisher \"$PRODUCER\""
fi
if [ "$VOLUMEID" != "" ]; then
GENISOIMAGE="$GENISOIMAGE -volid \"$VOLUMEID\""
fi
if [ "$GRAFTPOINTS" != "" ]; then
GENISOIMAGE="$GENISOIMAGE -graft-points"
else
GRAFTPOINTS=$SRCDIRS
fi
if [ ! -d $(dirname $ISO) ]; then
echo "Required ISO directory $(dirname $ISO) does not exist, aborting."
exit -1
fi
if [ ! -d $(dirname $TMPISO) ]; then
echo "Required temporary ISO directory $(dirname $TMPISO) does not exist, aborting."
exit -1
fi
if [ -e $ISO ]; then
if [ $FORCE == 1 ]; then
echo "Removing old ISO image $ISO"
rm -f $ISO
else
echo "ISO image $ISO does already exist, aborting"
exit
fi
fi
check_iso_size() {
echo "Calculating ISO size (SRCDIRS: $SRCDIRS)"
a=$(du -kcs $SRCDIRS | tail -n1 | awk '{ print $1 }') # Size of src data directories
if [ -a $ISO ]; then rm -fv $ISO; fi # Removing old ISO images if it exist
if (( a > b )); then
echo "maximum size limit of ${b}k for CDr Media excedded"
exit 1
fi
}
setup_crypto_volume() {
# new methods doesn't work anymore :(
# LOOP=$(losetup -f)
for i in /dev/loop[0-7]; do
losetup $i >/dev/null 2>&1
if [ $? -eq 1 ] ; then LOOP=$i ;break ; fi
done
if [ -z "$LOOP" ]; then echo "no free loop device" >&2; exit; fi
echo "Setting up crypto volume"
dd if=/dev/urandom of=$ISO bs=512 count=2048
dd if=/dev/urandom of=$ISO bs=512 count=1 seek=$MAXSIZE
losetup $LOOP $ISO
cryptsetup $CRYPT luksFormat $LOOP
echo "Opening crypto volume"
cryptsetup luksOpen $LOOP $MAPPER
}
create_iso_image() {
echo "Creating ISO image tmp file (may take a while)"
# Why eval?
# If we pass parameters that contain spaces we want to get them interpreted as ONE parameter,
# not as two, so we write "a b". To avoid mangling of the names (if used in $(...)) we use eval
eval nice genisoimage $GENISOIMAGE -o $TMPISO $GRAFTPOINTS
}
copy_iso_image() {
local COPYISO=$1
echo "Copying ISO image $COPYISO into crypto volume"
SIZE=$(nice dd if=$COPYISO of=/dev/mapper/$MAPPER bs=512 2>&1 | grep "records out" | cut -f1 -d+)
SIZE_VOL1=$(blockdev --getsize /dev/mapper/$MAPPER)
SIZE_LOOP=$(blockdev --getsize $LOOP)
}
remove_temp_iso_image() {
echo "Removing temporary ISO image"
rm -vf $TMPISO
echo "SIZE=$SIZE SIZE_VOL1=$SIZE_VOL1 SIZE_LOOP=$SIZE_LOOP"
}
close_crypto_volume() {
echo "Closing crypto volume"
cryptsetup luksClose $MAPPER
losetup -d $LOOP
}
truncate_crypto_container() {
SIZE=$(( $SIZE + ($SIZE_LOOP - $SIZE_VOL1) ))
# echo "SIZE recalculated to $SIZE (SIZE=$SIZE + (SIZE_LOOP=$SIZE_LOOP - SIZE_VOL1=$SIZE_VOL1))"
dd if=$ISO of=$ISO bs=512 count=0 skip=$SIZE seek=$SIZE
}
test_iso_image() {
echo "Testing ISO image..."
losetup $LOOP $ISO
losetup $LOOP $ISO
echo "Enter your luks password phrase"
cryptsetup luksOpen $LOOP $MAPPER
echo "Mounting encrypted optical media disc to $MOUNTDIR"
if [ ! -d $MOUNTDIR ]; then
mkdir -p $MOUNTDIR
fi
mount /dev/mapper/$MAPPER $MOUNTDIR
ls -al $ISO
ls -al $MOUNTDIR
}
burn_abort_standby() {
cat << EOF
Now make sure data is good so we can continue...
Your options now:
B Burn - Burn image
A Abort - Abort, ISO will stay
S Standby - Standby, will close crypto volume and
then waits for another key press, useful
for example if you want to add a key
(cryptsetup -y -i 3000 luksAddKey $LOOP)
EOF
echo "What to do? Burn/Abort/Standby"; read c
echo "Closing crypto volume"
umount $MOUNTDIR
cryptsetup luksClose $MAPPER
if [[ $c =~ [Ss][Tt][Aa][Nn][Dd][Bb][Yy]|[Ss] ]]; then
echo "Waiting... enter Burn or Abort when done"
read c
fi
losetup -d $LOOP
if [[ $c =~ [Aa][Bb][Oo][Rr][Tt]|[Aa] ]]; then
echo "Are you sure you want to abort?"; read d
if [[ $d =~ [Yy]|[Yy][Ee][Ss] ]]; then
echo "Aborting..."; exit 1
fi
fi
if [ ! -b $CDRECORDER ]; then
echo "CDr/DVDr Burner it's not a block device. exiting"
exit 1
else
echo "Burning CryptoCD/DVD media"
# using growisofs instead of wodim for now until upstream fixes bug.
#wodim -v -dao dev=$CDRECORDER speed=$BURNSPEED $ISO
growisofs -Z ${CDRECORDER}=${ISO} -speed=${BURNSPEED:-8}
fi
if [ $KEEPISO == 0 ]; then
echo "Deleting ISO $ISO"
rm -fv $ISO
fi
}
# The real procedure...
if [ -z "$CUSTOMISO" ]; then
check_iso_size
else
echo "Using custom ISO image, NOT checking size"
fi
setup_crypto_volume
if [ -z "$CUSTOMISO" ]; then
create_iso_image
fi
if [ ! -z "$CUSTOMISO" ]; then
copy_iso_image $CUSTOMISO
else
copy_iso_image $TMPISO
remove_temp_iso_image
fi
close_crypto_volume
truncate_crypto_container
test_iso_image
burn_abort_standby
echo "all done. Enjoy your encrypted DVD/CD."
|
The two scripts below can be used to mount/umount your encrypted optical media.
| File: cryptocd-mount |
#!/bin/bash if [ $(whoami) != root ]; then echo "this script must be run as root."; exit; fi MOUNTDIR=/mnt/cryptocd # Directory to mount iso data. CDROM=/dev/dvd1 # Optional path to your optical drive. MAPPER="cryptocd" # Name for mapped volume. LOOP=$(losetup -f) # Free loop device. if [ -z "$LOOP" ]; then echo "no free loop device" >&2; exit; fi [ ! -d $MOUNTDIR ] && mkdir $MOUNTDIR losetup $LOOP $CDROM && echo $LOOP >/tmp/loop_device cryptsetup luksOpen $LOOP $MAPPER mount /dev/mapper/$MAPPER $MOUNTDIR echo "all done." |
| File: cryptocd-umount |
#!/bin/bash
if [ $(whoami) != root ]; then echo "this script must be run as root."; exit; fi
error() {
echo "error occured, exiting."
exit
}
MOUNTDIR=/mnt/cryptocd # Directory to mount iso data
MAPPER="cryptocd" # Name for mapped volume
LOOP=$(cat /tmp/loop_device) # Loop device from cryptocd-mount
umount $MOUNTDIR || error
cryptsetup luksClose /dev/mapper/$MAPPER
losetup -d $LOOP
echo "all done."
|
FAQ
Please see LUKSFaq as well.
- I lost my password. What can I do?
Sorry but You're SOL buddy. :P
| Tip! keep more than one luks password phrase just incase, this must be done before the burning process takes place. read the Luks FAQ for info on adding/deleting keyslots in luks mappings. |
Ciphers
Some of the available ciphers found on the cryptographic kernel menu:
Credits
This project features code adapted and or merged from.
- easy_iso_crypt.sh. GPL2
- CryptoDVD Backup Script. GPL2
Change Log
- 20071011 - updated code that finds free loop device.
- 20071005 - updates to cryptocd-mount and crypto-umount scripts.
- 20071001 - code additions by tim.
TODO
- Add error correction and detection.
- Stegnography support.
- Future port to python.
--Likewhoa 12:44, 23 January 2007 (UTC)
Created by NickStallman.net, Luxury Homes Australia
Real estate agents should be using interactive floor plans and real estate agent tools.
