--- old/usr/src/cmd/lofiadm/main.c	2016-02-27 21:21:24.568462984 +0300
+++ new/usr/src/cmd/lofiadm/main.c	2016-02-27 21:21:24.575650008 +0300
@@ -25,6 +25,7 @@
  *
  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  * Copyright (c) 2014 Gary Mills
+ * Copyright (c) 2016 Andrey Sokolov
  */
 
 /*
@@ -153,6 +154,8 @@
 #define	GIGABYTE		(KILOBYTE * MEGABYTE)
 #define	LIBZ			"libz.so.1"
 
+const char lofi_crypto_magic[6] = LOFI_CRYPTO_MAGIC;
+
 static void
 usage(const char *pname)
 {
@@ -215,7 +218,7 @@
 /*ARGSUSED*/
 static int
 lzma_compress(void *src, size_t srclen, void *dst,
-	size_t *dstlen, int level)
+    size_t *dstlen, int level)
 {
 	CLzmaEncProps props;
 	size_t outsize2;
@@ -835,7 +838,8 @@
  * 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;
@@ -866,7 +870,8 @@
 		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"));
 	}
 
@@ -1759,6 +1764,28 @@
 	}
 }
 
+static boolean_t
+check_file_is_encrypted(const char *filename)
+{
+	int	fd;
+	char    buf[sizeof (lofi_crypto_magic)];
+
+	fd = open64(filename, O_RDONLY);
+	if (fd == -1) {
+		die(gettext("open: %s"), filename);
+	}
+	if (lseek(fd, CRYOFF, SEEK_SET) != CRYOFF) {
+		die(gettext("lseek: %s"), filename);
+	}
+	if (read(fd, buf, sizeof (buf)) != sizeof (buf)) {
+		die(gettext("read: %s"), filename);
+	}
+	(void) close(fd);
+
+	return (strncmp(buf, lofi_crypto_magic,
+	    sizeof (lofi_crypto_magic)) == 0);
+}
+
 static uint32_t
 convert_to_num(const char *str)
 {
@@ -1832,7 +1859,7 @@
 	(void) setlocale(LC_ALL, "");
 	(void) textdomain(TEXT_DOMAIN);
 
-	while ((c = getopt(argc, argv, "a:c:Cd:efk:o:rs:T:U")) != EOF) {
+	while ((c = getopt(argc, argv, "a:c:Cd:efk:rs:T:U")) != EOF) {
 		switch (c) {
 		case 'a':
 			addflag = B_TRUE;
@@ -2021,7 +2048,8 @@
 		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);
--- old/usr/src/uts/common/io/lofi.c	2016-02-27 21:21:24.885937830 +0300
+++ new/usr/src/uts/common/io/lofi.c	2016-02-27 21:21:24.893212411 +0300
@@ -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"
--- old/usr/src/uts/common/sys/lofi.h	2016-02-27 21:21:25.209821185 +0300
+++ new/usr/src/uts/common/sys/lofi.h	2016-02-27 21:21:25.216844432 +0300
@@ -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 @@
 #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 @@
  * 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 */
 
