[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include <crypto/p224_spake.h> |
| 6 | |
| 7 | #include "base/logging.h" |
| 8 | #include "testing/gtest/include/gtest/gtest.h" |
| 9 | |
[email protected] | 3c6cf57f | 2012-11-03 00:48:17 | [diff] [blame] | 10 | namespace crypto { |
| 11 | |
| 12 | namespace { |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 13 | |
| 14 | bool RunExchange(P224EncryptedKeyExchange* client, |
| 15 | P224EncryptedKeyExchange* server) { |
| 16 | |
| 17 | for (;;) { |
| 18 | std::string client_message, server_message; |
| 19 | client_message = client->GetMessage(); |
| 20 | server_message = server->GetMessage(); |
| 21 | |
| 22 | P224EncryptedKeyExchange::Result client_result, server_result; |
| 23 | client_result = client->ProcessMessage(server_message); |
| 24 | server_result = server->ProcessMessage(client_message); |
| 25 | |
| 26 | // Check that we never hit the case where only one succeeds. |
| 27 | if ((client_result == P224EncryptedKeyExchange::kResultSuccess) ^ |
| 28 | (server_result == P224EncryptedKeyExchange::kResultSuccess)) { |
| 29 | CHECK(false) << "Parties differ on whether authentication was successful"; |
| 30 | } |
| 31 | |
| 32 | if (client_result == P224EncryptedKeyExchange::kResultFailed || |
| 33 | server_result == P224EncryptedKeyExchange::kResultFailed) { |
| 34 | return false; |
| 35 | } |
| 36 | |
| 37 | if (client_result == P224EncryptedKeyExchange::kResultSuccess && |
| 38 | server_result == P224EncryptedKeyExchange::kResultSuccess) { |
| 39 | return true; |
| 40 | } |
| 41 | |
| 42 | CHECK_EQ(P224EncryptedKeyExchange::kResultPending, client_result); |
| 43 | CHECK_EQ(P224EncryptedKeyExchange::kResultPending, server_result); |
| 44 | } |
| 45 | } |
| 46 | |
[email protected] | 3c6cf57f | 2012-11-03 00:48:17 | [diff] [blame] | 47 | const char kPassword[] = "foo"; |
| 48 | |
| 49 | } // namespace |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 50 | |
| 51 | TEST(MutualAuth, CorrectAuth) { |
| 52 | P224EncryptedKeyExchange client( |
[email protected] | 78df46a | 2011-12-13 07:00:19 | [diff] [blame] | 53 | P224EncryptedKeyExchange::kPeerTypeClient, kPassword); |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 54 | P224EncryptedKeyExchange server( |
[email protected] | 78df46a | 2011-12-13 07:00:19 | [diff] [blame] | 55 | P224EncryptedKeyExchange::kPeerTypeServer, kPassword); |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 56 | |
| 57 | EXPECT_TRUE(RunExchange(&client, &server)); |
[email protected] | 78df46a | 2011-12-13 07:00:19 | [diff] [blame] | 58 | EXPECT_EQ(client.GetKey(), server.GetKey()); |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | TEST(MutualAuth, IncorrectPassword) { |
| 62 | P224EncryptedKeyExchange client( |
| 63 | P224EncryptedKeyExchange::kPeerTypeClient, |
[email protected] | 78df46a | 2011-12-13 07:00:19 | [diff] [blame] | 64 | kPassword); |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 65 | P224EncryptedKeyExchange server( |
| 66 | P224EncryptedKeyExchange::kPeerTypeServer, |
[email protected] | 78df46a | 2011-12-13 07:00:19 | [diff] [blame] | 67 | "wrongpassword"); |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 68 | |
| 69 | EXPECT_FALSE(RunExchange(&client, &server)); |
| 70 | } |
| 71 | |
| 72 | TEST(MutualAuth, Fuzz) { |
| 73 | static const unsigned kIterations = 40; |
| 74 | |
| 75 | for (unsigned i = 0; i < kIterations; i++) { |
| 76 | P224EncryptedKeyExchange client( |
[email protected] | 78df46a | 2011-12-13 07:00:19 | [diff] [blame] | 77 | P224EncryptedKeyExchange::kPeerTypeClient, kPassword); |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 78 | P224EncryptedKeyExchange server( |
[email protected] | 78df46a | 2011-12-13 07:00:19 | [diff] [blame] | 79 | P224EncryptedKeyExchange::kPeerTypeServer, kPassword); |
[email protected] | d9a262d | 2011-11-22 01:29:37 | [diff] [blame] | 80 | |
| 81 | // We'll only be testing small values of i, but we don't want that to bias |
| 82 | // the test coverage. So we disperse the value of i by multiplying by the |
| 83 | // FNV, 32-bit prime, producing a poor-man's PRNG. |
| 84 | const uint32 rand = i * 16777619; |
| 85 | |
| 86 | for (unsigned round = 0;; round++) { |
| 87 | std::string client_message, server_message; |
| 88 | client_message = client.GetMessage(); |
| 89 | server_message = server.GetMessage(); |
| 90 | |
| 91 | if ((rand & 1) == round) { |
| 92 | const bool server_or_client = rand & 2; |
| 93 | std::string* m = server_or_client ? &server_message : &client_message; |
| 94 | if (rand & 4) { |
| 95 | // Truncate |
| 96 | *m = m->substr(0, (i >> 3) % m->size()); |
| 97 | } else { |
| 98 | // Corrupt |
| 99 | const size_t bits = m->size() * 8; |
| 100 | const size_t bit_to_corrupt = (rand >> 3) % bits; |
| 101 | const_cast<char*>(m->data())[bit_to_corrupt / 8] ^= |
| 102 | 1 << (bit_to_corrupt % 8); |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | P224EncryptedKeyExchange::Result client_result, server_result; |
| 107 | client_result = client.ProcessMessage(server_message); |
| 108 | server_result = server.ProcessMessage(client_message); |
| 109 | |
| 110 | // If we have corrupted anything, we expect the authentication to fail, |
| 111 | // although one side can succeed if we happen to corrupt the second round |
| 112 | // message to the other. |
| 113 | ASSERT_FALSE( |
| 114 | client_result == P224EncryptedKeyExchange::kResultSuccess && |
| 115 | server_result == P224EncryptedKeyExchange::kResultSuccess); |
| 116 | |
| 117 | if (client_result == P224EncryptedKeyExchange::kResultFailed || |
| 118 | server_result == P224EncryptedKeyExchange::kResultFailed) { |
| 119 | break; |
| 120 | } |
| 121 | |
| 122 | ASSERT_EQ(P224EncryptedKeyExchange::kResultPending, |
| 123 | client_result); |
| 124 | ASSERT_EQ(P224EncryptedKeyExchange::kResultPending, |
| 125 | server_result); |
| 126 | } |
| 127 | } |
| 128 | } |
[email protected] | 3c6cf57f | 2012-11-03 00:48:17 | [diff] [blame] | 129 | |
| 130 | } // namespace crypto |