#!/bin/bash
#
# loopaes: Simulate Loop-AES using device mapper.
# version: 2005 May 27
#
# This may work for you if you were using Loop-AES with
#    losetup -e AES256
#    or
#    losetup -e AES128
#
# Goodluck!!
# - Greg Larson <dmloopaes@glarson.org>
#
# Added support for AES128
# - Yoav Weiss <crypto@unpatched.net>
#
# Usage:
#	loopaes <LoopNo> <File> [<keybits>]
#
#	Resulting mapped volume will be volaes<LoopNo>
#	accessed as /dev/mapper/loopaes<LoopNo>
#
#	loopaes -d <LoopNo>
#
#	Unmount and unmap device.
#

#
# Example:
#
# Old commands:
#	losetup -e AES256 /dev/loop5 /privfs.aes256
#	e2fsck /dev/loop5
#	mount /dev/loop5 /mnt/priv/privfs
#
# New command:
#	loopaes 5 /privfs.aes256
#	e2fsck /dev/mapper/loopaes5
#	mount /dev/mapper/loopaes5 /mnt/priv/privfs
#
# Example with key size: 
#	loopaes 6 /privfs.aes128 128
#	e2fsck /dev/mapper/loopaes6
#	mount /dev/mapper/loopaes6 /mnt/priv/privfs
#

if [ "$1" = "-d" ]; then
	shift
	unloopaes="1"
else
	unloopaes=""
fi

loopnum="$1"
loopfile="$2"
loopdev=/dev/loop$loopnum
loopvol=loopaes$loopnum
dmdev=/dev/mapper/$loopvol
bits="$3"

#
# Default to 256 bits.
#
if [ -z $bits ]; then
	bits=256
fi

#
# Unmount mapped device (volume) if it is mounted.
#
grep -q $dmdev /proc/mounts && umount $dmdev

#
# Remove mapped device (volume) if it exists.
#
dmsetup status $loopvol &> /dev/null && dmsetup remove $loopvol

#
# Unmap loop device
#
losetup -d $loopdev &> /dev/null

if [ "$unloopaes" ]; then
	#
	# All cleaned up and done.
	#
	exit
fi

#
# Map the loop device to the file.
#
losetup $loopdev $loopfile

#
# Get the size and key.
#
echo "Passphrase for $loopfile mount via $dmdev."
size=$(blockdev --getsize $loopdev)
if [ "$bits" = "256" ]; then
	key=$(hashalot -x -n 32 sha512)
elif [ "$bits" = "128" ]; then
	key=$(hashalot -x -n 16 sha256)
else
	echo Unsupported keysize. Feel free to read loop-AES source and add modes.
	exit
fi

#
# Make sure the necessary modules are loaded.
#
modprobe dm_crypt
modprobe aes

#
# Map the device (volume)
#
echo 0 $size crypt aes-plain $key 0 $loopdev 0 | dmsetup create $loopvol


