X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Futils_crypt.c;h=dd7496a3aa490e18903279ed9d0de74526d9ea6a;hb=a9d9a2ad4466432323226f482d4e1d53844c12a3;hp=cf3933880dee6696719d42d20e9e1558c50c8ff3;hpb=075fb8d261f0f6fa08a628895b96e0e79f9c4168;p=platform%2Fupstream%2Fcryptsetup.git diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c index cf39338..dd7496a 100644 --- a/lib/utils_crypt.c +++ b/lib/utils_crypt.c @@ -1,8 +1,8 @@ /* - * util_crypt - cipher utilities for cryptsetup + * utils_crypt - cipher utilities for cryptsetup * * Copyright (C) 2004-2007, Clemens Fruhwirth - * 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 @@ -58,6 +58,15 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums, 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) @@ -257,14 +266,14 @@ 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; @@ -273,8 +282,13 @@ int crypt_get_key(const char *prompt, /* 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 (read_stdin) log_dbg("STDIN descriptor passphrase entry requested."); @@ -303,11 +317,19 @@ int crypt_get_key(const char *prompt, } 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 ((size_t)st.st_size >= keyfile_size_max) + if (file_read_size >= keyfile_size_max) buflen = keyfile_size_max; - else if (st.st_size) - buflen = st.st_size; + else if (file_read_size) + buflen = file_read_size; } } @@ -317,6 +339,13 @@ int crypt_get_key(const char *prompt, 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; @@ -348,7 +377,7 @@ int crypt_get_key(const char *prompt, /* 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; } @@ -368,3 +397,29 @@ out_err: crypt_safe_free(pass); return r; } + +ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc) +{ + char buf[3] = "xx\0", *endp, *bytes; + size_t i, len; + + len = strlen(hex); + if (len % 2) + return -EINVAL; + len /= 2; + + bytes = safe_alloc ? crypt_safe_alloc(len) : malloc(len); + if (!bytes) + return -ENOMEM; + + for (i = 0; i < len; i++) { + memcpy(buf, &hex[i * 2], 2); + bytes[i] = strtoul(buf, &endp, 16); + if (endp != &buf[2]) { + safe_alloc ? crypt_safe_free(bytes) : free(bytes); + return -EINVAL; + } + } + *result = bytes; + return i; +}