55 "path/filepath"
66
77 "github.com/oasisprotocol/oasis-core/go/common"
8+ "github.com/oasisprotocol/oasis-core/go/common/sgx"
89 "github.com/oasisprotocol/oasis-core/go/common/version"
910 "github.com/oasisprotocol/oasis-core/go/runtime/bundle/component"
1011)
@@ -40,8 +41,12 @@ type Component struct {
4041 Version version.Version
4142
4243 // Executable is the name of the runtime ELF executable file if any.
44+ // NOTE: This may go away in the future, use `ELF` instead.
4345 Executable string `json:"executable,omitempty"`
4446
47+ // ELF is the ELF specific manifest metadata if any.
48+ ELF * ELFMetadata `json:"elf,omitempty"`
49+
4550 // SGX is the SGX specific manifest metadata if any.
4651 SGX * SGXMetadata `json:"sgx,omitempty"`
4752
@@ -78,6 +83,12 @@ func (c *Component) Validate() error {
7883 ) {
7984 return fmt .Errorf ("each component can only include metadata for a single TEE" )
8085 }
86+ if c .ELF != nil {
87+ err := c .ELF .Validate ()
88+ if err != nil {
89+ return fmt .Errorf ("elf: %w" , err )
90+ }
91+ }
8192 if c .SGX != nil {
8293 err := c .SGX .Validate ()
8394 if err != nil {
@@ -96,7 +107,7 @@ func (c *Component) Validate() error {
96107 if c .Name != "" {
97108 return fmt .Errorf ("RONL component must have an empty name" )
98109 }
99- if c .Executable == "" {
110+ if c .Executable == "" && c . ELF == nil {
100111 return fmt .Errorf ("RONL component must define an executable" )
101112 }
102113 if c .Disabled {
@@ -123,7 +134,7 @@ func (c *Component) IsNetworkAllowed() bool {
123134
124135// IsTEERequired returns true iff the component only provides TEE executables.
125136func (c * Component ) IsTEERequired () bool {
126- return c .Executable == "" && c .TEEKind () != component .TEEKindNone
137+ return c .Executable == "" && c .ELF == nil && c . TEEKind () != component .TEEKindNone
127138}
128139
129140// TEEKind returns the kind of TEE supported by the component.
@@ -137,3 +148,120 @@ func (c *Component) TEEKind() component.TEEKind {
137148 return component .TEEKindNone
138149 }
139150}
151+
152+ // ELFMetadata is the ELF specific manifest metadata.
153+ type ELFMetadata struct {
154+ // Executable is the name of the ELF executable file.
155+ Executable string `json:"executable"`
156+ }
157+
158+ // Validate validates the ELF metadata structure for well-formedness.
159+ func (e * ELFMetadata ) Validate () error {
160+ if e .Executable == "" {
161+ return fmt .Errorf ("executable must be set" )
162+ }
163+ return nil
164+ }
165+
166+ // SGXMetadata is the SGX specific manifest metadata.
167+ type SGXMetadata struct {
168+ // Executable is the name of the SGX enclave executable file.
169+ Executable string `json:"executable"`
170+
171+ // Signature is the name of the SGX enclave signature file.
172+ Signature string `json:"signature"`
173+ }
174+
175+ // Validate validates the SGX metadata structure for well-formedness.
176+ func (s * SGXMetadata ) Validate () error {
177+ if s .Executable == "" {
178+ return fmt .Errorf ("executable must be set" )
179+ }
180+ return nil
181+ }
182+
183+ // TDXMetadata is the TDX specific manifest metadata.
184+ //
185+ // Note that changes to these fields may change the TD measurements.
186+ type TDXMetadata struct {
187+ // Firmware is the name of the virtual firmware file. It should rarely change and multiple
188+ // components may use the same firmware.
189+ Firmware string `json:"firmware"`
190+ // Kernel is the name of the kernel image file. It should rarely change and multiple components
191+ // may use the same kernel.
192+ Kernel string `json:"kernel,omitempty"`
193+ // InitRD is the name of the initial RAM disk image file. It should rarely change and multiple
194+ // components may use the same initrd.
195+ InitRD string `json:"initrd,omitempty"`
196+ // ExtraKernelOptions are the extra kernel options to pass to the kernel after any of the
197+ // default options. Note that kernel options affect TD measurements.
198+ ExtraKernelOptions []string `json:"extra_kernel_options,omitempty"`
199+
200+ // Stage2Image is the name of the stage 2 VM image file.
201+ Stage2Image string `json:"stage2_image,omitempty"`
202+
203+ // Resources are the requested VM resources.
204+ Resources TDXResources `json:"resources"`
205+ }
206+
207+ // Validate validates the TDX metadata structure for well-formedness.
208+ func (t * TDXMetadata ) Validate () error {
209+ if t .Firmware == "" {
210+ return fmt .Errorf ("firmware must be set" )
211+ }
212+ if ! t .HasKernel () && t .HasStage2 () {
213+ return fmt .Errorf ("kernel must be set if stage 2 image is set" )
214+ }
215+ if ! t .HasKernel () && t .HasInitRD () {
216+ return fmt .Errorf ("kernel must be set if initrd image is set" )
217+ }
218+ if err := t .Resources .Validate (); err != nil {
219+ return err
220+ }
221+ return nil
222+ }
223+
224+ // HasKernel returns true iff the TDX metadata indicates there is a kernel present.
225+ func (t * TDXMetadata ) HasKernel () bool {
226+ return t .Kernel != ""
227+ }
228+
229+ // HasInitRD returns true iff the TDX metadata indicates there is an initial RAM disk image present.
230+ func (t * TDXMetadata ) HasInitRD () bool {
231+ return t .InitRD != ""
232+ }
233+
234+ // HasStage2 returns true iff the TDX metadata indicates there is a stage 2 image present.
235+ func (t * TDXMetadata ) HasStage2 () bool {
236+ return t .Stage2Image != ""
237+ }
238+
239+ // TDXResources are the requested VM resources for TDX VMs.
240+ //
241+ // Note that changes to these fields may change the TD measurements.
242+ type TDXResources struct {
243+ // Memory is the requested VM memory amount in megabytes.
244+ Memory uint64 `json:"memory"`
245+ // CPUCount is the requested number of vCPUs.
246+ CPUCount uint8 `json:"cpus"`
247+ }
248+
249+ // Validate validates the VM resources.
250+ func (r * TDXResources ) Validate () error {
251+ if r .Memory < 16 {
252+ return fmt .Errorf ("memory limit must be at least 16M" )
253+ }
254+ if r .CPUCount < 1 {
255+ return fmt .Errorf ("vCPU count must be at least 1" )
256+ }
257+ return nil
258+ }
259+
260+ // Identity is the cryptographic identity of a component.
261+ type Identity struct {
262+ // Hypervisor is the optional hypervisor this identity is for.
263+ Hypervisor string `json:"hypervisor,omitempty"`
264+
265+ // Enclave is the enclave identity.
266+ Enclave sgx.EnclaveIdentity `json:"enclave"`
267+ }
0 commit comments