Skip to content

Commit

Permalink
create crypto/internal/backend package
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Jan 12, 2022
1 parent a18476b commit 2cc8bd5
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/crypto/internal/backend/backend_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2017 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 backend

import (
"testing"
)

// Test that func init does not panic.
func TestInit(t *testing.T) {}

// Test that Unreachable panics.
func TestUnreachable(t *testing.T) {
defer func() {
if Enabled {
if err := recover(); err == nil {
t.Fatal("expected Unreachable to panic")
}
} else {
if err := recover(); err != nil {
t.Fatalf("expected Unreachable to be a no-op")
}
}
}()
Unreachable()
}

// Test that UnreachableExceptTests does not panic (this is a test).
func TestUnreachableExceptTests(t *testing.T) {
UnreachableExceptTests()
}
112 changes: 112 additions & 0 deletions src/crypto/internal/backend/nobackend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2017 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.

//go:build !linux || !cgo || android || cmd_go_bootstrap || msan || no_openssl
// +build !linux !cgo android cmd_go_bootstrap msan no_openssl

package backend

import (
"crypto"
"crypto/cipher"
"crypto/internal/boring/sig"
"hash"
"math/big"
)

const Enabled = false

// Unreachable marks code that should be unreachable
// when OpenSSLCrypto is in use. It is a no-op without OpenSSLCrypto.
func Unreachable() {
// Code that's unreachable when using OpenSSLCrypto
// is exactly the code we want to detect for reporting
// standard Go crypto.
sig.StandardCrypto()
}

// UnreachableExceptTests marks code that should be unreachable
// when OpenSSLCrypto is in use. It is a no-op without OpenSSLCrypto.
func UnreachableExceptTests() {}

type randReader int

func (randReader) Read(b []byte) (int, error) { panic("opensslcrypto: not available") }

const RandReader = randReader(0)

func NewSHA1() hash.Hash { panic("opensslcrypto: not available") }
func NewSHA224() hash.Hash { panic("opensslcrypto: not available") }
func NewSHA256() hash.Hash { panic("opensslcrypto: not available") }
func NewSHA384() hash.Hash { panic("opensslcrypto: not available") }
func NewSHA512() hash.Hash { panic("opensslcrypto: not available") }

func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("opensslcrypto: not available") }

func NewAESCipher(key []byte) (cipher.Block, error) { panic("opensslcrypto: not available") }

type PublicKeyECDSA struct{ _ int }
type PrivateKeyECDSA struct{ _ int }

func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) {
panic("opensslcrypto: not available")
}
func NewPrivateKeyECDSA(curve string, X, Y, D *big.Int) (*PrivateKeyECDSA, error) {
panic("opensslcrypto: not available")
}
func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) {
panic("opensslcrypto: not available")
}
func SignECDSA(priv *PrivateKeyECDSA, hash []byte) (r, s *big.Int, err error) {
panic("opensslcrypto: not available")
}
func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool {
panic("opensslcrypto: not available")
}

type PublicKeyRSA struct{ _ int }
type PrivateKeyRSA struct{ _ int }

func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) {
panic("opensslcrypto: not available")
}
func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) {
panic("opensslcrypto: not available")
}
func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) {
panic("opensslcrypto: not available")
}
func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {
panic("opensslcrypto: not available")
}
func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) {
panic("opensslcrypto: not available")
}
func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error {
panic("opensslcrypto: not available")
}
func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error {
panic("opensslcrypto: not available")
}
132 changes: 132 additions & 0 deletions src/crypto/internal/backend/openssl_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright 2017 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.

//go:build linux && !android && !no_openssl && !cmd_go_bootstrap && !msan
// +build linux,!android,!no_openssl,!cmd_go_bootstrap,!msan

// Package openssl provides access to OpenSSLCrypto implementation functions.
// Check the variable Enabled to find out whether OpenSSLCrypto is available.
// If OpenSSLCrypto is not available, the functions in this package all panic.
package backend

import (
"crypto/internal/backend/internal/openssl"
"crypto/internal/boring/sig"
"errors"
"os"
"strings"
)

// Enabled controls whether FIPS crypto is enabled.
var Enabled = false

func init() {
if !needFIPS() {
return
}
err := openssl.Init()
if err != nil {
panic(err)
}

if !openssl.FIPS() {
if err = openssl.SetFIPS(true); err != nil {
panic(err)
}
}

Enabled = true
sig.BoringCrypto()
}

func needFIPS() bool {
// TODO: use runtime instead of os.
// https://github.com/microsoft/go/issues/360
if os.Getenv("GOLANG_FIPS") == "1" {
// Opt-in to FIPS mode regardless of Linux kernel mode.
return true
}
if os.Getenv("GOLANG_FIPS") == "0" {
// Opt-out to FIPS mode regardless of Linux kernel mode.
return false
}
// Check if Linux kernel is booted in FIPS mode.
buf, err := os.ReadFile("/proc/sys/crypto/fips_enabled")
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return false
}
// If there is an error reading we could either panic or assume FIPS is not enabled.
// Panicking would be too disruptive for apps that don't require FIPS.
// If an app wants to be 100% sure that is running in FIPS mode
// it should use boring.Enabled() or GOLANG_FIPS=1.
return false
}
return strings.TrimSpace(string(buf)) == "1"
}

// Unreachable marks code that should be unreachable
// when OpenSSLCrypto is in use. It panics only when
// the system is in FIPS mode.
func Unreachable() {
if Enabled {
panic("opensslcrypto: invalid code execution")
}
}

func hasSuffix(s, t string) bool {
return len(s) > len(t) && s[len(s)-len(t):] == t
}

// UnreachableExceptTests marks code that should be unreachable
// when OpenSSLCrypto is in use. It panics.
func UnreachableExceptTests() {
// TODO: use runtime instead of os.
// https://github.com/microsoft/go/issues/360
name := os.Args[0]
// If OpenSSLCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well.
if Enabled && !hasSuffix(name, "_test") && !hasSuffix(name, ".test") {
println("opensslcrypto: unexpected code execution in", name)
panic("opensslcrypto: invalid code execution")
}
}

const RandReader = openssl.RandReader

var NewSHA1 = openssl.NewSHA1
var NewSHA224 = openssl.NewSHA224
var NewSHA256 = openssl.NewSHA256
var NewSHA384 = openssl.NewSHA384
var NewSHA512 = openssl.NewSHA512

var NewHMAC = openssl.NewHMAC

var NewAESCipher = openssl.NewAESCipher

type PublicKeyECDSA = openssl.PublicKeyECDSA
type PrivateKeyECDSA = openssl.PrivateKeyECDSA

var GenerateKeyECDSA = openssl.GenerateKeyECDSA
var NewPrivateKeyECDSA = openssl.NewPrivateKeyECDSA
var NewPublicKeyECDSA = openssl.NewPublicKeyECDSA
var SignECDSA = openssl.SignECDSA
var SignMarshalECDSA = openssl.SignMarshalECDSA
var VerifyECDSA = openssl.VerifyECDSA

type PublicKeyRSA = openssl.PublicKeyRSA
type PrivateKeyRSA = openssl.PrivateKeyRSA

var DecryptRSAOAEP = openssl.DecryptRSAOAEP
var DecryptRSAPKCS1 = openssl.DecryptRSAPKCS1
var DecryptRSANoPadding = openssl.DecryptRSANoPadding
var EncryptRSAOAEP = openssl.EncryptRSAOAEP
var EncryptRSAPKCS1 = openssl.EncryptRSAPKCS1
var EncryptRSANoPadding = openssl.EncryptRSANoPadding
var GenerateKeyRSA = openssl.GenerateKeyRSA
var NewPrivateKeyRSA = openssl.NewPrivateKeyRSA
var NewPublicKeyRSA = openssl.NewPublicKeyRSA
var SignRSAPKCS1v15 = openssl.SignRSAPKCS1v15
var SignRSAPSS = openssl.SignRSAPSS
var VerifyRSAPKCS1v15 = openssl.VerifyRSAPKCS1v15
var VerifyRSAPSS = openssl.VerifyRSAPSS

0 comments on commit 2cc8bd5

Please sign in to comment.