Skip to content

Commit

Permalink
feat: draft-ffm-rats-cca-token-00 support
Browse files Browse the repository at this point in the history
Fix #31

Signed-off-by: Thomas Fossati <thomas.fossati@linaro.org>
  • Loading branch information
thomas-fossati committed Sep 10, 2024
1 parent 1f26c01 commit dc81c92
Show file tree
Hide file tree
Showing 30 changed files with 566 additions and 179 deletions.
21 changes: 19 additions & 2 deletions evidence.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package ccatoken

import (
"crypto"
"crypto/ecdsa"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
Expand All @@ -18,6 +19,7 @@ import (
"github.com/veraison/ccatoken/platform"
"github.com/veraison/ccatoken/realm"
cose "github.com/veraison/go-cose"
"github.com/veraison/psatoken"
)

// CBORCollection is a wrapper containing the CBOR data for both platform and
Expand Down Expand Up @@ -299,9 +301,24 @@ func (e *Evidence) Verify(iak crypto.PublicKey) error {
return fmt.Errorf("extracting RAK from the realm token: %w", err)
}

rak, err := ecdsaPublicKeyFromRaw(rawRAK)
var rak *ecdsa.PublicKey

_, err = e.RealmClaims.GetProfile()
if err != nil {
return fmt.Errorf("decoding RAK: %w", err)
switch err {
case psatoken.ErrOptionalClaimMissing:
rak, err = ecdsaPublicKeyFromRaw(rawRAK)
if err != nil {
return fmt.Errorf("decoding RAK: %w", err)
}
default:
return fmt.Errorf("extracting realm profile: %w", err)
}
} else {
rak, err = ecdsaPublicKeyFromCOSE(rawRAK)
if err != nil {
return fmt.Errorf("decoding RAK: %w", err)
}
}

// Next verify the realm token
Expand Down
46 changes: 41 additions & 5 deletions evidence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func mustBuildValidCcaRealmClaims(t *testing.T) realm.IClaims {
err = c.SetHashAlgID(testHashAlgID)
require.NoError(t, err)

err = c.SetPubKey(testRAKPubRaw)
err = c.SetPubKey(testRAKPubCOSE)
require.NoError(t, err)

err = c.SetPubKeyHashAlgID(testPubKeyHashAlgID)
Expand Down Expand Up @@ -164,7 +164,7 @@ func TestEvidence_sign_and_verify_realm_key_mismatch(t *testing.T) {

// now set a different key from the one which is going to be used for
// signing
err = EvidenceIn.RealmClaims.SetPubKey(testAltRAKPubRaw)
err = EvidenceIn.RealmClaims.SetPubKey(testAltRAKPubCOSE)
assert.NoError(t, err)

ccaToken, err := EvidenceIn.ValidateAndSign(pSigner, rSigner)
Expand Down Expand Up @@ -260,7 +260,7 @@ func TestEvidence_GetRealmPubKey_ok(t *testing.T) {
)
require.NoError(t, err)

expected := &testRAKPubRaw
expected := &testRAKPubCOSE

actual := e.GetRealmPublicKey()
assert.Equal(t, expected, actual)
Expand Down Expand Up @@ -485,8 +485,10 @@ func TestEvidence_Verify_no_message(t *testing.T) {
assert.EqualError(t, err, "no message found")
}

func TestEvidence_Verify_RMM(t *testing.T) {
b := mustHexDecode(t, testRMMEvidence)
func TestEvidence_Verify_RMM_Legacy(t *testing.T) {
b := mustHexDecode(t, testRMMLegacyEvidence)

fmt.Printf("%x\n", b)

e, err := DecodeAndValidateEvidenceFromCBOR(b)
require.NoError(t, err)
Expand Down Expand Up @@ -572,3 +574,37 @@ func TestEvidence_Validate_nagative(t *testing.T) {
assert.Contains(t, err.Error(), "realm challenge claim: wrong syntax")

}

func Test_UnmarshalCBOR_InvalidEntries_MissingSign1Tag(t *testing.T) {
tv := []byte{
0xd9, 0x01, 0x8f, // tag(399)
0xa2, // map(2)
0x19, 0xac, 0xca, // unsigned(44234)
0x42, // bytes(2)
0xde, 0xad, // h'dead'
0x19, 0xac, 0xd1, // unsigned(44241)
0x42, // bytes(2)
0xbe, 0xef, // h'beef'
}
e := Evidence{}
err := e.UnmarshalCBOR(tv)
assert.ErrorContains(t, err, "decoding of CCA evidence failed")
}

func Test_UnmarshalCBOR_InvalidEntries_EmptySign1(t *testing.T) {
tv := []byte{
0xd9, 0x01, 0x8f,
0xa2,
0x19, 0xac, 0xca,
0x4e,
// invalid platform token
0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x42, 0xde, 0xad, 0x42, 0xbe, 0xef,
0x19, 0xac, 0xd1,
0x4e,
// invalid realm token
0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x42, 0xde, 0xad, 0x42, 0xbe, 0xef,
}
e := Evidence{}
err := e.UnmarshalCBOR(tv)
assert.ErrorContains(t, err, "decoding of CCA evidence failed")
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/lestrrat-go/jwx/v2 v2.0.8
github.com/stretchr/testify v1.8.1
github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53
github.com/veraison/go-cose v1.1.0
github.com/veraison/go-cose v1.2.1
github.com/veraison/psatoken v1.2.1-0.20240719122628-26fe500fd5d4
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53 h1:5gnX2TrGd/Xz8DOp2OaLtg/jLoIubSUTrgz6iZ58pJ4=
github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53/go.mod h1:+kxt8iuFiVvKRs2VQ1Ho7bbAScXAB/kHFFuP5Biw19I=
github.com/veraison/go-cose v1.1.0 h1:AalPS4VGiKavpAzIlBjrn7bhqXiXi4jbMYY/2+UC+4o=
github.com/veraison/go-cose v1.1.0/go.mod h1:7ziE85vSq4ScFTg6wyoMXjucIGOf4JkFEZi/an96Ct4=
github.com/veraison/go-cose v1.2.1 h1:Gj4x20D0YP79J2+cK3anjGEMwIkg2xX+TKVVGUXwNAc=
github.com/veraison/go-cose v1.2.1/go.mod h1:t6V8WJzHm1PD5HNsuDjW3KLv577uWb6UTzbZGvdQHD8=
github.com/veraison/psatoken v1.2.1-0.20240719122628-26fe500fd5d4 h1:N7qg7vDF2mUg7I+8AoU+ieJ20cgcShwFHXHkV5b2YAA=
github.com/veraison/psatoken v1.2.1-0.20240719122628-26fe500fd5d4/go.mod h1:6+WZzXr0ACXYiUAJJqTaCxW43gY2+gEaCoVNdDv3+Bw=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
Expand Down
9 changes: 7 additions & 2 deletions platform/claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
"github.com/veraison/psatoken"
)

const ProfileName = "http://arm.com/CCA-SSD/1.0.0"
const ProfileNameLegacy = "http://arm.com/CCA-SSD/1.0.0"
const ProfileName = "tag:arm.com,2023:cca_platform#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
Expand All @@ -22,6 +23,10 @@ func (o Profile) GetName() string {
return ProfileName
}

func (o Profile) GetNameLegacy() string {
return ProfileNameLegacy
}

func (o Profile) GetClaims() psatoken.IClaims {
return NewClaims()
}
Expand Down Expand Up @@ -212,7 +217,7 @@ func (c *Claims) GetProfile() (string, error) {
return "", err
}

if profileString != c.CanonicalProfile {
if profileString != c.CanonicalProfile && profileString != ProfileNameLegacy {
return "", fmt.Errorf("%w: expecting %q, got %q",
psatoken.ErrWrongProfile, c.CanonicalProfile, profileString)
}
Expand Down
13 changes: 5 additions & 8 deletions platform/claims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ func Test_CCAPlatform_UnmarshalCBOR_ok_mandatory_only(t *testing.T) {
actualSwComp, err := c.GetSoftwareComponents()
assert.NoError(t, err)
assert.Equal(t, expectedSwComp, actualSwComp)

}

func Test_CCAPlatform_Claims_UnmarshalCBOR_bad_input(t *testing.T) {
Expand Down Expand Up @@ -216,7 +215,7 @@ func Test_CCAPlatform_MarshalJSON_ok(t *testing.T) {
c := mustBuildValidClaims(t, true)

expected := `{
"cca-platform-profile": "http://arm.com/CCA-SSD/1.0.0",
"cca-platform-profile": "tag:arm.com,2023:cca_platform#1.0.0",
"cca-platform-challenge": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=",
"cca-platform-implementation-id":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"cca-platform-instance-id": "AQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC",
Expand Down Expand Up @@ -309,18 +308,16 @@ func Test_CCAPlatform_UnmarshalJSON_negatives(t *testing.T) {
func Test_DecodeClaims_CCAPlatform_ok(t *testing.T) {
tvs := []string{
testEncodedCcaPlatformClaimsAll,
testEncodedCcaPlatformLegacyClaimsAll,
testEncodedCcaPlatformClaimsMandatoryOnly,
testEncodedCcaPlatformLegacyClaimsMandatoryOnly,
}

for _, tv := range tvs {
buf := mustHexDecode(t, tv)
c, err := DecodeAndValidateClaimsFromCBOR(buf)

assert.NoError(t, err)
_, err := DecodeAndValidateClaimsFromCBOR(buf)

actualProfile, err := c.GetProfile()
assert.NoError(t, err)
assert.Equal(t, ProfileName, actualProfile)
}
}

Expand Down Expand Up @@ -374,7 +371,7 @@ func Test_DecodeJSONClaims_CcaPlatform(t *testing.T) {
assert.NoError(t, err)
actualProfile, err := c.GetProfile()
assert.NoError(t, err)
assert.Equal(t, ProfileName, actualProfile)
assert.Equal(t, ProfileNameLegacy, actualProfile)
}

func Test_DecodeUnvalidatedJSONCCAClaims(t *testing.T) {
Expand Down
57 changes: 41 additions & 16 deletions platform/pretty_test_vectors.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
// Copyright 2021-2024 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0

package platform

// automatically generated from CcaPlatformClaimsAll.diag
var testEncodedCcaPlatformClaimsAll = `
a919010978237461673a61726d2e636f6d2c323032333a6363615f706c61
74666f726d23312e302e300a582001010101010101010101010101010101
0101010101010101010101010101010119095c5820000000000000000000
000000000000000000000000000000000000000000000019010058210102
020202020202020202020202020202020202020202020202020202020202
021909614301020319095b19300019095f81a20258200303030303030303
030303030303030303030303030303030303030303030303055820040404
040404040404040404040404040404040404040404040404040404040419
0960782e68747470733a2f2f7665726169736f6e2e6578616d706c652f76
312f6368616c6c656e67652d726573706f6e7365190962677368612d3235
36
`

// automatically generated from CcaPlatformLegacyClaimsAll.diag
var testEncodedCcaPlatformLegacyClaimsAll = `
a9190109781c687474703a2f2f61726d2e636f6d2f4343412d5353442f31
2e302e300a58200101010101010101010101010101010101010101010101
01010101010101010119095c582000000000000000000000000000000000
Expand All @@ -17,6 +29,32 @@ a9190109781c687474703a2f2f61726d2e636f6d2f4343412d5353442f31
656e67652d726573706f6e7365190962677368612d323536
`

// automatically generated from CcaPlatformClaimsMandatoryOnly.diag
var testEncodedCcaPlatformClaimsMandatoryOnly = `
a819010978237461673a61726d2e636f6d2c323032333a6363615f706c61
74666f726d23312e302e300a582001010101010101010101010101010101
0101010101010101010101010101010119095c5820000000000000000000
000000000000000000000000000000000000000000000019010058210102
020202020202020202020202020202020202020202020202020202020202
021909614301020319095b19300019095f81a20258200303030303030303
030303030303030303030303030303030303030303030303055820040404
040404040404040404040404040404040404040404040404040404040419
0962677368612d323536
`

// automatically generated from CcaPlatformLegacyClaimsMandatoryOnly.diag
var testEncodedCcaPlatformLegacyClaimsMandatoryOnly = `
a8190109781c687474703a2f2f61726d2e636f6d2f4343412d5353442f31
2e302e300a58200101010101010101010101010101010101010101010101
01010101010101010119095c582000000000000000000000000000000000
000000000000000000000000000000001901005821010202020202020202
020202020202020202020202020202020202020202020202190961430102
0319095b19300019095f81a2025820030303030303030303030303030303
030303030303030303030303030303030305582004040404040404040404
04040404040404040404040404040404040404040404190962677368612d
323536
`

// automatically generated from CcaPlatformClaimsInvalidMultiNonce.diag
var testEncodedCcaPlatformClaimsInvalidMultiNonce = `
a9190109781c687474703a2f2f61726d2e636f6d2f4343412d5353442f31
Expand All @@ -32,19 +70,6 @@ a9190109781c687474703a2f2f61726d2e636f6d2f4343412d5353442f31
6368616c6c656e67652d726573706f6e7365190962677368612d323536
`

// automatically generated from CcaPlatformClaimsMandatoryOnly.diag
var testEncodedCcaPlatformClaimsMandatoryOnly = `
a8190109781c687474703a2f2f61726d2e636f6d2f4343412d5353442f31
2e302e300a58200101010101010101010101010101010101010101010101
01010101010101010119095c582000000000000000000000000000000000
000000000000000000000000000000001901005821010202020202020202
020202020202020202020202020202020202020202020202190961430102
0319095b19300019095f81a2025820030303030303030303030303030303
030303030303030303030303030303030305582004040404040404040404
04040404040404040404040404040404040404040404190962677368612d
323536
`

// automatically generated from CcaPlatformClaimsMissingMandatoryNonce.diag
var testEncodedCcaPlatformClaimsMissingMandatoryNonce = `
a8190109781c687474703a2f2f61726d2e636f6d2f4343412d5353442f31
Expand Down
2 changes: 1 addition & 1 deletion platform/testvectors/cbor/CcaPlatformClaimsAll.diag
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
265: "http://arm.com/CCA-SSD/1.0.0",
265: "tag:arm.com,2023:cca_platform#1.0.0",
10: h'0101010101010101010101010101010101010101010101010101010101010101',
2396: h'0000000000000000000000000000000000000000000000000000000000000000',
256: h'010202020202020202020202020202020202020202020202020202020202020202',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
265: "http://arm.com/CCA-SSD/1.0.0",
265: "tag:arm.com,2023:cca_platform#1.0.0",
10: h'0101010101010101010101010101010101010101010101010101010101010101',
2396: h'0000000000000000000000000000000000000000000000000000000000000000',
256: h'010202020202020202020202020202020202020202020202020202020202020202',
Expand Down
25 changes: 25 additions & 0 deletions platform/testvectors/cbor/CcaPlatformExample.diag
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
265: "tag:arm.com,2023:cca_platform#1.0.0",
10: h'0D22E08A98469058486318283489BDB36F09DBEFEB1864DF433FA6E54EA2D711',
2396: h'7F454C4602010100000000000000000003003E00010000005058000000000000',
256: h'0107060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918',
2401: h'CFCFCFCF',
2395: 12291,
2402: "sha-256",
2400: "https://veraison.example/.well-known/veraison/verification",
2399: [
{ 1: "RSE_BL1_2", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'9A271F2A916B0B6EE6CECB2426F0B3206EF074578BE55D9BC94F6F3FE3AB86AA', 6: "sha-256" },
{ 1: "RSE_BL2", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'53C234E5E8472B6AC51C1AE1CAB3FE06FAD053BEB8EBFD8977B010655BFDD3C3', 6: "sha-256" },
{ 1: "RSE_S", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'1121CFCCD5913F0A63FEC40A6FFD44EA64F9DC135C66634BA001D10BCF4302A2', 6: "sha-256" },
{ 1: "AP_BL1", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'1571B5EC78BD68512BF7830BB6A2A44B2047C7DF57BCE79EB8A1C0E5BEA0A501', 6: "sha-256" },
{ 1: "AP_BL2", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'10159BAF262B43A92D95DB59DAE1F72C645127301661E0A3CE4E38B295A97C58', 6: "sha-256" },
{ 1: "SCP_BL1", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'10122E856B3FCD49F063636317476149CB730A1AA1CFAAD818552B72F56D6F68', 6: "sha-256" },
{ 1: "SCP_BL2", 5: h'F14B4987904BCB5814E4459A057ED4D20F58A633152288A761214DCD28780B56', 2: h'AA67A169B0BBA217AA0AA88A65346920C84C42447C36BA5F7EA65F422C1FE5D8', 6: "sha-256" },
{ 1: "AP_BL31", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'2E6D31A5983A91251BFAE5AEFA1C0A19D8BA3CF601D0E8A706B4CFA9661A6B8A', 6: "sha-256" },
{ 1: "RMM", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'A1FB50E6C86FAE1679EF3351296FD6713411A08CF8DD1790A4FD05FAE8688164', 6: "sha-256" },
{ 1: "HW_CONFIG", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'1A252402972F6057FA53CC172B52B9FFCA698E18311FACD0F3B06ECAAEF79E17', 6: "sha-256" },
{ 1: "FW_CONFIG", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'9A92ADBC0CEE38EF658C71CE1B1BF8C65668F166BFB213644C895CCB1AD07A25', 6: "sha-256" },
{ 1: "TB_FW_CONFIG", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'238903180CC104EC2C5D8B3F20C5BC61B389EC0A967DF8CC208CDC7CD454174F', 6: "sha-256" },
{ 1: "SOC_FW_CONFIG", 5: h'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3', 2: h'E6C21E8D260FE71882DEBDB339D2402A2CA7648529BC2303F48649BCE0380017', 6: "sha-256" }
]
}
16 changes: 16 additions & 0 deletions platform/testvectors/cbor/CcaPlatformLegacyClaimsAll.diag
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
265: "http://arm.com/CCA-SSD/1.0.0",
10: h'0101010101010101010101010101010101010101010101010101010101010101',
2396: h'0000000000000000000000000000000000000000000000000000000000000000',
256: h'010202020202020202020202020202020202020202020202020202020202020202',
2401: h'010203',
2395: 12288,
2399: [
{
2: h'0303030303030303030303030303030303030303030303030303030303030303',
5: h'0404040404040404040404040404040404040404040404040404040404040404'
}
],
2400: "https://veraison.example/v1/challenge-response",
2402: "sha-256"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
265: "http://arm.com/CCA-SSD/1.0.0",
10: h'0101010101010101010101010101010101010101010101010101010101010101',
2396: h'0000000000000000000000000000000000000000000000000000000000000000',
256: h'010202020202020202020202020202020202020202020202020202020202020202',
2401: h'010203',
2395: 12288,
2399: [
{
2: h'0303030303030303030303030303030303030303030303030303030303030303',
5: h'0404040404040404040404040404040404040404040404040404040404040404'
}
],
2402: "sha-256"
}
6 changes: 4 additions & 2 deletions platform/testvectors/cbor/build-test-vectors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ set -o pipefail

DIAG_FILES=
DIAG_FILES="${DIAG_FILES} CcaPlatformClaimsAll"
DIAG_FILES="${DIAG_FILES} CcaPlatformClaimsInvalidMultiNonce"
DIAG_FILES="${DIAG_FILES} CcaPlatformLegacyClaimsAll"
DIAG_FILES="${DIAG_FILES} CcaPlatformClaimsMandatoryOnly"
DIAG_FILES="${DIAG_FILES} CcaPlatformLegacyClaimsMandatoryOnly"
DIAG_FILES="${DIAG_FILES} CcaPlatformClaimsInvalidMultiNonce"
DIAG_FILES="${DIAG_FILES} CcaPlatformClaimsMissingMandatoryNonce"

TV_DOT_GO=${TV_DOT_GO?must be set in the environment.}

printf "package psatoken\n\n" > ${TV_DOT_GO}
printf "package platform\n\n" > ${TV_DOT_GO}

for t in ${DIAG_FILES}
do
Expand Down
Loading

0 comments on commit dc81c92

Please sign in to comment.