mirror of
https://github.com/Llewellynvdm/Tomb.git
synced 2024-12-22 18:18:59 +00:00
Add KDF support #82
Include pbkdf2 tools inside tomb It also supports parameters (itertime).
This commit is contained in:
parent
6bb655df0b
commit
2e6a3df756
36
KEY_SPECIFICATIONS.txt
Normal file
36
KEY_SPECIFICATIONS.txt
Normal file
@ -0,0 +1,36 @@
|
||||
Overview
|
||||
=========
|
||||
|
||||
|
||||
What's a key?
|
||||
It basicly is a gpg simmetrically encrypted, ascii-armored file.
|
||||
It's encryption key is a function (see below, on KDF section) of your tomb
|
||||
passphrase.
|
||||
|
||||
|
||||
Layout
|
||||
======
|
||||
|
||||
Before coming to the gpg part, there could be some "header" lines specifying
|
||||
metatada. They're done like this:
|
||||
_FIELD_params_params_and_more_params_
|
||||
|
||||
where FIELD should be the description for the header.
|
||||
Pay much attention to the fact that there should ONLY be ASCII characters there,
|
||||
to avoid encoding issues and whatever. Needs something more? Use base64encode.
|
||||
(Of course, you're free to pack params into a single field, base64encoding
|
||||
whatever you want).
|
||||
And every header field should be in only one line.
|
||||
|
||||
KDF
|
||||
===
|
||||
|
||||
Key Derivation Functions, are functions which will make your key stronger
|
||||
spending some CPU time: the basic idea is that you have to compute that function
|
||||
just once in a while, but an attacker that wants to bruteforce has to compute it
|
||||
for every passphrase he's checking. This will make the bruteforce much more
|
||||
expensive.
|
||||
|
||||
The header line format is _KDF_$method_$params_$params_... where $method is the
|
||||
method we are using (ie: scrypt) and params is something that it needs (ie:
|
||||
salt).
|
@ -1 +1 @@
|
||||
SUBDIRS = src share doc
|
||||
SUBDIRS = src src/kdf share doc
|
||||
|
@ -89,6 +89,7 @@ dnl ---------------------------------------------------------------
|
||||
|
||||
PKG_CHECK_MODULES(GTK2, [gtk+-2.0 >= 2.16], :,
|
||||
AC_MSG_ERROR([*** Gtk+2 >=2.16 development files not found!]))
|
||||
AM_PATH_LIBGCRYPT([1.5.0], :, AC_MSG_ERROR([gcrypt development files not found]))
|
||||
AC_SUBST([GTK2_CFLAGS])
|
||||
AC_SUBST([GTK2_LIBS])
|
||||
|
||||
@ -130,6 +131,7 @@ dnl alphabetic order on dir/subdir, but Makefile sorts before everything
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
src/kdf/Makefile
|
||||
doc/Makefile
|
||||
share/Makefile
|
||||
])
|
||||
|
27
doc/tomb.1
27
doc/tomb.1
@ -111,7 +111,7 @@ the size of the new \fIfile\fR to be created, in megabytes.
|
||||
.IP "-k \fI<keyfile>\fR"
|
||||
When opening a tomb, this option can be used to specify the location
|
||||
of the key to use. Keys are created with the same name of the tomb
|
||||
file adding a '.gpg' suffix, but can be later renamed and transported
|
||||
file adding a '.key' suffix, but can be later renamed and transported
|
||||
on other media. When a key is not found, the program asks to insert a
|
||||
USB storage device and it will look for the key file inside it.
|
||||
If \fI<keyfile>\fR is "-" (dash), it will read stdin
|
||||
@ -123,6 +123,31 @@ tomb create -s 100 tombname -k /media/usb/tombname
|
||||
.EE
|
||||
to put the key on a usb pendrive
|
||||
|
||||
.B
|
||||
.IP "--kdf \fI<method>\fR"
|
||||
This will specify the KDF method to use for the tomb we're creating.
|
||||
Please note that no stable release of tomb supports KDF; if you use it,
|
||||
your tomb might be unusable with an older version of tomb.
|
||||
|
||||
You can specify parameters with --kdf=method:param. That is, for example,
|
||||
\fI--kdf=pbkdf2:2.5\fR will use pbkdf2 with an itertime of 2.5 seconds
|
||||
|
||||
Supported methods are: pbkdf2, null
|
||||
|
||||
.B pbkdf2
|
||||
is probably the most used kdf in security applications, so it's a good choice.
|
||||
It accepts one parameter, that is the seconds it will take on this computer to
|
||||
derive the key. The default is 1.
|
||||
|
||||
.B null
|
||||
is just the same as not using --kdf at all: it will stick to the "classic"
|
||||
behaviour
|
||||
|
||||
.B
|
||||
.IP "--kdf \fI<method>\fR"
|
||||
This will specify the KDF method to use for the tomb we're creating.
|
||||
Please note that no stable release of tomb supports KDF; if you use it,
|
||||
your tomb might be unusable with an older version of tomb.
|
||||
.B
|
||||
.IP "-n"
|
||||
Skip processing of post-hooks and bind-hooks if found inside the tomb.
|
||||
|
4
src/kdf/.gitignore
vendored
Normal file
4
src/kdf/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
tomb-kdf-pbkdf2
|
||||
tomb-kdf-pbkdf2-gensalt
|
||||
tomb-kdf-pbkdf2-getiter
|
||||
tomb-utils-hexencode
|
13
src/kdf/Makefile.am
Normal file
13
src/kdf/Makefile.am
Normal file
@ -0,0 +1,13 @@
|
||||
bin_PROGRAMS = tomb-kdf-pbkdf2 tomb-kdf-pbkdf2-gensalt tomb-kdf-pbkdf2-getiter hexencode
|
||||
tomb_kdf_pbkdf2_SOURCES = pbkdf2/pbkdf2.c
|
||||
tomb_kdf_pbkdf2_CFLAGS = $(LIBGCRYPT_CFLAGS)
|
||||
tomb_kdf_pbkdf2_LDADD = $(LIBGCRYPT_LIBS)
|
||||
|
||||
tomb_kdf_pbkdf2_gensalt_SOURCES = pbkdf2/gen_salt.c
|
||||
|
||||
tomb_kdf_pbkdf2_getiter_SOURCES = pbkdf2/benchmark.c
|
||||
tomb_kdf_pbkdf2_getiter_CFLAGS = $(LIBGCRYPT_CFLAGS)
|
||||
tomb_kdf_pbkdf2_getiter_LDADD = $(LIBGCRYPT_LIBS)
|
||||
|
||||
hexencode_SOURCES = hexencode.c
|
||||
|
20
src/kdf/README
Normal file
20
src/kdf/README
Normal file
@ -0,0 +1,20 @@
|
||||
PLANS
|
||||
------
|
||||
|
||||
While this can be useful for general purpose, it specially fits tomb, and it's designed for easy integration and compilation.
|
||||
|
||||
Binary name will then be:
|
||||
tomb-kdf-${algo}
|
||||
tomb-kdf-${algo}-gensalt
|
||||
tomb-kdf-${algo}-getiter
|
||||
|
||||
hexencode (or similar utils, should they be developed), go with:
|
||||
tomb-utils-hexencode
|
||||
|
||||
Base64 vs hexencode
|
||||
-------------------
|
||||
|
||||
While base64 is easier to use (shell command, more compact), pbkdf2 use hex
|
||||
in its specifications.
|
||||
This could be solved with an option (-x for hex, defaults to base64)
|
||||
|
49
src/kdf/hexencode.c
Normal file
49
src/kdf/hexencode.c
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* A simple utility that reads from stdin and output the hexencoding (on a single line) of the input
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
static int decode_mode = 0;
|
||||
int main(int argc, char *argv[]) {
|
||||
char c;
|
||||
char buf[3];
|
||||
int read_bytes;
|
||||
int opt;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"decode", no_argument, &decode_mode, 1},
|
||||
{"encode", no_argument, &decode_mode, 0},
|
||||
{0,0,0,0}
|
||||
};
|
||||
int option_index = 0;
|
||||
|
||||
while(1) {
|
||||
option_index = 0;
|
||||
opt = getopt_long(argc, argv, "", long_options, &option_index);
|
||||
if(opt == -1)
|
||||
break;
|
||||
switch(opt) {
|
||||
case 0:
|
||||
break;
|
||||
case '?':
|
||||
return 127;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if(decode_mode == 0) {
|
||||
while(( c = (char)getchar() ) != EOF)
|
||||
printf("%02x", c);
|
||||
return 0;
|
||||
} else {
|
||||
while( (read_bytes=fread(buf, sizeof(char), 2, stdin)) != 0) {
|
||||
if(read_bytes == 1) buf[1]='\0';
|
||||
sscanf(buf, "%x", &c);
|
||||
printf("%c", c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
59
src/kdf/pbkdf2/benchmark.c
Normal file
59
src/kdf/pbkdf2/benchmark.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
static long bench(int ic) {
|
||||
char *pass = "mypass";
|
||||
unsigned char *salt = "abcdefghijklmno";
|
||||
int salt_len = strlen(salt);
|
||||
int result_len = 64;
|
||||
unsigned char *result = calloc(result_len, sizeof(char));
|
||||
struct timeval start, end;
|
||||
long microtime;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
gcry_kdf_derive( pass, strlen(pass), GCRY_KDF_PBKDF2, GCRY_MD_SHA1, salt, salt_len, ic, result_len, result);
|
||||
gettimeofday(&end, NULL);
|
||||
microtime = 1000000*end.tv_sec+end.tv_usec - (1000000*start.tv_sec+start.tv_usec);
|
||||
|
||||
return (long)microtime;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
long desired_time = 1000000;
|
||||
long microtime;
|
||||
int ic=100;
|
||||
int tries=0;
|
||||
if(argc >= 2)
|
||||
sscanf(argv[1], "%ld", &desired_time);
|
||||
if (!gcry_check_version ("1.5.0")) {
|
||||
fputs ("libgcrypt version mismatch\n", stderr);
|
||||
exit (2);
|
||||
}
|
||||
/* Allocate a pool of 16k secure memory. This make the secure memory
|
||||
available and also drops privileges where needed. */
|
||||
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
|
||||
/* It is now okay to let Libgcrypt complain when there was/is
|
||||
a problem with the secure memory. */
|
||||
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
|
||||
/* Tell Libgcrypt that initialization has completed. */
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
|
||||
|
||||
microtime = bench(ic);
|
||||
while( abs(desired_time-microtime) > (desired_time/10) /*little difference */
|
||||
&& tries++ <= 5) {
|
||||
float ratio = (float)desired_time/microtime;
|
||||
if(ratio > 1000) ratio=1000.0;
|
||||
ic*=ratio;
|
||||
if(ic<1) ic=1;
|
||||
microtime = bench(ic);
|
||||
}
|
||||
printf("%d\n", ic);
|
||||
return 0;
|
||||
|
||||
}
|
39
src/kdf/pbkdf2/gen_salt.c
Normal file
39
src/kdf/pbkdf2/gen_salt.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void print_hex(unsigned char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<len;i++){
|
||||
printf("%02x", buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int len=32;
|
||||
int res;
|
||||
unsigned char *buf;
|
||||
FILE *rand;
|
||||
if(argc>=2) {
|
||||
if(sscanf(argv[1], "%d", &len) != 1) {
|
||||
fprintf(stderr, "Error: len must be an integer\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
buf = calloc(len, sizeof(char));
|
||||
memset(buf, 9, len);
|
||||
rand = fopen("/dev/random", "r");
|
||||
res = fread(buf, sizeof(char), len, rand);
|
||||
if( res != len) {
|
||||
fprintf(stderr, "Error reading /dev/random: %d != %d, \n", res, len);
|
||||
fclose(rand);
|
||||
free(buf);
|
||||
return 2;
|
||||
}
|
||||
fclose(rand);
|
||||
print_hex(buf, len);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
144
src/kdf/pbkdf2/pbkdf2.c
Normal file
144
src/kdf/pbkdf2/pbkdf2.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
** SYNOPSIS
|
||||
** echo "passphrase" | pbkdf2 salt_hex count > 48_byte_hex_key_and_iv
|
||||
**
|
||||
** DESCRIPTION
|
||||
**
|
||||
** Make the "Password-Based Key Derivation Function v2" function found in
|
||||
** the openssl library available to the command line, as it is not available
|
||||
** for use from the "openssl" command. At the time of writing the "openssl"
|
||||
** command only encrypts using the older, 'fast' pbkdf1.5 method.
|
||||
**
|
||||
** The 'salt_hex' is the salt to be used, as a hexadecimal string. Typically
|
||||
** this is 8 bytes (64 bit), and is an assigned randomly during encryption.
|
||||
**
|
||||
** The 'count' is iteration count used to make the calculation of the key
|
||||
** from the passphrase longer so as to take 1/2 to 2 seconds to generate.
|
||||
** This complexity prevents slows down brute force attacks enormously.
|
||||
**
|
||||
** The output of the above is a 48 bytes in hexadeximal, which is typically
|
||||
** used for 32 byte encryption key KEY and a 16 byte IV as needed by
|
||||
** Crypt-AES-256 (or some other encryption method).
|
||||
**
|
||||
** NOTE: While the "openssl" command can accept a hex encoded 'key' and 'iv'
|
||||
** it only does so on the command line, which is insecure. As such I
|
||||
** recommend that the output only be used with API access to the "OpenSSL"
|
||||
** cryptography libraries.
|
||||
**
|
||||
*************
|
||||
**
|
||||
** Anthony Thyssen 4 November 2009 A.Thyssen@griffith.edu.au
|
||||
**
|
||||
** Based on a test program "pkcs5.c" found on
|
||||
** http://www.mail-archive.com/openssl-users@openssl.org
|
||||
** which uses openssl to perform PBKDF2 (RFC2898) iteritive (slow) password
|
||||
** hashing.
|
||||
**
|
||||
** Build
|
||||
** gcc -o pbkdf2 pbkdf2.c -lcrypto
|
||||
**
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
/* TODO: move print_hex and hex_to_binary to utils.h, with separate compiling */
|
||||
void print_hex(unsigned char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
printf("%02x", buf[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int hex_to_binary(unsigned char *buf, char *hex)
|
||||
{
|
||||
int ret;
|
||||
int count=0;
|
||||
while(*hex) {
|
||||
if( hex[1] ) {
|
||||
ret = sscanf( hex, "%2x", (unsigned int*) buf++ );
|
||||
hex += 2;
|
||||
}
|
||||
else {
|
||||
ret = sscanf( hex++, "%1x", (unsigned int*)buf++ );
|
||||
}
|
||||
count++;
|
||||
if( ret != 1)
|
||||
return -1;
|
||||
}
|
||||
*buf = 0; // null terminate -- precaution
|
||||
return count;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *pass = NULL;
|
||||
unsigned char *salt;
|
||||
int salt_len; // salt length in bytes
|
||||
int ic=0; // iterative count
|
||||
int result_len;
|
||||
unsigned char *result; // result (binary - 32+16 chars)
|
||||
int i;
|
||||
|
||||
if ( argc != 4 ) {
|
||||
fprintf(stderr, "usage: %s salt count len <passwd >binary_key_iv\n", argv[0]);
|
||||
exit(10);
|
||||
}
|
||||
|
||||
//TODO: move to base64decode
|
||||
salt=calloc(strlen(argv[1])/2+3, sizeof(char));
|
||||
salt_len=hex_to_binary(salt, argv[1]);
|
||||
if( salt_len <= 0 ) {
|
||||
fprintf(stderr, "Error: %s is not a valid salt (it must be a hexadecimal string)\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( sscanf(argv[2], "%d", &ic) == 0 || ic<=0) {
|
||||
fprintf(stderr, "Error: count must be a positive integer\n");
|
||||
exit(1);
|
||||
}
|
||||
if( sscanf(argv[3], "%d", &result_len) == 0 || result_len<=0) {
|
||||
fprintf(stderr, "Error: result_len must be a positive integer\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fscanf(stdin, "%ms", &pass);
|
||||
if ( pass[strlen(pass)-1] == '\n' )
|
||||
pass[strlen(pass)-1] = '\0';
|
||||
|
||||
// PBKDF 2
|
||||
result = calloc(result_len, sizeof(unsigned char*));
|
||||
if (!gcry_check_version ("1.5.0")) {
|
||||
fputs ("libgcrypt version mismatch\n", stderr);
|
||||
exit (2);
|
||||
}
|
||||
/* Allocate a pool of 16k secure memory. This make the secure memory
|
||||
available and also drops privileges where needed. */
|
||||
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
|
||||
/* It is now okay to let Libgcrypt complain when there was/is
|
||||
a problem with the secure memory. */
|
||||
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
|
||||
/* Tell Libgcrypt that initialization has completed. */
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
|
||||
gcry_kdf_derive( pass, strlen(pass), GCRY_KDF_PBKDF2, GCRY_MD_SHA1, salt, salt_len, ic, result_len, result);
|
||||
print_hex(result, result_len); // Key + IV (as hex string)
|
||||
|
||||
//clear and free everything
|
||||
for(i=0; i<result_len;i++)
|
||||
result[i]=0;
|
||||
free(result);
|
||||
for(i=0; i<strlen(pass); i++) //blank
|
||||
pass[i]=0;
|
||||
free(pass);
|
||||
for(i=0; i<strlen(argv[1])/2+3; i++) //blank
|
||||
salt[i]=0;
|
||||
free(salt);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* vim: set noexpandtab ts=4 sw=4: */
|
22
src/kdf/test.sh
Normal file
22
src/kdf/test.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
error=0
|
||||
while read line; do
|
||||
pass=`cut -f1 <<<$line`
|
||||
salt=`cut -f2 <<<$line`
|
||||
iter=`cut -f3 <<<$line`
|
||||
keylen=`cut -f4 <<<$line`
|
||||
expected=`cut -f5 <<<$line`
|
||||
hexsalt=`cut -f6 <<<$line`
|
||||
#TODO: check!
|
||||
derived=`./pbkdf2 $hexsalt $iter $keylen <<<$pass`
|
||||
if [[ $derived != $expected ]]; then
|
||||
echo ./pbkdf2 $hexsalt $iter $keylen "<<<$pass"
|
||||
echo "Expected $expected, got $derived" >&2
|
||||
error=$((error + 1))
|
||||
fi
|
||||
done < test.txt
|
||||
|
||||
if [[ $error == 1 ]]; then
|
||||
exit $error
|
||||
fi
|
BIN
src/kdf/test.txt
Normal file
BIN
src/kdf/test.txt
Normal file
Binary file not shown.
125
src/tomb
125
src/tomb
@ -166,6 +166,17 @@ check_bin() {
|
||||
# resize suite check bin!
|
||||
which e2fsck > /dev/null || die "Cannot find e2fsck. Please install it." 1
|
||||
which resize2fs > /dev/null || die "Cannot find resize2fs. Please install it." 1
|
||||
|
||||
if which tomb-kdf-pbkdf2 &> /dev/null; then
|
||||
KDF_PBKDF2="tomb-kdf-pbkdf2"
|
||||
else
|
||||
local our_pbkdf2
|
||||
our_pbkdf2="$(dirname $(readlink -f $TOMBEXEC))/kdf/tomb-kdf-pbkdf2"
|
||||
if which $our_pbkdf2 &> /dev/null; then
|
||||
KDF_PBKDF2=$our_pbkdf2
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# }}}
|
||||
@ -732,15 +743,15 @@ create_tomb() {
|
||||
|
||||
# here user is prompted for key password
|
||||
for c in 1 2 3; do
|
||||
# 3 tries to write two times a matching password
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Secure key for ${tombname}"`
|
||||
tombpasstmp=$tombpass
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Secure key for ${tombname} (again)"`
|
||||
if [ "$tombpasstmp" = "$tombpass" ]; then
|
||||
break;
|
||||
fi
|
||||
unset tombpasstmp
|
||||
unset tombpass
|
||||
# 3 tries to write two times a matching password
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Secure key for ${tombname}"`
|
||||
tombpasstmp=$tombpass
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Secure key for ${tombname} (again)"`
|
||||
if [ "$tombpasstmp" = "$tombpass" ]; then
|
||||
break;
|
||||
fi
|
||||
unset tombpasstmp
|
||||
unset tombpass
|
||||
done
|
||||
|
||||
if [ -z $tombpass ]; then
|
||||
@ -751,9 +762,36 @@ create_tomb() {
|
||||
fi
|
||||
|
||||
|
||||
gpg \
|
||||
--openpgp --batch --no-options --no-tty --passphrase-fd 0 2>/dev/null \
|
||||
-o "${tombkey}" -c -a ${keytmp}/tomb.tmp <<< ${tombpass}
|
||||
_verbose "KDF method chosen is: '`option_value --kdf`'"
|
||||
kdf_method=$(cut -d: -f1 <<<`option_value --kdf` )
|
||||
case $kdf_method in
|
||||
pbkdf2)
|
||||
#one parameter: iter time in seconds
|
||||
seconds=$(cut -d: -f2 -s <<<`option_value --kdf`)
|
||||
if [[ -z $seconds ]]; then
|
||||
seconds=1
|
||||
fi
|
||||
local -i microseconds
|
||||
microseconds=$((seconds*1000000))
|
||||
_verbose "Microseconds: $microseconds"
|
||||
pbkdf2_salt=`${KDF_PBKDF2}-gensalt`
|
||||
pbkdf2_iter=`${KDF_PBKDF2}-getiter $microseconds`
|
||||
tombpass=`${KDF_PBKDF2} $pbkdf2_salt $pbkdf2_iter 64 <<<${tombpass}` #64bytes=512bits is the key length (huge!)
|
||||
header="_KDF_pbkdf2sha1_${pbkdf2_salt}_${pbkdf2_iter}_64\n"
|
||||
;;
|
||||
""|null)
|
||||
|
||||
header=""
|
||||
;;
|
||||
*)
|
||||
_warning "KDF method non recognized"
|
||||
return 1
|
||||
header=""
|
||||
;;
|
||||
esac
|
||||
( echo -n $header; gpg \
|
||||
--openpgp --batch --no-options --no-tty --passphrase-fd 0 2>/dev/null \
|
||||
-o - -c -a ${keytmp}/tomb.tmp <<< ${tombpass} ) > $tombkey
|
||||
|
||||
unset tombpass
|
||||
chown ${_uid}:${_gid} ${tombkey}
|
||||
@ -924,31 +962,46 @@ mount_tomb() {
|
||||
|
||||
_warning "Password is required for key ${keyname}"
|
||||
for c in 1 2 3; do
|
||||
if [ $c = 1 ]; then
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb ${keyname}"`
|
||||
else
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb $keyname (retry $c)"`
|
||||
fi
|
||||
(gpg --batch --passphrase-fd 0 --no-tty --no-options \
|
||||
-d "${tombkey}" 2> /dev/null <<< ${tombpass} ) \
|
||||
| cryptsetup --key-file - luksOpen ${nstloop} ${mapper}
|
||||
unset tombpass
|
||||
if [ $c = 1 ]; then
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb ${keyname}"`
|
||||
else
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb $keyname (retry $c)"`
|
||||
fi
|
||||
#TODO: read the first line: if it looks like a KDF, do KDF
|
||||
firstline=`head -n1 < $tombkey`
|
||||
if [[ $firstline =~ '^_KDF_' ]]; then
|
||||
_verbose "KDF: `cut -d_ -f 3 <<<$firstline`"
|
||||
case `cut -d_ -f 3 <<<$firstline` in
|
||||
pbkdf2sha1)
|
||||
pbkdf2_param=`cut -d_ -f 4- <<<$firstline | tr '_' ' '`
|
||||
tombpass=$(${KDF_PBKDF2} ${=pbkdf2_param} 2> /dev/null <<<$tombpass)
|
||||
;;
|
||||
*)
|
||||
_failure "No suitable program for KDF `cut -f 3 <<<$firstline`"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
(gpg --batch --passphrase-fd 0 --no-tty --no-options \
|
||||
-d "${tombkey}" 2> /dev/null <<< ${tombpass} ) \
|
||||
| cryptsetup --key-file - luksOpen ${nstloop} ${mapper}
|
||||
unset tombpass
|
||||
|
||||
# if key was from stdin delete temp file and dir
|
||||
if [ $tombkeydir ]; then
|
||||
${=WIPE} ${tombkey}
|
||||
rmdir $tombkeydir
|
||||
fi
|
||||
# if key was from stdin delete temp file and dir
|
||||
if [ $tombkeydir ]; then
|
||||
${=WIPE} ${tombkey}
|
||||
rmdir $tombkeydir
|
||||
fi
|
||||
|
||||
# if key was from stdin delete temp file and dir
|
||||
if [ $tombkeydir ]; then
|
||||
${WIPE[@]} ${tombkey}
|
||||
rmdir $tombkeydir
|
||||
fi
|
||||
# if key was from stdin delete temp file and dir
|
||||
if [ $tombkeydir ]; then
|
||||
${WIPE[@]} ${tombkey}
|
||||
rmdir $tombkeydir
|
||||
fi
|
||||
|
||||
if [ -r /dev/mapper/${mapper} ]; then
|
||||
break; # password was correct
|
||||
fi
|
||||
if [ -r /dev/mapper/${mapper} ]; then
|
||||
break; # password was correct
|
||||
fi
|
||||
done
|
||||
|
||||
if ! [ -r /dev/mapper/${mapper} ]; then
|
||||
@ -1679,7 +1732,7 @@ main() {
|
||||
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"
|
||||
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"
|
||||
subcommands_opts[create]="f s: -size=s -force k: -key=k U: -uid=U G: -gid=G -ignore-swap -kdf:"
|
||||
subcommands_opts[passwd]="f -ignore-swap"
|
||||
subcommands_opts[close]=""
|
||||
subcommands_opts[help]=""
|
||||
@ -1756,7 +1809,7 @@ main() {
|
||||
continue #it shouldnt be appended to PARAM
|
||||
elif [[ $arg[1] == '-' ]]; then
|
||||
if [[ $ok == 0 ]]; then
|
||||
die "unrecognized option $arg" 127
|
||||
die "unrecognized option $arg for subcommand $subcommand" 127
|
||||
fi
|
||||
fi
|
||||
PARAM+=$arg
|
||||
|
Loading…
Reference in New Issue
Block a user