mirror of
https://github.com/Llewellynvdm/Tomb.git
synced 2024-11-22 12:35:13 +00:00
new creation system in 3 steps and some tips in documentation
This commit is contained in:
parent
b9b7927e81
commit
84d4385696
25
doc/Tomb_User_Manual.org
Normal file
25
doc/Tomb_User_Manual.org
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
|
||||||
|
when creating a tomb make sure the device mapper is loaded among kernel modules
|
||||||
|
or creation will fail and leave you in the dust.
|
||||||
|
|
||||||
|
modprobe dm_mod
|
||||||
|
modprobe dm_crypt
|
||||||
|
|
||||||
|
to create a tomb on a server (even VPS) is possible, but the problem becomes the little
|
||||||
|
available entropy. in order to fix this one can use EGD the Entropy Gathering Daemon.
|
||||||
|
|
||||||
|
on Debian, do:
|
||||||
|
|
||||||
|
sudo aptitude install libdigest-sha1-perl
|
||||||
|
sudo aptitude install ekeyd-egd-linux
|
||||||
|
|
||||||
|
/etc/default/ekeyd-egd-linux
|
||||||
|
|
||||||
|
wget http://egd.sourceforge.net/
|
||||||
|
|
||||||
|
perl ./egd.pl
|
||||||
|
|
||||||
|
/etc/init.d/ekeyd-egd-linux start
|
||||||
|
|
||||||
|
|
224
src/tomb
224
src/tomb
@ -640,10 +640,12 @@ exec_safe_post_hooks() {
|
|||||||
create_tomb() {
|
create_tomb() {
|
||||||
_message "Commanded to create tomb $1"
|
_message "Commanded to create tomb $1"
|
||||||
|
|
||||||
# running as root, remembering the uid:gid
|
# we run as root, but remember the original uid:gid to drop
|
||||||
|
# privileges when not needed anymore
|
||||||
if option_is_set -U; then _uid="`option_value -U`"; fi
|
if option_is_set -U; then _uid="`option_value -U`"; fi
|
||||||
if option_is_set -G; then _gid="`option_value -G`"; fi
|
if option_is_set -G; then _gid="`option_value -G`"; fi
|
||||||
|
|
||||||
|
# if swap is on, we remind the user about possible data leaks to disk
|
||||||
if ! option_is_set -f && ! option_is_set --ignore-swap; then check_swap; fi
|
if ! option_is_set -f && ! option_is_set --ignore-swap; then check_swap; fi
|
||||||
|
|
||||||
if ! [ $1 ]; then
|
if ! [ $1 ]; then
|
||||||
@ -651,10 +653,11 @@ create_tomb() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ $2 ]; then
|
# the encryption cipher for a tomb can be set at creation using -o
|
||||||
create_cipher=aes-cbc-essiv
|
if ! option_is_set -o; then
|
||||||
|
create_cipher="`option_value -o`"
|
||||||
else
|
else
|
||||||
create_cipher=${2}
|
create_cipher=aes-cbc-essiv:sha256
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tombfile=`basename $1`
|
tombfile=`basename $1`
|
||||||
@ -662,7 +665,10 @@ create_tomb() {
|
|||||||
# make sure the file has a .tomb extension
|
# make sure the file has a .tomb extension
|
||||||
tombname=${tombfile%%\.*}
|
tombname=${tombfile%%\.*}
|
||||||
tombfile=${tombname}.tomb
|
tombfile=${tombname}.tomb
|
||||||
tombsize=$opts[-s]
|
|
||||||
|
|
||||||
|
# require the specification of the size of the tomb (-s) in MB
|
||||||
|
tombsize="`option_value -s`"
|
||||||
|
|
||||||
[ $tombsize ] || die "Size argument missing, use --size"
|
[ $tombsize ] || die "Size argument missing, use --size"
|
||||||
|
|
||||||
@ -674,16 +680,22 @@ create_tomb() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# check if the key is set manually then use the one existing
|
||||||
if option_is_set -k; then
|
if option_is_set -k; then
|
||||||
tombkey="`option_value -k`.tomb.key"
|
tombkey="`option_value -k`"
|
||||||
else
|
if [ -e "${tombkey}" ]; then
|
||||||
tombkey="${tombdir}/${tombfile}.key"
|
_message "Use an existing key to lock the new tomb:"
|
||||||
|
ls -lh ${tombkey}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -e "${tombkey}" ]; then
|
# this does a check on the file header, virtuosism by hellekin
|
||||||
_warning "tomb key already exists. Quitting."
|
# [[ `file =(awk '/^-+BEGIN/,0' $1) -bi` =~ application/pgp ]]
|
||||||
ls -lh ${tombkey}
|
if ! is_valid_key ${tombkey}; then
|
||||||
return 1
|
_warning "The key seems invalid, the application/pgp header is missing"
|
||||||
|
die "Operation aborted."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
tombkey="new" # generate it new later
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_success "Creating a new tomb in ${tombdir}/${tombfile}"
|
_success "Creating a new tomb in ${tombdir}/${tombfile}"
|
||||||
@ -751,14 +763,18 @@ create_tomb() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
_success "Setup your secret key file ${tombkey}"
|
_success "Setup your secret key file ${tombkey}"
|
||||||
|
if [ "$tombkey" = "new" ]; then
|
||||||
|
tombkey="${tombdir}/${tombfile}.key"
|
||||||
touch ${tombkey}
|
touch ${tombkey}
|
||||||
chown ${_uid}:${_gid} ${tombkey}
|
chown ${_uid}:${_gid} ${tombkey}
|
||||||
chmod 0600 ${tombkey}
|
chmod 0600 ${tombkey}
|
||||||
gen_key ${keytmp}/tomb.tmp > ${tombkey}
|
gen_key ${keytmp}/tomb.tmp > ${tombkey}
|
||||||
|
fi
|
||||||
|
|
||||||
if ! is_valid_key ${tombkey}; then
|
if ! is_valid_key ${tombkey}; then
|
||||||
_warning "The key does not seem to be valid"
|
_warning "The key does not seem to be valid"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# if [ $? != 0 ]; then
|
# if [ $? != 0 ]; then
|
||||||
# _warning "setting password failed: gnupg returns 2"
|
# _warning "setting password failed: gnupg returns 2"
|
||||||
# umount ${keytmp}
|
# umount ${keytmp}
|
||||||
@ -772,7 +788,7 @@ create_tomb() {
|
|||||||
# for security, performance and compatibility
|
# for security, performance and compatibility
|
||||||
# XXX: More for compatibility then, because xts-plain is better nowadays.
|
# XXX: More for compatibility then, because xts-plain is better nowadays.
|
||||||
cryptsetup --batch-mode \
|
cryptsetup --batch-mode \
|
||||||
--cipher ${create_cipher}:sha256 --key-size 256 \
|
--cipher ${create_cipher} --key-size 256 \
|
||||||
luksFormat ${nstloop} ${keytmp}/tomb.tmp
|
luksFormat ${nstloop} ${keytmp}/tomb.tmp
|
||||||
|
|
||||||
if ! [ $? = 0 ]; then
|
if ! [ $? = 0 ]; then
|
||||||
@ -807,6 +823,162 @@ create_tomb() {
|
|||||||
_success "Your tomb is ready in ${tombdir}/${tombfile} and secured with key ${tombkey}"
|
_success "Your tomb is ready in ${tombdir}/${tombfile} and secured with key ${tombkey}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# This is a new way to create tombs which dissects the whole create_tomb() into 3 clear steps:
|
||||||
|
# - dig a .tomb (the large file) using /dev/random (takes some minutes at least)
|
||||||
|
# - forge a .key (the small file) using /dev/urandom (good entropy needed)
|
||||||
|
# - lock the .tomb file with the key, binding the key to the tomb (requires dm_crypt format)
|
||||||
|
|
||||||
|
forge_key() {
|
||||||
|
_message "Commanded to forge key $1"
|
||||||
|
|
||||||
|
# we run as root, but remember the original uid:gid
|
||||||
|
# to set the permissions as readable for the calling user
|
||||||
|
if option_is_set -U; then _uid="`option_value -U`"; fi
|
||||||
|
if option_is_set -G; then _gid="`option_value -G`"; fi
|
||||||
|
|
||||||
|
if ! [ $1 ]; then
|
||||||
|
_warning "no key name specified for creation"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if swap is on, we remind the user about possible data leaks to disk
|
||||||
|
if ! option_is_set -f && ! option_is_set --ignore-swap; then check_swap; fi
|
||||||
|
|
||||||
|
# the encryption cipher for a tomb can be set at creation using -o
|
||||||
|
if ! option_is_set -o; then
|
||||||
|
create_cipher="`option_value -o`"
|
||||||
|
else
|
||||||
|
create_cipher=aes-cbc-essiv:sha256
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# create the keyfile in tmpfs so that we leave less traces in RAM
|
||||||
|
keytmp=`safe_dir tomb`
|
||||||
|
(( $? )) && die "error creating temp dir"
|
||||||
|
xxx "safe_dir at $keytmp"
|
||||||
|
|
||||||
|
mount tmpfs "${keytmp}" -t tmpfs -o size=1m
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
_warning "cannot mount tmpfs filesystem in volatile memory"
|
||||||
|
rm -r "${keytmp}"
|
||||||
|
die "operation aborted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
tombkey="$1"
|
||||||
|
|
||||||
|
_message "this operation takes time, keep using this computer on other tasks,"
|
||||||
|
_message "once done you will be asked to choose a password for your tomb."
|
||||||
|
_message "To make it faster you can move the mouse around."
|
||||||
|
_message "If you are on a server, you can use an Entropy Generation Daemon."
|
||||||
|
|
||||||
|
touch ${keytmp}/tomb.tmp
|
||||||
|
chmod 0600 ${keytmp}/tomb.tmp
|
||||||
|
random_source=/dev/random
|
||||||
|
if option_is_set --use-urandom; then
|
||||||
|
random_source=/dev/urandom
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $DD = "dcfldd" ]]; then
|
||||||
|
$DD bs=1 count=256 if=$random_source of=${keytmp}/tomb.tmp statusinterval=1
|
||||||
|
else
|
||||||
|
$DD bs=1 count=256 if=$random_source of=${keytmp}/tomb.tmp
|
||||||
|
fi
|
||||||
|
if ! [ -r ${keytmp}/tomb.tmp ]; then
|
||||||
|
_warning "cannot generate encryption key"
|
||||||
|
umount ${keytmp}
|
||||||
|
rm -r $keytmp
|
||||||
|
die "operation aborted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
_success "Choose the password of your key: ${tombkey}"
|
||||||
|
_message "(you can also change it later using 'tomb passwd')"
|
||||||
|
touch ${tombkey}
|
||||||
|
chown ${_uid}:${_gid} ${tombkey}
|
||||||
|
chmod 0600 ${tombkey}
|
||||||
|
|
||||||
|
tombname="$tombkey"
|
||||||
|
# the gen_key() function takes care of the new key's encryption
|
||||||
|
gen_key ${keytmp}/tomb.tmp > ${tombkey}
|
||||||
|
|
||||||
|
# this does a check on the file header, virtuosism by hellekin
|
||||||
|
# [[ `file =(awk '/^-+BEGIN/,0' $1) -bi` =~ application/pgp ]]
|
||||||
|
if ! is_valid_key ${tombkey}; then
|
||||||
|
_warning "The key does not seem to be valid"
|
||||||
|
_warning "Dumping contents to screen:"
|
||||||
|
cat ${tombkey}
|
||||||
|
_warning "--"
|
||||||
|
umount ${keytmp}
|
||||||
|
rm -r $keytmp
|
||||||
|
die "operation aborted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
${=WIPE} ${keytmp}/tomb.tmp # no need really, but anyway
|
||||||
|
umount ${keytmp}
|
||||||
|
rm -r ${keytmp}
|
||||||
|
|
||||||
|
chown ${_uid}:${_gid} ${tombkey}
|
||||||
|
|
||||||
|
_message "done forging $tombkey"
|
||||||
|
_success "Your key is ready:"
|
||||||
|
ls -lh ${tombkey}
|
||||||
|
}
|
||||||
|
|
||||||
|
# dig a tomb
|
||||||
|
dig_tomb() {
|
||||||
|
_message "Commanded to dig tomb $1"
|
||||||
|
|
||||||
|
# if swap is on, we remind the user about possible data leaks to disk
|
||||||
|
if ! option_is_set -f && ! option_is_set --ignore-swap; then check_swap; fi
|
||||||
|
|
||||||
|
if ! [ $1 ]; then
|
||||||
|
_warning "no tomb name specified for creation"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
tombfile=`basename $1`
|
||||||
|
tombdir=`dirname $1`
|
||||||
|
# make sure the file has a .tomb extension
|
||||||
|
tombname=${tombfile%%\.*}
|
||||||
|
tombfile=${tombname}.tomb
|
||||||
|
|
||||||
|
|
||||||
|
# require the specification of the size of the tomb (-s) in MB
|
||||||
|
tombsize="`option_value -s`"
|
||||||
|
|
||||||
|
[ $tombsize ] || die "Size argument missing, use --size"
|
||||||
|
|
||||||
|
[[ $tombsize != <-> ]] && die "Size argument is not an integer"
|
||||||
|
|
||||||
|
if [ -e ${tombdir}/${tombfile} ]; then
|
||||||
|
_warning "A tomb exists already. I'm not digging here:"
|
||||||
|
_warning " `ls -lh ${tombdir}/${tombfile}`"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_success "Creating a new tomb in ${tombdir}/${tombfile}"
|
||||||
|
|
||||||
|
|
||||||
|
tombsize_4k=`expr $tombsize \* 1024 / 4`
|
||||||
|
_message "Generating ${tombfile} of ${tombsize}Mb (${tombsize_4k} blocks of 4Kb)"
|
||||||
|
# we will first touch the file and set permissions: this way, even if interrupted, permissions are right
|
||||||
|
touch ${tombdir}/${tombfile}
|
||||||
|
chmod 0600 "${tombdir}/${tombfile}"
|
||||||
|
$DD if=/dev/urandom bs=4k count=${tombsize_4k} of=${tombdir}/${tombfile}
|
||||||
|
|
||||||
|
if [ $? = 0 -a -e ${tombdir}/${tombfile} ]; then
|
||||||
|
_message " `ls -lh ${tombdir}/${tombfile}`"
|
||||||
|
else
|
||||||
|
die "Error creating the tomb ${tombdir}/${tombfile}, operation aborted."
|
||||||
|
fi
|
||||||
|
|
||||||
|
_success "Done digging $tombname"
|
||||||
|
_message "your tomb is not yet ready, you need to forge a key and lock it:"
|
||||||
|
_message "tomb forge ${tombname}.tomb.key"
|
||||||
|
_message "tomb lock ${tombname}.tomb ${tombname}.tomb.key"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#internal use
|
#internal use
|
||||||
#$1 is the keyfile we are checking
|
#$1 is the keyfile we are checking
|
||||||
is_valid_key() {
|
is_valid_key() {
|
||||||
@ -846,7 +1018,7 @@ get_lukskey() {
|
|||||||
|
|
||||||
# internal use
|
# internal use
|
||||||
# $1 the lukskey to encrypt
|
# $1 the lukskey to encrypt
|
||||||
#it respects --kdf and --tomb-pwd
|
# honored options: --kdf --tomb-pwd
|
||||||
gen_key() {
|
gen_key() {
|
||||||
local lukskey=$1
|
local lukskey=$1
|
||||||
# here user is prompted for key password
|
# here user is prompted for key password
|
||||||
@ -879,7 +1051,8 @@ gen_key() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# KDF is a new key strenghtening technique against brute forcing
|
||||||
|
# see: https://github.com/dyne/Tomb/issues/82
|
||||||
_verbose "KDF method chosen is: '`option_value --kdf`'"
|
_verbose "KDF method chosen is: '`option_value --kdf`'"
|
||||||
kdf_method=$(cut -d: -f1 <<<`option_value --kdf` )
|
kdf_method=$(cut -d: -f1 <<<`option_value --kdf` )
|
||||||
case $kdf_method in
|
case $kdf_method in
|
||||||
@ -887,7 +1060,7 @@ gen_key() {
|
|||||||
if [[ -z $KDF_PBKDF2 ]]; then
|
if [[ -z $KDF_PBKDF2 ]]; then
|
||||||
die "The tomb use kdf method 'pbkdf2', which is unsupported on your system"
|
die "The tomb use kdf method 'pbkdf2', which is unsupported on your system"
|
||||||
fi
|
fi
|
||||||
#one parameter: iter time in seconds
|
# --kdf takes one parameter: iter time (on present machine) in seconds
|
||||||
seconds=$(cut -d: -f2 -s <<<`option_value --kdf`)
|
seconds=$(cut -d: -f2 -s <<<`option_value --kdf`)
|
||||||
if [[ -z $seconds ]]; then
|
if [[ -z $seconds ]]; then
|
||||||
seconds=1
|
seconds=1
|
||||||
@ -897,7 +1070,9 @@ gen_key() {
|
|||||||
_verbose "Microseconds: $microseconds"
|
_verbose "Microseconds: $microseconds"
|
||||||
pbkdf2_salt=`${KDF_PBKDF2}-gensalt`
|
pbkdf2_salt=`${KDF_PBKDF2}-gensalt`
|
||||||
pbkdf2_iter=`${KDF_PBKDF2}-getiter $microseconds`
|
pbkdf2_iter=`${KDF_PBKDF2}-getiter $microseconds`
|
||||||
tombpass=`${KDF_PBKDF2} $pbkdf2_salt $pbkdf2_iter 64 <<<"${tombpass}"` #64bytes=512bits is the key length (huge!)
|
# We use a length of 64bytes = 512bits (more than needed!?)
|
||||||
|
tombpass=`${KDF_PBKDF2} $pbkdf2_salt $pbkdf2_iter 64 <<<"${tombpass}"`
|
||||||
|
|
||||||
header="_KDF_pbkdf2sha1_${pbkdf2_salt}_${pbkdf2_iter}_64\n"
|
header="_KDF_pbkdf2sha1_${pbkdf2_salt}_${pbkdf2_iter}_64\n"
|
||||||
;;
|
;;
|
||||||
""|null)
|
""|null)
|
||||||
@ -1758,7 +1933,12 @@ main() {
|
|||||||
subcommands_opts[__default]=""
|
subcommands_opts[__default]=""
|
||||||
subcommands_opts[open]="f n -nohook=n k: -key=k U: -uid=U G: -gid=G o: -mount-options=o -ignore-swap -sudo-pwd: -tomb-pwd:"
|
subcommands_opts[open]="f n -nohook=n k: -key=k U: -uid=U G: -gid=G o: -mount-options=o -ignore-swap -sudo-pwd: -tomb-pwd:"
|
||||||
subcommands_opts[mount]=${subcommands_opts[open]}
|
subcommands_opts[mount]=${subcommands_opts[open]}
|
||||||
|
|
||||||
subcommands_opts[create]="f s: -size=s -force k: -key=k U: -uid=U G: -gid=G -ignore-swap -kdf: -sudo-pwd: -tomb-pwd: -use-urandom"
|
subcommands_opts[create]="f s: -size=s -force k: -key=k U: -uid=U G: -gid=G -ignore-swap -kdf: -sudo-pwd: -tomb-pwd: -use-urandom"
|
||||||
|
|
||||||
|
subcommands_opts[forge]="f -ignore-swap -kdf: -use-urandom U: -uid=U G: -gid=G"
|
||||||
|
subcommands_opts[dig]="f -ignore-swap s: -size=s"
|
||||||
|
|
||||||
subcommands_opts[passwd]="f -ignore-swap -kdf: -tomb-old-pwd: -tomb-pwd: "
|
subcommands_opts[passwd]="f -ignore-swap -kdf: -tomb-old-pwd: -tomb-pwd: "
|
||||||
subcommands_opts[close]="-sudo-pwd: U: -uid=U G: -gid=G"
|
subcommands_opts[close]="-sudo-pwd: U: -uid=U G: -gid=G"
|
||||||
subcommands_opts[help]=""
|
subcommands_opts[help]=""
|
||||||
@ -1864,6 +2044,16 @@ main() {
|
|||||||
check_priv
|
check_priv
|
||||||
create_tomb ${=PARAM}
|
create_tomb ${=PARAM}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
# new creation in three steps
|
||||||
|
forge)
|
||||||
|
check_priv
|
||||||
|
forge_key ${=PARAM}
|
||||||
|
;;
|
||||||
|
dig)
|
||||||
|
dig_tomb ${=PARAM}
|
||||||
|
;;
|
||||||
|
|
||||||
mount|open)
|
mount|open)
|
||||||
check_priv
|
check_priv
|
||||||
mount_tomb $PARAM[1] $PARAM[2]
|
mount_tomb $PARAM[1] $PARAM[2]
|
||||||
|
Loading…
Reference in New Issue
Block a user