+2009-08-30 Milan Broz <mbroz@redhat.com>
+ * Require device device-mapper to build and do not use backend wrapper for dm calls.
+
2009-08-17 Milan Broz <mbroz@redhat.com>
* Fix PBKDF2 speed calculation for large passhrases.
* Allow using passphrase provided in options struct for LuksOpen.
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
ctype.h unistd.h locale.h)
-AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR('You need the uuid library (from e2fsprogs)')])
+AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR('You need the uuid library')])
+AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR('You need the device-mapper library')])
saved_LIBS="$LIBS"
-AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR('You need the uuid library (from e2fsprogs)')])
+AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR('You need the uuid library')])
+AC_CHECK_LIB(devmapper, dm_task_set_name,,[AC_MSG_ERROR('You need the device-mapper library')])
UUID_LIBS="$LIBS"
LIBS="$saved_LIBS"
AC_SUBST(UUID_LIBS)
AC_ARG_ENABLE(selinux,
[ --disable-selinux disable selinux support [[default=auto]]],[], [])
-MODULE_HELPER(libdevmapper,
-[ --enable-libdevmapper enable dm-crypt backend through libdevmapper
- [[default=auto]]],auto,[
- have_module=yes
- saved_LIBS="$LIBS"
- if test "x$enable_selinux" != xno; then
- AC_CHECK_LIB(sepol, sepol_bool_set)
- AC_CHECK_LIB(selinux, is_selinux_enabled)
- # Check if we need -pthread with --enable-static and selinux
- if test x$build_static = xyes; then
- saved_LIBS2="$LIBS"
- LIBS="$LIBS -static"
- AC_SEARCH_LIBS([pthread_mutex_lock], [pthread],
- [test "$ac_cv_search_pthread_mutex_lock" = "none required" || LIB_PTHREAD=-lpthread])
- LIBS="$saved_LIBS2"
- fi
+saved_LIBS="$LIBS"
+if test "x$enable_selinux" != xno; then
+ AC_CHECK_LIB(sepol, sepol_bool_set)
+ AC_CHECK_LIB(selinux, is_selinux_enabled)
+ # Check if we need -pthread with --enable-static and selinux
+ if test x$build_static = xyes; then
+ saved_LIBS2="$LIBS"
+ LIBS="$LIBS -static"
+ AC_SEARCH_LIBS([pthread_mutex_lock], [pthread],
+ [test "$ac_cv_search_pthread_mutex_lock" = "none required" || LIB_PTHREAD=-lpthread])
+ LIBS="$saved_LIBS2"
fi
- AC_CHECK_LIB(devmapper, dm_task_set_name,,unset have_module)
- AC_CHECK_HEADER(libdevmapper.h,,unset have_module)
- LIBDEVMAPPER_LIBS="$LIBS $LIB_PTHREAD"
- LIBS="$saved_LIBS"
- AC_SUBST(LIBDEVMAPPER_LIBS)
- AC_SUBST(LIBDEVMAPPER_CFLAGS)
-])
+fi
+LIBDEVMAPPER_LIBS="$LIBS $LIB_PTHREAD"
+LIBS="$saved_LIBS"
+AC_SUBST(LIBDEVMAPPER_LIBS)
+AC_SUBST(LIBDEVMAPPER_CFLAGS)
+
AM_CONDITIONAL(BUILD_LIBDEVMAPPER, test x$build_static = xyes)
AM_CONDITIONAL(SHARED_LIBDEVMAPPER, test x$build_shared = xyes)
#include "internal.h"
extern struct hash_backend hash_gcrypt_backend;
-extern struct setup_backend setup_libdevmapper_backend;
#ifdef USE_PLUGINS
static void init_plugins(void)
NULL
};
-static struct setup_backend *setup_backends[] = {
-#ifdef BUILTIN_LIBDEVMAPPER
- &setup_libdevmapper_backend,
-#endif
- NULL
-};
-
struct hash_backend *get_hash_backend(const char *name)
{
struct hash_backend **backend;
return r;
}
-
-struct setup_backend *get_setup_backend(const char *name)
-{
- struct setup_backend **backend;
-
- init_plugins();
-
- for(backend = setup_backends; *backend; backend++)
- if (!name || strcmp(name, (*backend)->name) == 0)
- break;
-
- return *backend;
-}
-
-void put_setup_backend(struct setup_backend *backend)
-{
-#ifdef USE_PLUGINS
-#endif
-}
void (*free_hashes)(struct hash_type *hashes);
};
-struct setup_backend {
- const char *name;
- int (*init)(void);
- void (*exit)(void);
- int (*create)(int reload, struct crypt_options *options,
- const char *key, const char *uuid);
- int (*status)(int details, struct crypt_options *options,
- char **key);
- int (*remove)(int force, struct crypt_options *options);
-
- const char * (*dir)(void);
-};
+struct crypt_device;
void set_error_va(const char *fmt, va_list va);
void set_error(const char *fmt, ...);
char *result, size_t size,
const char *passphrase, size_t sizep);
-struct setup_backend *get_setup_backend(const char *name);
-void put_setup_backend(struct setup_backend *backend);
-
void hexprint(char *d, int n);
+/* Device mapper backend */
+const char *dm_get_dir(void);
+int dm_init(struct crypt_device *context, int check_kernel);
+void dm_exit(void);
+int dm_remove_device(const char *name, int force, uint64_t size);
+int dm_status_device(const char *name);
+int dm_query_device(const char *name,
+ char **device,
+ uint64_t *size,
+ uint64_t *skip,
+ uint64_t *offset,
+ char **cipher,
+ int *key_size,
+ char **key,
+ int *read_only);
+int dm_create_device(const char *name, const char *device, const char *cipher, const char *uuid,
+ uint64_t size, uint64_t skip, uint64_t offset,
+ size_t key_size, const char *key,
+ int read_only, int reload);
+
int sector_size_for_device(const char *device);
ssize_t write_blockwise(int fd, const void *buf, size_t count);
ssize_t read_blockwise(int fd, void *_buf, size_t count);
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
#include <sys/ioctl.h>
-#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <libdevmapper.h>
#include <fcntl.h>
#include <linux/fs.h>
-#include "libcryptsetup.h"
#include "internal.h"
#include "luks.h"
#define DM_CRYPT_TARGET "crypt"
#define RETRY_COUNT 5
+static int _dm_use_count = 0;
+static struct crypt_device *_context = NULL;
+
static void set_dm_error(int level, const char *file, int line,
- const char *f, ...)
+ const char *f, ...)
{
va_list va;
static int _dm_simple(int task, const char *name);
-static int dm_init(void)
+int dm_init(struct crypt_device *context, int check_kernel)
{
- dm_log_init(set_dm_error);
- if (!_dm_simple(DM_DEVICE_LIST_VERSIONS, "test")) {
- set_error("Cannot communicate with device-mapper. Is the dm_mod module loaded?");
- return -1;
+ if (!_dm_use_count++) {
+ if (check_kernel && !_dm_simple(DM_DEVICE_LIST_VERSIONS, NULL))
+ return -1;
+ dm_log_init(set_dm_error);
+ dm_log_init_verbose(10);
}
+ if (context)
+ _context = context;
+
return 1; /* unsafe memory */
}
-static void dm_exit(void)
+void dm_exit(void)
{
- dm_log_init(NULL);
- dm_lib_release();
+ if (_dm_use_count && (!--_dm_use_count)) {
+ dm_log_init_verbose(0);
+ dm_log_init(NULL);
+ dm_lib_release();
+ _context = NULL;
+ }
}
static char *__lookup_dev(char *path, dev_t dev)
return r;
}
-static char *get_params(struct crypt_options *options, const char *key)
+static char *get_params(const char *device, uint64_t skip, uint64_t offset,
+ const char *cipher, size_t key_size, const char *key)
{
char *params;
char *hexkey;
int i;
- hexkey = safe_alloc(options->key_size * 2 + 1);
- if (!hexkey) {
- set_error("Memory allocation problem");
+ hexkey = safe_alloc(key_size * 2 + 1);
+ if (!hexkey)
return NULL;
- }
- for(i = 0; i < options->key_size; i++)
+ for(i = 0; i < key_size; i++)
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
- params = safe_alloc(strlen(hexkey) + strlen(options->cipher) +
- strlen(options->device) + 64);
- if (!params) {
- set_error("Memory allocation problem");
+ params = safe_alloc(strlen(hexkey) + strlen(cipher) + strlen(device) + 64);
+ if (!params)
goto out;
- }
sprintf(params, "%s %s %" PRIu64 " %s %" PRIu64,
- options->cipher, hexkey, options->skip,
- options->device, options->offset);
+ cipher, hexkey, skip, device, offset);
out:
safe_free(hexkey);
-
return params;
}
if (!(dmt = dm_task_create(task)))
return 0;
- if (!dm_task_set_name(dmt, name))
+ if (name && !dm_task_set_name(dmt, name))
goto out;
r = dm_task_run(dmt);
return r;
}
-static int _error_device(struct crypt_options *options)
+static int _error_device(const char *name, size_t size)
{
struct dm_task *dmt;
int r = 0;
if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
return 0;
- if (!dm_task_set_name(dmt, options->name))
+ if (!dm_task_set_name(dmt, name))
goto error;
- if (!dm_task_add_target(dmt, UINT64_C(0), options->size, "error", ""))
+ if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
goto error;
if (!dm_task_set_ro(dmt))
if (!dm_task_run(dmt))
goto error;
- if (!_dm_simple(DM_DEVICE_RESUME, options->name)) {
- _dm_simple(DM_DEVICE_CLEAR, options->name);
+ if (!_dm_simple(DM_DEVICE_RESUME, name)) {
+ _dm_simple(DM_DEVICE_CLEAR, name);
goto error;
}
return r;
}
-static int _dm_remove(struct crypt_options *options, int force)
+int dm_remove_device(const char *name, int force, uint64_t size)
{
int r = -EINVAL;
int retries = force ? RETRY_COUNT : 1;
+ if (!name || (force && !size))
+ return -EINVAL;
+
/* If force flag is set, replace device with error, read-only target.
* it should stop processes from reading it and also removed underlying
* device from mapping, so it is usable again.
* it is bug - no other process should try touch it (e.g. udev).
*/
if (force) {
- _error_device(options);
+ _error_device(name, size);
retries = RETRY_COUNT;
}
do {
- r = _dm_simple(DM_DEVICE_REMOVE, options->name) ? 0 : -EINVAL;
- if (--retries && r)
+ r = _dm_simple(DM_DEVICE_REMOVE, name) ? 0 : -EINVAL;
+ if (--retries && r) {
sleep(1);
+ }
} while (r == -EINVAL && retries);
dm_task_update_nodes();
return r;
}
-static int dm_create_device(int reload, struct crypt_options *options,
- const char *key, const char *uuid)
+int dm_create_device(const char *name,
+ const char *device,
+ const char *cipher,
+ const char *uuid,
+ uint64_t size,
+ uint64_t skip,
+ uint64_t offset,
+ size_t key_size,
+ const char *key,
+ int read_only,
+ int reload)
{
struct dm_task *dmt = NULL;
struct dm_task *dmt_query = NULL;
int r = -EINVAL;
uint32_t read_ahead = 0;
- params = get_params(options, key);
+ params = get_params(device, skip, offset, cipher, key_size, key);
if (!params)
goto out_no_removal;
if (!(dmt = dm_task_create(reload ? DM_DEVICE_RELOAD
: DM_DEVICE_CREATE)))
- goto out;
- if (!dm_task_set_name(dmt, options->name))
- goto out;
- if (options->flags & CRYPT_FLAG_READONLY && !dm_task_set_ro(dmt))
- goto out;
- if (!dm_task_add_target(dmt, 0, options->size, DM_CRYPT_TARGET, params))
- goto out;
+ goto out_no_removal;
+ if (!dm_task_set_name(dmt, name))
+ goto out_no_removal;
+ if (read_only && !dm_task_set_ro(dmt))
+ goto out_no_removal;
+ if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params))
+ goto out_no_removal;
#ifdef DM_READ_AHEAD_MINIMUM_FLAG
- if (_dev_read_ahead(options->device, &read_ahead) &&
+ if (_dev_read_ahead(device, &read_ahead) &&
!dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
- goto out;
+ goto out_no_removal;
#endif
if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
- goto out;
+ goto out_no_removal;
if (!dm_task_run(dmt))
- goto out;
+ goto out_no_removal;
if (reload) {
dm_task_destroy(dmt);
if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
goto out;
- if (!dm_task_set_name(dmt, options->name))
+ if (!dm_task_set_name(dmt, name))
goto out;
if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
goto out;
if (!dm_task_get_info(dmt, &dmi))
goto out;
- if (dmi.read_only)
- options->flags |= CRYPT_FLAG_READONLY;
r = 0;
out:
if (get_error())
error = strdup(get_error());
- _dm_remove(options, 0);
+ dm_remove_device(name, 0, 0);
if (error) {
set_error(error);
return r;
}
-static int dm_query_device(int details, struct crypt_options *options,
- char **key)
+int dm_status_device(const char *name)
{
struct dm_task *dmt;
struct dm_info dmi;
void *next = NULL;
int r = -EINVAL;
- if (!(dmt = dm_task_create(details ? DM_DEVICE_TABLE
- : DM_DEVICE_STATUS)))
+ if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
+ return -EINVAL;
+
+ if (!dm_task_set_name(dmt, name)) {
+ r = -EINVAL;
+ goto out;
+ }
+
+ if (!dm_task_run(dmt)) {
+ r = -ENODEV;
+ goto out;
+ }
+
+ if (!dm_task_get_info(dmt, &dmi)) {
+ r = -EINVAL;
+ goto out;
+ }
+
+ if (!dmi.exists) {
+ r = -ENODEV;
+ goto out;
+ }
+
+ next = dm_get_next_target(dmt, next, &start, &length,
+ &target_type, ¶ms);
+ if (!target_type || strcmp(target_type, DM_CRYPT_TARGET) != 0 ||
+ start != 0 || next)
+ r = -EINVAL;
+ else
+ r = (dmi.open_count > 0);
+out:
+ if (dmt)
+ dm_task_destroy(dmt);
+
+ return r;
+}
+
+int dm_query_device(const char *name,
+ char **device,
+ uint64_t *size,
+ uint64_t *skip,
+ uint64_t *offset,
+ char **cipher,
+ int *key_size,
+ char **key,
+ int *read_only)
+{
+ struct dm_task *dmt;
+ struct dm_info dmi;
+ uint64_t start, length, val64;
+ char *target_type, *params, *rcipher, *key_, *rdevice, *endp, buffer[3];
+ void *next = NULL;
+ int i, r = -EINVAL;
+
+ if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
goto out;
- if (!dm_task_set_name(dmt, options->name))
+ if (!dm_task_set_name(dmt, name))
goto out;
r = -ENODEV;
if (!dm_task_run(dmt))
start != 0 || next)
goto out;
- options->hash = NULL;
- options->cipher = NULL;
- options->offset = 0;
- options->skip = 0;
- options->size = length;
- if (details) {
- char *cipher, *key_, *device;
- uint64_t val64;
+ if (size)
+ *size = length;
- set_error("Invalid dm table");
+ rcipher = strsep(¶ms, " ");
+ /* cipher */
+ if (cipher)
+ *cipher = strdup(rcipher);
- cipher = strsep(¶ms, " ");
- key_ = strsep(¶ms, " ");
- if (!params)
- goto out;
+ /* skip */
+ key_ = strsep(¶ms, " ");
+ if (!params)
+ goto out;
+ val64 = strtoull(params, ¶ms, 10);
+ if (*params != ' ')
+ goto out;
+ params++;
+ if (skip)
+ *skip = val64;
- val64 = strtoull(params, ¶ms, 10);
- if (*params != ' ')
- goto out;
- params++;
- options->skip = val64;
+ /* device */
+ rdevice = strsep(¶ms, " ");
+ if (device)
+ *device = lookup_dev(rdevice);
- device = strsep(¶ms, " ");
- if (!params)
+ /*offset */
+ if (!params)
+ goto out;
+ val64 = strtoull(params, ¶ms, 10);
+ if (*params)
+ goto out;
+ if (offset)
+ *offset = val64;
+
+ /* key_size */
+ if (key_size)
+ *key_size = strlen(key_) / 2;
+
+ /* key */
+ if (key_size && key) {
+ *key = safe_alloc(*key_size);
+ if (!*key) {
+ r = -ENOMEM;
goto out;
+ }
- val64 = strtoull(params, ¶ms, 10);
- if (*params)
- goto out;
- options->offset = val64;
-
- options->cipher = strdup(cipher);
- options->key_size = strlen(key_) / 2;
- if (key) {
- char buffer[3];
- char *endp;
- int i;
-
- *key = safe_alloc(options->key_size);
- if (!*key) {
- set_error("Out of memory");
- r = -ENOMEM;
+ buffer[2] = '\0';
+ for(i = 0; i < *key_size; i++) {
+ memcpy(buffer, &key_[i * 2], 2);
+ (*key)[i] = strtoul(buffer, &endp, 16);
+ if (endp != &buffer[2]) {
+ safe_free(key);
+ *key = NULL;
goto out;
}
-
- buffer[2] = '\0';
- for(i = 0; i < options->key_size; i++) {
- memcpy(buffer, &key_[i * 2], 2);
- (*key)[i] = strtoul(buffer, &endp, 16);
- if (endp != &buffer[2]) {
- safe_free(key);
- *key = NULL;
- goto out;
- }
- }
}
- memset(key_, 0, strlen(key_));
- options->device = lookup_dev(device);
-
- set_error(NULL);
}
+ memset(key_, 0, strlen(key_));
- r = (dmi.open_count > 0);
+ /* read_only */
+ if (read_only)
+ *read_only = dmi.read_only;
+ r = (dmi.open_count > 0);
out:
if (dmt)
dm_task_destroy(dmt);
- if (r >= 0) {
- if (options->device)
- options->flags |= CRYPT_FLAG_FREE_DEVICE;
- if (options->cipher)
- options->flags |= CRYPT_FLAG_FREE_CIPHER;
- options->flags &= ~CRYPT_FLAG_READONLY;
- if (dmi.read_only)
- options->flags |= CRYPT_FLAG_READONLY;
- } else {
- if (options->device) {
- free((char *)options->device);
- options->device = NULL;
- options->flags &= ~CRYPT_FLAG_FREE_DEVICE;
- }
- if (options->cipher) {
- free((char *)options->cipher);
- options->cipher = NULL;
- options->flags &= ~CRYPT_FLAG_FREE_CIPHER;
- }
- }
- return r;
-}
-
-static int dm_remove_device(int force, struct crypt_options *options)
-{
- if (!options || !options->name)
- return -EINVAL;
- return _dm_remove(options, force);;
+ return r;
}
-
-static const char *dm_get_dir(void)
+const char *dm_get_dir(void)
{
return dm_dir();
}
-
-struct setup_backend setup_libdevmapper_backend = {
- .name = "dm-crypt",
- .init = dm_init,
- .exit = dm_exit,
- .create = dm_create_device,
- .status = dm_query_device,
- .remove = dm_remove_device,
- .dir = dm_get_dir
-};
};
static int memory_unsafe = 0;
-static char *default_backend = NULL;
#define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; })
logger(options, class, "%02hhx ", (char)d[i]);
}
-static int setup_enter(struct setup_backend *backend, void (*log)(int, char *))
+static int setup_enter(void (*log)(int, char *))
{
int r;
set_error(NULL);
- if (backend) {
- r = backend->init();
- if (r < 0)
- return r;
- if (r > 0)
- memory_unsafe = 1;
- }
-
return 0;
}
-static int setup_leave(struct setup_backend *backend)
+static int setup_leave(void)
{
- if (backend)
- backend->exit();
-
/* dangerous, we can't wipe all the memory */
if (!memory_unsafe)
munlockall();
}
}
-static int __crypt_create_device(int reload, struct setup_backend *backend,
- struct crypt_options *options)
+static int __crypt_create_device(int reload, struct crypt_options *options)
{
- struct crypt_options tmp = {
- .name = options->name,
- };
struct device_infos infos;
char *key = NULL;
unsigned int keyLen;
char *processed_key = NULL;
int r;
- r = backend->status(0, &tmp, NULL);
+ r = dm_status_device(options->name);
if (reload) {
if (r < 0)
return r;
return -ENOENT;
}
- r = backend->create(reload, options, processed_key, NULL);
+ r = dm_create_device(options->name, options->device, options->cipher,
+ NULL, options->size, options->skip, options->offset,
+ options->key_size, processed_key,
+ options->flags & CRYPT_FLAG_READONLY, reload);
safe_free(processed_key);
return r;
}
-static int __crypt_query_device(int details, struct setup_backend *backend,
- struct crypt_options *options)
+static int __crypt_query_device(int details, struct crypt_options *options)
{
- int r = backend->status(details, options, NULL);
+ int read_only, r;
+
+ r = dm_status_device(options->name);
if (r == -ENODEV)
return 0;
- else if (r >= 0)
- return 1;
- else
+
+ r = dm_query_device(options->name, (char **)&options->device, &options->size,
+ &options->skip, &options->offset, (char **)&options->cipher,
+ &options->key_size, NULL, &read_only);
+
+ if (r < 0)
return r;
+
+ if (read_only)
+ options->flags |= CRYPT_FLAG_READONLY;
+
+ options->flags |= CRYPT_FLAG_FREE_DEVICE;
+ options->flags |= CRYPT_FLAG_FREE_CIPHER;
+
+ return 1;
}
-static int __crypt_resize_device(int details, struct setup_backend *backend,
- struct crypt_options *options)
+static int __crypt_resize_device(int details, struct crypt_options *options)
{
- struct crypt_options tmp = {
- .name = options->name,
- };
+ char *device, *cipher, *key = NULL;
+ uint64_t size, skip, offset;
+ int key_size, read_only, r;
struct device_infos infos;
- char *key = NULL;
- int r;
- r = backend->status(1, &tmp, &key);
+ r = dm_query_device(options->name, &device, &size, &skip, &offset,
+ &cipher, &key_size, &key, &read_only);
if (r < 0)
return r;
- if (get_device_infos(tmp.device, &infos) < 0)
+ if (get_device_infos(device, &infos) < 0)
return -EINVAL;
if (!options->size) {
set_error("Not a block device");
return -ENOTBLK;
}
- if (options->size <= tmp.offset) {
+ if (options->size <= offset) {
set_error("Invalid offset");
return -EINVAL;
}
- options->size -= tmp.offset;
+ options->size -= offset;
}
- tmp.size = options->size;
+ size = options->size;
if (infos.readonly)
options->flags |= CRYPT_FLAG_READONLY;
- r = backend->create(1, &tmp, key, NULL);
+ r = dm_create_device(options->name, device, cipher, NULL, size, skip, offset,
+ key_size, key, read_only, 1);
safe_free(key);
+ free(cipher);
+ free(device);
return r;
}
-static int __crypt_remove_device(int arg, struct setup_backend *backend,
- struct crypt_options *options)
+static int __crypt_remove_device(int arg, struct crypt_options *options)
{
int r;
- r = backend->status(0, options, NULL);
+ r = dm_status_device(options->name);
if (r < 0)
return r;
if (r > 0) {
return -EBUSY;
}
- return backend->remove(0, options);
+ return dm_remove_device(options->name, 0, 0);
}
-static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
+static int __crypt_luks_format(int arg, struct crypt_options *options)
{
int r;
if(r < 0) goto out;
/* Set key, also writes phdr */
- r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk, backend);
+ r = LUKS_set_key(options->device, keyIndex, password, passwordLen, &header, mk);
if(r < 0) goto out;
r = 0;
return r;
}
-static int __crypt_luks_open(int arg, struct setup_backend *backend, struct crypt_options *options)
+static int __crypt_luks_open(int arg, struct crypt_options *options)
{
struct luks_masterkey *mk=NULL;
struct luks_phdr hdr;
char *password;
unsigned int passwordLen;
struct device_infos infos;
- struct crypt_options tmp = {
- .name = options->name,
- };
char *dmCipherSpec = NULL;
int r, tries = options->tries;
int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ? 0 : O_EXCL ;
- r = backend->status(0, &tmp, NULL);
+ r = dm_status_device(options->name);
if (r >= 0) {
set_error("Device %s already exists.", options->name);
return -EEXIST;
r = -EINVAL; goto out;
}
- r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk, backend);
+ r = LUKS_open_any_key(options->device, password, passwordLen, &hdr, &mk);
if (r == -EPERM)
set_error("No key available with this passphrase.\n");
if (r < 0)
options->size -= options->offset;
/* FIXME: code allows multiple crypt mapping, cannot use uuid then.
* anyway, it is dangerous and can corrupt data. Remove it in next version! */
- r = backend->create(0, options, mk->key, excl ? hdr.uuid : NULL);
+ r = dm_create_device(options->name, options->device, options->cipher,
+ excl ? hdr.uuid : NULL, options->size,
+ 0, options->offset, mk->keyLength, mk->key,
+ options->flags & CRYPT_FLAG_READONLY, 0);
out2:
free(dmCipherSpec);
return r;
}
-static int __crypt_luks_add_key(int arg, struct setup_backend *backend, struct crypt_options *options)
+static int __crypt_luks_add_key(int arg, struct crypt_options *options)
{
struct luks_masterkey *mk=NULL;
struct luks_phdr hdr;
if(!password) {
r = -EINVAL; goto out;
}
- r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend);
+ r = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk);
if(r < 0) {
options->icb->log(CRYPT_LOG_ERROR,"No key available with this passphrase.\n");
r = -EPERM; goto out;
if (r < 0) goto out;
hdr.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000));
- r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, backend);
+ r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk);
if(r < 0) goto out;
r = 0;
return r;
}
-static int luks_remove_helper(int arg, struct setup_backend *backend, struct crypt_options *options, int supply_it)
+static int luks_remove_helper(int arg, struct crypt_options *options, int supply_it)
{
struct luks_masterkey *mk;
struct luks_phdr hdr;
r = -EINVAL; goto out;
}
- keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk, backend);
+ keyIndex = LUKS_open_any_key(device, password, passwordLen, &hdr, &mk);
if(keyIndex < 0) {
options->icb->log(CRYPT_LOG_ERROR,"No remaining key available with this passphrase.\n");
r = -EPERM; goto out;
if(!last_slot)
hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
- openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, backend);
+ openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk);
/* Clean up */
if (openedIndex >= 0) {
LUKS_dealloc_masterkey(mk);
return r;
}
-static int __crypt_luks_kill_slot(int arg, struct setup_backend *backend, struct crypt_options *options) {
- return luks_remove_helper(arg, backend, options, 0);
+static int __crypt_luks_kill_slot(int arg, struct crypt_options *options) {
+ return luks_remove_helper(arg, options, 0);
}
-static int __crypt_luks_remove_key(int arg, struct setup_backend *backend, struct crypt_options *options) {
- return luks_remove_helper(arg, backend, options, 1);
+static int __crypt_luks_remove_key(int arg, struct crypt_options *options) {
+ return luks_remove_helper(arg, options, 1);
}
-static int crypt_job(int (*job)(int arg, struct setup_backend *backend,
- struct crypt_options *options),
+static int crypt_job(int (*job)(int arg, struct crypt_options *options),
int arg, struct crypt_options *options)
{
- struct setup_backend *backend;
int r;
- backend = get_setup_backend(default_backend);
-
- if (setup_enter(backend,options->icb->log) < 0) {
- r = -ENOSYS;
- goto out;
- }
-
- if (!backend) {
- set_error("No setup backend available");
+ if (setup_enter(options->icb->log) < 0) {
r = -ENOSYS;
goto out;
}
- r = job(arg, backend, options);
+ r = job(arg, options);
out:
- setup_leave(backend);
- if (backend)
- put_setup_backend(backend);
+ setup_leave();
if (r >= 0)
set_error(NULL);
}
}
-void crypt_set_default_backend(const char *backend)
-{
- if (default_backend)
- free(default_backend);
- if (backend)
- default_backend = strdup(backend);
- else
- default_backend = NULL;
-}
-
const char *crypt_get_dir(void)
{
- struct setup_backend *backend;
- const char *dir;
-
- backend = get_setup_backend(default_backend);
- if (!backend)
- return NULL;
-
- dir = backend->dir();
-
- put_setup_backend(backend);
-
- return dir;
+ return dm_get_dir();
}
-
-// Local Variables:
-// c-basic-offset: 8
-// indent-tabs-mode: nil
-// End:
#include <signal.h>
#include "luks.h"
-#include "../lib/libcryptsetup.h"
+//#include "../lib/libcryptsetup.h"
#include "../lib/internal.h"
-#include "../lib/blockdev.h"
+//#include "../lib/blockdev.h"
#define div_round_up(a,b) ({ \
typeof(a) __a = (a); \
return div_round_up(x, m) * m;
}
-static struct setup_backend *cleaner_backend=NULL;
static const char *cleaner_name=NULL;
static uint64_t cleaner_size = 0;
static int devfd=-1;
-static int setup_mapping(const char *cipher, const char *name,
+static int setup_mapping(const char *cipher, const char *name,
const char *device, unsigned int payloadOffset,
- const char *key, size_t keyLength,
- unsigned int sector, size_t srcLength,
- struct setup_backend *backend,
+ const char *key, size_t keyLength,
+ unsigned int sector, size_t srcLength,
int mode)
{
- struct crypt_options k = {0};
- struct crypt_options *options = &k;
int device_sector_size = sector_size_for_device(device);
- int r;
+ uint64_t size;
/*
* we need to round this to nearest multiple of the underlying
set_error(_("Unable to obtain sector size for %s"),device);
return -EINVAL;
}
- options->size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
- cleaner_size = options->size;
-
- options->offset = sector;
- options->cipher = cipher;
- options->key_size = keyLength;
- options->skip = 0;
- options->flags = 0;
- options->name = name;
- options->device = device;
-
- if (mode == O_RDONLY) {
- options->flags |= CRYPT_FLAG_READONLY;
- }
-
set_error(NULL);
+ size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
+ cleaner_size = size;
- r = backend->create(0, options, key, NULL);
-
- return r;
-}
-
-static int clear_mapping(const char *name, uint64_t size, struct setup_backend *backend)
-{
- struct crypt_options options = {0};
- options.name=name;
- options.size = size;
- return backend->remove(1, &options);
+ return dm_create_device(name, device, cipher, NULL, size, 0, sector,
+ keyLength, key, (mode == O_RDONLY), 0);
}
static void sigint_handler(int sig)
{
- if(devfd >= 0)
- close(devfd);
- devfd = -1;
- if(cleaner_backend && cleaner_name)
- clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
- signal(SIGINT, SIG_DFL);
- kill(getpid(), SIGINT);
+ if(devfd >= 0)
+ close(devfd);
+ devfd = -1;
+ if(cleaner_name)
+ dm_remove_device(cleaner_name, 1, cleaner_size);
+
+ signal(SIGINT, SIG_DFL);
+ kill(getpid(), SIGINT);
}
static char *_error_hint(char *cipherName, char *cipherMode, size_t keyLength)
struct luks_phdr *hdr,
char *key, size_t keyLength,
const char *device,
- unsigned int sector, struct setup_backend *backend,
+ unsigned int sector,
ssize_t (*func)(int, void *, size_t),
int mode)
{
char *name = NULL;
char *fullpath = NULL;
char *dmCipherSpec = NULL;
- const char *dmDir = backend->dir();
+ const char *dmDir = dm_get_dir();
int r = -1;
if(dmDir == NULL) {
signal(SIGINT, sigint_handler);
cleaner_name = name;
- cleaner_backend = backend;
- r = setup_mapping(dmCipherSpec,name,device,hdr->payloadOffset,key,keyLength,sector,srcLength,backend,mode);
+ r = setup_mapping(dmCipherSpec, name, device, hdr->payloadOffset,
+ key, keyLength, sector, srcLength, mode);
if(r < 0) {
set_error("Failed to setup dm-crypt key mapping for device %s.\n"
"Check that kernel supports %s cipher (check syslog for more info).\n%s",
}
devfd = open(fullpath, mode | O_DIRECT | O_SYNC); /* devfd is a global var */
- if(devfd == -1) { r = -EIO; goto out2; }
+ if(devfd == -1) {
+ r = -EIO;
+ goto out2;
+ }
r = func(devfd,src,srcLength);
- if(r < 0) { r = -EIO; goto out3; }
+ if(r < 0) {
+ r = -EIO;
+ goto out3;
+ }
r = 0;
out3:
close(devfd);
devfd = -1;
out2:
- clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
+ dm_remove_device(cleaner_name, 1, cleaner_size);
out1:
signal(SIGINT, SIG_DFL);
cleaner_name = NULL;
- cleaner_backend = NULL;
cleaner_size = 0;
free(dmCipherSpec);
- free(fullpath);
- free(name);
+ free(fullpath);
+ free(name);
return r;
}
-int LUKS_encrypt_to_storage(char *src, size_t srcLength,
- struct luks_phdr *hdr,
- char *key, size_t keyLength,
- const char *device,
- unsigned int sector, struct setup_backend *backend)
-{
-
- return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device, sector, backend,
- (ssize_t (*)(int, void *, size_t)) write_blockwise, O_RDWR);
-}
-
-int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
- struct luks_phdr *hdr,
- char *key, size_t keyLength,
- const char *device,
- unsigned int sector, struct setup_backend *backend)
+int LUKS_encrypt_to_storage(char *src, size_t srcLength,
+ struct luks_phdr *hdr,
+ char *key, size_t keyLength,
+ const char *device,
+ unsigned int sector)
{
- return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device, sector, backend, read_blockwise, O_RDONLY);
+ return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device, sector,
+ (ssize_t (*)(int, void *, size_t)) write_blockwise,
+ O_RDWR);
}
-// Local Variables:
-// c-basic-offset: 8
-// indent-tabs-mode: nil
-// End:
+int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
+ struct luks_phdr *hdr,
+ char *key, size_t keyLength,
+ const char *device,
+ unsigned int sector)
+{
+ return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device,
+ sector, read_blockwise, O_RDONLY);
+}
int LUKS_set_key(const char *device, unsigned int keyIndex,
const char *password, size_t passwordLen,
- struct luks_phdr *hdr, struct luks_masterkey *mk,
- struct setup_backend *backend)
+ struct luks_phdr *hdr, struct luks_masterkey *mk)
{
char derivedKey[hdr->keyBytes];
char *AfKey;
derivedKey,
hdr->keyBytes,
device,
- hdr->keyblock[keyIndex].keyMaterialOffset,
- backend);
+ hdr->keyblock[keyIndex].keyMaterialOffset);
if(r < 0) {
if(!get_error())
set_error("Failed to write to key storage");
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
- struct luks_masterkey *mk,
- struct setup_backend *backend)
+ struct luks_masterkey *mk)
{
char derivedKey[hdr->keyBytes];
char *AfKey;
derivedKey,
hdr->keyBytes,
device,
- hdr->keyblock[keyIndex].keyMaterialOffset,
- backend);
+ hdr->keyblock[keyIndex].keyMaterialOffset);
if(r < 0) goto out;
r = AF_merge(AfKey,mk->key,mk->keyLength,hdr->keyblock[keyIndex].stripes,hdr->hashSpec);
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
- struct luks_masterkey **mk,
- struct setup_backend *backend)
+ struct luks_masterkey **mk)
{
int r;
r = LUKS_read_phdr(device, hdr);
if(r < 0)
return r;
- return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk,backend);
+ return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk);
}
int LUKS_open_any_key_with_hdr(const char *device,
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
- struct luks_masterkey **mk,
- struct setup_backend *backend)
+ struct luks_masterkey **mk)
{
unsigned int i;
int r;
*mk=LUKS_alloc_masterkey(hdr->keyBytes);
for(i=0; i<LUKS_NUMKEYS; i++) {
- r = LUKS_open_key(device, i, password, passwordLen, hdr, *mk, backend);
+ r = LUKS_open_key(device, i, password, passwordLen, hdr, *mk);
if(r == 0)
return i;
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
- struct luks_masterkey *mk,
- struct setup_backend *backend);
+ struct luks_masterkey *mk);
int LUKS_open_key(const char *device,
unsigned int keyIndex,
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
- struct luks_masterkey *mk,
- struct setup_backend *backend);
+ struct luks_masterkey *mk);
int LUKS_open_any_key(const char *device,
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
- struct luks_masterkey **mk,
- struct setup_backend *backend);
+ struct luks_masterkey **mk);
int LUKS_open_any_key_with_hdr(const char *device,
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
- struct luks_masterkey **mk,
- struct setup_backend *backend);
+ struct luks_masterkey **mk);
int LUKS_del_key(const char *device, unsigned int keyIndex);
struct luks_phdr *hdr,
char *key, size_t keyLength,
const char *device,
- unsigned int sector, struct setup_backend *backend);
+ unsigned int sector);
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
const char *device,
- unsigned int sector, struct setup_backend *backend);
+ unsigned int sector);
int LUKS_device_ready(const char *device, int mode);
#endif