From 6dcbc3caeb98de32809575c27d30419b43659116 Mon Sep 17 00:00:00 2001 From: Jay Hou Date: Thu, 1 Feb 2024 10:36:22 +0000 Subject: [PATCH] Add identity counter to Status data structures. (#155) * Add identity counter to witness status data structures. * Move identity counter out of WitnessStatus. --- api/api.go | 19 +++++---- api/api.pb.go | 105 ++++++++++++++++++++++++---------------------- api/api.proto | 92 +++++++++++++++++++++------------------- trusted_os/ctl.go | 1 + 4 files changed, 115 insertions(+), 102 deletions(-) diff --git a/api/api.go b/api/api.go index 8b7c241..cfd959d 100644 --- a/api/api.go +++ b/api/api.go @@ -92,17 +92,18 @@ func (p *Status) Print() string { var status bytes.Buffer status.WriteString("----------------------------------------------------------- Trusted OS ----\n") - status.WriteString(fmt.Sprintf("Serial number ..........: %s\n", p.Serial)) - status.WriteString(fmt.Sprintf("Secure Boot ............: %v\n", p.HAB)) - status.WriteString(fmt.Sprintf("Revision ...............: %s\n", p.Revision)) - status.WriteString(fmt.Sprintf("Version ................: %d (%s)\n", p.Version, time.Unix(int64(p.Version), 0))) - status.WriteString(fmt.Sprintf("Runtime ................: %s\n", p.Runtime)) - status.WriteString(fmt.Sprintf("Link ...................: %v\n", p.Link)) + status.WriteString(fmt.Sprintf("Serial number ..............: %s\n", p.Serial)) + status.WriteString(fmt.Sprintf("Secure Boot ................: %v\n", p.HAB)) + status.WriteString(fmt.Sprintf("Revision ...................: %s\n", p.Revision)) + status.WriteString(fmt.Sprintf("Version ....................: %d (%s)\n", p.Version, time.Unix(int64(p.Version), 0))) + status.WriteString(fmt.Sprintf("Runtime ....................: %s\n", p.Runtime)) + status.WriteString(fmt.Sprintf("Link .......................: %v\n", p.Link)) + status.WriteString(fmt.Sprintf("IdentityCounter ............: %d", p.IdentityCounter)) if p.Witness != nil { - status.WriteString(fmt.Sprintf("Witness/Identity .......: %v\n", p.Witness.Identity)) - status.WriteString(fmt.Sprintf("Witness/IP .............: %v", p.Witness.IP)) + status.WriteString(fmt.Sprintf("Witness/Identity ...........: %v\n", p.Witness.Identity)) + status.WriteString(fmt.Sprintf("Witness/IP .................: %v", p.Witness.IP)) } else { - status.WriteString(fmt.Sprint("Witness ................: ")) + status.WriteString(fmt.Sprint("Witness ....................: ")) } return status.String() diff --git a/api/api.pb.go b/api/api.pb.go index c6af91b..b106ed1 100644 --- a/api/api.pb.go +++ b/api/api.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.28.1 -// protoc v3.20.1 +// protoc v3.21.12 // source: api.proto package api @@ -83,17 +83,14 @@ func (ErrorCode) EnumDescriptor() ([]byte, []int) { return file_api_proto_rawDescGZIP(), []int{0} } +// AppletUpdate // +// A `AppletUpdate` represents an OTA sequence applet slice. // -//AppletUpdate -// -//A `AppletUpdate` represents an OTA sequence applet slice. -// -//The `TotalChunks` value indicates the total number of chunks for the update, -//`Seq` is the transmitted AppletUpdate chunk number: -//- `0` indicates that the struct contains verification data in `Header`. -//- `1` onwards identifies the first, second, ... chunk of firmware image data. -// +// The `TotalChunks` value indicates the total number of chunks for the update, +// `Seq` is the transmitted AppletUpdate chunk number: +// - `0` indicates that the struct contains verification data in `Header`. +// - `1` onwards identifies the first, second, ... chunk of firmware image data. type AppletUpdate struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -102,6 +99,7 @@ type AppletUpdate struct { Total uint32 `protobuf:"varint,1,opt,name=Total,proto3" json:"Total,omitempty"` Seq uint32 `protobuf:"varint,2,opt,name=Seq,proto3" json:"Seq,omitempty"` // Types that are assignable to Payload: + // // *AppletUpdate_Data // *AppletUpdate_Header Payload isAppletUpdate_Payload `protobuf_oneof:"Payload"` @@ -199,9 +197,11 @@ type AppletUpdateHeader struct { Signature []byte `protobuf:"bytes,1,opt,name=Signature,proto3" json:"Signature,omitempty"` // Checkpoint contains a note-formatted Log Checkpoint. Checkpoint []byte `protobuf:"bytes,2,opt,name=Checkpoint,proto3" json:"Checkpoint,omitempty"` - // Manifest is metadata about the applet, which has been logged to a firmware transparency log. + // Manifest is metadata about the applet, which has been logged to a firmware + // transparency log. Manifest []byte `protobuf:"bytes,3,opt,name=Manifest,proto3" json:"Manifest,omitempty"` - // InclusionProof is a log inclusion proof for Manifest committed to by Checkpoint. + // InclusionProof is a log inclusion proof for Manifest committed to by + // Checkpoint. InclusionProof [][]byte `protobuf:"bytes,4,rep,name=InclusionProof,proto3" json:"InclusionProof,omitempty"` // LogIndex is the index of Manifest in the firmware transparency log. LogIndex uint64 `protobuf:"varint,5,opt,name=LogIndex,proto3" json:"LogIndex,omitempty"` @@ -274,13 +274,10 @@ func (x *AppletUpdateHeader) GetLogIndex() uint64 { return 0 } +// Status information // -// -//Status information -// -//The status information format is returned on any message sent with the -//`U2FHID_ARMORY_INF` vendor specific command. -// +// The status information format is returned on any message sent with the +// `U2FHID_ARMORY_INF` vendor specific command. type Status struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -294,6 +291,9 @@ type Status struct { Runtime string `protobuf:"bytes,6,opt,name=Runtime,proto3" json:"Runtime,omitempty"` Link bool `protobuf:"varint,7,opt,name=Link,proto3" json:"Link,omitempty"` Witness *WitnessStatus `protobuf:"bytes,8,opt,name=Witness,proto3" json:"Witness,omitempty"` + // IdentityCounter is incremented when the device is recovered and the device + // needs a new witness identity. + IdentityCounter uint32 `protobuf:"varint,9,opt,name=IdentityCounter,proto3" json:"IdentityCounter,omitempty"` } func (x *Status) Reset() { @@ -384,13 +384,17 @@ func (x *Status) GetWitness() *WitnessStatus { return nil } +func (x *Status) GetIdentityCounter() uint32 { + if x != nil { + return x.IdentityCounter + } + return 0 +} + +// WitnessStatus contains witness-applet specific status information. // -// -//WitnessStatus contains witness-applet specific status information. -// -//This is embedded in the general Status message if the applet has provided -//this information to the OS. -// +// This is embedded in the general Status message if the applet has provided +// this information to the OS. type WitnessStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -615,7 +619,7 @@ var file_api_proto_rawDesc = []byte{ 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1a, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x4c, 0x6f, 0x67, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x22, 0xda, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, + 0x65, 0x78, 0x22, 0x84, 0x02, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x48, 0x41, 0x42, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x48, 0x41, 0x42, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x76, 0x69, 0x73, @@ -628,30 +632,33 @@ var file_api_proto_rawDesc = []byte{ 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x2c, 0x0a, 0x07, 0x57, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x57, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x22, - 0x3b, 0x0a, 0x0d, 0x57, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, - 0x49, 0x50, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x50, 0x22, 0xa1, 0x01, 0x0a, - 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x44, 0x48, 0x43, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x44, 0x48, - 0x43, 0x50, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x50, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x49, 0x50, 0x12, 0x18, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x4e, 0x65, 0x74, 0x6d, 0x61, 0x73, 0x6b, 0x12, 0x18, 0x0a, 0x07, - 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x47, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x54, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x54, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x22, 0x4a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0x28, 0x0a, 0x09, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, - 0x45, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x3b, 0x61, 0x70, 0x69, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x57, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x12, + 0x28, 0x0a, 0x0f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x3b, 0x0a, 0x0d, 0x57, 0x69, 0x74, + 0x6e, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x50, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x49, 0x50, 0x22, 0xa1, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x48, 0x43, 0x50, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x44, 0x48, 0x43, 0x50, 0x12, 0x0e, 0x0a, 0x02, + 0x49, 0x50, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x50, 0x12, 0x18, 0x0a, 0x07, + 0x4e, 0x65, 0x74, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4e, + 0x65, 0x74, 0x6d, 0x61, 0x73, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, + 0x4e, 0x54, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x4e, 0x54, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x4a, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, + 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0x28, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x11, 0x0a, + 0x0d, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, + 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/api/api.proto b/api/api.proto index f758e2a..d98b383 100644 --- a/api/api.proto +++ b/api/api.proto @@ -16,10 +16,10 @@ syntax = "proto3"; -option go_package = "./;api"; - package api; +option go_package = "./;api"; + /* Trusted Applet updates are supported with a sequence that splits the applet @@ -79,15 +79,14 @@ The `TotalChunks` value indicates the total number of chunks for the update, */ message AppletUpdate { - uint32 Total = 1; - uint32 Seq = 2; - oneof Payload { - bytes Data = 3; - AppletUpdateHeader Header = 4; - }; + uint32 Total = 1; + uint32 Seq = 2; + oneof Payload { + bytes Data = 3; + AppletUpdateHeader Header = 4; + } } - /* AppletUpdateHeader @@ -99,16 +98,18 @@ It's sent in the zero-th `AppletUpdate` message during an OTA. */ message AppletUpdateHeader { - // Signature holds the signature over the applet. - bytes Signature = 1; - // Checkpoint contains a note-formatted Log Checkpoint. - bytes Checkpoint = 2; - // Manifest is metadata about the applet, which has been logged to a firmware transparency log. - bytes Manifest = 3; - // InclusionProof is a log inclusion proof for Manifest committed to by Checkpoint. - repeated bytes InclusionProof = 4; - // LogIndex is the index of Manifest in the firmware transparency log. - uint64 LogIndex = 5; + // Signature holds the signature over the applet. + bytes Signature = 1; + // Checkpoint contains a note-formatted Log Checkpoint. + bytes Checkpoint = 2; + // Manifest is metadata about the applet, which has been logged to a firmware + // transparency log. + bytes Manifest = 3; + // InclusionProof is a log inclusion proof for Manifest committed to by + // Checkpoint. + repeated bytes InclusionProof = 4; + // LogIndex is the index of Manifest in the firmware transparency log. + uint64 LogIndex = 5; } /* @@ -120,14 +121,17 @@ The status information format is returned on any message sent with the */ message Status { - string Serial = 1; - bool HAB = 2; - string Revision = 3; - string Build = 4; - uint32 Version = 5; - string Runtime = 6; - bool Link = 7; - WitnessStatus Witness = 8; + string Serial = 1; + bool HAB = 2; + string Revision = 3; + string Build = 4; + uint32 Version = 5; + string Runtime = 6; + bool Link = 7; + WitnessStatus Witness = 8; + // IdentityCounter is incremented when the device is recovered and the device + // needs a new witness identity. + uint32 IdentityCounter = 9; } /* @@ -139,11 +143,11 @@ this information to the OS. */ message WitnessStatus { - // Identity is the note-formatted public key which can be used to verify - // checkpoints cosigned by this witness. - string Identity = 1; - // IP is a string representation of the witness applet's current IP address. - string IP = 2; + // Identity is the note-formatted public key which can be used to verify + // checkpoints cosigned by this witness. + string Identity = 1; + // IP is a string representation of the witness applet's current IP address. + string IP = 2; } /* @@ -159,23 +163,23 @@ command. */ message Configuration { - bool DHCP = 1; - string IP = 2; - string Netmask = 3; - string Gateway = 4; - string Resolver = 5; - string NTPServer = 6; + bool DHCP = 1; + string IP = 2; + string Netmask = 3; + string Gateway = 4; + string Resolver = 5; + string NTPServer = 6; } message Response { - ErrorCode Error = 1; - bytes Payload = 2; + ErrorCode Error = 1; + bytes Payload = 2; } enum ErrorCode { - NONE = 0; + NONE = 0; - // GENERIC_ERROR is returned in case of a generic error, in this case - // Payload might contain the error string. - GENERIC_ERROR = 1; + // GENERIC_ERROR is returned in case of a generic error, in this case + // Payload might contain the error string. + GENERIC_ERROR = 1; } diff --git a/trusted_os/ctl.go b/trusted_os/ctl.go index 5fa8f7e..8ff11a5 100644 --- a/trusted_os/ctl.go +++ b/trusted_os/ctl.go @@ -61,6 +61,7 @@ func getStatus() (s *api.Status) { Build: Build, Version: version, Runtime: fmt.Sprintf("%s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH), + // TODO(jayhou): set IdentityCounter here. } if witnessStatus != nil { s.Witness = &api.WitnessStatus{