mirror of
https://github.com/vgough/encfs.git
synced 2024-11-24 00:43:41 +01:00
Merge pull request #23 from rfjakob/master
Add integration tests & Compare MACs in constant time
This commit is contained in:
commit
744f56b95d
@ -206,12 +206,18 @@ ssize_t MACFileIO::readOneBlock( const IORequest &req ) const
|
||||
uint64_t mac = cipher->MAC_64( tmp.data + macBytes,
|
||||
readSize - macBytes, key );
|
||||
|
||||
// Constant time comparision to prevent timing attacks
|
||||
unsigned char fail = 0;
|
||||
for(int i=0; i<macBytes; ++i, mac >>= 8)
|
||||
{
|
||||
int test = mac & 0xff;
|
||||
int stored = tmp.data[i];
|
||||
if(test != stored)
|
||||
{
|
||||
|
||||
fail |= (test ^ stored);
|
||||
}
|
||||
|
||||
if( fail > 0 )
|
||||
{
|
||||
// uh oh..
|
||||
long blockNum = req.offset / bs;
|
||||
rWarning(_("MAC comparison failure in block %li"),
|
||||
@ -222,8 +228,6 @@ ssize_t MACFileIO::readOneBlock( const IORequest &req ) const
|
||||
throw ERROR(
|
||||
_("MAC comparison failure, refusing to read"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
37
tests/default.xml
Normal file
37
tests/default.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<!DOCTYPE boost_serialization>
|
||||
<boost_serialization signature="serialization::archive" version="10">
|
||||
<cfg class_id="0" tracking_level="0" version="20">
|
||||
<version>20100713</version>
|
||||
<creator>EncFS 1.7.5</creator>
|
||||
<cipherAlg class_id="1" tracking_level="0" version="0">
|
||||
<name>ssl/aes</name>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
</cipherAlg>
|
||||
<nameAlg>
|
||||
<name>nameio/block</name>
|
||||
<major>4</major>
|
||||
<minor>0</minor>
|
||||
</nameAlg>
|
||||
<keySize>192</keySize>
|
||||
<blockSize>1024</blockSize>
|
||||
<uniqueIV>1</uniqueIV>
|
||||
<chainedNameIV>1</chainedNameIV>
|
||||
<externalIVChaining>0</externalIVChaining>
|
||||
<blockMACBytes>0</blockMACBytes>
|
||||
<blockMACRandBytes>0</blockMACRandBytes>
|
||||
<allowHoles>1</allowHoles>
|
||||
<encodedKeySize>44</encodedKeySize>
|
||||
<encodedKeyData>
|
||||
AL2iRMLYyuf7RXcFCK0CcegQ/+enbaaqTq1OY3WULMLpcz0yvo8K4KtVw7c=
|
||||
</encodedKeyData>
|
||||
<saltLen>20</saltLen>
|
||||
<saltData>
|
||||
RVCTqJyxxp7ZN0AsLJhgpvSuUB8=
|
||||
</saltData>
|
||||
<kdfIterations>170562</kdfIterations>
|
||||
<desiredKDFDuration>500</desiredKDFDuration>
|
||||
</cfg>
|
||||
</boost_serialization>
|
||||
|
37
tests/mac.xml
Normal file
37
tests/mac.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<!DOCTYPE boost_serialization>
|
||||
<boost_serialization signature="serialization::archive" version="10">
|
||||
<cfg class_id="0" tracking_level="0" version="20">
|
||||
<version>20100713</version>
|
||||
<creator>EncFS 1.7.5</creator>
|
||||
<cipherAlg class_id="1" tracking_level="0" version="0">
|
||||
<name>ssl/aes</name>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
</cipherAlg>
|
||||
<nameAlg>
|
||||
<name>nameio/block</name>
|
||||
<major>4</major>
|
||||
<minor>0</minor>
|
||||
</nameAlg>
|
||||
<keySize>192</keySize>
|
||||
<blockSize>1024</blockSize>
|
||||
<uniqueIV>1</uniqueIV>
|
||||
<chainedNameIV>1</chainedNameIV>
|
||||
<externalIVChaining>0</externalIVChaining>
|
||||
<blockMACBytes>8</blockMACBytes>
|
||||
<blockMACRandBytes>0</blockMACRandBytes>
|
||||
<allowHoles>1</allowHoles>
|
||||
<encodedKeySize>44</encodedKeySize>
|
||||
<encodedKeyData>
|
||||
AL2iRMLYyuf7RXcFCK0CcegQ/+enbaaqTq1OY3WULMLpcz0yvo8K4KtVw7c=
|
||||
</encodedKeyData>
|
||||
<saltLen>20</saltLen>
|
||||
<saltData>
|
||||
RVCTqJyxxp7ZN0AsLJhgpvSuUB8=
|
||||
</saltData>
|
||||
<kdfIterations>170562</kdfIterations>
|
||||
<desiredKDFDuration>500</desiredKDFDuration>
|
||||
</cfg>
|
||||
</boost_serialization>
|
||||
|
109
tests/run.sh
Executable file
109
tests/run.sh
Executable file
@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This is the wrapper script for all tests.
|
||||
# It calls the unit tests and all integration tests.
|
||||
#
|
||||
# Functions that are useful in more than one integration test
|
||||
# should be defined here.
|
||||
|
||||
set -eu
|
||||
|
||||
# Set up envrionment variables, cd to the correct directory
|
||||
function init {
|
||||
|
||||
# Make sure we are in the "tests" directory
|
||||
TESTDIR=$(dirname $(realpath "$0"))
|
||||
cd $TESTDIR
|
||||
|
||||
# Full path to encfs binary
|
||||
ENCFS=$(realpath ../encfs/encfs)
|
||||
|
||||
# Directory for temporary files (scratch)
|
||||
SCRATCH=$(realpath scratch)
|
||||
LOWER=$SCRATCH/lower
|
||||
UPPER=$SCRATCH/upper
|
||||
|
||||
# Test number counter
|
||||
TESTNO=1
|
||||
|
||||
trap 'echo -e "***\e[31m test(s) FAILED\e[0m"' ERR
|
||||
}
|
||||
|
||||
# Run all test_*.sh files
|
||||
function run_cli_tests {
|
||||
|
||||
cd $TESTDIR
|
||||
for i in $(echo test_*.sh)
|
||||
do
|
||||
cleanup
|
||||
mkdir $SCRATCH
|
||||
echo "*** running $i"
|
||||
source $i
|
||||
done
|
||||
}
|
||||
|
||||
# fresh_mount CONFIG
|
||||
#
|
||||
# Mount a fresh, empty encfs filesystem using the encfs config file
|
||||
# CONFIG as .encfs6.xml. The password must be set to "a".
|
||||
# The backing files will be at $LOWER, the mounted filesystem at $UPPER.
|
||||
function fresh_mount {
|
||||
cd $TESTDIR
|
||||
fusermount -q -u $UPPER 2> /dev/null || true
|
||||
wait
|
||||
rm -Rf $LOWER $UPPER
|
||||
mkdir -p $LOWER $UPPER
|
||||
touch $UPPER/not_yet_mounted
|
||||
|
||||
cp $TESTDIR/$1 $SCRATCH/lower/.encfs6.xml
|
||||
|
||||
echo a | $ENCFS -f -S -o nonempty $LOWER $UPPER 2> /dev/null &
|
||||
while [ -e $UPPER/not_yet_mounted ]
|
||||
do
|
||||
sleep 0.1s
|
||||
done
|
||||
}
|
||||
|
||||
# Clean up scratch directory
|
||||
function cleanup {
|
||||
test -d $SCRATCH || return 0
|
||||
|
||||
cd $SCRATCH/..
|
||||
fusermount -q -u $UPPER 2> /dev/null || true
|
||||
wait
|
||||
rm -Rf $SCRATCH
|
||||
}
|
||||
|
||||
# Get the plain MD5 sum of a file, without the filename that is output
|
||||
# by md5sum
|
||||
# md5sum foo: 5f47bbbd6db883f93f5d00fd05f149ff foo
|
||||
# plain_md5 foo: 5f47bbbd6db883f93f5d00fd05f149ff
|
||||
function md5 {
|
||||
OUTPUT=$(md5sum "$1") # Capture md5sum output
|
||||
ARRAY=($OUTPUT) # Split into array
|
||||
echo ${ARRAY[0]} # Return first element
|
||||
}
|
||||
|
||||
# Indicate beginning of a test
|
||||
# Prints test number and title
|
||||
function test_begin {
|
||||
echo -n "$TESTNO $1: "
|
||||
let TESTNO++
|
||||
}
|
||||
|
||||
# Indicate successful completion of a test
|
||||
function test_ok {
|
||||
echo "OK"
|
||||
}
|
||||
|
||||
init
|
||||
|
||||
test_begin "Running unit tests"
|
||||
../encfs/test 2> /dev/null
|
||||
test_ok
|
||||
|
||||
run_cli_tests
|
||||
|
||||
echo -e "***\e[32m All tests OK\e[0m"
|
||||
|
||||
cleanup
|
31
tests/test_corruption.sh
Normal file
31
tests/test_corruption.sh
Normal file
@ -0,0 +1,31 @@
|
||||
fresh_mount default.xml
|
||||
cd $SCRATCH
|
||||
dd if=/dev/urandom of=foo bs=1M count=1 2> /dev/null
|
||||
A=$(md5 foo)
|
||||
cp foo $UPPER
|
||||
cd $UPPER
|
||||
test_begin "Reading file"
|
||||
B=$(md5 foo)
|
||||
test $A = $B
|
||||
test_ok
|
||||
|
||||
test_begin "Reading corrupted file"
|
||||
echo DEADBEEF >> $LOWER/$(ls $LOWER)
|
||||
B=$(md5 foo)
|
||||
test $A != $B
|
||||
test_ok
|
||||
|
||||
fresh_mount mac.xml
|
||||
cd $SCRATCH
|
||||
cp foo $UPPER
|
||||
cd $UPPER
|
||||
test_begin "Reading file with MAC"
|
||||
B=$(md5 foo)
|
||||
test $A = $B
|
||||
test_ok
|
||||
|
||||
test_begin "Corruption with MAC returns IO error"
|
||||
echo DEADBEEF >> $LOWER/$(ls $LOWER)
|
||||
md5 foo 2>&1 | grep "Input/output error" > /dev/null
|
||||
test_ok
|
||||
|
40
tests/test_file_expansion.sh
Normal file
40
tests/test_file_expansion.sh
Normal file
@ -0,0 +1,40 @@
|
||||
fresh_mount default.xml
|
||||
cd $UPPER
|
||||
test_begin "Creating files of different sizes: "
|
||||
for i in `seq 0 50` `seq 1000 1050`
|
||||
do
|
||||
OUTPUT=$(dd if=/dev/zero bs=$i count=1 2> /dev/null | tee $i | md5sum)
|
||||
ARRAY=($OUTPUT)
|
||||
A=${ARRAY[0]} # Remove filename
|
||||
B=$(md5 $i)
|
||||
test $A = $B
|
||||
done
|
||||
test_ok
|
||||
|
||||
test_begin "Growing file"
|
||||
rm -f ../grow
|
||||
for i in `seq 0 300`
|
||||
do
|
||||
echo -n "abcdefg" >> ../grow
|
||||
echo -n "abcdefg" >> grow
|
||||
|
||||
A=$(md5 ../grow)
|
||||
B=$(md5 grow)
|
||||
test "$A" = "$B"
|
||||
done
|
||||
test_ok
|
||||
|
||||
test_begin "Internal modification"
|
||||
dd if=/dev/urandom of=../internal bs=1M count=2 2> /dev/null
|
||||
cp ../internal internal
|
||||
for i in 0 30 1020 1200
|
||||
do
|
||||
dd if=/dev/zero of=../internal bs=1 count=1 skip=$i 2> /dev/null
|
||||
dd if=/dev/zero of=internal bs=1 count=1 skip=$i 2> /dev/null
|
||||
|
||||
A=$(md5 ../internal)
|
||||
B=$(md5 internal)
|
||||
test "$A" = "$B"
|
||||
done
|
||||
test_ok
|
||||
|
Loading…
Reference in New Issue
Block a user