diff options
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. |
