File: sio.go

package info (click to toggle)
golang-github-secure-io-sio-go 0.3.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 248 kB
  • sloc: sh: 16; makefile: 3
file content (90 lines) | stat: -rw-r--r-- 2,430 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright (c) 2019 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.

// Package sioutil implements some I/O utility functions.
package sioutil

import (
	"crypto/rand"
	"io"

	"golang.org/x/sys/cpu"
)

type nopCloser struct {
	io.Writer
}

func (nopCloser) Close() error { return nil }

// NopCloser returns a WriteCloser that wraps w
// and implements Close as a no-op.
func NopCloser(w io.Writer) io.WriteCloser {
	return nopCloser{w}
}

// NativeAES returns true when the executing CPU
// provides AES-GCM hardware instructions and
// an optimized assembler implementation is
// available.
//
// It is strongly recommended to only use AES-GCM
// when NativeAES() returns true. Otherwise, the
// AES-GCM implementation may be vulnerable to
// timing attacks.
// See: https://golang.org/pkg/crypto/aes
func NativeAES() bool {
	if cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ {
		return true
	}
	if cpu.ARM64.HasAES {
		return true
	}

	// Go 1.14 introduces an AES-GCM asm implementation
	// for PPC64le. Therefore, we have to use build tags
	// to determine whether we're compiling for PPC64 and
	// use Go 1.14 (or newer).
	// TODO(aead): Once we drop Go 1.13 support
	// (bump go version in go.mod) we can remove
	// pcc64-related build tags again.
	if ppcHasAES {
		return true
	}

	// On s390x, aes.NewCipher(...) returns a type
	// that provides AES asm implementations only
	// if all (CBC, CTR and GCM) AES hardware
	// instructions are available.
	// See: https://golang.org/src/crypto/aes/cipher_s390x.go#L39
	return cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
		(cpu.S390X.HasAESGCM || cpu.S390X.HasGHASH)
}

// Random returns n randomly generated bytes if
// and only if err == nil.
//
// Random uses crypto/rand.Reader as cryptographically
// secure random number generator (CSPRNG).
func Random(n int) (b []byte, err error) {
	b = make([]byte, n)
	if _, err = io.ReadFull(rand.Reader, b); err != nil {
		return nil, err
	}
	return b, nil
}

// MustRandom returns n randomly generated bytes.
// It panics if it fails to read n random bytes
// from its entropy source.
//
// MustRandom uses crypto/rand.Reader as cryptographically
// secure random number generator (CSPRNG).
func MustRandom(n int) []byte {
	b, err := Random(n)
	if err != nil {
		panic("sioutil: out of entropy: " + err.Error())
	}
	return b
}