Check if requested hash is supported before writing LUKS header.
[platform/upstream/cryptsetup.git] / tests / api-test.c
index bf38e11..3063dce 100644 (file)
@@ -169,8 +169,10 @@ static void _setup(void)
 
        r = system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\"");
        r = system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"");
-       if (!strncmp("/dev/loop", DEVICE_1, 9))
+       if (!strncmp("/dev/loop", DEVICE_1, 9)) {
+               r = system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2");
                r = system("losetup " DEVICE_1 " " IMAGE1);
+       }
        if (!strncmp("/dev/loop", DEVICE_2, 9)) {
                r = system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4");
                r = system("losetup " DEVICE_2 " " IMAGE_EMPTY);
@@ -291,7 +293,7 @@ static void LuksOpen(void)
 
 static void query_device(void)
 {
-       struct crypt_options co = {. icb = &cmd_icb };
+       struct crypt_options co = {.icb = &cmd_icb };
 
        co.name = CDEVICE_WRONG;
        EQ_(crypt_query_device(&co), 0);
@@ -311,7 +313,7 @@ static void query_device(void)
 static void remove_device(void)
 {
        int fd;
-       struct crypt_options co = {. icb = &cmd_icb };
+       struct crypt_options co = {.icb = &cmd_icb };
 
        co.name = CDEVICE_WRONG;
        EQ_(crypt_remove_device(&co), -ENODEV);
@@ -474,7 +476,6 @@ void DeviceResizeGame(void)
        co.size = 0;
        OK_(crypt_resize_device(&co));
        EQ_(_get_device_size(DMDIR CDEVICE_2), (orig_size - 333));
-
        co.size = 0;
        co.offset = 444;
        co.skip = 555;
@@ -490,10 +491,36 @@ void DeviceResizeGame(void)
        EQ_(co.key_size, 128 / 8);
        EQ_(co.offset, 444);
        EQ_(co.skip, 555);
-       OK_(crypt_remove_device(&co));
+       crypt_put_options(&co);
+
+       // dangerous switch device still works
+       memset(&co, 0, sizeof(co));
+       co.name = CDEVICE_2,
+       co.device = DEVICE_1;
+       co.key_file = KEYFILE2;
+       co.key_size = 128 / 8;
+       co.cipher = "aes-cbc-plain";
+       co.hash = "sha1";
+       co.icb = &cmd_icb;
+       OK_(crypt_update_device(&co));
 
+       memset(&co, 0, sizeof(co));
+       co.icb = &cmd_icb,
+       co.name = CDEVICE_2;
+       EQ_(crypt_query_device(&co), 1);
+       EQ_(strcmp(co.cipher, "aes-cbc-plain"), 0);
+       EQ_(co.key_size, 128 / 8);
+       EQ_(co.offset, 0);
+       EQ_(co.skip, 0);
+       // This expect lookup returns prefered /dev/loopX
+       EQ_(strcmp(co.device, DEVICE_1), 0);
        crypt_put_options(&co);
 
+       memset(&co, 0, sizeof(co));
+       co.icb = &cmd_icb,
+       co.name = CDEVICE_2;
+       OK_(crypt_remove_device(&co));
+
        _remove_keyfiles();
 }
 
@@ -523,6 +550,7 @@ static void AddDevicePlain(void)
        // default is "plain" hash - no password hash
        OK_(crypt_init(&cd, DEVICE_1));
        OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, NULL));
+       FAIL_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0), "cannot verify key with plain");
        OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
        EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
        // FIXME: this should get key from active device?
@@ -534,6 +562,8 @@ static void AddDevicePlain(void)
        // Now use hashed password
        OK_(crypt_init(&cd, DEVICE_1));
        OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, &params));
+       FAIL_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0),
+             "cannot verify passphrase with plain" );
        OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0));
 
        // device status check
@@ -575,6 +605,7 @@ static void UseLuksDevice(void)
        OK_(crypt_init(&cd, DEVICE_1));
        OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
        EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE);
+       OK_(crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
        OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
        FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0), "already open");
        EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
@@ -590,6 +621,7 @@ static void UseLuksDevice(void)
 
        EQ_(0, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1)));
        OK_(crypt_volume_key_verify(cd, key, key_size));
+       OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
        OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
        EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
        OK_(crypt_deactivate(cd, CDEVICE_1));
@@ -665,6 +697,18 @@ static void AddDeviceLuks(void)
        EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE);
        OK_(crypt_deactivate(cd, CDEVICE_2));
 
+       EQ_(1, crypt_keyslot_add_by_volume_key(cd, 1, key, key_size, KEY1, strlen(KEY1)));
+       OK_(_prepare_keyfile(KEYFILE1, KEY1));
+       OK_(_prepare_keyfile(KEYFILE2, KEY2));
+       EQ_(2, crypt_keyslot_add_by_keyfile(cd, 2, KEYFILE1, 0, KEYFILE2, 0));
+       FAIL_(crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, strlen(KEY2)-1, 0), "key mismatch");
+       EQ_(2, crypt_activate_by_keyfile(cd, NULL, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
+       EQ_(2, crypt_activate_by_keyfile(cd, CDEVICE_2, CRYPT_ANY_SLOT, KEYFILE2, 0, 0));
+       OK_(crypt_keyslot_destroy(cd, 1));
+       OK_(crypt_keyslot_destroy(cd, 2));
+       OK_(crypt_deactivate(cd, CDEVICE_2));
+       _remove_keyfiles();
+
        FAIL_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), "slot used");
        key[1] = ~key[1];
        FAIL_(crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)), "key mismatch");
@@ -717,6 +761,10 @@ static void NonFIPSAlg(void)
        }
        OK_(crypt_init(&cd, DEVICE_2));
        OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
+
+       params.hash = "md5";
+       FAIL_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params),
+             "MD5 unsupported, too short");
        crypt_free(cd);
 }
 
@@ -729,7 +777,7 @@ static void _gcrypt_compatible()
        if (!(f = popen("libgcrypt-config --version", "r")))
                return;
 
-       if (fscanf(f, "%d.%d.%d", &maj, &min, &patch) == 2 &&
+       if (fscanf(f, "%d.%d.%d", &maj, &min, &patch) == 3 &&
            maj >= 1 && min >= 4)
                gcrypt_compatible = 1;
        if (_debug)