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