summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2018-08-29 19:18:20 +0000
committertb <>2018-08-29 19:18:20 +0000
commit261d8fa7686e3eb82020d3c6d5d7aacdb78e6eb7 (patch)
treeab6e8f747a3a7bd048cfd41020ff0161f2fd06a0 /src
parentbf83c1a361dfac65b5a7175e00cebfd1200801d0 (diff)
downloadopenbsd-261d8fa7686e3eb82020d3c6d5d7aacdb78e6eb7.tar.gz
openbsd-261d8fa7686e3eb82020d3c6d5d7aacdb78e6eb7.tar.bz2
openbsd-261d8fa7686e3eb82020d3c6d5d7aacdb78e6eb7.zip
Run Wycheproof AES-GCM testvectors against libcrypto.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go125
1 files changed, 83 insertions, 42 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index 9022279346..55f6858e89 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.34 2018/08/29 19:00:41 tb Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.35 2018/08/29 19:18:20 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> 4 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
@@ -75,15 +75,15 @@ type wycheproofTestAesCbcPkcs5 struct {
75 Flags []string `json:"flags"` 75 Flags []string `json:"flags"`
76} 76}
77 77
78type wycheproofTestGroupAesCcm struct { 78type wycheproofTestGroupAesCcmOrGcm struct {
79 IVSize int `json:"ivSize"` 79 IVSize int `json:"ivSize"`
80 KeySize int `json:"keySize"` 80 KeySize int `json:"keySize"`
81 TagSize int `json:"tagSize"` 81 TagSize int `json:"tagSize"`
82 Type string `json:"type"` 82 Type string `json:"type"`
83 Tests []*wycheproofTestAesCcm `json:"tests"` 83 Tests []*wycheproofTestAesCcmOrGcm `json:"tests"`
84} 84}
85 85
86type wycheproofTestAesCcm struct { 86type wycheproofTestAesCcmOrGcm struct {
87 TCID int `json:"tcId"` 87 TCID int `json:"tcId"`
88 Comment string `json:"comment"` 88 Comment string `json:"comment"`
89 Key string `json:"key"` 89 Key string `json:"key"`
@@ -412,7 +412,22 @@ func runAesCbcPkcs5TestGroup(wtg *wycheproofTestGroupAesCbcPkcs5) bool {
412 return success 412 return success
413} 413}
414 414
415func checkAesCcm(ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, iv []byte, ivLen int, aad []byte, aadLen int, in []byte, inLen int, out []byte, outLen int, tag []byte, tagLen int, wt *wycheproofTestAesCcm) bool { 415func checkAesCcmOrGcm(algorithm string, ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, iv []byte, ivLen int, aad []byte, aadLen int, in []byte, inLen int, out []byte, outLen int, tag []byte, tagLen int, wt *wycheproofTestAesCcmOrGcm) bool {
416 var ctrlSetIVLen C.int
417 var ctrlSetTag C.int
418 var ctrlGetTag C.int
419
420 switch algorithm {
421 case "AES-CCM":
422 ctrlSetIVLen = C.EVP_CTRL_CCM_SET_IVLEN
423 ctrlSetTag = C.EVP_CTRL_CCM_SET_TAG
424 ctrlGetTag = C.EVP_CTRL_CCM_GET_TAG
425 case "AES-GCM":
426 ctrlSetIVLen = C.EVP_CTRL_GCM_SET_IVLEN
427 ctrlSetTag = C.EVP_CTRL_GCM_SET_TAG
428 ctrlGetTag = C.EVP_CTRL_GCM_GET_TAG
429 }
430
416 setTag := unsafe.Pointer(nil) 431 setTag := unsafe.Pointer(nil)
417 var action string 432 var action string
418 433
@@ -428,22 +443,24 @@ func checkAesCcm(ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, i
428 log.Fatalf("[%v] cipher init failed", action) 443 log.Fatalf("[%v] cipher init failed", action)
429 } 444 }
430 445
431 ret = C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_CCM_SET_IVLEN, C.int(ivLen), nil) 446 ret = C.EVP_CIPHER_CTX_ctrl(ctx, ctrlSetIVLen, C.int(ivLen), nil)
432 if ret != 1 { 447 if ret != 1 {
433 if wt.Comment == "Nonce is too long" || wt.Comment == "Invalid nonce size" { 448 if wt.Comment == "Nonce is too long" || wt.Comment == "Invalid nonce size" || wt.Comment == "0 size IV is not valid" {
434 return true 449 return true
435 } 450 }
436 fmt.Printf("FAIL: Test case %d (%q) [%v] - setting IV len to %d failed. got %d, want %v\n", wt.TCID, wt.Comment, action, ivLen, ret, wt.Result) 451 fmt.Printf("FAIL: Test case %d (%q) [%v] - setting IV len to %d failed. got %d, want %v\n", wt.TCID, wt.Comment, action, ivLen, ret, wt.Result)
437 return false 452 return false
438 } 453 }
439 454
440 ret = C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_CCM_SET_TAG, C.int(tagLen), setTag) 455 if doEncrypt == 0 || algorithm == "AES-CCM" {
441 if ret != 1 { 456 ret = C.EVP_CIPHER_CTX_ctrl(ctx, ctrlSetTag, C.int(tagLen), setTag)
442 if wt.Comment == "Invalid tag size" { 457 if ret != 1 {
443 return true 458 if wt.Comment == "Invalid tag size" {
459 return true
460 }
461 fmt.Printf("FAIL: Test case %d (%q) [%v] - setting tag length to %d failed. got %d, want %v\n", wt.TCID, wt.Comment, action, tagLen, ret, wt.Result)
462 return false
444 } 463 }
445 fmt.Printf("FAIL: Test case %d (%q) [%v] - setting tag length to %d failed. got %d, want %v\n", wt.TCID, wt.Comment, action, tagLen, ret, wt.Result)
446 return false
447 } 464 }
448 465
449 ret = C.EVP_CipherInit_ex(ctx, nil, nil, (*C.uchar)(unsafe.Pointer(&key[0])), (*C.uchar)(unsafe.Pointer(&iv[0])), C.int(doEncrypt)) 466 ret = C.EVP_CipherInit_ex(ctx, nil, nil, (*C.uchar)(unsafe.Pointer(&key[0])), (*C.uchar)(unsafe.Pointer(&iv[0])), C.int(doEncrypt))
@@ -453,10 +470,12 @@ func checkAesCcm(ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, i
453 } 470 }
454 471
455 var cipherOutLen C.int 472 var cipherOutLen C.int
456 ret = C.EVP_CipherUpdate(ctx, nil, &cipherOutLen, nil, C.int(inLen)) 473 if algorithm == "AES-CCM" {
457 if ret != 1 { 474 ret = C.EVP_CipherUpdate(ctx, nil, &cipherOutLen, nil, C.int(inLen))
458 fmt.Printf("FAIL: Test case %d (%q) [%v] - setting input length to %d failed. got %d, want %v\n", wt.TCID, wt.Comment, action, inLen, ret, wt.Result) 475 if ret != 1 {
459 return false 476 fmt.Printf("FAIL: Test case %d (%q) [%v] - setting input length to %d failed. got %d, want %v\n", wt.TCID, wt.Comment, action, inLen, ret, wt.Result)
477 return false
478 }
460 } 479 }
461 480
462 ret = C.EVP_CipherUpdate(ctx, nil, &cipherOutLen, (*C.uchar)(unsafe.Pointer(&aad[0])), C.int(aadLen)) 481 ret = C.EVP_CipherUpdate(ctx, nil, &cipherOutLen, (*C.uchar)(unsafe.Pointer(&aad[0])), C.int(aadLen))
@@ -504,12 +523,13 @@ func checkAesCcm(ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, i
504 } 523 }
505 if doEncrypt == 1 { 524 if doEncrypt == 1 {
506 tagOut := make([]byte, tagLen) 525 tagOut := make([]byte, tagLen)
507 ret = C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_CCM_GET_TAG, C.int(tagLen), unsafe.Pointer(&tagOut[0])) 526 ret = C.EVP_CIPHER_CTX_ctrl(ctx, ctrlGetTag, C.int(tagLen), unsafe.Pointer(&tagOut[0]))
508 if ret != 1 { 527 if ret != 1 {
509 fmt.Printf("FAIL: Test case %d (%q) [%v] - EVP_CIPHER_CTX_ctrl() failed: got %d, want %v\n", wt.TCID, wt.Comment, action, ret, wt.Result) 528 fmt.Printf("FAIL: Test case %d (%q) [%v] - EVP_CIPHER_CTX_ctrl() failed: got %d, want %v\n", wt.TCID, wt.Comment, action, ret, wt.Result)
510 return false 529 return false
511 } 530 }
512 if bytes.Equal(tagOut, tag) != (wt.Result == "valid") { 531 // XXX audit acceptable cases...
532 if bytes.Equal(tagOut, tag) != (wt.Result == "valid" || wt.Result == "acceptable") {
513 fmt.Printf("FAIL: Test case %d (%q) [%v] - expected and computed tag do not match. Result: %v\n", wt.TCID, wt.Comment, action, ret, wt.Result) 533 fmt.Printf("FAIL: Test case %d (%q) [%v] - expected and computed tag do not match. Result: %v\n", wt.TCID, wt.Comment, action, ret, wt.Result)
514 success = false 534 success = false
515 } 535 }
@@ -517,7 +537,7 @@ func checkAesCcm(ctx *C.EVP_CIPHER_CTX, doEncrypt int, key []byte, keyLen int, i
517 return success 537 return success
518} 538}
519 539
520func runAesCcmTest(ctx *C.EVP_CIPHER_CTX, wt *wycheproofTestAesCcm) bool { 540func runAesCcmOrGcmTest(algorithm string, ctx *C.EVP_CIPHER_CTX, wt *wycheproofTestAesCcmOrGcm) bool {
521 key, err := hex.DecodeString(wt.Key) 541 key, err := hex.DecodeString(wt.Key)
522 if err != nil { 542 if err != nil {
523 log.Fatalf("Failed to decode key %q: %v", wt.Key, err) 543 log.Fatalf("Failed to decode key %q: %v", wt.Key, err)
@@ -569,26 +589,41 @@ func runAesCcmTest(ctx *C.EVP_CIPHER_CTX, wt *wycheproofTestAesCcm) bool {
569 tag = append(tag, 0) 589 tag = append(tag, 0)
570 } 590 }
571 591
572 openSuccess := checkAesCcm(ctx, 0, key, keyLen, iv, ivLen, aad, aadLen, ct, ctLen, msg, msgLen, tag, tagLen, wt) 592 openSuccess := checkAesCcmOrGcm(algorithm, ctx, 0, key, keyLen, iv, ivLen, aad, aadLen, ct, ctLen, msg, msgLen, tag, tagLen, wt)
573 sealSuccess := checkAesCcm(ctx, 1, key, keyLen, iv, ivLen, aad, aadLen, msg, msgLen, ct, ctLen, tag, tagLen, wt) 593 sealSuccess := checkAesCcmOrGcm(algorithm, ctx, 1, key, keyLen, iv, ivLen, aad, aadLen, msg, msgLen, ct, ctLen, tag, tagLen, wt)
574 594
575 return openSuccess && sealSuccess 595 return openSuccess && sealSuccess
576} 596}
577 597
578func runAesCcmTestGroup(wtg *wycheproofTestGroupAesCcm) bool { 598func runAesCcmOrGcmTestGroup(algorithm string, wtg *wycheproofTestGroupAesCcmOrGcm) bool {
579 fmt.Printf("Running AES-CCM test group %v with IV size %d, key size %d and tag size %d...\n", wtg.Type, wtg.IVSize, wtg.KeySize, wtg.TagSize) 599 fmt.Printf("Running %v test group %v with IV size %d, key size %d and tag size %d...\n", algorithm, wtg.Type, wtg.IVSize, wtg.KeySize, wtg.TagSize)
580 600
581 var cipher *C.EVP_CIPHER 601 var cipher *C.EVP_CIPHER
582 switch wtg.KeySize { 602 switch algorithm {
583 case 128: 603 case "AES-CCM":
584 cipher = C.EVP_aes_128_ccm() 604 switch wtg.KeySize {
585 case 192: 605 case 128:
586 cipher = C.EVP_aes_192_ccm() 606 cipher = C.EVP_aes_128_ccm()
587 case 256: 607 case 192:
588 cipher = C.EVP_aes_256_ccm() 608 cipher = C.EVP_aes_192_ccm()
589 default: 609 case 256:
590 fmt.Printf("INFO: Skipping tests with invalid key size %d\n", wtg.KeySize) 610 cipher = C.EVP_aes_256_ccm()
591 return true 611 default:
612 fmt.Printf("INFO: Skipping tests with invalid key size %d\n", wtg.KeySize)
613 return true
614 }
615 case "AES-GCM":
616 switch wtg.KeySize {
617 case 128:
618 cipher = C.EVP_aes_128_gcm()
619 case 192:
620 cipher = C.EVP_aes_192_gcm()
621 case 256:
622 cipher = C.EVP_aes_256_gcm()
623 default:
624 fmt.Printf("INFO: Skipping tests with invalid key size %d\n", wtg.KeySize)
625 return true
626 }
592 } 627 }
593 628
594 ctx := C.EVP_CIPHER_CTX_new() 629 ctx := C.EVP_CIPHER_CTX_new()
@@ -601,7 +636,7 @@ func runAesCcmTestGroup(wtg *wycheproofTestGroupAesCcm) bool {
601 636
602 success := true 637 success := true
603 for _, wt := range wtg.Tests { 638 for _, wt := range wtg.Tests {
604 if !runAesCcmTest(ctx, wt) { 639 if !runAesCcmOrGcmTest(algorithm, ctx, wt) {
605 success = false 640 success = false
606 } 641 }
607 } 642 }
@@ -1204,9 +1239,11 @@ func runTestVectors(path string) bool {
1204 case "AES-CBC-PKCS5": 1239 case "AES-CBC-PKCS5":
1205 wtg = &wycheproofTestGroupAesCbcPkcs5{} 1240 wtg = &wycheproofTestGroupAesCbcPkcs5{}
1206 case "AES-CCM": 1241 case "AES-CCM":
1207 wtg = &wycheproofTestGroupAesCcm{} 1242 wtg = &wycheproofTestGroupAesCcmOrGcm{}
1208 case "AES-CMAC": 1243 case "AES-CMAC":
1209 wtg = &wycheproofTestGroupAesCmac{} 1244 wtg = &wycheproofTestGroupAesCmac{}
1245 case "AES-GCM":
1246 wtg = &wycheproofTestGroupAesCcmOrGcm{}
1210 case "CHACHA20-POLY1305": 1247 case "CHACHA20-POLY1305":
1211 wtg = &wycheproofTestGroupChaCha20Poly1305{} 1248 wtg = &wycheproofTestGroupChaCha20Poly1305{}
1212 case "DSA": 1249 case "DSA":
@@ -1232,13 +1269,17 @@ func runTestVectors(path string) bool {
1232 success = false 1269 success = false
1233 } 1270 }
1234 case "AES-CCM": 1271 case "AES-CCM":
1235 if !runAesCcmTestGroup(wtg.(*wycheproofTestGroupAesCcm)) { 1272 if !runAesCcmOrGcmTestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupAesCcmOrGcm)) {
1236 success = false 1273 success = false
1237 } 1274 }
1238 case "AES-CMAC": 1275 case "AES-CMAC":
1239 if !runAesCmacTestGroup(wtg.(*wycheproofTestGroupAesCmac)) { 1276 if !runAesCmacTestGroup(wtg.(*wycheproofTestGroupAesCmac)) {
1240 success = false 1277 success = false
1241 } 1278 }
1279 case "AES-GCM":
1280 if !runAesCcmOrGcmTestGroup(wtv.Algorithm, wtg.(*wycheproofTestGroupAesCcmOrGcm)) {
1281 success = false
1282 }
1242 case "CHACHA20-POLY1305": 1283 case "CHACHA20-POLY1305":
1243 if !runChaCha20Poly1305TestGroup(wtg.(*wycheproofTestGroupChaCha20Poly1305)) { 1284 if !runChaCha20Poly1305TestGroup(wtg.(*wycheproofTestGroupChaCha20Poly1305)) {
1244 success = false 1285 success = false
@@ -1278,7 +1319,7 @@ func main() {
1278 name string 1319 name string
1279 pattern string 1320 pattern string
1280 }{ 1321 }{
1281 {"AES", "aes_c*test.json"}, 1322 {"AES", "aes_[cg]*[^xv]_test.json"}, // Skip AES-EAX, AES-GCM-SIV and AES-SIV-CMAC.
1282 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"}, 1323 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"},
1283 {"DSA", "dsa_test.json"}, 1324 {"DSA", "dsa_test.json"},
1284 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. 1325 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now.