blob: cdf4ff580ec010e59d0ce7a1cfabdf17bfdc85da [file] [log] [blame]
Arnar Birgissonf27459e2016-02-09 18:09:00 -08001/* 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 Benjamin01d65c22017-04-23 12:00:39 -040015#include <openssl/curve25519.h>
16
Arnar Birgissonf27459e2016-02-09 18:09:00 -080017#include <string>
18
19#include <stdint.h>
20#include <stdio.h>
21#include <string.h>
22
David Benjamin01d65c22017-04-23 12:00:39 -040023#include <gtest/gtest.h>
Arnar Birgissonf27459e2016-02-09 18:09:00 -080024
David Benjamin17cf2cb2016-12-13 01:07:13 -050025#include "../internal.h"
26
Arnar Birgissonf27459e2016-02-09 18:09:00 -080027
David Benjamin808f8322017-08-18 14:06:02 -040028// TODO(agl): add tests with fixed vectors once SPAKE2 is nailed down.
David Benjamin01d65c22017-04-23 12:00:39 -040029
Arnar Birgissonf27459e2016-02-09 18:09:00 -080030struct SPAKE2Run {
31 bool Run() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -070032 bssl::UniquePtr<SPAKE2_CTX> alice(SPAKE2_CTX_new(
Arnar Birgissonf27459e2016-02-09 18:09:00 -080033 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 Braithwaited17d74d2016-08-17 20:10:28 -070038 bssl::UniquePtr<SPAKE2_CTX> bob(SPAKE2_CTX_new(
Arnar Birgissonf27459e2016-02-09 18:09:00 -080039 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 Benjamin17cf2cb2016-12-13 01:07:13 -050080 OPENSSL_memcmp(alice_key, bob_key, alice_key_len) == 0);
Arnar Birgissonf27459e2016-02-09 18:09:00 -080081
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 Benjamin01d65c22017-04-23 12:00:39 -040099TEST(SPAKE25519Test, SPAKE2) {
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800100 for (unsigned i = 0; i < 20; i++) {
101 SPAKE2Run spake2;
David Benjamin01d65c22017-04-23 12:00:39 -0400102 ASSERT_TRUE(spake2.Run());
103 EXPECT_TRUE(spake2.key_matches());
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800104 }
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800105}
106
David Benjamin01d65c22017-04-23 12:00:39 -0400107TEST(SPAKE25519Test, WrongPassword) {
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800108 SPAKE2Run spake2;
109 spake2.bob_password = "wrong password";
David Benjamin01d65c22017-04-23 12:00:39 -0400110 ASSERT_TRUE(spake2.Run());
111 EXPECT_FALSE(spake2.key_matches()) << "Key matched for unequal passwords.";
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800112}
113
David Benjamin01d65c22017-04-23 12:00:39 -0400114TEST(SPAKE25519Test, WrongNames) {
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800115 SPAKE2Run spake2;
116 spake2.alice_names.second = "charlie";
117 spake2.bob_names.second = "charlie";
David Benjamin01d65c22017-04-23 12:00:39 -0400118 ASSERT_TRUE(spake2.Run());
119 EXPECT_FALSE(spake2.key_matches()) << "Key matched for unequal names.";
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800120}
121
David Benjamin01d65c22017-04-23 12:00:39 -0400122TEST(SPAKE25519Test, CorruptMessages) {
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800123 for (int i = 0; i < 8 * SPAKE2_MAX_MSG_SIZE; i++) {
124 SPAKE2Run spake2;
125 spake2.alice_corrupt_msg_bit = i;
David Benjamin01d65c22017-04-23 12:00:39 -0400126 EXPECT_FALSE(spake2.Run() && spake2.key_matches())
127 << "Passed after corrupting Alice's message, bit " << i;
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800128 }
Arnar Birgissonf27459e2016-02-09 18:09:00 -0800129}