Documentation for commands associated with check_signatures: * High-level discussion in new section "Security and signatures" * Environment variable check_signatures * New documentation for commands distrust, trust, list_trusted, verify_detached (pre-existing commands, but not covered by existing documentation) * Modifications to documentation for load_env, save_env, hashsum
Signed-off-by: Jon McCune <jonmcc...@google.com> --- docs/grub.texi | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 178 insertions(+), 2 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index d5ed014..80baa03 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -96,6 +96,7 @@ This edition documents version @value{VERSION}. * Commands:: The list of available builtin commands * Internationalisation:: Topics relating to language support * Security:: Authentication and authorisation +* Security and signatures:: Verifying digital signatures in GRUB * Platform limitations:: The list of platform-specific limitations * Platform-specific operations:: Platform-specific operations * Supported kernels:: The list of supported kernels @@ -2741,6 +2742,7 @@ These variables have special meaning to GRUB. @menu * biosnum:: +* check_signatures:: * chosen:: * color_highlight:: * color_normal:: @@ -2794,6 +2796,25 @@ For an alternative approach which also changes BIOS drive mappings for the chain-loaded system, @pxref{drivemap}. +@node check_signatures +@subsection check_signatures + +This variable controls whether GRUB enforces digital signature +validation (@pxref{Security and signatures}) on all loaded files. If +@var{check_signatures=enforce}, then every attempt by the GRUB +@file{core.img} to load another file @file{foo} (e.g., a loadable +module, a configuration file, or a Linux kernel) implicitly invokes +@code{verify_detached foo foo.sig} (@pxref{verify_detached}). +@code{foo.sig} must contain a valid digital signature over the +contents of @code{foo}, which can be verified with a public key +currently trusted by grub (@pxref{list_trusted}, @pxref{trust}, +and @pxref{distrust}). If validation fails, then file @file{foo} +cannot be opened. This failure may halt or otherwise impact the boot +process. An initial trusted public key can be embedded within the +GRUB @file{core.img} using the @code{--pubkey} option to +@command{grub-install} (@pxref{Invoking grub-install}). + + @node chosen @subsection chosen @@ -3442,6 +3463,7 @@ you forget a command, you can run the command @command{help} * cryptomount:: Mount a crypto device * date:: Display or set current date and time * devicetree:: Load a device tree blob +* distrust:: Remove a pubkey from trusted keys * drivemap:: Map a drive to another * echo:: Display a line of text * eval:: Evaluate agruments as GRUB commands @@ -3459,6 +3481,7 @@ you forget a command, you can run the command @command{help} * linux:: Load a Linux kernel * linux16:: Load a Linux kernel (16-bit mode) * list_env:: List variables in environment block +* list_trusted:: List trusted public keys * loadfont:: Load font files * load_env:: Load variables from environment block * loopback:: Make a device from a filesystem image @@ -3490,9 +3513,11 @@ you forget a command, you can run the command @command{help} * source:: Read a configuration file in same context * test:: Check file types and compare values * true:: Do nothing, successfully +* trust:: Add public key to list of trusted keys * unset:: Unset an environment variable * uppermem:: Set the upper memory size @comment * vbeinfo:: List available video modes +* verify_detached:: Verify detached digital signature * videoinfo:: List available video modes @end menu @@ -3763,6 +3788,16 @@ but rather replaces it completely. @ref{GNU/Linux}. @end deffn +@node distrust +@subsection distrust + +@deffn Command distrust pubkey_id +Remove public key @var{pubkey_id} from GRUB's keyring of trusted keys. +These keys are used to validate signatures when +@var{check_signatures=enforce} (@pxref{check_signatures}), and by some +invocations of @command{verify_detached} (@pxref{verify_detached}). +@xref{Security and signatures}, for more information. +@end deffn @node drivemap @subsection drivemap @@ -3921,7 +3956,8 @@ list of @var{hash name} pairs in the same format as used by UNIX @command{md5sum} command. Option @option{--prefix} may be used to give directory where files are located. Hash verification stops after the first mismatch was found unless option @option{--keep-going} -was given. +was given. The exit code @code{$?} is set to 0 if hash verification +is successful. If it fails, @code{$?} is set to a nonzero value. @end deffn @@ -4030,16 +4066,41 @@ The @option{-f} option overrides the default location of the environment block. @end deffn +@node list_trusted +@subsection list_trusted + +@deffn Command list_trusted +List all public keys trusted by GRUB for validating signatures. These +public keys are used implicitly when environment variable +@var{check_signatures=enforce} (@pxref{check_signatures}), and by some +invocations of @command{verify_detached}. @xref{Security and +signatures}, for more information. +@end deffn @node load_env @subsection load_env -@deffn Command load_env [@option{-f} file] +@deffn Command load_env [@option{-f} file] [whitelisted_variable_name] @dots{} Load all variables from the environment block file into the environment. @xref{Environment block}. The @option{-f} option overrides the default location of the environment block. + +If one or more variable names are provided as arguments, they are +interpreted as a whitelist of variables to load from the environment +block file. Variables set in the file but not on the whitelist are +ignored. + +If one or more whitelisted variable names are provided, and +@var{check_signatures=enforce} (@pxref{check_signatures}), then +those variables can be read from an untrusted (either unsigned or +incorrectly signed) file. When used with care, this enables an +administrator to configure a system to boot only signed +configurations, but to allow the user to select from among multiple +configurations, and to enable ``one-shot'' boot attempts and +``savedefault'' behavior. @xref{Security and signatures}, for +more information. @end deffn @@ -4289,6 +4350,13 @@ Save the named variables from the environment to the environment block file. The @option{-f} option overrides the default location of the environment block. + +This command will operate successfully even when +@var{check_signatures=enforce} (@pxref{check_signatures}), meaning +that it is possible to modify a digitally signed environment block +file from within grub such that its signature will no longer be valid +on subsequent boots. @xref{Security and signatures}, for more +information. @end deffn @@ -4598,6 +4666,19 @@ Do nothing, successfully. This is mainly useful in control constructs such as @code{if} and @code{while} (@pxref{Shell-like scripting}). @end deffn +@node trust +@subsection trust + +@deffn Command trust pubkey_file +Read public key from @var{pubkey_file} and add it to GRUB's internal +list of trusted public keys. These keys are used to validate digital +signatures when @var{check_signatures=enforce}. Note that if +@var{check_signatures=enforce} when this command is run, then +@var{pubkey_file} must itself be signed such that an already-loaded +public key (@pxref{list_trusted}) can validate that signature. +@xref{Security and signatures}, for more information. +@end deffn + @node unset @subsection unset @@ -4624,6 +4705,21 @@ only on PC BIOS platforms. @end ignore +@node verify_detached +@subsection verify_detached + +@deffn Command verify_detached file signature_file [pubkey_file] +Verifies a GPG-style detached signature, where the signed file is +@var{file}, and the signature itself is in file @var{signature_file}. +Optionally, a specific public key to use can be specified using +@var{pubkey_file}. Otherwise, public keys from GRUB's trusted keys +(@pxref{list_trusted}, @pxref{trust}, and @pxref{distrust}) are +tried. + +Exit code @code{$?} is set to 0 if the signature validates +successfully. If validation fails, it is set to a non-zero value. +@end deffn + @node videoinfo @subsection videoinfo @@ -4813,6 +4909,86 @@ generating configuration files with authentication. You can use adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} commands. +@node Security and signatures +@chapter Security considerations when using digital signatures + +GRUB's @file{core.img} can optionally provide enforcement that all +files subsequently read from disk are covered by a valid digital +signature. This includes GRUB configuration files, the GRUB +environment block, GRUB loadable modules and their dependency files, +and loaded operating system files such as a Linux kernel. This +document does @strong{not} cover how to ensure that your platform's +firmware (e.g., GNU Coreboot or UEFI Secure Boot) validates +@file{core.img}. + +GRUB uses GPG-style detached signatures (meaning that a file +@file{foo.sig} will be produced when file @file{foo} is signed), and +currently supports the DSA signing algorithm. Both 2048-bit and +3072-bit keys are supported. A signing key can be generated as +follows: + +@example +gpg --gen-key +@end example + +The corresponding public key must be embedded in @file{core.img} when +executing the @command{grub-install} (@pxref{Invoking grub-install}) +utility. This can be done using the @code{--pubkey} option and +manually specifying that the modules required for signature +verification be embedded in @file{core.img}. For example: + +@example +grub-install \ + --pubkey=/boot/pubkey.gpg \ + --modules="verify gcry_rsa gcry_dsa gcry_sha256 hashsum"\ +"gcry_sha1 mpi echo loadenv" \ + /dev/sda +@end example + +An individual file can be signed as follows: + +@example +gpg --detach-sign /path/to/file +@end example + +For successful validation of all of GRUB's subcomponents and the +loaded OS kernel, they must all be signed. One way to accomplish this +is the following (after having already produced the desired +@file{grub.cfg} file, e.g., by running @command{grub-mkconfig} +(@pxref{Invoking grub-mkconfig}): + +@example +@group +# Edit /dev/shm/passphrase.txt to contain your signing key's passphrase +for i in `find /boot -name "*.cfg" -or -name "*.lst" -or \ + -name "*.mod" -or -name "vmlinuz*" -or -name "initrd*" -or \ + -name "grubenv"`; +do + gpg --batch --detach-sign --passphrase-fd 0 $i < \ + /dev/shm/passphrase.txt +done +shred /dev/shm/passphrase.txt +@end group +@end example + +See also: @ref{check_signatures}, @ref{verify_detached}, @ref{trust}, +@ref{list_trusted}, @ref{distrust}, @ref{load_env}, @ref{save_env}. + +Note that internally signature enforcement is controlled by setting +the environment variable @var{check_signatures=enforce}. Passing a +@code{--pubkey} option to @command{grub-install} implicitly enables +enforcement in @file{core.img}. + +Note that signature checking does @strong{not} prevent an attacker +with (serial, physical, ...) console access from dropping manually to +the grub console and executing: + +@example +set check_signatures=no +@end example + +To prevent this, password-protection as described in @pxref{Security} +is essential. @node Platform limitations @chapter Platform limitations -- 1.8.4 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel