summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/lofiadm/main.c46
-rw-r--r--usr/src/uts/common/io/lofi.c10
-rw-r--r--usr/src/uts/common/sys/lofi.h13
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 */