| // Copyright 2024 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Package impl is a registry of alternative implementations of cryptographic | |
| // primitives, to allow selecting them for testing. | |
| package impl | |
| import "strings" | |
| type implementation struct { | |
| Package string | |
| Name string | |
| Available bool | |
| Toggle *bool | |
| } | |
| var allImplementations []implementation | |
| // Register records an alternative implementation of a cryptographic primitive. | |
| // The implementation might be available or not based on CPU support. If | |
| // available is false, the implementation is unavailable and can't be tested on | |
| // this machine. If available is true, it can be set to false to disable the | |
| // implementation. If all alternative implementations but one are disabled, the | |
| // remaining one must be used (i.e. disabling one implementation must not | |
| // implicitly disable any other). Each package has an implicit base | |
| // implementation that is selected when all alternatives are unavailable or | |
| // disabled. pkg must be the package name, not path (e.g. "aes" not "crypto/aes"). | |
| func Register(pkg, name string, available *bool) { | |
| if strings.Contains(pkg, "/") { | |
| panic("impl: package name must not contain slashes") | |
| } | |
| allImplementations = append(allImplementations, implementation{ | |
| Package: pkg, | |
| Name: name, | |
| Available: *available, | |
| Toggle: available, | |
| }) | |
| } | |
| // Packages returns the list of all packages for which alternative | |
| // implementations are registered. | |
| func Packages() []string { | |
| var pkgs []string | |
| seen := make(map[string]bool) | |
| for _, i := range allImplementations { | |
| if !seen[i.Package] { | |
| pkgs = append(pkgs, i.Package) | |
| seen[i.Package] = true | |
| } | |
| } | |
| return pkgs | |
| } | |
| // List returns the names of all alternative implementations registered for the | |
| // given package, whether available or not. The implicit base implementation is | |
| // not included. | |
| func List(pkg string) []string { | |
| var names []string | |
| for _, i := range allImplementations { | |
| if i.Package == pkg { | |
| names = append(names, i.Name) | |
| } | |
| } | |
| return names | |
| } | |
| func available(pkg, name string) bool { | |
| for _, i := range allImplementations { | |
| if i.Package == pkg && i.Name == name { | |
| return i.Available | |
| } | |
| } | |
| panic("unknown implementation") | |
| } | |
| // Select disables all implementations for the given package except the one | |
| // with the given name. If name is empty, the base implementation is selected. | |
| // It returns whether the selected implementation is available. | |
| func Select(pkg, name string) bool { | |
| if name == "" { | |
| for _, i := range allImplementations { | |
| if i.Package == pkg { | |
| *i.Toggle = false | |
| } | |
| } | |
| return true | |
| } | |
| if !available(pkg, name) { | |
| return false | |
| } | |
| for _, i := range allImplementations { | |
| if i.Package == pkg { | |
| *i.Toggle = i.Name == name | |
| } | |
| } | |
| return true | |
| } | |
| func Reset(pkg string) { | |
| for _, i := range allImplementations { | |
| if i.Package == pkg { | |
| *i.Toggle = i.Available | |
| return | |
| } | |
| } | |
| } | |