package main import ( "context" "fmt" "io" "os" "time" "github.com/pkg/errors" "github.com/dustin/go-humanize" "github.com/hairyhenderson/go-onerng" "github.com/spf13/cobra" ) func readCmd(ctx context.Context) *cobra.Command { readOut := "" disableAvalanche := false enableRF := false disableWhitener := false enableAESWhiten := true count := int64(-1) cmd := &cobra.Command{ Use: "read", Short: "read some random data from the OneRNG", RunE: func(cmd *cobra.Command, args []string) error { o := &onerng.OneRNG{Path: opts.Device} err := o.Init(ctx) if err != nil { return errors.Wrapf(err, "init failed") } // set flags based on commandline options flags := onerng.Default if disableAvalanche { flags |= onerng.DisableAvalanche } if enableRF { flags |= onerng.EnableRF } if disableWhitener { flags |= onerng.DisableWhitener } // waste some entropy... devNull, err := os.OpenFile("/dev/null", os.O_WRONLY, 0200) if err != nil { return err } _, err = o.Read(ctx, devNull, 10*1024, flags) if err != nil { fmt.Fprintf(os.Stderr, "warning: entropy wasteage failed or incomplete, continuing anyway\n") } var out io.WriteCloser if readOut == "-" { out = os.Stdout } else { out, err = os.OpenFile(readOut, os.O_RDWR|os.O_CREATE, 0644) if err != nil { return err } } if enableAESWhiten { out, err = o.AESWhitener(ctx, out) if err != nil { return err } } start := time.Now() written, err := o.Read(ctx, out, count, flags) delta := time.Since(start) rate := float64(written) / delta.Seconds() fmt.Fprintf(os.Stderr, "%s written in %s (%s/s)\n", humanize.Bytes(uint64(written)), delta, humanize.Bytes(uint64(rate))) return err }, } cmd.Flags().StringVarP(&readOut, "out", "o", "-", "output file for data (use - for stdout)") cmd.Flags().BoolVar(&disableAvalanche, "disable-avalanche", false, "Disable noise generation from the Avalanche Diode") cmd.Flags().BoolVar(&enableRF, "enable-rf", false, "Enable noise generation from RF") cmd.Flags().BoolVar(&disableWhitener, "disable-whitener", false, "Disable the on-board CRC16 generator") cmd.Flags().Int64VarP(&count, "count", "n", -1, "Read only N bytes (use -1 for unlimited)") cmd.Flags().BoolVar(&enableAESWhiten, "aes-whitener", true, "encrypt with AES-128 to 'whiten' the input stream with a random key obtained from the OneRNG") return cmd }