// Code generated by cmd/cgo; DO NOT EDIT.

//line /usr/lib/golang/src/crypto/internal/boring/boring.go:1:1
// 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.

// +build linux
// +build !android
// +build !no_openssl
// +build !cmd_go_bootstrap
// +build !msan

package boring

// #include "goboringcrypto.h"
// #cgo LDFLAGS: -lcrypto
import _ "unsafe"
import (
	"crypto/internal/boring/sig"
	"io/ioutil"
	"math/big"
	"os"
	"runtime"
)

const (
	fipsOn  = _Ctype_int(1)
	fipsOff = _Ctype_int(0)
)

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

func init() {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	// Check to see if the system is running in FIPS mode, if so
	// enable "boring" mode to call into OpenSSL for FIPS compliance.
	if systemFIPSEnabled() {
		enableBoringFIPSMode()
		if !fipsModeEnabled() {
			panic("boringcrypto: not in FIPS mode")
		}
	}
	sig.BoringCrypto()
}

func enableBoringFIPSMode() {
	enabled = true

	if (_Cfunc__goboringcrypto_OPENSSL_thread_setup)() != 1 {
		panic("boringcrypto: OpenSSL thread setup failed")
	}
	// By setting FIPS mode on, the power on self test will run.
	if (_Cfunc__goboringcrypto_FIPS_mode_set)(fipsOn) != fipsOn {
		panic("boringcrypto: not in FIPS mode")
	}
}

func fipsModeEnabled() bool {
	return (_Cfunc__goboringcrypto_FIPS_mode)() == fipsOn
}

func systemFIPSEnabled() bool {
	var f *os.File
	defer func() {
		if f != nil {
			f.Close()
		}
	}()
	_, err := os.Stat("/etc/system-fips")
	if err != nil {
		return false
	}
	f, err = os.Open("/proc/sys/crypto/fips_enabled")
	if err != nil {
		return false
	}
	var b []byte
	b, err = ioutil.ReadAll(f)
	if err != nil {
		return false
	}
	return string(b) == "1"
}

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

// provided by runtime to avoid os import
func runtime_arg0() string

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 BoringCrypto is in use. It panics.
func UnreachableExceptTests() {
	name := runtime_arg0()
	// If BoringCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well.
	if Enabled() && !hasSuffix(name, "_test") && !hasSuffix(name, ".test") {
		println("boringcrypto: unexpected code execution in", name)
		panic("boringcrypto: invalid code execution")
	}
}

type fail string

func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }

func bigToBN(x *big.Int) *_Ctype_struct_bignum_st {
	raw := x.Bytes()
	return (_Cfunc__goboringcrypto_BN_bin2bn)(base(raw), _Ctype_size_t(len(raw)), nil)
}

func bnToBig(bn *_Ctype_struct_bignum_st) *big.Int {
	raw := make([]byte, func(_cgo0 *_Ctype_struct_bignum_st) _Ctype_uint {;	_cgoCheckPointer(_cgo0);	return (_Cfunc__goboringcrypto_BN_num_bytes)(_cgo0);}(bn))
	n := func(_cgo0 *_Ctype_struct_bignum_st, _cgo1 *_Ctype_uint8_t) _Ctype_size_t {;	_cgoCheckPointer(_cgo0);	return (_Cfunc__goboringcrypto_BN_bn2bin)(_cgo0, _cgo1);}(bn, base(raw))
	return new(big.Int).SetBytes(raw[:n])
}

func bigToBn(bnp **_Ctype_struct_bignum_st, b *big.Int) bool {
	if *bnp != nil {
		func(_cgo0 *_Ctype_struct_bignum_st) {;	_cgoCheckPointer(_cgo0);	(_Cfunc__goboringcrypto_BN_free)(_cgo0);}(*bnp)
		*bnp = nil
	}
	if b == nil {
		return true
	}
	raw := b.Bytes()
	bn := (_Cfunc__goboringcrypto_BN_bin2bn)(base(raw), _Ctype_size_t(len(raw)), nil)
	if bn == nil {
		return false
	}
	*bnp = bn
	return true
}
