...

Source file src/crypto/internal/boring/boring.go

Documentation: crypto/internal/boring

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build boringcrypto && linux && (amd64 || arm64) && !android && !msan
     6  
     7  package boring
     8  
     9  /*
    10  // goboringcrypto_linux_amd64.syso references pthread functions.
    11  #cgo LDFLAGS: "-pthread"
    12  
    13  #include "goboringcrypto.h"
    14  */
    15  import "C"
    16  import (
    17  	"crypto/internal/boring/sig"
    18  	_ "crypto/internal/boring/syso"
    19  	"internal/stringslite"
    20  	"math/bits"
    21  	"unsafe"
    22  )
    23  
    24  const available = true
    25  
    26  func init() {
    27  	C._goboringcrypto_BORINGSSL_bcm_power_on_self_test()
    28  	if C._goboringcrypto_FIPS_mode() != 1 {
    29  		panic("boringcrypto: not in FIPS mode")
    30  	}
    31  	sig.BoringCrypto()
    32  }
    33  
    34  // Unreachable marks code that should be unreachable
    35  // when BoringCrypto is in use. It panics.
    36  func Unreachable() {
    37  	panic("boringcrypto: invalid code execution")
    38  }
    39  
    40  // provided by runtime to avoid os import.
    41  func runtime_arg0() string
    42  
    43  // UnreachableExceptTests marks code that should be unreachable
    44  // when BoringCrypto is in use. It panics.
    45  func UnreachableExceptTests() {
    46  	name := runtime_arg0()
    47  	// If BoringCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well.
    48  	if !stringslite.HasSuffix(name, "_test") && !stringslite.HasSuffix(name, ".test") {
    49  		println("boringcrypto: unexpected code execution in", name)
    50  		panic("boringcrypto: invalid code execution")
    51  	}
    52  }
    53  
    54  type fail string
    55  
    56  func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }
    57  
    58  func wbase(b BigInt) *C.uint8_t {
    59  	if len(b) == 0 {
    60  		return nil
    61  	}
    62  	return (*C.uint8_t)(unsafe.Pointer(&b[0]))
    63  }
    64  
    65  const wordBytes = bits.UintSize / 8
    66  
    67  func bigToBN(x BigInt) *C.GO_BIGNUM {
    68  	return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil)
    69  }
    70  
    71  func bytesToBN(x []byte) *C.GO_BIGNUM {
    72  	return C._goboringcrypto_BN_bin2bn((*C.uint8_t)(&x[0]), C.size_t(len(x)), nil)
    73  }
    74  
    75  func bnToBig(bn *C.GO_BIGNUM) BigInt {
    76  	x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
    77  	if C._goboringcrypto_BN_bn2le_padded(wbase(x), C.size_t(len(x)*wordBytes), bn) == 0 {
    78  		panic("boringcrypto: bignum conversion failed")
    79  	}
    80  	return x
    81  }
    82  
    83  func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool {
    84  	if *bnp != nil {
    85  		C._goboringcrypto_BN_free(*bnp)
    86  		*bnp = nil
    87  	}
    88  	if b == nil {
    89  		return true
    90  	}
    91  	bn := bigToBN(b)
    92  	if bn == nil {
    93  		return false
    94  	}
    95  	*bnp = bn
    96  	return true
    97  }
    98  
    99  // noescape hides a pointer from escape analysis.  noescape is
   100  // the identity function but escape analysis doesn't think the
   101  // output depends on the input.  noescape is inlined and currently
   102  // compiles down to zero instructions.
   103  // USE CAREFULLY!
   104  //
   105  //go:nosplit
   106  func noescape(p unsafe.Pointer) unsafe.Pointer {
   107  	x := uintptr(p)
   108  	return unsafe.Pointer(x ^ 0)
   109  }
   110  
   111  var zero byte
   112  
   113  // addr converts p to its base addr, including a noescape along the way.
   114  // If p is nil, addr returns a non-nil pointer, so that the result can always
   115  // be dereferenced.
   116  //
   117  //go:nosplit
   118  func addr(p []byte) *byte {
   119  	if len(p) == 0 {
   120  		return &zero
   121  	}
   122  	return (*byte)(noescape(unsafe.Pointer(&p[0])))
   123  }
   124  

View as plain text