diff --git a/go.mod b/go.mod index a5eb801f..4600ac4a 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,10 @@ go 1.15 require ( github.com/alecthomas/kong v0.5.0 github.com/davecgh/go-spew v1.1.1 - github.com/dswarbrick/smart v0.0.0-20190505152634-909a45200d6d // indirect + github.com/dswarbrick/smart v0.0.0-20190505152634-909a45200d6d github.com/prometheus/client_golang v1.12.1 github.com/prometheus/common v0.32.1 golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 - golang.org/x/sys v0.0.0-20220207234003-57398862261d + golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect google.golang.org/protobuf v1.28.0 // indirect ) diff --git a/go.sum b/go.sum index 970caaa6..b09aa77a 100644 --- a/go.sum +++ b/go.sum @@ -470,7 +470,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= diff --git a/lb.yaml b/lb.yaml new file mode 100644 index 00000000..94770301 --- /dev/null +++ b/lb.yaml @@ -0,0 +1,13 @@ +go-tcg-storage: + go-tcg-storage: + deps: + - file://cmd + - file://go.mod + - file://go.sum + - file://lb.yaml + - file://LICENSE + - file://Makefile + - file://pkg + - file://README.md + - file://renovate.json + diff --git a/pkg/core/method/method.go b/pkg/core/method/method.go index 47903f26..27b0cced 100644 --- a/pkg/core/method/method.go +++ b/pkg/core/method/method.go @@ -10,6 +10,9 @@ import ( "bytes" "errors" + //"fmt" + //"log" + "github.com/open-source-firmware/go-tcg-storage/pkg/core/stream" "github.com/open-source-firmware/go-tcg-storage/pkg/core/uid" ) @@ -65,6 +68,8 @@ type Call interface { } type MethodCall struct { + iid uid.InvokingID + mid uid.MethodID buf bytes.Buffer // Used to verify detect programming errors depth int @@ -73,7 +78,7 @@ type MethodCall struct { // Prepare a new method call func NewMethodCall(iid uid.InvokingID, mid uid.MethodID, flags MethodFlag) *MethodCall { - m := &MethodCall{bytes.Buffer{}, 0, flags} + m := &MethodCall{iid, mid, bytes.Buffer{}, 0, flags} m.buf.Write(stream.Token(stream.Call)) m.Bytes(iid[:]) m.Bytes(mid[:]) @@ -82,9 +87,158 @@ func NewMethodCall(iid uid.InvokingID, mid uid.MethodID, flags MethodFlag) *Meth return m } +// func (m *MethodCall) parseParams(params stream.List) { +// for i := 0; i < len(params); i++ { +// param := params[i] +// tok, ok1 := param.(stream.TokenType) +// if ok1 { +// if tok == stream.StartName { +// _, ok1 := params[i+1].([]byte) // name +// _, ok2 := params[i+2].(uint) // val2 +// endToc, ok3 := params[i+3].(stream.TokenType) +// if ok1 && ok2 && ok3 && endToc == stream.EndName { +// //log.Printf("got tokenType %q on params[%d]. name: %s, index: %d", tok.String(), i, string(name), uint(val2)) +// i += 3 +// } else { +// _, ok1 := params[i+1].(uint) //val1 +// _, ok2 := params[i+2].([]byte) //name +// endToc, ok3 := params[i+3].(stream.TokenType) +// if ok1 && ok2 && ok3 && endToc == stream.EndName { +// //log.Printf("got tokenType %q on params[%d]. index: %d, name: %s", tok.String(), i, uint(val1), string(name)) +// i += 3 +// } else { +// //log.Printf("got tokenType %q on params[%d]", tok.String(), i) +// } +// } +// } +// continue +// } +// lst, ok2 := param.(stream.List) +// if ok2 { +// //log.Printf("got list on params[%d]", i) +// m.parseParams(lst) +// continue +// } +// _, ok3 := param.(uint) +// if ok3 { +// //log.Printf("got uint on params[%d]", i) +// continue +// } +// _, ok4 := param.([]byte) +// if ok4 { +// //log.Printf("got []byte on params[%d]", i) +// continue +// } +// log.Printf("unknown value at params[%d], %v", i, param) +// } +// } + +// func (m *MethodCall) String() string { +// var buff bytes.Buffer +// b, err := m.MarshalBinary() +// if err != nil { +// log.Printf("failed to marshal binary") +// return "" +// } + +// req, err := stream.Decode(b) +// if err != nil { +// log.Printf("failed to decode m") +// return "" +// } +// if len(req) >= 6 { +// if tok, ok := req[0].(stream.TokenType); !ok || tok != stream.Call { +// log.Printf("expected first token to be Call") +// return "" +// } +// var uidStr uid.InvokingID +// var midstr uid.MethodID +// if iid, ok := req[1].([]byte); !ok { +// log.Printf("expected uid") +// return "" +// } else { +// copy(uidStr[:], iid[:8]) +// } +// if mid, ok := req[2].([]byte); !ok { +// return "" +// } else { +// copy(midstr[:], mid[:8]) +// } +// if params, ok := req[3].(stream.List); ok { +// m.parseParams(params) +// } + +// // if tok, ok := req[4].(stream.TokenType); ok { +// // if lst, ok := req[5].(stream.List); ok { +// // log.Printf("got tokenType %q: %v", tok.String(), lst) +// // } +// // } +// if midstr == uid.MethodIDSMStartSession { +// reqBytes := req[3].(stream.List) +// hsn := reqBytes[0] +// spid := reqBytes[1].([]byte) +// readOnly := reqBytes[2].(uint) +// // for some reason readOnly is opposite - we set mc.Bool(!s.ReadOnly) so 0 means read-only -- go figure +// buff.WriteString(fmt.Sprintf("[MethodID: StartSession] hsn: %d, spid: %v, readOnly: %t", hsn, spid, readOnly == 0)) +// } else if midstr == uid.OpalGet { +// buff.WriteString("[MethodID: Get]") +// } else if midstr == uid.OpalNext { +// buff.WriteString("[MethodID: Next]") +// } else if midstr == uid.OpalSet { +// reqBytes := req[3].(stream.List) +// _ = reqBytes[0].(stream.TokenType) //startList +// _ = reqBytes[1].(uint) +// lst := reqBytes[2].(stream.List) +// _ = lst[0].(stream.TokenType) //startName +// length := lst[1].(uint) //len +// name, ok := lst[2].([]byte) //data +// if !ok { +// buff.WriteString(fmt.Sprintf("[MethodID: Set] %v,", req[3])) +// } +// _ = lst[3].(stream.TokenType) //endName +// buff.WriteString(fmt.Sprintf("[MethodID: Set] len: %v, name: %v", length, string(name))) +// } else if midstr == uid.OpalAuthenticate { +// reqBytes := req[3].(stream.List) +// lockingAuthority := reqBytes[0].([]byte) +// _ = reqBytes[1].(stream.TokenType) //startName +// length := reqBytes[2].(uint) +// name := reqBytes[3].([]byte) +// _ = reqBytes[4].(stream.TokenType) //endName +// buff.WriteString(fmt.Sprintf("[MethodID: Authenticate] authority: %v, len: %d, name: %s", lockingAuthority, length, string(name))) +// } else if midstr == uid.OpalRevert { +// buff.WriteString("[MethodID: Revert]") +// } else if midstr == uid.MethodIDSMProperties { +// // var tp TPerProperties +// // parseTPerProperties(req[3].(stream.List), &tp) +// // buff.WriteString(fmt.Sprintf("[MethodID: Properties] tp: %v", tp)) +// // reqBytes := req[3].(stream.List) +// // for i := 0; i < len(reqBytes); i++ { +// // tokenType := reqBytes[i].(stream.TokenType) +// // if tokenType == stream.StartName { +// // length := reqBytes[i+1].(uint) +// // name := reqBytes[i+2].(stream.List) +// // _ = reqBytes[i+3].(stream.TokenType) +// // buff.WriteString(fmt.Sprintf("[MethodID: Properties] tokenType: %v, length: %d, name: %s", stream.StartName, length, name)) +// // i += 3 +// // } +// } else { +// buff.WriteString(fmt.Sprintf("default to invoking-id: %s, method-id: %s. req: %+v", uidStr.String(), midstr.String(), req[3])) +// } +// return buff.String() +// } + +// return fmt.Sprintf("unhandled method call - invoking-id: %s, method-id: %s. req: %+v", m.iid.String(), m.mid.String(), req) +// } + // Copy the current state of a method call into a new independent copy func (m *MethodCall) Clone() *MethodCall { - mn := &MethodCall{bytes.Buffer{}, m.depth, m.flags} + mn := &MethodCall{ + iid: m.iid, + mid: m.mid, + buf: bytes.Buffer{}, + depth: m.depth, + flags: m.flags, + } mn.buf.Write(m.buf.Bytes()) return mn } diff --git a/pkg/core/uid/methods.go b/pkg/core/uid/methods.go index ff8ee0a1..f67b0649 100644 --- a/pkg/core/uid/methods.go +++ b/pkg/core/uid/methods.go @@ -4,6 +4,10 @@ package uid +import ( + "fmt" +) + type MethodID UID var ( @@ -35,3 +39,54 @@ var ( OpalRandom = MethodID{0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01} OpalErase = MethodID{0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03} ) + +func (mid MethodID) String() string { + switch mid { + case MethodIDSMProperties: + return "MethodIDSMProperties" + case MethodIDSMStartSession: + return "MethodIDSMStartSession" + case MethodIDSMSyncSession: + return "MethodIDSMSyncSession" + case MethodIDSMStartTrustedSession: + return "MethodIDSMStartTrustedSession" + case MethodIDSMSyncTrustedSession: + return "MethodIDSMSyncTrustedSession" + case MethodIDSMCloseSession: + return "MethodIDSMCloseSession" + case OpalProperties: + return "OpalProperties" + case OpalStartSession: + return "OpalStartSession" + case OpalRevert: + return "OpalRevert" + case OpalActivate: + return "OpalActivate" + case OpalEnterpriseGet: + return "OpalEnterpriseGet" + case OpalEnterpriseSet: + return "OpalEnterpriseSet" + case OpalNext: + return "OpalNext" + case OpalEnterpriseAuthenticate: + return "OpalEnterpriseAuthenticate" + case OpalGetACL: + return "OpalGetACL" + case OpalGenKey: + return "OpalGenKey" + case OpalRevertSP: + return "OpalRevertSP" + case OpalSet: + return "OpalSet" + case OpalGet: + return "OpalGet" + case OpalAuthenticate: + return "OpalAuthenticate" + case OpalRandom: + return "OpalRandom" + case OpalErase: + return "OpalErase" + } + return fmt.Sprintf("%v", mid) +} + diff --git a/pkg/core/uid/uid.go b/pkg/core/uid/uid.go index 91b4a14a..f0078423 100644 --- a/pkg/core/uid/uid.go +++ b/pkg/core/uid/uid.go @@ -4,6 +4,10 @@ package uid +import ( + "fmt" +) + // UID is a general type which all UID shall be based upon. // Specified in TCG Storage Architecture Core Specification Version 2.01 - Rev 1.0 type UID [8]byte @@ -25,6 +29,7 @@ var ( var ( LockingAuthorityBandMaster0 = AuthorityObjectUID{0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x01} LockingAuthorityAdmin1 = AuthorityObjectUID{0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01} + LockingAuthorityAdmin2 = AuthorityObjectUID{0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02} AuthorityAnybody = AuthorityObjectUID{0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01} AuthoritySID = AuthorityObjectUID{0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06} AuthorityPSID = AuthorityObjectUID{0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xFF, 0x01} // Opal Feature Set: PSID @@ -39,3 +44,37 @@ var ( LockingSP = SPID{0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02} EnterpriseLockingSP = SPID{0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x00, 0x01} // Enterprise SSC ) + +var ( + // 5.3.2.12 Credential Table Group - C_PIN (Object Table) + CPIN_SID InvokingID = [8]byte{0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01} + CPIN_MSID InvokingID = [8]byte{0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x54, 0x02} +) + +func (iid InvokingID) String() string { + switch iid { + case InvokeIDNull: + return "InvokeIDNull" + case InvokeIDThisSP: + return "InvokeIDThisSP" + case InvokeIDSMU: + return "InvokeIDSMU" + case InvokingID(AdminSP): + return "AdminSP" + case InvokingID(LockingSP): + return "LockingSP" + case InvokingID(EnterpriseLockingSP): + return "EnterpriseLockingSP" + case InvokingID(AuthorityPSID): + return "AuthorityPSID" + case InvokingID(AuthorityAnybody): + return "AuthorityAnybody" + case InvokingID(AuthoritySID): + return "AuthoritySID" + case InvokingID(CPIN_SID): + return "CPIN_SID" + case InvokingID(CPIN_MSID): + return "CPIN_MSID" + } + return fmt.Sprintf("%v", iid) +}