github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/cpu/cpu_s390x.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 package cpu 6 7 const CacheLinePadSize = 256 8 9 // bitIsSet reports whether the bit at index is set. The bit index 10 // is in big endian order, so bit index 0 is the leftmost bit. 11 func bitIsSet(bits []uint64, index uint) bool { 12 return bits[index/64]&((1<<63)>>(index%64)) != 0 13 } 14 15 // function is the function code for the named function. 16 type function uint8 17 18 const ( 19 // KM{,A,C,CTR} function codes 20 aes128 function = 18 // AES-128 21 aes192 function = 19 // AES-192 22 aes256 function = 20 // AES-256 23 24 // K{I,L}MD function codes 25 sha1 function = 1 // SHA-1 26 sha256 function = 2 // SHA-256 27 sha512 function = 3 // SHA-512 28 29 // KLMD function codes 30 ghash function = 65 // GHASH 31 ) 32 33 // queryResult contains the result of a Query function 34 // call. Bits are numbered in big endian order so the 35 // leftmost bit (the MSB) is at index 0. 36 type queryResult struct { 37 bits [2]uint64 38 } 39 40 // Has reports whether the given functions are present. 41 func (q *queryResult) Has(fns ...function) bool { 42 if len(fns) == 0 { 43 panic("no function codes provided") 44 } 45 for _, f := range fns { 46 if !bitIsSet(q.bits[:], uint(f)) { 47 return false 48 } 49 } 50 return true 51 } 52 53 // facility is a bit index for the named facility. 54 type facility uint8 55 56 const ( 57 // mandatory facilities 58 zarch facility = 1 // z architecture mode is active 59 stflef facility = 7 // store-facility-list-extended 60 ldisp facility = 18 // long-displacement 61 eimm facility = 21 // extended-immediate 62 63 // miscellaneous facilities 64 dfp facility = 42 // decimal-floating-point 65 etf3eh facility = 30 // extended-translation 3 enhancement 66 67 // cryptography facilities 68 msa facility = 17 // message-security-assist 69 msa3 facility = 76 // message-security-assist extension 3 70 msa4 facility = 77 // message-security-assist extension 4 71 msa5 facility = 57 // message-security-assist extension 5 72 msa8 facility = 146 // message-security-assist extension 8 73 74 // vector facilities 75 ve1 facility = 135 // vector-enhancements 1 76 77 // Note: vx and highgprs are excluded because they require 78 // kernel support and so must be fetched from HWCAP. 79 ) 80 81 // facilityList contains the result of an STFLE call. 82 // Bits are numbered in big endian order so the 83 // leftmost bit (the MSB) is at index 0. 84 type facilityList struct { 85 bits [4]uint64 86 } 87 88 // Has reports whether the given facilities are present. 89 func (s *facilityList) Has(fs ...facility) bool { 90 if len(fs) == 0 { 91 panic("no facility bits provided") 92 } 93 for _, f := range fs { 94 if !bitIsSet(s.bits[:], uint(f)) { 95 return false 96 } 97 } 98 return true 99 } 100 101 // The following feature detection functions are defined in cpu_s390x.s. 102 // They are likely to be expensive to call so the results should be cached. 103 func stfle() facilityList 104 func kmQuery() queryResult 105 func kmcQuery() queryResult 106 func kmctrQuery() queryResult 107 func kmaQuery() queryResult 108 func kimdQuery() queryResult 109 func klmdQuery() queryResult 110 111 func doinit() { 112 options = []option{ 113 {Name: "zarch", Feature: &S390X.HasZArch}, 114 {Name: "stfle", Feature: &S390X.HasSTFLE}, 115 {Name: "ldisp", Feature: &S390X.HasLDisp}, 116 {Name: "msa", Feature: &S390X.HasMSA}, 117 {Name: "eimm", Feature: &S390X.HasEImm}, 118 {Name: "dfp", Feature: &S390X.HasDFP}, 119 {Name: "etf3eh", Feature: &S390X.HasETF3Enhanced}, 120 {Name: "vx", Feature: &S390X.HasVX}, 121 {Name: "ve1", Feature: &S390X.HasVE1}, 122 } 123 124 aes := []function{aes128, aes192, aes256} 125 facilities := stfle() 126 127 S390X.HasZArch = facilities.Has(zarch) 128 S390X.HasSTFLE = facilities.Has(stflef) 129 S390X.HasLDisp = facilities.Has(ldisp) 130 S390X.HasEImm = facilities.Has(eimm) 131 S390X.HasDFP = facilities.Has(dfp) 132 S390X.HasETF3Enhanced = facilities.Has(etf3eh) 133 S390X.HasMSA = facilities.Has(msa) 134 135 if S390X.HasMSA { 136 // cipher message 137 km, kmc := kmQuery(), kmcQuery() 138 S390X.HasAES = km.Has(aes...) 139 S390X.HasAESCBC = kmc.Has(aes...) 140 if facilities.Has(msa4) { 141 kmctr := kmctrQuery() 142 S390X.HasAESCTR = kmctr.Has(aes...) 143 } 144 if facilities.Has(msa8) { 145 kma := kmaQuery() 146 S390X.HasAESGCM = kma.Has(aes...) 147 } 148 149 // compute message digest 150 kimd := kimdQuery() // intermediate (no padding) 151 klmd := klmdQuery() // last (padding) 152 S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) 153 S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) 154 S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) 155 S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist 156 } 157 if S390X.HasVX { 158 S390X.HasVE1 = facilities.Has(ve1) 159 } 160 }