diff options
| -rw-r--r-- | usr/src/cmd/lofiadm/main.c | 46 | ||||
| -rw-r--r-- | usr/src/uts/common/io/lofi.c | 10 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/lofi.h | 13 |
3 files changed, 56 insertions, 13 deletions
diff --git a/usr/src/cmd/lofiadm/main.c b/usr/src/cmd/lofiadm/main.c index 991ca7b994..542bec8063 100644 --- a/usr/src/cmd/lofiadm/main.c +++ b/usr/src/cmd/lofiadm/main.c @@ -154,6 +154,8 @@ lofi_compress_info_t lofi_compress_table[LOFI_COMPRESS_FUNCTIONS] = { #define GIGABYTE (KILOBYTE * MEGABYTE) #define LIBZ "libz.so.1" +const char lofi_crypto_magic[6] = LOFI_CRYPTO_MAGIC; + static void usage(const char *pname) { @@ -836,7 +838,8 @@ parsetoken(char *spec) * PBE the passphrase into a raw key */ static void -getkeyfromuser(mech_alias_t *cipher, char **raw_key, size_t *raw_key_sz) +getkeyfromuser(mech_alias_t *cipher, char **raw_key, size_t *raw_key_sz, + boolean_t with_confirmation) { CK_SESSION_HANDLE sess; CK_RV rv; @@ -867,7 +870,8 @@ getkeyfromuser(mech_alias_t *cipher, char **raw_key, size_t *raw_key_sz) goto cleanup; /* get user passphrase with 8 byte minimum */ - if (pkcs11_get_pass(NULL, &pass, &passlen, MIN_PASSLEN, B_TRUE) < 0) { + if (pkcs11_get_pass(NULL, &pass, &passlen, MIN_PASSLEN, + with_confirmation) < 0) { die(gettext("passphrases do not match\n")); } @@ -1760,6 +1764,41 @@ check_file_validity(const char *filename) } } +static boolean_t +check_file_is_encrypted(const char *filename) +{ + int fd; + char buf[sizeof (lofi_crypto_magic)]; + int got; + int rest = sizeof (lofi_crypto_magic); + + fd = open64(filename, O_RDONLY); + if (fd == -1) + die(gettext("failed to open: %s"), filename); + + if (lseek(fd, CRYOFF, SEEK_SET) != CRYOFF) + die(gettext("failed to seek to offset 0x%lx in file %s"), + CRYOFF, filename); + + do { + got = read(fd, buf + sizeof (lofi_crypto_magic) - rest, rest); + if ((got == 0) || ((got == -1) && (errno != EINTR))) + die(gettext("failed to read crypto header" + " at offset 0x%lx in file %s"), CRYOFF, filename); + + if (got > 0) + rest -= got; + } while (rest > 0); + + while (close(fd) == -1) { + if (errno != EINTR) + die(gettext("failed to close file %s"), filename); + } + + return (strncmp(buf, lofi_crypto_magic, + sizeof (lofi_crypto_magic)) == 0); +} + static uint32_t convert_to_num(const char *str) { @@ -2022,7 +2061,8 @@ main(int argc, char *argv[]) init_crypto(token, cipher, &sess); if (cipher_only) { - getkeyfromuser(cipher, &rkey, &rksz); + getkeyfromuser(cipher, &rkey, &rksz, + !check_file_is_encrypted(filename)); } else if (token != NULL) { getkeyfromtoken(sess, token, keyfile, cipher, &rkey, &rksz); diff --git a/usr/src/uts/common/io/lofi.c b/usr/src/uts/common/io/lofi.c index 9f390dc939..e11f910a91 100644 --- a/usr/src/uts/common/io/lofi.c +++ b/usr/src/uts/common/io/lofi.c @@ -22,6 +22,7 @@ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2016 Andrey Sokolov */ /* @@ -132,15 +133,6 @@ #include <sys/rctl.h> #include <LzmaDec.h> -/* - * The basis for CRYOFF is derived from usr/src/uts/common/sys/fs/ufs_fs.h. - * Crypto metadata, if it exists, is located at the end of the boot block - * (BBOFF + BBSIZE, which is SBOFF). The super block and everything after - * is offset by the size of the crypto metadata which is handled by - * lsp->ls_crypto_offset. - */ -#define CRYOFF ((off_t)8192) - #define NBLOCKS_PROP_NAME "Nblocks" #define SIZE_PROP_NAME "Size" #define ZONE_PROP_NAME "zone" diff --git a/usr/src/uts/common/sys/lofi.h b/usr/src/uts/common/sys/lofi.h index 957c4b4feb..e4716c96af 100644 --- a/usr/src/uts/common/sys/lofi.h +++ b/usr/src/uts/common/sys/lofi.h @@ -22,6 +22,7 @@ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2016 Andrey Sokolov */ #ifndef _SYS_LOFI_H @@ -163,6 +164,17 @@ struct lofi_ioctl { #define S_ISLOFIABLE(mode) \ (S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode)) +/* + * The basis for CRYOFF is derived from usr/src/uts/common/sys/fs/ufs_fs.h. + * Crypto metadata, if it exists, is located at the end of the boot block + * (BBOFF + BBSIZE, which is SBOFF). The super block and everything after + * is offset by the size of the crypto metadata which is handled by + * lsp->ls_crypto_offset. + */ +#define CRYOFF ((off_t)8192) + +#define LOFI_CRYPTO_MAGIC { 'C', 'F', 'L', 'O', 'F', 'I' } + #if defined(_KERNEL) @@ -195,7 +207,6 @@ struct compbuf { * Need exactly 6 bytes to identify encrypted lofi image */ extern const char lofi_crypto_magic[6]; -#define LOFI_CRYPTO_MAGIC { 'C', 'F', 'L', 'O', 'F', 'I' } #define LOFI_CRYPTO_VERSION ((uint16_t)0) #define LOFI_CRYPTO_DATA_SECTOR ((uint32_t)16) /* for version 0 */ |
