@@ -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,66 @@ 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 )
356356 }
357-
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
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 )
368362 }
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+ refVal .PersonalizationValue , err = measurement .Val .RawValue .GetBytes ()
372+ if err != nil {
373+ return fmt .Errorf ("%s: %w" , cca .CCARealmPersonalizationMkey , err )
374+ }
375+ default :
376+ logger .Debugw ("skipping non-realm measurement" , "mkey" , mkey )
369377 }
370378
379+ }
380+
381+ if refVal .InitialMeasurement != nil {
371382 referenceValues = append (referenceValues , refVal )
372383 }
373384 }
385+ logger .Debug ("collected realm reference values" , "values" , referenceValues )
374386
375387 for _ , refVal := range referenceValues {
376388 if ! bytes .Equal (refVal .InitialMeasurement , evidenceRIM ) {
@@ -428,6 +440,38 @@ func convertToPlatformClaims(v any) (platform.IClaims, error) {
428440 return platform .DecodeClaimsFromJSON (encoded )
429441}
430442
443+ func readMeasurementKey (measurement * comid.Measurement ) (string , error ) {
444+ if measurement .Key == nil || ! measurement .Key .IsSet () {
445+ return "" , errors .New (" measurement missing mkey" )
446+ }
447+
448+ if measurement .Key .Type () != comid .StringType {
449+ return "" , fmt .Errorf (
450+ "measurement mkey must be string, got %s" ,
451+ measurement .Key .Type (),
452+ )
453+ }
454+
455+ return measurement .Key .Value .String (), nil
456+ }
457+
458+ func readMeasurementDigestBytes (measurement * comid.Measurement ) ([]byte , error ) {
459+ // Not a platform-config entry: this must be a platform software component.
460+ if measurement .Val .Digests == nil {
461+ return nil , errors .New ("no digests in reference value measurement" )
462+ }
463+
464+ numDigests := len (* measurement .Val .Digests )
465+ if numDigests != 1 {
466+ return nil , fmt .Errorf (
467+ "expected exactly 1 digest in measurement; found %d" ,
468+ numDigests ,
469+ )
470+ }
471+
472+ return (* measurement .Val .Digests )[0 ].HashValue , nil
473+ }
474+
431475func matchPlatformClaimsToReferenceValues (
432476 logger * zap.SugaredLogger ,
433477 claims platform.IClaims ,
@@ -436,30 +480,18 @@ func matchPlatformClaimsToReferenceValues(
436480 var err error
437481 var referenceConfigValue []byte
438482
483+ logger .Debug ("building platform reference values map..." )
439484 referenceValues := make (map [string ][2 ]string )
440485 for _ , triple := range endorsements {
441- // set Instance indicates realm endorsements
442- if triple .Environment .Instance != nil {
443- continue
444- }
445-
446486 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" )
449- }
450-
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- )
487+ mkey , err := readMeasurementKey (& measurement )
488+ if err != nil {
489+ return false , false , err
456490 }
457491
458- mkey := measurement .Key .Value .String ()
459-
460492 // Check if this is a platform config measurement.
461- if mkey == cca . CCAPlatformConfigMkey {
462-
493+ switch mkey {
494+ case cca . CCAPlatformConfigMkey :
463495 if measurement .Val .RawValue == nil {
464496 return false , false ,
465497 errors .New ("no raw value in platform config measurement" )
@@ -471,42 +503,30 @@ func matchPlatformClaimsToReferenceValues(
471503 }
472504
473505 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- }
506+ case cca .CCASoftwareComponentMkey :
507+ digest , err := readMeasurementDigestBytes (& measurement )
508+ if err != nil {
509+ return false , false , err
510+ }
482511
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- }
512+ encoded := base64 .StdEncoding .EncodeToString (digest )
513+ // Extract label (mtype) and version from measurement value
514+ var label , version string
487515
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- }
495-
496- encoded := base64 .StdEncoding .EncodeToString ((* measurement .Val .Digests )[0 ].HashValue )
497- // Extract label (mtype) and version from measurement value
498- var label , version string
516+ if measurement .Val .Name != nil {
517+ label = * measurement .Val .Name
518+ }
519+ if measurement .Val .Ver != nil {
520+ version = measurement .Val .Ver .Version
521+ }
499522
500- if measurement .Val .Name != nil {
501- label = * measurement .Val .Name
523+ referenceValues [encoded ] = [2 ]string {label , version }
524+ default :
525+ logger .Debugw ("skipping non-platform measurement" , "mkey" , mkey )
502526 }
503- if measurement .Val .Ver != nil {
504- version = measurement .Val .Ver .Version
505- }
506-
507- referenceValues [encoded ] = [2 ]string {label , version }
508527 }
509528 }
529+ logger .Debugw ("platform reference values" , "map" , referenceValues )
510530
511531 evidenceConfigValue , err := claims .GetConfig ()
512532 if err != nil {
@@ -539,7 +559,7 @@ func matchPlatformClaimsToReferenceValues(
539559 }
540560
541561 mversion , err := swComp .GetVersion ()
542- if err != nil {
562+ if err != nil && ! errors . Is ( err , psatoken . ErrOptionalFieldMissing ) {
543563 return false , false , handler .BadEvidence (fmt .Errorf ("S/W comp. %d version: %w" , i , err ))
544564 }
545565
@@ -571,7 +591,7 @@ func allMatch(lhs, rhs [][]byte) bool {
571591 }
572592
573593 for i , lhsV := range lhs {
574- if ! bytes .Equal (lhsV , rhs [i ]) {
594+ if len ( lhsV ) > 0 && ! bytes .Equal (lhsV , rhs [i ]) {
575595 return false
576596 }
577597 }
0 commit comments