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

//line /builddir/build/BUILD/go-go-1.12.12-4-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"
	"errors"
	"math/big"
	"os"
	"runtime"
	"strings"
)

const (
	fipsOn  =  /*line :27:12*/_Ctype_int /*line :27:17*/(1)
	fipsOff =  /*line :28:12*/_Ctype_int /*line :28:17*/(0)
)

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

// When this variable is true, the go crypto API will panic when a caller
// tries to use the API in a non-compliant manner.  When this is false, the
// go crytpo API will allow existing go crypto APIs to be used even
// if they aren't FIPS compliant.  However, all the unerlying crypto operations
// will still be done by OpenSSL.
var strictFIPS = false

func init() {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	// Check if we can `dlopen` OpenSSL
	if ( /*line :46:5*/_Cfunc__goboringcrypto_DLOPEN_OPENSSL /*line :46:36*/)() == ( /*line :46:43*/_Cmacro_NULL() /*line :46:48*/) {
		return
	}

	// Initialize the OpenSSL library.
	( /*line :51:2*/_Cfunc__goboringcrypto_OPENSSL_setup /*line :51:32*/)()

	// 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 ( /*line :64:5*/_Cfunc__goboringcrypto_OPENSSL_thread_setup /*line :64:42*/)() != 1 {
		panic("boringcrypto: OpenSSL thread setup failed")
	}
	fipstls.Force()
}

func fipsModeEnabled() bool {
	return os.Getenv("GOLANG_FIPS") == "1" ||
		( /*line :72:3*/_Cfunc__goboringcrypto_FIPS_mode /*line :72:29*/)() == fipsOn
}

var randstub bool

func RandStubbed() bool {
	return randstub
}

func StubOpenSSLRand() {
	if !randstub {
		randstub = true
		( /*line :84:3*/_Cfunc__goboringcrypto_stub_openssl_rand /*line :84:37*/)()
	}
}

func RestoreOpenSSLRand() {
	if randstub {
		randstub = false
		( /*line :91:3*/_Cfunc__goboringcrypto_restore_openssl_rand /*line :91:40*/)()
	}
}

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

func PanicIfStrictFIPS(msg string) {
	if os.Getenv("GOLANG_STRICT_FIPS") == "1" || strictFIPS {
		panic(msg)
	}
}

func NewOpenSSLError(msg string) error {
	var b strings.Builder
	var e  /*line :130:8*/_Ctype_ulong /*line :130:15*/

	b.WriteString(msg)
	b.WriteString("\nopenssl error(s):\n")

	for {
		e = ( /*line :136:7*/_Cfunc__goboringcrypto_internal_ERR_get_error /*line :136:46*/)()
		if e == 0 {
			break
		}
		var buf [256]byte
		( /*line :141:3*/_Cfunc__goboringcrypto_internal_ERR_error_string_n /*line :141:47*/)(e, base(buf[:]), 256)
		b.Write(buf[:])
		b.WriteByte('\n')
	}
	return errors.New(b.String())
}

type fail string

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

func bigToBN(x *big.Int) * /*line :152:27*/_Ctype_struct_bignum_st /*line :152:38*/ {
	raw := x.Bytes()
	return ( /*line :154:9*/_Cfunc__goboringcrypto_BN_bin2bn /*line :154:35*/)(base(raw),  /*line :154:48*/_Ctype_size_t /*line :154:56*/(len(raw)), nil)
}

func bnToBig(bn * /*line :157:18*/_Ctype_struct_bignum_st /*line :157:29*/) *big.Int {
	raw := make([]byte, func() _Ctype_uint{ _cgo0 := /*line :158:53*/bn; _cgoCheckPointer(_cgo0); return _Cfunc__goboringcrypto_BN_num_bytes(_cgo0); }())
	n := func() _Ctype_size_t{ _cgo0 := /*line :159:35*/bn; var _cgo1 *_Ctype_uint8_t = /*line :159:39*/base(raw); _cgoCheckPointer(_cgo0); return _Cfunc__goboringcrypto_BN_bn2bin(_cgo0, _cgo1); }()
	return new(big.Int).SetBytes(raw[:n])
}

func bigToBn(bnp ** /*line :163:20*/_Ctype_struct_bignum_st /*line :163:31*/, b *big.Int) bool {
	if *bnp != nil {
		func() { _cgo0 := /*line :165:29*/*bnp; _cgoCheckPointer(_cgo0); _Cfunc__goboringcrypto_BN_free(_cgo0); }()
		*bnp = nil
	}
	if b == nil {
		return true
	}
	raw := b.Bytes()
	bn := ( /*line :172:8*/_Cfunc__goboringcrypto_BN_bin2bn /*line :172:34*/)(base(raw),  /*line :172:47*/_Ctype_size_t /*line :172:55*/(len(raw)), nil)
	if bn == nil {
		return false
	}
	*bnp = bn
	return true
}
