[tink] Add build flag to allow building without tink

Change-Id: Idfca61d0a8341b5c5338221cd0efcfe38528f86a
Reviewed-on: https://fuchsia-review.googlesource.com/c/cobalt/+/475957
Reviewed-by: Alexandre Zani <azani@google.com>
Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
Fuchsia-Auto-Submit: Zach Bush <zmbush@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 8e4553a..a9c3a81 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -21,6 +21,8 @@
     "$root_gen_dir/third_party/cobalt",
   ]
 
+  defines = [ "TQ_COBALT_USE_TINK" ]
+
   if (is_fuchsia_tree) {
     include_dirs += [
       "//sdk/lib/syslog/cpp",
diff --git a/src/lib/util/BUILD.gn b/src/lib/util/BUILD.gn
index 41c3a46..1bf5ba1 100644
--- a/src/lib/util/BUILD.gn
+++ b/src/lib/util/BUILD.gn
@@ -46,6 +46,8 @@
   sources = [
     "encrypted_message_util.cc",
     "encrypted_message_util.h",
+    "hybrid_tink_encrypted_message_maker.cc",
+    "hybrid_tink_encrypted_message_maker.h",
   ]
   configs += [ "//build/config:no_rtti" ]
   configs -= [ "//build/config:no_rtti" ]
diff --git a/src/lib/util/encrypted_message_util.cc b/src/lib/util/encrypted_message_util.cc
index 3586933..8601e32 100644
--- a/src/lib/util/encrypted_message_util.cc
+++ b/src/lib/util/encrypted_message_util.cc
@@ -14,44 +14,19 @@
 #include "src/pb/encrypted_message.pb.h"
 #include "src/pb/key.pb.h"
 #include "src/tracing.h"
-#include "third_party/tink/cc/hybrid/hybrid_config.h"
-#include "third_party/tink/cc/hybrid_encrypt.h"
-#include "third_party/tink/cc/keyset_handle.h"
+
+#if TQ_COBALT_USE_TINK
+#include "src/lib/util/hybrid_tink_encrypted_message_maker.h"
+#endif
 
 namespace cobalt::util {
 
 namespace {
+
+#if TQ_COBALT_USE_TINK
 constexpr char kShufflerContextInfo[] = "cobalt-1.0-shuffler";
 constexpr char kAnalyzerContextInfo[] = "cobalt-1.0-analyzer";
-
-Status StatusFromTinkStatus(const ::crypto::tink::util::Status& tink_status) {
-  return Status(StatusCode(tink_status.error_code()), tink_status.error_message());
-}
-
-// Make a HybridTinkEncryptedMessageMaker from a serialized encoded keyset.
-lib::statusor::StatusOr<std::unique_ptr<EncryptedMessageMaker>> MakeHybridTinkEncryptedMessageMaker(
-    const std::string& public_keyset_bytes, const std::string& context_info, uint32_t key_index) {
-  auto status = ::crypto::tink::HybridConfig::Register();
-  if (!status.ok()) {
-    return StatusFromTinkStatus(status);
-  }
-
-  auto read_result = ::crypto::tink::KeysetHandle::ReadNoSecret(public_keyset_bytes);
-  if (!read_result.ok()) {
-    return StatusFromTinkStatus(read_result.status());
-  }
-  auto keyset_handle = std::move(read_result.ValueOrDie());
-
-  auto primitive_result = keyset_handle->GetPrimitive<::crypto::tink::HybridEncrypt>();
-  if (!primitive_result.ok()) {
-    return StatusFromTinkStatus(primitive_result.status());
-  }
-
-  std::unique_ptr<EncryptedMessageMaker> maker(new HybridTinkEncryptedMessageMaker(
-      std::move(primitive_result.ValueOrDie()), context_info, key_index));
-
-  return maker;
-}
+#endif
 
 // Parse and validate a serialized CobaltEncryptionKey.
 lib::statusor::StatusOr<cobalt::CobaltEncryptionKey> ParseCobaltEncryptionKey(
@@ -92,9 +67,14 @@
     return Status(INVALID_ARGUMENT, "EncryptedMessageMaker: Expected a shuffler key.");
   }
 
+#if TQ_COBALT_USE_TINK
   return MakeHybridTinkEncryptedMessageMaker(cobalt_encryption_key.serialized_key(),
                                              kShufflerContextInfo,
                                              cobalt_encryption_key.key_index());
+#else
+  std::unique_ptr<EncryptedMessageMaker> maker(new UnencryptedMessageMaker());
+  return maker;
+#endif
 }
 
 lib::statusor::StatusOr<std::unique_ptr<EncryptedMessageMaker>>
@@ -109,44 +89,14 @@
     return Status(INVALID_ARGUMENT, "EncryptedMessageMaker: Expected an analyzer key.");
   }
 
+#if TQ_COBALT_USE_TINK
   return MakeHybridTinkEncryptedMessageMaker(cobalt_encryption_key.serialized_key(),
                                              kAnalyzerContextInfo,
                                              cobalt_encryption_key.key_index());
-}
-
-HybridTinkEncryptedMessageMaker::HybridTinkEncryptedMessageMaker(
-    std::unique_ptr<::crypto::tink::HybridEncrypt> encrypter, std::string context_info,
-    uint32_t key_index)
-    : encrypter_(std::move(encrypter)),
-      context_info_(std::move(context_info)),
-      key_index_(key_index) {}
-
-bool HybridTinkEncryptedMessageMaker::Encrypt(const google::protobuf::MessageLite& message,
-                                              EncryptedMessage* encrypted_message) const {
-  TRACE_DURATION("cobalt_core", "HybridTinkEncryptedMessageMaker::Encrypt");
-  if (!encrypted_message) {
-    return false;
-  }
-
-  std::string serialized_message;
-  message.SerializeToString(&serialized_message);
-
-  VLOG(5) << "EncryptedMessage: encryption_scheme=HYBRID_TINK.";
-
-  auto encrypted_result = encrypter_->Encrypt(serialized_message, context_info_);
-  if (!encrypted_result.ok()) {
-    VLOG(5) << "EncryptedMessage: Tink could not encrypt message: "
-            << encrypted_result.status().error_message();
-    return false;
-  }
-  encrypted_message->set_ciphertext(encrypted_result.ValueOrDie());
-  if (key_index_ == 0) {
-    encrypted_message->set_scheme(EncryptedMessage::HYBRID_TINK);
-  } else {
-    encrypted_message->set_key_index(key_index_);
-  }
-
-  return true;
+#else
+  std::unique_ptr<EncryptedMessageMaker> maker(new UnencryptedMessageMaker());
+  return maker;
+#endif
 }
 
 bool UnencryptedMessageMaker::Encrypt(const google::protobuf::MessageLite& message,
diff --git a/src/lib/util/encrypted_message_util.h b/src/lib/util/encrypted_message_util.h
index 0ccc64a..1c68d31 100644
--- a/src/lib/util/encrypted_message_util.h
+++ b/src/lib/util/encrypted_message_util.h
@@ -64,26 +64,6 @@
   virtual ~EncryptedMessageMaker() = default;
 };
 
-// HybridTinkEncryptedMessageMaker is an implementation of
-// EncryptedMessageMaker. See EncryptedMessage::HYBRID_TINK for details.
-class HybridTinkEncryptedMessageMaker : public EncryptedMessageMaker {
- public:
-  HybridTinkEncryptedMessageMaker(std::unique_ptr<::crypto::tink::HybridEncrypt> encrypter,
-                                  std::string context_info, uint32_t key_index);
-
-  bool Encrypt(const google::protobuf::MessageLite& message,
-               EncryptedMessage* encrypted_message) const override;
-
-  [[nodiscard]] EncryptedMessage::EncryptionScheme scheme() const override {
-    return EncryptedMessage::HYBRID_TINK;
-  }
-
- private:
-  std::unique_ptr<::crypto::tink::HybridEncrypt> encrypter_;
-  std::string context_info_;
-  uint32_t key_index_;
-};
-
 // UnencryptedMessageMaker is an implementation of EncryptedMessageMaker that
 // does not perform any encryption.
 class UnencryptedMessageMaker : public EncryptedMessageMaker {
diff --git a/src/lib/util/hybrid_tink_encrypted_message_maker.cc b/src/lib/util/hybrid_tink_encrypted_message_maker.cc
new file mode 100644
index 0000000..3592829
--- /dev/null
+++ b/src/lib/util/hybrid_tink_encrypted_message_maker.cc
@@ -0,0 +1,76 @@
+
+#include "src/lib/util/hybrid_tink_encrypted_message_maker.h"
+
+#include "src/logging.h"
+#include "src/tracing.h"
+#include "third_party/tink/cc/hybrid/hybrid_config.h"
+#include "third_party/tink/cc/hybrid_encrypt.h"
+#include "third_party/tink/cc/keyset_handle.h"
+
+namespace cobalt::util {
+
+Status StatusFromTinkStatus(const ::crypto::tink::util::Status& tink_status) {
+  return Status(StatusCode(tink_status.error_code()), tink_status.error_message());
+}
+
+// Make a HybridTinkEncryptedMessageMaker from a serialized encoded keyset.
+lib::statusor::StatusOr<std::unique_ptr<EncryptedMessageMaker>> MakeHybridTinkEncryptedMessageMaker(
+    const std::string& public_keyset_bytes, const std::string& context_info, uint32_t key_index) {
+  auto status = ::crypto::tink::HybridConfig::Register();
+  if (!status.ok()) {
+    return StatusFromTinkStatus(status);
+  }
+
+  auto read_result = ::crypto::tink::KeysetHandle::ReadNoSecret(public_keyset_bytes);
+  if (!read_result.ok()) {
+    return StatusFromTinkStatus(read_result.status());
+  }
+  auto keyset_handle = std::move(read_result.ValueOrDie());
+
+  auto primitive_result = keyset_handle->GetPrimitive<::crypto::tink::HybridEncrypt>();
+  if (!primitive_result.ok()) {
+    return StatusFromTinkStatus(primitive_result.status());
+  }
+
+  std::unique_ptr<EncryptedMessageMaker> maker(new HybridTinkEncryptedMessageMaker(
+      std::move(primitive_result.ValueOrDie()), context_info, key_index));
+
+  return maker;
+}
+
+HybridTinkEncryptedMessageMaker::HybridTinkEncryptedMessageMaker(
+    std::unique_ptr<::crypto::tink::HybridEncrypt> encrypter, std::string context_info,
+    uint32_t key_index)
+    : encrypter_(std::move(encrypter)),
+      context_info_(std::move(context_info)),
+      key_index_(key_index) {}
+
+bool HybridTinkEncryptedMessageMaker::Encrypt(const google::protobuf::MessageLite& message,
+                                              EncryptedMessage* encrypted_message) const {
+  TRACE_DURATION("cobalt_core", "HybridTinkEncryptedMessageMaker::Encrypt");
+  if (!encrypted_message) {
+    return false;
+  }
+
+  std::string serialized_message;
+  message.SerializeToString(&serialized_message);
+
+  VLOG(5) << "EncryptedMessage: encryption_scheme=HYBRID_TINK.";
+
+  auto encrypted_result = encrypter_->Encrypt(serialized_message, context_info_);
+  if (!encrypted_result.ok()) {
+    VLOG(5) << "EncryptedMessage: Tink could not encrypt message: "
+            << encrypted_result.status().error_message();
+    return false;
+  }
+  encrypted_message->set_ciphertext(encrypted_result.ValueOrDie());
+  if (key_index_ == 0) {
+    encrypted_message->set_scheme(EncryptedMessage::HYBRID_TINK);
+  } else {
+    encrypted_message->set_key_index(key_index_);
+  }
+
+  return true;
+}
+
+}  // namespace cobalt::util
diff --git a/src/lib/util/hybrid_tink_encrypted_message_maker.h b/src/lib/util/hybrid_tink_encrypted_message_maker.h
new file mode 100644
index 0000000..c9c1a14
--- /dev/null
+++ b/src/lib/util/hybrid_tink_encrypted_message_maker.h
@@ -0,0 +1,39 @@
+// Copyright 2021 The Fuchsia 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 COBALT_SRC_LIB_UTIL_HYBRID_TINK_ENCRYPTED_MESSAGE_MAKER_H_
+#define COBALT_SRC_LIB_UTIL_HYBRID_TINK_ENCRYPTED_MESSAGE_MAKER_H_
+
+#include "google/protobuf/message_lite.h"
+#include "src/lib/util/encrypted_message_util.h"
+#include "third_party/tink/cc/hybrid_encrypt.h"
+
+namespace cobalt::util {
+
+lib::statusor::StatusOr<std::unique_ptr<EncryptedMessageMaker>> MakeHybridTinkEncryptedMessageMaker(
+    const std::string& public_keyset_bytes, const std::string& context_info, uint32_t key_index);
+
+// HybridTinkEncryptedMessageMaker is an implementation of
+// EncryptedMessageMaker. See EncryptedMessage::HYBRID_TINK for details.
+class HybridTinkEncryptedMessageMaker : public EncryptedMessageMaker {
+ public:
+  HybridTinkEncryptedMessageMaker(std::unique_ptr<::crypto::tink::HybridEncrypt> encrypter,
+                                  std::string context_info, uint32_t key_index);
+
+  bool Encrypt(const google::protobuf::MessageLite& message,
+               EncryptedMessage* encrypted_message) const override;
+
+  [[nodiscard]] EncryptedMessage::EncryptionScheme scheme() const override {
+    return EncryptedMessage::HYBRID_TINK;
+  }
+
+ private:
+  std::unique_ptr<::crypto::tink::HybridEncrypt> encrypter_;
+  std::string context_info_;
+  uint32_t key_index_;
+};
+
+}  // namespace cobalt::util
+
+#endif  // COBALT_SRC_LIB_UTIL_HYBRID_TINK_ENCRYPTED_MESSAGE_MAKER_H_