summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go142
1 files changed, 141 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index d145723877..c00a869f6f 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.5 2018/08/10 16:22:58 jsing Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.6 2018/08/20 17:06:18 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -25,6 +25,7 @@ package main
25#include <openssl/curve25519.h> 25#include <openssl/curve25519.h>
26#include <openssl/ec.h> 26#include <openssl/ec.h>
27#include <openssl/ecdsa.h> 27#include <openssl/ecdsa.h>
28#include <openssl/evp.h>
28#include <openssl/objects.h> 29#include <openssl/objects.h>
29#include <openssl/rsa.h> 30#include <openssl/rsa.h>
30*/ 31*/
@@ -48,6 +49,27 @@ import (
48 49
49const testVectorPath = "/usr/local/share/wycheproof/testvectors" 50const testVectorPath = "/usr/local/share/wycheproof/testvectors"
50 51
52type wycheproofTestGroupChaCha20Poly1305 struct {
53 IVSize int `json:"ivSize"`
54 KeySize int `json:"keySize"`
55 TagSize int `json:"tagSize"`
56 Type string `json:"type"`
57 Tests []*wycheproofTestChaCha20Poly1305 `json:"tests"`
58}
59
60type wycheproofTestChaCha20Poly1305 struct {
61 TCID int `json:"tcId"`
62 Comment string `json:"comment"`
63 Key string `json:"key"`
64 IV string `json:"iv"`
65 AAD string `json:"aad"`
66 Msg string `json:"msg"`
67 CT string `json:"ct"`
68 Tag string `json:"tag"`
69 Result string `json:"result"`
70 Flags []string `json:"flags"`
71}
72
51type wycheproofECDSAKey struct { 73type wycheproofECDSAKey struct {
52 Curve string `json:"curve"` 74 Curve string `json:"curve"`
53 KeySize int `json:"keySize"` 75 KeySize int `json:"keySize"`
@@ -169,6 +191,117 @@ func hashFromString(hs string) (hash.Hash, error) {
169 } 191 }
170} 192}
171 193
194func runChaCha20Poly1305Test(iv_len int, key_len int, tag_len int, wt *wycheproofTestChaCha20Poly1305) bool {
195 aead := C.EVP_aead_chacha20_poly1305()
196 if aead == nil {
197 log.Fatal("EVP_aead_chacha20_poly1305 failed")
198 }
199
200 key, err := hex.DecodeString(wt.Key)
201 if err != nil {
202 log.Fatalf("Failed to decode key %q: %v", wt.Key, err)
203 }
204 if key_len != len(key) {
205 log.Fatalf("Key length mismatch: got %d, want %d", len(key), key_len)
206 }
207
208 var ctx C.EVP_AEAD_CTX
209 if C.EVP_AEAD_CTX_init((*C.EVP_AEAD_CTX)(unsafe.Pointer(&ctx)), aead, (*C.uchar)(unsafe.Pointer(&key[0])), C.size_t(key_len), C.size_t(tag_len), nil) != 1 {
210 log.Fatalf("Failed to initialize AEAD context")
211 }
212
213 iv, err := hex.DecodeString(wt.IV)
214 if err != nil {
215 log.Fatalf("Failed to decode key %q: %v", wt.IV, err)
216 }
217 if iv_len != len(iv) {
218 log.Fatalf("IV length mismatch: got %d, want %d", len(iv), iv_len)
219 }
220 aad, err := hex.DecodeString(wt.AAD)
221 if err != nil {
222 log.Fatalf("Failed to decode AAD %q: %v", wt.AAD, err)
223 }
224 msg, err := hex.DecodeString(wt.Msg)
225 if err != nil {
226 log.Fatalf("Failed to decode msg %q: %v", wt.Msg, err)
227 }
228
229 ivLen, aadLen, msgLen := len(iv), len(aad), len(msg)
230 if ivLen == 0 {
231 iv = append(iv, 0)
232 }
233 if aadLen == 0 {
234 aad = append(aad, 0)
235 }
236 if msgLen == 0 {
237 msg = append(msg, 0)
238 }
239
240 maxOutLen := msgLen + tag_len
241 out := make([]byte, maxOutLen)
242 var outLen C.size_t
243
244 ret := C.EVP_AEAD_CTX_seal((*C.EVP_AEAD_CTX)(unsafe.Pointer(&ctx)), (*C.uint8_t)(unsafe.Pointer(&out[0])), (*C.size_t)(unsafe.Pointer(&outLen)), C.size_t(maxOutLen), (*C.uint8_t)(unsafe.Pointer(&iv[0])), C.size_t(ivLen), (*C.uint8_t)(unsafe.Pointer(&msg[0])), C.size_t(msgLen), (*C.uint8_t)(unsafe.Pointer(&aad[0])), C.size_t(aadLen))
245
246 C.EVP_AEAD_CTX_cleanup((*C.EVP_AEAD_CTX)(unsafe.Pointer(&ctx)))
247
248 if ret != 1 && wt.Result == "invalid" {
249 fmt.Printf("INFO: Test case %d (%q) - EVP_AEAD_CTX_seal() = %d, want %v\n", wt.TCID, wt.Comment, int(ret), wt.Result)
250 return true
251 }
252
253 if (outLen != C.size_t(maxOutLen)) {
254 fmt.Printf("FAIL: Test case %d (%q) - ChaCha output length mismatch: got %d, want %d", wt.TCID, wt.Comment, outLen, maxOutLen)
255 return false
256 }
257
258 outCt := out[0:msgLen]
259 outTag := out[msgLen: maxOutLen]
260
261 ct, err := hex.DecodeString(wt.CT)
262 if err != nil {
263 log.Fatalf("Failed to decode ct %q: %v", wt.CT, err)
264 }
265 if len(ct) != msgLen {
266 fmt.Printf("FAIL: Test case %d (%q) - msg length %d doesn't match ct length %d", wt.TCID, wt.Comment, msgLen, len(ct))
267 return false
268 }
269 tag, err := hex.DecodeString(wt.Tag)
270 if err != nil {
271 log.Fatalf("Failed to decode tag %q: %v", wt.Tag, err)
272 }
273 if len(tag) != tag_len {
274 fmt.Printf("FAIL: Test case %d (%q) tag length: got %d, want %d", wt.TCID, wt.Comment, len(tag), tag_len)
275 return false
276 }
277
278 success := false
279 if (bytes.Equal(outCt, ct) && bytes.Equal(outTag, tag)) || wt.Result == "invalid" {
280 success = true
281 } else {
282 fmt.Printf("FAIL: Test case %d (%q) - EVP_AEAD_CTX_seal() = %d, ct match: %t, tag match: %t; want %v\n", wt.TCID, wt.Comment, int(ret), bytes.Equal(outCt, ct), bytes.Equal(outTag, tag), wt.Result)
283 }
284
285 return success
286}
287
288func runChaCha20Poly1305TestGroup(wtg *wycheproofTestGroupChaCha20Poly1305) bool {
289 // We currently only support nonces of length 12 (96 bits)
290 if wtg.IVSize != 96 {
291 return true
292 }
293
294 fmt.Printf("Running ChaCha20-Poly1305 test group %v with IV size %d, key size %d, tag size %d...\n", wtg.Type, wtg.IVSize, wtg.KeySize, wtg.TagSize)
295
296 success := true
297 for _, wt := range wtg.Tests {
298 if !runChaCha20Poly1305Test(wtg.IVSize / 8, wtg.KeySize / 8, wtg.TagSize / 8, wt) {
299 success = false
300 }
301 }
302 return success
303}
304
172func runECDSATest(ecKey *C.EC_KEY, nid int, h hash.Hash, wt *wycheproofTestECDSA) bool { 305func runECDSATest(ecKey *C.EC_KEY, nid int, h hash.Hash, wt *wycheproofTestECDSA) bool {
173 msg, err := hex.DecodeString(wt.Msg) 306 msg, err := hex.DecodeString(wt.Msg)
174 if err != nil { 307 if err != nil {
@@ -390,6 +523,8 @@ func runTestVectors(path string) bool {
390 523
391 var wtg interface{} 524 var wtg interface{}
392 switch wtv.Algorithm { 525 switch wtv.Algorithm {
526 case "CHACHA20-POLY1305":
527 wtg = &wycheproofTestGroupChaCha20Poly1305{}
393 case "ECDSA": 528 case "ECDSA":
394 wtg = &wycheproofTestGroupECDSA{} 529 wtg = &wycheproofTestGroupECDSA{}
395 case "RSASig": 530 case "RSASig":
@@ -406,6 +541,10 @@ func runTestVectors(path string) bool {
406 log.Fatalf("Failed to unmarshal test groups JSON: %v", err) 541 log.Fatalf("Failed to unmarshal test groups JSON: %v", err)
407 } 542 }
408 switch wtv.Algorithm { 543 switch wtv.Algorithm {
544 case "CHACHA20-POLY1305":
545 if !runChaCha20Poly1305TestGroup(wtg.(*wycheproofTestGroupChaCha20Poly1305)) {
546 success = false
547 }
409 case "ECDSA": 548 case "ECDSA":
410 if !runECDSATestGroup(wtg.(*wycheproofTestGroupECDSA)) { 549 if !runECDSATestGroup(wtg.(*wycheproofTestGroupECDSA)) {
411 success = false 550 success = false
@@ -437,6 +576,7 @@ func main() {
437 name string 576 name string
438 pattern string 577 pattern string
439 }{ 578 }{
579 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"},
440 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. 580 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now.
441 {"RSA signature", "rsa_signature_*test.json"}, 581 {"RSA signature", "rsa_signature_*test.json"},
442 {"X25519", "x25519_*test.json"}, 582 {"X25519", "x25519_*test.json"},