diff --git a/evidence.go b/evidence.go index ac5c690..cea203b 100644 --- a/evidence.go +++ b/evidence.go @@ -20,11 +20,15 @@ import ( cose "github.com/veraison/go-cose" ) +// CBORCollection is a wrapper containing the CBOR data for both platform and +// realm tokens. type CBORCollection struct { PlatformToken *[]byte `cbor:"44234,keyasint"` RealmToken *[]byte `cbor:"44241,keyasint"` } +// JSONCollection is a wrapper containing the JSON data for both platform and +// realm tokens. type JSONCollection struct { PlatformToken json.RawMessage `json:"cca-platform-token,omitempty"` RealmToken json.RawMessage `json:"cca-realm-delegated-token,omitempty"` diff --git a/platform/claims.go b/platform/claims.go index 7a0996c..4ac97bb 100644 --- a/platform/claims.go +++ b/platform/claims.go @@ -13,6 +13,9 @@ import ( const ProfileName = "http://arm.com/CCA-SSD/1.0.0" +// Profile is the psatoken.IProfile implementation for CCA claims. It is +// registered to associate the claims with the profile name, so that it can be +// automatically used during unmarshaling. type Profile struct{} func (o Profile) GetName() string { @@ -23,6 +26,8 @@ func (o Profile) GetClaims() psatoken.IClaims { return NewClaims() } +// Claims contains the CCA platform claims. It implements IClaims, which is an +// extension of psatoken.IClaims. type Claims struct { Profile *eat.Profile `cbor:"265,keyasint" json:"cca-platform-profile"` Challenge *eat.Nonce `cbor:"10,keyasint" json:"cca-platform-challenge"` @@ -38,6 +43,7 @@ type Claims struct { CanonicalProfile string `cbor:"-" json:"-"` } +// NewClaims claims returns a new instance of Claims. func NewClaims() IClaims { p := eat.Profile{} if err := p.Set(ProfileName); err != nil { diff --git a/platform/iclaims.go b/platform/iclaims.go index d09713a..1dd0a55 100644 --- a/platform/iclaims.go +++ b/platform/iclaims.go @@ -9,6 +9,7 @@ import ( "github.com/veraison/psatoken" ) +// IClaims extends psatoken.IClaims to add accessors for CCA claims. type IClaims interface { psatoken.IClaims @@ -19,6 +20,7 @@ type IClaims interface { SetHashAlgID(string) error } +// DecodeClaims unmarshals CCA platform claims from provided CBOR data. func DecodeClaims(buf []byte) (IClaims, error) { cl := NewClaims() @@ -29,6 +31,8 @@ func DecodeClaims(buf []byte) (IClaims, error) { return cl, nil } +// ValidateClaims returns an error if the provided IClaims instance does not +// contain a valid set of CCA platform claims. func ValidateClaims(c IClaims) error { if err := psatoken.ValidateClaims(c); err != nil { return err diff --git a/platform/lifecycle.go b/platform/lifecycle.go index 817d168..6695960 100644 --- a/platform/lifecycle.go +++ b/platform/lifecycle.go @@ -26,6 +26,9 @@ const ( LifecycleDecommissionedMax = 0x60ff ) +// LifeCycleState indicates the life cycle state of attested device. The state +// is derived from the life cycle claim value, with a range of values mapping +// onto each state. type LifeCycleState uint16 const ( @@ -40,10 +43,12 @@ const ( StateInvalid // must be last ) +// IsValid returns true if the LifeCycleState has a valid value. func (o LifeCycleState) IsValid() bool { return o < StateInvalid } +// String returns a string representation of the life cycle state. func (o LifeCycleState) String() string { switch o { case StateUnknown: @@ -65,6 +70,9 @@ func (o LifeCycleState) String() string { } } +// LifeCycleToState translates the provide life cycle claim value into +// corresponding LifeCycleState.If the value is not within valid range, then +// StateInvalid is returned. func LifeCycleToState(v uint16) LifeCycleState { if v >= LifecycleUnknownMin && v <= LifecycleUnknownMax { @@ -104,6 +112,8 @@ func LifeCycleToState(v uint16) LifeCycleState { return StateInvalid } +// ValidateSecurityLifeCycle returns an error if the provided value does not +// correspond to a valid LifeCycleState. func ValidateSecurityLifeCycle(v uint16) error { if !LifeCycleToState(v).IsValid() { return fmt.Errorf("%w: value %d is invalid", psatoken.ErrWrongSyntax, v) diff --git a/realm/claims.go b/realm/claims.go index e207db8..4fd1a7f 100644 --- a/realm/claims.go +++ b/realm/claims.go @@ -9,6 +9,8 @@ import ( "github.com/veraison/psatoken" ) +// Claims contains the CCA realm claims. It implements IClaims, which is an +// extension of psatoken.IClaimBase. type Claims struct { Challenge *eat.Nonce `cbor:"10,keyasint" json:"cca-realm-challenge"` PersonalizationValue *[]byte `cbor:"44235,keyasint" json:"cca-realm-personalization-value"` diff --git a/realm/common.go b/realm/common.go index ae5a9de..186f68f 100644 --- a/realm/common.go +++ b/realm/common.go @@ -13,6 +13,8 @@ const ( MaxLenRealmExtendedMeas = 4 ) +// ValidateChallenge returns an error if the provided value does not contain a +// valid CCA challenge. func ValidateChallenge(v []byte) error { l := len(v) @@ -26,6 +28,8 @@ func ValidateChallenge(v []byte) error { return nil } +// ValidatePersonalizationValue returns an error if the provided value is not a +// valid personalization value (must be exactly 64 bytes long). func ValidatePersonalizationValue(b []byte) error { l := len(b) @@ -38,8 +42,9 @@ func ValidatePersonalizationValue(b []byte) error { return nil } +// ValidateRealmPubKey returns an error if the provided value does not contain +// a valid realm public key (must 97-byte ECC-P384). func ValidateRealmPubKey(b []byte) error { - // Realm Public Key is ECC Public key of type ECC-P384 of size 97 bytes l := len(b) if l != 97 { @@ -59,6 +64,8 @@ func ValidateRealmPubKey(b []byte) error { return nil } +// ValidateRealmMeas returns an error if the provided value does not contain a +// valid realm measurement (must be 32, 48, or 64 bytes long). func ValidateRealmMeas(b []byte) error { l := len(b) @@ -72,6 +79,8 @@ func ValidateRealmMeas(b []byte) error { return nil } +// ValidateHashAlgID returns an error if the provided value is not a valid +// hash algorithm string. func ValidateHashAlgID(v string) error { if v == "" { return fmt.Errorf("%w: empty string", psatoken.ErrWrongSyntax) @@ -80,6 +89,9 @@ func ValidateHashAlgID(v string) error { return nil } +// ValidateExtendedMeas returns an error if the provided slice does not contain +// valid realm extended measurements (it must be non-empty, and each value must +// be a valid ream measurement). func ValidateExtendedMeas(v [][]byte) error { if len(v) == 0 { return fmt.Errorf("%w realm extended measurements", diff --git a/realm/iclaims.go b/realm/iclaims.go index 90a7aec..2a4faaf 100644 --- a/realm/iclaims.go +++ b/realm/iclaims.go @@ -32,10 +32,12 @@ type IClaims interface { SetPubKeyHashAlgID(string) error } +// NewClaims returns a new instance of platform Claims. func NewClaims() IClaims { return &Claims{} } +// DecodeClaims unmarshals CCA realm claims from provided CBOR data. func DecodeClaims(buf []byte) (IClaims, error) { cl := &Claims{} @@ -46,6 +48,8 @@ func DecodeClaims(buf []byte) (IClaims, error) { return cl, nil } +// ValidateClaims returns an error if the provided IClaims instance does not +// contain a valid set of CCA realm claims. func ValidateClaims(c IClaims) error { if err := psatoken.FilterError(c.GetChallenge()); err != nil { return fmt.Errorf("validating realm challenge claim: %w", err)