summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2018-08-10 16:22:58 +0000
committerjsing <>2018-08-10 16:22:58 +0000
commite6625680fe64e577e004e285005ccd4500eb7437 (patch)
treefb3a69e57f165cff00e728e11466873646c3b963 /src
parent147f7e731ee7fba4625e336ab845bf98406dff14 (diff)
downloadopenbsd-e6625680fe64e577e004e285005ccd4500eb7437.tar.gz
openbsd-e6625680fe64e577e004e285005ccd4500eb7437.tar.bz2
openbsd-e6625680fe64e577e004e285005ccd4500eb7437.zip
Run the wycheproof ECDSA test vectors against libcrypto.
Skip the ecdsa_webcrypto_test.json vectors for the time being, as these likely need some extra glue.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go154
1 files changed, 147 insertions, 7 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index 427dc47aec..d145723877 100644
--- a/src/regress/lib/libcrypto/wycheproof/wycheproof.go
+++ b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
@@ -1,4 +1,4 @@
1/* $OpenBSD: wycheproof.go,v 1.4 2018/08/10 16:18:55 jsing Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.5 2018/08/10 16:22:58 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -23,6 +23,8 @@ package main
23 23
24#include <openssl/bn.h> 24#include <openssl/bn.h>
25#include <openssl/curve25519.h> 25#include <openssl/curve25519.h>
26#include <openssl/ec.h>
27#include <openssl/ecdsa.h>
26#include <openssl/objects.h> 28#include <openssl/objects.h>
27#include <openssl/rsa.h> 29#include <openssl/rsa.h>
28*/ 30*/
@@ -46,6 +48,33 @@ import (
46 48
47const testVectorPath = "/usr/local/share/wycheproof/testvectors" 49const testVectorPath = "/usr/local/share/wycheproof/testvectors"
48 50
51type wycheproofECDSAKey struct {
52 Curve string `json:"curve"`
53 KeySize int `json:"keySize"`
54 Type string `json:"type"`
55 Uncompressed string `json:"uncompressed"`
56 WX string `json:"wx"`
57 WY string `json:"wy"`
58}
59
60type wycheproofTestECDSA struct {
61 TCID int `json:"tcId"`
62 Comment string `json:"comment"`
63 Msg string `json:"msg"`
64 Sig string `json:"sig"`
65 Result string `json:"result"`
66 Flags []string `json:"flags"`
67}
68
69type wycheproofTestGroupECDSA struct {
70 Key *wycheproofECDSAKey `json:"key"`
71 KeyDER string `json:"keyDer"`
72 KeyPEM string `json:"keyPem"`
73 SHA string `json:"sha"`
74 Type string `json:"type"`
75 Tests []*wycheproofTestECDSA `json:"tests"`
76}
77
49type wycheproofTestRSA struct { 78type wycheproofTestRSA struct {
50 TCID int `json:"tcId"` 79 TCID int `json:"tcId"`
51 Comment string `json:"comment"` 80 Comment string `json:"comment"`
@@ -94,11 +123,25 @@ type wycheproofTestVectors struct {
94} 123}
95 124
96var nids = map[string]int{ 125var nids = map[string]int{
97 "SHA-1": C.NID_sha1, 126 "brainpoolP224r1": C.NID_brainpoolP224r1,
98 "SHA-224": C.NID_sha224, 127 "brainpoolP256r1": C.NID_brainpoolP256r1,
99 "SHA-256": C.NID_sha256, 128 "brainpoolP320r1": C.NID_brainpoolP320r1,
100 "SHA-384": C.NID_sha384, 129 "brainpoolP384r1": C.NID_brainpoolP384r1,
101 "SHA-512": C.NID_sha512, 130 "brainpoolP512r1": C.NID_brainpoolP512r1,
131 "brainpoolP224t1": C.NID_brainpoolP224t1,
132 "brainpoolP256t1": C.NID_brainpoolP256t1,
133 "brainpoolP320t1": C.NID_brainpoolP320t1,
134 "brainpoolP384t1": C.NID_brainpoolP384t1,
135 "brainpoolP512t1": C.NID_brainpoolP512t1,
136 "secp224r1": C.NID_secp224r1,
137 "secp256k1": C.NID_secp256k1,
138 "secp384r1": C.NID_secp384r1,
139 "secp521r1": C.NID_secp521r1,
140 "SHA-1": C.NID_sha1,
141 "SHA-224": C.NID_sha224,
142 "SHA-256": C.NID_sha256,
143 "SHA-384": C.NID_sha384,
144 "SHA-512": C.NID_sha512,
102} 145}
103 146
104func nidFromString(ns string) (int, error) { 147func nidFromString(ns string) (int, error) {
@@ -126,6 +169,96 @@ func hashFromString(hs string) (hash.Hash, error) {
126 } 169 }
127} 170}
128 171
172func runECDSATest(ecKey *C.EC_KEY, nid int, h hash.Hash, wt *wycheproofTestECDSA) bool {
173 msg, err := hex.DecodeString(wt.Msg)
174 if err != nil {
175 log.Fatalf("Failed to decode message %q: %v", wt.Msg, err)
176 }
177
178 h.Reset()
179 h.Write(msg)
180 msg = h.Sum(nil)
181
182 sig, err := hex.DecodeString(wt.Sig)
183 if err != nil {
184 log.Fatalf("Failed to decode signature %q: %v", wt.Sig, err)
185 }
186
187 msgLen, sigLen := len(msg), len(sig)
188 if msgLen == 0 {
189 msg = append(msg, 0)
190 }
191 if sigLen == 0 {
192 sig = append(sig, 0)
193 }
194 ret := C.ECDSA_verify(0, (*C.uchar)(unsafe.Pointer(&msg[0])), C.int(msgLen),
195 (*C.uchar)(unsafe.Pointer(&sig[0])), C.int(sigLen), ecKey)
196
197 // XXX audit acceptable cases...
198 success := true
199 if (ret == 1) != (wt.Result == "valid") && wt.Result != "acceptable" {
200 fmt.Printf("FAIL: Test case %d (%q) - ECDSA_verify() = %d, want %v\n", wt.TCID, wt.Comment, int(ret), wt.Result)
201 success = false
202 }
203 return success
204}
205
206func runECDSATestGroup(wtg *wycheproofTestGroupECDSA) bool {
207 // No secp256r1 support.
208 if wtg.Key.Curve == "secp256r1" {
209 return true
210 }
211
212 fmt.Printf("Running ECDSA test group %v with curve %v, key size %d and %v...\n", wtg.Type, wtg.Key.Curve, wtg.Key.KeySize, wtg.SHA)
213
214 nid, err := nidFromString(wtg.Key.Curve)
215 if err != nil {
216 log.Fatalf("Failed to get nid for curve: %v", err)
217 }
218 ecKey := C.EC_KEY_new_by_curve_name(C.int(nid))
219 if ecKey == nil {
220 log.Fatal("EC_KEY_new_by_curve_name failed")
221 }
222 defer C.EC_KEY_free(ecKey)
223
224 var bnX *C.BIGNUM
225 wx := C.CString(wtg.Key.WX)
226 if C.BN_hex2bn(&bnX, wx) == 0 {
227 log.Fatal("Failed to decode WX")
228 }
229 C.free(unsafe.Pointer(wx))
230 defer C.BN_free(bnX)
231
232 var bnY *C.BIGNUM
233 wy := C.CString(wtg.Key.WY)
234 if C.BN_hex2bn(&bnY, wy) == 0 {
235 log.Fatal("Failed to decode WY")
236 }
237 C.free(unsafe.Pointer(wy))
238 defer C.BN_free(bnY)
239
240 if C.EC_KEY_set_public_key_affine_coordinates(ecKey, bnX, bnY) != 1 {
241 log.Fatal("Failed to set EC public key")
242 }
243
244 nid, err = nidFromString(wtg.SHA)
245 if err != nil {
246 log.Fatalf("Failed to get MD NID: %v", err)
247 }
248 h, err := hashFromString(wtg.SHA)
249 if err != nil {
250 log.Fatalf("Failed to get hash: %v", err)
251 }
252
253 success := true
254 for _, wt := range wtg.Tests {
255 if !runECDSATest(ecKey, nid, h, wt) {
256 success = false
257 }
258 }
259 return success
260}
261
129func runRSATest(rsa *C.RSA, nid int, h hash.Hash, wt *wycheproofTestRSA) bool { 262func runRSATest(rsa *C.RSA, nid int, h hash.Hash, wt *wycheproofTestRSA) bool {
130 msg, err := hex.DecodeString(wt.Msg) 263 msg, err := hex.DecodeString(wt.Msg)
131 if err != nil { 264 if err != nil {
@@ -257,6 +390,8 @@ func runTestVectors(path string) bool {
257 390
258 var wtg interface{} 391 var wtg interface{}
259 switch wtv.Algorithm { 392 switch wtv.Algorithm {
393 case "ECDSA":
394 wtg = &wycheproofTestGroupECDSA{}
260 case "RSASig": 395 case "RSASig":
261 wtg = &wycheproofTestGroupRSA{} 396 wtg = &wycheproofTestGroupRSA{}
262 case "X25519": 397 case "X25519":
@@ -271,6 +406,10 @@ func runTestVectors(path string) bool {
271 log.Fatalf("Failed to unmarshal test groups JSON: %v", err) 406 log.Fatalf("Failed to unmarshal test groups JSON: %v", err)
272 } 407 }
273 switch wtv.Algorithm { 408 switch wtv.Algorithm {
409 case "ECDSA":
410 if !runECDSATestGroup(wtg.(*wycheproofTestGroupECDSA)) {
411 success = false
412 }
274 case "RSASig": 413 case "RSASig":
275 if !runRSATestGroup(wtg.(*wycheproofTestGroupRSA)) { 414 if !runRSATestGroup(wtg.(*wycheproofTestGroupRSA)) {
276 success = false 415 success = false
@@ -293,11 +432,12 @@ func main() {
293 os.Exit(0) 432 os.Exit(0)
294 } 433 }
295 434
296 // TODO: AES, Chacha20Poly1305, DSA, ECDH, ECDSA, RSA-PSS. 435 // AES, Chacha20Poly1305, DSA, ECDH
297 tests := []struct { 436 tests := []struct {
298 name string 437 name string
299 pattern string 438 pattern string
300 }{ 439 }{
440 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now.
301 {"RSA signature", "rsa_signature_*test.json"}, 441 {"RSA signature", "rsa_signature_*test.json"},
302 {"X25519", "x25519_*test.json"}, 442 {"X25519", "x25519_*test.json"},
303 } 443 }