Index: etc/defaults/rc.conf =================================================================== --- etc/defaults/rc.conf +++ etc/defaults/rc.conf @@ -77,6 +77,8 @@ # GELI disk encryption configuration. geli_devices="" # List of devices to automatically attach in addition to # GELI devices listed in /etc/fstab. +geli_groups="" # List of groups containing devices to automatically + # attach with the same keyfiles and passphrase geli_tries="" # Number of times to attempt attaching geli device. # If empty, kern.geom.eli.tries will be used. geli_default_flags="" # Default flags for geli(8). @@ -88,6 +90,11 @@ #geli_da1_flags="-p -k /etc/geli/da1.keys" #geli_da1_autodetach="NO" #geli_mirror_home_flags="-k /etc/geli/home.keys" +#geli_groups="storage backup" +#geli_storage_flags="-k /etc/geli/storage.keys" +#geli_storage_devices="ada0 ada1" +#geli_backup_flags="-j /etc/geli/backup.passfile -k /etc/geli/backup.keys" +#geli_backup_devices="ada2 ada3" root_rw_mount="YES" # Set to NO to inhibit remounting root read-write. root_hold_delay="30" # Time to wait for root mount hold release. Index: etc/rc.d/geli =================================================================== --- etc/rc.d/geli +++ etc/rc.d/geli @@ -34,7 +34,7 @@ name="geli" desc="GELI disk encryption" -start_precmd='[ -n "$(geli_make_list)" ]' +start_precmd='[ -n "$(geli_make_list)" -o -n "$geli_groups" ]' start_cmd="geli_start" stop_cmd="geli_stop" required_modules="geom_eli:g_eli" @@ -72,11 +72,47 @@ done fi done + + for group in ${geli_groups}; do + group_=`ltr ${group} '/-' '_'` + + eval "flags=\${geli_${group_}_flags}" + if [ -z "${flags}" ]; then + flags=${geli_default_flags} + fi + + eval "providers=\${geli_${group_}_devices}" + if [ -z "${providers}" ]; then + echo "No devices listed in geli group ${group}." + break + fi + + if [ -e "/dev/${providers%% *}" -a ! -e "/dev/${providers%% *}.eli" ]; then + echo "Configuring Disk Encryption for geli group ${group}, containing ${providers}." + count=1 + while [ ${count} -le ${geli_tries} ]; do + geli attach ${flags} ${providers} + if [ -e "/dev/${providers%% *}.eli" ]; then + break + fi + echo "Attach failed; attempt ${count} of ${geli_tries}." + count=$((count+1)) + done + fi + done } geli_stop() { devices=`geli_make_list` + + for group in ${geli_groups}; do + group_=`ltr ${group} '/-' '_'` + + eval "providers=\${geli_${group_}_devices}" + + devices="${devices} ${providers}" + done for provider in ${devices}; do if [ -e "/dev/${provider}.eli" ]; then Index: sbin/geom/class/eli/geli.8 =================================================================== --- sbin/geom/class/eli/geli.8 +++ sbin/geom/class/eli/geli.8 @@ -70,7 +70,7 @@ .Op Fl dprv .Op Fl j Ar passfile .Op Fl k Ar keyfile -.Ar prov +.Ar prov ... .Nm .Cm detach .Op Fl fl @@ -191,8 +191,7 @@ one or more files. .It Allows encryption of the root partition. -The user will be asked for the -passphrase before the root file system is mounted. +The user is asked for the passphrase before the root filesystem is mounted. .It Strengthens the passphrase component of the User Key with: .Rs @@ -216,12 +215,12 @@ it is possible to get the data back by restoring keys from backup. .It -Providers can be configured to automatically detach on last close -(so users do not have to remember to detach providers after unmounting -the file systems). +Providers can be configured to automatically detach on last close, +so users do not have to remember to detach providers after unmounting +the filesystems. .It -Allows attaching a provider with a random, one-time Master Key - -useful for swap partitions and temporary file systems. +Allows attaching a provider with a random, one-time Master Key, +which is useful for swap partitions and temporary filesystems. .It Allows verification of data integrity (data authentication). .It @@ -374,26 +373,31 @@ versions. Consult the .Sx HISTORY -section to find which metadata version is supported by which FreeBSD version. +section to find which metadata version is supported by which +.Fx +version. Note that using an older version of metadata may limit the number of features available. .El .It Cm attach -Attach the given provider. -The encrypted Master Key will be loaded from the metadata and decrypted -using the given passphrase/keyfile and a new GEOM provider will be created -using the given provider's name with an +Attach the given providers. +The encrypted Master Keys are loaded from the metadata and decrypted +using the given passphrase/keyfile and new GEOM providers are created +using the specified provider names. A .Qq .eli -suffix. +suffix is added to the user specified provider names. +Multiple providers can only be attached with a single +.Cm attach +command if they all have the same passphrase and keyfiles. .Pp Additional options include: .Bl -tag -width ".Fl j Ar passfile" .It Fl d -If specified, a decrypted provider will be detached automatically on last close. -This can help with scarce memory so the user does not have to remember to detach the -provider after unmounting the file system. -It only works when the provider was opened for writing, so it will not work if -the file system on the provider is mounted read-only. +If specified, the decrypted providers are detached automatically on last close, +so the user does not have to remember to detach +providers after unmounting the filesystems. +This only works when providers were opened for writing, and will not work if +the filesystems on the providers were mounted read-only. Probably a better choice is the .Fl l option for the @@ -407,6 +411,7 @@ option for the .Cm init subcommand. +The same passfiles are used for all listed providers. .It Fl k Ar keyfile Specifies a file which contains the keyfile component of the User Key (or part of it). @@ -415,14 +420,15 @@ option for the .Cm init subcommand. +The same keyfiles are used for all listed providers. .It Fl p -Do not use a passphrase as a component of the User Key. +Do not use a passphrase as a component of the User Keys. Cannot be combined with the .Fl j option. .It Fl r -Attach read-only provider. -It will not be opened for writing. +Attach read-only providers. +They are not opened for writing. .El .It Cm detach Detach the given providers, which means remove the devfs entry @@ -433,14 +439,14 @@ .It Fl f Force detach - detach even if the provider is open. .It Fl l -Mark provider to detach on last close. -If this option is specified, the provider will not be detached +Mark provider to detach on last close (after the last filesystem has been +unmounted). If this option is specified, the provider will not be detached while it is open, but will be automatically detached when it is closed for the last time even if it was only opened for reading. .El .It Cm onetime Attach the given providers with a random, one-time (ephemeral) Master Key. -The command can be used to encrypt swap partitions or temporary file systems. +The command can be used to encrypt swap partitions or temporary filesystems. .Pp Additional options include: .Bl -tag -width ".Fl a Ar sectorsize" @@ -455,10 +461,10 @@ .Cm init subcommand. .It Fl d -Detach on last close. -Note: this option is not usable for temporary file systems as the provider will -be detached after creating the file system on it. -It still can (and should be) used for swap partitions. +Detach on last close (after the last filesystem has been unmounted). +Note: this option is not usable for temporary filesystems as the provider is +detached after creating the filesystem on it. +It still can, and should, be used for swap partitions. For more information, see the description of the .Cm attach subcommand. @@ -622,14 +628,14 @@ .El .It Cm suspend Suspend device by waiting for all inflight requests to finish, clearing all -sensitive information (like the Master Key and Data Keys) from kernel memory, +sensitive information such as the Master Key and Data Keys from kernel memory, and blocking all further I/O requests until the .Cm resume subcommand is executed. This functionality is useful for laptops: when one wants to suspend a laptop, one does not want to leave an encrypted device attached. -Instead of closing all files and directories opened from a file system located -on an encrypted device, unmounting the file system, and detaching the device, +Instead of closing all files and directories opened from a filesystem located +on an encrypted device, unmounting the filesystem, and detaching the device, the .Cm suspend subcommand can be used. @@ -643,8 +649,8 @@ subcommand does not work with devices created with the .Cm onetime subcommand. -Please note that sensitive data might still be present in memory after -suspending an encrypted device due to the file system cache, etc. +Please note that sensitive data might still be present in memory locations +such as the filesystem cache after suspending an encrypted device. .Pp Additional options include: .Bl -tag -width ".Fl a" @@ -657,9 +663,9 @@ Resume previously suspended device. The caller must ensure that executing this subcommand does not access the suspended device, leading to a deadlock. -For example suspending a device which contains the file system where the +For example, suspending a device which contains the filesystem where the .Nm -utility is stored is bad idea. +utility is stored is a bad idea. .Pp Additional options include: .Bl -tag -width ".Fl j Ar passfile" @@ -789,18 +795,17 @@ maximum amount of debug information is printed. .It Va kern.geom.eli.tries : No 3 Number of times a user is asked for the passphrase. -This is only used for providers which are attached on boot -(before the root file system is mounted). +This is only used for providers which are attached on boot, +before the root filesystem is mounted. If set to 0, attaching providers on boot will be disabled. This variable should be set in .Pa /boot/loader.conf . .It Va kern.geom.eli.overwrites : No 5 -Specifies how many times the Master Key will be overwritten +Specifies how many times the Master Key is overwritten with random values when it is destroyed. After this operation it is filled with zeros. .It Va kern.geom.eli.visible_passphrase : No 0 -If set to 1, the passphrase entered on boot (before the root -file system is mounted) will be visible. +If set to 1, the passphrase entered on boot will be visible. This alternative should be used with caution as the entered passphrase can be logged and exposed via .Xr dmesg 8 . @@ -839,7 +844,7 @@ Initialize a provider which is going to be encrypted with a passphrase and random data from a file on the user's pen drive. Use 4kB sector size. -Attach the provider, create a file system, and mount it. +Attach the provider, create a filesystem, and mount it. Do the work. Unmount the provider and detach it: .Bd -literal -offset indent @@ -894,7 +899,7 @@ .Ed .Pp The example below shows how to configure two providers which will be attached -on boot (before the root file system is mounted). +on boot, before the root filesystem is mounted. One of them is using passphrase and three keyfile parts and the other is using only a keyfile in one part: .Bd -literal -offset indent @@ -972,7 +977,7 @@ Enter passphrase: .Ed .Pp -If an encrypted file system is extended, it is necessary to relocate and +If an encrypted filesystem is extended, it is necessary to relocate and update the metadata: .Bd -literal -offset indent # gpart create -s GPT ada0 Index: sbin/geom/class/eli/geom_eli.c =================================================================== --- sbin/geom/class/eli/geom_eli.c +++ sbin/geom/class/eli/geom_eli.c @@ -60,7 +60,14 @@ #define GELI_BACKUP_DIR "/var/backups/" #define GELI_ENC_ALGO "aes" +#define BUFSIZE 1024 +/* + * Passphrase cached when attaching multiple providers, in order to be more + * user-friendly if they are using the same passphrase. + */ +static char cached_passphrase[BUFSIZE] = ""; + static void eli_main(struct gctl_req *req, unsigned flags); static void eli_init(struct gctl_req *req); static void eli_attach(struct gctl_req *req); @@ -84,7 +91,7 @@ * * init [-bgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov * label - alias for 'init' - * attach [-dprv] [-j passfile] [-k keyfile] prov + * attach [-dprv] [-j passfile] [-k keyfile] prov ... * detach [-fl] prov ... * stop - alias for 'detach' * onetime [-d] [-a aalgo] [-e ealgo] [-l keylen] prov @@ -267,8 +274,6 @@ static int verbose = 0; -#define BUFSIZE 1024 - static int eli_protect(struct gctl_req *req) { @@ -474,6 +479,10 @@ bool nopassphrase; int nfiles; + /* + * Return error if the 'do not use passphrase' flag was given but a + * passfile was provided. + */ nopassphrase = gctl_get_int(req, new ? "nonewpassphrase" : "nopassphrase"); if (nopassphrase) { @@ -486,20 +495,32 @@ return (0); } + /* + * Return error if using a provider which does not require a passphrase + * but the 'do not use passphrase' flag was not given. + */ if (!new && md->md_iterations == -1) { gctl_error(req, "Missing -p flag."); return (-1); } passbuf[0] = '\0'; - nfiles = eli_genkey_files(req, new, "passfile", NULL, passbuf, - sizeof(passbuf)); - if (nfiles == -1) - return (-1); - else if (nfiles == 0) { - if (eli_genkey_passphrase_prompt(req, new, passbuf, - sizeof(passbuf)) == -1) { + + /* Use cached passphrase if defined. */ + if (strcmp(cached_passphrase, "") != 0) { + memcpy(passbuf, cached_passphrase, sizeof(passbuf)); + } else { + nfiles = eli_genkey_files(req, new, "passfile", NULL, passbuf, + sizeof(passbuf)); + if (nfiles == -1) return (-1); + else if (nfiles == 0) { + if (eli_genkey_passphrase_prompt(req, new, passbuf, + sizeof(passbuf)) == -1) { + return (-1); + } } + /* Cache the passphrase for other providers. */ + memcpy(cached_passphrase, passbuf, sizeof(passbuf)); } /* * Field md_iterations equal to -1 means "choose some sane @@ -876,38 +897,56 @@ eli_attach(struct gctl_req *req) { struct g_eli_metadata md; - unsigned char key[G_ELI_USERKEYLEN]; const char *prov; off_t mediasize; - int nargs; + char param[16]; + int i, nargs; nargs = gctl_get_int(req, "nargs"); - if (nargs != 1) { - gctl_error(req, "Invalid number of arguments."); + if (nargs == 0) { + gctl_error(req, "Too few arguments."); return; } - prov = gctl_get_ascii(req, "arg0"); - if (eli_metadata_read(req, prov, &md) == -1) - return; + /* Use a 2D array for storing the derived keys (1 row per provider) */ + unsigned char key[nargs][G_ELI_USERKEYLEN]; - mediasize = g_get_mediasize(prov); - if (md.md_provsize != (uint64_t)mediasize) { - gctl_error(req, "Provider size mismatch."); - return; - } + /* Generate the derived key for each provider */ + for (i = 0; i < nargs; i++) { + prov = gctl_get_ascii(req, "arg%d", i); - if (eli_genkey(req, &md, key, false) == NULL) { - bzero(key, sizeof(key)); - return; + if (eli_metadata_read(req, prov, &md) == -1) + return; + + mediasize = g_get_mediasize(prov); + if (md.md_provsize != (uint64_t)mediasize) { + gctl_error(req, "Provider size mismatch."); + return; + } + + if (eli_genkey(req, &md, key[i], false) == NULL) { + bzero(key, sizeof(key)); + return; + } + + snprintf(param, sizeof(param), "key%d", i); + gctl_ro_param(req, param, sizeof(key[i]), key[i]); } - gctl_ro_param(req, "key", sizeof(key), key); if (gctl_issue(req) == NULL) { - if (verbose) - printf("Attached to %s.\n", prov); + if (verbose) { + printf("Attached to"); + for (i = 0; i < nargs; i++) { + printf(" %s", gctl_get_ascii(req, "arg%d", i)); + } + printf(".\n"); + } } + + /* Clear each of the derived keys from the 2D array */ bzero(key, sizeof(key)); + /* Clear the cached passphrase */ + bzero(cached_passphrase, sizeof(cached_passphrase)); } static void Index: share/man/man5/rc.conf.5 =================================================================== --- share/man/man5/rc.conf.5 +++ share/man/man5/rc.conf.5 @@ -1931,6 +1931,13 @@ Note that .eli devices from .Pa /etc/fstab are automatically appended to this list. +.It Va geli_groups +.Pq Vt str +List of groups containing devices to automatically attach on boot with the same +keyfiles and passphrase. +This must be accompanied with a corresponding +.Va geli_ Ns Ao Ar group Ac Ns Va _devices +variable. .It Va geli_tries .Pq Vt int Number of times user is asked for the pass-phrase. @@ -1942,8 +1949,10 @@ Default flags to use by .Xr geli 8 when configuring disk encryption. -Flags can be configured for every device separately by defining +Flags can be configured for every device separately by defining the .Va geli_ Ns Ao Ar device Ac Ns Va _flags +variable, and for every group separately by defining the +.Va geli_ Ns Ao Ar group Ac Ns Va _flags variable. .It Va geli_autodetach .Pq Vt str @@ -1951,7 +1960,7 @@ file systems are mounted. Default is .Dq Li YES . -This can be changed for every device separately by defining +This can be changed for every device separately by defining the .Va geli_ Ns Ao Ar device Ac Ns Va _autodetach variable. .It Va root_rw_mount @@ -2753,6 +2762,19 @@ whose contents will later be passed to a .Dq Nm route Cm add Fl inet6 operation. +.It Va natm_static_routes +.Pq Vt str +The +.Xr natmip 4 +equivalent of +.Va static_routes . +If not empty then for each whitespace separated +.Ar element +in the value, a +.Va route_ Ns Aq Ar element +variable is assumed to exist whose contents will later be passed to a +.Dq Nm atmconfig Cm natm Cm add +operation. .It Va gateway_enable .Pq Vt bool If set to @@ -2933,6 +2955,136 @@ .Va rtsol_flags ; .Va rtsold_enable takes precedence. +.It Va atm_enable +.Pq Vt bool +Set to +.Dq Li YES +to enable the configuration of ATM interfaces at system boot time. +For all of the ATM variables described below, please refer to the +.Xr atm 8 +manual page for further details on the available command parameters. +Also refer to the files in +.Pa /usr/share/examples/atm +for more detailed configuration information. +.It Va atm_load +.Pq Vt str +This is a list of physical ATM interface drivers to load. +Typical values are +.Dq Li hfa_pci +and/or +.Dq Li hea_pci . +.It Va atm_netif_ Ns Aq Ar intf +.Pq Vt str +For the ATM physical interface +.Ar intf , +this variable defines the name prefix and count for the ATM network +interfaces to be created. +The value will be passed as the parameters of an +.Dq Nm atm Cm "set netif" Ar intf +command. +.It Va atm_sigmgr_ Ns Aq Ar intf +.Pq Vt str +For the ATM physical interface +.Ar intf , +this variable defines the ATM signalling manager to be used. +The value will be passed as the parameters of an +.Dq Nm atm Cm attach Ar intf +command. +.It Va atm_prefix_ Ns Aq Ar intf +.Pq Vt str +For the ATM physical interface +.Ar intf , +this variable defines the NSAP prefix for interfaces using a UNI signalling +manager. +If set to +.Dq Li ILMI , +the prefix will automatically be set via the +.Xr ilmid 8 +daemon. +Otherwise, the value will be passed as the parameters of an +.Dq Nm atm Cm "set prefix" Ar intf +command. +.It Va atm_macaddr_ Ns Aq Ar intf +.Pq Vt str +For the ATM physical interface +.Ar intf , +this variable defines the MAC address for interfaces using a UNI signalling +manager. +If set to +.Dq Li NO , +the hardware MAC address contained in the ATM interface card will be used. +Otherwise, the value will be passed as the parameters of an +.Dq Nm atm Cm "set mac" Ar intf +command. +.It Va atm_arpserver_ Ns Aq Ar netif +.Pq Vt str +For the ATM network interface +.Ar netif , +this variable defines the ATM address for a host which is to provide ATMARP +service. +This variable is only applicable to interfaces using a UNI signalling +manager. +If set to +.Dq Li local , +this host will become an ATMARP server. +The value will be passed as the parameters of an +.Dq Nm atm Cm "set arpserver" Ar netif +command. +.It Va atm_scsparp_ Ns Aq Ar netif +.Pq Vt bool +If set to +.Dq Li YES , +SCSP/ATMARP service for the network interface +.Ar netif +will be initiated using the +.Xr scspd 8 +and +.Xr atmarpd 8 +daemons. +This variable is only applicable if +.Va atm_arpserver_ Ns Aq Ar netif +is set to +.Dq Li local . +.It Va atm_pvcs +.Pq Vt str +Set to the list of ATM PVCs to be added at system +boot time. +For each whitespace separated +.Ar element +in the value, an +.Va atm_pvc_ Ns Aq Ar element +variable is assumed to exist. +The value of each of these variables +will be passed as the parameters of an +.Dq Nm atm Cm "add pvc" +command. +.It Va atm_arps +.Pq Vt str +Set to the list of permanent ATM ARP entries to be added +at system boot time. +For each whitespace separated +.Ar element +in the value, an +.Va atm_arp_ Ns Aq Ar element +variable is assumed to exist. +The value of each of these variables +will be passed as the parameters of an +.Dq Nm atm Cm "add arp" +command. +.It Va natm_interfaces +.Pq Vt str +Set to the list of +.Xr natm 4 +interfaces that will also be used for HARP through +.Xr harp 4 . +If this list is not empty all interfaces in the list will be brought up +with +.Xr ifconfig 8 +and +.Xr harp 4 +will be loaded. +For this to work the interface drivers must be either compiled into the +kernel or must reside on the root partition. .It Va keybell .Pq Vt str The keyboard bell sound. @@ -4449,6 +4601,7 @@ .Xr accton 8 , .Xr amd 8 , .Xr apm 8 , +.Xr atm 8 , .Xr bsdinstall 8 , .Xr bthidd 8 , .Xr chkprintcap 8 , Index: sys/geom/eli/g_eli_ctl.c =================================================================== --- sys/geom/eli/g_eli_ctl.c +++ sys/geom/eli/g_eli_ctl.c @@ -57,8 +57,9 @@ struct g_provider *pp; const char *name; u_char *key, mkey[G_ELI_DATAIVKEYLEN]; + char param[16], argname[16]; int *nargs, *detach, *readonly; - int keysize, error; + int i, keysize, error; u_int nkey; g_topology_assert(); @@ -68,8 +69,8 @@ gctl_error(req, "No '%s' argument.", "nargs"); return; } - if (*nargs != 1) { - gctl_error(req, "Invalid number of arguments."); + if (*nargs == 0) { + gctl_error(req, "Too few arguments."); return; } @@ -90,58 +91,66 @@ return; } - name = gctl_get_asciiparam(req, "arg0"); - if (name == NULL) { - gctl_error(req, "No 'arg%u' argument.", 0); - return; - } - if (strncmp(name, "/dev/", strlen("/dev/")) == 0) - name += strlen("/dev/"); - pp = g_provider_by_name(name); - if (pp == NULL) { - gctl_error(req, "Provider %s is invalid.", name); - return; - } - error = g_eli_read_metadata(mp, pp, &md); - if (error != 0) { - gctl_error(req, "Cannot read metadata from %s (error=%d).", - name, error); - return; - } - if (md.md_keys == 0x00) { - explicit_bzero(&md, sizeof(md)); - gctl_error(req, "No valid keys on %s.", pp->name); - return; - } + /* Attach each provider in the request */ + for (i = 0; i < *nargs; i++) { + snprintf(argname, sizeof(argname), "arg%d", i); + name = gctl_get_asciiparam(req, argname); + if (name == NULL) { + gctl_error(req, "No '%s' argument.", argname); + continue; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + if (pp == NULL) { + gctl_error(req, "Provider %s is invalid.", name); + continue; + } + error = g_eli_read_metadata(mp, pp, &md); + if (error != 0) { + gctl_error(req, "Cannot read metadata from %s (error=%d).", + name, error); + continue; + } + if (md.md_keys == 0x00) { + explicit_bzero(&md, sizeof(md)); + gctl_error(req, "No valid keys on %s.", pp->name); + continue; + } - key = gctl_get_param(req, "key", &keysize); - if (key == NULL || keysize != G_ELI_USERKEYLEN) { - explicit_bzero(&md, sizeof(md)); - gctl_error(req, "No '%s' argument.", "key"); - return; - } + /* Get the derived key for this provider from the request */ + snprintf(param, sizeof(param), "key%d", i); + key = gctl_get_param(req, param, &keysize); + if (key == NULL || keysize != G_ELI_USERKEYLEN) { + explicit_bzero(&md, sizeof(md)); + gctl_error(req, "No '%s' argument.", param); + continue; + } - error = g_eli_mkey_decrypt(&md, key, mkey, &nkey); - explicit_bzero(key, keysize); - if (error == -1) { + /* Decrypt the master key for this provider */ + error = g_eli_mkey_decrypt(&md, key, mkey, &nkey); + explicit_bzero(key, keysize); + if (error == -1) { + explicit_bzero(&md, sizeof(md)); + gctl_error(req, "Wrong key for %s.", pp->name); + continue; + } else if (error > 0) { + explicit_bzero(&md, sizeof(md)); + gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).", + pp->name, error); + continue; + } + G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name); + + /* Create the new GEOM provider using the master key */ + if (*detach) + md.md_flags |= G_ELI_FLAG_WO_DETACH; + if (*readonly) + md.md_flags |= G_ELI_FLAG_RO; + g_eli_create(req, mp, pp, &md, mkey, nkey); + explicit_bzero(mkey, sizeof(mkey)); explicit_bzero(&md, sizeof(md)); - gctl_error(req, "Wrong key for %s.", pp->name); - return; - } else if (error > 0) { - explicit_bzero(&md, sizeof(md)); - gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).", - pp->name, error); - return; } - G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name); - - if (*detach) - md.md_flags |= G_ELI_FLAG_WO_DETACH; - if (*readonly) - md.md_flags |= G_ELI_FLAG_RO; - g_eli_create(req, mp, pp, &md, mkey, nkey); - explicit_bzero(mkey, sizeof(mkey)); - explicit_bzero(&md, sizeof(md)); } static struct g_eli_softc *