summaryrefslogtreecommitdiffstats
path: root/src/msg/async/crypto_onwire.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/msg/async/crypto_onwire.h')
-rw-r--r--src/msg/async/crypto_onwire.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/msg/async/crypto_onwire.h b/src/msg/async/crypto_onwire.h
new file mode 100644
index 000000000..55f755086
--- /dev/null
+++ b/src/msg/async/crypto_onwire.h
@@ -0,0 +1,130 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_CRYPTO_ONWIRE_H
+#define CEPH_CRYPTO_ONWIRE_H
+
+#include <cstdint>
+#include <memory>
+
+#include "auth/Auth.h"
+#include "include/buffer.h"
+
+namespace ceph::math {
+
+// TODO
+template <typename T>
+class always_aligned_t {
+ T val;
+
+ template <class... Args>
+ always_aligned_t(Args&&... args)
+ : val(std::forward<Args>(args)...) {
+ }
+};
+
+} // namespace ceph::math
+
+namespace ceph::crypto::onwire {
+
+struct MsgAuthError : public std::runtime_error {
+ MsgAuthError()
+ : runtime_error("message signature mismatch") {
+ }
+};
+
+struct TxHandlerError : public std::runtime_error {
+ TxHandlerError(const char* what)
+ : std::runtime_error(std::string("tx handler error: ") + what) {}
+};
+
+struct TxHandler {
+ virtual ~TxHandler() = default;
+
+ // Instance of TxHandler must be reset before doing any encrypt-update
+ // step. This applies also to situation when encrypt-final was already
+ // called and another round of update-...-update-final will take place.
+ //
+ // The input parameter informs implementation how the -update sequence
+ // is fragmented and allows to make concious decision about allocation
+ // or reusage of provided memory. One implementation could do in-place
+ // encryption while other might prefer one huge output buffer.
+ //
+ // It's undefined what will happen if client doesn't follow the order.
+ //
+ // TODO: switch to always_aligned_t
+ virtual void reset_tx_handler(const uint32_t* first,
+ const uint32_t* last) = 0;
+
+ void reset_tx_handler(std::initializer_list<uint32_t> update_size_sequence) {
+ if (update_size_sequence.size() > 0) {
+ const uint32_t* first = &*update_size_sequence.begin();
+ reset_tx_handler(first, first + update_size_sequence.size());
+ } else {
+ reset_tx_handler(nullptr, nullptr);
+ }
+ }
+
+ // Perform encryption. Client gives full ownership right to provided
+ // bufferlist. The method MUST NOT be called after _final() if there
+ // was no call to _reset().
+ virtual void authenticated_encrypt_update(
+ const ceph::bufferlist& plaintext) = 0;
+
+ // Generates authentication signature and returns bufferlist crafted
+ // basing on plaintext from preceding call to _update().
+ virtual ceph::bufferlist authenticated_encrypt_final() = 0;
+};
+
+class RxHandler {
+public:
+ virtual ~RxHandler() = default;
+
+ // Transmitter can append extra bytes of ciphertext at the -final step.
+ // This method return how much was added, and thus let client translate
+ // plaintext size into ciphertext size to grab from wire.
+ virtual std::uint32_t get_extra_size_at_final() = 0;
+
+ // Instance of RxHandler must be reset before doing any decrypt-update
+ // step. This applies also to situation when decrypt-final was already
+ // called and another round of update-...-update-final will take place.
+ virtual void reset_rx_handler() = 0;
+
+ // Perform decryption ciphertext must be ALWAYS aligned to 16 bytes.
+ virtual void authenticated_decrypt_update(ceph::bufferlist& bl) = 0;
+
+ // Perform decryption of last cipertext's portion and verify signature
+ // for overall decryption sequence.
+ // Throws on integrity/authenticity checks
+ virtual void authenticated_decrypt_update_final(ceph::bufferlist& bl) = 0;
+};
+
+struct rxtx_t {
+ //rxtx_t(rxtx_t&& r) : rx(std::move(rx)), tx(std::move(tx)) {}
+ // Each peer can use different handlers.
+ // Hmm, isn't that too much flexbility?
+ std::unique_ptr<RxHandler> rx;
+ std::unique_ptr<TxHandler> tx;
+
+ static rxtx_t create_handler_pair(
+ CephContext* ctx,
+ const class AuthConnectionMeta& auth_meta,
+ bool new_nonce_format,
+ bool crossed);
+};
+
+} // namespace ceph::crypto::onwire
+
+#endif // CEPH_CRYPTO_ONWIRE_H