You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
4.9 KiB
172 lines
4.9 KiB
// 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...) |
|
} |
|
}
|
|
|