10 #include <sys/types.h>
12 #include <sys/ioctl.h>
16 #include <sys/resource.h>
18 #include "libcryptsetup.h"
22 struct safe_allocation {
27 static char *error=NULL;
29 void set_error_va(const char *fmt, va_list va)
39 if (vasprintf(&error, fmt, va) < 0) {
45 void set_error(const char *fmt, ...)
50 set_error_va(fmt, va);
54 const char *get_error(void)
59 void *safe_alloc(size_t size)
61 struct safe_allocation *alloc;
66 alloc = malloc(size + offsetof(struct safe_allocation, data));
75 void safe_free(void *data)
77 struct safe_allocation *alloc;
82 alloc = data - offsetof(struct safe_allocation, data);
84 memset(data, 0, alloc->size);
86 alloc->size = 0x55aa55aa;
90 void *safe_realloc(void *data, size_t size)
94 new_data = safe_alloc(size);
96 if (new_data && data) {
97 struct safe_allocation *alloc;
99 alloc = data - offsetof(struct safe_allocation, data);
101 if (size > alloc->size)
104 memcpy(new_data, data, size);
111 char *safe_strdup(const char *s)
113 char *s2 = safe_alloc(strlen(s) + 1);
118 return strcpy(s2, s);
121 static int get_alignment(int fd)
123 int alignment = DEFAULT_ALIGNMENT;
125 #ifdef _PC_REC_XFER_ALIGN
126 alignment = fpathconf(fd, _PC_REC_XFER_ALIGN);
128 alignment = DEFAULT_ALIGNMENT;
133 static void *aligned_malloc(void **base, int size, int alignment)
135 #ifdef HAVE_POSIX_MEMALIGN
136 return posix_memalign(base, alignment, size) ? NULL : *base;
138 /* Credits go to Michal's padlock patches for this alignment code */
141 ptr = malloc(size + alignment);
142 if(ptr == NULL) return NULL;
145 if(alignment > 1 && ((long)ptr & (alignment - 1))) {
146 ptr += alignment - ((long)(ptr) & (alignment - 1));
151 static int sector_size(int fd)
154 if (ioctl(fd,BLKSSZGET, &bsize) < 0)
160 int sector_size_for_device(const char *device)
162 int fd = open(device, O_RDONLY);
171 ssize_t write_blockwise(int fd, const void *orig_buf, size_t count)
173 void *hangover_buf, *hangover_buf_base = NULL;
174 void *buf, *buf_base = NULL;
175 int r, hangover, solid, bsize, alignment;
178 if ((bsize = sector_size(fd)) < 0)
181 hangover = count % bsize;
182 solid = count - hangover;
183 alignment = get_alignment(fd);
185 if ((long)orig_buf & (alignment - 1)) {
186 buf = aligned_malloc(&buf_base, count, alignment);
189 memcpy(buf, orig_buf, count);
191 buf = (void *)orig_buf;
193 r = write(fd, buf, solid);
194 if (r < 0 || r != solid)
198 hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
202 r = read(fd, hangover_buf, bsize);
203 if(r < 0 || r != bsize) goto out;
205 r = lseek(fd, -bsize, SEEK_CUR);
208 memcpy(hangover_buf, buf + solid, hangover);
210 r = write(fd, hangover_buf, bsize);
211 if(r < 0 || r != bsize) goto out;
212 free(hangover_buf_base);
221 ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
222 void *hangover_buf, *hangover_buf_base;
223 void *buf, *buf_base = NULL;
224 int r, hangover, solid, bsize, alignment;
227 if ((bsize = sector_size(fd)) < 0)
230 hangover = count % bsize;
231 solid = count - hangover;
232 alignment = get_alignment(fd);
234 if ((long)orig_buf & (alignment - 1)) {
235 buf = aligned_malloc(&buf_base, count, alignment);
241 r = read(fd, buf, solid);
242 if(r < 0 || r != solid) {
243 set_error("read failed in read_blockwise.\n");
248 hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
251 r = read(fd, hangover_buf, bsize);
252 if (r < 0 || r != bsize)
255 memcpy(buf + solid, hangover_buf, hangover);
256 free(hangover_buf_base);
260 if (buf != orig_buf) {
261 memcpy(orig_buf, buf, count);
268 * Combines llseek with blockwise write. write_blockwise can already deal with short writes
269 * but we also need a function to deal with short writes at the start. But this information
270 * is implicitly included in the read/write offset, which can not be set to non-aligned
271 * boundaries. Hence, we combine llseek with write.
274 ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offset) {
275 int bsize = sector_size(fd);
276 const char *orig_buf = buf;
277 char frontPadBuf[bsize];
278 int frontHang = offset % bsize;
280 int innerCount = count < bsize ? count : bsize;
285 lseek(fd, offset - frontHang, SEEK_SET);
287 r = read(fd,frontPadBuf,bsize);
290 memcpy(frontPadBuf+frontHang, buf, innerCount);
292 lseek(fd, offset - frontHang, SEEK_SET);
293 r = write(fd,frontPadBuf,bsize);
299 if(count <= 0) return buf - orig_buf;
301 return write_blockwise(fd, buf, count) + innerCount;
304 /* Password reading helpers */
306 static int untimed_read(int fd, char *pass, size_t maxlen)
310 i = read(fd, pass, maxlen);
314 } else if (i == 0) { /* EOF */
321 static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
332 if (select(fd+1, &fds, NULL, NULL, &t) > 0)
333 failed = untimed_read(fd, pass, maxlen);
335 set_error("Operation timed out");
339 static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
342 struct termios orig, tmp;
344 int infd = STDIN_FILENO, outfd;
349 /* Read and write to /dev/tty if available */
350 if ((infd = outfd = open("/dev/tty", O_RDWR)) == -1) {
352 outfd = STDERR_FILENO;
355 if (tcgetattr(infd, &orig)) {
356 set_error("Unable to get terminal");
359 memcpy(&tmp, &orig, sizeof(tmp));
360 tmp.c_lflag &= ~ECHO;
362 if (write(outfd, prompt, strlen(prompt)) < 0)
365 tcsetattr(infd, TCSAFLUSH, &tmp);
367 failed = timed_read(infd, pass, maxlen, timeout);
369 failed = untimed_read(infd, pass, maxlen);
370 tcsetattr(infd, TCSAFLUSH, &orig);
374 (void)write(outfd, "\n", 1);
375 if (infd != STDIN_FILENO)
381 * Password reading behaviour matrix of get_key
384 * -----------------+---+---+---+---
385 * interactive | Y | Y | Y | Inf
386 * from fd | N | N | Y | Inf
387 * from binary file | N | N | N | Inf or options->key_size
389 * Legend: p..prompt, v..can verify, n..newline-stop, h..read horizon
391 * Note: --key-file=- is interpreted as a read from a binary file (stdin)
393 * Returns true when more keys are available (that is when password
394 * reading can be retried as for interactive terminals).
397 int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
398 const char *key_file, int passphrase_fd, int timeout, int how2verify)
401 const int verify = how2verify & CRYPT_FLAG_VERIFY;
402 const int verify_if_possible = how2verify & CRYPT_FLAG_VERIFY_IF_POSSIBLE;
407 if(key_file && !strcmp(key_file, "-")) {
408 /* Allow binary reading from stdin */
412 } else if (key_file) {
413 fd = open(key_file, O_RDONLY);
416 set_error("Error opening key file: %s",
417 strerror_r(errno, buf, 128));
422 /* This can either be 0 (LUKS) or the actually number
423 * of key bytes (default or passed by -s) */
424 read_horizon = key_size;
428 read_horizon = 0; /* Infinite, if read from terminal or fd */
431 /* Interactive case */
435 pass = safe_alloc(512);
436 if (!pass || (i = interactive_pass(prompt, pass, 512, timeout))) {
437 set_error("Error reading passphrase");
440 if (verify || verify_if_possible) {
441 char pass_verify[512];
442 i = interactive_pass("Verify passphrase: ", pass_verify, sizeof(pass_verify), timeout);
443 if (i || strcmp(pass, pass_verify) != 0) {
444 set_error("Passphrases do not match");
447 memset(pass_verify, 0, sizeof(pass_verify));
449 *passLen = strlen(pass);
453 * This is either a fd-input or a file, in neither case we can verify the input,
454 * however we don't stop on new lines if it's a binary file.
459 set_error("Can't do passphrase verification on non-tty inputs");
462 /* The following for control loop does an exhausting
463 * read on the key material file, if requested with
464 * key_size == 0, as it's done by LUKS. However, we
465 * should warn the user, if it's a non-regular file,
466 * such as /dev/random, because in this case, the loop
469 if(key_file && strcmp(key_file, "-") && read_horizon == 0) {
471 if(stat(key_file, &st) < 0) {
472 set_error("Can't stat key file");
475 if(!S_ISREG(st.st_mode)) {
476 // set_error("Can't do exhausting read on non regular files");
478 fprintf(stderr,"Warning: exhausting read requested, but key file is not a regular file, function might never return.\n");
482 for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
483 if(i >= buflen - 1) {
485 pass = safe_realloc(pass, buflen);
487 set_error("Not enough memory while "
488 "reading passphrase");
492 if(read(fd, pass + i, 1) != 1 || (newline_stop && pass[i] == '\n'))
502 return isatty(fd); /* Return true, when password reading can be tried on interactive fds */
513 #define DEFAULT_PROCESS_PRIORITY -18
515 static int _priority;
516 static int _memlock_count = 0;
518 // return 1 if memory is locked
519 int memlock_inc(struct crypt_device *ctx)
521 if (!_memlock_count++) {
522 if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
523 set_error(_("WARNING!!! Possibly insecure memory. Are you root?\n"));
528 if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno)
529 set_error(_("Cannot get process priority.\n"));
531 if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY))
532 set_error(_("setpriority %u failed: %s"),
533 DEFAULT_PROCESS_PRIORITY, strerror(errno));
535 return _memlock_count ? 1 : 0;
538 int memlock_dec(struct crypt_device *ctx)
540 if (_memlock_count && (!--_memlock_count)) {
542 set_error(_("Cannot unlock memory."));
543 if (setpriority(PRIO_PROCESS, 0, _priority))
544 set_error(_("setpriority %u failed: %s"), _priority, strerror(errno));
546 return _memlock_count ? 1 : 0;