Program Listing for File cipher_provider.hpp
↰ Return to documentation for file (libspookyaction/include/desfire/cipher_provider.hpp
)
//
// Created by spak on 5/10/21.
//
#ifndef DESFIRE_CIPHER_PROVIDER_HPP
#define DESFIRE_CIPHER_PROVIDER_HPP
#include <desfire/data.hpp>
#include <desfire/keys.hpp>
#include <desfire/protocol.hpp>
#include <memory>
namespace desfire {
struct cipher_provider {
[[nodiscard]] virtual std::unique_ptr<protocol> protocol_from_key(any_key const &key) = 0;
[[nodiscard]] virtual std::unique_ptr<crypto> crypto_from_key(any_key const &key) = 0;
virtual ~cipher_provider() = default;
[[nodiscard]] static std::unique_ptr<cipher_provider> platform_default();
};
template <class CryptoDES, class Crypto2K3DES, class Crypto3K3DES, class CryptoAES,
class ProtocolDES = protocol_legacy, class Protocol2K3DES = protocol_legacy,
class Protocol3K3DES = protocol_default, class ProtocolAES = protocol_default>
struct typed_cipher_provider final : public cipher_provider {
static_assert(std::is_base_of_v<crypto, CryptoDES>);
static_assert(std::is_base_of_v<crypto, Crypto2K3DES>);
static_assert(std::is_base_of_v<crypto, Crypto3K3DES>);
static_assert(std::is_base_of_v<crypto, CryptoAES>);
static_assert(std::is_base_of_v<protocol, ProtocolDES>);
static_assert(std::is_base_of_v<protocol, Protocol2K3DES>);
static_assert(std::is_base_of_v<protocol, Protocol3K3DES>);
static_assert(std::is_base_of_v<protocol, ProtocolAES>);
using crypto_des = CryptoDES;
using crypto_2k3des = Crypto2K3DES;
using crypto_3k3des = Crypto3K3DES;
using crypto_aes = CryptoAES;
using protocol_des = ProtocolDES;
using protocol_2k3des = Protocol2K3DES;
using protocol_3k3des = Protocol3K3DES;
using protocol_aes = ProtocolAES;
[[nodiscard]] std::unique_ptr<protocol> protocol_from_key(any_key const &key) override;
[[nodiscard]] std::unique_ptr<crypto> crypto_from_key(any_key const &key) override;
[[nodiscard]] crypto_des typed_crypto_from_key(key<cipher_type::des> const &key) const {
crypto_des retval{};
retval.setup_with_key(key.as_range());
return retval;
}
[[nodiscard]] protocol_des typed_protocol_from_key(key<cipher_type::des> const &key) const {
return protocol_des{typed_crypto_from_key(key)};
}
[[nodiscard]] crypto_2k3des typed_crypto_from_key(key<cipher_type::des3_2k> const &key) const {
crypto_2k3des retval{};
retval.setup_with_key(key.as_range());
return retval;
}
[[nodiscard]] protocol_2k3des typed_protocol_from_key(key<cipher_type::des3_2k> const &key) const {
return protocol_2k3des{typed_crypto_from_key(key)};
}
[[nodiscard]] crypto_3k3des typed_crypto_from_key(key<cipher_type::des3_3k> const &key) const {
crypto_3k3des retval{};
retval.setup_with_key(key.as_range());
return retval;
}
[[nodiscard]] protocol_3k3des typed_protocol_from_key(key<cipher_type::des3_3k> const &key) const {
return protocol_3k3des{typed_crypto_from_key(key)};
}
[[nodiscard]] crypto_aes typed_crypto_from_key(key<cipher_type::aes128> const &key) const {
crypto_aes retval{};
retval.setup_with_key(key.as_range());
return retval;
}
[[nodiscard]] protocol_aes typed_protocol_from_key(key<cipher_type::aes128> const &key) const {
return protocol_aes{typed_crypto_from_key(key)};
}
};
}// namespace desfire
namespace desfire {
template <class CryptoDES, class Crypto2K3DES, class Crypto3K3DES, class CryptoAES,
class ProtocolDES, class Protocol2K3DES, class Protocol3K3DES, class ProtocolAES>
std::unique_ptr<protocol> typed_cipher_provider<CryptoDES, Crypto2K3DES, Crypto3K3DES, CryptoAES,
ProtocolDES, Protocol2K3DES, Protocol3K3DES, ProtocolAES>::protocol_from_key(any_key const &key) {
switch (key.type()) {
case cipher_type::des: {
auto crypto = std::make_unique<CryptoDES>();
crypto->setup_with_key(key.template get<cipher_type::des>().as_range());
return std::make_unique<ProtocolDES>(std::move(crypto));
}
case cipher_type::des3_2k: {
auto crypto = std::make_unique<Crypto2K3DES>();
crypto->setup_with_key(key.template get<cipher_type::des3_2k>().as_range());
return std::make_unique<Protocol2K3DES>(std::move(crypto));
}
case cipher_type::des3_3k: {
auto crypto = std::make_unique<Crypto3K3DES>();
crypto->setup_with_key(key.template get<cipher_type::des3_3k>().as_range());
return std::make_unique<Protocol3K3DES>(std::move(crypto));
}
case cipher_type::aes128: {
auto crypto = std::make_unique<CryptoAES>();
crypto->setup_with_key(key.template get<cipher_type::aes128>().as_range());
return std::make_unique<ProtocolAES>(std::move(crypto));
}
case cipher_type::none:
[[fallthrough]];
default:
return std::make_unique<protocol_dummy>();
}
}
template <class CryptoDES, class Crypto2K3DES, class Crypto3K3DES, class CryptoAES,
class ProtocolDES, class Protocol2K3DES, class Protocol3K3DES, class ProtocolAES>
std::unique_ptr<crypto> typed_cipher_provider<CryptoDES, Crypto2K3DES, Crypto3K3DES, CryptoAES,
ProtocolDES, Protocol2K3DES, Protocol3K3DES, ProtocolAES>::crypto_from_key(any_key const &key) {
switch (key.type()) {
case cipher_type::des: {
auto crypto = std::make_unique<CryptoDES>();
crypto->setup_with_key(key.template get<cipher_type::des>().as_range());
return crypto;
}
case cipher_type::des3_2k: {
auto crypto = std::make_unique<Crypto2K3DES>();
crypto->setup_with_key(key.template get<cipher_type::des3_2k>().as_range());
return crypto;
}
case cipher_type::des3_3k: {
auto crypto = std::make_unique<Crypto3K3DES>();
crypto->setup_with_key(key.template get<cipher_type::des3_3k>().as_range());
return crypto;
}
case cipher_type::aes128: {
auto crypto = std::make_unique<CryptoAES>();
crypto->setup_with_key(key.template get<cipher_type::aes128>().as_range());
return crypto;
}
case cipher_type::none:
[[fallthrough]];
default:
return nullptr;
}
}
}// namespace desfire
#endif//DESFIRE_CIPHER_PROVIDER_HPP