Newer
Older
/**
* Use cryptsetup to initialise the luks container.
* It will not be opened (decrypted) yet, but it does check if the container
* seems usable.
* @param crypt_device struct to store crypt device context
* @param path path to the encrypted container
static int container_initialise(struct crypt_device ** cd, const char * path,
// Check if the device exists.
y_log_message(Y_LOG_LEVEL_ERROR, "device does not exist: %s.", path);
// Let LUKS initialise the encrypted device.
int r = crypt_init(cd, path);
if (r < 0)
{

Maarten de Waard
committed
y_log_message(Y_LOG_LEVEL_ERROR,
"crypt_init() failed for '%s', status: %d.", path, r);
return r;
}
// Load the LUKS header from the block device into the crypt device context.

Maarten de Waard
committed
y_log_message(Y_LOG_LEVEL_ERROR,
"crypt_load() failed on device %s.",
/**
* Check if the given device is actually an encrypted container.
* @param path path to the encrypted container
*/
static bool is_encrypted_device(const char * path)
{
// Let LUKS initialise the encrypted device.
struct crypt_device * cd;
int r = container_initialise(&cd, path, false);
/**
* Use cryptsetup to unlock the luks container.
* This will create `/dev/mapper/$device_name`.
* @param path path to the encrypted container
* @param device_name name of the mapping
* @param password encryption password of the container
* @return status code
static int encryption_unlock(const char * path, const char * device_name,
const char * password)
{
// Let LUKS initialise the encrypted device.
struct crypt_device * cd;
int r = container_initialise(&cd, path, true);
// Create device mapping with name device_name.
r = crypt_activate_by_passphrase(cd, device_name, CRYPT_ANY_SLOT,
password, strlen(password), 0);

Maarten de Waard
committed
y_log_message(Y_LOG_LEVEL_ERROR,
"Device %s activation failed.", device_name);

Maarten de Waard
committed
y_log_message(Y_LOG_LEVEL_DEBUG,
"LUKS device %s/%s is active.", crypt_get_dir(), device_name);
y_log_message(Y_LOG_LEVEL_DEBUG, "\tcipher used: %s",

Maarten de Waard
committed
crypt_get_cipher(cd));
y_log_message(Y_LOG_LEVEL_DEBUG, "\tcipher mode: %s",

Maarten de Waard
committed
crypt_get_cipher_mode(cd));
y_log_message(Y_LOG_LEVEL_DEBUG, "\tdevice UUID: %s",

Maarten de Waard
committed
crypt_get_uuid(cd));
/**
* Use cryptsetup to lock the luks container again.
* @param device_name name of the mapping
* @return status code
*/
static int encryption_lock(const char * device_name)
int r;
r = crypt_init_by_name(&cd, device_name);
if (r < 0)
{
y_log_message(Y_LOG_LEVEL_ERROR, "crypt_init_by_name() failed for %s.", device_name);
return r;
}
if (crypt_status(cd, device_name) == CRYPT_ACTIVE)
{
y_log_message(Y_LOG_LEVEL_ERROR, "Device %s is still active.", device_name);
y_log_message(Y_LOG_LEVEL_ERROR, "Something failed perhaps, device %s is not active.",
device_name);
crypt_free(cd);
return -1;
}
r = crypt_deactivate(cd, device_name);
if (r < 0)
{
y_log_message(Y_LOG_LEVEL_ERROR, "crypt_deactivate() failed.");
crypt_free(cd);
return r;
}
y_log_message(Y_LOG_LEVEL_DEBUG, "Device %s is now deactivated.", device_name);
crypt_free(cd);
return 0;
}
/**
* Create a new encrypted container on a given device.
* This overwrites the current contents of the device.
* @param path path to the device
* @param password password of the new container
* @return status code
*/
static int create_encrypted_device(const char * path, const char * password)
{
struct crypt_device * cd;
struct crypt_params_luks1 params;
int r;
r = crypt_init(&cd, path);
if (r < 0 )
{
y_log_message(Y_LOG_LEVEL_ERROR, "crypt_init() failed for %s.", path);
y_log_message(Y_LOG_LEVEL_DEBUG, "Context is attached to block device %s.",
crypt_get_device_name(cd));
params.hash = "sha1";
params.data_alignment = 0;
params.data_device = NULL;
r = crypt_format(cd, CRYPT_LUKS1, "aes", "xts-plain64", NULL, NULL, 256 / 8,
¶ms);
if (r < 0)
{
y_log_message(Y_LOG_LEVEL_ERROR, "crypt_format() failed on device %s",
crypt_get_device_name(cd));
crypt_free(cd);
return r;
}
r = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, NULL, 0, password,
strlen(password));
if (r < 0)
{
y_log_message(Y_LOG_LEVEL_ERROR, "Adding keyslot failed.");
y_log_message(Y_LOG_LEVEL_DEBUG, "The first keyslot is initialized.");
crypt_free(cd);
return 0;
}