Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 1 | /* Copyright (c) 2016, Google Inc. |
| 2 | * |
| 3 | * Permission to use, copy, modify, and/or distribute this software for any |
| 4 | * purpose with or without fee is hereby granted, provided that the above |
| 5 | * copyright notice and this permission notice appear in all copies. |
| 6 | * |
| 7 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 8 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 9 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| 10 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 11 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| 12 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| 13 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
| 14 | |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 15 | #include <openssl/curve25519.h> |
| 16 | |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 17 | #include <string> |
| 18 | |
| 19 | #include <stdint.h> |
| 20 | #include <stdio.h> |
| 21 | #include <string.h> |
| 22 | |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 23 | #include <gtest/gtest.h> |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 24 | |
David Benjamin | 17cf2cb | 2016-12-13 01:07:13 -0500 | [diff] [blame] | 25 | #include "../internal.h" |
| 26 | |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 27 | |
David Benjamin | 808f832 | 2017-08-18 14:06:02 -0400 | [diff] [blame] | 28 | // TODO(agl): add tests with fixed vectors once SPAKE2 is nailed down. |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 29 | |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 30 | struct SPAKE2Run { |
| 31 | bool Run() { |
Matt Braithwaite | d17d74d | 2016-08-17 20:10:28 -0700 | [diff] [blame] | 32 | bssl::UniquePtr<SPAKE2_CTX> alice(SPAKE2_CTX_new( |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 33 | spake2_role_alice, |
| 34 | reinterpret_cast<const uint8_t *>(alice_names.first.data()), |
| 35 | alice_names.first.size(), |
| 36 | reinterpret_cast<const uint8_t *>(alice_names.second.data()), |
| 37 | alice_names.second.size())); |
Matt Braithwaite | d17d74d | 2016-08-17 20:10:28 -0700 | [diff] [blame] | 38 | bssl::UniquePtr<SPAKE2_CTX> bob(SPAKE2_CTX_new( |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 39 | spake2_role_bob, |
| 40 | reinterpret_cast<const uint8_t *>(bob_names.first.data()), |
| 41 | bob_names.first.size(), |
| 42 | reinterpret_cast<const uint8_t *>(bob_names.second.data()), |
| 43 | bob_names.second.size())); |
| 44 | |
| 45 | if (!alice || !bob) { |
| 46 | return false; |
| 47 | } |
| 48 | |
| 49 | uint8_t alice_msg[SPAKE2_MAX_MSG_SIZE]; |
| 50 | uint8_t bob_msg[SPAKE2_MAX_MSG_SIZE]; |
| 51 | size_t alice_msg_len, bob_msg_len; |
| 52 | |
| 53 | if (!SPAKE2_generate_msg( |
| 54 | alice.get(), alice_msg, &alice_msg_len, sizeof(alice_msg), |
| 55 | reinterpret_cast<const uint8_t *>(alice_password.data()), |
| 56 | alice_password.size()) || |
| 57 | !SPAKE2_generate_msg( |
| 58 | bob.get(), bob_msg, &bob_msg_len, sizeof(bob_msg), |
| 59 | reinterpret_cast<const uint8_t *>(bob_password.data()), |
| 60 | bob_password.size())) { |
| 61 | return false; |
| 62 | } |
| 63 | |
| 64 | if (alice_corrupt_msg_bit >= 0 && |
| 65 | static_cast<size_t>(alice_corrupt_msg_bit) < 8 * alice_msg_len) { |
| 66 | alice_msg[alice_corrupt_msg_bit/8] ^= 1 << (alice_corrupt_msg_bit & 7); |
| 67 | } |
| 68 | |
| 69 | uint8_t alice_key[64], bob_key[64]; |
| 70 | size_t alice_key_len, bob_key_len; |
| 71 | |
| 72 | if (!SPAKE2_process_msg(alice.get(), alice_key, &alice_key_len, |
| 73 | sizeof(alice_key), bob_msg, bob_msg_len) || |
| 74 | !SPAKE2_process_msg(bob.get(), bob_key, &bob_key_len, sizeof(bob_key), |
| 75 | alice_msg, alice_msg_len)) { |
| 76 | return false; |
| 77 | } |
| 78 | |
| 79 | key_matches_ = (alice_key_len == bob_key_len && |
David Benjamin | 17cf2cb | 2016-12-13 01:07:13 -0500 | [diff] [blame] | 80 | OPENSSL_memcmp(alice_key, bob_key, alice_key_len) == 0); |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 81 | |
| 82 | return true; |
| 83 | } |
| 84 | |
| 85 | bool key_matches() const { |
| 86 | return key_matches_; |
| 87 | } |
| 88 | |
| 89 | std::string alice_password = "password"; |
| 90 | std::string bob_password = "password"; |
| 91 | std::pair<std::string, std::string> alice_names = {"alice", "bob"}; |
| 92 | std::pair<std::string, std::string> bob_names = {"bob", "alice"}; |
| 93 | int alice_corrupt_msg_bit = -1; |
| 94 | |
| 95 | private: |
| 96 | bool key_matches_ = false; |
| 97 | }; |
| 98 | |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 99 | TEST(SPAKE25519Test, SPAKE2) { |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 100 | for (unsigned i = 0; i < 20; i++) { |
| 101 | SPAKE2Run spake2; |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 102 | ASSERT_TRUE(spake2.Run()); |
| 103 | EXPECT_TRUE(spake2.key_matches()); |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 104 | } |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 105 | } |
| 106 | |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 107 | TEST(SPAKE25519Test, WrongPassword) { |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 108 | SPAKE2Run spake2; |
| 109 | spake2.bob_password = "wrong password"; |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 110 | ASSERT_TRUE(spake2.Run()); |
| 111 | EXPECT_FALSE(spake2.key_matches()) << "Key matched for unequal passwords."; |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 112 | } |
| 113 | |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 114 | TEST(SPAKE25519Test, WrongNames) { |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 115 | SPAKE2Run spake2; |
| 116 | spake2.alice_names.second = "charlie"; |
| 117 | spake2.bob_names.second = "charlie"; |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 118 | ASSERT_TRUE(spake2.Run()); |
| 119 | EXPECT_FALSE(spake2.key_matches()) << "Key matched for unequal names."; |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 120 | } |
| 121 | |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 122 | TEST(SPAKE25519Test, CorruptMessages) { |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 123 | for (int i = 0; i < 8 * SPAKE2_MAX_MSG_SIZE; i++) { |
| 124 | SPAKE2Run spake2; |
| 125 | spake2.alice_corrupt_msg_bit = i; |
David Benjamin | 01d65c2 | 2017-04-23 12:00:39 -0400 | [diff] [blame] | 126 | EXPECT_FALSE(spake2.Run() && spake2.key_matches()) |
| 127 | << "Passed after corrupting Alice's message, bit " << i; |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 128 | } |
Arnar Birgisson | f27459e | 2016-02-09 18:09:00 -0800 | [diff] [blame] | 129 | } |