@@ -9,22 +9,23 @@ import (
99 "encoding/json"
1010 "errors"
1111 "fmt"
12- "strconv"
13- "strings"
1412
1513 "github.com/veraison/ccatoken"
1614 "github.com/veraison/ccatoken/platform"
1715 "github.com/veraison/ccatoken/realm"
1816 "github.com/veraison/corim/comid"
1917 "github.com/veraison/corim/profiles/cca"
2018 "github.com/veraison/ear"
19+ "github.com/veraison/psatoken"
2120 "github.com/veraison/services/handler"
2221 "github.com/veraison/services/log"
2322 "github.com/veraison/services/scheme/common"
2423 "github.com/veraison/services/vts/appraisal"
2524 "go.uber.org/zap"
2625)
2726
27+ const NUM_REMS = 4
28+
2829var Descriptor = handler.SchemeDescriptor {
2930 Name : "ARM_CCA" ,
3031 VersionMajor : 1 ,
@@ -113,7 +114,9 @@ func (o *Implementation) GetReferenceValueIDs(
113114 Class : trustAnchors [0 ].Environment .Class ,
114115 },
115116 {
116- Instance : comid .MustNewBytesInstance (rimValue ),
117+ Class : & comid.Class {
118+ ClassID : comid .MustNewBytesClassID (rimValue ),
119+ },
117120 },
118121 }, nil
119122}
@@ -320,57 +323,71 @@ func AppraiseRealm(
320323 appraisal .TrustVector .InstanceIdentity = ear .TrustworthyInstanceClaim
321324 appraisal .TrustVector .Executables = ear .UnrecognizedRuntimeClaim
322325
326+ logger .Debug ("collecting realm reference values..." )
323327 referenceValues := make ([]realmReference , 0 , len (endorsements ))
324328 for _ , triple := range endorsements {
325- // unset Instance indicates platform endorsements
326- if triple .Environment .Instance == nil {
327- continue
329+ refVal := realmReference {
330+ ExtensibleMeasurements : make ([][]byte , NUM_REMS ),
328331 }
329332
330333 for _ , measurement := range triple .Measurements .Values {
331- refVal := realmReference {}
334+ mkey , err := readMeasurementKey (& measurement )
335+ if err != nil {
336+ return err
337+ }
332338
333- if measurement .Val .RawValue != nil {
334- refVal .PersonalizationValue , err = measurement .Val .RawValue .GetBytes ()
339+ switch mkey {
340+ case cca .CCARealmInitialMeasurementMkey :
341+ digest , err := readMeasurementDigestBytes (& measurement )
335342 if err != nil {
336- return fmt .Errorf ("personalization value : %w" , err )
343+ return fmt .Errorf ("%s : %w" , cca . CCARealmInitialMeasurementMkey , err )
337344 }
338- }
339-
340- if measurement .Val .IntegrityRegisters == nil {
341- return errors .New ("integrity registers not set in realm reference" )
342- }
343-
344- numREMs := len (measurement .Val .IntegrityRegisters .IndexMap ) - 1
345- refVal .ExtensibleMeasurements = make ([][]byte , numREMs )
346-
347- for key , digests := range measurement .Val .IntegrityRegisters .IndexMap {
348- dLen := len (digests )
349- if dLen != 1 {
350- return fmt .Errorf ("expected 1 digest for integ. reg.; found %d" , dLen )
345+ refVal .InitialMeasurement = digest
346+ case cca .CCARealmExtendedMeasurement0Mkey :
347+ digest , err := readMeasurementDigestBytes (& measurement )
348+ if err != nil {
349+ return fmt .Errorf ("%s: %w" , cca .CCARealmExtendedMeasurement0Mkey , err )
351350 }
352-
353- keyText , ok := key .(string )
354- if ! ok {
355- return fmt .Errorf ("non-string integ. reg. key: %v" , key )
351+ refVal .ExtensibleMeasurements [0 ] = digest
352+ case cca .CCARealmExtendedMeasurement1Mkey :
353+ digest , err := readMeasurementDigestBytes (& measurement )
354+ if err != nil {
355+ return fmt .Errorf ("%s: %w" , cca .CCARealmExtendedMeasurement1Mkey , err )
356+ }
357+ refVal .ExtensibleMeasurements [1 ] = digest
358+ case cca .CCARealmExtendedMeasurement2Mkey :
359+ digest , err := readMeasurementDigestBytes (& measurement )
360+ if err != nil {
361+ return fmt .Errorf ("%s: %w" , cca .CCARealmExtendedMeasurement2Mkey , err )
362+ }
363+ refVal .ExtensibleMeasurements [2 ] = digest
364+ case cca .CCARealmExtendedMeasurement3Mkey :
365+ digest , err := readMeasurementDigestBytes (& measurement )
366+ if err != nil {
367+ return fmt .Errorf ("%s: %w" , cca .CCARealmExtendedMeasurement3Mkey , err )
368+ }
369+ refVal .ExtensibleMeasurements [3 ] = digest
370+ case cca .CCARealmPersonalizationMkey :
371+ if measurement .Val .RawValue == nil {
372+ return fmt .Errorf ("raw-value not set for %s" ,
373+ cca .CCARealmPersonalizationMkey )
356374 }
357375
358- if keyText == "rim" {
359- refVal .InitialMeasurement = digests [0 ].HashValue
360- } else {
361- idxText := strings .Replace (keyText , "rem" , "" , 1 )
362- idx , err := strconv .Atoi (idxText )
363- if err != nil {
364- return fmt .Errorf ("bad REM key: %s" , keyText )
365- }
366-
367- refVal .ExtensibleMeasurements [idx ] = digests [0 ].HashValue
376+ refVal .PersonalizationValue , err = measurement .Val .RawValue .GetBytes ()
377+ if err != nil {
378+ return fmt .Errorf ("%s: %w" , cca .CCARealmPersonalizationMkey , err )
368379 }
380+ default :
381+ logger .Debugw ("skipping non-realm measurement" , "mkey" , mkey )
369382 }
370383
384+ }
385+
386+ if refVal .InitialMeasurement != nil {
371387 referenceValues = append (referenceValues , refVal )
372388 }
373389 }
390+ logger .Debug ("collected realm reference values" , "values" , referenceValues )
374391
375392 for _ , refVal := range referenceValues {
376393 if ! bytes .Equal (refVal .InitialMeasurement , evidenceRIM ) {
@@ -428,6 +445,38 @@ func convertToPlatformClaims(v any) (platform.IClaims, error) {
428445 return platform .DecodeClaimsFromJSON (encoded )
429446}
430447
448+ func readMeasurementKey (measurement * comid.Measurement ) (string , error ) {
449+ if measurement .Key == nil || ! measurement .Key .IsSet () {
450+ return "" , errors .New (" measurement missing mkey" )
451+ }
452+
453+ if measurement .Key .Type () != comid .StringType {
454+ return "" , fmt .Errorf (
455+ "measurement mkey must be string, got %s" ,
456+ measurement .Key .Type (),
457+ )
458+ }
459+
460+ return measurement .Key .Value .String (), nil
461+ }
462+
463+ func readMeasurementDigestBytes (measurement * comid.Measurement ) ([]byte , error ) {
464+ // Not a platform-config entry: this must be a platform software component.
465+ if measurement .Val .Digests == nil {
466+ return nil , errors .New ("no digests in reference value measurement" )
467+ }
468+
469+ numDigests := len (* measurement .Val .Digests )
470+ if numDigests != 1 {
471+ return nil , fmt .Errorf (
472+ "expected exactly 1 digest in measurement; found %d" ,
473+ numDigests ,
474+ )
475+ }
476+
477+ return (* measurement .Val .Digests )[0 ].HashValue , nil
478+ }
479+
431480func matchPlatformClaimsToReferenceValues (
432481 logger * zap.SugaredLogger ,
433482 claims platform.IClaims ,
@@ -436,30 +485,18 @@ func matchPlatformClaimsToReferenceValues(
436485 var err error
437486 var referenceConfigValue []byte
438487
488+ logger .Debug ("building platform reference values map..." )
439489 referenceValues := make (map [string ][2 ]string )
440490 for _ , triple := range endorsements {
441- // set Instance indicates realm endorsements
442- if triple .Environment .Instance != nil {
443- continue
444- }
445-
446491 for _ , measurement := range triple .Measurements .Values {
447- if measurement .Key == nil || ! measurement .Key .IsSet () {
448- return false , false , errors .New ("platform reference value measurement missing mkey" )
492+ mkey , err := readMeasurementKey (& measurement )
493+ if err != nil {
494+ return false , false , err
449495 }
450496
451- if measurement .Key .Type () != comid .StringType {
452- return false , false , fmt .Errorf (
453- "platform reference value measurement mkey must be string, got %s" ,
454- measurement .Key .Type (),
455- )
456- }
457-
458- mkey := measurement .Key .Value .String ()
459-
460497 // Check if this is a platform config measurement.
461- if mkey == cca . CCAPlatformConfigMkey {
462-
498+ switch mkey {
499+ case cca . CCAPlatformConfigMkey :
463500 if measurement .Val .RawValue == nil {
464501 return false , false ,
465502 errors .New ("no raw value in platform config measurement" )
@@ -471,42 +508,30 @@ func matchPlatformClaimsToReferenceValues(
471508 }
472509
473510 continue
474- }
475-
476- if mkey != "cca.software-component" {
477- return false , false , fmt .Errorf (
478- "invalid mkey %q in platform reference value measurement" ,
479- mkey ,
480- )
481- }
482-
483- // Not a platform-config entry: this must be a platform software component.
484- if measurement .Val .Digests == nil {
485- return false , false , errors .New ("no digests in reference value measurement" )
486- }
511+ case cca .CCASoftwareComponentMkey :
512+ digest , err := readMeasurementDigestBytes (& measurement )
513+ if err != nil {
514+ return false , false , err
515+ }
487516
488- numDigests := len (* measurement .Val .Digests )
489- if numDigests != 1 {
490- return false , false , fmt .Errorf (
491- "expected exactly 1 digest in measurement; found %d" ,
492- numDigests ,
493- )
494- }
517+ encoded := base64 .StdEncoding .EncodeToString (digest )
518+ // Extract label (mtype) and version from measurement value
519+ var label , version string
495520
496- encoded := base64 .StdEncoding .EncodeToString ((* measurement .Val .Digests )[0 ].HashValue )
497- // Extract label (mtype) and version from measurement value
498- var label , version string
521+ if measurement .Val .Name != nil {
522+ label = * measurement .Val .Name
523+ }
524+ if measurement .Val .Ver != nil {
525+ version = measurement .Val .Ver .Version
526+ }
499527
500- if measurement .Val .Name != nil {
501- label = * measurement .Val .Name
528+ referenceValues [encoded ] = [2 ]string {label , version }
529+ default :
530+ logger .Debugw ("skipping non-platform measurement" , "mkey" , mkey )
502531 }
503- if measurement .Val .Ver != nil {
504- version = measurement .Val .Ver .Version
505- }
506-
507- referenceValues [encoded ] = [2 ]string {label , version }
508532 }
509533 }
534+ logger .Debugw ("platform reference values" , "map" , referenceValues )
510535
511536 evidenceConfigValue , err := claims .GetConfig ()
512537 if err != nil {
@@ -539,7 +564,7 @@ func matchPlatformClaimsToReferenceValues(
539564 }
540565
541566 mversion , err := swComp .GetVersion ()
542- if err != nil {
567+ if err != nil && ! errors . Is ( err , psatoken . ErrOptionalFieldMissing ) {
543568 return false , false , handler .BadEvidence (fmt .Errorf ("S/W comp. %d version: %w" , i , err ))
544569 }
545570
@@ -571,7 +596,7 @@ func allMatch(lhs, rhs [][]byte) bool {
571596 }
572597
573598 for i , lhsV := range lhs {
574- if ! bytes .Equal (lhsV , rhs [i ]) {
599+ if len ( lhsV ) > 0 && ! bytes .Equal (lhsV , rhs [i ]) {
575600 return false
576601 }
577602 }
0 commit comments