123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // 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...)
- }
- }
|