Better tcrypt test options.
[platform/upstream/cryptsetup.git] / lib / tcrypt / tcrypt.c
index 373637d..920be02 100644 (file)
@@ -344,6 +344,8 @@ static int decrypt_hdr_cbci(struct tcrypt_algs *ciphers,
        memcpy(iv, &key[ciphers->cipher[0].iv_offset], bs);
 
        /* Initialize all ciphers in chain in ECB mode */
+       for (j = 0; j < ciphers->chain_count; j++)
+               cipher[j] = NULL;
        for (j = 0; j < ciphers->chain_count; j++) {
                r = crypt_cipher_init(&cipher[j], ciphers->cipher[j].name, "ecb",
                                      &key[ciphers->cipher[j].key_offset],
@@ -377,7 +379,7 @@ static int decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
                        const char *key, int legacy_modes)
 {
        struct tcrypt_phdr hdr2;
-       int i, j, r;
+       int i, j, r = -EINVAL;
 
        for (i = 0; tcrypt_cipher[i].chain_count; i++) {
                if (!legacy_modes && tcrypt_cipher[i].legacy)
@@ -398,13 +400,11 @@ static int decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
                                break;
                }
 
-               if (r == -ENOENT) {
-                       log_err(cd, _("Required kernel crypto interface is not available.\n"
-                                     "Ensure you have af_skcipher kernel module loaded.\n"));
-                       return -ENOTSUP;
-               }
                if (r < 0) {
                        log_dbg("TCRYPT:   returned error %d, skipped.", r);
+                       if (r == -ENOTSUP)
+                               break;
+                       r = -ENOENT;
                        continue;
                }
 
@@ -468,7 +468,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
        unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
        size_t passphrase_size;
        char *key;
-       int r = -EINVAL, i, legacy_modes;
+       int r = -EINVAL, i, legacy_modes, skipped = 0;
 
        if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
                return -ENOMEM;
@@ -506,10 +506,17 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
 
                /* Decrypt header */
                r = decrypt_hdr(cd, hdr, key, legacy_modes);
+               if (r == -ENOENT) {
+                       skipped++;
+                       continue;
+               }
                if (r != -EPERM)
                        break;
        }
 
+       if ((skipped && skipped == i) || r == -ENOTSUP)
+               log_err(cd, _("Required kernel crypto interface not available.\n"
+                             "Ensure you have algif_skcipher kernel module loaded.\n"));
        if (r < 0)
                goto out;