From: Jon McCune <jonmccune@google.com>
To: grub-devel@gnu.org
Cc: Jon McCune <jonmccune@google.com>
Subject: [PATCH v2 5/5] Additional security-relevant documentation
Date: Fri, 6 Sep 2013 09:18:53 -0700 [thread overview]
Message-ID: <1378484333-13577-6-git-send-email-jonmccune@google.com> (raw)
In-Reply-To: <1378484333-13577-1-git-send-email-jonmccune@google.com>
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 <jonmccune@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
prev parent reply other threads:[~2013-09-06 16:20 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-06 16:18 [PATCH v2 0/5] Enable savedefault, etc with check_signatures=enforce Jon McCune
2013-09-06 16:18 ` [PATCH v2 1/5] style: indent --no-tabs --gnu-style grub-core/commands/loadenv.c Jon McCune
2013-09-06 16:18 ` [PATCH v2 2/5] load_env support for whitelisting which variables are read from an env file, even if check_signatures=enforce Jon McCune
2013-09-06 19:48 ` Andrey Borzenkov
2013-09-06 21:10 ` Jonathan McCune
2013-09-07 9:33 ` Andrey Borzenkov
2013-09-09 15:34 ` Jonathan McCune
2013-09-19 10:12 ` Andrey Borzenkov
2013-09-19 18:18 ` Jonathan McCune
2013-09-19 7:18 ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-09-19 10:06 ` Andrey Borzenkov
2013-09-06 16:18 ` [PATCH v2 3/5] save_env should work, " Jon McCune
2013-09-06 16:18 ` [PATCH v2 4/5] Add -k, --pubkey=FILE support to grub-install command Jon McCune
2013-09-06 19:40 ` Andrey Borzenkov
2013-09-06 21:10 ` Jonathan McCune
2013-09-06 16:18 ` Jon McCune [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1378484333-13577-6-git-send-email-jonmccune@google.com \
--to=jonmccune@google.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).