Fix skcipher failure handling.
[platform/upstream/cryptsetup.git] / src / cryptsetup.c
index 0cc7f07..820fdba 100644 (file)
@@ -44,7 +44,7 @@ static uint64_t opt_offset = 0;
 static uint64_t opt_skip = 0;
 static int opt_skip_valid = 0;
 static int opt_readonly = 0;
-static int opt_iteration_time = 1000;
+static int opt_iteration_time = DEFAULT_LUKS1_ITER_TIME;
 static int opt_version_mode = 0;
 static int opt_timeout = 0;
 static int opt_tries = 3;
@@ -82,6 +82,7 @@ static int action_luksRestore(int arg);
 static int action_loopaesOpen(int arg);
 static int action_luksRepair(int arg);
 static int action_tcryptOpen(int arg);
+static int action_tcryptDump(int arg);
 
 static struct action_type {
        const char *type;
@@ -115,6 +116,7 @@ static struct action_type {
        { "loopaesOpen",action_loopaesOpen,     0, 2, 1, N_("<device> <name> "), N_("open loop-AES device as mapping <name>") },
        { "loopaesClose",action_remove,         0, 1, 1, N_("<name>"), N_("remove loop-AES mapping") },
        { "tcryptOpen", action_tcryptOpen,      0, 2, 1, N_("<device> <name> "), N_("open TCRYPT device as mapping <name>") },
+       { "tcryptDump", action_tcryptDump,      0, 1, 1, N_("<device>"), N_("dump TCRYPT device information") },
        { NULL, NULL, 0, 0, 0, NULL, NULL }
 };
 
@@ -302,6 +304,41 @@ out:
        return r;
 }
 
+static int action_tcryptDump(int arg __attribute__((unused)))
+{
+       struct crypt_device *cd = NULL;
+       struct crypt_params_tcrypt params = {
+               .keyfiles = opt_keyfiles,
+               .keyfiles_count = opt_keyfiles_count,
+               .flags = CRYPT_TCRYPT_LEGACY_MODES,
+       };
+       int r;
+
+       if ((r = crypt_init(&cd, action_argv[0])))
+               goto out;
+
+       /* TCRYPT header is encrypted, get passphrase now */
+       r = crypt_get_key(_("Enter passphrase: "),
+                         CONST_CAST(char**)&params.passphrase,
+                         &params.passphrase_size, 0, 0, NULL, opt_timeout,
+                         _verify_passphrase(0), cd);
+       if (r < 0)
+               goto out;
+
+       if (opt_hidden)
+               params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
+
+       r = crypt_load(cd, CRYPT_TCRYPT, &params);
+       if (r < 0)
+               goto out;
+
+       r = crypt_dump(cd);
+out:
+       crypt_free(cd);
+       crypt_safe_free(CONST_CAST(char*)params.passphrase);
+       return r;
+}
+
 static int action_remove(int arg __attribute__((unused)))
 {
        struct crypt_device *cd = NULL;
@@ -425,7 +462,7 @@ static int action_benchmark(int arg __attribute__((unused)))
        char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
        double enc_mbr = 0, dec_mbr = 0;
        int key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS);
-       int iv_size = 16;
+       int iv_size = 16, skipped = 0;
        int buffer_size = 1024 * 1024;
        char *c;
        int i, r;
@@ -452,14 +489,20 @@ static int action_benchmark(int arg __attribute__((unused)))
                        strncat(cipher, cipher_mode, MAX_CIPHER_LEN);
                        log_std("%11s  %4db  %5.1f MiB/s  %5.1f MiB/s\n",
                                cipher, key_size, enc_mbr, dec_mbr);
-               } else
-                       log_err(_("Cannot benchmark %s.\n"), cipher);
+               } else if (r == -ENOENT)
+                       log_err(_("Cipher %s is not available.\n"), opt_cipher);
        } else {
-               log_std("%s", header);
                for (i = 0; bciphers[i].cipher; i++) {
                        r = crypt_benchmark(NULL, bciphers[i].cipher, bciphers[i].mode,
                                            bciphers[i].key_size, bciphers[i].iv_size,
                                            buffer_size, &enc_mbr, &dec_mbr);
+                       if (r == -ENOTSUP)
+                               break;
+                       if (r == -ENOENT)
+                               skipped++;
+                       if (i == 0)
+                               log_std("%s", header);
+
                        snprintf(cipher, MAX_CIPHER_LEN, "%s-%s",
                                 bciphers[i].cipher, bciphers[i].mode);
                        if (!r)
@@ -469,8 +512,13 @@ static int action_benchmark(int arg __attribute__((unused)))
                                log_std("%11s  %4db %12s %12s\n", cipher,
                                        bciphers[i].key_size*8, _("N/A"), _("N/A"));
                }
+               if (skipped == i)
+                       r = -ENOTSUP;
        }
 
+       if (r == -ENOTSUP)
+               log_err( _("Required kernel crypto interface not available.\n"
+                          "Ensure you have algif_skcipher kernel module loaded.\n"));
        return r;
 }
 
@@ -1165,10 +1213,12 @@ static void help(poptContext popt_context,
                         "<key file> optional key file for the new key for luksAddKey action\n"),
                        crypt_get_dir());
 
-               log_std(_("\nDefault compiled-in keyfile parameters:\n"
+               log_std(_("\nDefault compiled-in key and passphrase parameters:\n"
                         "\tMaximum keyfile size: %dkB, "
-                        "Maximum interactive passphrase length %d (characters)\n"),
-                        DEFAULT_KEYFILE_SIZE_MAXKB, DEFAULT_PASSPHRASE_SIZE_MAX);
+                        "Maximum interactive passphrase length %d (characters)\n"
+                        "Default PBKDF2 iteration time for LUKS: %d (ms)\n"),
+                        DEFAULT_KEYFILE_SIZE_MAXKB, DEFAULT_PASSPHRASE_SIZE_MAX,
+                        DEFAULT_LUKS1_ITER_TIME);
 
                log_std(_("\nDefault compiled-in device cipher parameters:\n"
                         "\tloop-AES: %s, Key %d bits\n"
@@ -1423,9 +1473,9 @@ int main(int argc, const char **argv)
                _("Option --offset is supported only for create and loopaesOpen commands.\n"),
                poptGetInvocationName(popt_context));
 
-       if (opt_hidden && strcmp(aname, "tcryptOpen"))
+       if (opt_hidden && strcmp(aname, "tcryptOpen") && strcmp(aname, "tcryptDump"))
                usage(popt_context, EXIT_FAILURE,
-               _("Option --hidden is supported only for tcryptOpen command.\n"),
+               _("Option --hidden is supported only for TCRYPT commands.\n"),
                poptGetInvocationName(popt_context));
 
        if (opt_debug) {