[go: nahoru, domu]

Add Fuzzer targets for UKEY2

Bug: 1037793
Change-Id: Ia8148e61569e8b16cf6ae67dd136081c150b08ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2278059
Reviewed-by: Andrew Grieve <agrieve@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Reviewed-by: Himanshu Jaju <himanshujaju@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Commit-Queue: Alex Chau <alexchau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#786757}
diff --git a/BUILD.gn b/BUILD.gn
index 75e360a..801a0a0 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -765,6 +765,7 @@
       "//third_party/grpc:fuzzers",
       "//third_party/icu/fuzzers",
       "//third_party/qcms:fuzzers",
+      "//third_party/ukey2/fuzzers",
       "//third_party/zlib/contrib/tests/fuzzers",
     ]
 
diff --git a/third_party/ukey2/fuzzers/BUILD.gn b/third_party/ukey2/fuzzers/BUILD.gn
new file mode 100644
index 0000000..1aba406
--- /dev/null
+++ b/third_party/ukey2/fuzzers/BUILD.gn
@@ -0,0 +1,59 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//testing/libfuzzer/fuzzer_test.gni")
+
+# root BUILD depends on this target. Needed for package discovery
+group("fuzzers") {
+}
+
+fuzzer_test("d2d_connection_context_server_fuzzer") {
+  sources = [
+    "d2d_connection_context_factory.cc",
+    "d2d_connection_context_factory.h",
+    "d2d_connection_context_server_fuzzer.cc",
+  ]
+  deps = [
+    "//base",
+    "//third_party/protobuf:protobuf_lite",
+    "//third_party/ukey2",
+  ]
+}
+
+fuzzer_test("d2d_connection_context_client_fuzzer") {
+  sources = [
+    "d2d_connection_context_client_fuzzer.cc",
+    "d2d_connection_context_factory.cc",
+    "d2d_connection_context_factory.h",
+  ]
+  deps = [
+    "//base",
+    "//third_party/protobuf:protobuf_lite",
+    "//third_party/ukey2",
+  ]
+}
+
+fuzzer_test("ukey2_handshake_client_init_fuzzer") {
+  sources = [ "ukey2_handshake_client_init_fuzzer.cc" ]
+  deps = [
+    "//base",
+    "//third_party/ukey2",
+  ]
+}
+
+fuzzer_test("ukey2_handshake_server_init_fuzzer") {
+  sources = [ "ukey2_handshake_server_init_fuzzer.cc" ]
+  deps = [
+    "//base",
+    "//third_party/ukey2",
+  ]
+}
+
+fuzzer_test("ukey2_handshake_client_finish_fuzzer") {
+  sources = [ "ukey2_handshake_client_finish_fuzzer.cc" ]
+  deps = [
+    "//base",
+    "//third_party/ukey2",
+  ]
+}
diff --git a/third_party/ukey2/fuzzers/DEPS b/third_party/ukey2/fuzzers/DEPS
new file mode 100644
index 0000000..5cd0867
--- /dev/null
+++ b/third_party/ukey2/fuzzers/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+base",
+]
diff --git a/third_party/ukey2/fuzzers/d2d_connection_context_client_fuzzer.cc b/third_party/ukey2/fuzzers/d2d_connection_context_client_fuzzer.cc
new file mode 100644
index 0000000..a413c2d
--- /dev/null
+++ b/third_party/ukey2/fuzzers/d2d_connection_context_client_fuzzer.cc
@@ -0,0 +1,43 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/no_destructor.h"
+#include "third_party/protobuf/src/google/protobuf/stubs/logging.h"
+#include "third_party/ukey2/fuzzers/d2d_connection_context_factory.h"
+
+// Disable noisy logging in protobuf.
+google::protobuf::LogSilencer log_silencer;
+
+struct Environment {
+  Environment() {
+    // Disable noisy logging as per "libFuzzer in Chrome" documentation:
+    // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
+    logging::SetMinLogLevel(logging::LOG_FATAL);
+    // Disable noisy logging in securemessage.
+    std::cerr.setstate(std::ios_base::failbit);
+
+    // Create instance once to be reused between fuzzing rounds.
+    client_context = securegcm::CreateClientContext();
+    CHECK(client_context);
+  }
+
+  std::unique_ptr<securegcm::D2DConnectionContextV1> client_context;
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static base::NoDestructor<Environment> environment;
+
+  std::string buffer(data, data + size);
+  environment->client_context->DecodeMessageFromPeer(buffer);
+
+  return 0;
+}
diff --git a/third_party/ukey2/fuzzers/d2d_connection_context_factory.cc b/third_party/ukey2/fuzzers/d2d_connection_context_factory.cc
new file mode 100644
index 0000000..28b21a0
--- /dev/null
+++ b/third_party/ukey2/fuzzers/d2d_connection_context_factory.cc
@@ -0,0 +1,85 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/ukey2/fuzzers/d2d_connection_context_factory.h"
+
+#include <string>
+
+#include "base/check.h"
+#include "third_party/ukey2/src/src/main/cpp/include/securegcm/ukey2_handshake.h"
+
+namespace securegcm {
+
+namespace {
+
+const securegcm::UKey2Handshake::HandshakeCipher kCipher =
+    securegcm::UKey2Handshake::HandshakeCipher::P256_SHA512;
+// Arbitrary chosen length as verification string is discarded regardless.
+const int32_t kMaxUkey2VerificationStringLength = 32;
+
+void PerformHandshake(UKey2Handshake* server, UKey2Handshake* client) {
+  std::unique_ptr<std::string> client_init = client->GetNextHandshakeMessage();
+  CHECK(client_init) << client->GetLastError();
+
+  UKey2Handshake::ParseResult parse_result =
+      server->ParseHandshakeMessage(*client_init);
+  CHECK(parse_result.success) << server->GetLastError();
+
+  std::unique_ptr<std::string> server_init = server->GetNextHandshakeMessage();
+  CHECK(server_init) << server->GetLastError();
+
+  client->ParseHandshakeMessage(*server_init);
+  CHECK(parse_result.success) << client->GetLastError();
+
+  std::unique_ptr<std::string> client_finish =
+      client->GetNextHandshakeMessage();
+  CHECK(client_finish) << client->GetLastError();
+
+  parse_result = server->ParseHandshakeMessage(*client_finish);
+  CHECK(parse_result.success) << server->GetLastError();
+}
+
+}  // namespace
+
+std::unique_ptr<D2DConnectionContextV1> CreateServerContext() {
+  std::unique_ptr<UKey2Handshake> server =
+      UKey2Handshake::ForResponder(kCipher);
+  CHECK(server);
+
+  std::unique_ptr<UKey2Handshake> client =
+      UKey2Handshake::ForInitiator(kCipher);
+  CHECK(client);
+
+  PerformHandshake(server.get(), client.get());
+
+  std::unique_ptr<std::string> verification_string =
+      server->GetVerificationString(kMaxUkey2VerificationStringLength);
+  CHECK(verification_string) << server->GetLastError();
+
+  bool verify_result = server->VerifyHandshake();
+  CHECK(verify_result) << server->GetLastError();
+
+  return server->ToConnectionContext();
+}
+
+std::unique_ptr<D2DConnectionContextV1> CreateClientContext() {
+  auto server = UKey2Handshake::ForResponder(kCipher);
+  CHECK(server);
+
+  auto client = UKey2Handshake::ForInitiator(kCipher);
+  CHECK(client);
+
+  PerformHandshake(server.get(), client.get());
+
+  std::unique_ptr<std::string> verification_string =
+      client->GetVerificationString(kMaxUkey2VerificationStringLength);
+  CHECK(verification_string) << client->GetLastError();
+
+  bool verify_result = client->VerifyHandshake();
+  CHECK(verify_result) << client->GetLastError();
+
+  return client->ToConnectionContext();
+}
+
+}  // namespace securegcm
diff --git a/third_party/ukey2/fuzzers/d2d_connection_context_factory.h b/third_party/ukey2/fuzzers/d2d_connection_context_factory.h
new file mode 100644
index 0000000..82789f0
--- /dev/null
+++ b/third_party/ukey2/fuzzers/d2d_connection_context_factory.h
@@ -0,0 +1,20 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_UKEY2_D2D_CONNECTION_CONTEXT_FACTORY_H_
+#define THIRD_PARTY_UKEY2_D2D_CONNECTION_CONTEXT_FACTORY_H_
+
+#include <memory>
+
+#include "third_party/ukey2/src/src/main/cpp/include/securegcm/d2d_connection_context_v1.h"
+
+namespace securegcm {
+
+std::unique_ptr<securegcm::D2DConnectionContextV1> CreateServerContext();
+
+std::unique_ptr<securegcm::D2DConnectionContextV1> CreateClientContext();
+
+}  // namespace securegcm
+
+#endif  // THIRD_PARTY_UKEY2_D2D_CONNECTION_CONTEXT_FACTORY_H_
diff --git a/third_party/ukey2/fuzzers/d2d_connection_context_server_fuzzer.cc b/third_party/ukey2/fuzzers/d2d_connection_context_server_fuzzer.cc
new file mode 100644
index 0000000..f96e500
--- /dev/null
+++ b/third_party/ukey2/fuzzers/d2d_connection_context_server_fuzzer.cc
@@ -0,0 +1,43 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/no_destructor.h"
+#include "third_party/protobuf/src/google/protobuf/stubs/logging.h"
+#include "third_party/ukey2/fuzzers/d2d_connection_context_factory.h"
+
+// Disable noisy logging in protobuf.
+google::protobuf::LogSilencer log_silencer;
+
+struct Environment {
+  Environment() {
+    // Disable noisy logging as per "libFuzzer in Chrome" documentation:
+    // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
+    logging::SetMinLogLevel(logging::LOG_FATAL);
+    // Disable noisy logging in securemessage.
+    std::cerr.setstate(std::ios_base::failbit);
+
+    // Create instance once to be reused between fuzzing rounds.
+    server_context = securegcm::CreateServerContext();
+    CHECK(server_context);
+  }
+
+  std::unique_ptr<securegcm::D2DConnectionContextV1> server_context;
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static base::NoDestructor<Environment> environment;
+
+  std::string buffer(data, data + size);
+  environment->server_context->DecodeMessageFromPeer(buffer);
+
+  return 0;
+}
diff --git a/third_party/ukey2/fuzzers/ukey2_handshake_client_finish_fuzzer.cc b/third_party/ukey2/fuzzers/ukey2_handshake_client_finish_fuzzer.cc
new file mode 100644
index 0000000..74066aa
--- /dev/null
+++ b/third_party/ukey2/fuzzers/ukey2_handshake_client_finish_fuzzer.cc
@@ -0,0 +1,58 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/ukey2/src/src/main/cpp/include/securegcm/ukey2_handshake.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <memory>
+#include <string>
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/no_destructor.h"
+
+const securegcm::UKey2Handshake::HandshakeCipher kCipher =
+    securegcm::UKey2Handshake::HandshakeCipher::P256_SHA512;
+
+struct Environment {
+  Environment() {
+    // Disable noisy logging as per "libFuzzer in Chrome" documentation:
+    // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
+    logging::SetMinLogLevel(logging::LOG_FATAL);
+
+    // Create instance once to be reused between fuzzing rounds.
+    server = securegcm::UKey2Handshake::ForResponder(kCipher);
+    CHECK(server);
+
+    // Advance server to parse client init, generate serer init, then wait for
+    // client finish.
+    std::unique_ptr<securegcm::UKey2Handshake> client =
+        securegcm::UKey2Handshake::ForInitiator(kCipher);
+    CHECK(client);
+
+    std::unique_ptr<std::string> client_init =
+        client->GetNextHandshakeMessage();
+    CHECK(client_init) << client->GetLastError();
+
+    securegcm::UKey2Handshake::ParseResult parse_result =
+        server->ParseHandshakeMessage(*client_init);
+    CHECK(parse_result.success) << server->GetLastError();
+
+    std::unique_ptr<std::string> server_init =
+        server->GetNextHandshakeMessage();
+    CHECK(server_init) << server->GetLastError();
+  }
+
+  std::unique_ptr<securegcm::UKey2Handshake> server;
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static base::NoDestructor<Environment> environment;
+
+  std::string buffer(data, data + size);
+  environment->server->ParseHandshakeMessage(buffer);
+
+  return 0;
+}
diff --git a/third_party/ukey2/fuzzers/ukey2_handshake_client_init_fuzzer.cc b/third_party/ukey2/fuzzers/ukey2_handshake_client_init_fuzzer.cc
new file mode 100644
index 0000000..3236be8
--- /dev/null
+++ b/third_party/ukey2/fuzzers/ukey2_handshake_client_init_fuzzer.cc
@@ -0,0 +1,40 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/ukey2/src/src/main/cpp/include/securegcm/ukey2_handshake.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <memory>
+#include <string>
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/no_destructor.h"
+
+const securegcm::UKey2Handshake::HandshakeCipher kCipher =
+    securegcm::UKey2Handshake::HandshakeCipher::P256_SHA512;
+
+struct Environment {
+  Environment() {
+    // Disable noisy logging as per "libFuzzer in Chrome" documentation:
+    // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
+    logging::SetMinLogLevel(logging::LOG_FATAL);
+
+    // Create instance once to be reused between fuzzing rounds.
+    server = securegcm::UKey2Handshake::ForResponder(kCipher);
+    CHECK(server);
+  }
+
+  std::unique_ptr<securegcm::UKey2Handshake> server;
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static base::NoDestructor<Environment> environment;
+
+  std::string buffer(data, data + size);
+  environment->server->ParseHandshakeMessage(buffer);
+
+  return 0;
+}
diff --git a/third_party/ukey2/fuzzers/ukey2_handshake_server_init_fuzzer.cc b/third_party/ukey2/fuzzers/ukey2_handshake_server_init_fuzzer.cc
new file mode 100644
index 0000000..25cbba9
--- /dev/null
+++ b/third_party/ukey2/fuzzers/ukey2_handshake_server_init_fuzzer.cc
@@ -0,0 +1,45 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/ukey2/src/src/main/cpp/include/securegcm/ukey2_handshake.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <memory>
+#include <string>
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/no_destructor.h"
+
+const securegcm::UKey2Handshake::HandshakeCipher kCipher =
+    securegcm::UKey2Handshake::HandshakeCipher::P256_SHA512;
+
+struct Environment {
+  Environment() {
+    // Disable noisy logging as per "libFuzzer in Chrome" documentation:
+    // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
+    logging::SetMinLogLevel(logging::LOG_FATAL);
+
+    // Create instance once to be reused between fuzzing rounds.
+    client = securegcm::UKey2Handshake::ForInitiator(kCipher);
+    CHECK(client);
+
+    // Advance client to generate client init, then wait for server init.
+    std::unique_ptr<std::string> client_init =
+        client->GetNextHandshakeMessage();
+    CHECK(client_init) << client->GetLastError();
+  }
+
+  std::unique_ptr<securegcm::UKey2Handshake> client;
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static base::NoDestructor<Environment> environment;
+
+  std::string buffer(data, data + size);
+  environment->client->ParseHandshakeMessage(buffer);
+
+  return 0;
+}