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

//line /builddir/build/BUILD/go-go-1.11.6-5-openssl-fips/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: -ldl
import _ "unsafe"
import (
	"crypto/internal/boring/fipstls"
	"crypto/internal/boring/sig"
	"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 if we can `dlopen` OpenSSL
	if (_Cfunc__goboringcrypto_DLOPEN_OPENSSL)() == (_Cmacro_NULL()) {
		return
	}

	// Initialize the OpenSSL library.
	(_Cfunc__goboringcrypto_OPENSSL_setup)()

	// Check to see if the system is running in FIPS mode, if so
	// enable "boring" mode to call into OpenSSL for FIPS compliance.
	if fipsModeEnabled() {
		enableBoringFIPSMode()
	}
	sig.BoringCrypto()
}

func enableBoringFIPSMode() {
	enabled = true

	if (_Cfunc__goboringcrypto_OPENSSL_thread_setup)() != 1 {
		panic("boringcrypto: OpenSSL thread setup failed")
	}
	fipstls.Force()
}

func fipsModeEnabled() bool {
	return os.Getenv("GOLANG_FIPS") == "1" ||
		(_Cfunc__goboringcrypto_FIPS_mode)() == fipsOn
}

var randstub bool

func RandStubbed() bool {
	return randstub
}

func StubOpenSSLRand() {
	if !randstub {
		randstub = true
		(_Cfunc__goboringcrypto_stub_openssl_rand)()
	}
}

func RestoreOpenSSLRand() {
	if randstub {
		randstub = false
		(_Cfunc__goboringcrypto_restore_openssl_rand)()
	}
}

// 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
}
