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.

cpu_linux_s390x.go 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright 2019 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. package cpu
  5. const (
  6. // bit mask values from /usr/include/bits/hwcap.h
  7. hwcap_ZARCH = 2
  8. hwcap_STFLE = 4
  9. hwcap_MSA = 8
  10. hwcap_LDISP = 16
  11. hwcap_EIMM = 32
  12. hwcap_DFP = 64
  13. hwcap_ETF3EH = 256
  14. hwcap_VX = 2048
  15. hwcap_VXE = 8192
  16. )
  17. // bitIsSet reports whether the bit at index is set. The bit index
  18. // is in big endian order, so bit index 0 is the leftmost bit.
  19. func bitIsSet(bits []uint64, index uint) bool {
  20. return bits[index/64]&((1<<63)>>(index%64)) != 0
  21. }
  22. // function is the code for the named cryptographic function.
  23. type function uint8
  24. const (
  25. // KM{,A,C,CTR} function codes
  26. aes128 function = 18 // AES-128
  27. aes192 function = 19 // AES-192
  28. aes256 function = 20 // AES-256
  29. // K{I,L}MD function codes
  30. sha1 function = 1 // SHA-1
  31. sha256 function = 2 // SHA-256
  32. sha512 function = 3 // SHA-512
  33. sha3_224 function = 32 // SHA3-224
  34. sha3_256 function = 33 // SHA3-256
  35. sha3_384 function = 34 // SHA3-384
  36. sha3_512 function = 35 // SHA3-512
  37. shake128 function = 36 // SHAKE-128
  38. shake256 function = 37 // SHAKE-256
  39. // KLMD function codes
  40. ghash function = 65 // GHASH
  41. )
  42. // queryResult contains the result of a Query function
  43. // call. Bits are numbered in big endian order so the
  44. // leftmost bit (the MSB) is at index 0.
  45. type queryResult struct {
  46. bits [2]uint64
  47. }
  48. // Has reports whether the given functions are present.
  49. func (q *queryResult) Has(fns ...function) bool {
  50. if len(fns) == 0 {
  51. panic("no function codes provided")
  52. }
  53. for _, f := range fns {
  54. if !bitIsSet(q.bits[:], uint(f)) {
  55. return false
  56. }
  57. }
  58. return true
  59. }
  60. // facility is a bit index for the named facility.
  61. type facility uint8
  62. const (
  63. // cryptography facilities
  64. msa4 facility = 77 // message-security-assist extension 4
  65. msa8 facility = 146 // message-security-assist extension 8
  66. )
  67. // facilityList contains the result of an STFLE call.
  68. // Bits are numbered in big endian order so the
  69. // leftmost bit (the MSB) is at index 0.
  70. type facilityList struct {
  71. bits [4]uint64
  72. }
  73. // Has reports whether the given facilities are present.
  74. func (s *facilityList) Has(fs ...facility) bool {
  75. if len(fs) == 0 {
  76. panic("no facility bits provided")
  77. }
  78. for _, f := range fs {
  79. if !bitIsSet(s.bits[:], uint(f)) {
  80. return false
  81. }
  82. }
  83. return true
  84. }
  85. func doinit() {
  86. // test HWCAP bit vector
  87. has := func(featureMask uint) bool {
  88. return hwCap&featureMask == featureMask
  89. }
  90. // mandatory
  91. S390X.HasZARCH = has(hwcap_ZARCH)
  92. // optional
  93. S390X.HasSTFLE = has(hwcap_STFLE)
  94. S390X.HasLDISP = has(hwcap_LDISP)
  95. S390X.HasEIMM = has(hwcap_EIMM)
  96. S390X.HasETF3EH = has(hwcap_ETF3EH)
  97. S390X.HasDFP = has(hwcap_DFP)
  98. S390X.HasMSA = has(hwcap_MSA)
  99. S390X.HasVX = has(hwcap_VX)
  100. if S390X.HasVX {
  101. S390X.HasVXE = has(hwcap_VXE)
  102. }
  103. // We need implementations of stfle, km and so on
  104. // to detect cryptographic features.
  105. if !haveAsmFunctions() {
  106. return
  107. }
  108. // optional cryptographic functions
  109. if S390X.HasMSA {
  110. aes := []function{aes128, aes192, aes256}
  111. // cipher message
  112. km, kmc := kmQuery(), kmcQuery()
  113. S390X.HasAES = km.Has(aes...)
  114. S390X.HasAESCBC = kmc.Has(aes...)
  115. if S390X.HasSTFLE {
  116. facilities := stfle()
  117. if facilities.Has(msa4) {
  118. kmctr := kmctrQuery()
  119. S390X.HasAESCTR = kmctr.Has(aes...)
  120. }
  121. if facilities.Has(msa8) {
  122. kma := kmaQuery()
  123. S390X.HasAESGCM = kma.Has(aes...)
  124. }
  125. }
  126. // compute message digest
  127. kimd := kimdQuery() // intermediate (no padding)
  128. klmd := klmdQuery() // last (padding)
  129. S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
  130. S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
  131. S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
  132. S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
  133. sha3 := []function{
  134. sha3_224, sha3_256, sha3_384, sha3_512,
  135. shake128, shake256,
  136. }
  137. S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
  138. }
  139. }