1UKIFY(1) ukify UKIFY(1)
2
3
4
6 ukify - Combine components into a signed Unified Kernel Image for UEFI
7 systems
8
10 /usr/lib/systemd/ukify [OPTIONS...] build
11
12 ukify [OPTIONS...] genkey
13
15 Note: this command is experimental for now. While it is intended to
16 become a regular component of systemd, it might still change in
17 behaviour and interface.
18
19 ukify is a tool whose primary purpose is to combine components (usually
20 a kernel, an initrd, and a UEFI boot stub) to create a Unified Kernel
21 Image (UKI)[1] — a PE binary that can be executed by the firmware to
22 start the embedded linux kernel. See systemd-stub(7) for details about
23 the stub.
24
26 The following commands are understood:
27
28 build
29 This command creates a Unified Kernel Image. The two primary options
30 that should be specified for the build verb are Linux=/--linux=, and
31 Initrd=/--initrd=. Initrd= accepts multiple whitespace-separated paths
32 and --initrd= can be specified multiple times.
33
34 Additional sections will be inserted into the UKI, either automatically
35 or only if a specific option is provided. See the discussions of
36 Cmdline=/--cmdline=, OSRelease=/--os-release=,
37 DeviceTree=/--devicetree=, Splash=/--splash=, PCRPKey=/--pcrpkey=,
38 Uname=/--uname=, SBAT=/--sbat=, and --section= below.
39
40 ukify can also be used to assemble a PE binary that is not executable
41 but contains auxiliary data, for example additional kernel command line
42 entries.
43
44 If PCR signing keys are provided via the
45 PCRPrivateKey=/--pcr-private-key= and PCRPublicKey=/--pcr-public-key=
46 options, PCR values that will be seen after booting with the given
47 kernel, initrd, and other sections, will be calculated, signed, and
48 embedded in the UKI. systemd-measure(1) is used to perform this
49 calculation and signing.
50
51 The calculation of PCR values is done for specific boot phase paths.
52 Those can be specified with the Phases=/--phases= option. If not
53 specified, the default provided by systemd-measure is used. It is also
54 possible to specify the PCRPrivateKey=/--pcr-private-key=,
55 PCRPublicKey=/--pcr-public-key=, and Phases=/--phases= arguments more
56 than once. Signatures will then be performed with each of the specified
57 keys. On the command line, when both --phases= and --pcr-private-key=
58 are used, they must be specified the same number of times, and then the
59 n-th boot phase path set will be signed by the n-th key. This can be
60 used to build different trust policies for different phases of the
61 boot. In the config file, PCRPrivateKey=, PCRPublicKey=, and Phases=
62 are grouped into separate sections, describing separate boot phases.
63
64 If a SecureBoot signing key is provided via the
65 SecureBootPrivateKey=/--secureboot-private-key= option, the resulting
66 PE binary will be signed as a whole, allowing the resulting UKI to be
67 trusted by SecureBoot. Also see the discussion of automatic enrollment
68 in systemd-boot(7).
69
70 If the stub and/or the kernel contain ".sbat" sections they will be
71 merged in the UKI so that revocation updates affecting either are
72 considered when the UKI is loaded by Shim. For more information on SBAT
73 see Shim's documentation.[2]
74
75 genkey
76 This command creates the keys for PCR signing and the key and
77 certificate used for SecureBoot signing. The same configuration options
78 that determine what keys and in which paths will be needed for signing
79 when build is used, here determine which keys will be created. See the
80 discussion of PCRPrivateKey=/--pcr-private-key=,
81 PCRPublicKey=/--pcr-public-key=, and
82 SecureBootPrivateKey=/--secureboot-private-key= below.
83
84 The output files must not exist.
85
87 Settings can appear in configuration files (the syntax with
88 SomeSetting=value) and on the command line (the syntax with
89 --some-setting=value). For some command line parameters, a
90 single-letter shortcut is also allowed. In the configuration files, the
91 setting must be in the appropriate section, so the descriptions are
92 grouped by section below. When the same setting appears in the
93 configuration file and on the command line, generally the command line
94 setting has higher priority and overwrites the config file setting
95 completely. If some setting behaves differently, this is described
96 below.
97
98 The LINUX and INITRD positional arguments, or the equivalent Linux= and
99 Initrd= settings, are optional. If more than one initrd is specified,
100 they will all be combined into a single PE section. This is useful to,
101 for example, prepend microcode before the actual initrd.
102
103 The following options and settings are understood:
104
105 Commandline-only options
106 --config=PATH
107 Load configuration from the given config file. In general, settings
108 specified in the config file have lower precedence than the
109 settings specified via options. In cases where the commandline
110 option does not fully override the config file setting are
111 explicitly mentioned in the descriptions of individual options.
112
113 --measure, --no-measure
114 Enable or disable a call to systemd-measure(1) to print
115 pre-calculated PCR values. Defaults to false.
116
117 --section=NAME:TEXT|@PATH
118 Specify an arbitrary additional section "NAME". Note that the name
119 is used as-is, and if the section name should start with a dot, it
120 must be included in NAME. The argument may be a literal string, or
121 "@" followed by a path name. This option may be specified more than
122 once. Any sections specified in this fashion will be inserted (in
123 order) before the ".linux" section which is always last.
124
125 --tools=DIRS
126 Specify one or more directories with helper tools. ukify will look
127 for helper tools in those directories first, and if not found, try
128 to load them from $PATH in the usual fashion.
129
130 --output=FILENAME
131 The output filename. If not specified, the name of the LINUX
132 argument, with the suffix ".unsigned.efi" or ".signed.efi" will be
133 used, depending on whether signing for SecureBoot was performed.
134
135 --summary
136 Print a summary of loaded config and exit. This is useful to check
137 how the options form the configuration file and the commandline are
138 combined.
139
140 -h, --help
141 Print a short help text and exit.
142
143 --version
144 Print a short version string and exit.
145
146 [UKI] section
147 Linux=LINUX, --linux=LINUX
148 A path to the kernel binary.
149
150 Initrd=INITRD..., --initrd=LINUX
151 Zero or more initrd paths. In the configuration file, items are
152 separated by whitespace. The initrds are combined in the order of
153 specification, with the initrds specified in the config file first.
154
155 Cmdline=TEXT|@PATH, --cmdline=TEXT|@PATH
156 The kernel command line (the ".cmdline" section). The argument may
157 be a literal string, or "@" followed by a path name. If not
158 specified, no command line will be embedded.
159
160 OSRelease=TEXT|@PATH, --os-release=TEXT|@PATH
161 The os-release description (the ".osrel" section). The argument may
162 be a literal string, or "@" followed by a path name. If not
163 specified, the os-release(5) file will be picked up from the host
164 system.
165
166 DeviceTree=PATH, --devicetree=PATH
167 The devicetree description (the ".dtb" section). The argument is a
168 path to a compiled binary DeviceTree file. If not specified, the
169 section will not be present.
170
171 Splash=PATH, --splash=PATH
172 A picture to display during boot (the ".splash" section). The
173 argument is a path to a BMP file. If not specified, the section
174 will not be present.
175
176 PCRPKey=PATH, --pcrpkey=PATH
177 A path to a public key to embed in the ".pcrpkey" section. If not
178 specified, and there's exactly one PCRPublicKey=/--pcr-public-key=
179 argument, that key will be used. Otherwise, the section will not be
180 present.
181
182 Uname=VERSION, --uname=VERSION
183 Specify the kernel version (as in uname -r, the ".uname" section).
184 If not specified, an attempt will be made to extract the version
185 string from the kernel image. It is recommended to pass this
186 explicitly if known, because the extraction is based on heuristics
187 and not very reliable. If not specified and extraction fails, the
188 section will not be present.
189
190 PCRBanks=PATH, --pcr-banks=PATH
191 A comma or space-separated list of PCR banks to sign a policy for.
192 If not present, all known banks will be used ("sha1", "sha256",
193 "sha384", "sha512"), which will fail if not supported by the
194 system.
195
196 SecureBootSigningTool=SIGNER, --signtool=SIGNER
197 Whether to use "sbsign" or "pesign". Depending on this choice,
198 different parameters are required in order to sign an image.
199 Defaults to "sbsign".
200
201 SecureBootPrivateKey=SB_KEY, --secureboot-private-key=SB_KEY
202 A path to a private key to use for signing of the resulting binary.
203 If the SigningEngine=/--signing-engine= option is used, this may
204 also be an engine-specific designation. This option is required by
205 SecureBootSigningTool=sbsign/--signtool=sbsign.
206
207 SecureBootCertificate=SB_CERT, --secureboot-certificate=SB_CERT
208 A path to a certificate to use for signing of the resulting binary.
209 If the SigningEngine=/--signing-engine= option is used, this may
210 also be an engine-specific designation. This option is required by
211 SecureBootSigningTool=sbsign/--signtool=sbsign.
212
213 SecureBootCertificateDir=SB_PATH, --secureboot-certificate-dir=SB_PATH
214 A path to a nss certificate database directory to use for signing
215 of the resulting binary. Takes effect when
216 SecureBootSigningTool=pesign/--signtool=pesign is used. Defaults to
217 /etc/pki/pesign.
218
219 SecureBootCertificateName=SB_CERTNAME,
220 --secureboot-certificate-name=SB_CERTNAME
221 The name of the nss certificate database entry to use for signing
222 of the resulting binary. This option is required by
223 SecureBootSigningTool=pesign/--signtool=pesign.
224
225 SecureBootCertificateValidity=DAYS,
226 --secureboot-certificate-validity=DAYS
227 Period of validity (in days) for a certificate created by genkey.
228 Defaults to 3650, i.e. 10 years.
229
230 SigningEngine=ENGINE, --signing-engine=ENGINE
231 An "engine" for signing of the resulting binary. This option is
232 currently passed verbatim to the --engine= option of sbsign(1).
233
234 SignKernel=BOOL, --sign-kernel, --no-sign-kernel
235 Override the detection of whether to sign the Linux binary itself
236 before it is embedded in the combined image. If not specified, it
237 will be signed if a SecureBoot signing key is provided via the
238 SecureBootPrivateKey=/--secureboot-private-key= option and the
239 binary has not already been signed. If SignKernel=/--sign-kernel is
240 true, and the binary has already been signed, the signature will be
241 appended anyway.
242
243 SBAT=TEXT|@PATH, --sbat=TEXT|@PATH
244 SBAT metadata associated with the UKI or addon. SBAT policies are
245 useful to revoke whole groups of UKIs or addons with a single,
246 static policy update that does not take space in DBX/MOKX. If not
247 specified manually, a default metadata entry consisting of
248 "uki,1,UKI,uki,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html"
249 will be used, to ensure it is always possible to revoke UKIs and
250 addons. For more information on SBAT see Shim's documentation.[2]
251
252 [PCRSignature:NAME] section
253 In the config file, those options are grouped by section. On the
254 commandline, they must be specified in the same order. The sections
255 specified in both sources are combined.
256
257 PCRPrivateKey=PATH, --pcr-private-key=PATH
258 A private key to use for signing PCR policies. On the commandline,
259 this option may be specified more than once, in which case multiple
260 signatures will be made.
261
262 PCRPublicKey=PATH, --pcr-public-key=PATH
263 A public key to use for signing PCR policies.
264
265 On the commandline, this option may be specified more than once,
266 similarly to the --pcr-private-key= option. If not present, the
267 public keys will be extracted from the private keys. On the
268 commandline, if present, the this option must be specified the same
269 number of times as the --pcr-private-key= option.
270
271 Phases=LIST, --phases=LIST
272 A comma or space-separated list of colon-separated phase paths to
273 sign a policy for. Each set of boot phase paths will be signed with
274 the corresponding private key. If not present, the default of
275 systemd-measure(1) will be used.
276
277 On the commandline, when this argument is present, it must appear
278 the same number of times as the --pcr-private-key= option.
279
281 Example 1. Minimal invocation
282
283 $ ukify build \
284 --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
285 --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \
286 --cmdline='quiet rw'
287
288
289 This creates an unsigned UKI ./vmlinuz.unsigned.efi.
290
291 Example 2. All the bells and whistles
292
293 $ /usr/lib/systemd/ukify build \
294 --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
295 --initrd=early_cpio \
296 --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \
297 --sbat='sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
298 uki.author.myimage,1,UKI for System,uki.author.myimage,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html' \
299 --pcr-private-key=pcr-private-initrd-key.pem \
300 --pcr-public-key=pcr-public-initrd-key.pem \
301 --phases='enter-initrd' \
302 --pcr-private-key=pcr-private-system-key.pem \
303 --pcr-public-key=pcr-public-system-key.pem \
304 --phases='enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit \
305 enter-initrd:leave-initrd:sysinit:ready' \
306 --pcr-banks=sha384,sha512 \
307 --secureboot-private-key=sb.key \
308 --secureboot-certificate=sb.cert \
309 --sign-kernel \
310 --cmdline='quiet rw rhgb'
311
312
313 This creates a signed UKI ./vmlinuz.signed.efi. The initrd section
314 contains two concatenated parts, early_cpio and
315 initramfs-6.0.9-300.fc37.x86_64.img. The policy embedded in the
316 ".pcrsig" section will be signed for the initrd (the enter-initrd
317 phase) with the key pcr-private-initrd-key.pem, and for the main system
318 (phases leave-initrd, sysinit, ready) with the key
319 pcr-private-system-key.pem. The Linux binary and the resulting combined
320 image will be signed with the SecureBoot key sb.key.
321
322 Example 3. All the bells and whistles, via a config file
323
324 This is the same as the previous example, but this time the
325 configuration is stored in a file:
326
327 $ cat ukify.conf
328 [UKI]
329 Initrd=early_cpio
330 Cmdline=quiet rw rhgb
331
332 SecureBootPrivateKey=sb.key
333 SecureBootCertificate=sb.cert
334 SignKernel=yes
335 PCRBanks=sha384,sha512
336
337 [PCRSignature:initrd]
338 PCRPrivateKey=pcr-private-initrd-key.pem
339 PCRPublicKey=pcr-public-initrd-key.pem
340 Phases=enter-initrd
341
342 [PCRSignature:system]
343 PCRPrivateKey=pcr-private-system-key.pem
344 PCRPublicKey=pcr-public-system-key.pem
345 Phases=enter-initrd:leave-initrd
346 enter-initrd:leave-initrd:sysinit
347 enter-initrd:leave-initrd:sysinit:ready
348
349 $ /usr/lib/systemd/ukify -c ukify.conf build \
350 --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \
351 --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img
352
353
354 One "initrd" (early_cpio) is specified in the config file, and the
355 other initrd (initramfs-6.0.9-300.fc37.x86_64.img) is specified on the
356 commandline. This may be useful for example when the first initrd
357 contains microcode for the CPU and does not need to be updated when the
358 kernel version changes, unlike the actual initrd.
359
360 Example 4. Kernel command line auxiliary PE
361
362 ukify build \
363 --secureboot-private-key=sb.key \
364 --secureboot-certificate=sb.cert \
365 --cmdline='debug' \
366 --sbat='sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
367 uki.addon.author,1,UKI Addon for System,uki.addon.author,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html'
368 --output=debug.cmdline
369
370
371 This creates a signed PE binary that contains the additional kernel
372 command line parameter "debug" with SBAT metadata referring to the
373 owner of the addon.
374
375 Example 5. Decide signing policy and create certificate and keys
376
377 First, let's create an config file that specifies what signatures shall
378 be made:
379
380 # cat >/etc/kernel/uki.conf <<EOF
381 [UKI]
382 SecureBootPrivateKey=/etc/kernel/secure-boot.key.pem
383 SecureBootCertificate=/etc/kernel/secure-boot.cert.pem
384
385 [PCRSignature:initrd]
386 Phases=enter-initrd
387 PCRPrivateKey=/etc/kernel/pcr-initrd.key.pem
388 PCRPublicKey=/etc/kernel/pcr-initrd.pub.pem
389
390 [PCRSignature:system]
391 Phases=enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit
392 enter-initrd:leave-initrd:sysinit:ready
393 PCRPrivateKey=/etc/kernel/pcr-system.key.pem
394 PCRPublicKey=/etc/kernel/pcr-system.pub.pem
395 EOF
396
397 Next, we can generate the certificate and keys:
398
399 # /usr/lib/systemd/ukify genkey --config=/etc/kernel/uki.conf
400 Writing SecureBoot private key to /etc/kernel/secure-boot.key.pem
401 Writing SecureBoot certificate to /etc/kernel/secure-boot.cert.pem
402 Writing private key for PCR signing to /etc/kernel/pcr-initrd.key.pem
403 Writing public key for PCR signing to /etc/kernel/pcr-initrd.pub.pem
404 Writing private key for PCR signing to /etc/kernel/pcr-system.key.pem
405 Writing public key for PCR signing to /etc/kernel/pcr-system.pub.pem
406
407 (Both operations need to be done as root to allow write access to
408 /etc/kernel/.)
409
410 Subsequent invocations of using the config file (/usr/lib/systemd/ukify
411 build --config=/etc/kernel/uki.conf) will use this certificate and key
412 files. Note that the kernel-install(8) plugin 60-ukify.install uses
413 /etc/kernel/uki.conf by default, so after this file has been created,
414 installations of kernels that create a UKI on the local machine using
415 kernel-install would perform signing using this config.
416
418 systemd(1), systemd-stub(7), systemd-boot(7), systemd-measure(1),
419 systemd-pcrphase.service(8)
420
422 1. Unified Kernel Image (UKI)
423 https://uapi-group.org/specifications/specs/unified_kernel_image/
424
425 2. Shim's documentation.
426 https://github.com/rhboot/shim/blob/main/SBAT.md
427
428
429
430systemd 254 UKIFY(1)