Skip to content

Commit bdbeb4e

Browse files
authored
COCOS-199 - Enable testing of SEV features on any machine (#205)
* make attestation embeddable Signed-off-by: Sammy Oina <sammyoina@gmail.com> * mock backend info Signed-off-by: Sammy Oina <sammyoina@gmail.com> * embed files Signed-off-by: Sammy Oina <sammyoina@gmail.com> * finish up Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
1 parent c402248 commit bdbeb4e

File tree

14 files changed

+159
-49
lines changed

14 files changed

+159
-49
lines changed

Makefile

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
11
BUILD_DIR = build
22
SERVICES = manager agent cli
3-
PLATFORM_INFO = platform_info
3+
BACKEND_INFO = backend_info
44
CGO_ENABLED ?= 0
55
GOARCH ?= amd64
66
VERSION ?= $(shell git describe --abbrev=0 --tags --always)
77
COMMIT ?= $(shell git rev-parse HEAD)
88
TIME ?= $(shell date +%F_%T)
9+
EMBED_ENABLED ?= 0
910

1011
define compile_service
1112
CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) \
1213
go build -ldflags "-s -w \
1314
-X 'github.com/absmach/magistrala.BuildTime=$(TIME)' \
1415
-X 'github.com/absmach/magistrala.Version=$(VERSION)' \
1516
-X 'github.com/absmach/magistrala.Commit=$(COMMIT)'" \
17+
$(if $(filter 1,$(EMBED_ENABLED)),-tags "embed",) \
1618
-o ${BUILD_DIR}/cocos-$(1) cmd/$(1)/main.go
1719
endef
1820

19-
.PHONY: all $(SERVICES) $(PLATFORM_INFO)
21+
.PHONY: all $(SERVICES) $(BACKEND_INFO)
2022

2123
all: $(SERVICES)
2224

2325
$(SERVICES):
24-
$(call compile_service,$(@))
26+
$(call compile_service,$@)
2527

26-
$(PLATFORM_INFO):
27-
$(MAKE) -C ./scripts/platform_info
28+
$(BACKEND_INFO):
29+
$(MAKE) -C ./scripts/backend_info
2830

2931
protoc:
3032
protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative agent/agent.proto

agent/quoteprovider/embed.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) Ultraviolet
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//go:build embed
5+
// +build embed
6+
7+
package quoteprovider
8+
9+
import (
10+
"github.com/google/go-sev-guest/client"
11+
pb "github.com/google/go-sev-guest/proto/sevsnp"
12+
cocosai "github.com/ultravioletrs/cocos"
13+
)
14+
15+
var _ client.QuoteProvider = (*embeddedQuoteProvider)(nil)
16+
17+
type embeddedQuoteProvider struct {
18+
}
19+
20+
func GetQuoteProvider() (client.QuoteProvider, error) {
21+
return &embeddedQuoteProvider{}, nil
22+
}
23+
24+
// GetQuote returns the SEV quote for the given report data.
25+
func (e *embeddedQuoteProvider) GetRawQuote(reportData [64]byte) ([]byte, error) {
26+
return cocosai.EmbeddedAttestation, nil
27+
}
28+
29+
// IsSupported returns true if the SEV platform is supported.
30+
func (e *embeddedQuoteProvider) IsSupported() bool {
31+
return true
32+
}
33+
34+
// Product returns the SEV product information.
35+
// unimplemented since it is deprecated and not used.
36+
func (e *embeddedQuoteProvider) Product() *pb.SevProduct {
37+
panic("unimplemented")
38+
}

agent/quoteprovider/sev.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) Ultraviolet
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//go:build !embed
5+
// +build !embed
6+
7+
package quoteprovider
8+
9+
import "github.com/google/go-sev-guest/client"
10+
11+
func GetQuoteProvider() (client.QuoteProvider, error) {
12+
return client.GetQuoteProvider()
13+
}

agent/service.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,23 @@ type Service interface {
6868
}
6969

7070
type agentService struct {
71-
computation Computation // Holds the current computation manifest.
72-
algorithm algorithm.Algorithm // Filepath to the algorithm received for the computation.
73-
result []byte // Stores the result of the computation.
74-
sm *StateMachine // Manages the state transitions of the agent service.
75-
runError error // Stores any error encountered during the computation run.
76-
eventSvc events.Service // Service for publishing events related to computation.
71+
computation Computation // Holds the current computation request details.
72+
algorithm algorithm.Algorithm // Filepath to the algorithm received for the computation.
73+
result []byte // Stores the result of the computation.
74+
sm *StateMachine // Manages the state transitions of the agent service.
75+
runError error // Stores any error encountered during the computation run.
76+
eventSvc events.Service // Service for publishing events related to computation.
77+
quoteProvider client.QuoteProvider // Provider for generating attestation quotes.
7778
}
7879

7980
var _ Service = (*agentService)(nil)
8081

8182
// New instantiates the agent service implementation.
82-
func New(ctx context.Context, logger *slog.Logger, eventSvc events.Service, cmp Computation) Service {
83+
func New(ctx context.Context, logger *slog.Logger, eventSvc events.Service, cmp Computation, quoteProvider client.QuoteProvider) Service {
8384
svc := &agentService{
84-
sm: NewStateMachine(logger, cmp),
85-
eventSvc: eventSvc,
85+
sm: NewStateMachine(logger, cmp),
86+
eventSvc: eventSvc,
87+
quoteProvider: quoteProvider,
8688
}
8789

8890
go svc.sm.Start(ctx)
@@ -252,11 +254,7 @@ func (as *agentService) Result(ctx context.Context) ([]byte, error) {
252254
}
253255

254256
func (as *agentService) Attestation(ctx context.Context, reportData [ReportDataSize]byte) ([]byte, error) {
255-
provider, err := client.GetQuoteProvider()
256-
if err != nil {
257-
return []byte{}, err
258-
}
259-
rawQuote, err := provider.GetRawQuote(reportData)
257+
rawQuote, err := as.quoteProvider.GetRawQuote(reportData)
260258
if err != nil {
261259
return []byte{}, err
262260
}

attestation.bin

1.21 KB
Binary file not shown.

attestation.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Ultraviolet
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//go:build embed
5+
// +build embed
6+
7+
package cocosai
8+
9+
import _ "embed"
10+
11+
//go:embed attestation.bin
12+
var EmbeddedAttestation []byte

cmd/agent/main.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ import (
1111
"log/slog"
1212

1313
"github.com/absmach/magistrala/pkg/prometheus"
14+
"github.com/google/go-sev-guest/client"
1415
"github.com/mdlayher/vsock"
1516
"github.com/ultravioletrs/cocos/agent"
1617
"github.com/ultravioletrs/cocos/agent/api"
1718
agentgrpc "github.com/ultravioletrs/cocos/agent/api/grpc"
1819
"github.com/ultravioletrs/cocos/agent/auth"
1920
"github.com/ultravioletrs/cocos/agent/events"
21+
"github.com/ultravioletrs/cocos/agent/quoteprovider"
2022
agentlogger "github.com/ultravioletrs/cocos/internal/logger"
2123
"github.com/ultravioletrs/cocos/internal/server"
2224
grpcserver "github.com/ultravioletrs/cocos/internal/server/grpc"
@@ -62,7 +64,13 @@ func main() {
6264
}
6365
defer eventSvc.Close()
6466

65-
svc := newService(ctx, logger, eventSvc, cfg)
67+
qp, err := quoteprovider.GetQuoteProvider()
68+
if err != nil {
69+
logger.Error(fmt.Sprintf("failed to create quote provider %s", err.Error()))
70+
return
71+
}
72+
73+
svc := newService(ctx, logger, eventSvc, cfg, qp)
6674

6775
grpcServerConfig := server.Config{
6876
Port: cfg.AgentConfig.Port,
@@ -85,7 +93,7 @@ func main() {
8593
return
8694
}
8795

88-
gs := grpcserver.New(ctx, cancel, svcName, grpcServerConfig, registerAgentServiceServer, logger, svc, authSvc)
96+
gs := grpcserver.New(ctx, cancel, svcName, grpcServerConfig, registerAgentServiceServer, logger, qp, authSvc)
8997

9098
g.Go(func() error {
9199
return gs.Start()
@@ -100,8 +108,8 @@ func main() {
100108
}
101109
}
102110

103-
func newService(ctx context.Context, logger *slog.Logger, eventSvc events.Service, cmp agent.Computation) agent.Service {
104-
svc := agent.New(ctx, logger, eventSvc, cmp)
111+
func newService(ctx context.Context, logger *slog.Logger, eventSvc events.Service, cmp agent.Computation, qp client.QuoteProvider) agent.Service {
112+
svc := agent.New(ctx, logger, eventSvc, cmp, qp)
105113

106114
svc = api.LoggingMiddleware(svc, logger)
107115
counter, latency := prometheus.MakeMetrics(svcName, "api")

hal/linux/configs/cocos_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ BR2_TOOLCHAIN_BUILDROOT_LIBSTDCPP=y
7171
BR2_PACKAGE_GCC=y
7272
BR2_PACKAGE_GCC_TARGET=y
7373
BR2_PACKAGE_LIBSTDCPP=y
74+

hal/linux/package/agent/agent.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ AGENT_VERSION = main
88
AGENT_SITE = $(call github,ultravioletrs,cocos,$(AGENT_VERSION))
99

1010
define AGENT_BUILD_CMDS
11-
$(MAKE) -C $(@D) agent
11+
$(MAKE) -C $(@D) agent EMBED_ENABLED=$(AGENT_EMBED_ENABLED)
1212
endef
1313

1414
define AGENT_INSTALL_TARGET_CMDS

internal/server/grpc/grpc.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
"os"
2121
"time"
2222

23-
"github.com/ultravioletrs/cocos/agent"
23+
"github.com/google/go-sev-guest/client"
2424
agentgrpc "github.com/ultravioletrs/cocos/agent/api/grpc"
2525
"github.com/ultravioletrs/cocos/agent/auth"
2626
"github.com/ultravioletrs/cocos/internal/server"
@@ -48,15 +48,15 @@ type Server struct {
4848
server.BaseServer
4949
server *grpc.Server
5050
registerService serviceRegister
51-
agent agent.Service
51+
quoteProvider client.QuoteProvider
5252
authSvc auth.Authenticator
5353
}
5454

5555
type serviceRegister func(srv *grpc.Server)
5656

5757
var _ server.Server = (*Server)(nil)
5858

59-
func New(ctx context.Context, cancel context.CancelFunc, name string, config server.Config, registerService serviceRegister, logger *slog.Logger, agentSvc agent.Service, authSvc auth.Authenticator) server.Server {
59+
func New(ctx context.Context, cancel context.CancelFunc, name string, config server.Config, registerService serviceRegister, logger *slog.Logger, qp client.QuoteProvider, authSvc auth.Authenticator) server.Server {
6060
listenFullAddress := fmt.Sprintf("%s:%s", config.Host, config.Port)
6161
return &Server{
6262
BaseServer: server.BaseServer{
@@ -68,7 +68,7 @@ func New(ctx context.Context, cancel context.CancelFunc, name string, config ser
6868
Logger: logger,
6969
},
7070
registerService: registerService,
71-
agent: agentSvc,
71+
quoteProvider: qp,
7272
authSvc: authSvc,
7373
}
7474
}
@@ -93,7 +93,7 @@ func (s *Server) Start() error {
9393

9494
switch {
9595
case s.Config.AttestedTLS:
96-
certificateBytes, privateKeyBytes, err := generateCertificatesForATLS(s.agent)
96+
certificateBytes, privateKeyBytes, err := generateCertificatesForATLS(s.quoteProvider)
9797
if err != nil {
9898
return fmt.Errorf("failed to create certificate: %w", err)
9999
}
@@ -228,7 +228,7 @@ func loadX509KeyPair(certfile, keyfile string) (tls.Certificate, error) {
228228
return tls.X509KeyPair(cert, key)
229229
}
230230

231-
func generateCertificatesForATLS(svc agent.Service) ([]byte, []byte, error) {
231+
func generateCertificatesForATLS(qp client.QuoteProvider) ([]byte, []byte, error) {
232232
curve := elliptic.P256()
233233
privateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
234234
if err != nil {
@@ -241,7 +241,7 @@ func generateCertificatesForATLS(svc agent.Service) ([]byte, []byte, error) {
241241
}
242242

243243
// The Attestation Report will be added as an X.509 certificate extension
244-
attestationReport, err := svc.Attestation(context.Background(), sha3.Sum512(publicKeyBytes))
244+
attestationReport, err := qp.GetRawQuote(sha3.Sum512(publicKeyBytes))
245245
if err != nil {
246246
return nil, nil, fmt.Errorf("failed to fetch the attestation report: %w", err)
247247
}

0 commit comments

Comments
 (0)