Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: axeld/driveencryption
base: 887479d03f
...
head fork: axeld/driveencryption
compare: ba6e60a5db
  • 13 commits
  • 18 files changed
  • 0 commit comments
  • 1 contributor
7 .gitignore
View
@@ -0,0 +1,7 @@
+bin/encrypted_drive_control
+driver/encrypted_drive
+gui/DriveEncryption
+lib/libcrypt.a
+login/Login
+test/crypt_test
+*/objects.*
18 bin/makefile
View
@@ -24,23 +24,23 @@ TYPE= APP
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
-SRCS= encrypted_drive_control.cpp random.cpp
+SRCS= encrypted_drive_control.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
-RSRCS=
+RSRCS=
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
-#
+#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
-LIBS=
+LIBS= ../lib/libcrypt.a
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
@@ -48,7 +48,7 @@ LIBS=
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
-LIBPATHS=
+LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
@@ -62,23 +62,23 @@ LOCAL_INCLUDE_PATHS = ../headers/
# specify the level of optimization that you desire
# NONE, SOME, FULL
-OPTIMIZE=
+OPTIMIZE=
# specify any preprocessor symbols to be defined. The symbols
# will be set to a value of 1. For example specify DEBUG if you want
# DEBUG=1 to be set when compiling.
-DEFINES=
+DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
-WARNINGS =
+WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
-SYMBOLS =
+SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from
84 bin/random.cpp
View
@@ -1,84 +0,0 @@
-/*
- * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
- * Distributed under the terms of the MIT License.
- */
-
-
-#include "random.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <OS.h>
-
-
-static uint32
-hash_string(const char *string)
-{
- uint32 hash = 0;
- char c;
-
- // we assume hash to be at least 32 bits
- while ((c = *string++) != 0) {
- hash ^= hash >> 28;
- hash <<= 4;
- hash ^= c;
- }
-
- return hash;
-}
-
-
-void
-fill_random_buffer(uint8* buffer, uint32 size)
-{
- // TODO: have some better number generator!
- char hostname[256];
- gethostname(hostname, sizeof(hostname));
- char user[256];
- strncpy(user, getlogin(), sizeof(user));
- uint32 base = hash_string(hostname) ^ hash_string(user);
- system_info systemInfo;
-
- for (uint32 i = 0; i < size; i++) {
- switch (i & 255) {
- case 0:
- get_system_info(&systemInfo);
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages);
- break;
- case 32:
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages
- ^ systemInfo.used_teams);
- break;
- case 64:
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages
- ^ systemInfo.used_ports);
- break;
- case 96:
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages
- ^ systemInfo.used_threads);
- break;
- case 128:
- get_system_info(&systemInfo);
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages
- ^ systemInfo.boot_time);
- break;
- case 160:
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages
- ^ systemInfo.page_faults);
- break;
- case 192:
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages
- ^ systemInfo.used_sems);
- break;
- case 224:
- srand((uint32)system_time() ^ base ^ systemInfo.used_pages
- ^ (uint32)systemInfo.cpu_clock_speed);
- break;
- }
- buffer[i] = rand() % 255;
- }
-}
-
14 bin/random.h
View
@@ -1,14 +0,0 @@
-/*
- * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
- * Distributed under the terms of the MIT License.
- */
-#ifndef RANDOM_H
-#define RANDOM_H
-
-
-#include <SupportDefs.h>
-
-
-void fill_random_buffer(uint8* buffer, uint32 size);
-
-#endif // RANDOM_H
300 driver/encrypted_drive.cpp
View
@@ -9,7 +9,11 @@
#include "encrypted_drive.h"
+
#include "encrypted_drive_icon.h"
+#include "crypt.h"
+
+#include <util/AutoLock.h>
#include <fcntl.h>
#include <errno.h>
@@ -19,8 +23,6 @@
#include <string.h>
#include <unistd.h>
-#include "crypt.h"
-
//#define TRACE_DRIVER
#ifdef TRACE_DRIVER
@@ -56,7 +58,6 @@ static struct benaphore {
thread_id owner;
int32 nesting;
} sDriverLock;
-static uint8 sBuffer[65536];
typedef struct device_info {
int32 open_count;
@@ -67,8 +68,14 @@ typedef struct device_info {
char file[B_PATH_NAME_LENGTH];
const char* device_path;
device_geometry geometry;
+ mutex lock;
} device_info;
+struct open_cookie {
+ int32 device_index;
+ uint8 buffer[65536];
+};
+
#define kDeviceCount 11
#define kDataDeviceCount (kDeviceCount - 1)
#define kControlDevice (kDeviceCount - 1)
@@ -77,31 +84,8 @@ struct device_info gDeviceInfos[kDeviceCount];
static int32 gRegistrationCount = 0;
static int gControlDeviceFD = -1;
-
-
-static void
-lock_driver()
-{
- thread_id thread = find_thread(NULL);
- if (sDriverLock.owner != thread) {
- if (atomic_add(&sDriverLock.count, -1) <= 0)
- acquire_sem(sDriverLock.sem);
- sDriverLock.owner = thread;
- }
- sDriverLock.nesting++;
-}
-
-
-static void
-unlock_driver()
-{
- thread_id thread = find_thread(NULL);
- if (sDriverLock.owner == thread && --sDriverLock.nesting == 0) {
- sDriverLock.owner = -1;
- if (atomic_add(&sDriverLock.count, 1) < 0)
- release_sem(sDriverLock.sem);
- }
-}
+static Worker sWorker;
+static recursive_lock sLock;
static inline bool
@@ -135,7 +119,7 @@ clear_device_info(int32 index)
{
TRACE(("encrypted_drive: clear_device_info(%ld)\n", index));
- device_info &info = gDeviceInfos[index];
+ device_info& info = gDeviceInfos[index];
info.open_count = 0;
info.fd = -1;
info.unused = (index != kDeviceCount - 1);
@@ -159,10 +143,7 @@ init_device_info(int32 index, encrypted_drive_info *initInfo, bool initialize)
return B_BAD_VALUE;
bool readOnly = initInfo->read_only;
- mode_t mode = readOnly ? O_RDONLY : O_RDWR;
-#ifdef __HAIKU__
- mode |= O_NOCACHE;
-#endif
+ mode_t mode = O_NOCACHE | (readOnly ? O_RDONLY : O_RDWR);
// open the file
int fd = open(initInfo->file_name, mode);
@@ -170,10 +151,7 @@ init_device_info(int32 index, encrypted_drive_info *initInfo, bool initialize)
// try again with read-only
initInfo->read_only = true;
readOnly = true;
- mode = O_RDONLY;
-#ifdef __HAIKU__
- mode |= O_NOCACHE;
-#endif
+ mode = O_RDONLY | O_NOCACHE;
fd = open(initInfo->file_name, mode);
}
if (fd < 0)
@@ -219,23 +197,6 @@ init_device_info(int32 index, encrypted_drive_info *initInfo, bool initialize)
if (error == B_OK && S_ISREG(stat.st_mode)) {
// Disable caching for underlying file! (else this driver will deadlock)
// We probably cannot resize the file once the cache has been disabled!
-
-#ifndef __HAIKU__
- // This applies to BeOS only:
- // Work around a bug in BFS: the file is not synced before the cache is
- // turned off, and thus causing possible inconsistencies.
- // Unfortunately, this only solves one half of the issue; there is
- // no way to remove the blocks in the cache, so changes made to the
- // image have the chance to get lost.
- fsync(fd);
-
- // This is a special reserved ioctl() opcode not defined anywhere in
- // the Be headers.
- if (ioctl(fd, 10000) != 0) {
- dprintf("encrypted_drive: disable caching ioctl failed\n");
- return errno;
- }
-#endif
}
if (error < B_OK) {
@@ -253,6 +214,8 @@ init_device_info(int32 index, encrypted_drive_info *initInfo, bool initialize)
info.registered = true;
strcpy(info.file, initInfo->file_name);
info.device_path = sDeviceName[index];
+ mutex_init(&info.lock, "encrypted device");
+
// open_count doesn't have to be changed here
// (encrypted_drive_open() will do that for us)
@@ -273,6 +236,7 @@ uninit_device_info(int32 index)
return B_BAD_VALUE;
close(info.fd);
+ mutex_destroy(&info.lock);
clear_device_info(index);
return B_OK;
}
@@ -340,10 +304,11 @@ init_driver(void)
{
TRACE(("encrypted_drive: init\n"));
- sDriverLock.sem = create_sem(0, "encrypted_drive lock");
- sDriverLock.count = 1;
- sDriverLock.owner = -1;
- sDriverLock.nesting = 0;
+ recursive_lock_init(&sLock, "encrypted_drive lock");
+
+ new(&sWorker) Worker();
+ sWorker.Init();
+ init_crypt();
// init the device infos
for (int32 i = 0; i < kDeviceCount; i++) {
@@ -359,12 +324,16 @@ void
uninit_driver(void)
{
TRACE(("encrypted_drive: uninit\n"));
- delete_sem(sDriverLock.sem);
// uninit the device infos
for (int32 i = 0; i < kDeviceCount; i++) {
gDeviceInfos[i].context.~VolumeCryptContext();
}
+
+ uninit_crypt();
+ sWorker.~Worker();
+
+ recursive_lock_destroy(&sLock);
}
@@ -388,88 +357,98 @@ find_device(const char* name)
static status_t
-encrypted_drive_open(const char *name, uint32 flags, void **cookie)
+encrypted_drive_open(const char* name, uint32 flags, void** _cookie)
{
- TRACE(("encrypted_drive: open %s\n",name));
+ TRACE(("encrypted_drive: open %s\n", name));
- *cookie = (void *)-1;
+ RecursiveLocker locker(sLock);
- lock_driver();
+ int32 deviceIndex = dev_index_for_path(name);
+ open_cookie* cookie;
- int32 devIndex = dev_index_for_path(name);
+ TRACE(("encrypted_drive: deviceIndex %ld!\n", deviceIndex));
- TRACE(("encrypted_drive: devIndex %ld!\n", devIndex));
-
- if (!is_valid_device_index(devIndex)) {
+ if (!is_valid_device_index(deviceIndex)) {
TRACE(("encrypted_drive: wrong index!\n"));
- unlock_driver();
- return B_ERROR;
+ return B_BAD_VALUE;
}
- if (gDeviceInfos[devIndex].unused) {
+ if (gDeviceInfos[deviceIndex].unused) {
TRACE(("encrypted_drive: device is unused!\n"));
- unlock_driver();
- return B_ERROR;
+ return B_NO_INIT;
}
- if (!gDeviceInfos[devIndex].registered) {
+ if (!gDeviceInfos[deviceIndex].registered) {
TRACE(("encrypted_drive: device has been unregistered!\n"));
- unlock_driver();
- return B_ERROR;
+ return B_NOT_ALLOWED;
}
- // store index in cookie
- *cookie = (void *)devIndex;
+ cookie = new(std::nothrow) open_cookie();
+ if (cookie == NULL)
+ return B_NO_MEMORY;
+
+ cookie->device_index = deviceIndex;
+ *_cookie = cookie;
- if (devIndex != kControlDevice)
- gDeviceInfos[devIndex].open_count++;
+ if (deviceIndex != kControlDevice)
+ gDeviceInfos[deviceIndex].open_count++;
- unlock_driver();
return B_OK;
}
static status_t
-encrypted_drive_close(void *cookie)
+encrypted_drive_close(void* _cookie)
{
- int32 devIndex = (int)cookie;
+ open_cookie* cookie = (open_cookie*)_cookie;
+ int32 deviceIndex = cookie->device_index;
- TRACE(("encrypted_drive: close() devIndex = %ld\n", devIndex));
- if (!is_valid_data_device_index(devIndex))
+ TRACE(("encrypted_drive: close() deviceIndex = %ld\n", deviceIndex));
+ if (!is_valid_data_device_index(deviceIndex))
return B_OK;
- lock_driver();
+ RecursiveLocker locker(sLock);
- gDeviceInfos[devIndex].open_count--;
- if (gDeviceInfos[devIndex].open_count == 0
- && !gDeviceInfos[devIndex].registered) {
- // The last FD is closed and the device has been unregistered. Free its info.
- uninit_device_info(devIndex);
+ gDeviceInfos[deviceIndex].open_count--;
+ if (gDeviceInfos[deviceIndex].open_count == 0
+ && !gDeviceInfos[deviceIndex].registered) {
+ // The last FD is closed and the device has been unregistered.
+ // Free its info.
+ uninit_device_info(deviceIndex);
}
- unlock_driver();
+ return B_OK;
+}
+
+static status_t
+encrypted_drive_free(void* _cookie)
+{
+ TRACE(("encrypted_drive: free cookie()\n"));
+ delete (open_cookie*)_cookie;
return B_OK;
}
static status_t
-encrypted_drive_read(void *cookie, off_t position, void *buffer,
- size_t *numBytes)
+encrypted_drive_read(void* _cookie, off_t position, void* buffer,
+ size_t* numBytes)
{
- TRACE(("encrypted_drive: read pos = 0x%08Lx, bytes = 0x%08lx\n", position, *numBytes));
+ TRACE(("encrypted_drive: read pos = 0x%08Lx, bytes = 0x%08lx\n", position,
+ *numBytes));
// check parameters
- int devIndex = (int)cookie;
- if (devIndex == kControlDevice) {
+ open_cookie* cookie = (open_cookie*)_cookie;
+ int32 deviceIndex = cookie->device_index;
+ if (deviceIndex == kControlDevice) {
TRACE(("encrypted_drive: reading from control device not allowed\n"));
return B_NOT_ALLOWED;
}
if (position < 0)
return B_BAD_VALUE;
- lock_driver();
- device_info &info = gDeviceInfos[devIndex];
+ device_info& info = gDeviceInfos[deviceIndex];
+ MutexLocker locker(info.lock);
// adjust position and numBytes according to the file size
if (position > info.context.Size())
@@ -481,56 +460,75 @@ encrypted_drive_read(void *cookie, off_t position, void *buffer,
// We use the block number as part of the decryption mechanism,
// so we have to make sure any access is block aligned.
dprintf("TODO read partial!\n");
- unlock_driver();
- return -1;
+ return B_NOT_SUPPORTED;
}
position += info.context.Offset();
- // read
status_t error = B_OK;
- ssize_t bytesRead = read_pos(info.fd, position, buffer, *numBytes);
- if (bytesRead < 0)
- error = errno;
- else
- *numBytes = bytesRead;
+ size_t bytesLeft = *numBytes;
+ while (bytesLeft > 0) {
+ size_t bytes = min_c(bytesLeft, sizeof(cookie->buffer));
- info.context.DecryptBlock((uint8*)buffer, bytesRead,
- position / info.geometry.bytes_per_sector);
+ ssize_t bytesRead = read_pos(info.fd, position, cookie->buffer,
+ bytes);
+ if (bytesRead < 0) {
+ error = errno;
+ break;
+ }
+
+ DecryptTask task(info.context, cookie->buffer, bytesRead,
+ position / BLOCK_SIZE);
+ TRACE(("decrypt %d: %p, %" B_PRIuSIZE ", index %" B_PRIu64 "\n",
+ find_thread(NULL), cookie->buffer, bytesRead,
+ position / BLOCK_SIZE));
+ sWorker.AddTask(task);
+ sWorker.WaitFor(task);
+
+ if (user_memcpy(buffer, cookie->buffer, bytesRead) != B_OK) {
+ error = B_BAD_ADDRESS;
+ break;
+ }
+
+ buffer = (void*)((uint8*)buffer + bytesRead);
+ bytesLeft -= bytesRead;
+ position += bytesRead;
+ }
+
+ if (bytesLeft > 0)
+ *numBytes -= bytesLeft;
- unlock_driver();
return error;
}
static status_t
-encrypted_drive_write(void *cookie, off_t position, const void *buffer,
- size_t *numBytes)
+encrypted_drive_write(void* _cookie, off_t position, const void* buffer,
+ size_t* numBytes)
{
TRACE(("encrypted_drive: write pos = 0x%08Lx, bytes = 0x%08lx\n", position, *numBytes));
// check parameters
- int devIndex = (int)cookie;
- if (devIndex == kControlDevice) {
+ open_cookie* cookie = (open_cookie*)_cookie;
+ int32 deviceIndex = cookie->device_index;
+ if (deviceIndex == kControlDevice) {
TRACE(("encrypted_drive: writing to control device not allowed\n"));
return B_NOT_ALLOWED;
}
if (position < 0)
return B_BAD_VALUE;
- lock_driver();
- device_info &info = gDeviceInfos[devIndex];
+ device_info &info = gDeviceInfos[deviceIndex];
+ MutexLocker locker(info.lock);
- if (info.geometry.read_only) {
- unlock_driver();
+ if (info.geometry.read_only)
return B_READ_ONLY_DEVICE;
- }
+
if (position % info.geometry.bytes_per_sector != 0) {
// We use the block number as part of the decryption mechanism,
// so we have to make sure any access is block aligned.
dprintf("TODO write partial!\n");
- unlock_driver();
- return -1;
+ return B_NOT_SUPPORTED;
}
// adjust position and numBytes according to the file size
@@ -543,41 +541,50 @@ encrypted_drive_write(void *cookie, off_t position, const void *buffer,
size_t bytesLeft = *numBytes;
status_t error = B_OK;
- for (uint32 i = 0; bytesLeft > 0; i++) {
- size_t bytes = min_c(bytesLeft, sizeof(sBuffer));
- memcpy(sBuffer, buffer, bytes);
+ while (bytesLeft > 0) {
+ size_t bytes = min_c(bytesLeft, sizeof(cookie->buffer));
+ if (user_memcpy(cookie->buffer, buffer, bytes) != B_OK) {
+ error = B_BAD_ADDRESS;
+ break;
+ }
- info.context.EncryptBlock(sBuffer, bytes,
- position / info.geometry.bytes_per_sector);
+ EncryptTask task(info.context, cookie->buffer, bytes,
+ position / BLOCK_SIZE);
+ TRACE(("encrypt %d: %p, %" B_PRIuSIZE ", index %" B_PRIu64 "\n",
+ find_thread(NULL), cookie->buffer, bytes,
+ position / BLOCK_SIZE));
+ sWorker.AddTask(task);
+ sWorker.WaitFor(task);
- ssize_t bytesWritten = write_pos(info.fd, position, sBuffer, bytes);
+ ssize_t bytesWritten = write_pos(info.fd, position, cookie->buffer,
+ bytes);
if (bytesWritten < 0) {
error = errno;
break;
- } else {
- buffer = (const void*)((const uint8*)buffer + bytes);
- bytesLeft -= bytes;
- position += bytes;
}
+
+ buffer = (const void*)((const uint8*)buffer + bytes);
+ bytesLeft -= bytes;
+ position += bytes;
}
if (bytesLeft > 0)
*numBytes -= bytesLeft;
- unlock_driver();
return error;
}
static status_t
-encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
+encrypted_drive_control(void* _cookie, uint32 op, void* arg, size_t length)
{
TRACE(("encrypted_drive: ioctl\n"));
- int devIndex = (int)cookie;
- device_info &info = gDeviceInfos[devIndex];
+ open_cookie* cookie = (open_cookie*)_cookie;
+ int32 deviceIndex = cookie->device_index;
+ device_info& info = gDeviceInfos[deviceIndex];
- if (devIndex == kControlDevice || info.unused) {
+ if (deviceIndex == kControlDevice || info.unused) {
// control device or unused data device
switch (op) {
case B_GET_DEVICE_SIZE:
@@ -609,7 +616,7 @@ encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
TRACE(("encrypted_drive: ENCRYPTED_DRIVE_REGISTER_FILE\n"));
encrypted_drive_info *driveInfo = (encrypted_drive_info *)arg;
- if (devIndex != kControlDevice || driveInfo == NULL
+ if (deviceIndex != kControlDevice || driveInfo == NULL
|| driveInfo->magic != ENCRYPTED_DRIVE_MAGIC
|| driveInfo->drive_info_size != sizeof(encrypted_drive_info)
|| driveInfo->key_length > 0 && driveInfo->key == NULL)
@@ -618,7 +625,7 @@ encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
status_t error = B_ERROR;
int32 i;
- lock_driver();
+ RecursiveLocker locker(sLock);
// first, look if we already have opened that file and see
// if it's available to us which happens when it has been
@@ -666,14 +673,13 @@ encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
}
}
- unlock_driver();
return error;
}
case ENCRYPTED_DRIVE_ENCRYPT_BUFFER:
{
encrypted_drive_info* driveInfo = (encrypted_drive_info*)arg;
- if (devIndex != kControlDevice || driveInfo == NULL
+ if (deviceIndex != kControlDevice || driveInfo == NULL
|| driveInfo->magic != ENCRYPTED_DRIVE_MAGIC
|| driveInfo->drive_info_size != sizeof(encrypted_drive_info)
|| driveInfo->key_length > 0 && driveInfo->key == NULL)
@@ -684,7 +690,7 @@ encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
case ENCRYPTED_DRIVE_DECRYPT_BUFFER:
{
encrypted_drive_info* driveInfo = (encrypted_drive_info*)arg;
- if (devIndex != kControlDevice || driveInfo == NULL
+ if (deviceIndex != kControlDevice || driveInfo == NULL
|| driveInfo->magic != ENCRYPTED_DRIVE_MAGIC
|| driveInfo->drive_info_size != sizeof(encrypted_drive_info)
|| driveInfo->key_length > 0 && driveInfo->key == NULL)
@@ -783,16 +789,15 @@ encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
case ENCRYPTED_DRIVE_UNREGISTER_FILE:
{
TRACE(("encrypted_drive: ENCRYPTED_DRIVE_UNREGISTER_FILE\n"));
- lock_driver();
+ RecursiveLocker locker(sLock);
bool wasRegistered = info.registered;
-
info.registered = false;
if (info.open_count == 0) {
// The device is not used anymore, we can uninitialize
// it now
- uninit_device_info(devIndex);
+ uninit_device_info(deviceIndex);
}
// on the last unregistration we need to close the
@@ -802,7 +807,6 @@ encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
gControlDeviceFD = -1;
}
- unlock_driver();
return B_OK;
}
case ENCRYPTED_DRIVE_GET_INFO:
@@ -832,14 +836,6 @@ encrypted_drive_control(void *cookie, uint32 op, void *arg, size_t len)
}
-static status_t
-encrypted_drive_free(void *cookie)
-{
- TRACE(("encrypted_drive: free cookie()\n"));
- return B_OK;
-}
-
-
device_hooks sDeviceHooks = {
encrypted_drive_open,
encrypted_drive_close,
18 gui/makefile
View
@@ -26,23 +26,23 @@ TYPE= APP
# in folder names do not work well with this makefile.
SRCS= DriveEncryption.cpp DriveWindow.cpp ColumnListView.cpp ColumnTypes.cpp \
PasswordWindow.cpp ChangePasswordWindow.cpp FileSizeWindow.cpp \
- mount_support.cpp random.cpp
+ mount_support.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
-RSRCS=
+RSRCS=
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
-#
+#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
-LIBS= be tracker
+LIBS= ../lib/libcrypt.a be tracker
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
@@ -50,7 +50,7 @@ LIBS= be tracker
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
-LIBPATHS=
+LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
@@ -64,7 +64,7 @@ LOCAL_INCLUDE_PATHS = ../headers/
# specify the level of optimization that you desire
# NONE, SOME, FULL
-OPTIMIZE=
+OPTIMIZE=
# specify any preprocessor symbols to be defined. The symbols
# will be set to a value of 1. For example specify DEBUG if you want
@@ -75,17 +75,17 @@ DEFINES= _ZETA_TS_FIND_DIR_
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
-WARNINGS =
+WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
-SYMBOLS =
+SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from
# a source-level debugger
-DEBUGGER =
+DEBUGGER =
# specify additional compiler flags for all files
COMPILER_FLAGS =
20 headers/Worker.h
View
@@ -24,10 +24,22 @@ class Job {
class Task : public DoublyLinkedListLinkImpl<Task> {
public:
- Task() {}
- virtual ~Task() {}
+ Task();
+ virtual ~Task();
- virtual Job* NextJob() = 0;
+ Job* NextJob();
+
+ void JobDone(Job* job);
+ void Wait();
+
+protected:
+ virtual Job* CreateNextJob() = 0;
+
+private:
+ mutex fLock;
+ ConditionVariable fFinishCondition;
+ vint32 fPending;
+ bool fFinished;
};
typedef DoublyLinkedList<Task> TaskList;
@@ -42,7 +54,7 @@ class Worker {
int32 CountThreads() const { return fThreadCount; }
void AddTask(Task& task);
- void Wait();
+ void WaitFor(Task& task);
private:
static status_t _Worker(void* self);
14 headers/crypt.h
View
@@ -37,10 +37,6 @@ class CryptContext {
encryption_mode modeType, const uint8* key, size_t keyLength);
status_t SetKey(const uint8* key, size_t keyLength);
- ThreadContext* ThreadContexts() const { return fThreadContexts; }
- int32 CountThreadContexts() const;
- EncryptionMode* Mode() const { return fMode; }
-
void DecryptBlock(uint8 *buffer, size_t length, uint64 blockIndex);
void EncryptBlock(uint8 *buffer, size_t length, uint64 blockIndex);
@@ -50,9 +46,12 @@ class CryptContext {
protected:
void _Uninit();
+protected:
+ friend class CryptTask;
+
EncryptionAlgorithm* fAlgorithm;
EncryptionMode* fMode;
- ThreadContext* fThreadContexts;
+ ThreadContext** fThreadContexts;
};
class VolumeCryptContext : public CryptContext {
@@ -85,14 +84,13 @@ class CryptTask : public Task {
uint64 blockIndex);
virtual ~CryptTask() {}
- virtual Job* NextJob();
-
- EncryptionMode* Mode() { return fContext.Mode(); }
+ EncryptionMode* Mode() { return fContext.fMode; }
bool IsDone() const { return fLength == 0; }
void Put(ThreadContext* threadContext);
protected:
+ virtual Job* CreateNextJob();
virtual CryptJob* CreateJob() = 0;
private:
0  gui/random.h → headers/random.h
View
File renamed without changes
123 lib/Worker.cpp
View
@@ -11,12 +11,77 @@
#include <new>
+Task::Task()
+ :
+ fFinished(false),
+ fPending(0)
+{
+ mutex_init(&fLock, "task");
+ fFinishCondition.Init(this, "task finished");
+}
+
+
+Task::~Task()
+{
+ mutex_destroy(&fLock);
+}
+
+
+Job*
+Task::NextJob()
+{
+ Job* job = CreateNextJob();
+
+ MutexLocker locker(fLock);
+ if (job == NULL) {
+ fFinished = true;
+ if (fPending == 0)
+ fFinishCondition.NotifyOne();
+ } else
+ fPending++;
+
+ return job;
+}
+
+
+void
+Task::JobDone(Job* job)
+{
+ MutexLocker locker(fLock);
+
+ if (--fPending == 0 && fFinished)
+ fFinishCondition.NotifyOne();
+}
+
+
+void
+Task::Wait()
+{
+ while (true) {
+ MutexLocker locker(fLock);
+
+ if (fFinished && !fPending)
+ return;
+
+ ConditionVariableEntry entry;
+ fFinishCondition.Add(&entry);
+ locker.Unlock();
+
+ entry.Wait();
+ }
+}
+
+
+// #pragma mark -
+
+
Worker::Worker()
:
fThreads(NULL),
fThreadCount(0)
{
mutex_init(&fLock, "worker");
+ MutexLocker t(fLock);
fCondition.Init(this, "work wait");
system_info info;
@@ -29,7 +94,16 @@ Worker::Worker()
Worker::~Worker()
{
- delete[] fThreads;
+ fCondition.NotifyAll(false, B_ERROR);
+ mutex_destroy(&fLock);
+
+ if (fThreads != NULL) {
+ for (int32 i = 0; i < fThreadCount; i++) {
+ wait_for_thread(fThreads[i], NULL);
+ }
+
+ delete[] fThreads;
+ }
}
@@ -62,9 +136,10 @@ Worker::AddTask(Task& task)
void
-Worker::Wait()
+Worker::WaitFor(Task& task)
{
- _Worker();
+ _Work();
+ task.Wait();
}
@@ -81,13 +156,17 @@ Worker::_Worker()
{
while (true) {
MutexLocker locker(fLock);
- ConditionVariableEntry entry;
- fCondition.Add(&entry);
- locker.Unlock();
- status_t status = entry.Wait();
- if (status != B_OK)
- break;
+ if (fTasks.IsEmpty()) {
+ ConditionVariableEntry entry;
+ fCondition.Add(&entry);
+ locker.Unlock();
+
+ status_t status = entry.Wait();
+ if (status != B_OK)
+ break;
+ } else
+ locker.Unlock();
_Work();
}
@@ -97,22 +176,22 @@ Worker::_Worker()
void
Worker::_Work()
{
- MutexLocker locker(fLock);
+ while (true) {
+ MutexLocker locker(fLock);
- Task* task = fTasks.First();
- if (task == NULL)
- return;
+ Task* task = fTasks.First();
+ if (task == NULL)
+ return;
+
+ Job* job = task->NextJob();
+ if (job == NULL) {
+ fTasks.Remove(task);
+ return;
+ }
- Job* job = task->NextJob();
- if (job == NULL) {
- fTasks.Remove(task);
locker.Unlock();
- delete task;
- return;
+ job->Do();
+ task->JobDone(job);
}
-
- locker.Unlock();
-
- job->Do();
}
4 lib/crc32.c
View
@@ -47,8 +47,9 @@ static const uint32 kCRC32Tab[] = {
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
+
uint32
-crc32(uint8 *data, int32 length)
+crc32(const uint8* data, int32 length)
{
uint32 crc = 0xffffffff;
@@ -58,4 +59,3 @@ crc32(uint8 *data, int32 length)
return crc ^ 0xffffffff;
}
-
4 lib/crc32.h
View
@@ -14,6 +14,4 @@
#ifdef __cplusplus
extern "C"
#endif
-uint32 crc32(uint8 *data, int32 length);
-//unsigned __int32 crc32int (unsigned __int32 *data);
-//BOOL crc32_selftests (void);
+uint32 crc32(const uint8* data, int32 length);
143 lib/crypt.cpp
View
@@ -22,12 +22,20 @@
#include <errno.h>
#include <new>
+#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+//#define TRACE_CRYPT
+#ifdef TRACE_CRYPT
+# define TRACE(...) dprintf(__VA_ARGS__)
+#else
+# define TRACE(...) ;
+#endif
+
const uint32 kTrueCryptMagic = 'TRUE';
#define DISK_KEY_SIZE 64
@@ -41,15 +49,18 @@ struct true_crypt_header {
uint16 version;
uint16 required_program_version;
uint32 crc_checksum;
- uint64 volume_creation_time;
- uint64 header_creation_time;
+ uint8 _reserved1[16];
uint64 hidden_size;
// v4 fields
uint64 volume_size;
uint64 encrypted_offset;
uint64 encrypted_size;
+ uint32 flags;
+ // v5
+ uint32 block_size;
- uint8 _reserved[132];
+ uint8 _reserved2[120];
+ uint32 header_crc_checksum;
uint8 disk_key[256];
uint32 Magic() const
@@ -60,6 +71,8 @@ struct true_crypt_header {
{ return B_BENDIAN_TO_HOST_INT16(required_program_version); }
uint32 CrcChecksum() const
{ return B_BENDIAN_TO_HOST_INT32(crc_checksum); }
+ uint32 HeaderCrcChecksum() const
+ { return B_BENDIAN_TO_HOST_INT32(header_crc_checksum); }
uint64 HiddenSize() const
{ return B_BENDIAN_TO_HOST_INT64(hidden_size); }
uint64 VolumeSize() const
@@ -68,6 +81,10 @@ struct true_crypt_header {
{ return B_BENDIAN_TO_HOST_INT64(encrypted_offset); }
uint64 EncryptedSize() const
{ return B_BENDIAN_TO_HOST_INT64(encrypted_size); }
+ uint32 Flags() const
+ { return B_BENDIAN_TO_HOST_INT32(flags); }
+ uint32 BlockSize() const
+ { return B_BENDIAN_TO_HOST_INT32(block_size); }
} _PACKED;
@@ -77,8 +94,8 @@ class ThreadContext {
ThreadContext(const ThreadContext& context);
~ThreadContext();
- int32 AddBuffer(size_t size);
- void* BufferFor(int32 index);
+ ssize_t AddBuffer(size_t size);
+ void* BufferFor(int32 offset);
void Reset();
ThreadContext& operator=(const ThreadContext& other);
@@ -261,6 +278,9 @@ class DecryptJob : public CryptJob {
virtual void Do()
{
+ TRACE(" %d: decrypt %p, %" B_PRIuSIZE ", index %" B_PRIu64
+ ", context %p\n", find_thread(NULL), fData, fLength, fBlockIndex,
+ fThreadContext);
fTask->Mode()->DecryptBlock(*fThreadContext, fData, fLength,
fBlockIndex);
Done();
@@ -275,6 +295,9 @@ class EncryptJob : public CryptJob {
virtual void Do()
{
+ TRACE(" %d: encrypt %p, %" B_PRIuSIZE ", index %" B_PRIu64
+ ", context %p\n", find_thread(NULL), fData, fLength, fBlockIndex,
+ fThreadContext);
fTask->Mode()->EncryptBlock(*fThreadContext, fData, fLength,
fBlockIndex);
Done();
@@ -436,23 +459,33 @@ dump_true_crypt_header(true_crypt_header& header)
dprintf("required program version: %x\n", header.RequiredProgramVersion());
dprintf("crc checksum: %lu (%lu)\n", header.CrcChecksum(),
crc32(header.disk_key, 256));
- dprintf("volume creation time: %lld\n", header.volume_creation_time);
- dprintf("header creation time: %lld\n", header.header_creation_time);
dprintf("hidden size: %lld\n", header.HiddenSize());
if (header.Version() >= 4) {
dprintf("volume size: %lld\n", header.VolumeSize());
dprintf("encrypted offset: %lld\n", header.EncryptedOffset());
dprintf("encrypted size: %lld\n", header.EncryptedSize());
+ dprintf("flags: %lx\n", header.Flags());
+ dprintf("header crc checksum: %lx\n", header.HeaderCrcChecksum());
}
+ if (header.Version() >= 5)
+ dprintf("block size: %lx\n", header.BlockSize());
}
static bool
valid_true_crypt_header(true_crypt_header& header)
{
- return header.Magic() == kTrueCryptMagic
- && header.CrcChecksum() == crc32(header.disk_key, 256);
+ if (header.Magic() != kTrueCryptMagic)
+ return false;
+ if (header.CrcChecksum() != crc32(header.disk_key, 256))
+ return false;
+
+ if (header.Version() >= 0x4
+ && header.HeaderCrcChecksum() != crc32((uint8*)&header, 188))
+ return false;
+
+ return true;
}
@@ -532,7 +565,7 @@ ThreadContext::~ThreadContext()
}
-int32
+ssize_t
ThreadContext::AddBuffer(size_t size)
{
if (size == 0)
@@ -562,9 +595,9 @@ ThreadContext::AddBuffer(size_t size)
void*
-ThreadContext::BufferFor(int32 index)
+ThreadContext::BufferFor(int32 offset)
{
- return (void*)((uint8*)fBuffer + index);
+ return (void*)((uint8*)fBuffer + offset);
}
@@ -1159,6 +1192,13 @@ CryptContext::CryptContext()
CryptContext::~CryptContext()
{
+ if (fThreadContexts != NULL) {
+ for (int32 i = 0; i < sThreadCount; i++) {
+ delete fThreadContexts[i];
+ }
+
+ delete[] fThreadContexts;
+ }
}
@@ -1186,10 +1226,14 @@ CryptContext::Init(encryption_algorithm algorithm, encryption_mode mode,
if (status != B_OK)
return status;
- fThreadContexts = new(std::nothrow) ThreadContext(threadContext);
+ fThreadContexts = new(std::nothrow) ThreadContext*[sThreadCount];
if (fThreadContexts == NULL)
return B_NO_MEMORY;
+ for (int32 i = 0; i < sThreadCount; i++) {
+ fThreadContexts[i] = new ThreadContext(threadContext);
+ }
+
return SetKey(key, keyLength);
}
@@ -1197,47 +1241,45 @@ CryptContext::Init(encryption_algorithm algorithm, encryption_mode mode,
status_t
CryptContext::SetKey(const uint8* key, size_t keyLength)
{
- status_t status = fAlgorithm->SetCompleteKey(*fThreadContexts, key,
- keyLength);
- if (status == B_OK)
- status = fMode->SetCompleteKey(*fThreadContexts, key, keyLength);
-
- return status;
-}
+ for (int32 i = 0; i < sThreadCount; i++) {
+ status_t status = fAlgorithm->SetCompleteKey(*fThreadContexts[i], key,
+ keyLength);
+ if (status == B_OK)
+ status = fMode->SetCompleteKey(*fThreadContexts[i], key, keyLength);
+ if (status != B_OK)
+ return status;
+ }
-int32
-CryptContext::CountThreadContexts() const
-{
- return sThreadCount;
+ return B_OK;
}
void
CryptContext::DecryptBlock(uint8 *buffer, size_t length, uint64 blockIndex)
{
- fMode->DecryptBlock(*fThreadContexts, buffer, length, blockIndex);
+ fMode->DecryptBlock(*(fThreadContexts[0]), buffer, length, blockIndex);
}
void
CryptContext::EncryptBlock(uint8 *buffer, size_t length, uint64 blockIndex)
{
- fMode->EncryptBlock(*fThreadContexts, buffer, length, blockIndex);
+ fMode->EncryptBlock(*(fThreadContexts[0]), buffer, length, blockIndex);
}
void
CryptContext::Decrypt(uint8 *buffer, size_t length)
{
- fMode->Decrypt(*fThreadContexts, buffer, length);
+ fMode->Decrypt(*(fThreadContexts[0]), buffer, length);
}
void
CryptContext::Encrypt(uint8 *buffer, size_t length)
{
- fMode->Encrypt(*fThreadContexts, buffer, length);
+ fMode->Encrypt(*(fThreadContexts[0]), buffer, length);
}
@@ -1291,8 +1333,8 @@ VolumeCryptContext::Setup(int fd, const uint8* key, uint32 keyLength,
if (status < B_OK)
return status;
- fOffset = BLOCK_SIZE;
- fSize = size - BLOCK_SIZE;
+ fOffset = max_c(4096, BLOCK_SIZE);
+ fSize = size - fOffset;
fHidden = false;
const uint8* salt = random;
@@ -1304,15 +1346,17 @@ VolumeCryptContext::Setup(int fd, const uint8* key, uint32 keyLength,
true_crypt_header& header = *(true_crypt_header*)&buffer[PKCS5_SALT_SIZE];
header.magic = B_HOST_TO_BENDIAN_INT32(kTrueCryptMagic);
- header.version = B_HOST_TO_BENDIAN_INT16(0x2);
- header.required_program_version = B_HOST_TO_BENDIAN_INT16(0x410);
- header.volume_creation_time
- = B_HOST_TO_BENDIAN_INT64(real_time_clock_usecs());
- header.header_creation_time
- = B_HOST_TO_BENDIAN_INT64(real_time_clock_usecs());
+ header.version = B_HOST_TO_BENDIAN_INT16(0x4);
+ header.required_program_version = B_HOST_TO_BENDIAN_INT16(0x600);
+ header.volume_size = B_HOST_TO_BENDIAN_INT64(fOffset + fSize);
+ header.encrypted_offset = B_HOST_TO_BENDIAN_INT64(fOffset);
+ header.encrypted_size = B_HOST_TO_BENDIAN_INT64(fSize);
+ header.flags = 0;
memcpy(header.disk_key, random, sizeof(header.disk_key));
random += sizeof(header.disk_key);
header.crc_checksum = B_HOST_TO_BENDIAN_INT32(crc32(header.disk_key, 256));
+ header.header_crc_checksum
+ = B_HOST_TO_BENDIAN_INT32(crc32((uint8*)&header, 188));
// use key + salt to encrypt the header, and write it to disk
@@ -1365,6 +1409,8 @@ VolumeCryptContext::_Detect(int fd, off_t offset, off_t size, const uint8* key,
Decrypt((uint8*)&header, sizeof(true_crypt_header));
if (!valid_true_crypt_header(header)) {
+ dump_true_crypt_header(header);
+
// Try with legacy encryption mode LRW instead
status = Init(ALGORITHM_AES, MODE_LRW, diskKey, DISK_KEY_SIZE);
if (status != B_OK)
@@ -1380,7 +1426,11 @@ VolumeCryptContext::_Detect(int fd, off_t offset, off_t size, const uint8* key,
}
}
- dump_true_crypt_header(header);
+ if (header.RequiredProgramVersion() >= 0x700) {
+ // TODO: test if the block size is really not 512 bytes
+ dprintf("header version not yet supported!\n");
+ return B_NOT_SUPPORTED;
+ }
// then init context with the keys from the unencrypted header
@@ -1425,7 +1475,7 @@ CryptTask::CryptTask(CryptContext& context, uint8* data, size_t length,
Job*
-CryptTask::NextJob()
+CryptTask::CreateNextJob()
{
if (IsDone())
return NULL;
@@ -1439,9 +1489,8 @@ CryptTask::NextJob()
void
CryptTask::Put(ThreadContext* threadContext)
{
- size_t count = fContext.CountThreadContexts();
- for (int32 i = 0; i < count; i++) {
- if (&fContext.ThreadContexts()[i] == threadContext) {
+ for (int32 i = 0; i < sThreadCount; i++) {
+ if (fContext.fThreadContexts[i] == threadContext) {
atomic_and(&fUsedThreadContexts, ~(1L << i));
break;
}
@@ -1452,9 +1501,10 @@ CryptTask::Put(ThreadContext* threadContext)
void
CryptTask::_PrepareJob(CryptJob* job)
{
- job->SetTo(this, _Get(), fData, fJobLength, fBlockIndex);
- fData += fJobLength;
- fLength -= fJobLength;
+ size_t bytes = min_c(fJobLength, fLength);
+ job->SetTo(this, _Get(), fData, bytes, fBlockIndex);
+ fData += bytes;
+ fLength -= bytes;
fBlockIndex += fJobLength / BLOCK_SIZE;
}
@@ -1462,12 +1512,11 @@ CryptTask::_PrepareJob(CryptJob* job)
ThreadContext*
CryptTask::_Get()
{
- size_t count = fContext.CountThreadContexts();
- for (int32 i = 0; i < count; i++) {
+ for (int32 i = 0; i < sThreadCount; i++) {
int32 bit = 1L << i;
if ((fUsedThreadContexts & bit) == 0) {
fUsedThreadContexts |= bit;
- return &fContext.ThreadContexts()[i];
+ return fContext.fThreadContexts[i];
}
}
4 lib/makefile
View
@@ -7,7 +7,7 @@
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
-NAME= libcrypt.a
+NAME= libcrypt
# specify the type of binary
# APP: Application
@@ -25,7 +25,7 @@ TYPE= STATIC
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
SRCS= crypt.cpp ripemd160.c gf_mul.c aescrypt.c \
- aeskey.c aestab.c crc32.c Worker.cpp
+ aeskey.c aestab.c crc32.c Worker.cpp random.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
0  gui/random.cpp → lib/random.cpp
View
File renamed without changes
15 makefile
View
@@ -5,7 +5,22 @@ default install:
@cd bin; make -f makefile $@
@cd gui; make -f makefile $@
@cd login; make -f makefile $@
+ @cd test; make -f makefile $@
+lib:
+ @cd lib; make -f makefile
+driver:
+ @cd driver; make -f makefile
+bin:
+ @cd bin; make -f makefile
+gui:
+ @cd gui; make -f makefile
+login:
+ @cd login; make -f makefile
+test:
+ @cd test; make -f makefile
+
+.PHONY : lib driver bin gui login test
# Sets some attributes on the "Read Me" and install-encryption.sh files
# from SVN properties.
94 test/crypt_test.cpp
View
@@ -1,17 +1,23 @@
/*
- * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
+ * Copyright 2009-2012, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include "crypt.h"
+#include "random.h"
+
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+const size_t kTestSize = 65536*1024;
+const size_t kBufferSize = 65536;
+
+
extern "C" void
dprintf(const char *format,...)
{
@@ -30,7 +36,7 @@ dump_block(const char *buffer, int size, const char *prefix)
{
const int DUMPED_BLOCK_SIZE = 16;
int i;
-
+
for (i = 0; i < size;) {
int start = i;
@@ -68,23 +74,91 @@ main(int argc, char** argv)
if (argc < 3)
return 1;
- int fd = open(argv[1], O_RDONLY);
+ bool initialize = argc > 3 && !strcmp(argv[3], "init");
+
+ int fd = open(argv[1], initialize ? O_RDWR : O_RDONLY);
if (fd < 0)
return 1;
+ uint8* key = (uint8*)argv[2];
+ size_t keyLength = strlen(argv[2]);
+
+ init_crypt();
+
+ Worker worker;
+ worker.Init();
+
VolumeCryptContext context;
+ status_t status;
- status_t status = context.Detect(fd, (uint8*)argv[2],
- strlen(argv[2]));
- printf("detect: %s\n", strerror(status));
+ uint8* block = (uint8*)malloc(kBufferSize);
+ if (block == NULL)
+ return 1;
+
+ if (initialize) {
+ // generate random data to be used as salt and AES keys
+ uint8 random[2048];
+ fill_random_buffer(random, sizeof(random));
+
+ status = context.Setup(fd, key, keyLength, random, sizeof(random));
+ printf("setup: %s\n", strerror(status));
+
+ if (status == B_OK) {
+ // write test data
+ for (int i = 0; i < kBufferSize; i++)
+ block[i] = i % 256;
+
+ off_t offset = context.Offset();
+ size_t written = 0;
+ while (written < kTestSize) {
+ size_t toWrite = min_c(kBufferSize, kTestSize - written);
+
+// context.EncryptBlock(block, toWrite, offset / BLOCK_SIZE);
+ EncryptTask task(context, block, toWrite, offset / BLOCK_SIZE);
+ worker.AddTask(task);
+ worker.WaitFor(task);
+ write_pos(fd, offset, block, toWrite);
+
+ written += toWrite;
+ offset += toWrite;
+ }
+ }
+ } else {
+ status = context.Detect(fd, key, keyLength);
+ printf("detect: %s, offset %lld\n", strerror(status), context.Offset());
+ }
if (status == B_OK) {
- uint8 block[512];
- read_pos(fd, context.Offset(), block, 512);
- context.DecryptBlock(block, 512, context.Offset() / 512);
+ off_t offset = context.Offset();
+ size_t totalBytesRead = 0;
+ while (totalBytesRead < kTestSize) {
+ size_t toRead = min_c(kBufferSize, kTestSize - totalBytesRead);
+ ssize_t bytesRead = read_pos(fd, offset, block, toRead);
+ if (bytesRead == toRead) {
+// context.DecryptBlock(block, toRead, offset / BLOCK_SIZE);
+ DecryptTask task(context, block, toRead, offset / BLOCK_SIZE);
+ worker.AddTask(task);
+ worker.WaitFor(task);
+
+ for (int i = 0; i < toRead; i++) {
+ if (block[i] != i % 256) {
+ fprintf(stderr, "Block at %d is corrupt!\n", i);
+ dump_block((char*)&block[i], min_c(128, toRead - i),
+ "Corrupt");
+ break;
+ }
+ }
+ } else {
+ fprintf(stderr, "Could not read block: %s\n",
+ strerror(bytesRead));
+ break;
+ }
- dump_block((char*)block, 512, "");
+ totalBytesRead += toRead;
+ offset += toRead;
+ }
}
+ free(block);
close(fd);
return 0;
27 test/makefile
View
@@ -28,19 +28,19 @@ SRCS= crypt_test.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
-RSRCS=
+RSRCS=
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
-#
+#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
-LIBS= ../lib/libcrypt.a
+LIBS= ../lib/libcrypt.a kernelland_emu
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
@@ -48,37 +48,44 @@ LIBS= ../lib/libcrypt.a
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
-LIBPATHS=
+LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
-SYSTEM_INCLUDE_PATHS = .
+HAIKU_SOURCE = /boot/home/develop/haiku/haiku
+SYSTEM_INCLUDE_PATHS = $(HAIKU_SOURCE)/headers/private/kernel \
+ $(HAIKU_SOURCE)/private/kernel/arch \
+ $(HAIKU_SOURCE)/headers/private/kernel/arch/x86 \
+ $(HAIKU_SOURCE)/headers/private/system \
+ $(HAIKU_SOURCE)/headers/private/shared \
+ $(HAIKU_SOURCE)/headers/private \
+ $(HAIKU_SOURCE)/build/config_headers/
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
-LOCAL_INCLUDE_PATHS = ../headers/
+LOCAL_INCLUDE_PATHS = ../headers/ ../bin/
# specify the level of optimization that you desire
# NONE, SOME, FULL
-OPTIMIZE=
+OPTIMIZE=
# specify any preprocessor symbols to be defined. The symbols
# will be set to a value of 1. For example specify DEBUG if you want
# DEBUG=1 to be set when compiling.
-DEFINES=
+DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
-WARNINGS =
+WARNINGS =
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
-SYMBOLS =
+SYMBOLS =
# specify debug settings
# if TRUE will allow application to be run from

No commit comments for this range

Something went wrong with that request. Please try again.