|
@@ -0,0 +1,227 @@
|
|
|
+luksmeta(8)
|
|
|
+===========
|
|
|
+:doctype: manpage
|
|
|
+
|
|
|
+== NAME
|
|
|
+
|
|
|
+luksmeta - Utility for storing metadata in a LUKSv1 header
|
|
|
+
|
|
|
+== SYNOPSIS
|
|
|
+
|
|
|
+*luksmeta test* -d DEVICE
|
|
|
+
|
|
|
+*luksmeta nuke* -d DEVICE [-f]
|
|
|
+
|
|
|
+*luksmeta init* -d DEVICE [-f] [-n]
|
|
|
+
|
|
|
+*luksmeta show* -d DEVICE [-s SLOT]
|
|
|
+
|
|
|
+*luksmeta save* -d DEVICE [-s SLOT] -u UUID < DATA
|
|
|
+
|
|
|
+*luksmeta load* -d DEVICE -s SLOT [-u UUID] > DATA
|
|
|
+
|
|
|
+*luksmeta wipe* -d DEVICE -s SLOT [-u UUID] [-f]
|
|
|
+
|
|
|
+== OVERVIEW
|
|
|
+
|
|
|
+The *luksmeta* utility enables an administrator to store metadata in the gap
|
|
|
+between the end of the LUKSv1 header and the start of the encrypted data. This
|
|
|
+is useful for storing data that is available before the volume is unlocked,
|
|
|
+usually for use during the volume unlock process.
|
|
|
+
|
|
|
+The metadata is stored in a series of UUID-typed slots, allowing multiple
|
|
|
+blocks of metadata. Although the *luksmeta* slots are inspired by the LUKS
|
|
|
+slots, they are functionally independent and share only a casual relationship.
|
|
|
+Slots merely provide a hint that a given chunk of metadata is associated with
|
|
|
+a specific LUKSv1 password (in a slot with the same number). However,
|
|
|
+*luksmeta* itself is indifferent to the relationship between a LUKSv1 slot
|
|
|
+and the correspondly numbered *luksmeta* slot, with one exception (detailed
|
|
|
+below).
|
|
|
+
|
|
|
+After a LUKSv1 volume is initialized using *cryptsetup*(8), it must also be
|
|
|
+initialized for metadata storage by *luksmeta init*. Once this is complete,
|
|
|
+the device is ready to store medata.
|
|
|
+
|
|
|
+Data can be written to a slot using *luksmeta save* or read from a slot
|
|
|
+using *luksmeta load*. You can also erase the data in an existing slot using
|
|
|
+*luksmeta wipe* or query the slots using *luksmeta show*.
|
|
|
+
|
|
|
+== UUID GENERATION
|
|
|
+
|
|
|
+It is often presumed that saving metadata to a slot requires a specific UUID
|
|
|
+or that there is an official registry of UUID types. This is incorrect.
|
|
|
+
|
|
|
+UUID stands for Universally Unique IDentifier. UUIDs are a standardized,
|
|
|
+widely-used data type used for identification without a central registry. For
|
|
|
+the relevant standards, see ISO 9834-8:2005 and RFC 4122.
|
|
|
+
|
|
|
+UUIDs are large enough that collision is practically impossible. So if your
|
|
|
+application wants to store data in a *luksmeta* slot, just generate your own
|
|
|
+UUID and use it consistently to refer to your type of data. If you have
|
|
|
+multiple types of data, feel free to generate multiple UUIDs.
|
|
|
+
|
|
|
+The easiest way to generate a UUID is to use *uuidgen*(1). However, any compliant
|
|
|
+UUID generator will suffice.
|
|
|
+
|
|
|
+== INITIALIZATION
|
|
|
+
|
|
|
+Before reading or writing metadata, the LUKSv1 block device must be
|
|
|
+initialized for metadata storage. Three commands help with this process:
|
|
|
+*luksmeta test*, *luksmeta nuke* and *luksmeta init*.
|
|
|
+
|
|
|
+The *luksmeta test* command simply checks an existing block device to see
|
|
|
+if it is initialized for metadata storage. This command does not provide any
|
|
|
+output, so be sure to check its return code (see below).
|
|
|
+
|
|
|
+The *luksmeta nuke* command will zero (erase) the entire LUKSv1 header gap.
|
|
|
+Since this operation is destructive, user confirmation will be required before
|
|
|
+clearing the gap unless the *-f* option is supplied.
|
|
|
+
|
|
|
+The *luksmeta init* command initializes the LUKSv1 block device for metadata
|
|
|
+storage. This process will wipe out any data in the LUKSv1 header gap. For
|
|
|
+this reason, this command will require user confirmation before any data is
|
|
|
+written unless the *-f* option is supplied. Note that this command succeeds
|
|
|
+without any modification if the device is already initialized. If you would
|
|
|
+like to force the creation of clean initialization state, you can specify the
|
|
|
+*-n* option to nuke the LUKSv1 header gap before initialization (but after
|
|
|
+user confirmation).
|
|
|
+
|
|
|
+== METADATA STATE
|
|
|
+
|
|
|
+The *luksmeta show* command displays the current state of slots on the LUKSv1
|
|
|
+block device. If no slot is specified, it prints a table consisting of the
|
|
|
+slot number, the corresponding LUKSv1 slot state and the UUID of the data
|
|
|
+stored in the *luksmeta* slot (or "empty" if no data is stored). If a slot is
|
|
|
+specified, this command simply prints out the UUID of the data in the slot. If
|
|
|
+the slot does not contain data, it prints nothing.
|
|
|
+
|
|
|
+== MANAGING METADATA
|
|
|
+
|
|
|
+Managing the metadata in the slots is performed with three commands:
|
|
|
+*luksmeta save*, *luksmeta load* and *luksmeta wipe*. These commands write
|
|
|
+metadata to a slot, read metadata from a slot and erase metadata in a slot,
|
|
|
+respectively.
|
|
|
+
|
|
|
+The *luksmeta save* command reads metadata on standard input and writes it to
|
|
|
+the specified slot using the specified UUID. If no slot is specified,
|
|
|
+*luksmeta* will search for the first slot number for which the LUKSv1 slot
|
|
|
+is inactive and the *luksmeta* slot is empty. This represents the only
|
|
|
+official correlation between LUKSv1 slots and *luksmeta* slots. In this case,
|
|
|
+the metadata is written to the first applicable slot using the specified UUID
|
|
|
+and the slot number is printed to standard output. In either case, this
|
|
|
+command will never overwrite existing data. To replace data in a slot you will
|
|
|
+need to execute *luksmeta wipe* before *luksmeta save*.
|
|
|
+
|
|
|
+The *luksmeta load* command reads data from the specified slot and writes it
|
|
|
+to standard output. If a UUID is specified, the command will verify that the
|
|
|
+UUID associated with the metadata in the slot matches the specified UUID. This
|
|
|
+type check helps to ensure that you always receive the type of data you are
|
|
|
+expecting as output. If the UUIDs do not match, the command will fail.
|
|
|
+
|
|
|
+The *luksmeta wipe* command erases the data from the given slot. If a UUID is
|
|
|
+specified, the command will verify that the UUID associated with the metadata
|
|
|
+in the slot matches the specified UUID. This type check helps to ensure that
|
|
|
+you only erase the data you intended to erase. Because this is a destructive
|
|
|
+operation, this command will require user confirmation before any data is
|
|
|
+erased, unless the *-f* option is supplied. Note that this command succeeds
|
|
|
+if you attempt to wipe a slot that is already empty.
|
|
|
+
|
|
|
+== CAVEATS
|
|
|
+
|
|
|
+The amount of storage in the LUKSv1 header gap is extremely limited. It also
|
|
|
+varies based upon the configuration used by LUKSv1 at device initialization
|
|
|
+time. In some LUKSv1 configurations, there is not even enough space for
|
|
|
+all the metadata slots even at the smallest possible slot size.
|
|
|
+
|
|
|
+During the design of this utility, we considered it likely that users would
|
|
|
+want to reduce the number of usable slots in exchange for more storage space
|
|
|
+in the slots used. In order to provide this flexibility, the amount of storage
|
|
|
+available per-slot is dynamic. Put simply, slots are not a fixed size. This
|
|
|
+means that it is possible (and even somewhat likely) to encounter an error
|
|
|
+during *luksmeta save* indicating that there is insufficient space.
|
|
|
+
|
|
|
+This error is not a programming bug. If you encounter this error it likely
|
|
|
+means that either all space is being consumed by the already-written slots or
|
|
|
+that the metadata you are attempting to write simply does not fit.
|
|
|
+
|
|
|
+You can attempt to resolve this problem by calling *luksmeta wipe* on slots
|
|
|
+that are no longer in use. This will release the storage space for use by
|
|
|
+other slots. Note that *luksmeta* does not, however, currently perform
|
|
|
+defragmentation since the number of usable blocks is rather limited. You can
|
|
|
+attempt to manually get around this by extracting all slot data, wiping the
|
|
|
+slots and reloading them in order. However, this operation is potentially
|
|
|
+dangerous and should be undertaken with great care.
|
|
|
+
|
|
|
+== OPTIONS
|
|
|
+
|
|
|
+* *-d* _DEVICE_, *--device*=_DEVICE_ :
|
|
|
+ The device on which to perform the operation.
|
|
|
+
|
|
|
+* *-s* _SLOT_, *--slot*=_SLOT_ :
|
|
|
+ The slot number on which to perform the operation.
|
|
|
+
|
|
|
+* *-u* _UUID_, *--uuid*=_UUID_ :
|
|
|
+ The UUID to associate with the operation.
|
|
|
+
|
|
|
+* *-f*, *--force* :
|
|
|
+ Forcibly suppress all user prompting.
|
|
|
+
|
|
|
+== RETURN VALUES
|
|
|
+
|
|
|
+This command uses the return values as defined by *sysexit.h*. The following
|
|
|
+are general errors whose meaning is shared by all *luksmeta* commands:
|
|
|
+
|
|
|
+* *EX_OK* : The operation was successful.
|
|
|
+* *EX_OSERR* : An undefined operating system error occurred.
|
|
|
+* *EX_USAGE* : The program was called with invalid parameters.
|
|
|
+* *EX_IOERR* : An IO error occurred when writing to the device.
|
|
|
+* *EX_OSFILE* : The device is not initialized or is corrupted.
|
|
|
+* *EX_NOPERM* : The user did not grant permission during confirmation.
|
|
|
+* *EX_NOINPUT* : An error occurred while reading from standard input.
|
|
|
+* *EX_DATAERR* : The specified UUID does not match the slot UUID.
|
|
|
+* *EX_CANTCREAT* : There is insufficient space in LUKSv1 header.
|
|
|
+
|
|
|
+Additionally, *luksmeta save* will return *EX_UNAVAILABLE* when you attempt
|
|
|
+to save data into a slot that is already used. Likewise, *luksmeta load* will
|
|
|
+return *EX_UNAVAILABLE* when you attempt to read from an empty slot.
|
|
|
+
|
|
|
+== EXAMPLES
|
|
|
+
|
|
|
+Destroy all data (including LUKSMeta data) in the LUKSv1 header gap and
|
|
|
+initialize the gap for LUKSMeta storage:
|
|
|
+
|
|
|
+ $ luksmeta init -n -f -d /dev/sdz
|
|
|
+
|
|
|
+If already initialized, do nothing. Otherwise, destroy all non-LUKSMeta data
|
|
|
+in the LUKSv1 header gap and initialize the gap for LUKSMeta storage:
|
|
|
+
|
|
|
+ $ luksmeta init -f -d /dev/sdz
|
|
|
+
|
|
|
+Write some data to a slot:
|
|
|
+
|
|
|
+ $ UUID=*uuidgen*
|
|
|
+ $ echo $UUID
|
|
|
+ 31c25e3b-b8e2-4eaa-a427-23aa882feef2
|
|
|
+ $ echo "Hello, World" | luksmeta save -d /dev/sdz -s 0 -u $UUID
|
|
|
+
|
|
|
+Read the data back:
|
|
|
+
|
|
|
+ $ luksmeta load -d /dev/sdz -s 0 -u $UUID
|
|
|
+ Hello, World
|
|
|
+
|
|
|
+Wipe the data from the slot:
|
|
|
+
|
|
|
+ $ luksmeta wipe -d /dev/sdz -s 0 -u $UUID
|
|
|
+
|
|
|
+Erase all trace of LUKSMeta:
|
|
|
+
|
|
|
+ $ luksmeta nuke -f -d /dev/sdz
|
|
|
+
|
|
|
+== AUTHOR
|
|
|
+
|
|
|
+Nathaniel McCallum <npmccallum@redhat.com>
|
|
|
+
|
|
|
+== SEE ALSO
|
|
|
+
|
|
|
+*cryptsetup*(8),
|
|
|
+*uuidgen*(1)
|