diff options
author | tb <> | 2018-08-29 19:18:20 +0000 |
---|---|---|
committer | tb <> | 2018-08-29 19:18:20 +0000 |
commit | 261d8fa7686e3eb82020d3c6d5d7aacdb78e6eb7 (patch) | |
tree | ab6e8f747a3a7bd048cfd41020ff0161f2fd06a0 /src | |
parent | bf83c1a361dfac65b5a7175e00cebfd1200801d0 (diff) | |
download | openbsd-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.go | 125 |
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 | ||
78 | type wycheproofTestGroupAesCcm struct { | 78 | type 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 | ||
86 | type wycheproofTestAesCcm struct { | 86 | type 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 | ||
415 | func 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 { | 415 | func 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 | ||
520 | func runAesCcmTest(ctx *C.EVP_CIPHER_CTX, wt *wycheproofTestAesCcm) bool { | 540 | func 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 | ||
578 | func runAesCcmTestGroup(wtg *wycheproofTestGroupAesCcm) bool { | 598 | func 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. |