/*
- * util_crypt - cipher utilities for cryptsetup
+ * utils_crypt - cipher utilities for cryptsetup
*
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2009-2011, Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdlib.h>
return 0;
}
+ /* Short version for "empty" cipher */
+ if (!strcmp(s, "null")) {
+ strncpy(cipher, "cipher_null", MAX_CIPHER_LEN);
+ strncpy(cipher_mode, "ecb", 9);
+ if (key_nums)
+ *key_nums = 0;
+ return 0;
+ }
+
if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]", cipher) == 1) {
strncpy(cipher_mode, "cbc-plain", 10);
if (key_nums)
if (!data)
return;
- alloc = data - offsetof(struct safe_allocation, data);
+ alloc = (struct safe_allocation *)
+ ((char *)data - offsetof(struct safe_allocation, data));
memset(data, 0, alloc->size);
if (new_data && data) {
- alloc = data - offsetof(struct safe_allocation, data);
+ alloc = (struct safe_allocation *)
+ ((char *)data - offsetof(struct safe_allocation, data));
if (size > alloc->size)
size = alloc->size;
if (strncmp(pass, pass_verify, key_size_max)) {
log_err(cd, _("Passphrases do not match.\n"));
+ r = -EPERM;
goto out_err;
}
}
*/
int crypt_get_key(const char *prompt,
char **key, size_t *key_size,
- size_t keyfile_size_max, const char *key_file,
- int timeout, int verify,
+ size_t keyfile_offset, size_t keyfile_size_max,
+ const char *key_file, int timeout, int verify,
struct crypt_device *cd)
{
int fd, regular_file, read_stdin, char_read, unlimited_read = 0;
int r = -EINVAL;
- char *pass = NULL;
- size_t buflen, i;
+ char *pass = NULL, tmp;
+ size_t buflen, i, file_read_size;
struct stat st;
*key = NULL;
/* Passphrase read from stdin? */
read_stdin = (!key_file || !strcmp(key_file, "-")) ? 1 : 0;
- if(read_stdin && isatty(STDIN_FILENO))
+ if (read_stdin && isatty(STDIN_FILENO)) {
+ if (keyfile_offset) {
+ log_err(cd, _("Cannot use offset with terminal input.\n"));
+ return -EINVAL;
+ }
return crypt_get_key_tty(prompt, key, key_size, timeout, verify, cd);
-
- if (keyfile_size_max < 0) {
- log_err(cd, _("Negative keyfile size not permitted.\n"));
- return -EINVAL;
}
if (read_stdin)
}
if(S_ISREG(st.st_mode)) {
regular_file = 1;
+ file_read_size = (size_t)st.st_size;
+
+ if (keyfile_offset > file_read_size) {
+ log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
+ goto out_err;
+ }
+ file_read_size -= keyfile_offset;
+
/* known keyfile size, alloc it in one step */
- if (st.st_size >= keyfile_size_max)
+ if (file_read_size >= keyfile_size_max)
buflen = keyfile_size_max;
- else
- buflen = st.st_size;
+ else if (file_read_size)
+ buflen = file_read_size;
}
}
goto out_err;
}
+ /* Discard keyfile_offset bytes on input */
+ for(i = 0; i < keyfile_offset; i++)
+ if (read(fd, &tmp, 1) != 1) {
+ log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
+ goto out_err;
+ }
+
for(i = 0; i < keyfile_size_max; i++) {
if(i == buflen) {
buflen += 4096;
/* Fail if we exceeded internal default (no specified size) */
if (unlimited_read && i == keyfile_size_max) {
- log_err(cd, _("Maximum keyfile size exceeeded.\n"));
+ log_err(cd, _("Maximum keyfile size exceeded.\n"));
goto out_err;
}
goto out_err;
}
- /* Well, for historical reasons reading empty keyfile is not fail. */
- if(!i) {
- crypt_safe_free(pass);
- pass = NULL;
- }
-
*key = pass;
*key_size = i;
r = 0;