1
2
3
4
5 package subtle
6
7 import (
8 "internal/cpu"
9 "internal/runtime/sys"
10 "testing"
11 )
12
13 func TestWithDataIndependentTiming(t *testing.T) {
14 if !cpu.ARM64.HasDIT {
15 t.Skip("CPU does not support DIT")
16 }
17
18 ditAlreadyEnabled := sys.DITEnabled()
19
20 WithDataIndependentTiming(func() {
21 if !sys.DITEnabled() {
22 t.Fatal("dit not enabled within WithDataIndependentTiming closure")
23 }
24
25 WithDataIndependentTiming(func() {
26 if !sys.DITEnabled() {
27 t.Fatal("dit not enabled within nested WithDataIndependentTiming closure")
28 }
29 })
30
31 if !sys.DITEnabled() {
32 t.Fatal("dit not enabled after return from nested WithDataIndependentTiming closure")
33 }
34 })
35
36 if !ditAlreadyEnabled && sys.DITEnabled() {
37 t.Fatal("dit not unset after returning from WithDataIndependentTiming closure")
38 }
39 }
40
41 func TestDITPanic(t *testing.T) {
42 if !cpu.ARM64.HasDIT {
43 t.Skip("CPU does not support DIT")
44 }
45
46 ditAlreadyEnabled := sys.DITEnabled()
47
48 defer func() {
49 e := recover()
50 if e == nil {
51 t.Fatal("didn't panic")
52 }
53 if !ditAlreadyEnabled && sys.DITEnabled() {
54 t.Error("DIT still enabled after panic inside of WithDataIndependentTiming closure")
55 }
56 }()
57
58 WithDataIndependentTiming(func() {
59 if !sys.DITEnabled() {
60 t.Fatal("dit not enabled within WithDataIndependentTiming closure")
61 }
62
63 panic("bad")
64 })
65 }
66
67 func TestDITGoroutineInheritance(t *testing.T) {
68 if !cpu.ARM64.HasDIT {
69 t.Skip("CPU does not support DIT")
70 }
71
72 ditAlreadyEnabled := sys.DITEnabled()
73
74 WithDataIndependentTiming(func() {
75 done := make(chan struct{})
76 go func() {
77 if !sys.DITEnabled() {
78 t.Error("DIT not enabled in new goroutine")
79 }
80 close(done)
81 }()
82 <-done
83 if !ditAlreadyEnabled && !sys.DITEnabled() {
84 t.Fatal("dit unset after returning from goroutine started in WithDataIndependentTiming closure")
85 }
86 })
87 }
88
View as plain text