github.com/FISCO-BCOS/crypto@v0.0.0-20200202032121-bd8ab0b5d4f1/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  	sha3_224 function = 32 // SHA3-224
    29  	sha3_256 function = 33 // SHA3-256
    30  	sha3_384 function = 34 // SHA3-384
    31  	sha3_512 function = 35 // SHA3-512
    32  	shake128 function = 36 // SHAKE-128
    33  	shake256 function = 37 // SHAKE-256
    34  
    35  	// KLMD function codes
    36  	ghash function = 65 // GHASH
    37  )
    38  
    39  const (
    40  	// KDSA function codes
    41  	ecdsaVerifyP256    function = 1  // NIST P256
    42  	ecdsaVerifyP384    function = 2  // NIST P384
    43  	ecdsaVerifyP521    function = 3  // NIST P521
    44  	ecdsaSignP256      function = 9  // NIST P256
    45  	ecdsaSignP384      function = 10 // NIST P384
    46  	ecdsaSignP521      function = 11 // NIST P521
    47  	eddsaVerifyEd25519 function = 32 // Curve25519
    48  	eddsaVerifyEd448   function = 36 // Curve448
    49  	eddsaSignEd25519   function = 40 // Curve25519
    50  	eddsaSignEd448     function = 44 // Curve448
    51  )
    52  
    53  // queryResult contains the result of a Query function
    54  // call. Bits are numbered in big endian order so the
    55  // leftmost bit (the MSB) is at index 0.
    56  type queryResult struct {
    57  	bits [2]uint64
    58  }
    59  
    60  // Has reports whether the given functions are present.
    61  func (q *queryResult) Has(fns ...function) bool {
    62  	if len(fns) == 0 {
    63  		panic("no function codes provided")
    64  	}
    65  	for _, f := range fns {
    66  		if !bitIsSet(q.bits[:], uint(f)) {
    67  			return false
    68  		}
    69  	}
    70  	return true
    71  }
    72  
    73  // facility is a bit index for the named facility.
    74  type facility uint8
    75  
    76  const (
    77  	// mandatory facilities
    78  	zarch  facility = 1  // z architecture mode is active
    79  	stflef facility = 7  // store-facility-list-extended
    80  	ldisp  facility = 18 // long-displacement
    81  	eimm   facility = 21 // extended-immediate
    82  
    83  	// miscellaneous facilities
    84  	dfp    facility = 42 // decimal-floating-point
    85  	etf3eh facility = 30 // extended-translation 3 enhancement
    86  
    87  	// cryptography facilities
    88  	msa  facility = 17  // message-security-assist
    89  	msa3 facility = 76  // message-security-assist extension 3
    90  	msa4 facility = 77  // message-security-assist extension 4
    91  	msa5 facility = 57  // message-security-assist extension 5
    92  	msa8 facility = 146 // message-security-assist extension 8
    93  	msa9 facility = 155 // message-security-assist extension 9
    94  
    95  	// vector facilities
    96  	vxe facility = 135 // vector-enhancements 1
    97  
    98  	// Note: vx and highgprs are excluded because they require
    99  	// kernel support and so must be fetched from HWCAP.
   100  )
   101  
   102  // facilityList contains the result of an STFLE call.
   103  // Bits are numbered in big endian order so the
   104  // leftmost bit (the MSB) is at index 0.
   105  type facilityList struct {
   106  	bits [4]uint64
   107  }
   108  
   109  // Has reports whether the given facilities are present.
   110  func (s *facilityList) Has(fs ...facility) bool {
   111  	if len(fs) == 0 {
   112  		panic("no facility bits provided")
   113  	}
   114  	for _, f := range fs {
   115  		if !bitIsSet(s.bits[:], uint(f)) {
   116  			return false
   117  		}
   118  	}
   119  	return true
   120  }
   121  
   122  // The following feature detection functions are defined in cpu_s390x.s.
   123  // They are likely to be expensive to call so the results should be cached.
   124  func stfle() facilityList
   125  func kmQuery() queryResult
   126  func kmcQuery() queryResult
   127  func kmctrQuery() queryResult
   128  func kmaQuery() queryResult
   129  func kimdQuery() queryResult
   130  func klmdQuery() queryResult
   131  func kdsaQuery() queryResult
   132  
   133  func doinit() {
   134  	options = []option{
   135  		{Name: "zarch", Feature: &S390X.HasZARCH},
   136  		{Name: "stfle", Feature: &S390X.HasSTFLE},
   137  		{Name: "ldisp", Feature: &S390X.HasLDISP},
   138  		{Name: "msa", Feature: &S390X.HasMSA},
   139  		{Name: "eimm", Feature: &S390X.HasEIMM},
   140  		{Name: "dfp", Feature: &S390X.HasDFP},
   141  		{Name: "etf3eh", Feature: &S390X.HasETF3EH},
   142  		{Name: "vx", Feature: &S390X.HasVX},
   143  		{Name: "vxe", Feature: &S390X.HasVXE},
   144  		{Name: "kdsa", Feature: &S390X.HasKDSA},
   145  	}
   146  
   147  	aes := []function{aes128, aes192, aes256}
   148  	facilities := stfle()
   149  
   150  	S390X.HasZARCH = facilities.Has(zarch)
   151  	S390X.HasSTFLE = facilities.Has(stflef)
   152  	S390X.HasLDISP = facilities.Has(ldisp)
   153  	S390X.HasEIMM = facilities.Has(eimm)
   154  	S390X.HasDFP = facilities.Has(dfp)
   155  	S390X.HasETF3EH = facilities.Has(etf3eh)
   156  	S390X.HasMSA = facilities.Has(msa)
   157  
   158  	if S390X.HasMSA {
   159  		// cipher message
   160  		km, kmc := kmQuery(), kmcQuery()
   161  		S390X.HasAES = km.Has(aes...)
   162  		S390X.HasAESCBC = kmc.Has(aes...)
   163  		if facilities.Has(msa4) {
   164  			kmctr := kmctrQuery()
   165  			S390X.HasAESCTR = kmctr.Has(aes...)
   166  		}
   167  		if facilities.Has(msa8) {
   168  			kma := kmaQuery()
   169  			S390X.HasAESGCM = kma.Has(aes...)
   170  		}
   171  
   172  		// compute message digest
   173  		kimd := kimdQuery() // intermediate (no padding)
   174  		klmd := klmdQuery() // last (padding)
   175  		S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
   176  		S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
   177  		S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
   178  		S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
   179  		sha3 := []function{
   180  			sha3_224, sha3_256, sha3_384, sha3_512,
   181  			shake128, shake256,
   182  		}
   183  		S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
   184  		S390X.HasKDSA = facilities.Has(msa9) // elliptic curves
   185  		if S390X.HasKDSA {
   186  			kdsa := kdsaQuery()
   187  			S390X.HasECDSA = kdsa.Has(ecdsaVerifyP256, ecdsaSignP256, ecdsaVerifyP384, ecdsaSignP384, ecdsaVerifyP521, ecdsaSignP521)
   188  			S390X.HasEDDSA = kdsa.Has(eddsaVerifyEd25519, eddsaSignEd25519, eddsaVerifyEd448, eddsaSignEd448)
   189  		}
   190  	}
   191  	if S390X.HasVX {
   192  		S390X.HasVXE = facilities.Has(vxe)
   193  	}
   194  }