Skip to content

Commit f77b54b

Browse files
author
Igor Egorov
authored
Fix SECIO security protocol (incl AES CTR) (#56)
* Fix SECIO security protocol * Implement correct AesCtr and fix SECIO * Add AES CTR stream data test Signed-off-by: Igor Egorov <[email protected]>
1 parent 665c102 commit f77b54b

File tree

19 files changed

+378
-384
lines changed

19 files changed

+378
-384
lines changed

include/libp2p/crypto/aes_ctr.hpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef LIBP2P_CRYPTO_IMPL_DETAIL_AES_CRYPT_HPP
7+
#define LIBP2P_CRYPTO_IMPL_DETAIL_AES_CRYPT_HPP
8+
9+
#include <gsl/span>
10+
#include <libp2p/common/types.hpp>
11+
#include <libp2p/crypto/common.hpp>
12+
#include <libp2p/outcome/outcome.hpp>
13+
14+
namespace libp2p::crypto::aes {
15+
16+
/**
17+
* An interface for stream data cipher encryption or decryption engine with
18+
* AES128 or AES256 algorithms.
19+
*/
20+
class AesCtr {
21+
public:
22+
using ByteArray = libp2p::common::ByteArray;
23+
24+
virtual ~AesCtr() = default;
25+
26+
/**
27+
* Encrypts or decrypts user data
28+
* @param data to be processed
29+
* @return processed data chunk or an error
30+
*/
31+
virtual outcome::result<ByteArray> crypt(
32+
gsl::span<const uint8_t> data) const = 0;
33+
34+
/**
35+
* Does stream data finalization
36+
* @return bytes buffer to correctly pad all the previously processed
37+
* data or an error
38+
*/
39+
virtual outcome::result<ByteArray> finalize() = 0;
40+
};
41+
} // namespace libp2p::crypto::aes
42+
43+
#endif // LIBP2P_CRYPTO_IMPL_DETAIL_AES_CRYPT_HPP
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef LIBP2P_CRYPTO_IMPL_DETAIL_AES_CRYPT_IMPL_HPP
7+
#define LIBP2P_CRYPTO_IMPL_DETAIL_AES_CRYPT_IMPL_HPP
8+
9+
#include <libp2p/crypto/aes_ctr.hpp>
10+
11+
#include <openssl/evp.h>
12+
#include <gsl/span>
13+
#include <libp2p/crypto/common.hpp>
14+
#include <libp2p/outcome/outcome.hpp>
15+
16+
namespace libp2p::crypto::aes {
17+
18+
class AesCtrImpl : public AesCtr {
19+
public:
20+
using Aes128Secret = libp2p::crypto::common::Aes128Secret;
21+
using Aes256Secret = libp2p::crypto::common::Aes256Secret;
22+
23+
enum class Mode {
24+
// all the constants are explicitly specified in accordance to OpenSSL
25+
// values
26+
DECRYPT = 0,
27+
ENCRYPT = 1,
28+
};
29+
30+
AesCtrImpl(const Aes128Secret &secret, Mode mode);
31+
32+
AesCtrImpl(const Aes256Secret &secret, Mode mode);
33+
34+
~AesCtrImpl() override;
35+
36+
outcome::result<ByteArray> crypt(
37+
gsl::span<const uint8_t> data) const override;
38+
39+
outcome::result<ByteArray> finalize() override;
40+
41+
private:
42+
outcome::result<void> init(gsl::span<const uint8_t> key,
43+
gsl::span<const uint8_t> iv,
44+
const EVP_CIPHER *cipher);
45+
46+
const Mode mode_;
47+
outcome::result<void> initialization_error_{outcome::success()};
48+
EVP_CIPHER_CTX *ctx_{nullptr};
49+
};
50+
51+
} // namespace libp2p::crypto::aes
52+
53+
#endif // LIBP2P_CRYPTO_IMPL_DETAIL_AES_CRYPT_IMPL_HPP

include/libp2p/crypto/aes_provider.hpp

Lines changed: 0 additions & 65 deletions
This file was deleted.

include/libp2p/crypto/aes_provider/aes_provider_impl.hpp

Lines changed: 0 additions & 40 deletions
This file was deleted.

include/libp2p/crypto/error.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace libp2p::crypto {
2626
FAILED_DECRYPT_FINALIZE, ///< failed to finalize decryption
2727
WRONG_IV_SIZE, ///< wrong iv size
2828
WRONG_KEY_SIZE, ///< wrong key size
29+
STREAM_FINALIZED, ///< crypt update operations cannot be performed after
30+
///< stream finalization
2931
};
3032

3133
enum class HmacProviderError {
@@ -58,7 +60,7 @@ namespace libp2p::crypto {
5860
CANNOT_LOAD_UNSPECIFIED, ///< cannot load unspecified key
5961
GET_KEY_BYTES_FAILED, ///< failed to get key bytes from PKEY
6062
INTERNAL_ERROR, ///< internal error happened
61-
UNSUPPORTED_CURVE_TYPE, ///< generator for curve type is not implemented
63+
UNSUPPORTED_CURVE_TYPE, ///< generator for curve type is not implemented
6264
};
6365

6466
enum class KeyValidatorError {

include/libp2p/injector/network_injector.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <boost/di.hpp>
1010

1111
// implementations
12-
#include <libp2p/crypto/aes_provider/aes_provider_impl.hpp>
12+
#include <libp2p/crypto/aes_ctr/aes_ctr_impl.hpp>
1313
#include <libp2p/crypto/crypto_provider/crypto_provider_impl.hpp>
1414
#include <libp2p/crypto/ecdsa_provider/ecdsa_provider_impl.hpp>
1515
#include <libp2p/crypto/ed25519_provider/ed25519_provider_impl.hpp>
@@ -259,7 +259,7 @@ namespace libp2p::injector {
259259
di::bind<crypto::rsa::RsaProvider>().template to(std::move(rsa_provider)),
260260
di::bind<crypto::ecdsa::EcdsaProvider>().template to(std::move(ecdsa_provider)),
261261
di::bind<crypto::secp256k1::Secp256k1Provider>().template to(std::move(secp256k1_provider)),
262-
di::bind<crypto::aes::AesProvider>().template to<crypto::aes::AesProviderImpl>(),
262+
di::bind<crypto::aes::AesCtr>().template to<crypto::aes::AesCtrImpl>(),
263263
di::bind<crypto::hmac::HmacProvider>().template to<crypto::hmac::HmacProviderImpl>(),
264264
di::bind<crypto::CryptoProvider>().template to<crypto::CryptoProviderImpl>(),
265265
di::bind<crypto::marshaller::KeyMarshaller>().template to<crypto::marshaller::KeyMarshallerImpl>(),

include/libp2p/security/secio/secio.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#define LIBP2P_SECIO_ADAPTOR_HPP
88

99
#include <libp2p/common/logger.hpp>
10-
#include <libp2p/crypto/aes_provider.hpp>
10+
#include <libp2p/crypto/aes_ctr.hpp>
1111
#include <libp2p/crypto/crypto_provider.hpp>
1212
#include <libp2p/crypto/hmac_provider.hpp>
1313
#include <libp2p/crypto/key_marshaller.hpp>
@@ -31,6 +31,7 @@ namespace libp2p::security {
3131
public:
3232
enum class Error {
3333
REMOTE_PEER_SIGNATURE_IS_INVALID = 1,
34+
INITIAL_PACKET_VERIFICATION_FAILED,
3435
};
3536

3637
static constexpr auto kProtocolId = "/secio/1.0.0";
@@ -46,8 +47,7 @@ namespace libp2p::security {
4647
std::shared_ptr<secio::ExchangeMessageMarshaller> exchange_marshaller,
4748
std::shared_ptr<peer::IdentityManager> idmgr,
4849
std::shared_ptr<crypto::marshaller::KeyMarshaller> key_marshaller,
49-
std::shared_ptr<crypto::hmac::HmacProvider> hmac_provider,
50-
std::shared_ptr<crypto::aes::AesProvider> aes_provider);
50+
std::shared_ptr<crypto::hmac::HmacProvider> hmac_provider);
5151

5252
peer::Protocol getProtocolId() const override;
5353

@@ -90,9 +90,9 @@ namespace libp2p::security {
9090
std::shared_ptr<crypto::marshaller::KeyMarshaller> key_marshaller_;
9191
// secio conn deps go below
9292
std::shared_ptr<crypto::hmac::HmacProvider> hmac_provider_;
93-
std::shared_ptr<crypto::aes::AesProvider> aes_provider_;
9493
//
9594
secio::ProposeMessage propose_message_;
95+
mutable common::ByteArray remote_peer_rand_;
9696
common::Logger log_ = common::createLogger("SECIO");
9797
};
9898
} // namespace libp2p::security

include/libp2p/security/secio/secio_connection.hpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
namespace libp2p::crypto {
2020
namespace aes {
21-
class AesProvider;
21+
class AesCtr;
2222
}
2323
namespace hmac {
2424
class HmacProvider;
@@ -61,7 +61,6 @@ namespace libp2p::connection {
6161
SecioConnection(
6262
std::shared_ptr<RawConnection> raw_connection,
6363
std::shared_ptr<crypto::hmac::HmacProvider> hmac_provider,
64-
std::shared_ptr<crypto::aes::AesProvider> aes_provider,
6564
std::shared_ptr<crypto::marshaller::KeyMarshaller> key_marshaller,
6665
crypto::PublicKey local_pubkey, crypto::PublicKey remote_pubkey,
6766
crypto::common::HashType hash_type,
@@ -141,28 +140,11 @@ namespace libp2p::connection {
141140
outcome::result<common::ByteArray> macRemote(
142141
gsl::span<const uint8_t> message) const;
143142

144-
/**
145-
* Does AES encryption of a message using local peer key
146-
* @param message to be encrypted
147-
* @return an encrypted representation of the message
148-
*/
149-
outcome::result<common::ByteArray> encryptLocal(
150-
gsl::span<const uint8_t> message) const;
151-
152-
/**
153-
* Does AES decryption of a message using remote peer key
154-
* @param message to be decrypted
155-
* @return a decrypted representation of the message
156-
*/
157-
outcome::result<common::ByteArray> decryptRemote(
158-
gsl::span<const uint8_t> message) const;
159-
160143
/// Returns MAC digest size in bytes for the chosen algorithm
161144
outcome::result<size_t> macSize() const;
162145

163146
std::shared_ptr<RawConnection> raw_connection_;
164147
std::shared_ptr<crypto::hmac::HmacProvider> hmac_provider_;
165-
std::shared_ptr<crypto::aes::AesProvider> aes_provider_;
166148
std::shared_ptr<crypto::marshaller::KeyMarshaller> key_marshaller_;
167149

168150
crypto::PublicKey local_;
@@ -176,6 +158,9 @@ namespace libp2p::connection {
176158
boost::optional<AesSecrets<crypto::common::Aes128Secret>> aes128_secrets_;
177159
boost::optional<AesSecrets<crypto::common::Aes256Secret>> aes256_secrets_;
178160

161+
boost::optional<std::unique_ptr<crypto::aes::AesCtr>> local_encryptor_;
162+
boost::optional<std::unique_ptr<crypto::aes::AesCtr>> remote_decryptor_;
163+
179164
std::queue<uint8_t> user_data_buffer_;
180165
common::Logger log_ = common::createLogger("SECCONN");
181166
};

src/crypto/aes_provider/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55

66
libp2p_add_library(p2p_aes_provider
7-
aes_provider_impl.cpp
7+
aes_ctr_impl.cpp
88
)
99

1010
target_link_libraries(p2p_aes_provider

0 commit comments

Comments
 (0)