talm

Форк
0
135 строк · 3.4 Кб
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
// Package uki creates the UKI file out of the sd-stub and other sections.
6
package uki
7

8
import (
9
	"fmt"
10
	"log"
11
	"os"
12

13
	"github.com/aenix-io/talm/internal/pkg/secureboot"
14
	"github.com/aenix-io/talm/internal/pkg/secureboot/measure"
15
	"github.com/aenix-io/talm/internal/pkg/secureboot/pesign"
16
)
17

18
// section is a UKI file section.
19
type section struct {
20
	// Section name.
21
	Name secureboot.Section
22
	// Path to the contents of the section.
23
	Path string
24
	// Should the section be measured to the TPM?
25
	Measure bool
26
	// Should the section be appended, or is it already in the PE file.
27
	Append bool
28
	// Size & VMA of the section.
29
	Size uint64
30
	VMA  uint64
31
}
32

33
// Builder is a UKI file builder.
34
type Builder struct {
35
	// Source options.
36
	//
37
	// Arch of the UKI file.
38
	Arch string
39
	// Version of Talos.
40
	Version string
41
	// Path to the sd-stub.
42
	SdStubPath string
43
	// Path to the sd-boot.
44
	SdBootPath string
45
	// Path to the kernel image.
46
	KernelPath string
47
	// Path to the initrd image.
48
	InitrdPath string
49
	// Kernel cmdline.
50
	Cmdline string
51
	// SecureBoot certificate and signer.
52
	SecureBootSigner pesign.CertificateSigner
53
	// PCR signer.
54
	PCRSigner measure.RSAKey
55

56
	// Output options:
57
	//
58
	// Path to the signed sd-boot.
59
	OutSdBootPath string
60
	// Path to the output UKI file.
61
	OutUKIPath string
62

63
	// fields initialized during build
64
	sections        []section
65
	scratchDir      string
66
	peSigner        *pesign.Signer
67
	unsignedUKIPath string
68
}
69

70
// Build the UKI file.
71
//
72
// Build process is as follows:
73
//   - sign the sd-boot EFI binary, and write it to the OutSdBootPath
74
//   - build ephemeral sections (uname, os-release), and other proposed sections
75
//   - measure sections, generate signature, and append to the list of sections
76
//   - assemble the final UKI file starting from sd-stub and appending generated section.
77
func (builder *Builder) Build(printf func(string, ...any)) error {
78
	var err error
79

80
	builder.scratchDir, err = os.MkdirTemp("", "talos-uki")
81
	if err != nil {
82
		return err
83
	}
84

85
	defer func() {
86
		if err = os.RemoveAll(builder.scratchDir); err != nil {
87
			log.Printf("failed to remove scratch dir: %v", err)
88
		}
89
	}()
90

91
	printf("signing systemd-boot")
92

93
	builder.peSigner, err = pesign.NewSigner(builder.SecureBootSigner)
94
	if err != nil {
95
		return fmt.Errorf("error initializing signer: %w", err)
96
	}
97

98
	// sign sd-boot
99
	if err = builder.peSigner.Sign(builder.SdBootPath, builder.OutSdBootPath); err != nil {
100
		return fmt.Errorf("error signing sd-boot: %w", err)
101
	}
102

103
	printf("generating UKI sections")
104

105
	// generate and build list of all sections
106
	for _, generateSection := range []func() error{
107
		builder.generateOSRel,
108
		builder.generateCmdline,
109
		builder.generateInitrd,
110
		builder.generateSplash,
111
		builder.generateUname,
112
		builder.generateSBAT,
113
		builder.generatePCRPublicKey,
114
		// append kernel last to account for decompression
115
		builder.generateKernel,
116
		// measure sections last
117
		builder.generatePCRSig,
118
	} {
119
		if err = generateSection(); err != nil {
120
			return fmt.Errorf("error generating sections: %w", err)
121
		}
122
	}
123

124
	printf("assembling UKI")
125

126
	// assemble the final UKI file
127
	if err = builder.assemble(); err != nil {
128
		return fmt.Errorf("error assembling UKI: %w", err)
129
	}
130

131
	printf("signing UKI")
132

133
	// sign the UKI file
134
	return builder.peSigner.Sign(builder.unsignedUKIPath, builder.OutUKIPath)
135
}
136

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.