1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  23  *
  24  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2016 Andrey Sokolov
  26  */
  27 
  28 #ifndef _SYS_LOFI_H
  29 #define _SYS_LOFI_H
  30 
  31 #include <sys/types.h>
  32 #include <sys/time.h>
  33 #include <sys/taskq.h>
  34 #include <sys/vtoc.h>
  35 #include <sys/dkio.h>
  36 #include <sys/vnode.h>
  37 #include <sys/list.h>
  38 #include <sys/crypto/api.h>
  39 #include <sys/zone.h>
  40 
  41 #ifdef  __cplusplus
  42 extern "C" {
  43 #endif
  44 
  45 /*
  46  * /dev names:
  47  *      /dev/lofictl    - master control device
  48  *      /dev/lofi       - block devices, named by minor number
  49  *      /dev/rlofi      - character devices, named by minor number
  50  */
  51 #define LOFI_DRIVER_NAME        "lofi"
  52 #define LOFI_CTL_NODE           "ctl"
  53 #define LOFI_CTL_NAME           LOFI_DRIVER_NAME LOFI_CTL_NODE
  54 #define LOFI_BLOCK_NAME         LOFI_DRIVER_NAME
  55 #define LOFI_CHAR_NAME          "r" LOFI_DRIVER_NAME
  56 
  57 #define SEGHDR          1
  58 #define COMPRESSED      1
  59 #define UNCOMPRESSED    0
  60 #define MAXALGLEN       36
  61 
  62 /*
  63  *
  64  * Use is:
  65  *      ld = open("/dev/lofictl", O_RDWR | O_EXCL);
  66  *
  67  * lofi must be opened exclusively. Access is controlled by permissions on
  68  * the device, which is 644 by default. Write-access is required for ioctls
  69  * that change state, but only read-access is required for the ioctls that
  70  * return information. Basically, only root can add and remove files, but
  71  * non-root can look at the current lists.
  72  *
  73  * ioctl usage:
  74  *
  75  * kernel ioctls
  76  *
  77  *      strcpy(li.li_filename, "somefilename");
  78  *      ioctl(ld, LOFI_MAP_FILE, &li);
  79  *      newminor = li.li_minor;
  80  *
  81  *      strcpy(li.li_filename, "somefilename");
  82  *      ioctl(ld, LOFI_UNMAP_FILE, &li);
  83  *
  84  *      strcpy(li.li_filename, "somefilename");
  85  *      li.li_minor = minor_number;
  86  *      ioctl(ld, LOFI_MAP_FILE_MINOR, &li);
  87  *
  88  *      li.li_minor = minor_number;
  89  *      ioctl(ld, LOFI_UNMAP_FILE_MINOR, &li);
  90  *
  91  *      li.li_minor = minor_number;
  92  *      ioctl(ld, LOFI_GET_FILENAME, &li);
  93  *      filename = li.li_filename;
  94  *      encrypted = li.li_crypto_enabled;
  95  *
  96  *      strcpy(li.li_filename, "somefilename");
  97  *      ioctl(ld, LOFI_GET_MINOR, &li);
  98  *      minor = li.li_minor;
  99  *
 100  *      li.li_minor = 0;
 101  *      ioctl(ld, LOFI_GET_MAXMINOR, &li);
 102  *      maxminor = li.li_minor;
 103  *
 104  *      strcpy(li.li_filename, "somefilename");
 105  *      li.li_minor = 0;
 106  *      ioctl(ld, LOFI_CHECK_COMPRESSED, &li);
 107  *
 108  * If the 'li_force' flag is set for any of the LOFI_UNMAP_* commands, then if
 109  * the device is busy, the underlying vnode will be closed, and any subsequent
 110  * operations will fail.  It will behave as if the device had been forcibly
 111  * removed, so the DKIOCSTATE ioctl will return DKIO_DEV_GONE.  When the device
 112  * is last closed, it will be torn down.
 113  *
 114  * If the 'li_cleanup' flag is set for any of the LOFI_UNMAP_* commands, then
 115  * if the device is busy, it is marked for removal at the next time it is
 116  * no longer held open by anybody.  When the device is last closed, it will be
 117  * torn down.
 118  *
 119  * Oh, and last but not least: these ioctls are totally private and only
 120  * for use by lofiadm(1M).
 121  *
 122  */
 123 
 124 typedef enum    iv_method {
 125         IVM_NONE,       /* no iv needed, iv is null */
 126         IVM_ENC_BLKNO   /* iv is logical block no. encrypted */
 127 } iv_method_t;
 128 
 129 struct lofi_ioctl {
 130         uint32_t        li_minor;
 131         boolean_t       li_force;
 132         boolean_t       li_cleanup;
 133         boolean_t       li_readonly;
 134         char    li_filename[MAXPATHLEN];
 135 
 136         /* the following fields are required for compression support */
 137         char    li_algorithm[MAXALGLEN];
 138 
 139         /* the following fields are required for encryption support */
 140         boolean_t       li_crypto_enabled;
 141         crypto_mech_name_t      li_cipher;      /* for data */
 142         uint32_t        li_key_len;             /* for data */
 143         char            li_key[56];     /* for data: max 448-bit Blowfish key */
 144         crypto_mech_name_t      li_iv_cipher;   /* for iv derivation */
 145         uint32_t        li_iv_len;              /* for iv derivation */
 146         iv_method_t     li_iv_type;             /* for iv derivation */
 147 };
 148 
 149 #define LOFI_IOC_BASE           (('L' << 16) | ('F' << 8))
 150 
 151 #define LOFI_MAP_FILE           (LOFI_IOC_BASE | 0x01)
 152 #define LOFI_MAP_FILE_MINOR     (LOFI_IOC_BASE | 0x02)
 153 #define LOFI_UNMAP_FILE         (LOFI_IOC_BASE | 0x03)
 154 #define LOFI_UNMAP_FILE_MINOR   (LOFI_IOC_BASE | 0x04)
 155 #define LOFI_GET_FILENAME       (LOFI_IOC_BASE | 0x05)
 156 #define LOFI_GET_MINOR          (LOFI_IOC_BASE | 0x06)
 157 #define LOFI_GET_MAXMINOR       (LOFI_IOC_BASE | 0x07)
 158 #define LOFI_CHECK_COMPRESSED   (LOFI_IOC_BASE | 0x08)
 159 
 160 /*
 161  * file types that might be usable with lofi, maybe. Only regular
 162  * files are documented though.
 163  */
 164 #define S_ISLOFIABLE(mode) \
 165         (S_ISREG(mode) || S_ISBLK(mode) || S_ISCHR(mode))
 166 
 167 /*
 168  * The basis for CRYOFF is derived from usr/src/uts/common/sys/fs/ufs_fs.h.
 169  * Crypto metadata, if it exists, is located at the end of the boot block
 170  * (BBOFF + BBSIZE, which is SBOFF).  The super block and everything after
 171  * is offset by the size of the crypto metadata which is handled by
 172  * lsp->ls_crypto_offset.
 173  */
 174 #define CRYOFF  ((off_t)8192)
 175 
 176 #define LOFI_CRYPTO_MAGIC       { 'C', 'F', 'L', 'O', 'F', 'I' }
 177 
 178 #if defined(_KERNEL)
 179 
 180 
 181 /*
 182  * Cache decompressed data segments for the compressed lofi images.
 183  *
 184  * To avoid that we have to decompress data of a compressed
 185  * segment multiple times when accessing parts of the segment's
 186  * data we cache the uncompressed data, using a simple linked list.
 187  */
 188 struct lofi_comp_cache {
 189         list_node_t     lc_list;                /* linked list */
 190         uchar_t         *lc_data;               /* decompressed segment data */
 191         uint64_t        lc_index;               /* segment index */
 192 };
 193 
 194 #define V_ISLOFIABLE(vtype) \
 195         ((vtype == VREG) || (vtype == VBLK) || (vtype == VCHR))
 196 
 197 /*
 198  * Pre-allocated memory buffers for the purpose of compression
 199  */
 200 struct compbuf {
 201         void            *buf;
 202         uint32_t        bufsize;
 203         int             inuse;
 204 };
 205 
 206 /*
 207  * Need exactly 6 bytes to identify encrypted lofi image
 208  */
 209 extern const char lofi_crypto_magic[6];
 210 #define LOFI_CRYPTO_VERSION     ((uint16_t)0)
 211 #define LOFI_CRYPTO_DATA_SECTOR ((uint32_t)16)          /* for version 0 */
 212 
 213 /*
 214  * Crypto metadata for encrypted lofi images
 215  * The fields here only satisfy initial implementation requirements.
 216  */
 217 struct crypto_meta {
 218         char            magic[6];               /* LOFI_CRYPTO_MAGIC */
 219         uint16_t        version;                /* version of encrypted lofi */
 220         char            reserved1[96];          /* future use */
 221         uint32_t        data_sector;            /* start of data area */
 222         char            pad[404];               /* end on DEV_BSIZE bdry */
 223         /* second header block is not defined at this time */
 224 };
 225 
 226 struct lofi_state {
 227         vnode_t         *ls_vp;         /* open real vnode */
 228         vnode_t         *ls_stacked_vp; /* open vnode */
 229         kmutex_t        ls_vp_lock;     /* protects ls_vp */
 230         kcondvar_t      ls_vp_cv;       /* signal changes to ls_vp */
 231         uint32_t        ls_vp_iocount;  /* # pending I/O requests */
 232         boolean_t       ls_vp_closereq; /* force close requested */
 233         u_offset_t      ls_vp_size;
 234         uint32_t        ls_blk_open;
 235         uint32_t        ls_chr_open;
 236         uint32_t        ls_lyr_open_count;
 237         int             ls_openflag;
 238         boolean_t       ls_cleanup;     /* cleanup on close */
 239         boolean_t       ls_readonly;
 240         taskq_t         *ls_taskq;
 241         kstat_t         *ls_kstat;
 242         kmutex_t        ls_kstat_lock;
 243         struct dk_geom  ls_dkg;
 244         struct vtoc     ls_vtoc;
 245         struct dk_cinfo ls_ci;
 246         zone_ref_t      ls_zone;
 247         list_node_t     ls_list;        /* all lofis */
 248         dev_t           ls_dev;         /* this node's dev_t */
 249 
 250         /* the following fields are required for compression support */
 251         int             ls_comp_algorithm_index; /* idx into compress_table */
 252         char            ls_comp_algorithm[MAXALGLEN];
 253         uint32_t        ls_uncomp_seg_sz; /* sz of uncompressed segment */
 254         uint32_t        ls_comp_index_sz; /* number of index entries */
 255         uint32_t        ls_comp_seg_shift; /* exponent for byte shift */
 256         uint32_t        ls_uncomp_last_seg_sz; /* sz of last uncomp segment */
 257         uint64_t        ls_comp_offbase; /* offset of actual compressed data */
 258         uint64_t        *ls_comp_seg_index; /* array of index entries */
 259         caddr_t         ls_comp_index_data; /* index pages loaded from file */
 260         uint32_t        ls_comp_index_data_sz;
 261         u_offset_t      ls_vp_comp_size; /* actual compressed file size */
 262 
 263         /* pre-allocated list of buffers for compressed segment data */
 264         kmutex_t        ls_comp_bufs_lock;
 265         struct compbuf  *ls_comp_bufs;
 266 
 267         /* lock and anchor for compressed segment caching */
 268         kmutex_t        ls_comp_cache_lock;     /* protects ls_comp_cache */
 269         list_t          ls_comp_cache;          /* cached decompressed segs */
 270         uint32_t        ls_comp_cache_count;
 271 
 272         /* the following fields are required for encryption support */
 273         boolean_t               ls_crypto_enabled;
 274         u_offset_t              ls_crypto_offset;       /* crypto meta size */
 275         struct crypto_meta      ls_crypto;
 276         crypto_mechanism_t      ls_mech;        /* for data encr/decr */
 277         crypto_key_t            ls_key;         /* for data encr/decr */
 278         crypto_mechanism_t      ls_iv_mech;     /* for iv derivation */
 279         size_t                  ls_iv_len;      /* for iv derivation */
 280         iv_method_t             ls_iv_type;     /* for iv derivation */
 281         kmutex_t                ls_crypto_lock;
 282         crypto_ctx_template_t   ls_ctx_tmpl;
 283 
 284 };
 285 
 286 #endif  /* _KERNEL */
 287 
 288 /*
 289  * Common signature for all lofi compress functions
 290  */
 291 typedef int lofi_compress_func_t(void *src, size_t srclen, void *dst,
 292         size_t *destlen, int level);
 293 
 294 /*
 295  * Information about each compression function
 296  */
 297 typedef struct lofi_compress_info {
 298         lofi_compress_func_t    *l_decompress;
 299         lofi_compress_func_t    *l_compress;
 300         int                     l_level;
 301         char                    *l_name;        /* algorithm name */
 302 } lofi_compress_info_t;
 303 
 304 enum lofi_compress {
 305         LOFI_COMPRESS_GZIP = 0,
 306         LOFI_COMPRESS_GZIP_6 = 1,
 307         LOFI_COMPRESS_GZIP_9 = 2,
 308         LOFI_COMPRESS_LZMA = 3,
 309         LOFI_COMPRESS_FUNCTIONS
 310 };
 311 
 312 #ifdef  __cplusplus
 313 }
 314 #endif
 315 
 316 #endif  /* _SYS_LOFI_H */