Skip to content

Commit 63f3d95

Browse files
committed
crypto: Add support for LUKS Reencryption.
1 parent b893c4b commit 63f3d95

File tree

6 files changed

+889
-5
lines changed

6 files changed

+889
-5
lines changed

docs/libblockdev-sections.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ bd_crypto_luks_header_restore
9494
bd_crypto_luks_set_label
9595
bd_crypto_luks_set_uuid
9696
bd_crypto_luks_convert
97+
BDCryptoLUKSReencryptParams
98+
bd_crypto_luks_reencrypt_params_copy
99+
bd_crypto_luks_reencrypt_params_free
100+
bd_crypto_luks_reencrypt_params_new
101+
bd_crypto_luks_reencrypt
102+
bd_crypto_luks_reencrypt_status
103+
bd_crypto_luks_reencrypt_resume
104+
BDCryptoLUKSReencryptProgFunc
105+
BDCryptoLUKSReencryptStatus
106+
BDCryptoLUKSReencryptMode
97107
BDCryptoLUKSInfo
98108
bd_crypto_luks_info_free
99109
bd_crypto_luks_info_copy

src/lib/plugin_apis/crypto.api

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ typedef enum {
2828
BD_CRYPTO_ERROR_KEYRING,
2929
BD_CRYPTO_ERROR_KEYFILE_FAILED,
3030
BD_CRYPTO_ERROR_INVALID_CONTEXT,
31+
BD_CRYPTO_ERROR_CONVERT_FAILED,
32+
BD_CRYPTO_ERROR_REENCRYPT_FAILED,
3133
} BDCryptoError;
3234

3335
typedef enum {
@@ -1111,6 +1113,193 @@ gboolean bd_crypto_luks_set_uuid (const gchar *device, const gchar *uuid, GError
11111113
*/
11121114
gboolean bd_crypto_luks_convert (const gchar *device, BDCryptoLUKSVersion target_version, GError **error);
11131115

1116+
1117+
#define BD_CRYPTO_TYPE_LUKS_REENCRYPT_PARAMS (bd_crypto_luks_reencrypt_params_get_type ())
1118+
GType bd_crypto_luks_reencrypt_params_get_type();
1119+
1120+
/**
1121+
* BDCryptoLUKSReencryptParams:
1122+
* @key_size new volume key size if @new_volume_key is true. Ignored otherwise
1123+
* @cipher new cipher
1124+
* @cipher_mode new cipher mode
1125+
* @resilience resilience mode to be used during reencryption
1126+
* @hash used hash for "checksum" resilience type, ignored otherwise
1127+
* @max_hotzone_size max hotzone size
1128+
* @sector_size sector size. Note that 0 is not a valid value
1129+
* @new_volume_key whether to generate a new volume key or keep the existing one
1130+
* @offline whether to perform an offline or online reencryption,
1131+
* i.e. whether a device is active in the time of reencryption or not
1132+
* @pbkdf PBDKF function parameters for a new keyslot
1133+
*/
1134+
typedef struct BDCryptoLUKSReencryptParams {
1135+
guint32 key_size;
1136+
gchar *cipher;
1137+
gchar *cipher_mode;
1138+
gchar *resilience;
1139+
gchar *hash;
1140+
guint64 max_hotzone_size;
1141+
guint32 sector_size;
1142+
gboolean new_volume_key;
1143+
gboolean offline;
1144+
BDCryptoLUKSPBKDF *pbkdf;
1145+
} BDCryptoLUKSReencryptParams;
1146+
1147+
/**
1148+
* bd_crypto_luks_reencrypt_params_copy: (skip)
1149+
* @params: (nullable): %BDCryptoLUKSReencryptParams to copy
1150+
*
1151+
* Creates a copy of @params.
1152+
*/
1153+
BDCryptoLUKSReencryptParams* bd_crypto_luks_reencrypt_params_copy (BDCryptoLUKSReencryptParams* params) {
1154+
if (params == NULL)
1155+
return NULL;
1156+
1157+
BDCryptoLUKSReencryptParams *new_params = g_new0 (BDCryptoLUKSReencryptParams, 1);
1158+
new_params->key_size = params->key_size;
1159+
new_params->cipher = g_strdup (params->cipher);
1160+
new_params->cipher_mode = g_strdup (params->cipher_mode);
1161+
new_params->resilience = g_strdup (params->resilience);
1162+
new_params->hash = g_strdup (params->hash);
1163+
new_params->max_hotzone_size = params->max_hotzone_size;
1164+
new_params->sector_size = params->sector_size;
1165+
new_params->new_volume_key = params->new_volume_key;
1166+
new_params->offline = params->offline;
1167+
new_params->pbkdf = bd_crypto_luks_pbkdf_copy(params->pbkdf);
1168+
1169+
return new_params;
1170+
}
1171+
1172+
/**
1173+
* bd_crypto_luks_reencrypt_params_free: (skip)
1174+
* @params: (nullable): %BDCryptoLUKSReencryptParams to free
1175+
*
1176+
* Frees @params.
1177+
*/
1178+
void bd_crypto_luks_reencrypt_params_free (BDCryptoLUKSReencryptParams* params) {
1179+
if (params == NULL)
1180+
return;
1181+
1182+
g_free (params->cipher);
1183+
g_free (params->cipher_mode);
1184+
g_free (params->resilience);
1185+
g_free (params->hash);
1186+
bd_crypto_luks_pbkdf_free(params->pbkdf);
1187+
}
1188+
1189+
/**
1190+
* bd_crypto_luks_reencrypt_params_new: (constructor)
1191+
* @key_size new volume key size if @new_volume_key is true. Ignored otherwise
1192+
* @cipher: (nullable): new cipher
1193+
* @cipher_mode: (nullable): new cipher mode
1194+
* @resilience: (nullable): resilience mode to be used during reencryption
1195+
* @hash: (nullable): used hash for "checksum" resilience type, ignored otherwise
1196+
* @max_hotzone_size max hotzone size
1197+
* @sector_size sector size. Note that 0 is not a valid value
1198+
* @new_volume_key whether to generate a new volume key or keep the existing one
1199+
* @offline whether to perform an offline or online reencryption,
1200+
* i.e. whether a device is active in the time of reencryption or not
1201+
* @pbkdf: (nullable): PBDKF function parameters for a new keyslot
1202+
*/
1203+
BDCryptoLUKSReencryptParams* bd_crypto_luks_reencrypt_params_new (guint32 key_size, gchar *cipher, gchar *cipher_mode, gchar *resilience, gchar *hash, guint64 max_hotzone_size, guint32 sector_size, gboolean new_volume_key, gboolean offline, BDCryptoLUKSPBKDF *pbkdf) {
1204+
BDCryptoLUKSReencryptParams *ret = g_new0 (BDCryptoLUKSReencryptParams, 1);
1205+
ret->key_size = key_size;
1206+
ret->cipher = g_strdup (cipher);
1207+
ret->cipher_mode = g_strdup (cipher_mode);
1208+
ret->resilience = g_strdup (resilience);
1209+
ret->hash = g_strdup (hash);
1210+
ret->max_hotzone_size = max_hotzone_size;
1211+
ret->sector_size = sector_size;
1212+
ret->new_volume_key = new_volume_key;
1213+
ret->offline = offline;
1214+
ret->pbkdf = bd_crypto_luks_pbkdf_copy(pbkdf);
1215+
1216+
return ret;
1217+
}
1218+
1219+
GType bd_crypto_luks_reencrypt_params_get_type () {
1220+
static GType type = 0;
1221+
1222+
if (G_UNLIKELY(type == 0)) {
1223+
type = g_boxed_type_register_static("BDCryptoLUKSReencryptParams",
1224+
(GBoxedCopyFunc) bd_crypto_luks_reencrypt_params_copy,
1225+
(GBoxedFreeFunc) bd_crypto_luks_reencrypt_params_free);
1226+
}
1227+
1228+
return type;
1229+
}
1230+
1231+
/**
1232+
* BDCryptoLUKSReencryptProgFunc:
1233+
* @size size of the device being reencrypted
1234+
* @offset current offset
1235+
*
1236+
* A callback function called during reencryption to report progress. Also used to possibly stop reencryption.
1237+
*
1238+
* Returns: 0, if the reencryption should continue.
1239+
* A non-zero value to stop the reencryption
1240+
*/
1241+
typedef int (*BDCryptoLUKSReencryptProgFunc) (guint64 size, guint64 offset);
1242+
1243+
typedef enum {
1244+
BD_CRYPTO_LUKS_REENCRYPT_NONE = 0,
1245+
BD_CRYPTO_LUKS_REENCRYPT_CLEAN,
1246+
BD_CRYPTO_LUKS_REENCRYPT_CRASH,
1247+
BD_CRYPTO_LUKS_REENCRYPT_INVALID
1248+
} BDCryptoLUKSReencryptStatus;
1249+
1250+
typedef enum {
1251+
BD_CRYPTO_LUKS_REENCRYPT = 0,
1252+
BD_CRYPTO_LUKS_ENCRYPT,
1253+
BD_CRYPTO_LUKS_DECRYPT,
1254+
} BDCryptoLUKSReencryptMode;
1255+
1256+
/**
1257+
* bd_crypto_luks_reencrypt:
1258+
* @device: device to reencrypt. Either an active device name for online reencryption, or a block device for offline reencryption.
1259+
* Must match the @params's "offline" parameter
1260+
* @params: reencryption parameters
1261+
* @context: key slot context to unlock @device. The newly created keyslot will use the same context
1262+
* @prog_func: (scope call) (nullable): progress function. Also used to possibly stop reencryption
1263+
* @error: (out) (optional): place to store error (if any)
1264+
*
1265+
* Reencrypts @device. This could mean a change of cipher, cipher mode, or volume key, based on @params
1266+
*
1267+
* Returns: true, if the reencryption was successful or gracefully stopped with @prog_func.
1268+
* false, if an error occurred.
1269+
*
1270+
* Supported @context types for this function: passphrase
1271+
*
1272+
* Tech category: %BD_CRYPTO_TECH_LUKS-%BD_CRYPTO_TECH_MODE_MODIFY
1273+
*/
1274+
gboolean bd_crypto_luks_reencrypt(const gchar *device, BDCryptoLUKSReencryptParams *params, BDCryptoKeyslotContext *context, BDCryptoLUKSReencryptProgFunc prog_func, GError **error);
1275+
1276+
/**
1277+
* bd_crypto_luks_reencrypt_status:
1278+
* @device: an active device name or a block device
1279+
* @mode: (out): the exact operation in the "reencryption family"
1280+
* Has no meaning if the return value is BD_CRYPTO_LUKS_REENCRYPT_NONE
1281+
* @error: (out) (optional): place to store error (if any)
1282+
*
1283+
* Returns: state of @device's reencryption
1284+
*
1285+
* Tech category: %BD_CRYPTO_TECH_LUKS-%BD_CRYPTO_TECH_MODE_QUERY
1286+
*/
1287+
BDCryptoLUKSReencryptStatus bd_crypto_luks_reencrypt_status (const gchar *device, BDCryptoLUKSReencryptMode *mode, GError **error);
1288+
1289+
/**
1290+
* bd_crypto_luks_reencrypt_resume:
1291+
* @device: device with a stopped reencryption. An active device name or a block device
1292+
* @context: key slot context to unlock @device
1293+
* @prog_func: (scope call) (nullable): progress function. Also used to possibly stop reencryption
1294+
* @error: (out) (optional): place to store error (if any)
1295+
*
1296+
* Returns: true, if the reencryption finished successfully or was gracefully stopped with @prog_func.
1297+
* false, if an error occurred.
1298+
*
1299+
* Tech category: %BD_CRYPTO_TECH_LUKS-%BD_CRYPTO_TECH_MODE_MODIFY
1300+
*/
1301+
gboolean bd_crypto_luks_reencrypt_resume (const gchar *device, BDCryptoKeyslotContext *context, BDCryptoLUKSReencryptProgFunc prog_func, GError **error);
1302+
11141303
/**
11151304
* bd_crypto_luks_info:
11161305
* @device: a device to get information about

0 commit comments

Comments
 (0)