*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2021 Milan Broz
+ * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
*/
struct crypt_device; /* crypt device handle */
+struct crypt_keyslot_context;
/**
* Initialize crypt device handle and check if the provided device exists.
* other values mean accepted.
*
* @param cd crypt device handle
- * @param confirm user defined confirm callback reference
+ * @param confirm user defined confirm callback reference; use
+ * @p msg for message for user to confirm and
+ * @p usrptr for identification in callback
* @param usrptr provided identification in callback
- * @param msg Message for user to confirm
*
* @note Current version of cryptsetup API requires confirmation for UUID change and
* LUKS header restore only.
* Set log function.
*
* @param cd crypt device handle (can be @e NULL to set default log function)
- * @param log user defined log function reference
+ * @param log user defined log function reference; use
+ * @p level for log level,
+ * @p msg for message, and
+ * @p usrptr for identification in callback
* @param usrptr provided identification in callback
- * @param level log level below (debug messages can uses other levels)
- * @param msg log message
*/
void crypt_set_log_callback(struct crypt_device *cd,
void (*log)(int level, const char *msg, void *usrptr),
* @param msg log message
*/
void crypt_log(struct crypt_device *cd, int level, const char *msg);
+
+/**
+ * Log function with variable arguments.
+ *
+ * @param cd crypt device handle
+ * @param level log level
+ * @param format formatted log message
+ */
+void crypt_logf(struct crypt_device *cd, int level, const char *format, ...);
/** @} */
/**
};
/** Iteration time set by crypt_set_iteration_time(), for compatibility only. */
-#define CRYPT_PBKDF_ITER_TIME_SET (1 << 0)
+#define CRYPT_PBKDF_ITER_TIME_SET (UINT32_C(1) << 0)
/** Never run benchmarks, use pre-set value or defaults. */
-#define CRYPT_PBKDF_NO_BENCHMARK (1 << 1)
+#define CRYPT_PBKDF_NO_BENCHMARK (UINT32_C(1) << 1)
/** PBKDF2 according to RFC2898, LUKS1 legacy */
#define CRYPT_KDF_PBKDF2 "pbkdf2"
/**
* Helper to lock/unlock memory to avoid swap sensitive data to disk.
+ * \b Deprecated, only for backward compatibility. Memory with keys are locked automatically.
*
* @param cd crypt device handle, can be @e NULL
* @param lock 0 to unlock otherwise lock memory
* @note Only root can do this.
* @note It locks/unlocks all process memory, not only crypt context.
*/
-int crypt_memory_lock(struct crypt_device *cd, int lock);
+int crypt_memory_lock(struct crypt_device *cd, int lock) __attribute__((deprecated));
/**
* Set global lock protection for on-disk metadata (file-based locking).
#define CRYPT_INTEGRITY "INTEGRITY"
/** BITLK (BitLocker-compatible mode) */
#define CRYPT_BITLK "BITLK"
+/** FVAULT2 (FileVault2-compatible mode) */
+#define CRYPT_FVAULT2 "FVAULT2"
/** LUKS any version */
#define CRYPT_LUKS NULL
};
/** No on-disk header (only hashes) */
-#define CRYPT_VERITY_NO_HEADER (1 << 0)
+#define CRYPT_VERITY_NO_HEADER (UINT32_C(1) << 0)
/** Verity hash in userspace before activation */
-#define CRYPT_VERITY_CHECK_HASH (1 << 1)
+#define CRYPT_VERITY_CHECK_HASH (UINT32_C(1) << 1)
/** Create hash - format hash device */
-#define CRYPT_VERITY_CREATE_HASH (1 << 2)
+#define CRYPT_VERITY_CREATE_HASH (UINT32_C(1) << 2)
/** Root hash signature required for activation */
-#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (1 << 3)
+#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (UINT32_C(1) << 3)
/**
*
};
/** Include legacy modes when scanning for header */
-#define CRYPT_TCRYPT_LEGACY_MODES (1 << 0)
+#define CRYPT_TCRYPT_LEGACY_MODES (UINT32_C(1) << 0)
/** Try to load hidden header (describing hidden device) */
-#define CRYPT_TCRYPT_HIDDEN_HEADER (1 << 1)
+#define CRYPT_TCRYPT_HIDDEN_HEADER (UINT32_C(1) << 1)
/** Try to load backup header */
-#define CRYPT_TCRYPT_BACKUP_HEADER (1 << 2)
+#define CRYPT_TCRYPT_BACKUP_HEADER (UINT32_C(1) << 2)
/** Device contains encrypted system (with boot loader) */
-#define CRYPT_TCRYPT_SYSTEM_HEADER (1 << 3)
+#define CRYPT_TCRYPT_SYSTEM_HEADER (UINT32_C(1) << 3)
/** Include VeraCrypt modes when scanning for header,
* all other TCRYPT flags applies as well.
* VeraCrypt device is reported as TCRYPT type.
*/
-#define CRYPT_TCRYPT_VERA_MODES (1 << 4)
+#define CRYPT_TCRYPT_VERA_MODES (UINT32_C(1) << 4)
/**
*
const struct crypt_params_integrity *integrity_params; /**< Data integrity parameters or @e NULL*/
size_t data_alignment; /**< data area alignment in 512B sectors, data offset is multiple of this */
const char *data_device; /**< detached encrypted data device or @e NULL */
- uint32_t sector_size; /**< encryption sector size */
+ uint32_t sector_size; /**< encryption sector size, 0 triggers auto-detection for optimal encryption sector size */
const char *label; /**< header label or @e NULL*/
const char *subsystem; /**< header subsystem label or @e NULL*/
};
uint32_t crypt_get_compatibility(struct crypt_device *cd);
/** dm-integrity device uses less effective (legacy) padding (old kernels) */
-#define CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING (1 << 0)
+#define CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING (UINT32_C(1) << 0)
/** dm-integrity device does not protect superblock with HMAC (old kernels) */
-#define CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC (1 << 1)
+#define CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC (UINT32_C(1) << 1)
/** dm-integrity allow recalculating of volumes with HMAC keys (old kernels) */
-#define CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC (1 << 2)
+#define CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC (UINT32_C(1) << 2)
/**
* Convert to new type for already existing device.
const char *subsystem);
/**
+ * Get the label of an existing device.
+ *
+ * @param cd crypt device handle
+ *
+ * @return label, or @e NULL otherwise
+ */
+const char *crypt_get_label(struct crypt_device *cd);
+
+/**
+ * Get the subsystem of an existing device.
+ *
+ * @param cd crypt device handle
+ *
+ * @return subsystem, or @e NULL otherwise
+ */
+const char *crypt_get_subsystem(struct crypt_device *cd);
+
+/**
* Enable or disable loading of volume keys via kernel keyring. When set to
* 'enabled' library loads key in kernel keyring first and pass the key
* description to dm-crypt instead of binary key copy. If set to 'disabled'
* @post In case LUKS header is read successfully but payload device is too small
* error is returned and device type in context is set to @e NULL
*
- * @note Note that in current version load works only for LUKS and VERITY device type.
+ * @note Note that load works only for device types with on-disk metadata.
+ * @note Function does not print visible error message if metadata is not present.
*
*/
int crypt_load(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size);
+/**
+ * Resume crypt device using LUKS2 token.
+ *
+ * @param cd LUKS2 crypt device handle
+ * @param name name of device to resume
+ * @param type restrict type of token, if @e NULL all types are allowed
+ * @param pin passphrase (or PIN) to unlock token (may be binary data)
+ * @param pin_size size of @e pin
+ * @param usrptr provided identification in callback
+ *
+ * @return unlocked key slot number or negative errno otherwise.
+ *
+ * @note EPERM errno means token provided passphrase successfully, but
+ * passphrase did not unlock any keyslot associated with the token.
+ *
+ * @note ENOENT errno means no token (or subsequently assigned keyslot) was
+ * eligible to resume LUKS2 device.
+ *
+ * @note ENOANO errno means that token is PIN protected and was either missing
+ * (NULL) or wrong.
+ *
+ * @note Negative EAGAIN errno means token handler requires additional hardware
+ * not present in the system to unlock keyslot.
+ *
+ * @note with @param token set to CRYPT_ANY_TOKEN libcryptsetup runs best effort loop
+ * to resume device using any available token. It may happen that various token handlers
+ * return different error codes. At the end loop returns error codes in the following
+ * order (from the most significant to the least) any negative errno except those
+ * listed below, non negative token id (success), -ENOANO, -EAGAIN, -EPERM, -ENOENT.
+ */
+int crypt_resume_by_token_pin(struct crypt_device *cd,
+ const char *name,
+ const char *type,
+ int token,
+ const char *pin,
+ size_t pin_size,
+ void *usrptr);
/** @} */
/**
size_t passphrase_size);
/** create keyslot with volume key not associated with current dm-crypt segment */
-#define CRYPT_VOLUME_KEY_NO_SEGMENT (1 << 0)
+#define CRYPT_VOLUME_KEY_NO_SEGMENT (UINT32_C(1) << 0)
/** create keyslot with new volume key and assign it to current dm-crypt segment */
-#define CRYPT_VOLUME_KEY_SET (1 << 1)
+#define CRYPT_VOLUME_KEY_SET (UINT32_C(1) << 1)
/** Assign key to first matching digest before creating new digest */
-#define CRYPT_VOLUME_KEY_DIGEST_REUSE (1 << 2)
+#define CRYPT_VOLUME_KEY_DIGEST_REUSE (UINT32_C(1) << 2)
/**
* Add key slot using provided key.
uint32_t flags);
/**
+ * @defgroup crypt-keyslot-context Crypt keyslot context
+ * @addtogroup crypt-keyslot-context
+ * @{
+ */
+
+/**
+ * Release crypt keyslot context and used memory.
+ *
+ * @param kc crypt keyslot context
+ */
+void crypt_keyslot_context_free(struct crypt_keyslot_context *kc);
+
+/**
+ * Initialize keyslot context via passphrase.
+ *
+ * @param cd crypt device handle initialized to LUKS device context
+ * @param passphrase passphrase for a keyslot
+ * @param passphrase_size size of passphrase
+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_PASSPHRASE
+ *
+ * @return zero on success or negative errno otherwise.
+ */
+int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd,
+ const char *passphrase,
+ size_t passphrase_size,
+ struct crypt_keyslot_context **kc);
+
+/**
+ * Initialize keyslot context via key file path.
+ *
+ * @param cd crypt device handle initialized to LUKS device context
+ *
+ * @param keyfile key file with passphrase for a keyslot
+ * @param keyfile_size number of bytes to read from keyfile, @e 0 is unlimited
+ * @param keyfile_offset number of bytes to skip at start of keyfile
+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEYFILE
+ *
+ * @return zero on success or negative errno otherwise.
+ */
+int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd,
+ const char *keyfile,
+ size_t keyfile_size,
+ uint64_t keyfile_offset,
+ struct crypt_keyslot_context **kc);
+
+/**
+ * Initialize keyslot context via LUKS2 token.
+ *
+ * @param cd crypt device handle initialized to LUKS2 device context
+ *
+ * @param token token providing passphrase for a keyslot or CRYPT_ANY_TOKEN
+ * @param type restrict type of token, if @e NULL all types are allowed
+ * @param pin passphrase (or PIN) to unlock token (may be binary data)
+ * @param pin_size size of @e pin
+ * @param usrptr provided identification in callback
+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_TOKEN
+ *
+ * @return zero on success or negative errno otherwise.
+ */
+int crypt_keyslot_context_init_by_token(struct crypt_device *cd,
+ int token,
+ const char *type,
+ const char *pin, size_t pin_size,
+ void *usrptr,
+ struct crypt_keyslot_context **kc);
+
+/**
+ * Initialize keyslot context via key.
+ *
+ * @param cd crypt device handle initialized to LUKS device context
+ *
+ * @param volume_key provided volume key or @e NULL if used after crypt_format
+ * or with CRYPT_VOLUME_KEY_NO_SEGMENT flag
+ * @param volume_key_size size of volume_key
+ * @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEY
+ *
+ * @return zero on success or negative errno otherwise.
+ */
+int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd,
+ const char *volume_key,
+ size_t volume_key_size,
+ struct crypt_keyslot_context **kc);
+
+/**
+ * Get error code per keyslot context from last failed call.
+ *
+ * @note If @link crypt_keyslot_add_by_keyslot_context @endlink passed with
+ * no negative return code. The return value of this function is undefined.
+ *
+ * @param kc keyslot context involved in failed @link crypt_keyslot_add_by_keyslot_context @endlink
+ *
+ * @return Negative errno if keyslot context caused a failure, zero otherwise.
+ */
+int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc);
+
+/**
+ * Set new pin to token based keyslot context.
+ *
+ * @note Use when @link crypt_keyslot_add_by_keyslot_context @endlink failed
+ * and token keyslot context returned -ENOANO error code via
+ * @link crypt_keyslot_context_get_error @endlink.
+ *
+ * @param cd crypt device handle initialized to LUKS2 device context
+ * @param pin passphrase (or PIN) to unlock token (may be binary data)
+ * @param pin_size size of @e pin
+ * @param kc LUKS2 keyslot context (only @link CRYPT_KC_TYPE_TOKEN @endlink is allowed)
+ *
+ * @return zero on success or negative errno otherwise
+ */
+int crypt_keyslot_context_set_pin(struct crypt_device *cd,
+ const char *pin, size_t pin_size,
+ struct crypt_keyslot_context *kc);
+
+/**
+ * @defgroup crypt-keyslot-context-types Crypt keyslot context
+ * @addtogroup crypt-keyslot-context-types
+ * @{
+ */
+/** keyslot context initialized by passphrase (@link crypt_keyslot_context_init_by_passphrase @endlink) */
+#define CRYPT_KC_TYPE_PASSPHRASE INT16_C(1)
+/** keyslot context initialized by keyfile (@link crypt_keyslot_context_init_by_keyfile @endlink) */
+#define CRYPT_KC_TYPE_KEYFILE INT16_C(2)
+/** keyslot context initialized by token (@link crypt_keyslot_context_init_by_token @endlink) */
+#define CRYPT_KC_TYPE_TOKEN INT16_C(3)
+/** keyslot context initialized by volume key or unbound key (@link crypt_keyslot_context_init_by_volume_key @endlink) */
+#define CRYPT_KC_TYPE_KEY INT16_C(4)
+/** @} */
+
+/**
+ * Get type identifier for crypt keyslot context.
+ *
+ * @param kc keyslot context
+ *
+ * @return crypt keyslot context type id (see @link crypt-keyslot-context-types @endlink) or negative errno otherwise.
+ */
+int crypt_keyslot_context_get_type(const struct crypt_keyslot_context *kc);
+/** @} */
+
+/**
+ * Add key slot by volume key provided by keyslot context (kc). New
+ * keyslot will be protected by passphrase provided by new keyslot context (new_kc).
+ * See @link crypt-keyslot-context @endlink for context initialization routines.
+ *
+ * @pre @e cd contains initialized and formatted LUKS device context.
+ *
+ * @param cd crypt device handle
+ * @param keyslot_existing existing keyslot or CRYPT_ANY_SLOT to get volume key from.
+ * @param kc keyslot context providing volume key.
+ * @param keyslot_new new keyslot or CRYPT_ANY_SLOT (first free number is used).
+ * @param new_kc keyslot context providing passphrase for new keyslot.
+ * @param flags key flags to set
+ *
+ * @return allocated key slot number or negative errno otherwise.
+ *
+ * @note new_kc can not be @e CRYPT_KC_TYPE_KEY type keyslot context.
+ *
+ * @note For kc parameter with type @e CRYPT_KC_TYPE_KEY the keyslot_existing
+ * parameter is ignored.
+ *
+ * @note in case there is no active LUKS keyslot to get existing volume key from, one of following must apply:
+ * @li @e cd must be device handle used in crypt_format() by current process (it holds reference to generated volume key)
+ * @li kc must be of @e CRYPT_KC_TYPE_KEY type with valid volume key.
+ *
+ * @note With CRYPT_VOLUME_KEY_NO_SEGMENT flag raised and kc of type @e CRYPT_KC_TYPE_KEY with @e volume_key set to @e NULL
+ * the new volume_key will be generated and stored in new keyslot. The keyslot will become unbound (unusable to
+ * dm-crypt device activation).
+ *
+ * @warning CRYPT_VOLUME_KEY_SET flag force updates volume key. It is @b not @b reencryption!
+ * By doing so you will most probably destroy your ciphertext data device. It's supposed
+ * to be used only in wrapped keys scheme for key refresh process where real (inner) volume
+ * key stays untouched. It may be involed on active @e keyslot which makes the (previously
+ * unbound) keyslot new regular keyslot.
+ */
+int crypt_keyslot_add_by_keyslot_context(struct crypt_device *cd,
+ int keyslot_existing,
+ struct crypt_keyslot_context *kc,
+ int keyslot_new,
+ struct crypt_keyslot_context *new_kc,
+ uint32_t flags);
+
+/**
* Destroy (and disable) key slot.
*
* @pre @e cd contains initialized and formatted LUKS device context
*/
/** device is read only */
-#define CRYPT_ACTIVATE_READONLY (1 << 0)
+#define CRYPT_ACTIVATE_READONLY (UINT32_C(1) << 0)
/** only reported for device without uuid */
-#define CRYPT_ACTIVATE_NO_UUID (1 << 1)
+#define CRYPT_ACTIVATE_NO_UUID (UINT32_C(1) << 1)
/** activate even if cannot grant exclusive access (DANGEROUS) */
-#define CRYPT_ACTIVATE_SHARED (1 << 2)
+#define CRYPT_ACTIVATE_SHARED (UINT32_C(1) << 2)
/** enable discards aka TRIM */
-#define CRYPT_ACTIVATE_ALLOW_DISCARDS (1 << 3)
+#define CRYPT_ACTIVATE_ALLOW_DISCARDS (UINT32_C(1) << 3)
/** skip global udev rules in activation ("private device"), input only */
-#define CRYPT_ACTIVATE_PRIVATE (1 << 4)
+#define CRYPT_ACTIVATE_PRIVATE (UINT32_C(1) << 4)
/** corruption detected (verity), output only */
-#define CRYPT_ACTIVATE_CORRUPTED (1 << 5)
+#define CRYPT_ACTIVATE_CORRUPTED (UINT32_C(1) << 5)
/** use same_cpu_crypt option for dm-crypt */
-#define CRYPT_ACTIVATE_SAME_CPU_CRYPT (1 << 6)
+#define CRYPT_ACTIVATE_SAME_CPU_CRYPT (UINT32_C(1) << 6)
/** use submit_from_crypt_cpus for dm-crypt */
-#define CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS (1 << 7)
+#define CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS (UINT32_C(1) << 7)
/** dm-verity: ignore_corruption flag - ignore corruption, log it only */
-#define CRYPT_ACTIVATE_IGNORE_CORRUPTION (1 << 8)
+#define CRYPT_ACTIVATE_IGNORE_CORRUPTION (UINT32_C(1) << 8)
/** dm-verity: restart_on_corruption flag - restart kernel on corruption */
-#define CRYPT_ACTIVATE_RESTART_ON_CORRUPTION (1 << 9)
+#define CRYPT_ACTIVATE_RESTART_ON_CORRUPTION (UINT32_C(1) << 9)
/** dm-verity: ignore_zero_blocks - do not verify zero blocks */
-#define CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS (1 << 10)
+#define CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS (UINT32_C(1) << 10)
/** key loaded in kernel keyring instead directly in dm-crypt */
-#define CRYPT_ACTIVATE_KEYRING_KEY (1 << 11)
+#define CRYPT_ACTIVATE_KEYRING_KEY (UINT32_C(1) << 11)
/** dm-integrity: direct writes, do not use journal */
-#define CRYPT_ACTIVATE_NO_JOURNAL (1 << 12)
+#define CRYPT_ACTIVATE_NO_JOURNAL (UINT32_C(1) << 12)
/** dm-integrity: recovery mode - no journal, no integrity checks */
-#define CRYPT_ACTIVATE_RECOVERY (1 << 13)
+#define CRYPT_ACTIVATE_RECOVERY (UINT32_C(1) << 13)
/** ignore persistently stored flags */
-#define CRYPT_ACTIVATE_IGNORE_PERSISTENT (1 << 14)
+#define CRYPT_ACTIVATE_IGNORE_PERSISTENT (UINT32_C(1) << 14)
/** dm-verity: check_at_most_once - check data blocks only the first time */
-#define CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE (1 << 15)
+#define CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE (UINT32_C(1) << 15)
/** allow activation check including unbound keyslots (keyslots without segments) */
-#define CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY (1 << 16)
+#define CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY (UINT32_C(1) << 16)
/** dm-integrity: activate automatic recalculation */
-#define CRYPT_ACTIVATE_RECALCULATE (1 << 17)
+#define CRYPT_ACTIVATE_RECALCULATE (UINT32_C(1) << 17)
/** reactivate existing and update flags, input only */
-#define CRYPT_ACTIVATE_REFRESH (1 << 18)
+#define CRYPT_ACTIVATE_REFRESH (UINT32_C(1) << 18)
/** Use global lock to serialize memory hard KDF on activation (OOM workaround) */
-#define CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF (1 << 19)
+#define CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF (UINT32_C(1) << 19)
/** dm-integrity: direct writes, use bitmap to track dirty sectors */
-#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (1 << 20)
+#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (UINT32_C(1) << 20)
/** device is suspended (key should be wiped from memory), output only */
-#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
+#define CRYPT_ACTIVATE_SUSPENDED (UINT32_C(1) << 21)
/** use IV sector counted in sector_size instead of default 512 bytes sectors */
-#define CRYPT_ACTIVATE_IV_LARGE_SECTORS (1 << 22)
+#define CRYPT_ACTIVATE_IV_LARGE_SECTORS (UINT32_C(1) << 22)
/** dm-verity: panic_on_corruption flag - panic kernel on corruption */
-#define CRYPT_ACTIVATE_PANIC_ON_CORRUPTION (1 << 23)
+#define CRYPT_ACTIVATE_PANIC_ON_CORRUPTION (UINT32_C(1) << 23)
/** dm-crypt: bypass internal workqueue and process read requests synchronously. */
-#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
+#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (UINT32_C(1) << 24)
/** dm-crypt: bypass internal workqueue and process write requests synchronously. */
-#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
+#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (UINT32_C(1) << 25)
+/** dm-integrity: reset automatic recalculation */
+#define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
+/** dm-verity: try to use tasklets */
+#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
/**
* Active device runtime attributes
* LUKS2 header requirements
*/
/** Unfinished offline reencryption */
-#define CRYPT_REQUIREMENT_OFFLINE_REENCRYPT (1 << 0)
+#define CRYPT_REQUIREMENT_OFFLINE_REENCRYPT (UINT32_C(1) << 0)
/** Online reencryption in-progress */
-#define CRYPT_REQUIREMENT_ONLINE_REENCRYPT (1 << 1)
+#define CRYPT_REQUIREMENT_ONLINE_REENCRYPT (UINT32_C(1) << 1)
/** unknown requirement in header (output only) */
-#define CRYPT_REQUIREMENT_UNKNOWN (1 << 31)
+#define CRYPT_REQUIREMENT_UNKNOWN (UINT32_C(1) << 31)
/**
* Persistent flags type
* @note For VERITY the volume key means root hash required for activation.
* Because kernel dm-verity is always read only, you have to provide
* CRYPT_ACTIVATE_READONLY flag always.
- * @note For TCRYPT the volume key should be always NULL and because master
- * key from decrypted header is used instead.
+ * @note For TCRYPT the volume key should be always NULL
+ * the key from decrypted header is used instead.
*/
int crypt_activate_by_volume_key(struct crypt_device *cd,
const char *name,
uint32_t flags);
/** lazy deactivation - remove once last user releases it */
-#define CRYPT_DEACTIVATE_DEFERRED (1 << 0)
+#define CRYPT_DEACTIVATE_DEFERRED (UINT32_C(1) << 0)
/** force deactivation - if the device is busy, it is replaced by error device */
-#define CRYPT_DEACTIVATE_FORCE (1 << 1)
+#define CRYPT_DEACTIVATE_FORCE (UINT32_C(1) << 1)
+/** if set, remove lazy deactivation */
+#define CRYPT_DEACTIVATE_DEFERRED_CANCEL (UINT32_C(1) << 2)
/**
* Deactivate crypt device. This function tries to remove active device-mapper
* @note For TCRYPT cipher chain is the volume key concatenated
* for all ciphers in chain.
* @note For VERITY the volume key means root hash used for activation.
+ * @note For LUKS devices, if passphrase is @e NULL and volume key is cached in
+ * device context it returns the volume key generated in preceding
+ * @link crypt_format @endlink call.
*/
int crypt_volume_key_get(struct crypt_device *cd,
int keyslot,
size_t passphrase_size);
/**
+ * Get volume key from crypt device by keyslot context.
+ *
+ * @param cd crypt device handle
+ * @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
+ * @param volume_key buffer for volume key
+ * @param volume_key_size on input, size of buffer @e volume_key,
+ * on output size of @e volume_key
+ * @param kc keyslot context used to unlock volume key
+ *
+ * @return unlocked key slot number or negative errno otherwise.
+ *
+ * @note See @link crypt-keyslot-context-types @endlink for info on keyslot
+ * context initialization.
+ * @note For TCRYPT cipher chain is the volume key concatenated
+ * for all ciphers in chain (kc may be NULL).
+ * @note For VERITY the volume key means root hash used for activation
+ * (kc may be NULL).
+ * @note For LUKS devices, if kc is @e NULL and volume key is cached in
+ * device context it returns the volume key generated in preceding
+ * @link crypt_format @endlink call.
+ * @note @link CRYPT_KC_TYPE_TOKEN @endlink keyslot context is usable only with LUKS2 devices.
+ * @note @link CRYPT_KC_TYPE_KEY @endlink keyslot context can not be used.
+ * @note To get LUKS2 unbound key, keyslot parameter must not be @e CRYPT_ANY_SLOT.
+ * @note EPERM errno means provided keyslot context could not unlock any (or selected)
+ * keyslot.
+ * @note ENOENT errno means no LUKS keyslot is available to retrieve volume key from
+ * and there's no cached volume key in device handle.
+ */
+int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd,
+ int keyslot,
+ char *volume_key,
+ size_t *volume_key_size,
+ struct crypt_keyslot_context *kc);
+
+/**
* Verify that provided volume key is valid for crypt device.
*
* @param cd crypt device handle
* @param volume_key_size size of @e volume_key
*
* @return @e 0 on success or negative errno value otherwise.
+ *
+ * @note Negative EPERM return value means that passed volume_key
+ * did not pass digest verification routine (not a valid volume
+ * key).
*/
int crypt_volume_key_verify(struct crypt_device *cd,
const char *volume_key,
int crypt_dump(struct crypt_device *cd);
/**
+ * Dump JSON-formatted information about LUKS2 device
+ *
+ * @param cd crypt device handle (only LUKS2 format supported)
+ * @param json buffer with JSON, if NULL use log callback for output
+ * @param flags dump flags (reserved)
+ *
+ * @return @e 0 on success or negative errno value otherwise.
+ */
+int crypt_dump_json(struct crypt_device *cd, const char **json, uint32_t flags);
+
+/**
* Get cipher used in device.
*
* @param cd crypt device handle
int crypt_get_sector_size(struct crypt_device *cd);
/**
+ * Check if initialized LUKS context uses detached header
+ * (LUKS header located on a different device than data.)
+ *
+ * @param cd crypt device handle
+ *
+ * @return @e 1 if detached header is used, @e 0 if not
+ * or negative errno value otherwise.
+ *
+ * @note This is a runtime attribute, it does not say
+ * if a LUKS device requires detached header.
+ * This function works only with LUKS devices.
+ */
+int crypt_header_is_detached(struct crypt_device *cd);
+
+/**
* Get device parameters for VERITY device.
*
* @param cd crypt device handle
uint32_t flags);
/** Read key only to the first end of line (\\n). */
-#define CRYPT_KEYFILE_STOP_EOL (1 << 0)
+#define CRYPT_KEYFILE_STOP_EOL (UINT32_C(1) << 0)
/** @} */
/**
typedef enum {
CRYPT_WIPE_ZERO, /**< Fill with zeroes */
CRYPT_WIPE_RANDOM, /**< Use RNG to fill data */
- CRYPT_WIPE_ENCRYPTED_ZERO, /**< Add encryption and fill with zeroes as plaintext */
+ CRYPT_WIPE_ENCRYPTED_ZERO, /**< Obsolete, same as CRYPT_WIPE_RANDOM */
CRYPT_WIPE_SPECIAL, /**< Compatibility only, do not use (Gutmann method) */
} crypt_wipe_pattern;
);
/** Use direct-io */
-#define CRYPT_WIPE_NO_DIRECT_IO (1 << 0)
+#define CRYPT_WIPE_NO_DIRECT_IO (UINT32_C(1) << 0)
/** @} */
/**
* @{
*/
+/**
+ * Get number of tokens supported for device type.
+ *
+ * @param type crypt device type
+ *
+ * @return token count or negative errno otherwise if device
+ * doesn't not support tokens.
+ *
+ * @note Real number of supported tokens for a particular device depends
+ * on usable metadata area size.
+ */
+int crypt_token_max(const char *type);
+
/** Iterate through all tokens */
#define CRYPT_ANY_TOKEN -1
* @param buffer returned allocated buffer with password
* @param buffer_len length of the buffer
* @param usrptr user data in @link crypt_activate_by_token @endlink
+ *
+ * @return 0 on success (token passed LUKS2 keyslot passphrase in buffer) or
+ * negative errno otherwise.
+ *
+ * @note Negative ENOANO errno means that token is PIN protected and caller should
+ * use @link crypt_activate_by_token_pin @endlink with PIN provided.
+ *
+ * @note Negative EAGAIN errno means token handler requires additional hardware
+ * not present in the system.
*/
typedef int (*crypt_token_open_func) (
struct crypt_device *cd,
void *usrptr);
/**
+ * Token handler open with passphrase/PIN function prototype.
+ * This function retrieves password from a token and return allocated buffer
+ * containing this password. This buffer has to be deallocated by calling
+ * free() function and content should be wiped before deallocation.
+ *
+ * @param cd crypt device handle
+ * @param token token id
+ * @param pin passphrase (or PIN) to unlock token (may be binary data)
+ * @param pin_size size of @e pin
+ * @param buffer returned allocated buffer with password
+ * @param buffer_len length of the buffer
+ * @param usrptr user data in @link crypt_activate_by_token @endlink
+ *
+ * @return 0 on success (token passed LUKS2 keyslot passphrase in buffer) or
+ * negative errno otherwise.
+ *
+ * @note Negative ENOANO errno means that token is PIN protected and PIN was
+ * missing or wrong.
+ *
+ * @note Negative EAGAIN errno means token handler requires additional hardware
+ * not present in the system.
+ */
+typedef int (*crypt_token_open_pin_func) (
+ struct crypt_device *cd,
+ int token,
+ const char *pin,
+ size_t pin_size,
+ char **buffer,
+ size_t *buffer_len,
+ void *usrptr);
+
+/**
* Token handler buffer free function prototype.
* This function is used by library to free the buffer with keyslot
* passphrase when it's no longer needed. If not defined the library
typedef void (*crypt_token_dump_func) (struct crypt_device *cd, const char *json);
/**
+ * Token handler version function prototype.
+ * This function is supposed to return pointer to version string information.
+ *
+ * @note The returned string is advised to contain only version.
+ * For example '1.0.0' or 'v1.2.3.4'.
+ *
+ */
+typedef const char * (*crypt_token_version_func) (void);
+
+/**
* Token handler
*/
typedef struct {
int crypt_token_register(const crypt_token_handler *handler);
/**
+ * Report configured path where library searches for external token handlers
+ *
+ * @return @e absolute path when external tokens are enabled or @e NULL otherwise.
+ */
+const char *crypt_token_external_path(void);
+
+/**
+ * Disable external token handlers (plugins) support
+ * If disabled, it cannot be enabled again.
+ */
+void crypt_token_external_disable(void);
+
+/** ABI version for external token in libcryptsetup-token-[name].so */
+#define CRYPT_TOKEN_ABI_VERSION1 "CRYPTSETUP_TOKEN_1.0"
+
+/** open by token - ABI exported symbol for external token (mandatory) */
+#define CRYPT_TOKEN_ABI_OPEN "cryptsetup_token_open"
+/** open by token with PIN - ABI exported symbol for external token */
+#define CRYPT_TOKEN_ABI_OPEN_PIN "cryptsetup_token_open_pin"
+/** deallocate callback - ABI exported symbol for external token */
+#define CRYPT_TOKEN_ABI_BUFFER_FREE "cryptsetup_token_buffer_free"
+/** validate token metadata - ABI exported symbol for external token */
+#define CRYPT_TOKEN_ABI_VALIDATE "cryptsetup_token_validate"
+/** dump token metadata - ABI exported symbol for external token */
+#define CRYPT_TOKEN_ABI_DUMP "cryptsetup_token_dump"
+/** token version - ABI exported symbol for external token */
+#define CRYPT_TOKEN_ABI_VERSION "cryptsetup_token_version"
+
+/**
* Activate device or check key using a token.
*
* @param cd crypt device handle
* @param flags activation flags
*
* @return unlocked key slot number or negative errno otherwise.
+ *
+ * @note EPERM errno means token provided passphrase successfully, but
+ * passphrase did not unlock any keyslot associated with the token.
+ *
+ * @note ENOENT errno means no token (or subsequently assigned keyslot) was
+ * eligible to unlock device.
+ *
+ * @note ENOANO errno means that token is PIN protected and you should call
+ * @link crypt_activate_by_token_pin @endlink with PIN
+ *
+ * @note Negative EAGAIN errno means token handler requires additional hardware
+ * not present in the system.
+ *
+ * @note with @e token set to CRYPT_ANY_TOKEN libcryptsetup runs best effort loop
+ * to unlock device using any available token. It may happen that various token handlers
+ * return different error codes. At the end loop returns error codes in the following
+ * order (from the most significant to the least) any negative errno except those
+ * listed below, non negative token id (success), -ENOANO, -EAGAIN, -EPERM, -ENOENT.
*/
int crypt_activate_by_token(struct crypt_device *cd,
const char *name,
int token,
void *usrptr,
uint32_t flags);
+
+/**
+ * Activate device or check key using a token with PIN.
+ *
+ * @param cd crypt device handle
+ * @param name name of device to create, if @e NULL only check token
+ * @param type restrict type of token, if @e NULL all types are allowed
+ * @param token requested token to check or CRYPT_ANY_TOKEN to check all
+ * @param pin passphrase (or PIN) to unlock token (may be binary data)
+ * @param pin_size size of @e pin
+ * @param usrptr provided identification in callback
+ * @param flags activation flags
+ *
+ * @return unlocked key slot number or negative errno otherwise.
+ *
+ * @note EPERM errno means token provided passphrase successfully, but
+ * passphrase did not unlock any keyslot associated with the token.
+ *
+ * @note ENOENT errno means no token (or subsequently assigned keyslot) was
+ * eligible to unlock device.
+ *
+ * @note ENOANO errno means that token is PIN protected and was either missing
+ * (NULL) or wrong.
+ *
+ * @note Negative EAGAIN errno means token handler requires additional hardware
+ * not present in the system.
+ *
+ * @note with @e token set to CRYPT_ANY_TOKEN libcryptsetup runs best effort loop
+ * to unlock device using any available token. It may happen that various token handlers
+ * return different error codes. At the end loop returns error codes in the following
+ * order (from the most significant to the least) any negative errno except those
+ * listed below, non negative token id (success), -ENOANO, -EAGAIN, -EPERM, -ENOENT.
+ */
+int crypt_activate_by_token_pin(struct crypt_device *cd,
+ const char *name,
+ const char *type,
+ int token,
+ const char *pin,
+ size_t pin_size,
+ void *usrptr,
+ uint32_t flags);
/** @} */
/**
*/
/** Initialize reencryption metadata but do not run reencryption yet. (in) */
-#define CRYPT_REENCRYPT_INITIALIZE_ONLY (1 << 0)
-/** Move the first segment, used only with data shift. (in/out) */
-#define CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT (1 << 1)
+#define CRYPT_REENCRYPT_INITIALIZE_ONLY (UINT32_C(1) << 0)
+/** Move the first segment, used only with datashift resilience mode
+ * and subvariants. (in/out) */
+#define CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT (UINT32_C(1) << 1)
/** Resume already initialized reencryption only. (in) */
-#define CRYPT_REENCRYPT_RESUME_ONLY (1 << 2)
+#define CRYPT_REENCRYPT_RESUME_ONLY (UINT32_C(1) << 2)
/** Run reencryption recovery only. (in) */
-#define CRYPT_REENCRYPT_RECOVERY (1 << 3)
+#define CRYPT_REENCRYPT_RECOVERY (UINT32_C(1) << 3)
/** Reencryption requires metadata protection. (in/out) */
-#define CRYPT_REENCRYPT_REPAIR_NEEDED (1 << 4)
+#define CRYPT_REENCRYPT_REPAIR_NEEDED (UINT32_C(1) << 4)
/**
* Reencryption direction
struct crypt_params_reencrypt {
crypt_reencrypt_mode_info mode; /**< Reencryption mode, immutable after first init. */
crypt_reencrypt_direction_info direction; /**< Reencryption direction, immutable after first init. */
- const char *resilience; /**< Resilience mode: "none", "checksum", "journal" or "shift" (only "shift" is immutable after init) */
+ const char *resilience; /**< Resilience mode: "none", "checksum", "journal", "datashift",
+ "datashift-checksum" or "datashift-journal".
+ "datashift" mode is immutable, "datashift-" subvariant can be only
+ changed to other "datashift-" subvariant */
const char *hash; /**< Used hash for "checksum" resilience type, ignored otherwise. */
- uint64_t data_shift; /**< Used in "shift" mode, must be non-zero, immutable after first init. */
- uint64_t max_hotzone_size; /**< Exact hotzone size for "none" mode. Maximum hotzone size for "checksum" and "journal" modes. */
+ uint64_t data_shift; /**< Used in "datashift" mode (and subvariants), must be non-zero,
+ immutable after first init. */
+ uint64_t max_hotzone_size; /**< Maximum hotzone size (may be lowered by library). For "datashift-" subvariants
+ it is used to set size of moved segment (decryption only). */
uint64_t device_size; /**< Reencrypt only initial part of the data device. */
const struct crypt_params_luks2 *luks2; /**< LUKS2 parameters for the final reencryption volume.*/
uint32_t flags; /**< Reencryption flags. */
const struct crypt_params_reencrypt *params);
/**
- * Run data reencryption.
+ * Legacy data reencryption function.
*
* @param cd crypt device handle
* @param progress is a callback function reporting device \b size,
* current \b offset of reencryption and provided \b usrptr identification
*
* @return @e 0 on success or negative errno value otherwise.
+ *
+ * @deprecated Use @link crypt_reencrypt_run @endlink instead.
*/
int crypt_reencrypt(struct crypt_device *cd,
- int (*progress)(uint64_t size, uint64_t offset, void *usrptr));
+ int (*progress)(uint64_t size, uint64_t offset, void *usrptr))
+__attribute__((deprecated));
+
+/**
+ * Run data reencryption.
+ *
+ * @param cd crypt device handle
+ * @param progress is a callback function reporting device \b size,
+ * current \b offset of reencryption and provided \b usrptr identification
+ * @param usrptr progress specific data
+ *
+ * @return @e 0 on success or negative errno value otherwise.
+ */
+int crypt_reencrypt_run(struct crypt_device *cd,
+ int (*progress)(uint64_t size, uint64_t offset, void *usrptr),
+ void *usrptr);
/**
* Reencryption status info