summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2018-08-27 20:58:02 +0000
committertb <>2018-08-27 20:58:02 +0000
commit0b0ed1b25513323adfcddff2f06752e192bfbed0 (patch)
tree6a4ae91e1cf155155c9fa1de7485205ad04bf264 /src
parentcf973d93a931fa3a2f6c7127e5bfbb0693d1d1a8 (diff)
downloadopenbsd-0b0ed1b25513323adfcddff2f06752e192bfbed0.tar.gz
openbsd-0b0ed1b25513323adfcddff2f06752e192bfbed0.tar.bz2
openbsd-0b0ed1b25513323adfcddff2f06752e192bfbed0.zip
Run Wycheproof AES-CCM testvectors against libcrypto.
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/wycheproof/wycheproof.go202
1 files changed, 200 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/wycheproof/wycheproof.go b/src/regress/lib/libcrypto/wycheproof/wycheproof.go
index 76e384fe55..ee9f533523 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.24 2018/08/26 17:43:39 tb Exp $ */ 1/* $OpenBSD: wycheproof.go,v 1.25 2018/08/27 20:58:02 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>
@@ -74,6 +74,27 @@ type wycheproofTestAesCbcPkcs5 struct {
74 Flags []string `json:"flags"` 74 Flags []string `json:"flags"`
75} 75}
76 76
77type wycheproofTestGroupAesCcm struct {
78 IVSize int `json:"ivSize"`
79 KeySize int `json:"keySize"`
80 TagSize int `json:"tagSize"`
81 Type string `json:"type"`
82 Tests []*wycheproofTestAesCcm `json:"tests"`
83}
84
85type wycheproofTestAesCcm struct {
86 TCID int `json:"tcId"`
87 Comment string `json:"comment"`
88 Key string `json:"key"`
89 IV string `json:"iv"`
90 AAD string `json:"aad"`
91 Msg string `json:"msg"`
92 CT string `json:"ct"`
93 Tag string `json:"tag"`
94 Result string `json:"result"`
95 Flags []string `json:"flags"`
96}
97
77type wycheproofTestGroupChaCha20Poly1305 struct { 98type wycheproofTestGroupChaCha20Poly1305 struct {
78 IVSize int `json:"ivSize"` 99 IVSize int `json:"ivSize"`
79 KeySize int `json:"keySize"` 100 KeySize int `json:"keySize"`
@@ -415,6 +436,177 @@ func runAesCbcPkcs5TestGroup(wtg *wycheproofTestGroupAesCbcPkcs5) bool {
415 return success 436 return success
416} 437}
417 438
439func 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 {
440 setTag := unsafe.Pointer(nil)
441 var action string
442
443 if doEncrypt == 1 {
444 action = "encrypting"
445 } else {
446 action = "decrypting"
447 setTag = unsafe.Pointer(&tag[0])
448 }
449
450 ret := C.EVP_CipherInit_ex(ctx, nil, nil, nil, nil, C.int(doEncrypt))
451 if ret != 1 {
452 log.Fatalf("[%v] cipher init failed", action)
453 }
454
455 ret = C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_CCM_SET_IVLEN, C.int(ivLen), nil)
456 if ret != 1 {
457 if (wt.Comment == "Nonce is too long" || wt.Comment == "Invalid nonce size") {
458 return true
459 }
460 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)
461 return false
462 }
463
464 ret = C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_CCM_SET_TAG, C.int(tagLen), setTag)
465 if ret != 1 {
466 if (wt.Comment == "Invalid tag size") {
467 return true
468 }
469 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)
470 return false
471 }
472
473 ret = C.EVP_CipherInit_ex(ctx, nil, nil, (*C.uchar)(unsafe.Pointer(&key[0])), (*C.uchar)(unsafe.Pointer(&iv[0])), C.int(doEncrypt))
474 if ret != 1 {
475 fmt.Printf("FAIL: Test case %d (%q) [%v]: setting key and IV failed. got %d, want %v\n", wt.TCID, wt.Comment, action, ret, wt.Result)
476 return false
477 }
478
479 var cipherOutLen C.int
480 ret = C.EVP_CipherUpdate(ctx, nil, &cipherOutLen, nil, C.int(inLen))
481 if ret != 1 {
482 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)
483 return false
484 }
485
486 ret = C.EVP_CipherUpdate(ctx, nil, &cipherOutLen, (*C.uchar)(unsafe.Pointer(&aad[0])), C.int(aadLen))
487 if ret != 1 {
488 fmt.Printf("FAIL: Test case %d (%q) [%v]: processing AAD failed. got %d, want %v\n", wt.TCID, wt.Comment, action, ret, wt.Result)
489 return false
490 }
491
492 cipherOutLen = 0
493 cipherOut := make([]byte, inLen)
494 if inLen == 0 {
495 cipherOut = append(cipherOut, 0)
496 }
497
498 ret = C.EVP_CipherUpdate(ctx, (*C.uchar)(unsafe.Pointer(&cipherOut[0])), &cipherOutLen, (*C.uchar)(unsafe.Pointer(&in[0])), C.int(inLen))
499 if ret != 1 {
500 if wt.Result == "invalid" {
501 return true
502 }
503 fmt.Printf("FAIL: Test case %d (%q) [%v]: EVP_CipherUpdate failed: got %d, want %v\n", wt.TCID, wt.Comment, action, ret, wt.Result)
504 return false
505 }
506
507 if cipherOutLen != C.int(outLen) {
508 fmt.Printf("FAIL: Test case %d (%q) [%v]: cipherOutLen %d != outLen %d. Result %v\n", wt.TCID, wt.Comment, cipherOutLen, action, outLen, wt.Result)
509 return false
510 }
511
512 success := true
513 if !bytes.Equal(cipherOut, out) {
514 fmt.Printf("FAIL: Test case %d (%q) [%v]: expected and computed output do not match. Result.%v\n", wt.TCID, wt.Comment, action, wt.Result)
515 success = false
516 }
517 return success
518}
519
520func runAesCcmTest(ctx *C.EVP_CIPHER_CTX, wt *wycheproofTestAesCcm) bool {
521 key, err := hex.DecodeString(wt.Key)
522 if err != nil {
523 log.Fatalf("Failed to decode key %q: %v", wt.Key, err)
524 }
525
526 iv, err := hex.DecodeString(wt.IV)
527 if err != nil {
528 log.Fatalf("Failed to decode IV %q: %v", wt.IV, err)
529 }
530
531 aad, err := hex.DecodeString(wt.AAD)
532 if err != nil {
533 log.Fatalf("Failed to decode AAD %q: %v", wt.AAD, err)
534 }
535
536 msg, err := hex.DecodeString(wt.Msg)
537 if err != nil {
538 log.Fatalf("Failed to decode msg %q: %v", wt.Msg, err)
539 }
540
541 ct, err := hex.DecodeString(wt.CT)
542 if err != nil {
543 log.Fatalf("Failed to decode CT %q: %v", wt.CT, err)
544 }
545
546 tag, err := hex.DecodeString(wt.Tag)
547 if err != nil {
548 log.Fatalf("Failed to decode tag %q: %v", wt.Tag, err)
549 }
550
551 keyLen, ivLen, aadLen, msgLen, ctLen, tagLen := len(key), len(iv), len(aad), len(msg), len(ct), len(tag)
552
553 if keyLen == 0 {
554 key = append(key, 0)
555 }
556 if ivLen == 0 {
557 iv = append(iv, 0)
558 }
559 if aadLen == 0 {
560 aad = append(aad, 0)
561 }
562 if msgLen == 0 {
563 msg = append(msg, 0)
564 }
565 if ctLen == 0 {
566 ct = append(ct, 0)
567 }
568 if tagLen == 0 {
569 tag = append(tag, 0)
570 }
571
572 openSuccess := checkAesCcm(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)
574
575 return openSuccess && sealSuccess
576}
577
578func runAesCcmTestGroup(wtg *wycheproofTestGroupAesCcm) 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)
580
581 var cipher *C.EVP_CIPHER
582 switch wtg.KeySize {
583 case 128:
584 cipher = C.EVP_aes_128_ccm()
585 case 192:
586 cipher = C.EVP_aes_192_ccm()
587 case 256:
588 cipher = C.EVP_aes_256_ccm()
589 default:
590 log.Fatalf("Unsupported key size: %d", wtg.KeySize)
591 }
592
593 ctx := C.EVP_CIPHER_CTX_new()
594 if ctx == nil {
595 log.Fatal("EVP_CIPHER_CTX_new() failed")
596 }
597 defer C.EVP_CIPHER_CTX_free(ctx)
598
599 C.EVP_CipherInit_ex(ctx, cipher, nil, nil, nil, 1)
600
601 success := true
602 for _, wt := range wtg.Tests {
603 if !runAesCcmTest(ctx, wt) {
604 success = false
605 }
606 }
607 return success
608}
609
418func checkChaCha20Poly1305Open(ctx *C.EVP_AEAD_CTX, iv []byte, ivLen int, aad []byte, aadLen int, msg []byte, msgLen int, ct []byte, ctLen int, tag []byte, tagLen int, wt *wycheproofTestChaCha20Poly1305) bool { 610func checkChaCha20Poly1305Open(ctx *C.EVP_AEAD_CTX, iv []byte, ivLen int, aad []byte, aadLen int, msg []byte, msgLen int, ct []byte, ctLen int, tag []byte, tagLen int, wt *wycheproofTestChaCha20Poly1305) bool {
419 maxOutLen := ctLen + tagLen 611 maxOutLen := ctLen + tagLen
420 612
@@ -920,6 +1112,8 @@ func runTestVectors(path string) bool {
920 switch wtv.Algorithm { 1112 switch wtv.Algorithm {
921 case "AES-CBC-PKCS5": 1113 case "AES-CBC-PKCS5":
922 wtg = &wycheproofTestGroupAesCbcPkcs5{} 1114 wtg = &wycheproofTestGroupAesCbcPkcs5{}
1115 case "AES-CCM":
1116 wtg = &wycheproofTestGroupAesCcm{}
923 case "CHACHA20-POLY1305": 1117 case "CHACHA20-POLY1305":
924 wtg = &wycheproofTestGroupChaCha20Poly1305{} 1118 wtg = &wycheproofTestGroupChaCha20Poly1305{}
925 case "DSA": 1119 case "DSA":
@@ -944,6 +1138,10 @@ func runTestVectors(path string) bool {
944 if !runAesCbcPkcs5TestGroup(wtg.(*wycheproofTestGroupAesCbcPkcs5)) { 1138 if !runAesCbcPkcs5TestGroup(wtg.(*wycheproofTestGroupAesCbcPkcs5)) {
945 success = false 1139 success = false
946 } 1140 }
1141 case "AES-CCM":
1142 if !runAesCcmTestGroup(wtg.(*wycheproofTestGroupAesCcm)) {
1143 success = false
1144 }
947 case "CHACHA20-POLY1305": 1145 case "CHACHA20-POLY1305":
948 if !runChaCha20Poly1305TestGroup(wtg.(*wycheproofTestGroupChaCha20Poly1305)) { 1146 if !runChaCha20Poly1305TestGroup(wtg.(*wycheproofTestGroupChaCha20Poly1305)) {
949 success = false 1147 success = false
@@ -983,7 +1181,7 @@ func main() {
983 name string 1181 name string
984 pattern string 1182 pattern string
985 }{ 1183 }{
986 {"AES", "aes_cbc*test.json"}, 1184 {"AES", "aes_c[bc]*test.json"},
987 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"}, 1185 {"ChaCha20-Poly1305", "chacha20_poly1305_test.json"},
988 {"DSA", "dsa_test.json"}, 1186 {"DSA", "dsa_test.json"},
989 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now. 1187 {"ECDSA", "ecdsa_[^w]*test.json"}, // Skip ecdsa_webcrypto_test.json for now.