Skip to content

Commit 41cea66

Browse files
committed
Stop using ECDSA_* function for signatures
For creating and verifying ECDSA signatures in a pre-hashed manner, we used the legacy ECDSA_sign and ECDSA_verify functions, which bypass the system-wide restriction on ECDSA. This switches to using our _goboringcrypto_EVP_{sign,verify}_raw, which internally use EVP_PKEY_ functions. Signed-off-by: Daiki Ueno <[email protected]>
1 parent b175be2 commit 41cea66

File tree

4 files changed

+97
-24
lines changed

4 files changed

+97
-24
lines changed

openssl/ecdsa.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,13 @@ func NewPrivateKeyECDSA(curve string, X, Y BigInt, D BigInt) (*PrivateKeyECDSA,
131131
func HashSignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (*big.Int, *big.Int, error) {
132132
size := C._goboringcrypto_ECDSA_size(priv.key)
133133
sig := make([]byte, size)
134-
var sigLen C.size_t
134+
var sigLen C.size_t = C.size_t(size)
135135
md := cryptoHashToMD(h)
136136
if md == nil {
137137
panic("boring: invalid hash")
138138
}
139-
if C._goboringcrypto_ECDSA_sign(md, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 {
139+
if C._goboringcrypto_ECDSA_sign(md, base(hash), C.size_t(len(hash)),
140+
(*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 {
140141
return nil, nil, NewOpenSSLError("ECDSA_sign failed")
141142
}
142143
runtime.KeepAlive(priv)
@@ -151,18 +152,19 @@ func HashSignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (*big.Int,
151152
func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
152153
size := C._goboringcrypto_ECDSA_size(priv.key)
153154
sig := make([]byte, size)
154-
var sigLen C.uint
155-
ok := C._goboringcrypto_internal_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) > 0
156-
if !ok {
157-
return nil, NewOpenSSLError(("ECDSA_sign failed"))
155+
var sigLen C.size_t = C.size_t(size)
156+
if C._goboringcrypto_ECDSA_sign_raw(nil, base(hash), C.size_t(len(hash)),
157+
(*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 {
158+
return nil, NewOpenSSLError("ECDSA_sign failed")
158159
}
159160

160161
runtime.KeepAlive(priv)
161162
return sig[:sigLen], nil
162163
}
163164

164165
func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool {
165-
ok := C._goboringcrypto_internal_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), pub.key) > 0
166+
ok := C._goboringcrypto_ECDSA_verify_raw(nil, base(hash), C.size_t(len(hash)),
167+
(*C.uint8_t)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), pub.key) > 0
166168
runtime.KeepAlive(pub)
167169
return ok
168170
}

openssl/goopenssl.h

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -499,22 +499,8 @@ _goboringcrypto_EC_KEY_oct2key(GO_EC_KEY *eckey, const unsigned char *buf, size_
499499

500500
#include <openssl/ecdsa.h>
501501

502-
typedef ECDSA_SIG GO_ECDSA_SIG;
503-
504-
DEFINEFUNC(GO_ECDSA_SIG *, ECDSA_SIG_new, (void), ())
505-
DEFINEFUNC(void, ECDSA_SIG_free, (GO_ECDSA_SIG * arg0), (arg0))
506-
DEFINEFUNC(GO_ECDSA_SIG *, ECDSA_do_sign, (const uint8_t *arg0, size_t arg1, const GO_EC_KEY *arg2), (arg0, arg1, arg2))
507-
DEFINEFUNC(int, ECDSA_do_verify, (const uint8_t *arg0, size_t arg1, const GO_ECDSA_SIG *arg2, GO_EC_KEY *arg3), (arg0, arg1, arg2, arg3))
508502
DEFINEFUNC(size_t, ECDSA_size, (const GO_EC_KEY *arg0), (arg0))
509503

510-
DEFINEFUNCINTERNAL(int, ECDSA_sign,
511-
(int type, const unsigned char *dgst, size_t dgstlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey),
512-
(type, dgst, dgstlen, sig, siglen, eckey))
513-
514-
DEFINEFUNCINTERNAL(int, ECDSA_verify,
515-
(int type, const unsigned char *dgst, size_t dgstlen, const unsigned char *sig, unsigned int siglen, EC_KEY *eckey),
516-
(type, dgst, dgstlen, sig, siglen, eckey))
517-
518504
#if OPENSSL_VERSION_NUMBER < 0x10100000L
519505
DEFINEFUNC(EVP_MD_CTX*, EVP_MD_CTX_create, (void), ())
520506
#else
@@ -578,6 +564,13 @@ DEFINEFUNC(void, EVP_MD_CTX_free, (EVP_MD_CTX *ctx), (ctx))
578564

579565
int _goboringcrypto_ECDSA_sign(EVP_MD *md, const uint8_t *arg1, size_t arg2, uint8_t *arg3, size_t *arg4, GO_EC_KEY *arg5);
580566
int _goboringcrypto_ECDSA_verify(EVP_MD *md, const uint8_t *arg1, size_t arg2, const uint8_t *arg3, unsigned int arg4, GO_EC_KEY *arg5);
567+
int _goboringcrypto_ECDSA_sign_raw(EVP_MD *md, const uint8_t *msg,
568+
size_t msgLen, uint8_t *sig, size_t *slen,
569+
GO_EC_KEY *ec_key);
570+
int _goboringcrypto_ECDSA_verify_raw(EVP_MD *md,
571+
const uint8_t *msg, size_t msgLen,
572+
const uint8_t *sig, unsigned int slen,
573+
GO_EC_KEY *ec_key);
581574

582575
#include <openssl/rsa.h>
583576

openssl/notboring.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,16 @@ func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error)
5858
func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) {
5959
panic("boringcrypto: not available")
6060
}
61-
func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s BigInt, err error) {
61+
func HashSignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s BigInt, err error) {
6262
panic("boringcrypto: not available")
6363
}
64-
func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) ([]byte, error) {
64+
func HashVerifyECDSA(pub *PublicKeyECDSA, msg []byte, r, s *big.Int, h crypto.Hash) bool {
6565
panic("boringcrypto: not available")
6666
}
67-
func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s BigInt, h crypto.Hash) bool {
67+
func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
68+
panic("boringcrypto: not available")
69+
}
70+
func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s BigInt) bool {
6871
panic("boringcrypto: not available")
6972
}
7073

openssl/openssl_ecdsa_signature.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,78 @@ int _goboringcrypto_ECDSA_verify(EVP_MD *md, const uint8_t *msg, size_t msgLen,
4444
_goboringcrypto_EVP_PKEY_free(key);
4545
return result;
4646
}
47+
48+
int _goboringcrypto_ECDSA_sign_raw(EVP_MD *md, const uint8_t *msg,
49+
size_t msgLen, uint8_t *sig, size_t *slen,
50+
GO_EC_KEY *ec_key) {
51+
int ret = 0;
52+
GO_EVP_PKEY_CTX *ctx = NULL;
53+
GO_EVP_PKEY *pkey = NULL;
54+
55+
pkey = _goboringcrypto_EVP_PKEY_new();
56+
if (!pkey)
57+
goto err;
58+
59+
if (_goboringcrypto_EVP_PKEY_set1_EC_KEY(pkey, ec_key) != 1)
60+
goto err;
61+
62+
ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL);
63+
if (!ctx)
64+
goto err;
65+
66+
if (_goboringcrypto_EVP_PKEY_sign_init(ctx) != 1)
67+
goto err;
68+
69+
if (md && _goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) != 1)
70+
goto err;
71+
72+
if (_goboringcrypto_EVP_PKEY_sign(ctx, sig, slen, msg, msgLen) != 1)
73+
goto err;
74+
75+
/* Success */
76+
ret = 1;
77+
78+
err:
79+
_goboringcrypto_EVP_PKEY_CTX_free(ctx);
80+
_goboringcrypto_EVP_PKEY_free(pkey);
81+
82+
return ret;
83+
}
84+
85+
int _goboringcrypto_ECDSA_verify_raw(EVP_MD *md,
86+
const uint8_t *msg, size_t msgLen,
87+
const uint8_t *sig, unsigned int slen,
88+
GO_EC_KEY *ec_key) {
89+
int ret = 0;
90+
GO_EVP_PKEY_CTX *ctx = NULL;
91+
GO_EVP_PKEY *pkey = NULL;
92+
93+
pkey = _goboringcrypto_EVP_PKEY_new();
94+
if (!pkey)
95+
goto err;
96+
97+
if (_goboringcrypto_EVP_PKEY_set1_EC_KEY(pkey, ec_key) != 1)
98+
goto err;
99+
100+
ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL);
101+
if (!ctx)
102+
goto err;
103+
104+
if (_goboringcrypto_EVP_PKEY_verify_init(ctx) != 1)
105+
goto err;
106+
107+
if (md && _goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) != 1)
108+
goto err;
109+
110+
if (_goboringcrypto_EVP_PKEY_verify(ctx, sig, slen, msg, msgLen) != 1)
111+
goto err;
112+
113+
/* Success */
114+
ret = 1;
115+
116+
err:
117+
_goboringcrypto_EVP_PKEY_CTX_free(ctx);
118+
_goboringcrypto_EVP_PKEY_free(pkey);
119+
120+
return ret;
121+
}

0 commit comments

Comments
 (0)