mirror of
https://github.com/golang/go
synced 2024-11-18 04:14:49 -07:00
crypto/{aes,internal/cipherhw,tls}: use common internal/cpu in place of cipherhw
When the internal/cpu package was introduced, the AES package still used
the custom crypto/internal/cipherhw package for amd64 and s390x. This
change removes that package entirely in favor of directly referencing the
cpu feature flags set and exposed by the internal/cpu package. In
addition, 5 new flags have been added to the internal/cpu s390x struct
for detecting various cipher message (KM) features.
Change-Id: I77cdd8bc1b04ab0e483b21bf1879b5801a4ba5f4
GitHub-Last-Rev: a611e3ecb1
GitHub-Pull-Request: golang/go#24766
Reviewed-on: https://go-review.googlesource.com/105695
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
482d241936
commit
3f2039e28d
@ -13,7 +13,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// The following functions are defined in gcm_amd64.s.
|
// The following functions are defined in gcm_amd64.s.
|
||||||
func hasGCMAsm() bool
|
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func aesEncBlock(dst, src *[16]byte, ks []uint32)
|
func aesEncBlock(dst, src *[16]byte, ks []uint32)
|
||||||
|
@ -151,29 +151,6 @@ loop:
|
|||||||
MOVD $0, R0
|
MOVD $0, R0
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// func supportsKMA() bool
|
|
||||||
TEXT ·supportsKMA(SB),NOSPLIT,$24-1
|
|
||||||
MOVD $tmp-24(SP), R1
|
|
||||||
MOVD $2, R0 // store 24-bytes
|
|
||||||
XC $24, (R1), (R1)
|
|
||||||
WORD $0xb2b01000 // STFLE (R1)
|
|
||||||
MOVWZ 16(R1), R2
|
|
||||||
ANDW $(1<<13), R2 // test bit 146 (message-security-assist 8)
|
|
||||||
BEQ no
|
|
||||||
|
|
||||||
MOVD $0, R0 // KMA-Query
|
|
||||||
XC $16, (R1), (R1)
|
|
||||||
WORD $0xb9296024 // kma %r6,%r2,%r4
|
|
||||||
MOVWZ (R1), R2
|
|
||||||
WORD $0xa7213800 // TMLL R2, $0x3800
|
|
||||||
BVS yes
|
|
||||||
no:
|
|
||||||
MOVB $0, ret+0(FP)
|
|
||||||
RET
|
|
||||||
yes:
|
|
||||||
MOVB $1, ret+0(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func kmaGCM(fn code, key, dst, src, aad []byte, tag *[16]byte, cnt *gcmCount)
|
// func kmaGCM(fn code, key, dst, src, aad []byte, tag *[16]byte, cnt *gcmCount)
|
||||||
TEXT ·kmaGCM(SB),NOSPLIT,$112-120
|
TEXT ·kmaGCM(SB),NOSPLIT,$112-120
|
||||||
MOVD fn+0(FP), R0
|
MOVD fn+0(FP), R0
|
||||||
|
@ -6,10 +6,11 @@ package aes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/internal/cipherhw"
|
"internal/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defined in asm_amd64.s
|
// defined in asm_amd64.s
|
||||||
|
|
||||||
func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
|
func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
|
||||||
func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
|
func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
|
||||||
func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
|
func expandKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
|
||||||
@ -18,10 +19,8 @@ type aesCipherAsm struct {
|
|||||||
aesCipher
|
aesCipher
|
||||||
}
|
}
|
||||||
|
|
||||||
var useAsm = cipherhw.AESGCMSupport()
|
|
||||||
|
|
||||||
func newCipher(key []byte) (cipher.Block, error) {
|
func newCipher(key []byte) (cipher.Block, error) {
|
||||||
if !useAsm {
|
if !cpu.X86.HasAES {
|
||||||
return newCipherGeneric(key)
|
return newCipherGeneric(key)
|
||||||
}
|
}
|
||||||
n := len(key) + 28
|
n := len(key) + 28
|
||||||
@ -35,8 +34,9 @@ func newCipher(key []byte) (cipher.Block, error) {
|
|||||||
case 256 / 8:
|
case 256 / 8:
|
||||||
rounds = 14
|
rounds = 14
|
||||||
}
|
}
|
||||||
|
|
||||||
expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
|
expandKeyAsm(rounds, &key[0], &c.enc[0], &c.dec[0])
|
||||||
if hasGCMAsm() {
|
if cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ {
|
||||||
return &aesCipherGCM{c}, nil
|
return &aesCipherGCM{c}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ func (c *aesCipherAsm) Decrypt(dst, src []byte) {
|
|||||||
// expandKey is used by BenchmarkExpand to ensure that the asm implementation
|
// expandKey is used by BenchmarkExpand to ensure that the asm implementation
|
||||||
// of key expansion is used for the benchmark when it is available.
|
// of key expansion is used for the benchmark when it is available.
|
||||||
func expandKey(key []byte, enc, dec []uint32) {
|
func expandKey(key []byte, enc, dec []uint32) {
|
||||||
if useAsm {
|
if cpu.X86.HasAES {
|
||||||
rounds := 10 // rounds needed for AES128
|
rounds := 10 // rounds needed for AES128
|
||||||
switch len(key) {
|
switch len(key) {
|
||||||
case 192 / 8:
|
case 192 / 8:
|
||||||
|
@ -11,23 +11,18 @@ import (
|
|||||||
// defined in asm_ppc64le.s
|
// defined in asm_ppc64le.s
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
func setEncryptKeyAsm(key *byte, keylen int, enc *uint32) int
|
func setEncryptKeyAsm(key *byte, keylen int, enc *uint32) int
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
func setDecryptKeyAsm(key *byte, keylen int, dec *uint32) int
|
func setDecryptKeyAsm(key *byte, keylen int, dec *uint32) int
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
func doEncryptKeyAsm(key *byte, keylen int, dec *uint32) int
|
func doEncryptKeyAsm(key *byte, keylen int, dec *uint32) int
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
func encryptBlockAsm(dst, src *byte, enc *uint32)
|
func encryptBlockAsm(dst, src *byte, enc *uint32)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
func decryptBlockAsm(dst, src *byte, dec *uint32)
|
func decryptBlockAsm(dst, src *byte, dec *uint32)
|
||||||
|
|
||||||
type aesCipherAsm struct {
|
type aesCipherAsm struct {
|
||||||
|
@ -6,7 +6,7 @@ package aes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/internal/cipherhw"
|
"internal/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
type code int
|
type code int
|
||||||
@ -20,8 +20,8 @@ const (
|
|||||||
|
|
||||||
type aesCipherAsm struct {
|
type aesCipherAsm struct {
|
||||||
function code // code for cipher message instruction
|
function code // code for cipher message instruction
|
||||||
key []byte // key (128, 192 or 256 bytes)
|
key []byte // key (128, 192 or 256 bits)
|
||||||
storage [256]byte // array backing key slice
|
storage [32]byte // array backing key slice
|
||||||
}
|
}
|
||||||
|
|
||||||
// cryptBlocks invokes the cipher message (KM) instruction with
|
// cryptBlocks invokes the cipher message (KM) instruction with
|
||||||
@ -30,10 +30,13 @@ type aesCipherAsm struct {
|
|||||||
//go:noescape
|
//go:noescape
|
||||||
func cryptBlocks(c code, key, dst, src *byte, length int)
|
func cryptBlocks(c code, key, dst, src *byte, length int)
|
||||||
|
|
||||||
var useAsm = cipherhw.AESGCMSupport()
|
|
||||||
|
|
||||||
func newCipher(key []byte) (cipher.Block, error) {
|
func newCipher(key []byte) (cipher.Block, error) {
|
||||||
if !useAsm {
|
// Strictly speaking, this check should be for HasKM.
|
||||||
|
// The check for HasKMC and HasKMCTR provides compatibility
|
||||||
|
// with the existing optimized s390x CBC and CTR implementations
|
||||||
|
// in this package, which already assert that they meet the
|
||||||
|
// cbcEncAble, cbcDecAble, and ctrAble interfaces
|
||||||
|
if !(cpu.S390X.HasKM && cpu.S390X.HasKMC && cpu.S390X.HasKMCTR) {
|
||||||
return newCipherGeneric(key)
|
return newCipherGeneric(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,20 +71,6 @@ GLOBL bswapMask<>(SB), (NOPTR+RODATA), $16
|
|||||||
GLOBL gcmPoly<>(SB), (NOPTR+RODATA), $16
|
GLOBL gcmPoly<>(SB), (NOPTR+RODATA), $16
|
||||||
GLOBL andMask<>(SB), (NOPTR+RODATA), $240
|
GLOBL andMask<>(SB), (NOPTR+RODATA), $240
|
||||||
|
|
||||||
// func hasGCMAsm() bool
|
|
||||||
// returns whether AES-NI AND CLMUL-NI are supported
|
|
||||||
TEXT ·hasGCMAsm(SB),NOSPLIT,$0
|
|
||||||
XORQ AX, AX
|
|
||||||
INCL AX
|
|
||||||
CPUID
|
|
||||||
MOVQ CX, DX
|
|
||||||
SHRQ $25, CX
|
|
||||||
SHRQ $1, DX
|
|
||||||
ANDQ DX, CX
|
|
||||||
ANDQ $1, CX
|
|
||||||
MOVB CX, ret+0(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func aesEncBlock(dst, src *[16]byte, ks []uint32)
|
// func aesEncBlock(dst, src *[16]byte, ks []uint32)
|
||||||
TEXT ·aesEncBlock(SB),NOSPLIT,$0
|
TEXT ·aesEncBlock(SB),NOSPLIT,$0
|
||||||
MOVQ dst+0(FP), DI
|
MOVQ dst+0(FP), DI
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"errors"
|
"errors"
|
||||||
|
"internal/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file contains two implementations of AES-GCM. The first implementation
|
// This file contains two implementations of AES-GCM. The first implementation
|
||||||
@ -84,7 +85,7 @@ func (c *aesCipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
|
|||||||
nonceSize: nonceSize,
|
nonceSize: nonceSize,
|
||||||
tagSize: tagSize,
|
tagSize: tagSize,
|
||||||
}
|
}
|
||||||
if hasKMA {
|
if cpu.S390X.HasKMA {
|
||||||
g := gcmKMA{g}
|
g := gcmKMA{g}
|
||||||
return &g, nil
|
return &g, nil
|
||||||
}
|
}
|
||||||
@ -288,13 +289,6 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// supportsKMA reports whether the message-security-assist 8 facility is available.
|
|
||||||
// This function call may be expensive so hasKMA should be queried instead.
|
|
||||||
func supportsKMA() bool
|
|
||||||
|
|
||||||
// hasKMA contains the result of supportsKMA.
|
|
||||||
var hasKMA = supportsKMA()
|
|
||||||
|
|
||||||
// gcmKMA implements the cipher.AEAD interface using the KMA instruction. It should
|
// gcmKMA implements the cipher.AEAD interface using the KMA instruction. It should
|
||||||
// only be used if hasKMA is true.
|
// only be used if hasKMA is true.
|
||||||
type gcmKMA struct {
|
type gcmKMA struct {
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// func hasAESNI() bool
|
|
||||||
TEXT ·hasAESNI(SB),NOSPLIT,$0
|
|
||||||
XORQ AX, AX
|
|
||||||
INCL AX
|
|
||||||
CPUID
|
|
||||||
SHRQ $25, CX
|
|
||||||
ANDQ $1, CX
|
|
||||||
MOVB CX, ret+0(FP)
|
|
||||||
RET
|
|
@ -1,44 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build s390x,!gccgo,!appengine
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// func hasHWSupport() bool
|
|
||||||
TEXT ·hasHWSupport(SB),NOSPLIT,$16-1
|
|
||||||
XOR R0, R0 // set function code to 0 (query)
|
|
||||||
LA mask-16(SP), R1 // 16-byte stack variable for mask
|
|
||||||
MOVD $(0x38<<40), R3 // mask for bits 18-20 (big endian)
|
|
||||||
|
|
||||||
// check for KM AES functions
|
|
||||||
WORD $0xB92E0024 // cipher message (KM)
|
|
||||||
MOVD mask-16(SP), R2
|
|
||||||
AND R3, R2
|
|
||||||
CMPBNE R2, R3, notfound
|
|
||||||
|
|
||||||
// check for KMC AES functions
|
|
||||||
WORD $0xB92F0024 // cipher message with chaining (KMC)
|
|
||||||
MOVD mask-16(SP), R2
|
|
||||||
AND R3, R2
|
|
||||||
CMPBNE R2, R3, notfound
|
|
||||||
|
|
||||||
// check for KMCTR AES functions
|
|
||||||
WORD $0xB92D4024 // cipher message with counter (KMCTR)
|
|
||||||
MOVD mask-16(SP), R2
|
|
||||||
AND R3, R2
|
|
||||||
CMPBNE R2, R3, notfound
|
|
||||||
|
|
||||||
// check for KIMD GHASH function
|
|
||||||
WORD $0xB93E0024 // compute intermediate message digest (KIMD)
|
|
||||||
MOVD mask-8(SP), R2 // bits 64-127
|
|
||||||
MOVD $(1<<62), R5
|
|
||||||
AND R5, R2
|
|
||||||
CMPBNE R2, R5, notfound
|
|
||||||
|
|
||||||
MOVB $1, ret+0(FP)
|
|
||||||
RET
|
|
||||||
notfound:
|
|
||||||
MOVB $0, ret+0(FP)
|
|
||||||
RET
|
|
@ -1,16 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build amd64,!gccgo,!appengine
|
|
||||||
|
|
||||||
package cipherhw
|
|
||||||
|
|
||||||
// defined in asm_amd64.s
|
|
||||||
func hasAESNI() bool
|
|
||||||
|
|
||||||
// AESGCMSupport returns true if the Go standard library supports AES-GCM in
|
|
||||||
// hardware.
|
|
||||||
func AESGCMSupport() bool {
|
|
||||||
return hasAESNI()
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build s390x,!gccgo,!appengine
|
|
||||||
|
|
||||||
package cipherhw
|
|
||||||
|
|
||||||
// hasHWSupport reports whether the AES-128, AES-192 and AES-256 cipher message
|
|
||||||
// (KM) function codes are supported. Note that this function is expensive.
|
|
||||||
// defined in asm_s390x.s
|
|
||||||
func hasHWSupport() bool
|
|
||||||
|
|
||||||
var hwSupport = hasHWSupport()
|
|
||||||
|
|
||||||
func AESGCMSupport() bool {
|
|
||||||
return hwSupport
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
// Copyright 2016 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 cipherhw exposes common functions for detecting whether hardware
|
|
||||||
// support for certain ciphers and authenticators is present.
|
|
||||||
package cipherhw
|
|
@ -1,11 +0,0 @@
|
|||||||
// Copyright 2016 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.
|
|
||||||
|
|
||||||
// +build !amd64,!s390x gccgo appengine
|
|
||||||
|
|
||||||
package cipherhw
|
|
||||||
|
|
||||||
func AESGCMSupport() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
@ -7,12 +7,12 @@ package tls
|
|||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/internal/cipherhw"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"internal/cpu"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
@ -917,7 +917,23 @@ func defaultCipherSuites() []uint16 {
|
|||||||
|
|
||||||
func initDefaultCipherSuites() {
|
func initDefaultCipherSuites() {
|
||||||
var topCipherSuites []uint16
|
var topCipherSuites []uint16
|
||||||
if cipherhw.AESGCMSupport() {
|
|
||||||
|
// Check the cpu flags for each platform that has optimized GCM implementations.
|
||||||
|
// Worst case, these variables will just all be false
|
||||||
|
hasGCMAsmAMD64 := cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
|
||||||
|
|
||||||
|
// TODO: enable the arm64 HasAES && HasPMULL feature check after the
|
||||||
|
// optimized AES-GCM implementation for arm64 is merged (CL 107298).
|
||||||
|
// This is explicitly set to false for now to prevent misprioritization
|
||||||
|
// of AES-GCM based cipher suites, which will be slower than chacha20-poly1305
|
||||||
|
hasGCMAsmARM64 := false
|
||||||
|
// hasGCMAsmARM64 := cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
|
||||||
|
|
||||||
|
hasGCMAsmS390X := cpu.S390X.HasKM && (cpu.S390X.HasKMA || (cpu.S390X.HasKMCTR && cpu.S390X.HasKIMD))
|
||||||
|
|
||||||
|
hasGCMAsm := hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X
|
||||||
|
|
||||||
|
if hasGCMAsm {
|
||||||
// If AES-GCM hardware is provided then prioritise AES-GCM
|
// If AES-GCM hardware is provided then prioritise AES-GCM
|
||||||
// cipher suites.
|
// cipher suites.
|
||||||
topCipherSuites = []uint16{
|
topCipherSuites = []uint16{
|
||||||
|
@ -120,7 +120,6 @@ var pkgDeps = map[string][]string{
|
|||||||
"L2",
|
"L2",
|
||||||
"crypto",
|
"crypto",
|
||||||
"crypto/cipher",
|
"crypto/cipher",
|
||||||
"crypto/internal/cipherhw",
|
|
||||||
"crypto/subtle",
|
"crypto/subtle",
|
||||||
"encoding/base32",
|
"encoding/base32",
|
||||||
"encoding/base64",
|
"encoding/base64",
|
||||||
|
@ -100,6 +100,11 @@ var S390X s390x
|
|||||||
type s390x struct {
|
type s390x struct {
|
||||||
_ [CacheLineSize]byte
|
_ [CacheLineSize]byte
|
||||||
HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.
|
HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.
|
||||||
|
HasKM bool // cipher message (KM)
|
||||||
|
HasKMA bool // cipher message assist (KMA)
|
||||||
|
HasKMC bool // cipher message with chaining (KMC)
|
||||||
|
HasKMCTR bool // cipher message with counter (KMCTR)
|
||||||
|
HasKIMD bool // compute intermediate message digest (KIMD)
|
||||||
_ [CacheLineSize]byte
|
_ [CacheLineSize]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,3 +5,18 @@
|
|||||||
package cpu
|
package cpu
|
||||||
|
|
||||||
const CacheLineSize = 256
|
const CacheLineSize = 256
|
||||||
|
|
||||||
|
// the following cpu feature detection functions are defined in cpu_s390x.s
|
||||||
|
func hasKM() bool
|
||||||
|
func hasKMC() bool
|
||||||
|
func hasKMCTR() bool
|
||||||
|
func hasKMA() bool
|
||||||
|
func hasKIMD() bool
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
S390X.HasKM = hasKM()
|
||||||
|
S390X.HasKMC = hasKMC()
|
||||||
|
S390X.HasKMCTR = hasKMCTR()
|
||||||
|
S390X.HasKMA = hasKMA()
|
||||||
|
S390X.HasKIMD = hasKIMD()
|
||||||
|
}
|
||||||
|
101
src/internal/cpu/cpu_s390x.s
Normal file
101
src/internal/cpu/cpu_s390x.s
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func hasKM() bool
|
||||||
|
TEXT ·hasKM(SB),NOSPLIT,$16-1
|
||||||
|
XOR R0, R0 // set function code to 0 (query)
|
||||||
|
LA mask-16(SP), R1 // 16-byte stack variable for mask
|
||||||
|
MOVD $(0x38<<40), R3 // mask for bits 18-20 (big endian)
|
||||||
|
|
||||||
|
// check for KM AES functions
|
||||||
|
WORD $0xB92E0024 // cipher message (KM)
|
||||||
|
MOVD mask-16(SP), R2
|
||||||
|
AND R3, R2
|
||||||
|
CMPBNE R2, R3, notfound
|
||||||
|
|
||||||
|
MOVB $1, ret+0(FP)
|
||||||
|
RET
|
||||||
|
notfound:
|
||||||
|
MOVB $0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func hasKMC() bool
|
||||||
|
TEXT ·hasKMC(SB),NOSPLIT,$16-1
|
||||||
|
XOR R0, R0 // set function code to 0 (query)
|
||||||
|
LA mask-16(SP), R1 // 16-byte stack variable for mask
|
||||||
|
MOVD $(0x38<<40), R3 // mask for bits 18-20 (big endian)
|
||||||
|
|
||||||
|
// check for KMC AES functions
|
||||||
|
WORD $0xB92F0024 // cipher message with chaining (KMC)
|
||||||
|
MOVD mask-16(SP), R2
|
||||||
|
AND R3, R2
|
||||||
|
CMPBNE R2, R3, notfound
|
||||||
|
|
||||||
|
MOVB $1, ret+0(FP)
|
||||||
|
RET
|
||||||
|
notfound:
|
||||||
|
MOVB $0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func hasKMCTR() bool
|
||||||
|
TEXT ·hasKMCTR(SB),NOSPLIT,$16-1
|
||||||
|
XOR R0, R0 // set function code to 0 (query)
|
||||||
|
LA mask-16(SP), R1 // 16-byte stack variable for mask
|
||||||
|
MOVD $(0x38<<40), R3 // mask for bits 18-20 (big endian)
|
||||||
|
|
||||||
|
// check for KMCTR AES functions
|
||||||
|
WORD $0xB92D4024 // cipher message with counter (KMCTR)
|
||||||
|
MOVD mask-16(SP), R2
|
||||||
|
AND R3, R2
|
||||||
|
CMPBNE R2, R3, notfound
|
||||||
|
|
||||||
|
MOVB $1, ret+0(FP)
|
||||||
|
RET
|
||||||
|
notfound:
|
||||||
|
MOVB $0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func hasKMA() bool
|
||||||
|
TEXT ·hasKMA(SB),NOSPLIT,$24-1
|
||||||
|
MOVD $tmp-24(SP), R1
|
||||||
|
MOVD $2, R0 // store 24-bytes
|
||||||
|
XC $24, (R1), (R1)
|
||||||
|
WORD $0xb2b01000 // STFLE (R1)
|
||||||
|
MOVWZ 16(R1), R2
|
||||||
|
ANDW $(1<<13), R2 // test bit 146 (message-security-assist 8)
|
||||||
|
BEQ no
|
||||||
|
|
||||||
|
MOVD $0, R0 // KMA-Query
|
||||||
|
XC $16, (R1), (R1)
|
||||||
|
WORD $0xb9296024 // kma %r6,%r2,%r4
|
||||||
|
MOVWZ (R1), R2
|
||||||
|
WORD $0xa7213800 // TMLL R2, $0x3800
|
||||||
|
BVS yes
|
||||||
|
no:
|
||||||
|
MOVB $0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
yes:
|
||||||
|
MOVB $1, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func hasKIMD() bool
|
||||||
|
TEXT ·hasKIMD(SB),NOSPLIT,$16-1
|
||||||
|
XOR R0, R0 // set function code to 0 (query)
|
||||||
|
LA mask-16(SP), R1 // 16-byte stack variable for mask
|
||||||
|
MOVD $(0x38<<40), R3 // mask for bits 18-20 (big endian)
|
||||||
|
|
||||||
|
// check for KIMD GHASH function
|
||||||
|
WORD $0xB93E0024 // compute intermediate message digest (KIMD)
|
||||||
|
MOVD mask-8(SP), R2 // bits 64-127
|
||||||
|
MOVD $(1<<62), R5
|
||||||
|
AND R5, R2
|
||||||
|
CMPBNE R2, R5, notfound
|
||||||
|
|
||||||
|
MOVB $1, ret+0(FP)
|
||||||
|
RET
|
||||||
|
notfound:
|
||||||
|
MOVB $0, ret+0(FP)
|
||||||
|
RET
|
Loading…
Reference in New Issue
Block a user