| ... | @@ -470,10 +470,9 @@ pub fn chacha20poly1305Seal(dst: []u8, plaintext: []const u8, data: []const u8, | ... | @@ -470,10 +470,9 @@ pub fn chacha20poly1305Seal(dst: []u8, plaintext: []const u8, data: []const u8, |
| 470 | } | 470 | } |
| 471 | | 471 | |
| 472 | /// Verifies and decrypts an authenticated message produced by chacha20poly1305Open. | 472 | /// Verifies and decrypts an authenticated message produced by chacha20poly1305Open. |
| 473 | /// Returns false if message was invalid or authentication failed. | 473 | pub fn chacha20poly1305Open(dst: []u8, ciphertext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { |
| 474 | pub fn chacha20poly1305Open(dst: []u8, ciphertext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) bool { | | |
| 475 | if (ciphertext.len < chacha20poly1305_tag_size) { | 474 | if (ciphertext.len < chacha20poly1305_tag_size) { |
| 476 | return false; | 475 | return error.InvalidMessage; |
| 477 | } | 476 | } |
| 478 | | 477 | |
| 479 | // split ciphertext and tag | 478 | // split ciphertext and tag |
| ... | @@ -515,12 +514,11 @@ pub fn chacha20poly1305Open(dst: []u8, ciphertext: []const u8, data: []const u8, | ... | @@ -515,12 +514,11 @@ pub fn chacha20poly1305Open(dst: []u8, ciphertext: []const u8, data: []const u8, |
| 515 | acc |= (computedTag[i] ^ polyTag[i]); | 514 | acc |= (computedTag[i] ^ polyTag[i]); |
| 516 | } | 515 | } |
| 517 | if (acc != 0) { | 516 | if (acc != 0) { |
| 518 | return false; | 517 | return error.AuthenticationFailed; |
| 519 | } | 518 | } |
| 520 | | 519 | |
| 521 | // decrypt ciphertext | 520 | // decrypt ciphertext |
| 522 | chaCha20IETF(dst[0..ciphertext.len], ciphertext, 1, key, nonce); | 521 | chaCha20IETF(dst[0..ciphertext.len], ciphertext, 1, key, nonce); |
| 523 | return true; | | |
| 524 | } | 522 | } |
| 525 | | 523 | |
| 526 | test "seal" { | 524 | test "seal" { |
| ... | @@ -585,8 +583,7 @@ test "open" { | ... | @@ -585,8 +583,7 @@ test "open" { |
| 585 | const exp_out = ""; | 583 | const exp_out = ""; |
| 586 | | 584 | |
| 587 | var out: [exp_out.len]u8 = undefined; | 585 | var out: [exp_out.len]u8 = undefined; |
| 588 | var valid: bool = chacha20poly1305Open(out[0..], ciphertext[0..], data, key, nonce); | 586 | try chacha20poly1305Open(out[0..], ciphertext[0..], data, key, nonce); |
| 589 | testing.expect(valid); | | |
| 590 | testing.expectEqualSlices(u8, exp_out, out); | 587 | testing.expectEqualSlices(u8, exp_out, out); |
| 591 | } | 588 | } |
| 592 | { | 589 | { |
| ... | @@ -619,22 +616,24 @@ test "open" { | ... | @@ -619,22 +616,24 @@ test "open" { |
| 619 | }; | 616 | }; |
| 620 | | 617 | |
| 621 | var out: [exp_out.len]u8 = undefined; | 618 | var out: [exp_out.len]u8 = undefined; |
| 622 | var valid: bool = chacha20poly1305Open(out[0..], ciphertext[0..], data[0..], key, nonce); | 619 | try chacha20poly1305Open(out[0..], ciphertext[0..], data[0..], key, nonce); |
| 623 | testing.expect(valid); | | |
| 624 | testing.expectEqualSlices(u8, exp_out, out); | 620 | testing.expectEqualSlices(u8, exp_out, out); |
| 625 | | 621 | |
| 626 | // corrupting the ciphertext, data, key, or nonce should cause a failure | 622 | // corrupting the ciphertext, data, key, or nonce should cause a failure |
| 627 | var bad_ciphertext = ciphertext; | 623 | var bad_ciphertext = ciphertext; |
| 628 | bad_ciphertext[0] ^= 1; | 624 | bad_ciphertext[0] ^= 1; |
| 629 | testing.expect(!chacha20poly1305Open(out[0..], bad_ciphertext[0..], data, key, nonce)); | 625 | testing.expectError(error.AuthenticationFailed, chacha20poly1305Open(out[0..], bad_ciphertext[0..], data, key, nonce)); |
| 630 | var bad_data = data; | 626 | var bad_data = data; |
| 631 | bad_data[0] ^= 1; | 627 | bad_data[0] ^= 1; |
| 632 | testing.expect(!chacha20poly1305Open(out[0..], ciphertext[0..], bad_data, key, nonce)); | 628 | testing.expectError(error.AuthenticationFailed, chacha20poly1305Open(out[0..], ciphertext[0..], bad_data, key, nonce)); |
| 633 | var bad_key = key; | 629 | var bad_key = key; |
| 634 | bad_key[0] ^= 1; | 630 | bad_key[0] ^= 1; |
| 635 | testing.expect(!chacha20poly1305Open(out[0..], ciphertext[0..], data, bad_key, nonce)); | 631 | testing.expectError(error.AuthenticationFailed, chacha20poly1305Open(out[0..], ciphertext[0..], data, bad_key, nonce)); |
| 636 | var bad_nonce = nonce; | 632 | var bad_nonce = nonce; |
| 637 | bad_nonce[0] ^= 1; | 633 | bad_nonce[0] ^= 1; |
| 638 | testing.expect(!chacha20poly1305Open(out[0..], ciphertext[0..], data, key, bad_nonce)); | 634 | testing.expectError(error.AuthenticationFailed, chacha20poly1305Open(out[0..], ciphertext[0..], data, key, bad_nonce)); |
| | 635 | |
| | 636 | // a short ciphertext should result in a different error |
| | 637 | testing.expectError(error.InvalidMessage, chacha20poly1305Open(out[0..], "", data, key, bad_nonce)); |
| 639 | } | 638 | } |
| 640 | } | 639 | } |