const char *key_file, size_t key_size,
const char *pass, size_t passLen)
{
- char *key = crypt_safe_alloc(key_size);
+ char *key;
+
+ if (!key_size)
+ return NULL;
+
+ key = crypt_safe_alloc(key_size);
memset(key, 0, key_size);
/* key is coming from binary file */
return -ENOMEM;
processed_key = process_key(cd, hash, key_file, key_size, key, keyLen);
- if (!processed_key)
- return -ENOENT;
+ if (!processed_key) {
+ r = -ENOENT;
+ goto out;
+ }
r = dm_create_device(name, cd->device, dm_cipher ?: cipher, cd->type, uuid, size, skip, offset,
key_size, processed_key, read_only, reload);
-
+out:
free(dm_cipher);
crypt_safe_free(processed_key);
return r;
static void key_from_terminal(struct crypt_device *cd, char *msg, char **key,
unsigned int *key_len, int force_verify)
{
+ char *prompt = NULL;
int r;
+ *key = NULL;
+ if(!msg && asprintf(&prompt, _("Enter passphrase for %s: "),
+ cd->device) < 0)
+ return;
+
+ if (!msg)
+ msg = prompt;
+
if (cd->password) {
*key = crypt_safe_alloc(MAX_TTY_PASSWORD_LEN);
- if (*key)
+ if (!*key) {
+ free(prompt);
return;
- r = cd->password(msg, *key, (size_t)key_len, cd->password_usrptr);
+ }
+ r = cd->password(msg, *key, MAX_TTY_PASSWORD_LEN, cd->password_usrptr);
if (r < 0) {
crypt_safe_free(*key);
*key = NULL;
} else
crypt_get_key(msg, key, key_len, 0, NULL, cd->timeout,
(force_verify || cd->password_verify), cd);
+
+ free(prompt);
}
static int volume_key_by_terminal_passphrase(struct crypt_device *cd, int keyslot,
struct volume_key **vk)
{
- char *prompt = NULL, *passphrase_read = NULL;
+ char *passphrase_read = NULL;
unsigned int passphrase_size_read;
int r = -EINVAL, tries = cd->tries;
- if(asprintf(&prompt, _("Enter passphrase for %s: "), cd->device) < 0)
- return -ENOMEM;
-
*vk = NULL;
do {
if (*vk)
crypt_free_volume_key(*vk);
*vk = NULL;
- key_from_terminal(cd, prompt, &passphrase_read,
+ key_from_terminal(cd, NULL, &passphrase_read,
&passphrase_size_read, 0);
if(!passphrase_read) {
r = -EINVAL;
crypt_free_volume_key(*vk);
*vk = NULL;
}
- free(prompt);
return r;
-
}
static void key_from_file(struct crypt_device *cd, char *msg,
{
crypt_status_info ci;
struct volume_key *vk = NULL;
- char *prompt = NULL;
+ char *read_passphrase = NULL;
int r;
log_dbg("%s volume %s [keyslot %d] using %spassphrase.",
name ? "Activating" : "Checking", name ?: "",
keyslot, passphrase ? "" : "[none] ");
- /* plain, use hashed passphrase */
- if (isPLAIN(cd->type))
- return create_device_helper(cd, name, cd->plain_hdr.hash,
- cd->plain_cipher, cd->plain_cipher_mode, NULL, passphrase, passphrase_size,
- cd->volume_key->keylength, 0, cd->plain_hdr.skip,
- cd->plain_hdr.offset, cd->plain_uuid, flags & CRYPT_ACTIVATE_READONLY, 0, 0);
-
if (name) {
ci = crypt_status(NULL, name);
if (ci == CRYPT_INVALID)
}
}
- if(asprintf(&prompt, _("Enter passphrase for %s: "), cd->device) < 0)
- return -ENOMEM;
+ /* plain, use hashed passphrase */
+ if (isPLAIN(cd->type)) {
+ if (!passphrase) {
+ key_from_terminal(cd, NULL, &read_passphrase,
+ &passphrase_size, 0);
+ if (!read_passphrase) {
+ r = -EINVAL;
+ goto out;
+ }
+ passphrase = read_passphrase;
+ }
+ r = create_device_helper(cd, name, cd->plain_hdr.hash,
+ cd->plain_cipher, cd->plain_cipher_mode,
+ NULL, passphrase, passphrase_size,
+ cd->volume_key->keylength, 0,
+ cd->plain_hdr.skip, cd->plain_hdr.offset,
+ cd->plain_uuid,
+ flags & CRYPT_ACTIVATE_READONLY, 0, 0);
+ keyslot = 0;
+ } else if (isLUKS(cd->type)) {
+ /* provided passphrase, do not retry */
+ if (passphrase) {
+ r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase,
+ passphrase_size, &cd->hdr, &vk, cd);
+ } else
+ r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
- /* provided passphrase, do not retry */
- if (passphrase) {
- r = LUKS_open_key_with_hdr(cd->device, keyslot, passphrase,
- passphrase_size, &cd->hdr, &vk, cd);
+ if (r >= 0) {
+ keyslot = r;
+ if (name)
+ r = open_from_hdr_and_vk(cd, vk, name, flags);
+ }
} else
- r = volume_key_by_terminal_passphrase(cd, keyslot, &vk);
-
- if (r >= 0) {
- keyslot = r;
- if (name)
- r = open_from_hdr_and_vk(cd, vk, name, flags);
- }
-
+ r = -EINVAL;
+out:
+ crypt_safe_free(read_passphrase);
crypt_free_volume_key(vk);
- free(prompt);
return r < 0 ? r : keyslot;
}
log_dbg("Activating volume %s by volume key.", name);
+ if (!volume_key_size)
+ return -EINVAL;
+
/* use key directly, no hash */
if (isPLAIN(cd->type))
return create_device_helper(cd, name, NULL,
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
+#include <assert.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#define KEYFILE2 "key2.file"
#define KEY2 "0123456789abcdef"
+#define PASSPHRASE "blabla"
+
#define DEVICE_TEST_UUID "12345678-1234-1234-1234-123456789abc"
static int _debug = 0;
int fd;
char key[128], key2[128], path[128];
- char *passphrase = "blabla";
+ char *passphrase = PASSPHRASE;
char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
size_t key_size = strlen(mk_hex) / 2;
char *cipher = "aes";
crypt_free(cd);
}
+#define CALLBACK_ERROR "calback_error xyz"
+static int pass_callback_err(const char *msg, char *buf, size_t length, void *usrptr)
+{
+ struct crypt_device *cd = usrptr;
+
+ assert(cd);
+ assert(length);
+ assert(msg);
+
+ crypt_log(cd, CRYPT_LOG_ERROR, CALLBACK_ERROR);
+ return -EINVAL;
+}
+
+static int pass_callback_ok(const char *msg, char *buf, size_t length, void *usrptr)
+{
+ assert(length);
+ assert(msg);
+ strcpy(buf, PASSPHRASE);
+ return strlen(buf);
+}
+
+static void CallbacksTest(void)
+{
+ struct crypt_device *cd;
+ struct crypt_params_plain params = {
+ .hash = "sha1",
+ .skip = 0,
+ .offset = 0,
+ };
+
+ size_t key_size = 256 / 8;
+ char *cipher = "aes";
+ char *cipher_mode = "cbc-essiv:sha256";
+ char *passphrase = PASSPHRASE;
+
+ OK_(crypt_init(&cd, DEVICE_1));
+ crypt_set_log_callback(cd, &new_log, NULL);
+ //crypt_set_log_callback(cd, NULL, NULL);
+
+ OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms));
+
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0));
+ EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ reset_log();
+ crypt_set_password_callback(cd, pass_callback_err, cd);
+ FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, NULL, 0, 0), "callback fails");
+ EQ_(strncmp(global_log, CALLBACK_ERROR, strlen(CALLBACK_ERROR)), 0);
+
+ crypt_set_password_callback(cd, pass_callback_ok, NULL);
+ OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, NULL, 0, 0));
+ EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
+ OK_(crypt_deactivate(cd, CDEVICE_1));
+
+ crypt_free(cd);
+}
+
static void UseLuksDevice(void)
{
struct crypt_device *cd;
crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
RUN_(NonFIPSAlg, "Crypto is properly initialised in format"); //must be the first!
+
RUN_(LuksUUID, "luksUUID API call");
RUN_(IsLuks, "isLuks API call");
RUN_(LuksOpen, "luksOpen API call");
RUN_(UseLuksDevice, "Use pre-formated LUKS device");
RUN_(SuspendDevice, "Suspend/Resume test");
+ RUN_(CallbacksTest, "API callbacks test");
+
_cleanup();
return 0;
}