mirror of
https://github.com/Llewellynvdm/Tomb.git
synced 2024-11-05 21:07:58 +00:00
Merge pull request #308 from AitorATuin/kdf_input
Fixes a problem reading passwords when using the kdf wrapper
This commit is contained in:
commit
e8919af867
@ -20,4 +20,5 @@ before_script:
|
|||||||
- sudo make --directory=extras/kdf-keys install
|
- sudo make --directory=extras/kdf-keys install
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
- make --directory=extras/kdf-keys test
|
||||||
- make test
|
- make test
|
||||||
|
@ -7,6 +7,10 @@ all:
|
|||||||
$(CC) -O2 -o tomb-kdb-pbkdf2-gensalt gen_salt.c -lgcrypt
|
$(CC) -O2 -o tomb-kdb-pbkdf2-gensalt gen_salt.c -lgcrypt
|
||||||
$(CC) -O2 -o tomb-kdb-hexencode hexencode.c
|
$(CC) -O2 -o tomb-kdb-hexencode hexencode.c
|
||||||
|
|
||||||
|
test:
|
||||||
|
@echo "Running Tomb-kdb tests"
|
||||||
|
./test.sh
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f tomb-kdb-pbkdf2 tomb-kdb-pbkdf2-getiter tomb-kdb-pbkdf2-gensalt tomb-kdb-hexencode
|
rm -f tomb-kdb-pbkdf2 tomb-kdb-pbkdf2-getiter tomb-kdb-pbkdf2-gensalt tomb-kdb-hexencode
|
||||||
|
|
||||||
|
@ -43,6 +43,9 @@
|
|||||||
|
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
|
|
||||||
|
/* block size for password buffer */
|
||||||
|
#define BLOCK_SIZE 40
|
||||||
|
|
||||||
/* TODO: move print_hex and hex_to_binary to utils.h, with separate compiling */
|
/* TODO: move print_hex and hex_to_binary to utils.h, with separate compiling */
|
||||||
void print_hex(unsigned char *buf, int len)
|
void print_hex(unsigned char *buf, int len)
|
||||||
{
|
{
|
||||||
@ -73,15 +76,37 @@ int hex_to_binary(unsigned char *buf, char *hex)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cleanup(char *result, int result_len, char *pass, char *salt, int salt_len) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
//clear and free everything
|
||||||
|
if (result) {
|
||||||
|
for(i=0; i<result_len;i++)
|
||||||
|
result[i]=0;
|
||||||
|
free(result);
|
||||||
|
}
|
||||||
|
if (pass) {
|
||||||
|
for(i=0; i<strlen(pass); i++) //blank
|
||||||
|
pass[i]=0;
|
||||||
|
free(pass);
|
||||||
|
}
|
||||||
|
if (salt) {
|
||||||
|
for(i=0; i<salt_len; i++) //blank
|
||||||
|
salt[i]=0;
|
||||||
|
free(salt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *pass = NULL;
|
char *pass = NULL;
|
||||||
unsigned char *salt;
|
unsigned char *salt = NULL;
|
||||||
int salt_len; // salt length in bytes
|
int salt_len; // salt length in bytes
|
||||||
int ic=0; // iterative count
|
int ic=0; // iterative count
|
||||||
int result_len;
|
int result_len;
|
||||||
unsigned char *result; // result (binary - 32+16 chars)
|
unsigned char *result = NULL; // result (binary - 32+16 chars)
|
||||||
int i;
|
int i, pw_len = 0;
|
||||||
|
int buff_len = BLOCK_SIZE;
|
||||||
|
|
||||||
if ( argc != 4 ) {
|
if ( argc != 4 ) {
|
||||||
fprintf(stderr, "usage: %s salt count len <passwd >binary_key_iv\n", argv[0]);
|
fprintf(stderr, "usage: %s salt count len <passwd >binary_key_iv\n", argv[0]);
|
||||||
@ -89,7 +114,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: move to base64decode
|
//TODO: move to base64decode
|
||||||
salt=calloc(strlen(argv[1])/2+3, sizeof(char));
|
salt_len = strlen(argv[1])/2+3;
|
||||||
|
salt = calloc(salt_len, sizeof(char));
|
||||||
salt_len=hex_to_binary(salt, argv[1]);
|
salt_len=hex_to_binary(salt, argv[1]);
|
||||||
if( salt_len <= 0 ) {
|
if( salt_len <= 0 ) {
|
||||||
fprintf(stderr, "Error: %s is not a valid salt (it must be a hexadecimal string)\n", argv[1]);
|
fprintf(stderr, "Error: %s is not a valid salt (it must be a hexadecimal string)\n", argv[1]);
|
||||||
@ -105,14 +131,41 @@ int main(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fscanf(stdin, "%ms", &pass);
|
/* Read password char by char.
|
||||||
if ( pass[strlen(pass)-1] == '\n' )
|
*
|
||||||
pass[strlen(pass)-1] = '\0';
|
* Doing in this way we make sure that blanks (even null bytes) end up
|
||||||
|
* in the password.
|
||||||
|
*
|
||||||
|
* passwords containing just a bunch of spaces are valid
|
||||||
|
*/
|
||||||
|
pass = calloc(buff_len, sizeof(char));
|
||||||
|
char c = getchar();
|
||||||
|
while (c != EOF) {
|
||||||
|
if (pw_len == buff_len) {
|
||||||
|
buff_len *= 2;
|
||||||
|
pass = realloc(pass, buff_len);
|
||||||
|
if (!pass) {
|
||||||
|
fprintf(stderr, "Error allocating memory");
|
||||||
|
cleanup(result, result_len, pass, salt, salt_len);
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pass[pw_len] = c;
|
||||||
|
pw_len++;
|
||||||
|
c = getchar();
|
||||||
|
}
|
||||||
|
if (pw_len <= 1) {
|
||||||
|
fprintf(stderr, "Error: password is empty\n");
|
||||||
|
cleanup(result, result_len, pass, salt, salt_len);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
pass[pw_len-1] = '\0';
|
||||||
|
|
||||||
// PBKDF 2
|
// PBKDF 2
|
||||||
result = calloc(result_len, sizeof(unsigned char*));
|
result = calloc(result_len, sizeof(unsigned char*));
|
||||||
if (!gcry_check_version ("1.5.0")) {
|
if (!gcry_check_version ("1.5.0")) {
|
||||||
fputs ("libgcrypt version mismatch\n", stderr);
|
fputs ("libgcrypt version mismatch\n", stderr);
|
||||||
|
cleanup(result, result_len, pass, salt, salt_len);
|
||||||
exit (2);
|
exit (2);
|
||||||
}
|
}
|
||||||
/* Allocate a pool of 16k secure memory. This make the secure memory
|
/* Allocate a pool of 16k secure memory. This make the secure memory
|
||||||
@ -124,19 +177,10 @@ int main(int argc, char *argv[])
|
|||||||
/* Tell Libgcrypt that initialization has completed. */
|
/* Tell Libgcrypt that initialization has completed. */
|
||||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
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);
|
gcry_kdf_derive(pass, pw_len-1, GCRY_KDF_PBKDF2, GCRY_MD_SHA1, salt, salt_len, ic, result_len, result);
|
||||||
print_hex(result, result_len); // Key + IV (as hex string)
|
print_hex(result, result_len); // Key + IV (as hex string)
|
||||||
|
|
||||||
//clear and free everything
|
cleanup(result, result_len, pass, salt, salt_len);
|
||||||
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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
72
extras/kdf-keys/test.sh
Normal file → Executable file
72
extras/kdf-keys/test.sh
Normal file → Executable file
@ -1,21 +1,65 @@
|
|||||||
#!/usr/bin/env zsh
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
error=0
|
error=0
|
||||||
while read line; do
|
|
||||||
pass=`cut -f1 <<<$line`
|
check_kdf() {
|
||||||
salt=`cut -f2 <<<$line`
|
while read line; do
|
||||||
iter=`cut -f3 <<<$line`
|
pass=`cut -f1 <<<$line`
|
||||||
keylen=`cut -f4 <<<$line`
|
salt=`cut -f2 <<<$line`
|
||||||
expected=`cut -f5 <<<$line`
|
iter=`cut -f3 <<<$line`
|
||||||
hexsalt=`cut -f6 <<<$line`
|
keylen=`cut -f4 <<<$line`
|
||||||
#TODO: check!
|
expected=`cut -f5 <<<$line`
|
||||||
derived=`./pbkdf2 $hexsalt $iter $keylen <<<$pass`
|
hexsalt=`cut -f6 <<<$line`
|
||||||
if [[ $derived != $expected ]]; then
|
#TODO: check!
|
||||||
echo ./pbkdf2 $hexsalt $iter $keylen "<<<$pass"
|
derived=`./tomb-kdb-pbkdf2 $hexsalt $iter $keylen <<<$pass`
|
||||||
echo "Expected $expected, got $derived" >&2
|
if [[ $derived != $expected ]]; then
|
||||||
|
echo "Expected $expected, got $derived" >&2
|
||||||
|
error=$((error + 1))
|
||||||
|
fi
|
||||||
|
done < test.txt
|
||||||
|
}
|
||||||
|
|
||||||
|
check_white_spaces() {
|
||||||
|
hexsalt="73616c74"
|
||||||
|
iter=4096
|
||||||
|
keylen=20
|
||||||
|
typeset -a results
|
||||||
|
passwords=('one two three' 'one two' 'one')
|
||||||
|
for pwd in $passwords; do
|
||||||
|
results+=`./tomb-kdb-pbkdf2 $hexsalt $iter $keylen <<<$pwd`
|
||||||
|
done
|
||||||
|
for ((i=1;i<=3;i++)); do
|
||||||
|
d1=$results[$i]
|
||||||
|
i1=$passwords[$i]
|
||||||
|
for ((j=(($i+1));j<=3;j++)); do
|
||||||
|
d2=$results[$j]
|
||||||
|
i2=$passwords[$j]
|
||||||
|
if [[ $d1 == $d2 ]]; then
|
||||||
|
echo "Inputs \"$i1\" and \"$i2\" produce the same output $d1" >&2
|
||||||
|
error=$((error + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
check_password_len() {
|
||||||
|
hexsalt="73616c74"
|
||||||
|
iter=4096
|
||||||
|
keylen=20
|
||||||
|
./tomb-kdb-pbkdf2 $hexsalt $iter $keylen 2>/dev/null <<<"" && {
|
||||||
|
echo "Empty passwords are accepted"
|
||||||
error=$((error + 1))
|
error=$((error + 1))
|
||||||
fi
|
}
|
||||||
done < test.txt
|
bigpassword=`perl -e 'print "a"x3000'`
|
||||||
|
./tomb-kdb-pbkdf2 $hexsalt $iter $keylen &>/dev/null <<<"$bigpassword" || {
|
||||||
|
echo "Error when using long password"
|
||||||
|
error=$((error + 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_kdf
|
||||||
|
check_white_spaces
|
||||||
|
check_password_len
|
||||||
|
|
||||||
if [[ $error == 1 ]]; then
|
if [[ $error == 1 ]]; then
|
||||||
exit $error
|
exit $error
|
||||||
|
Loading…
Reference in New Issue
Block a user