1// Copyright 2017 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4// +build linux 5 6package linux 7 8import ( 9 "flag" 10 "fmt" 11 "math/rand" 12 "strings" 13 "syscall" 14 "testing" 15 "unsafe" 16) 17 18// AF_ALG tests won't generally pass and intended for manual testing. 19// First, they require fresh kernel with _all_ crypto algorithms enabled. 20// Second, they require the newest hardware with all of SSE/AVX. 21// Finally, they still won't pass because some algorithms are arch-dependent. 22var flagRunAlgTests = flag.Bool("algtests", false, "run AF_ALG tests") 23 24func algTest(t *testing.T) { 25 if !*flagRunAlgTests { 26 t.Skip() 27 } 28 t.Parallel() 29} 30 31// TestAlgDescriptions checks that there are no duplicate names and that 32// templates mentioned in complete algorithms are also present as standalone templates. 33func TestAlgDescriptions(t *testing.T) { 34 algTest(t) 35 allall := make(map[string]bool) 36 for typ, algList := range allAlgs { 37 algs := make(map[string]bool) 38 templates := make(map[string]bool) 39 for _, alg := range algList { 40 allall[alg.name] = true 41 if algs[alg.name] { 42 t.Errorf("duplicate: %v", alg.name) 43 } 44 algs[alg.name] = true 45 if len(alg.args) > 0 { 46 templates[alg.name] = true 47 } 48 } 49 for _, alg := range algList { 50 if len(alg.args) > 0 || strings.HasPrefix(alg.name, "__") { 51 continue 52 } 53 brace := strings.IndexByte(alg.name, '(') 54 if brace == -1 { 55 continue 56 } 57 templ := alg.name[:brace] 58 if !templates[templ] { 59 t.Errorf("template %v is missing for type %v", templ, typ) 60 } 61 templates[templ] = true 62 } 63 } 64} 65 66// TestSingleAlg tests creation of all algorithms (not templates). 67func TestSingleAlg(t *testing.T) { 68 algTest(t) 69 for _, typ := range allTypes { 70 for _, alg := range allAlgs[typ.typ] { 71 if len(alg.args) != 0 { 72 continue 73 } 74 ok, skip := testAlg(t, typ.name, alg.name) 75 if skip { 76 t.Errorf("SKIP\t%10v\t%v", typ.name, alg.name) 77 continue 78 } 79 if !ok { 80 t.Errorf("FAIL\t%10v\t%v", typ.name, alg.name) 81 continue 82 } 83 } 84 } 85} 86 87// TestTemplateAlg1 tests creation of all templates with 1 argument. 88func TestTemplateAlg1(t *testing.T) { 89 algTest(t) 90 for _, typ := range allTypes { 91 for _, alg := range allAlgs[typ.typ] { 92 if len(alg.args) != 1 { 93 continue 94 } 95 var works []int 96 nextType: 97 for typ1, algs1 := range allAlgs { 98 var selection []algDesc 99 for _, x := range rand.Perm(len(algs1)) { 100 if len(algs1[x].args) != 0 { 101 continue 102 } 103 selection = append(selection, algs1[x]) 104 if len(selection) == 10 { 105 break 106 } 107 } 108 for _, alg1 := range selection { 109 name := fmt.Sprintf("%v(%v)", alg.name, alg1.name) 110 ok, _ := testAlg(t, typ.name, name) 111 if ok { 112 works = append(works, typ1) 113 continue nextType 114 } 115 } 116 } 117 if len(works) == 1 && works[0] == alg.args[0] { 118 continue 119 } 120 t.Errorf("FAIL\t%10v\t%v\tclaimed %v works with %v", 121 typ.name, alg.name, alg.args[0], works) 122 } 123 } 124} 125 126// TestTemplateAlg2 tests creation of all templates with 2 argument. 127func TestTemplateAlg2(t *testing.T) { 128 algTest(t) 129 // Can't afford to test all permutations of 2 algorithms, 130 // 20 algorithm pairs for each type pair and use them. 131 selections := make(map[int][]int) 132 for typ1, algs1 := range allAlgs { 133 for typ2, algs2 := range allAlgs { 134 var pairs []int 135 for i1, alg1 := range algs1 { 136 if len(alg1.args) != 0 { 137 continue 138 } 139 for i2, alg2 := range algs2 { 140 if len(alg2.args) != 0 { 141 continue 142 } 143 pairs = append(pairs, i1*1000+i2) 144 } 145 } 146 var selection []int 147 for _, x := range rand.Perm(len(pairs)) { 148 selection = append(selection, pairs[x]) 149 if len(selection) > 20 { 150 break 151 } 152 } 153 selections[typ1*1000+typ2] = selection 154 } 155 } 156 for _, typ := range allTypes { 157 for _, alg := range allAlgs[typ.typ] { 158 if len(alg.args) != 2 { 159 continue 160 } 161 for typ1, algs1 := range allAlgs { 162 for typ2, algs2 := range allAlgs { 163 selection := selections[typ1*1000+typ2] 164 for _, x := range selection { 165 alg1 := algs1[x/1000] 166 alg2 := algs2[x%1000] 167 name := fmt.Sprintf("%v(%v,%v)", 168 alg.name, alg1.name, alg2.name) 169 if ok, _ := testAlg(t, typ.name, name); ok { 170 t.Logf("%10v\t%v\tclaimed %v works with %v/%v (%v)", 171 typ.name, alg.name, alg.args, typ1, typ2, name) 172 break 173 } 174 } 175 } 176 } 177 } 178 } 179} 180 181type sockaddrAlg struct { 182 family uint16 183 typ [14]byte 184 feat uint32 185 mask uint32 186 name [64]byte 187} 188 189func testAlg(t *testing.T, typ, name string) (ok, skip bool) { 190 const AF_ALG = 0x26 191 addr := &sockaddrAlg{ 192 family: AF_ALG, 193 feat: 0, 194 mask: 0, 195 } 196 if len(typ) >= int(unsafe.Sizeof(addr.typ)) || 197 len(name) >= int(unsafe.Sizeof(addr.name)) { 198 return false, true 199 } 200 for i := 0; i < len(typ); i++ { 201 addr.typ[i] = typ[i] 202 } 203 for i := 0; i < len(name); i++ { 204 addr.name[i] = name[i] 205 } 206 sock, err := syscall.Socket(AF_ALG, syscall.SOCK_SEQPACKET, 0) 207 if err != nil { 208 t.Fatalf("failed to create AF_ALG socket: %v", err) 209 } 210 defer syscall.Close(sock) 211 _, _, errno := syscall.Syscall(syscall.SYS_BIND, uintptr(sock), 212 uintptr(unsafe.Pointer(addr)), unsafe.Sizeof(*addr)) 213 if errno != 0 { 214 return false, false 215 } 216 return true, false 217} 218