Skip to content

Commit f1ef5c2

Browse files
authored
Merge pull request #6469 from oasisprotocol/peternose/bugfix/pcesvn
go/common/sgx/pcs/tcb: Fix pcesvn validation
2 parents d6b34c6 + 373d3f9 commit f1ef5c2

5 files changed

Lines changed: 211 additions & 3 deletions

File tree

.changelog/6469.bugfix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
go/common/sgx/pcs/tcb: Fix pcesvn validation

go/.nancy-ignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ CVE-2024-34478 # can be ignored as we only use a few crypto libraries from btcd
22
CVE-2025-4673 until=2025-07-14 # no mitigation is currently available (2025-06-14)
33
CVE-2021-43668 # the vulnerability does not affect us as we don't use LevelDB
44
CVE-2025-11065 until=2025-12-01 # the vulnerability does not affect us
5-
CVE-2026-26014 until=2026-03-01 # requires upstream mitigation
5+
CVE-2026-26014 until=2026-04-01 # requires upstream mitigation

go/common/sgx/pcs/tcb.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ func (tl *TCBLevel) matches(sgxCompSvn [16]int32, tdxCompSvn *[16]byte, pcesvn u
466466
// in the TCB Level. If it is greater or equal to the value in TCB Level, read status
467467
// assigned to this TCB level (in case of SGX) or go to c (in case of TDX). Otherwise, move
468468
// to the next item on TCB Levels list.
469-
if tl.TCB.PCESVN < pcesvn {
469+
if pcesvn < tl.TCB.PCESVN {
470470
return false
471471
}
472472

go/common/sgx/pcs/tcb_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package pcs
2+
3+
import "testing"
4+
5+
func TestTCBLevelMatches(t *testing.T) {
6+
pcesvn := uint16(10)
7+
sgxSvn := [16]int32{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}
8+
tdxSvn := [16]byte{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}
9+
10+
var tl TCBLevel
11+
tl.TCB.PCESVN = pcesvn
12+
for i := range 16 {
13+
tl.TCB.SGXComponents[i].SVN = sgxSvn[i]
14+
tl.TCB.TDXComponents[i].SVN = int32(tdxSvn[i])
15+
}
16+
17+
tcs := []struct {
18+
name string
19+
pcesvn uint16
20+
sgxSvn [16]int32
21+
tdxSvn *[16]byte
22+
matches bool
23+
msg string
24+
}{
25+
{
26+
name: "same values",
27+
pcesvn: pcesvn,
28+
sgxSvn: sgxSvn,
29+
tdxSvn: &tdxSvn,
30+
matches: true,
31+
},
32+
{
33+
name: "higher pcesvn",
34+
pcesvn: pcesvn + 1,
35+
sgxSvn: sgxSvn,
36+
tdxSvn: &tdxSvn,
37+
matches: true,
38+
},
39+
{
40+
name: "lower pcesvn",
41+
pcesvn: pcesvn - 1,
42+
sgxSvn: sgxSvn,
43+
tdxSvn: &tdxSvn,
44+
matches: false,
45+
},
46+
{
47+
name: "higher sgx svn",
48+
pcesvn: pcesvn,
49+
sgxSvn: func() [16]int32 { ss := sgxSvn; ss[5] += 1; return ss }(),
50+
tdxSvn: &tdxSvn,
51+
matches: true,
52+
},
53+
{
54+
name: "lower sgx svn",
55+
pcesvn: pcesvn,
56+
sgxSvn: func() [16]int32 { ss := sgxSvn; ss[5] -= 1; return ss }(),
57+
tdxSvn: &tdxSvn,
58+
matches: false,
59+
},
60+
{
61+
name: "higher tdx svn",
62+
pcesvn: pcesvn,
63+
sgxSvn: sgxSvn,
64+
tdxSvn: func() *[16]byte { ts := tdxSvn; ts[5] += 1; return &ts }(),
65+
matches: true,
66+
},
67+
{
68+
name: "lower tdx svn",
69+
pcesvn: pcesvn,
70+
sgxSvn: sgxSvn,
71+
tdxSvn: func() *[16]byte { ts := tdxSvn; ts[5] -= 1; return &ts }(),
72+
matches: false,
73+
},
74+
{
75+
name: "no tdx svn",
76+
pcesvn: pcesvn,
77+
sgxSvn: sgxSvn,
78+
tdxSvn: nil,
79+
matches: true,
80+
},
81+
}
82+
83+
for _, tc := range tcs {
84+
t.Run(tc.name, func(t *testing.T) {
85+
if tl.matches(tc.sgxSvn, tc.tdxSvn, tc.pcesvn) != tc.matches {
86+
switch tc.matches {
87+
case true:
88+
t.Errorf("tcb level should match")
89+
case false:
90+
t.Errorf("tcb level should not match")
91+
}
92+
}
93+
})
94+
}
95+
}

runtime/src/common/sgx/pcs/tcb.rs

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ impl TCBLevel {
370370
// in the TCB Level. If it is greater or equal to the value in TCB Level, read status
371371
// assigned to this TCB level (in case of SGX) or go to c (in case of TDX). Otherwise,
372372
// move to the next item on TCB Levels list.
373-
if self.tcb.pcesvn < pcesvn {
373+
if pcesvn < self.tcb.pcesvn {
374374
return false;
375375
}
376376

@@ -694,3 +694,115 @@ pub struct EnclaveTCBVersions {
694694
#[serde(rename = "isvsvn")]
695695
pub isv_svn: u16,
696696
}
697+
698+
#[cfg(test)]
699+
mod tests {
700+
use super::*;
701+
702+
#[test]
703+
fn test_tcb_level_matches() {
704+
let pcesvn: u32 = 10;
705+
let sgx_svn: [u32; 16] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30];
706+
let tdx_svn: [u32; 16] = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31];
707+
708+
let mut tl = TCBLevel::default();
709+
tl.tcb.pcesvn = pcesvn;
710+
711+
for i in 0..16 {
712+
tl.tcb.sgx_components[i].svn = sgx_svn[i];
713+
tl.tcb.tdx_components[i].svn = tdx_svn[i];
714+
}
715+
716+
struct TestCase {
717+
name: &'static str,
718+
pcesvn: u32,
719+
sgx_svn: [u32; 16],
720+
tdx_svn: Option<[u32; 16]>,
721+
matches: bool,
722+
}
723+
724+
let tcs = vec![
725+
TestCase {
726+
name: "same values",
727+
pcesvn,
728+
sgx_svn,
729+
tdx_svn: Some(tdx_svn),
730+
matches: true,
731+
},
732+
TestCase {
733+
name: "higher pcesvn",
734+
pcesvn: pcesvn + 1,
735+
sgx_svn,
736+
tdx_svn: Some(tdx_svn),
737+
matches: true,
738+
},
739+
TestCase {
740+
name: "lower pcesvn",
741+
pcesvn: pcesvn - 1,
742+
sgx_svn,
743+
tdx_svn: Some(tdx_svn),
744+
matches: false,
745+
},
746+
TestCase {
747+
name: "higher sgx svn",
748+
pcesvn,
749+
sgx_svn: {
750+
let mut ss = sgx_svn;
751+
ss[5] += 1;
752+
ss
753+
},
754+
tdx_svn: Some(tdx_svn),
755+
matches: true,
756+
},
757+
TestCase {
758+
name: "lower sgx svn",
759+
pcesvn,
760+
sgx_svn: {
761+
let mut ss = sgx_svn;
762+
ss[5] -= 1;
763+
ss
764+
},
765+
tdx_svn: Some(tdx_svn),
766+
matches: false,
767+
},
768+
TestCase {
769+
name: "higher tdx svn",
770+
pcesvn,
771+
sgx_svn,
772+
tdx_svn: {
773+
let mut ts = tdx_svn;
774+
ts[5] += 1;
775+
Some(ts)
776+
},
777+
matches: true,
778+
},
779+
TestCase {
780+
name: "lower tdx svn",
781+
pcesvn,
782+
sgx_svn,
783+
tdx_svn: {
784+
let mut ts = tdx_svn;
785+
ts[5] -= 1;
786+
Some(ts)
787+
},
788+
matches: false,
789+
},
790+
TestCase {
791+
name: "no tdx svn",
792+
pcesvn,
793+
sgx_svn,
794+
tdx_svn: None,
795+
matches: true,
796+
},
797+
];
798+
799+
for tc in tcs {
800+
let result = tl.matches(&tc.sgx_svn, tc.tdx_svn.as_ref(), tc.pcesvn);
801+
if tc.matches {
802+
assert!(result, "tcb level should match when {}", tc.name);
803+
} else {
804+
assert!(!result, "tcb level should not match when {}", tc.name);
805+
}
806+
}
807+
}
808+
}

0 commit comments

Comments
 (0)