mirror of
https://github.com/safing/portbase
synced 2025-04-22 02:09:09 +00:00
79 lines
1.6 KiB
Go
79 lines
1.6 KiB
Go
package random
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/aead/serpent"
|
|
"github.com/seehuhn/fortuna"
|
|
|
|
"github.com/safing/portbase/config"
|
|
"github.com/safing/portbase/modules"
|
|
)
|
|
|
|
var (
|
|
rng *fortuna.Generator
|
|
rngLock sync.Mutex
|
|
rngReady = false
|
|
rngCipherOption config.StringOption
|
|
|
|
shutdownSignal = make(chan struct{}, 0)
|
|
)
|
|
|
|
func init() {
|
|
modules.Register("random", prep, Start, stop)
|
|
|
|
config.Register(&config.Option{
|
|
Name: "RNG Cipher",
|
|
Key: "random/rng_cipher",
|
|
Description: "Cipher to use for the Fortuna RNG. Requires restart to take effect.",
|
|
ExpertiseLevel: config.ExpertiseLevelDeveloper,
|
|
OptType: config.OptTypeString,
|
|
ExternalOptType: "string list",
|
|
DefaultValue: "aes",
|
|
ValidationRegex: "^(aes|serpent)$",
|
|
})
|
|
rngCipherOption = config.GetAsString("random/rng_cipher", "aes")
|
|
}
|
|
|
|
func prep() error {
|
|
return nil
|
|
}
|
|
|
|
func newCipher(key []byte) (cipher.Block, error) {
|
|
cipher := rngCipherOption()
|
|
switch cipher {
|
|
case "aes":
|
|
return aes.NewCipher(key)
|
|
case "serpent":
|
|
return serpent.NewCipher(key)
|
|
default:
|
|
return nil, fmt.Errorf("unknown or unsupported cipher: %s", cipher)
|
|
}
|
|
}
|
|
|
|
// Start starts the RNG. Normally, this should be only called by the portbase/modules package.
|
|
func Start() (err error) {
|
|
rngLock.Lock()
|
|
defer rngLock.Unlock()
|
|
|
|
rng = fortuna.NewGenerator(newCipher)
|
|
rngReady = true
|
|
|
|
// random source: OS
|
|
go osFeeder()
|
|
|
|
// random source: goroutine ticks
|
|
go tickFeeder()
|
|
|
|
// full feeder
|
|
go fullFeeder()
|
|
|
|
return nil
|
|
}
|
|
|
|
func stop() error {
|
|
return nil
|
|
}
|