Print this page
5857 lofiadm should ask passphrase once if the crypto is already set up
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/lofiadm/main.c
          +++ new/usr/src/cmd/lofiadm/main.c
↓ open down ↓ 146 lines elided ↑ open up ↑
 147  147  
 148  148  #define COMPRESS_ALGORITHM      "gzip"
 149  149  #define COMPRESS_THRESHOLD      2048
 150  150  #define SEGSIZE                 131072
 151  151  #define BLOCK_SIZE              512
 152  152  #define KILOBYTE                1024
 153  153  #define MEGABYTE                (KILOBYTE * KILOBYTE)
 154  154  #define GIGABYTE                (KILOBYTE * MEGABYTE)
 155  155  #define LIBZ                    "libz.so.1"
 156  156  
      157 +const char lofi_crypto_magic[6] = LOFI_CRYPTO_MAGIC;
      158 +
 157  159  static void
 158  160  usage(const char *pname)
 159  161  {
 160  162          (void) fprintf(stderr, gettext(USAGE), pname, pname, pname,
 161  163              pname, pname, pname, pname, pname, pname, pname);
 162  164          exit(E_USAGE);
 163  165  }
 164  166  
 165  167  static int
 166  168  gzip_compress(void *src, size_t srclen, void *dst, size_t *dstlen, int level)
↓ open down ↓ 662 lines elided ↑ open up ↑
 829  831           */
 830  832          if (ti->name == NULL && ti->mfr == NULL && ti->serno == NULL)
 831  833                  ti->name = strdup(pkcs11_default_token());
 832  834          return (ti);
 833  835  }
 834  836  
 835  837  /*
 836  838   * PBE the passphrase into a raw key
 837  839   */
 838  840  static void
 839      -getkeyfromuser(mech_alias_t *cipher, char **raw_key, size_t *raw_key_sz)
      841 +getkeyfromuser(mech_alias_t *cipher, char **raw_key, size_t *raw_key_sz,
      842 +    boolean_t with_confirmation)
 840  843  {
 841  844          CK_SESSION_HANDLE sess;
 842  845          CK_RV   rv;
 843  846          char    *pass = NULL;
 844  847          size_t  passlen = 0;
 845  848          void    *salt = NULL;   /* don't use NULL, see note on salt below */
 846  849          size_t  saltlen = 0;
 847  850          CK_KEY_TYPE ktype;
 848  851          void    *kvalue;
 849  852          size_t  klen;
↓ open down ↓ 10 lines elided ↑ open up ↑
 860  863  
 861  864          /*
 862  865           * use the passphrase to generate a PBE PKCS#5 secret key and
 863  866           * retrieve the raw key data to eventually pass it to the kernel;
 864  867           */
 865  868          rv = C_OpenSession(cipher->slot, CKF_SERIAL_SESSION, NULL, NULL, &sess);
 866  869          if (rv != CKR_OK)
 867  870                  goto cleanup;
 868  871  
 869  872          /* get user passphrase with 8 byte minimum */
 870      -        if (pkcs11_get_pass(NULL, &pass, &passlen, MIN_PASSLEN, B_TRUE) < 0) {
      873 +        if (pkcs11_get_pass(NULL, &pass, &passlen, MIN_PASSLEN,
      874 +            with_confirmation) < 0) {
 871  875                  die(gettext("passphrases do not match\n"));
 872  876          }
 873  877  
 874  878          /*
 875  879           * salt should not be NULL, or else pkcs11_PasswdToKey() will
 876  880           * complain about CKR_MECHANISM_PARAM_INVALID; the following is
 877  881           * to make up for not having a salt until a proper one is used
 878  882           */
 879  883          salt = pass;
 880  884          saltlen = passlen;
↓ open down ↓ 872 lines elided ↑ open up ↑
1753 1757                  die(gettext("size of %s is not a multiple of %d\n"),
1754 1758                      filename, DEV_BSIZE);
1755 1759          }
1756 1760          (void) close(fd);
1757 1761  
1758 1762          if (name_to_minor(filename) != 0) {
1759 1763                  die(gettext("cannot use %s on itself\n"), LOFI_DRIVER_NAME);
1760 1764          }
1761 1765  }
1762 1766  
     1767 +static boolean_t
     1768 +check_file_is_encrypted(const char *filename)
     1769 +{
     1770 +        int     fd;
     1771 +        char    buf[sizeof (lofi_crypto_magic)];
     1772 +        int     got;
     1773 +        int     rest = sizeof (lofi_crypto_magic);
     1774 +
     1775 +        fd = open64(filename, O_RDONLY);
     1776 +        if (fd == -1)
     1777 +                die(gettext("failed to open: %s"), filename);
     1778 +
     1779 +        if (lseek(fd, CRYOFF, SEEK_SET) != CRYOFF)
     1780 +                die(gettext("failed to seek to offset 0x%lx in file %s"),
     1781 +                    CRYOFF, filename);
     1782 +
     1783 +        do {
     1784 +                got = read(fd, buf + sizeof (lofi_crypto_magic) - rest, rest);
     1785 +                if ((got == 0) || ((got == -1) && (errno != EINTR)))
     1786 +                        die(gettext("failed to read crypto header"
     1787 +                            " at offset 0x%lx in file %s"), CRYOFF, filename);
     1788 +
     1789 +                if (got > 0)
     1790 +                        rest -= got;
     1791 +        } while (rest > 0);
     1792 +
     1793 +        while (close(fd) == -1) {
     1794 +                if (errno != EINTR)
     1795 +                        die(gettext("failed to close file %s"), filename);
     1796 +        }
     1797 +
     1798 +        return (strncmp(buf, lofi_crypto_magic,
     1799 +            sizeof (lofi_crypto_magic)) == 0);
     1800 +}
     1801 +
1763 1802  static uint32_t
1764 1803  convert_to_num(const char *str)
1765 1804  {
1766 1805          int len;
1767 1806          uint32_t segsize, mult = 1;
1768 1807  
1769 1808          len = strlen(str);
1770 1809          if (len && isalpha(str[len - 1])) {
1771 1810                  switch (str[len - 1]) {
1772 1811                  case 'k':
↓ open down ↓ 242 lines elided ↑ open up ↑
2015 2054                          cipher = DEFAULT_CIPHER;
2016 2055  
2017 2056                  if (!kernel_cipher_check(cipher))
2018 2057                          die(gettext(
2019 2058                              "use \"cryptoadm list -m\" to find available "
2020 2059                              "mechanisms\n"));
2021 2060  
2022 2061                  init_crypto(token, cipher, &sess);
2023 2062  
2024 2063                  if (cipher_only) {
2025      -                        getkeyfromuser(cipher, &rkey, &rksz);
     2064 +                        getkeyfromuser(cipher, &rkey, &rksz,
     2065 +                            !check_file_is_encrypted(filename));
2026 2066                  } else if (token != NULL) {
2027 2067                          getkeyfromtoken(sess, token, keyfile, cipher,
2028 2068                              &rkey, &rksz);
2029 2069                  } else {
2030 2070                          /* this also handles ephemeral keys */
2031 2071                          getkeyfromfile(keyfile, cipher, &rkey, &rksz);
2032 2072                  }
2033 2073  
2034 2074                  end_crypto(sess);
2035 2075          }
↓ open down ↓ 23 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX