]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.13] crypto/ecdsa: remove s390x assembly
authorMichael Munday <mike.munday@ibm.com>
Wed, 16 Oct 2019 21:38:40 +0000 (22:38 +0100)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 16 Oct 2019 22:09:14 +0000 (22:09 +0000)
This is a revert of CL 174437 and equivalent to CL 201360.

The size of the params block passed into the KDSA instruction is
incorrect and this appears to result in out-of-bounds writes
that cause a panic in the crypto/x509 tests when run on a machine
that supports KDSA.

Remove this assembly for now. We can revisit the use of the KDSA
instruction in a future release.

Fixes #34928.

Change-Id: I7ad2fe9714b47ad04abc25f18aa235b9d2aef062
Reviewed-on: https://go-review.googlesource.com/c/go/+/201361
Run-TryBot: Michael Munday <mike.munday@ibm.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/crypto/ecdsa/ecdsa.go
src/crypto/ecdsa/ecdsa_noasm.go [deleted file]
src/crypto/ecdsa/ecdsa_s390x.go [deleted file]
src/crypto/ecdsa/ecdsa_s390x.s [deleted file]
src/crypto/ecdsa/ecdsa_s390x_test.go [deleted file]

index ddc3b35ba30336c0618746bb364d151d9b57576b..cc1134f74fc975864e2166b6224812feec04f10a 100644 (file)
@@ -189,21 +189,14 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
 
        // See [NSA] 3.4.1
        c := priv.PublicKey.Curve
-       e := hashToInt(hash, c)
-       r, s, err = sign(priv, &csprng, c, e)
-       return
-}
-
-func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, e *big.Int) (r, s *big.Int, err error) {
        N := c.Params().N
        if N.Sign() == 0 {
                return nil, nil, errZeroParam
        }
-
        var k, kInv *big.Int
        for {
                for {
-                       k, err = randFieldElement(c, *csprng)
+                       k, err = randFieldElement(c, csprng)
                        if err != nil {
                                r = nil
                                return
@@ -221,6 +214,8 @@ func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve
                                break
                        }
                }
+
+               e := hashToInt(hash, c)
                s = new(big.Int).Mul(priv.D, r)
                s.Add(s, e)
                s.Mul(s, kInv)
@@ -229,6 +224,7 @@ func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve
                        break
                }
        }
+
        return
 }
 
@@ -246,12 +242,8 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
                return false
        }
        e := hashToInt(hash, c)
-       return verify(pub, c, e, r, s)
-}
 
-func verifyGeneric(pub *PublicKey, c elliptic.Curve, e, r, s *big.Int) bool {
        var w *big.Int
-       N := c.Params().N
        if in, ok := c.(invertible); ok {
                w = in.Inverse(s)
        } else {
diff --git a/src/crypto/ecdsa/ecdsa_noasm.go b/src/crypto/ecdsa/ecdsa_noasm.go
deleted file mode 100644 (file)
index 2dfdb86..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 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
-
-package ecdsa
-
-import (
-       "crypto/cipher"
-       "crypto/elliptic"
-       "math/big"
-)
-
-func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, e *big.Int) (r, s *big.Int, err error) {
-       r, s, err = signGeneric(priv, csprng, c, e)
-       return
-}
-
-func verify(pub *PublicKey, c elliptic.Curve, e, r, s *big.Int) bool {
-       return verifyGeneric(pub, c, e, r, s)
-}
diff --git a/src/crypto/ecdsa/ecdsa_s390x.go b/src/crypto/ecdsa/ecdsa_s390x.go
deleted file mode 100644 (file)
index f07c3bf..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2019 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
-
-package ecdsa
-
-import (
-       "crypto/cipher"
-       "crypto/elliptic"
-       "internal/cpu"
-       "math/big"
-)
-
-// s390x accelerated signatures
-//go:noescape
-func kdsaSig(fc uint64, block *[1720]byte) (errn uint64)
-
-type signverify int
-
-const (
-       signing signverify = iota
-       verifying
-)
-
-// bufferOffsets represents the offset of a particular parameter in
-// the buffer passed to the KDSA instruction.
-type bufferOffsets struct {
-       baseSize       int
-       hashSize       int
-       offsetHash     int
-       offsetKey1     int
-       offsetRNorKey2 int
-       offsetR        int
-       offsetS        int
-       functionCode   uint64
-}
-
-func canUseKDSA(sv signverify, c elliptic.Curve, bo *bufferOffsets) bool {
-       if !cpu.S390X.HasECDSA {
-               return false
-       }
-
-       switch c.Params().Name {
-       case "P-256":
-               bo.baseSize = 32
-               bo.hashSize = 32
-               bo.offsetHash = 64
-               bo.offsetKey1 = 96
-               bo.offsetRNorKey2 = 128
-               bo.offsetR = 0
-               bo.offsetS = 32
-               if sv == signing {
-                       bo.functionCode = 137
-               } else {
-                       bo.functionCode = 1
-               }
-               return true
-       case "P-384":
-               bo.baseSize = 48
-               bo.hashSize = 48
-               bo.offsetHash = 96
-               bo.offsetKey1 = 144
-               bo.offsetRNorKey2 = 192
-               bo.offsetR = 0
-               bo.offsetS = 48
-               if sv == signing {
-                       bo.functionCode = 138
-               } else {
-                       bo.functionCode = 2
-               }
-               return true
-       case "P-521":
-               bo.baseSize = 66
-               bo.hashSize = 80
-               bo.offsetHash = 160
-               bo.offsetKey1 = 254
-               bo.offsetRNorKey2 = 334
-               bo.offsetR = 14
-               bo.offsetS = 94
-               if sv == signing {
-                       bo.functionCode = 139
-               } else {
-                       bo.functionCode = 3
-               }
-               return true
-       }
-       return false
-}
-
-// zeroExtendAndCopy pads src with leading zeros until it has the size given.
-// It then copies the padded src into the dst. Bytes beyond size in dst are
-// not modified.
-func zeroExtendAndCopy(dst, src []byte, size int) {
-       nz := size - len(src)
-       if nz < 0 {
-               panic("src is too long")
-       }
-       // the compiler should replace this loop with a memclr call
-       z := dst[:nz]
-       for i := range z {
-               z[i] = 0
-       }
-       copy(dst[nz:size], src[:size-nz])
-       return
-}
-
-func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, e *big.Int) (r, s *big.Int, err error) {
-       var bo bufferOffsets
-       if canUseKDSA(signing, c, &bo) && e.Sign() != 0 {
-               var buffer [1720]byte
-               for {
-                       var k *big.Int
-                       k, err = randFieldElement(c, csprng)
-                       if err != nil {
-                               return nil, nil, err
-                       }
-                       zeroExtendAndCopy(buffer[bo.offsetHash:], e.Bytes(), bo.hashSize)
-                       zeroExtendAndCopy(buffer[bo.offsetKey1:], priv.D.Bytes(), bo.baseSize)
-                       zeroExtendAndCopy(buffer[bo.offsetRNorKey2:], k.Bytes(), bo.baseSize)
-                       errn := kdsaSig(bo.functionCode, &buffer)
-                       if errn == 2 {
-                               return nil, nil, errZeroParam
-                       }
-                       if errn == 0 { // success == 0 means successful signing
-                               r = new(big.Int)
-                               r.SetBytes(buffer[bo.offsetR : bo.offsetR+bo.baseSize])
-                               s = new(big.Int)
-                               s.SetBytes(buffer[bo.offsetS : bo.offsetS+bo.baseSize])
-                               return
-                       }
-                       //at this point, it must be that errn == 1: retry
-               }
-       }
-       r, s, err = signGeneric(priv, csprng, c, e)
-       return
-}
-
-func verify(pub *PublicKey, c elliptic.Curve, e, r, s *big.Int) bool {
-       var bo bufferOffsets
-       if canUseKDSA(verifying, c, &bo) && e.Sign() != 0 {
-               var buffer [1720]byte
-               zeroExtendAndCopy(buffer[bo.offsetR:], r.Bytes(), bo.baseSize)
-               zeroExtendAndCopy(buffer[bo.offsetS:], s.Bytes(), bo.baseSize)
-               zeroExtendAndCopy(buffer[bo.offsetHash:], e.Bytes(), bo.hashSize)
-               zeroExtendAndCopy(buffer[bo.offsetKey1:], pub.X.Bytes(), bo.baseSize)
-               zeroExtendAndCopy(buffer[bo.offsetRNorKey2:], pub.Y.Bytes(), bo.baseSize)
-               errn := kdsaSig(bo.functionCode, &buffer)
-               return errn == 0
-       }
-       return verifyGeneric(pub, c, e, r, s)
-}
diff --git a/src/crypto/ecdsa/ecdsa_s390x.s b/src/crypto/ecdsa/ecdsa_s390x.s
deleted file mode 100644 (file)
index 6ee00ce..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2019 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 kdsaSig(fc uint64, block *[1720]byte) (errn uint64)
-TEXT ·kdsaSig(SB), NOSPLIT|NOFRAME, $0-24
-       MOVD fc+0(FP), R0    // function code
-       MOVD block+8(FP), R1 // address parameter block
-
-loop:
-       WORD $0xB93A0008 // compute digital signature authentication
-       BVS  loop        // branch back if interrupted
-       BEQ  success     // signature creation successful
-       BGT  retry       // signing unsuccessful, but retry with new CSPRN
-
-error:
-       MOVD $2, R2          // fallthrough indicates fatal error
-       MOVD R2, errn+16(FP) // return 2 - sign/verify abort
-       RET
-
-retry:
-       MOVD $1, R2
-       MOVD R2, errn+16(FP) // return 1 - sign/verify was unsuccessful -- if sign, retry with new RN
-       RET
-
-success:
-       MOVD $0, R2
-       MOVD R2, errn+16(FP) // return 0 - sign/verify was successful
-       RET
diff --git a/src/crypto/ecdsa/ecdsa_s390x_test.go b/src/crypto/ecdsa/ecdsa_s390x_test.go
deleted file mode 100644 (file)
index 80babc9..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 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
-
-package ecdsa
-
-import (
-       "crypto/elliptic"
-       "testing"
-)
-
-func TestNoAsm(t *testing.T) {
-       curves := [...]elliptic.Curve{
-               elliptic.P256(),
-               elliptic.P384(),
-               elliptic.P521(),
-       }
-
-       for _, curve := range curves {
-               // override the name of the curve to stop the assembly path being taken
-               params := *curve.Params()
-               name := params.Name
-               params.Name = name + "_GENERIC_OVERRIDE"
-
-               testKeyGeneration(t, &params, name)
-               testSignAndVerify(t, &params, name)
-               testNonceSafety(t, &params, name)
-               testINDCCA(t, &params, name)
-               testNegativeInputs(t, &params, name)
-       }
-}