github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/boring/boring.go (about) 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 && !cmd_go_bootstrap && !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 "math/bits" 20 "unsafe" 21 ) 22 23 const available = true 24 25 func init() { 26 C._goboringcrypto_BORINGSSL_bcm_power_on_self_test() 27 if C._goboringcrypto_FIPS_mode() != 1 { 28 panic("boringcrypto: not in FIPS mode") 29 } 30 sig.BoringCrypto() 31 } 32 33 // Unreachable marks code that should be unreachable 34 // when BoringCrypto is in use. It panics. 35 func Unreachable() { 36 panic("boringcrypto: invalid code execution") 37 } 38 39 // provided by runtime to avoid os import. 40 func runtime_arg0() string 41 42 func hasSuffix(s, t string) bool { 43 return len(s) > len(t) && s[len(s)-len(t):] == t 44 } 45 46 // UnreachableExceptTests marks code that should be unreachable 47 // when BoringCrypto is in use. It panics. 48 func UnreachableExceptTests() { 49 name := runtime_arg0() 50 // If BoringCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well. 51 if !hasSuffix(name, "_test") && !hasSuffix(name, ".test") { 52 println("boringcrypto: unexpected code execution in", name) 53 panic("boringcrypto: invalid code execution") 54 } 55 } 56 57 type fail string 58 59 func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" } 60 61 func wbase(b BigInt) *C.uint8_t { 62 if len(b) == 0 { 63 return nil 64 } 65 return (*C.uint8_t)(unsafe.Pointer(&b[0])) 66 } 67 68 const wordBytes = bits.UintSize / 8 69 70 func bigToBN(x BigInt) *C.GO_BIGNUM { 71 return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil) 72 } 73 74 func bytesToBN(x []byte) *C.GO_BIGNUM { 75 return C._goboringcrypto_BN_bin2bn((*C.uint8_t)(&x[0]), C.size_t(len(x)), nil) 76 } 77 78 func bnToBig(bn *C.GO_BIGNUM) BigInt { 79 x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes) 80 if C._goboringcrypto_BN_bn2le_padded(wbase(x), C.size_t(len(x)*wordBytes), bn) == 0 { 81 panic("boringcrypto: bignum conversion failed") 82 } 83 return x 84 } 85 86 func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool { 87 if *bnp != nil { 88 C._goboringcrypto_BN_free(*bnp) 89 *bnp = nil 90 } 91 if b == nil { 92 return true 93 } 94 bn := bigToBN(b) 95 if bn == nil { 96 return false 97 } 98 *bnp = bn 99 return true 100 } 101 102 // noescape hides a pointer from escape analysis. noescape is 103 // the identity function but escape analysis doesn't think the 104 // output depends on the input. noescape is inlined and currently 105 // compiles down to zero instructions. 106 // USE CAREFULLY! 107 // 108 //go:nosplit 109 func noescape(p unsafe.Pointer) unsafe.Pointer { 110 x := uintptr(p) 111 return unsafe.Pointer(x ^ 0) 112 } 113 114 var zero byte 115 116 // addr converts p to its base addr, including a noescape along the way. 117 // If p is nil, addr returns a non-nil pointer, so that the result can always 118 // be dereferenced. 119 // 120 //go:nosplit 121 func addr(p []byte) *byte { 122 if len(p) == 0 { 123 return &zero 124 } 125 return (*byte)(noescape(unsafe.Pointer(&p[0]))) 126 }