...

Source file src/internal/cpu/cpu_s390x.go

     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	}
   195	

View as plain text