Skip to content

Commit 1f9730f

Browse files
Merge pull request #1095 from vojtechtrefny/master_set-persistent-flags
crypto: Add a function to set persistent flags for LUKS
2 parents edb5c84 + 1fffc8e commit 1f9730f

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ AS_IF([test "x$with_crypto" != "xno"],
207207
[AC_DEFINE([LIBCRYPTSETUP_26])], [])
208208
AS_IF([$PKG_CONFIG --atleast-version=2.7.0 libcryptsetup],
209209
[AC_DEFINE([LIBCRYPTSETUP_27])], [])
210+
AS_IF([$PKG_CONFIG --atleast-version=2.8.0 libcryptsetup],
211+
[AC_DEFINE([LIBCRYPTSETUP_28])], [])
210212
AC_CHECK_HEADER([linux/sed-opal.h],
211213
[AC_DEFINE([HAVE_LINUX_OPAL])], [])
212214
AS_IF([test "x$with_escrow" != "xno"],

src/lib/plugin_apis/crypto.api

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,16 @@ typedef enum {
380380
BD_CRYPTO_LUKS_HW_ENCRYPTION_OPAL_HW_AND_SW,
381381
} BDCryptoLUKSHWEncryptionType;
382382

383+
typedef enum {
384+
BD_CRYPTO_LUKS_ACTIVATE_ALLOW_DISCARDS = 1 << 0,
385+
BD_CRYPTO_LUKS_ACTIVATE_SAME_CPU_CRYPT = 1 << 1,
386+
BD_CRYPTO_LUKS_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS = 1 << 2,
387+
BD_CRYPTO_LUKS_ACTIVATE_NO_JOURNAL = 1 << 3,
388+
BD_CRYPTO_LUKS_ACTIVATE_NO_READ_WORKQUEUE = 1 << 4,
389+
BD_CRYPTO_LUKS_ACTIVATE_NO_WRITE_WORKQUEUE = 1 << 5,
390+
BD_CRYPTO_LUKS_ACTIVATE_HIGH_PRIORITY = 1 << 6,
391+
} BDCryptoLUKSPersistentFlags;
392+
383393
/**
384394
* BDCryptoLUKSInfo:
385395
* @version: LUKS version
@@ -1111,6 +1121,20 @@ gboolean bd_crypto_luks_set_uuid (const gchar *device, const gchar *uuid, GError
11111121
*/
11121122
gboolean bd_crypto_luks_convert (const gchar *device, BDCryptoLUKSVersion target_version, GError **error);
11131123

1124+
/**
1125+
* bd_crypto_luks_set_persistent_flags:
1126+
* @device: a LUKS device to set the persistent flags on
1127+
* @flags: flags to set
1128+
* @error: (out) (optional): place to store error (if any)
1129+
*
1130+
* Note: This function is valid only for LUKS2.
1131+
*
1132+
* Returns: whether the given @flags were successfully set or not
1133+
*
1134+
* Tech category: %BD_CRYPTO_TECH_LUKS-%BD_CRYPTO_TECH_MODE_MODIFY
1135+
*/
1136+
gboolean bd_crypto_luks_set_persistent_flags (const gchar *device, BDCryptoLUKSPersistentFlags flags, GError **error);
1137+
11141138
/**
11151139
* bd_crypto_luks_info:
11161140
* @device: a device to get information about

src/plugins/crypto.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,6 +2289,82 @@ gboolean bd_crypto_luks_convert (const gchar *device, BDCryptoLUKSVersion target
22892289
return TRUE;
22902290
}
22912291

2292+
/**
2293+
* bd_crypto_luks_set_persistent_flags:
2294+
* @device: a LUKS device to set the persistent flags on
2295+
* @flags: flags to set
2296+
* @error: (out) (optional): place to store error (if any)
2297+
*
2298+
* Note: This function is valid only for LUKS2.
2299+
*
2300+
* Returns: whether the given @flags were successfully set or not
2301+
*
2302+
* Tech category: %BD_CRYPTO_TECH_LUKS-%BD_CRYPTO_TECH_MODE_MODIFY
2303+
*/
2304+
gboolean bd_crypto_luks_set_persistent_flags (const gchar *device, BDCryptoLUKSPersistentFlags flags, GError **error) {
2305+
struct crypt_device *cd = NULL;
2306+
gint ret = 0;
2307+
guint32 crypt_flags = 0;
2308+
2309+
ret = crypt_init (&cd, device);
2310+
if (ret != 0) {
2311+
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
2312+
"Failed to initialize device: %s", strerror_l (-ret, c_locale));
2313+
return FALSE;
2314+
}
2315+
2316+
ret = crypt_load (cd, CRYPT_LUKS, NULL);
2317+
if (ret != 0) {
2318+
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
2319+
"Failed to load device: %s", strerror_l (-ret, c_locale));
2320+
crypt_free (cd);
2321+
return FALSE;
2322+
}
2323+
2324+
if (g_strcmp0 (crypt_get_type (cd), CRYPT_LUKS2) != 0) {
2325+
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
2326+
"Persistent flags can be set only on LUKS v2");
2327+
crypt_free (cd);
2328+
return FALSE;
2329+
}
2330+
2331+
if (flags & BD_CRYPTO_LUKS_ACTIVATE_ALLOW_DISCARDS)
2332+
crypt_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
2333+
if (flags & BD_CRYPTO_LUKS_ACTIVATE_SAME_CPU_CRYPT)
2334+
crypt_flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
2335+
if (flags & BD_CRYPTO_LUKS_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
2336+
crypt_flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
2337+
if (flags & BD_CRYPTO_LUKS_ACTIVATE_NO_JOURNAL)
2338+
crypt_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
2339+
if (flags & BD_CRYPTO_LUKS_ACTIVATE_NO_READ_WORKQUEUE)
2340+
crypt_flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
2341+
if (flags & BD_CRYPTO_LUKS_ACTIVATE_NO_WRITE_WORKQUEUE)
2342+
crypt_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
2343+
if (flags & BD_CRYPTO_LUKS_ACTIVATE_HIGH_PRIORITY) {
2344+
#ifdef LIBCRYPTSETUP_28
2345+
crypt_flags |= CRYPT_ACTIVATE_HIGH_PRIORITY;
2346+
#else
2347+
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_TECH_UNAVAIL,
2348+
"Libcryptsetup 2.8 or newer is needed for 'high priority' flag support");
2349+
crypt_free (cd);
2350+
return FALSE;
2351+
#endif
2352+
}
2353+
2354+
2355+
ret = crypt_persistent_flags_set (cd, CRYPT_FLAGS_ACTIVATION, crypt_flags);
2356+
if (ret != 0) {
2357+
g_set_error (error, BD_CRYPTO_ERROR, BD_CRYPTO_ERROR_DEVICE,
2358+
"Failed to set flags: %s", strerror_l (-ret, c_locale));
2359+
crypt_free (cd);
2360+
return FALSE;
2361+
}
2362+
2363+
crypt_free (cd);
2364+
2365+
return TRUE;
2366+
}
2367+
22922368
static gint synced_close (gint fd) {
22932369
gint ret = 0;
22942370
ret = fsync (fd);

src/plugins/crypto.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ typedef enum {
162162
BD_CRYPTO_LUKS_HW_ENCRYPTION_OPAL_HW_AND_SW,
163163
} BDCryptoLUKSHWEncryptionType;
164164

165+
typedef enum {
166+
BD_CRYPTO_LUKS_ACTIVATE_ALLOW_DISCARDS = 1 << 0,
167+
BD_CRYPTO_LUKS_ACTIVATE_SAME_CPU_CRYPT = 1 << 1,
168+
BD_CRYPTO_LUKS_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS = 1 << 2,
169+
BD_CRYPTO_LUKS_ACTIVATE_NO_JOURNAL = 1 << 3,
170+
BD_CRYPTO_LUKS_ACTIVATE_NO_READ_WORKQUEUE = 1 << 4,
171+
BD_CRYPTO_LUKS_ACTIVATE_NO_WRITE_WORKQUEUE = 1 << 5,
172+
BD_CRYPTO_LUKS_ACTIVATE_HIGH_PRIORITY = 1 << 6,
173+
} BDCryptoLUKSPersistentFlags;
174+
165175
/**
166176
* BDCryptoLUKSInfo:
167177
* @version: LUKS version
@@ -293,6 +303,7 @@ gboolean bd_crypto_luks_header_restore (const gchar *device, const gchar *backup
293303
gboolean bd_crypto_luks_set_label (const gchar *device, const gchar *label, const gchar *subsystem, GError **error);
294304
gboolean bd_crypto_luks_set_uuid (const gchar *device, const gchar *uuid, GError **error);
295305
gboolean bd_crypto_luks_convert (const gchar *device, BDCryptoLUKSVersion target_version, GError **error);
306+
gboolean bd_crypto_luks_set_persistent_flags (const gchar *device, BDCryptoLUKSPersistentFlags flags, GError **error);
296307

297308
BDCryptoLUKSInfo* bd_crypto_luks_info (const gchar *device, GError **error);
298309
BDCryptoBITLKInfo* bd_crypto_bitlk_info (const gchar *device, GError **error);

tests/crypto_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,35 @@ def test_luks2_set_uuid(self):
11591159
self.assertNotEqual(info.uuid, self.test_uuid)
11601160

11611161

1162+
class CryptoTestSetPersistentFlags(CryptoTestCase):
1163+
1164+
@tag_test(TestTags.SLOW, TestTags.CORE)
1165+
def test_luks_set_persistent_flags(self):
1166+
"""Verify that we can set flags on a LUKS device"""
1167+
1168+
self._luks_format(self.loop_dev, PASSWD)
1169+
1170+
with self.assertRaisesRegex(GLib.GError, "Persistent flags can be set only on LUKS v2"):
1171+
BlockDev.crypto_luks_set_persistent_flags(self.loop_dev,
1172+
BlockDev.CryptoLUKSPersistentFlags.ALLOW_DISCARDS)
1173+
1174+
@tag_test(TestTags.SLOW, TestTags.CORE)
1175+
def test_luks_set_persistent_flags(self):
1176+
"""Verify that we can set flags on a LUKS 2 device"""
1177+
1178+
self._luks2_format(self.loop_dev, PASSWD)
1179+
1180+
succ = BlockDev.crypto_luks_set_persistent_flags(self.loop_dev,
1181+
BlockDev.CryptoLUKSPersistentFlags.ALLOW_DISCARDS)
1182+
self.assertTrue(succ)
1183+
1184+
_ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev)
1185+
m = re.search(r"Flags:\s*(\S+)\s*", out)
1186+
if not m or len(m.groups()) != 1:
1187+
self.fail("Failed to get label information from:\n%s %s" % (out, err))
1188+
self.assertEqual(m.group(1), "allow-discards")
1189+
1190+
11621191
class CryptoTestConvert(CryptoTestCase):
11631192

11641193
@tag_test(TestTags.SLOW, TestTags.CORE)

0 commit comments

Comments
 (0)