mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			173 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2020 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.
 | 
						|
 | 
						|
package cpu
 | 
						|
 | 
						|
const cacheLineSize = 256
 | 
						|
 | 
						|
func initOptions() {
 | 
						|
	options = []option{
 | 
						|
		{Name: "zarch", Feature: &S390X.HasZARCH, Required: true},
 | 
						|
		{Name: "stfle", Feature: &S390X.HasSTFLE, Required: true},
 | 
						|
		{Name: "ldisp", Feature: &S390X.HasLDISP, Required: true},
 | 
						|
		{Name: "eimm", Feature: &S390X.HasEIMM, Required: true},
 | 
						|
		{Name: "dfp", Feature: &S390X.HasDFP},
 | 
						|
		{Name: "etf3eh", Feature: &S390X.HasETF3EH},
 | 
						|
		{Name: "msa", Feature: &S390X.HasMSA},
 | 
						|
		{Name: "aes", Feature: &S390X.HasAES},
 | 
						|
		{Name: "aescbc", Feature: &S390X.HasAESCBC},
 | 
						|
		{Name: "aesctr", Feature: &S390X.HasAESCTR},
 | 
						|
		{Name: "aesgcm", Feature: &S390X.HasAESGCM},
 | 
						|
		{Name: "ghash", Feature: &S390X.HasGHASH},
 | 
						|
		{Name: "sha1", Feature: &S390X.HasSHA1},
 | 
						|
		{Name: "sha256", Feature: &S390X.HasSHA256},
 | 
						|
		{Name: "sha3", Feature: &S390X.HasSHA3},
 | 
						|
		{Name: "sha512", Feature: &S390X.HasSHA512},
 | 
						|
		{Name: "vx", Feature: &S390X.HasVX},
 | 
						|
		{Name: "vxe", Feature: &S390X.HasVXE},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// bitIsSet reports whether the bit at index is set. The bit index
 | 
						|
// is in big endian order, so bit index 0 is the leftmost bit.
 | 
						|
func bitIsSet(bits []uint64, index uint) bool {
 | 
						|
	return bits[index/64]&((1<<63)>>(index%64)) != 0
 | 
						|
}
 | 
						|
 | 
						|
// facility is a bit index for the named facility.
 | 
						|
type facility uint8
 | 
						|
 | 
						|
const (
 | 
						|
	// mandatory facilities
 | 
						|
	zarch  facility = 1  // z architecture mode is active
 | 
						|
	stflef facility = 7  // store-facility-list-extended
 | 
						|
	ldisp  facility = 18 // long-displacement
 | 
						|
	eimm   facility = 21 // extended-immediate
 | 
						|
 | 
						|
	// miscellaneous facilities
 | 
						|
	dfp    facility = 42 // decimal-floating-point
 | 
						|
	etf3eh facility = 30 // extended-translation 3 enhancement
 | 
						|
 | 
						|
	// cryptography facilities
 | 
						|
	msa  facility = 17  // message-security-assist
 | 
						|
	msa3 facility = 76  // message-security-assist extension 3
 | 
						|
	msa4 facility = 77  // message-security-assist extension 4
 | 
						|
	msa5 facility = 57  // message-security-assist extension 5
 | 
						|
	msa8 facility = 146 // message-security-assist extension 8
 | 
						|
	msa9 facility = 155 // message-security-assist extension 9
 | 
						|
 | 
						|
	// vector facilities
 | 
						|
	vx   facility = 129 // vector facility
 | 
						|
	vxe  facility = 135 // vector-enhancements 1
 | 
						|
	vxe2 facility = 148 // vector-enhancements 2
 | 
						|
)
 | 
						|
 | 
						|
// facilityList contains the result of an STFLE call.
 | 
						|
// Bits are numbered in big endian order so the
 | 
						|
// leftmost bit (the MSB) is at index 0.
 | 
						|
type facilityList struct {
 | 
						|
	bits [4]uint64
 | 
						|
}
 | 
						|
 | 
						|
// Has reports whether the given facilities are present.
 | 
						|
func (s *facilityList) Has(fs ...facility) bool {
 | 
						|
	if len(fs) == 0 {
 | 
						|
		panic("no facility bits provided")
 | 
						|
	}
 | 
						|
	for _, f := range fs {
 | 
						|
		if !bitIsSet(s.bits[:], uint(f)) {
 | 
						|
			return false
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
// function is the code for the named cryptographic function.
 | 
						|
type function uint8
 | 
						|
 | 
						|
const (
 | 
						|
	// KM{,A,C,CTR} function codes
 | 
						|
	aes128 function = 18 // AES-128
 | 
						|
	aes192 function = 19 // AES-192
 | 
						|
	aes256 function = 20 // AES-256
 | 
						|
 | 
						|
	// K{I,L}MD function codes
 | 
						|
	sha1     function = 1  // SHA-1
 | 
						|
	sha256   function = 2  // SHA-256
 | 
						|
	sha512   function = 3  // SHA-512
 | 
						|
	sha3_224 function = 32 // SHA3-224
 | 
						|
	sha3_256 function = 33 // SHA3-256
 | 
						|
	sha3_384 function = 34 // SHA3-384
 | 
						|
	sha3_512 function = 35 // SHA3-512
 | 
						|
	shake128 function = 36 // SHAKE-128
 | 
						|
	shake256 function = 37 // SHAKE-256
 | 
						|
 | 
						|
	// KLMD function codes
 | 
						|
	ghash function = 65 // GHASH
 | 
						|
)
 | 
						|
 | 
						|
// queryResult contains the result of a Query function
 | 
						|
// call. Bits are numbered in big endian order so the
 | 
						|
// leftmost bit (the MSB) is at index 0.
 | 
						|
type queryResult struct {
 | 
						|
	bits [2]uint64
 | 
						|
}
 | 
						|
 | 
						|
// Has reports whether the given functions are present.
 | 
						|
func (q *queryResult) Has(fns ...function) bool {
 | 
						|
	if len(fns) == 0 {
 | 
						|
		panic("no function codes provided")
 | 
						|
	}
 | 
						|
	for _, f := range fns {
 | 
						|
		if !bitIsSet(q.bits[:], uint(f)) {
 | 
						|
			return false
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
func doinit() {
 | 
						|
	initS390Xbase()
 | 
						|
 | 
						|
	// We need implementations of stfle, km and so on
 | 
						|
	// to detect cryptographic features.
 | 
						|
	if !haveAsmFunctions() {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// optional cryptographic functions
 | 
						|
	if S390X.HasMSA {
 | 
						|
		aes := []function{aes128, aes192, aes256}
 | 
						|
 | 
						|
		// cipher message
 | 
						|
		km, kmc := kmQuery(), kmcQuery()
 | 
						|
		S390X.HasAES = km.Has(aes...)
 | 
						|
		S390X.HasAESCBC = kmc.Has(aes...)
 | 
						|
		if S390X.HasSTFLE {
 | 
						|
			facilities := stfle()
 | 
						|
			if facilities.Has(msa4) {
 | 
						|
				kmctr := kmctrQuery()
 | 
						|
				S390X.HasAESCTR = kmctr.Has(aes...)
 | 
						|
			}
 | 
						|
			if facilities.Has(msa8) {
 | 
						|
				kma := kmaQuery()
 | 
						|
				S390X.HasAESGCM = kma.Has(aes...)
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// compute message digest
 | 
						|
		kimd := kimdQuery() // intermediate (no padding)
 | 
						|
		klmd := klmdQuery() // last (padding)
 | 
						|
		S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
 | 
						|
		S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
 | 
						|
		S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
 | 
						|
		S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
 | 
						|
		sha3 := []function{
 | 
						|
			sha3_224, sha3_256, sha3_384, sha3_512,
 | 
						|
			shake128, shake256,
 | 
						|
		}
 | 
						|
		S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
 | 
						|
	}
 | 
						|
}
 |