├── fingerprint ├── fingerprint_switches.h ├── crypt │ ├── twofishcpp.h │ ├── openbsd.h │ ├── bcrypt.h │ ├── base64.h │ ├── twofishcpp.cc │ ├── node_blf.h │ ├── twofish.h │ ├── base64.cc │ ├── bcrypt.cc │ ├── blowfish.cc │ └── twofish.c ├── webrtc.h ├── navigator.h ├── webgl_renderer.h ├── webrtc.cc ├── settings_keys.h ├── services │ ├── settings_service.h │ ├── context.cc │ ├── path_service.h │ ├── context.h │ ├── use_service.h │ ├── path_service.cc │ └── settings_service.cc ├── utility.h ├── fingerprint_context.h ├── internal │ ├── uniform_int_distribution.h │ ├── apply_float_noise.h │ ├── uniform_float_distribution.h │ ├── string_algorithm.h │ └── string_algorithm.cc ├── webgl_noise.h ├── fingerprint_context.cc ├── utility.cc ├── webgl_renderer.cc ├── main.cc ├── settings.h └── settings.cc ├── .gitignore ├── CMakeLists.txt ├── BUILD.gn ├── README.md └── LICENSE /fingerprint/fingerprint_switches.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fingerprint { 4 | namespace switches { 5 | 6 | constexpr const char kFingerprintPreferences[] = "fingerprint-preferences"; 7 | 8 | } // namespace switches 9 | } // namespace fingerprint 10 | -------------------------------------------------------------------------------- /fingerprint/crypt/twofishcpp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace fingerprint { 7 | 8 | std::string TwofishEncrypt(std::string_view plaintext, std::string_view key); 9 | std::string TwofishDecrypt(std::string_view ciphertext, std::string_view key); 10 | 11 | } // namespace fingerprint 12 | -------------------------------------------------------------------------------- /fingerprint/webrtc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace fingerprint { 6 | 7 | enum WebRTCIPHandlingPolicy : std::size_t { 8 | kDefault, 9 | kDefaultPublicAndPrivateInterfaces, 10 | kDefaultPublicInterfaceOnly, 11 | kDisableNonProxiedUdp, 12 | }; 13 | 14 | std::string_view GetWebRTCIPHandlingPolicySwitch(WebRTCIPHandlingPolicy policy); 15 | 16 | } // namespace fingerprint 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Folders 35 | build/ 36 | out/ 37 | .vscode/ 38 | 39 | # Files 40 | .gn 41 | -------------------------------------------------------------------------------- /fingerprint/crypt/openbsd.h: -------------------------------------------------------------------------------- 1 | #ifndef ARC4RANDOM_H_INCLUDED 2 | #define ARC4RANDOM_H_INCLUDED 3 | 4 | #include /* srand, rand */ 5 | #include 6 | #include 7 | #include 8 | 9 | inline 10 | void arc4random_buf(void *buf, size_t nbytes) 11 | { 12 | 13 | for( size_t n = 0; n < nbytes; ++ n) 14 | ((char*)(buf))[n] = rand() %256; 15 | } 16 | 17 | inline 18 | void arc4random_init(void) 19 | { 20 | srand( (unsigned int) time(NULL)); 21 | } 22 | 23 | 24 | #endif // ARC4RANDOM_H_INCLUDED 25 | -------------------------------------------------------------------------------- /fingerprint/crypt/bcrypt.h: -------------------------------------------------------------------------------- 1 | #ifndef BCRYPT_H 2 | #define BCRYPT_H 3 | 4 | #include 5 | #include 6 | 7 | namespace fingerprint { 8 | 9 | constexpr unsigned gkBcryptRounds = 10u; 10 | 11 | // The bcrypt algorithm, where the value of rounds can be between 4 and 31 and 12 | // specifies the base 2 logarithm of the number of rounds. The special rounds 13 | // value ‘a’ automatically selects rounds based on system performance. 14 | std::string BcryptNewHash(std::string_view password, unsigned rounds = gkBcryptRounds); 15 | 16 | bool BcryptCheckPass(std::string_view password, std::string_view hash); 17 | 18 | } // namespace fingerprint 19 | 20 | #endif // BCRYPT_H 21 | -------------------------------------------------------------------------------- /fingerprint/navigator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace fingerprint { 8 | 9 | enum class PlatformId { 10 | kDefault, kMac, kWin 11 | }; 12 | 13 | constexpr const char* NavigatorPlatform(PlatformId id) { 14 | if (id == PlatformId::kDefault) { 15 | #if defined(__APPLE__) 16 | id = PlatformId::kMac; 17 | #elif defined(_WIN32) 18 | id = PlatformId::kWin; 19 | #else 20 | #error Not Reached 21 | #endif 22 | } 23 | switch (id) 24 | { 25 | case PlatformId::kMac: 26 | return "MacIntel"; 27 | case PlatformId::kWin: 28 | return "Win32"; 29 | default: 30 | assert(false && "Not Reached"); 31 | } 32 | return ""; 33 | } 34 | 35 | } // namespace fingerprint 36 | -------------------------------------------------------------------------------- /fingerprint/webgl_renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace fingerprint { 8 | 9 | class GLrendererPool final { 10 | public: 11 | using SetContainer = std::unordered_set; 12 | using RendererContainer = SetContainer; 13 | using VendorContainer = std::unordered_map; 14 | 15 | public: 16 | GLrendererPool(); 17 | ~GLrendererPool(); 18 | 19 | void Append(const std::string& vendor, const std::string& renderer); 20 | 21 | std::string NewVendor() const noexcept; 22 | std::string NewVendor(const std::string& keyword, 23 | bool excluded) const noexcept; 24 | 25 | std::string NewRenderer(const std::string& vendor) const noexcept; 26 | 27 | private: 28 | VendorContainer vendor_2_renderers_; 29 | }; 30 | 31 | } // namespace fingerprint 32 | -------------------------------------------------------------------------------- /fingerprint/webrtc.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/webrtc.h" 2 | 3 | #include 4 | 5 | namespace fingerprint { 6 | 7 | std::string_view GetWebRTCIPHandlingPolicySwitch( 8 | WebRTCIPHandlingPolicy policy) { 9 | std::string_view result("default"); 10 | switch (policy) { 11 | case WebRTCIPHandlingPolicy::kDefault: 12 | result = "default"; 13 | break; 14 | case WebRTCIPHandlingPolicy::kDefaultPublicAndPrivateInterfaces: 15 | result = "default_public_and_private_interfaces"; 16 | break; 17 | case WebRTCIPHandlingPolicy::kDefaultPublicInterfaceOnly: 18 | result = "default_public_interface_only"; 19 | break; 20 | case WebRTCIPHandlingPolicy::kDisableNonProxiedUdp: 21 | result = "disable_non_proxied_udp"; 22 | break; 23 | default: 24 | assert(false && "Not Reached"); 25 | break; 26 | } 27 | return result; 28 | } 29 | 30 | } // namespace fingerprint 31 | -------------------------------------------------------------------------------- /fingerprint/settings_keys.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace fingerprint { 4 | 5 | // Navigator 6 | constexpr const char gkNavigatorPlatform[] = "navigator.platform"; // string 7 | constexpr const char gkNavigatorTimeZone[] = "navigator.timezone"; // string 8 | 9 | // Proxy 10 | constexpr const char gkProxyServer[] = "proxy.server"; // string 11 | constexpr const char gkProxyRealm[] = "proxy.realm"; // string 12 | constexpr const char gkProxyUser[] = "proxy.user"; // string 13 | constexpr const char gkProxyPass[] = "proxy.pass"; // string 14 | 15 | // WebRTC 16 | constexpr const char gkWebRTCIPHandlingPolicy[] = 17 | "webrtc.ip_handling_policy"; // string 18 | 19 | // WebGL 20 | constexpr const char gkWebGLVendor[] = "webgl.vendor"; // string 21 | constexpr const char gkWebGLRenderer[] = "webgl.renderer"; // string 22 | constexpr const char gkWebGLImageNoises[] = "webgl.image_noises"; // float[N] 23 | 24 | } // namespace fingerprint 25 | -------------------------------------------------------------------------------- /fingerprint/services/settings_service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "fingerprint/services/context.h" 7 | #include "fingerprint/services/path_service.h" 8 | #include "fingerprint/settings.h" 9 | 10 | namespace fingerprint { 11 | 12 | class SettingsService : public internal::Context::Service { 13 | public: 14 | using ProviderFunc = std::function; 15 | using CryptFunc = std::function; 16 | 17 | public: 18 | explicit SettingsService(internal::Context& ctx); 19 | 20 | void RegisterProvider(ProviderFunc func); 21 | 22 | CryptFunc EncodeFunc() const; 23 | CryptFunc DecodeFunc() const; 24 | 25 | const Settings& GetSettings(bool* loaded = nullptr); 26 | 27 | std::string GetCipherData(); 28 | std::string GetPlainData(); 29 | 30 | private: 31 | bool LoadSettingsIfNeeded(); 32 | 33 | private: 34 | PathService& path_service_; 35 | Settings settings_; 36 | ProviderFunc provider_func_; 37 | }; 38 | 39 | } // namespace fingerprint 40 | -------------------------------------------------------------------------------- /fingerprint/utility.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "fingerprint/crypt/bcrypt.h" 6 | #include "fingerprint/crypt/twofishcpp.h" 7 | 8 | namespace fingerprint { 9 | 10 | constexpr std::size_t gkUserNameLen = 6u; 11 | constexpr std::size_t gkGroupNameLen = 6u; 12 | constexpr std::size_t gkPasswordLen = 20u; 13 | 14 | using fingerprint::BcryptCheckPass; 15 | using fingerprint::BcryptNewHash; 16 | 17 | using fingerprint::TwofishDecrypt; 18 | using fingerprint::TwofishEncrypt; 19 | 20 | namespace RandomChar { 21 | 22 | enum Type : unsigned { 23 | kLowerAlpha = 1 << 0, 24 | kUpperAlpha = 1 << 1, 25 | kDigit = 1 << 2, 26 | kUnderscore = 1 << 3, 27 | kHyphen = 1 << 4, 28 | kSpecialCharForPassword = 1 << 5, 29 | kUserNameRequired = kLowerAlpha | kDigit, 30 | kPasswordRequired = kUserNameRequired | kUpperAlpha, 31 | }; 32 | 33 | } // namespace RandomChar 34 | 35 | std::string NewRandomStr(std::size_t len, 36 | unsigned char_type = RandomChar::kUserNameRequired); 37 | 38 | } // namespace fingerprint 39 | -------------------------------------------------------------------------------- /fingerprint/services/context.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/services/context.h" 2 | 3 | namespace fingerprint { 4 | namespace internal { 5 | 6 | Context::Context() : first_service_{nullptr} {} 7 | 8 | Context::~Context() { 9 | ShutdownContext(); 10 | DestroyContext(); 11 | } 12 | 13 | void Context::ShutdownContext() { 14 | Context::Service* s = first_service_; 15 | for (; s; s = s->next_) { 16 | if (!s->shutdown_) { 17 | s->shutdown_ = true; 18 | s->ShutdownService(); 19 | } 20 | } 21 | } 22 | 23 | void Context::DestroyContext() { 24 | while (first_service_) { 25 | Service* s = first_service_->next_; 26 | delete first_service_; 27 | first_service_ = s; 28 | } 29 | } 30 | 31 | Context::Service::Service(Context& ctx) 32 | : context_{ctx}, id_{nullptr}, next_{nullptr}, shutdown_{false} {} 33 | 34 | Context::Service::~Service() {} 35 | 36 | Context& Context::Service::ContextRef() noexcept { return context_; } 37 | 38 | void Context::Service::ShutdownService() {} 39 | 40 | } // namespace internal 41 | } // namespace fingerprint -------------------------------------------------------------------------------- /fingerprint/fingerprint_context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "fingerprint/services/context.h" 4 | #include "fingerprint/services/path_service.h" 5 | #include "fingerprint/services/settings_service.h" 6 | 7 | namespace fingerprint { 8 | 9 | class Settings; 10 | 11 | // references: 12 | // - chromium: ChromeMain() 13 | class FPcontext : public internal::Context { 14 | public: 15 | static FPcontext* GetInstance(); 16 | 17 | public: 18 | FPcontext(); 19 | ~FPcontext() override; 20 | 21 | void RegisterPathProvider(PathService::PathKey key, 22 | PathService::ProviderFunc func); 23 | 24 | // called by render: get settings ciphertext from browser. 25 | void RegisterSettingsProvider(SettingsService::ProviderFunc func); 26 | 27 | SettingsService::CryptFunc GetSettingsEncodeFunc(); 28 | 29 | // called by browser: send ciphertext to render. 30 | std::string GetSettingsCipherData(); 31 | 32 | const Settings& GetSettings(bool* loaded = nullptr); 33 | }; 34 | 35 | FPcontext* FPcontextPtr(); 36 | 37 | } // namespace fingerprint 38 | -------------------------------------------------------------------------------- /fingerprint/services/path_service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "fingerprint/services/context.h" 9 | 10 | namespace fingerprint { 11 | 12 | namespace fs = std::filesystem; 13 | 14 | // references: 15 | // - chromium: enum BasePathKey 16 | // - chromium: RegisterPathProvider() -> GetPathData() -> PathService 17 | class PathService : public internal::Context::Service { 18 | public: 19 | enum PathKey { 20 | kDirHome, 21 | kFileSettings, 22 | }; 23 | 24 | using ProviderFunc = std::function; 25 | 26 | public: 27 | explicit PathService(internal::Context& ctx); 28 | 29 | // User's root home directory. 30 | fs::path GetHomeDir() const; 31 | 32 | // fingerprint's settings path. 33 | fs::path GetSettingsFile() const; 34 | 35 | public: 36 | fs::path Get(PathKey key) const; 37 | 38 | void RegisterProvider(PathKey key, ProviderFunc func); 39 | 40 | private: 41 | mutable std::mutex mutex_; 42 | std::unordered_map paths_; 43 | }; 44 | 45 | } // namespace fingerprint 46 | -------------------------------------------------------------------------------- /fingerprint/services/context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace fingerprint { 7 | namespace internal { 8 | 9 | class Context { 10 | template 11 | friend ServiceT& UseService(Context& ctx); 12 | 13 | public: 14 | class Service; 15 | 16 | public: 17 | Context(); 18 | Context(const Context&) = delete; 19 | Context& operator=(const Context&) = delete; 20 | virtual ~Context(); 21 | 22 | private: 23 | void ShutdownContext(); 24 | void DestroyContext(); 25 | 26 | private: 27 | std::mutex mutex_; 28 | Service* first_service_; 29 | }; 30 | 31 | class Context::Service { 32 | friend Context; 33 | 34 | template 35 | friend ServiceT& UseService(Context& ctx); 36 | 37 | protected: 38 | explicit Service(Context& ctx); 39 | virtual ~Service(); 40 | 41 | Context& ContextRef() noexcept; 42 | 43 | private: 44 | virtual void ShutdownService(); 45 | 46 | private: 47 | Context& context_; 48 | const std::type_info* id_; 49 | Service* next_; 50 | bool shutdown_; 51 | }; 52 | 53 | } // namespace internal 54 | } // namespace fingerprint 55 | -------------------------------------------------------------------------------- /fingerprint/internal/uniform_int_distribution.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace fingerprint { 7 | namespace internal { 8 | 9 | template 10 | class UniformIntDistribution { 11 | public: 12 | using ValueType = T; 13 | using Engine = std::default_random_engine; 14 | using Distribution = std::uniform_int_distribution; 15 | 16 | static_assert(std::is_integral::value); 17 | 18 | public: 19 | // [min, max] 20 | UniformIntDistribution(ValueType min, ValueType max) 21 | : gen_{Seed()}, distribution_{min, max} {} 22 | 23 | ValueType operator()() { return distribution_(gen_); } 24 | 25 | template 26 | void operator()(It first, It last) { 27 | while (first < last) { 28 | *first++ = distribution_(gen_); 29 | } 30 | } 31 | 32 | private: 33 | static Engine::result_type Seed() { 34 | constexpr auto max = (std::numeric_limits::max)(); 35 | auto s = std::random_device{}() % max; 36 | return static_cast(s); 37 | } 38 | 39 | private: 40 | Engine gen_; 41 | Distribution distribution_; 42 | }; 43 | 44 | } // namespace internal 45 | } // namespace fingerprint 46 | -------------------------------------------------------------------------------- /fingerprint/services/use_service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "fingerprint/services/context.h" 8 | 9 | namespace fingerprint { 10 | namespace internal { 11 | 12 | template 13 | ServiceT& UseService(Context& ctx) { 14 | Context::Service* s = nullptr; 15 | { 16 | std::lock_guard lock(ctx.mutex_); 17 | s = ctx.first_service_; 18 | } 19 | const std::type_info* id = &typeid(ServiceT); 20 | 21 | // return if service already exists. 22 | for (; s; s = s->next_) { 23 | if (*id == *s->id_) { 24 | return static_cast(*s); 25 | } 26 | } 27 | 28 | // create if service is not existed. 29 | auto new_s = std::make_unique(ctx); 30 | new_s->id_ = id; 31 | { 32 | std::lock_guard lock(ctx.mutex_); 33 | for (auto* ss = ctx.first_service_; ss; ss = ss->next_) { 34 | if (*id == *ss->id_) { 35 | return static_cast(*ss); 36 | } 37 | } 38 | new_s->next_ = ctx.first_service_; 39 | ctx.first_service_ = new_s.release(); 40 | return static_cast(*ctx.first_service_); 41 | } 42 | } 43 | 44 | } // namespace internal 45 | } // namespace fingerprint 46 | -------------------------------------------------------------------------------- /fingerprint/crypt/base64.h: -------------------------------------------------------------------------------- 1 | // 2 | // base64 encoding and decoding with C++. 3 | // Version: 2.rc.09 (release candidate) 4 | // 5 | 6 | #ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A 7 | #define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A 8 | 9 | #include 10 | 11 | #if __cplusplus >= 201703L 12 | #include 13 | #endif // __cplusplus >= 201703L 14 | 15 | std::string base64_encode (std::string const& s, bool url = false); 16 | std::string base64_encode_pem (std::string const& s); 17 | std::string base64_encode_mime(std::string const& s); 18 | 19 | std::string base64_decode(std::string const& s, bool remove_linebreaks = false); 20 | std::string base64_encode(unsigned char const*, size_t len, bool url = false); 21 | 22 | #if __cplusplus >= 201703L 23 | // 24 | // Interface with std::string_view rather than const std::string& 25 | // Requires C++17 26 | // Provided by Yannic Bonenberger (https://github.com/Yannic) 27 | // 28 | std::string base64_encode (std::string_view s, bool url = false); 29 | std::string base64_encode_pem (std::string_view s); 30 | std::string base64_encode_mime(std::string_view s); 31 | 32 | std::string base64_decode(std::string_view s, bool remove_linebreaks = false); 33 | #endif // __cplusplus >= 201703L 34 | 35 | #endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */ 36 | -------------------------------------------------------------------------------- /fingerprint/webgl_noise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "fingerprint/internal/apply_float_noise.h" 6 | #include "fingerprint/internal/uniform_float_distribution.h" 7 | 8 | namespace fingerprint { 9 | 10 | constexpr float gkGLnoiseMinimum = 0.0001f; 11 | constexpr float gkGLnoiseMaximum = 0.001f; 12 | constexpr unsigned int gkGLnoiseFloatArraySize = 64u; 13 | 14 | constexpr float gkGLclipSpaceMinimum = -1.0f; 15 | constexpr float gkGLclipSpaceMaximum = 1.0f; 16 | 17 | template 18 | void GLnewNoiseFloatArray(FloatArray& out) { 19 | using namespace fingerprint::internal; 20 | out.resize(gkGLnoiseFloatArraySize); 21 | FillRandomFloatArray(out.begin(), out.end(), gkGLnoiseMinimum, 22 | gkGLnoiseMaximum); 23 | } 24 | 25 | template 26 | Target* GLapplyNoise(Target* target, const Source* source, Count count, 27 | const NoiseFloatArray& noiseArray) { 28 | using namespace fingerprint::internal; 29 | ApplyFloatNoise transform{gkGLclipSpaceMinimum, 30 | gkGLclipSpaceMaximum, noiseArray}; 31 | auto first = static_cast(source); 32 | auto last = first; 33 | std::advance(last, count); 34 | transform(first, last, target); 35 | return target; 36 | } 37 | 38 | } // namespace fingerprint 39 | -------------------------------------------------------------------------------- /fingerprint/internal/apply_float_noise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace fingerprint { 7 | namespace internal { 8 | 9 | template > 10 | class ApplyFloatNoise { 11 | public: 12 | using ContainerType = Container; 13 | using ValueType = typename ContainerType::value_type; 14 | using SizeType = decltype(std::declval().size()); 15 | 16 | static_assert(std::is_floating_point::value); 17 | 18 | public: 19 | // [min, max] 20 | ApplyFloatNoise(ValueType min, ValueType max, ContainerType noises) 21 | : min_{min}, max_{max}, noises_{noises} {} 22 | 23 | ValueType operator()(ValueType value) { 24 | if (index_ < noises_.size()) { 25 | auto noise = noises_[index_]; 26 | index_ = ++index_ % noises_.size(); 27 | if (value + noise <= max_) { 28 | return value + noise; 29 | } else if (value - noise >= min_) { 30 | return value - noise; 31 | } 32 | } 33 | return value; 34 | } 35 | 36 | template 37 | void operator()(It first, It last, OutIt out) { 38 | while (first < last) { 39 | *out++ = (*this)(*first++); 40 | } 41 | } 42 | 43 | private: 44 | ValueType min_; 45 | ValueType max_; 46 | ContainerType noises_; 47 | SizeType index_ = 0; 48 | }; 49 | 50 | } // namespace internal 51 | } // namespace fingerprint 52 | -------------------------------------------------------------------------------- /fingerprint/fingerprint_context.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/fingerprint_context.h" 2 | 3 | #include 4 | 5 | #include "fingerprint/services/settings_service.h" 6 | #include "fingerprint/services/use_service.h" 7 | 8 | namespace { 9 | 10 | fingerprint::FPcontext* s_fp_context = nullptr; 11 | 12 | } // namespace 13 | 14 | namespace fingerprint { 15 | 16 | FPcontext* FPcontext::GetInstance() { 17 | assert(s_fp_context && 18 | "FPcontext must keep alive in application's lifecycle."); 19 | return s_fp_context; 20 | } 21 | 22 | FPcontext::FPcontext() { s_fp_context = this; } 23 | 24 | FPcontext::~FPcontext() { s_fp_context = nullptr; } 25 | 26 | void FPcontext::RegisterPathProvider(PathService::PathKey key, 27 | PathService::ProviderFunc func) { 28 | return internal::UseService(*this).RegisterProvider(key, func); 29 | } 30 | 31 | void FPcontext::RegisterSettingsProvider(SettingsService::ProviderFunc func) { 32 | return internal::UseService(*this).RegisterProvider(func); 33 | } 34 | 35 | SettingsService::CryptFunc FPcontext::GetSettingsEncodeFunc() { 36 | return internal::UseService(*this).EncodeFunc(); 37 | } 38 | 39 | std::string FPcontext::GetSettingsCipherData() { 40 | return internal::UseService(*this).GetCipherData(); 41 | } 42 | 43 | const Settings& FPcontext::GetSettings(bool* loaded) { 44 | return internal::UseService(*this).GetSettings(loaded); 45 | } 46 | 47 | FPcontext* FPcontextPtr() { return FPcontext::GetInstance(); } 48 | 49 | } // namespace fingerprint -------------------------------------------------------------------------------- /fingerprint/internal/uniform_float_distribution.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace fingerprint { 7 | namespace internal { 8 | 9 | template 10 | class UniformFloatDistribution { 11 | public: 12 | using ValueType = T; 13 | using Engine = std::default_random_engine; 14 | using Distribution = std::uniform_real_distribution; 15 | 16 | static_assert(std::is_floating_point::value); 17 | 18 | public: 19 | // [min, max) 20 | UniformFloatDistribution(ValueType min, ValueType max) 21 | : gen_{Seed()}, distribution_{min, max} {} 22 | 23 | ValueType operator()() { return distribution_(gen_); } 24 | 25 | template 26 | void operator()(It first, It last) { 27 | while (first < last) { 28 | *first++ = distribution_(gen_); 29 | } 30 | } 31 | 32 | private: 33 | static Engine::result_type Seed() { 34 | constexpr auto max = (std::numeric_limits::max)(); 35 | auto s = std::random_device{}() % max; 36 | return static_cast(s); 37 | } 38 | 39 | private: 40 | Engine gen_; 41 | Distribution distribution_; 42 | }; 43 | 44 | template 45 | void FillRandomFloatArray(It first, It last, Value min, Value max) { 46 | UniformFloatDistribution ufd{min, max}; 47 | ufd(first, last); 48 | } 49 | 50 | template 51 | void FillRandomFloatArrayN(It first, Size n, Value min, Value max) { 52 | auto last = first; 53 | std::advance(first, n); 54 | FillRandomFloatArray(first, last, min, max); 55 | } 56 | 57 | } // namespace internal 58 | } // namespace fingerprint 59 | -------------------------------------------------------------------------------- /fingerprint/services/path_service.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/services/path_service.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "fingerprint/internal/string_algorithm.h" 8 | 9 | namespace { 10 | 11 | constexpr std::string_view kSettingsProfile = ".fingerprint"; 12 | 13 | } // namespace 14 | 15 | namespace fingerprint { 16 | 17 | PathService::PathService(internal::Context& ctx) 18 | : internal::Context::Service(ctx) { 19 | // User's home directory. 20 | auto home_dir = []() -> fs::path { return std::getenv("HOME"); }; 21 | RegisterProvider(PathKey::kDirHome, home_dir); 22 | 23 | // TODO: 24 | auto settings_profile = [this]() { 25 | return GetHomeDir() / kSettingsProfile; 26 | }; 27 | RegisterProvider(PathKey::kFileSettings, settings_profile); 28 | } 29 | 30 | fs::path PathService::GetHomeDir() const { return Get(PathKey::kDirHome); } 31 | 32 | fs::path PathService::GetSettingsFile() const { 33 | return Get(PathKey::kFileSettings); 34 | } 35 | 36 | fs::path PathService::Get(PathKey key) const { 37 | ProviderFunc path_func; 38 | { 39 | std::lock_guard lock(mutex_); 40 | if (auto it = paths_.find(key); it != paths_.cend()) { 41 | path_func = it->second; 42 | } 43 | } 44 | if (!path_func) { 45 | auto ec = std::make_error_code(std::errc::invalid_argument); 46 | throw std::system_error{ec, "PathKey (" + 47 | internal::ToString(static_cast(key)) + 48 | ") not exists"}; 49 | } 50 | return path_func(); 51 | } 52 | 53 | void PathService::RegisterProvider(PathKey key, ProviderFunc func) { 54 | std::lock_guard lock(mutex_); 55 | paths_[key] = func; 56 | } 57 | 58 | } // namespace fingerprint -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | project(browser_fingerprint VERSION 0.1.0 LANGUAGES C CXX) 3 | 4 | set(sources 5 | "fingerprint/crypt/base64.cc" 6 | "fingerprint/crypt/base64.h" 7 | "fingerprint/crypt/bcrypt.cc" 8 | "fingerprint/crypt/bcrypt.h" 9 | "fingerprint/crypt/blowfish.cc" 10 | "fingerprint/crypt/node_blf.h" 11 | "fingerprint/crypt/openbsd.h" 12 | "fingerprint/crypt/twofishcpp.cc" 13 | "fingerprint/crypt/twofishcpp.h" 14 | "fingerprint/crypt/twofish.c" 15 | "fingerprint/crypt/twofish.h" 16 | "fingerprint/fingerprint_context.cc" 17 | "fingerprint/fingerprint_context.h" 18 | "fingerprint/fingerprint_switches.h" 19 | "fingerprint/internal/apply_float_noise.h" 20 | "fingerprint/internal/uniform_float_distribution.h" 21 | "fingerprint/internal/uniform_int_distribution.h" 22 | "fingerprint/internal/string_algorithm.cc" 23 | "fingerprint/internal/string_algorithm.h" 24 | "fingerprint/navigator.h" 25 | "fingerprint/services/context.cc" 26 | "fingerprint/services/context.h" 27 | "fingerprint/services/path_service.cc" 28 | "fingerprint/services/path_service.h" 29 | "fingerprint/services/settings_service.cc" 30 | "fingerprint/services/settings_service.h" 31 | "fingerprint/services/use_service.h" 32 | "fingerprint/settings.cc" 33 | "fingerprint/settings.h" 34 | "fingerprint/settings_keys.h" 35 | "fingerprint/webgl_noise.h" 36 | "fingerprint/webgl_renderer.cc" 37 | "fingerprint/webgl_renderer.h" 38 | "fingerprint/webrtc.cc" 39 | "fingerprint/webrtc.h" 40 | "fingerprint/utility.cc" 41 | "fingerprint/utility.h" 42 | ) 43 | 44 | set(fingerprint ${PROJECT_NAME}) 45 | add_library(${fingerprint} ${sources}) 46 | target_compile_features(${fingerprint} PUBLIC cxx_std_20) 47 | target_include_directories(${fingerprint} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 48 | 49 | # for developing 50 | add_executable(main "fingerprint/main.cc") 51 | target_link_libraries(main ${fingerprint}) 52 | -------------------------------------------------------------------------------- /fingerprint/utility.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/utility.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "fingerprint/internal/uniform_int_distribution.h" 7 | 8 | namespace fingerprint { 9 | 10 | std::string NewRandomStr(std::size_t len, unsigned char_type) { 11 | constexpr std::string_view kLowerAlphas = "abcdefghjkmnpqrstuvwxy"; 12 | constexpr std::string_view kUpperAlphas = "ABCDEFGHJKLMNPQRSTUVWXY"; 13 | constexpr std::string_view kDigits = "3456789"; 14 | constexpr std::string_view kUnderscore = "_"; 15 | constexpr std::string_view kHyphen = "-"; 16 | constexpr std::string_view kSpecialCharsForPassword = 17 | "!#$%&()*,./:;?@[]^_{|}~+<=>"; 18 | 19 | std::string charset; 20 | if (char_type & RandomChar::kLowerAlpha) { 21 | charset += kLowerAlphas; 22 | } 23 | if (char_type & RandomChar::kUpperAlpha) { 24 | charset += kUpperAlphas; 25 | } 26 | if (char_type & RandomChar::kDigit) { 27 | charset += kDigits; 28 | } 29 | if (char_type & RandomChar::kUnderscore) { 30 | charset += kUnderscore; 31 | } 32 | if (char_type & RandomChar::kHyphen) { 33 | charset += kHyphen; 34 | } 35 | if (char_type & RandomChar::kSpecialCharForPassword) { 36 | charset += kSpecialCharsForPassword; 37 | } 38 | const bool kHasHyphen = (charset.find(kHyphen) != std::string::npos); 39 | 40 | std::string result(len, '\0'); 41 | internal::UniformIntDistribution uid( 42 | 0, charset.size()); 43 | for (std::size_t i = 0; i != len;) { 44 | bool insert_hyphen = (((i + 1) % 7) == 0); 45 | if (!kHasHyphen && insert_hyphen) { 46 | result += kHyphen; 47 | ++i; 48 | continue; 49 | } 50 | 51 | auto ch = charset[uid()]; 52 | if (i == 0 && (char_type & RandomChar::kUserNameRequired)) { 53 | if (!std::isalpha(ch)) { 54 | continue; 55 | } 56 | } 57 | result.push_back(ch); 58 | ++i; 59 | } 60 | return result; 61 | } 62 | 63 | } // namespace fingerprint 64 | -------------------------------------------------------------------------------- /fingerprint/services/settings_service.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/services/settings_service.h" 2 | 3 | #include "fingerprint/crypt/base64.h" 4 | #include "fingerprint/services/use_service.h" 5 | #include "fingerprint/utility.h" 6 | 7 | namespace { 8 | 9 | constexpr std::string_view kPass = "WhrnQK-xfPqGr-yDHHGY"; 10 | 11 | std::string Encode(const std::string& plaintext) { 12 | return base64_encode(fingerprint::TwofishEncrypt(plaintext, kPass)); 13 | } 14 | 15 | std::string Decode(const std::string& ciphertext) { 16 | return fingerprint::TwofishDecrypt(base64_decode(ciphertext), kPass); 17 | } 18 | 19 | } // namespace 20 | 21 | namespace fingerprint { 22 | 23 | SettingsService::SettingsService(internal::Context& ctx) 24 | : internal::Context::Service(ctx), 25 | path_service_(internal::UseService(ctx)) {} 26 | 27 | void SettingsService::RegisterProvider(ProviderFunc func) { 28 | provider_func_ = func; 29 | } 30 | 31 | SettingsService::CryptFunc SettingsService::EncodeFunc() const { 32 | return Encode; 33 | } 34 | 35 | SettingsService::CryptFunc SettingsService::DecodeFunc() const { 36 | return Decode; 37 | } 38 | 39 | const Settings& SettingsService::GetSettings(bool* loaded) { 40 | if (loaded) { 41 | *loaded = LoadSettingsIfNeeded(); 42 | } else { 43 | LoadSettingsIfNeeded(); 44 | } 45 | return settings_; 46 | } 47 | 48 | std::string SettingsService::GetCipherData() { 49 | return Encode(GetPlainData()); 50 | } 51 | 52 | std::string SettingsService::GetPlainData() { 53 | return SaveSettingsToText(GetSettings()); 54 | } 55 | 56 | bool SettingsService::LoadSettingsIfNeeded() { 57 | static bool loaded = [this]() { 58 | // load from provider 59 | if (provider_func_) { 60 | auto ciphertext = provider_func_(); 61 | settings_ = LoadSettingsFromText(Decode(ciphertext)); 62 | return true; 63 | } 64 | // load from disk 65 | auto file = path_service_.GetSettingsFile(); 66 | if (fs::is_regular_file(file)) { 67 | settings_ = LoadSettingsFromFile(file, Decode); 68 | return true; 69 | } 70 | return false; 71 | }(); // call once 72 | return loaded; 73 | } 74 | 75 | } // namespace fingerprint 76 | -------------------------------------------------------------------------------- /fingerprint/webgl_renderer.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/webgl_renderer.h" 2 | 3 | #include 4 | 5 | #include "fingerprint/internal/uniform_int_distribution.h" 6 | #include "fingerprint/internal/string_algorithm.h" 7 | 8 | namespace fingerprint { 9 | 10 | GLrendererPool::GLrendererPool() { 11 | Append("Apple Inc.", "Apple GPU"); 12 | Append("Google Inc. (Apple)", "ANGLE (Apple, Apple M2, OpenGL 4.1)"); 13 | Append("Google Inc. (Apple)", 14 | "ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version)"); 15 | // TODO: add more... 16 | } 17 | 18 | GLrendererPool::~GLrendererPool() {} 19 | 20 | void GLrendererPool::Append(const std::string& vendor, 21 | const std::string& renderer) { 22 | vendor_2_renderers_[vendor].insert(renderer); 23 | } 24 | 25 | std::string GLrendererPool::NewVendor() const noexcept { 26 | const std::string keyword{"Apple"}; 27 | #if defined(__APPLE__) 28 | constexpr bool excluded = false; 29 | #else 30 | constexpr bool excluded = true; 31 | #endif 32 | return NewVendor(keyword, excluded); 33 | } 34 | 35 | std::string GLrendererPool::NewVendor(const std::string& keyword, 36 | bool excluded) const noexcept { 37 | std::vector vendors; 38 | for (const auto& [k, v] : vendor_2_renderers_) { 39 | if (keyword.empty() || 40 | (excluded ? !internal::StrContainsIgnoreCase(k, keyword) 41 | : internal::StrContainsIgnoreCase(k, keyword))) { 42 | vendors.push_back(k); 43 | } 44 | } 45 | if (vendors.size() > 0) { 46 | internal::UniformIntDistribution uid{0, vendors.size() - 1}; 47 | return vendors[uid()]; 48 | } 49 | return ""; 50 | } 51 | 52 | std::string GLrendererPool::NewRenderer( 53 | const std::string& vendor) const noexcept { 54 | if (auto it = vendor_2_renderers_.find(vendor); 55 | it != vendor_2_renderers_.cend() && !it->second.empty()) { 56 | internal::UniformIntDistribution uid{0, it->second.size() - 1}; 57 | auto first = it->second.cbegin(); 58 | std::advance(first, uid()); 59 | return *first; 60 | } 61 | return ""; 62 | } 63 | 64 | } // namespace fingerprint 65 | -------------------------------------------------------------------------------- /fingerprint/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "fingerprint/fingerprint_context.h" 5 | #include "fingerprint/navigator.h" 6 | #include "fingerprint/services/path_service.h" 7 | #include "fingerprint/services/use_service.h" 8 | #include "fingerprint/settings.h" 9 | #include "fingerprint/settings_keys.h" 10 | #include "fingerprint/utility.h" 11 | #include "fingerprint/webgl_noise.h" 12 | #include "fingerprint/webgl_renderer.h" 13 | #include "fingerprint/webrtc.h" 14 | 15 | using namespace fingerprint; 16 | 17 | Settings MakeSettings() { 18 | Settings st; 19 | 20 | // Navigator 21 | st.Put(gkNavigatorPlatform, NavigatorPlatform(PlatformId::kWin)); 22 | st.Put(gkNavigatorTimeZone, "America/Los_Angeles"); 23 | 24 | // Proxy 25 | st.Put(gkProxyServer, "socks5://bryan:abc123@localhost:7890"); 26 | 27 | // WebRTC 28 | st.Put(gkWebRTCIPHandlingPolicy, WebRTCIPHandlingPolicy::kDisableNonProxiedUdp); 29 | 30 | // WebGL.vendor & renderer 31 | GLrendererPool pool; 32 | auto vendor = pool.NewVendor(); 33 | st.Put(gkWebGLVendor, vendor); 34 | st.Put(gkWebGLRenderer, pool.NewRenderer(vendor)); 35 | 36 | // WebGL.image_noisces 37 | std::vector noises; 38 | GLnewNoiseFloatArray(noises); 39 | st.Put(gkWebGLImageNoises, noises.cbegin(), noises.cend()); 40 | 41 | return st; 42 | } 43 | 44 | int main() { 45 | std::cout << "Random User Info\n================" << std::endl; 46 | std::cout << "Name: " 47 | << NewRandomStr(gkUserNameLen, RandomChar::kUserNameRequired) 48 | << std::endl; 49 | std::cout << "Pass: " 50 | << NewRandomStr(gkPasswordLen, RandomChar::kPasswordRequired) 51 | << std::endl; 52 | std::cout << std::endl; 53 | 54 | FPcontext fp_context; 55 | 56 | std::cout << "Global Path Info\n================" << std::endl; 57 | auto& path_svc = UseService(fp_context); 58 | std::cout << "Home: " << path_svc.GetHomeDir() << std::endl; 59 | std::cout << "Profile: " << path_svc.GetSettingsFile() << std::endl; 60 | std::cout << std::endl; 61 | 62 | // make settings 63 | auto st = MakeSettings(); 64 | 65 | // save to disk 66 | SaveSettingsToFile(path_svc.GetSettingsFile(), st, 67 | fp_context.GetSettingsEncodeFunc()); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /BUILD.gn: -------------------------------------------------------------------------------- 1 | # for Chromium 2 | # 3 | # referenced by: 4 | # - //third_party/blink/renderer/core:core (public_deps) 5 | # 6 | 7 | config("config") { 8 | include_dirs = [ "." ] 9 | } 10 | 11 | component("fingerprint") { 12 | output_name = "browser_fingerprint" 13 | 14 | public_configs = [ ":config" ] 15 | if (is_component_build) { 16 | if (is_win) { 17 | defines += [ "FINGERPRINT_BUILD_DLL" ] 18 | } else { 19 | configs -= [ "//build/config/gcc:symbol_visibility_hidden" ] 20 | configs += [ "//build/config/gcc:symbol_visibility_default" ] 21 | } 22 | } 23 | configs -= [ 24 | "//build/config/compiler:no_exceptions", 25 | "//build/config/compiler:no_rtti", 26 | ] 27 | configs += [ 28 | "//build/config/compiler:exceptions", 29 | "//build/config/compiler:rtti", 30 | ] 31 | 32 | sources = [ 33 | "fingerprint/crypt/base64.cc", 34 | "fingerprint/crypt/base64.h", 35 | "fingerprint/crypt/bcrypt.cc", 36 | "fingerprint/crypt/bcrypt.h", 37 | "fingerprint/crypt/blowfish.cc", 38 | "fingerprint/crypt/node_blf.h", 39 | "fingerprint/crypt/openbsd.h", 40 | "fingerprint/crypt/twofishcpp.cc", 41 | "fingerprint/crypt/twofishcpp.h", 42 | "fingerprint/crypt/twofish.c", 43 | "fingerprint/crypt/twofish.h", 44 | "fingerprint/fingerprint_context.cc", 45 | "fingerprint/fingerprint_context.h", 46 | "fingerprint/fingerprint_switches.h", 47 | "fingerprint/internal/apply_float_noise.h", 48 | "fingerprint/internal/uniform_float_distribution.h", 49 | "fingerprint/internal/uniform_int_distribution.h", 50 | "fingerprint/internal/string_algorithm.cc", 51 | "fingerprint/internal/string_algorithm.h", 52 | "fingerprint/navigator.h", 53 | "fingerprint/services/context.cc", 54 | "fingerprint/services/context.h", 55 | "fingerprint/services/path_service.cc", 56 | "fingerprint/services/path_service.h", 57 | "fingerprint/services/settings_service.cc", 58 | "fingerprint/services/settings_service.h", 59 | "fingerprint/services/use_service.h", 60 | "fingerprint/settings.cc", 61 | "fingerprint/settings.h", 62 | "fingerprint/settings_keys.h", 63 | "fingerprint/webgl_noise.h", 64 | "fingerprint/webgl_renderer.cc", 65 | "fingerprint/webgl_renderer.h", 66 | "fingerprint/webrtc.cc", 67 | "fingerprint/webrtc.h", 68 | "fingerprint/utility.cc", 69 | "fingerprint/utility.h", 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /fingerprint/settings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "fingerprint/internal/string_algorithm.h" 9 | 10 | namespace fingerprint { 11 | 12 | class Settings { 13 | static constexpr auto kSeparator = ";"; 14 | 15 | friend std::string SaveSettingsToText(const Settings& settings); 16 | 17 | public: 18 | void Put(const std::string& key, const char* value); 19 | void Put(const std::string& key, const std::string& value); 20 | void Put(const std::string& key, std::size_t value); 21 | void Put(const std::string& key, double value); 22 | void Put(const std::string& key, bool value); 23 | 24 | template 25 | void Put(const std::string& key, It first, It last) { 26 | Put(key, internal::JoinRange(first, last, kSeparator)); 27 | } 28 | 29 | bool IsEmpty() const noexcept; 30 | bool HasKey(const std::string& key) const noexcept; 31 | 32 | std::string GetString(const std::string& key) const; 33 | std::size_t GetUInt(const std::string& key) const; 34 | double GetDouble(const std::string& key) const; 35 | bool GetBool(const std::string& key) const; 36 | 37 | template 38 | void Get(const std::string& key, Container& value) const; 39 | 40 | private: 41 | void PutInternal(const std::string& key, const std::string& value); 42 | std::string GetInternal(const std::string& key) const; 43 | 44 | private: 45 | std::unordered_map storage_; 46 | }; 47 | 48 | template 49 | void Settings::Get(const std::string& key, Container& value) const { 50 | using value_t = typename Container::value_type; 51 | 52 | auto result = GetString(key); 53 | const char* saveptr = nullptr; 54 | for (auto item = internal::StrToken(result, kSeparator, &saveptr); saveptr; 55 | item = internal::StrToken(result, kSeparator, &saveptr)) { 56 | value.push_back( 57 | internal::StrAs(std::string{item.data(), item.size()})); 58 | } 59 | } 60 | 61 | Settings LoadSettingsFromText(const std::string& text); 62 | std::string SaveSettingsToText(const Settings& settings); 63 | 64 | Settings LoadSettingsFromFile( 65 | const std::filesystem::path& path, 66 | std::function decode); 67 | void SaveSettingsToFile(const std::filesystem::path& path, 68 | const Settings& settings, 69 | std::function encode); 70 | 71 | } // namespace fingerprint 72 | -------------------------------------------------------------------------------- /fingerprint/internal/string_algorithm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace fingerprint { 9 | namespace internal { 10 | 11 | bool StrContainsIgnoreCase(std::string_view haystack, 12 | std::string_view needle) noexcept; 13 | 14 | bool EqualsIgnoreCase(std::string_view piece1, 15 | std::string_view piece2) noexcept; 16 | 17 | std::string_view StrStrip(std::string_view s) noexcept; 18 | 19 | template 20 | std::string ToString(T value) { 21 | return std::to_string(value); 22 | } 23 | 24 | std::string ToString(bool value); 25 | std::string ToString(const std::string& value); 26 | std::string ToString(std::string_view value); 27 | 28 | bool StrToBool(std::string_view value); 29 | 30 | template T> 31 | T StrAs(const std::string& value) { 32 | return StrToBool(value); 33 | } 34 | 35 | template 36 | T StrAs(const std::string& value) { 37 | constexpr auto size = sizeof(T); 38 | if constexpr (size == sizeof(unsigned long)) { 39 | return std::stoul(value); 40 | } else if constexpr (size == sizeof(unsigned long long)) { 41 | return std::stoull(value); 42 | } else { 43 | static_assert(size == sizeof(unsigned long) || 44 | size == sizeof(unsigned long long)); 45 | } 46 | } 47 | 48 | template 49 | T StrAs(const std::string& value) { 50 | constexpr auto size = sizeof(T); 51 | if constexpr (size == sizeof(float)) { 52 | return std::stof(value); 53 | } else if constexpr (size == sizeof(double)) { 54 | return std::stod(value); 55 | } else { 56 | static_assert(size == sizeof(float) || size == sizeof(double)); 57 | } 58 | } 59 | 60 | template T> 61 | T StrAs(const std::string& value) { 62 | return value; 63 | } 64 | 65 | template 66 | std::string JoinRange(It first, It last, std::string_view separator) { 67 | std::string result; 68 | if (first != last) { 69 | using value_t = typename std::iterator_traits::value_type; 70 | result = ToString(static_cast(*first)); 71 | while (++first != last) { 72 | result += separator; 73 | result += ToString(static_cast(*first)); 74 | } 75 | } 76 | return result; 77 | } 78 | 79 | std::string_view StrToken(std::string_view text, std::string_view delimiters, 80 | const char** saveptr); 81 | 82 | } // namespace internal 83 | } // namespace fingerprint 84 | -------------------------------------------------------------------------------- /fingerprint/internal/string_algorithm.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/internal/string_algorithm.h" 2 | 3 | #include 4 | 5 | namespace { 6 | 7 | constexpr auto kTrue = "true"; 8 | constexpr auto kFalse = "false"; 9 | 10 | } // namespace 11 | 12 | namespace fingerprint { 13 | namespace internal { 14 | 15 | bool StrContainsIgnoreCase(std::string_view haystack, 16 | std::string_view needle) noexcept { 17 | using size_t = std::string_view::size_type; 18 | 19 | const size_t hsize = haystack.size(); 20 | const size_t nsize = needle.size(); 21 | if (hsize < nsize) { 22 | return false; 23 | } 24 | 25 | size_t i = 0; 26 | size_t j = 0; 27 | while (i < hsize && j < nsize) { 28 | if (std::tolower(haystack[i]) == std::tolower(needle[j])) { 29 | ++i; 30 | ++j; 31 | } else { 32 | i = i - j + 1; 33 | j = 0; 34 | } 35 | } 36 | return j >= nsize; 37 | } 38 | 39 | bool EqualsIgnoreCase(std::string_view piece1, 40 | std::string_view piece2) noexcept { 41 | if (piece1.size() != piece2.size()) { 42 | return false; 43 | } 44 | for (std::string_view::size_type i = 0; i != piece1.size(); ++i) { 45 | if (std::tolower(piece1[i]) != std::tolower(piece2[i])) { 46 | return false; 47 | } 48 | } 49 | return true; 50 | } 51 | 52 | std::string_view StrStrip(std::string_view s) noexcept { 53 | auto first = s.cbegin(); 54 | for (auto it = s.cbegin(); it != s.cend(); ++it) { 55 | if (!std::isspace(*it)) { 56 | first = it; 57 | break; 58 | } 59 | } 60 | auto last = s.cend(); 61 | for (auto it = s.crbegin(); it != s.crend(); ++it) { 62 | if (!std::isspace(*it)) { 63 | last = it.base(); 64 | break; 65 | } 66 | } 67 | return {first, last}; 68 | } 69 | 70 | std::string ToString(bool value) { return value ? kTrue : kFalse; } 71 | 72 | std::string ToString(const std::string& value) { return value; } 73 | 74 | std::string ToString(std::string_view value) { 75 | return {value.data(), value.size()}; 76 | } 77 | 78 | bool StrToBool(std::string_view value) { 79 | return EqualsIgnoreCase(value, kTrue); 80 | } 81 | 82 | std::string_view StrToken(std::string_view text, std::string_view delimiters, 83 | const char** saveptr) { 84 | using size_t = std::string_view::size_type; 85 | 86 | size_t start_pos = 0; 87 | if (saveptr && *saveptr) { 88 | start_pos = *saveptr - text.data(); 89 | } 90 | 91 | // no found 92 | if (start_pos >= text.size()) { 93 | if (saveptr) { 94 | *saveptr = nullptr; 95 | } 96 | return std::string_view{}; 97 | } 98 | 99 | // start & continue 100 | size_t curr_pos = text.find_first_of(delimiters, start_pos); 101 | if (curr_pos != std::string_view::npos) { 102 | if (saveptr) { 103 | *saveptr = text.data() + curr_pos + 1; 104 | } 105 | return {text.data() + start_pos, curr_pos - start_pos}; 106 | } 107 | 108 | // last 109 | if (saveptr) { 110 | *saveptr = text.data() + text.size(); 111 | } 112 | return {text.data() + start_pos, text.size() - start_pos}; 113 | } 114 | 115 | } // namespace internal 116 | } // namespace fingerprint 117 | -------------------------------------------------------------------------------- /fingerprint/crypt/twofishcpp.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/crypt/twofishcpp.h" 2 | 3 | extern "C" { 4 | 5 | #include "fingerprint/crypt/twofish.h" 6 | } 7 | 8 | #include 9 | namespace fingerprint { 10 | 11 | std::string TwofishEncrypt(std::string_view plaintext, std::string_view key) { 12 | // initialize 13 | Twofish_initialise(); 14 | 15 | // prepare dkey 16 | Twofish_Byte dkey[32]; 17 | memset(dkey, 0, sizeof(dkey)); 18 | 19 | const int dkeylen = (key.size() < sizeof(dkey) ? key.size() : sizeof(dkey)); 20 | strncpy((char*)dkey, key.data(), dkeylen); 21 | 22 | Twofish_key xkey; 23 | Twofish_prepare_key(dkey, dkeylen, &xkey); 24 | 25 | // encrypt 26 | constexpr std::string_view::size_type blocksize = 16u; 27 | std::string ciphertext; 28 | ciphertext.reserve(plaintext.size() + (plaintext.size() % blocksize)); 29 | for (std::string_view::size_type i = 0; i != plaintext.size();) { 30 | std::string_view::size_type len = plaintext.size() - i; 31 | if (len >= blocksize) { 32 | len = blocksize; 33 | ciphertext.resize(i + len); 34 | Twofish_Byte* p = (Twofish_Byte*)plaintext.data() + i; 35 | Twofish_Byte* c = (Twofish_Byte*)ciphertext.data() + i; 36 | Twofish_encrypt(&xkey, p, c); 37 | } else { 38 | ciphertext.resize(i + blocksize); 39 | Twofish_Byte p[blocksize]; 40 | strncpy((char*)p, plaintext.data() + i, len); 41 | memset(p + len, 0, blocksize - len); 42 | Twofish_Byte* c = (Twofish_Byte*)ciphertext.data() + i; 43 | Twofish_encrypt(&xkey, p, c); 44 | } 45 | i += len; 46 | } 47 | return ciphertext; 48 | } 49 | 50 | std::string TwofishDecrypt(std::string_view ciphertext, std::string_view key) { 51 | // initialize 52 | Twofish_initialise(); 53 | 54 | // prepare dkey 55 | Twofish_Byte dkey[32]; 56 | memset(dkey, 0, sizeof(dkey)); 57 | 58 | const int dkeylen = (key.size() < sizeof(dkey) ? key.size() : sizeof(dkey)); 59 | strncpy((char*)dkey, key.data(), dkeylen); 60 | 61 | Twofish_key xkey; 62 | Twofish_prepare_key(dkey, dkeylen, &xkey); 63 | 64 | // decrypt 65 | constexpr std::string_view::size_type blocksize = 16u; 66 | std::string plaintext; 67 | plaintext.reserve(ciphertext.size() + (ciphertext.size() % blocksize)); 68 | for (std::string_view::size_type i = 0; i != ciphertext.size();) { 69 | std::string_view::size_type len = ciphertext.size() - i; 70 | if (len >= blocksize) { 71 | len = blocksize; 72 | plaintext.resize(i + len); 73 | Twofish_Byte* c = (Twofish_Byte*)ciphertext.data() + i; 74 | Twofish_Byte* p = (Twofish_Byte*)plaintext.data() + i; 75 | Twofish_decrypt(&xkey, c, p); 76 | } else { 77 | plaintext.resize(i + blocksize); 78 | Twofish_Byte c[blocksize]; 79 | strncpy((char*)c, ciphertext.data() + i, len); 80 | memset(c + len, 0, blocksize - len); 81 | Twofish_Byte* p = (Twofish_Byte*)plaintext.data() + i; 82 | Twofish_decrypt(&xkey, c, p); 83 | } 84 | i += len; 85 | } 86 | std::string::size_type n = 0; 87 | for (auto it = plaintext.crbegin(); it != plaintext.crend(); ++it) { 88 | if (*it != '\0') { 89 | break; 90 | } 91 | ++n; 92 | } 93 | return plaintext.substr(0, plaintext.size() - n); 94 | } 95 | 96 | } // namespace fingerprint 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 浏览器指纹 2 | 3 | 随机 Chromium 浏览器指纹。 4 | 5 | - [ ] Cookie 6 | - [ ] User-Agent 7 | - [ ] 时区 8 | - [ ] WebRTC 9 | - [ ] 地理位置 10 | - [ ] 语言 11 | - [ ] 屏幕分辨率 12 | - [ ] 字体 13 | - [ ] Canvas 图像噪音 14 | - [x] WebGL 图像噪音 15 | - [x] WebGL 元数据掩蔽 16 | - [ ] AudioContext 17 | - [ ] 媒体设备 18 | - [ ] ClientRects 19 | - [ ] SpeechVoices 20 | - [ ] 硬件并发数 21 | - [ ] 设备内存 22 | - [ ] 设备名称 23 | - [ ] Mac 地址 24 | - [ ] Do Not Track 25 | - [ ] Flask 26 | - [ ] 端口扫描保护 27 | - [ ] 硬件加速 28 | 29 | **Chromium 开发分支**:https://github.com/yanminhui/chromium/tree/dev 30 | 31 | ## Canves 图像噪音 32 | 33 | - 坐标偏移 34 | - RGB 噪音 35 | - 渐变比例噪音 36 | - 渐变颜色噪音 37 | - 文本测量噪音:控制在单字范围内偏差 38 | 39 | ## WebGL 图像噪音 40 | 41 | ```cpp 42 | void WebGLRenderingContextBase::BufferDataImpl(GLenum target, 43 | int64_t size, 44 | const void* data, 45 | GLenum usage) { 46 | 47 | // ... 48 | buffer->SetSize(size); 49 | 50 | using namespace fingerprint; 51 | if (data && 0 < size && size % sizeof(GLfloat) == 0 && 52 | FPcontextPtr()->GetSettings().HasKey(gkWebGLImageNoises)) { 53 | // 使用噪音序列,而不是单个噪音避免碰撞。 54 | using FloatArray = WTF::Vector; 55 | static base::NoDestructor pnoises{[]() { 56 | FloatArray fa; 57 | FPcontextPtr()->GetSettings().Get(gkWebGLImageNoises, fa); 58 | return fa; 59 | }()}; // 缓存数据,避免重复解析噪音序列。 60 | 61 | auto len = size / sizeof(GLfloat); 62 | GLfloat out[len]; 63 | GLapplyNoise(out, data, len, *pnoises); 64 | ContextGL()->BufferData(target, static_cast(size), out, usage); 65 | return; 66 | } 67 | 68 | ContextGL()->BufferData(target, static_cast(size), data, usage); 69 | } 70 | ``` 71 | 72 | ## WebGL 元数据掩蔽 73 | 74 | ```cpp 75 | ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state, 76 | GLenum pname) { 77 | // ... 78 | case WebGLDebugRendererInfo::kUnmaskedRendererWebgl: 79 | if (ExtensionEnabled(kWebGLDebugRendererInfoName)) { 80 | using namespace fingerprint; 81 | auto renderer = String(ContextGL()->GetString(GL_RENDERER)); 82 | // 当解析不到定制的配置时,使用实际值。 83 | if (FPcontextPtr()->GetSettings().HasKey(gkWebGLRenderer)) { 84 | renderer = 85 | String(FPcontextPtr()->GetSettings().GetString(gkWebGLRenderer)); 86 | } 87 | if (IdentifiabilityStudySettings::Get()->ShouldSampleType( 88 | blink::IdentifiableSurface::Type::kWebGLParameter)) { 89 | RecordIdentifiableGLParameterDigest( 90 | pname, IdentifiabilityBenignStringToken(renderer)); 91 | } 92 | return WebGLAny(script_state, renderer); 93 | } 94 | SynthesizeGLError( 95 | GL_INVALID_ENUM, "getParameter", 96 | "invalid parameter name, WEBGL_debug_renderer_info not enabled"); 97 | return ScriptValue::CreateNull(script_state->GetIsolate()); 98 | case WebGLDebugRendererInfo::kUnmaskedVendorWebgl: 99 | if (ExtensionEnabled(kWebGLDebugRendererInfoName)) { 100 | using namespace fingerprint; 101 | auto vendor = String(ContextGL()->GetString(GL_VENDOR)); 102 | // 当解析不到定制的配置时,使用实际值。 103 | if (FPcontextPtr()->GetSettings().HasKey(gkWebGLVendor)) { 104 | vendor = 105 | String(FPcontextPtr()->GetSettings().GetString(gkWebGLVendor)); 106 | } 107 | if (IdentifiabilityStudySettings::Get()->ShouldSampleType( 108 | blink::IdentifiableSurface::Type::kWebGLParameter)) { 109 | RecordIdentifiableGLParameterDigest( 110 | pname, IdentifiabilityBenignStringToken(vendor)); 111 | } 112 | return WebGLAny(script_state, vendor); 113 | } 114 | SynthesizeGLError( 115 | GL_INVALID_ENUM, "getParameter", 116 | "invalid parameter name, WEBGL_debug_renderer_info not enabled"); 117 | return ScriptValue::CreateNull(script_state->GetIsolate()); 118 | // ... 119 | } 120 | ``` 121 | -------------------------------------------------------------------------------- /fingerprint/settings.cc: -------------------------------------------------------------------------------- 1 | #include "fingerprint/settings.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace { 9 | 10 | constexpr std::size_t kSettingsCapacity = 4096u; 11 | constexpr std::string_view kKeyValueSeparator = ":"; 12 | constexpr std::string_view kLineSeparator = "\n"; 13 | 14 | } // namespace 15 | 16 | namespace fingerprint { 17 | 18 | void Settings::Put(const std::string& key, const char* value) { 19 | PutInternal(key, value); 20 | } 21 | 22 | void Settings::Put(const std::string& key, const std::string& value) { 23 | PutInternal(key, value); 24 | } 25 | 26 | void Settings::Put(const std::string& key, std::size_t value) { 27 | PutInternal(key, internal::ToString(value)); 28 | } 29 | 30 | void Settings::Put(const std::string& key, double value) { 31 | PutInternal(key, internal::ToString(value)); 32 | } 33 | 34 | void Settings::Put(const std::string& key, bool value) { 35 | PutInternal(key, internal::ToString(value)); 36 | } 37 | 38 | bool Settings::IsEmpty() const noexcept { return storage_.empty(); } 39 | 40 | bool Settings::HasKey(const std::string& key) const noexcept { 41 | auto it = storage_.find(key); 42 | return it != storage_.cend(); 43 | } 44 | 45 | std::string Settings::GetString(const std::string& key) const { 46 | return GetInternal(key); 47 | } 48 | 49 | std::size_t Settings::GetUInt(const std::string& key) const { 50 | return internal::StrAs(GetInternal(key)); 51 | } 52 | 53 | double Settings::GetDouble(const std::string& key) const { 54 | return internal::StrAs(GetInternal(key)); 55 | } 56 | 57 | bool Settings::GetBool(const std::string& key) const { 58 | return internal::StrToBool(GetInternal(key)); 59 | } 60 | 61 | void Settings::PutInternal(const std::string& key, const std::string& value) { 62 | storage_[key] = value; 63 | } 64 | 65 | std::string Settings::GetInternal(const std::string& key) const { 66 | if (auto it = storage_.find(key); it != storage_.cend()) { 67 | return it->second; 68 | } 69 | auto ec = std::make_error_code(std::errc::invalid_argument); 70 | throw std::system_error{ec, "\"" + key + "\" not found in settings"}; 71 | } 72 | 73 | Settings LoadSettingsFromText(const std::string& text) { 74 | Settings storage; 75 | const char* savelptr = nullptr; 76 | for (auto line = internal::StrToken(text, kLineSeparator, &savelptr); 77 | savelptr; line = internal::StrToken(text, kLineSeparator, &savelptr)) { 78 | auto pos = line.find(kKeyValueSeparator); 79 | if (pos == std::string_view::npos) { 80 | assert(false && "key-value is invalid in settings."); 81 | continue; 82 | } 83 | auto key = internal::StrStrip(line.substr(0, pos++)); 84 | auto value = internal::StrStrip(line.substr(pos)); 85 | storage.Put(std::string{key.data(), key.size()}, 86 | std::string{value.data(), value.size()}); 87 | } 88 | return storage; 89 | } 90 | 91 | std::string SaveSettingsToText(const Settings& settings) { 92 | std::string text; 93 | text.reserve(kSettingsCapacity); 94 | auto first = settings.storage_.cbegin(); 95 | auto last = settings.storage_.cend(); 96 | for (auto it = first; it != last; ++it) { 97 | if (it != first) { 98 | text += kLineSeparator; 99 | } 100 | text += it->first; 101 | text += kKeyValueSeparator; 102 | text += " "; 103 | text += it->second; 104 | } 105 | return text; 106 | } 107 | 108 | Settings LoadSettingsFromFile( 109 | const std::filesystem::path& path, 110 | std::function decode) { 111 | std::ifstream in(path, std::ifstream::ate | std::ifstream::binary); 112 | if (!in) { 113 | auto ec = std::make_error_code(std::errc::io_error); 114 | throw std::system_error{ec, "open \"" + path.string() + "\" failed"}; 115 | } 116 | auto size = in.tellg(); 117 | if (size == 0) { 118 | return Settings{}; 119 | } 120 | in.seekg(0); 121 | 122 | std::string ciphertext(size, '\0'); 123 | if (!in.read(&ciphertext[0], size)) { 124 | auto ec = std::make_error_code(std::errc::io_error); 125 | throw std::system_error{ec, "read \"" + path.string() + "\" error"}; 126 | } 127 | if (decode) { 128 | return LoadSettingsFromText(decode(ciphertext)); 129 | } 130 | return LoadSettingsFromText(ciphertext); 131 | } 132 | 133 | void SaveSettingsToFile(const std::filesystem::path& path, 134 | const Settings& settings, 135 | std::function encode) { 136 | std::string ciphertext; 137 | if (!settings.IsEmpty()) { 138 | if (encode) { 139 | ciphertext = encode(SaveSettingsToText(settings)); 140 | } else { 141 | ciphertext = SaveSettingsToText(settings); 142 | } 143 | } 144 | std::ofstream out(path, std::ofstream::out | std::ofstream::binary); 145 | if (!out) { 146 | auto ec = std::make_error_code(std::errc::io_error); 147 | throw std::system_error{ec, "open \"" + path.string() + "\" failed"}; 148 | } 149 | if (!out.write(ciphertext.data(), ciphertext.size())) { 150 | auto ec = std::make_error_code(std::errc::io_error); 151 | throw std::system_error{ec, "write \"" + path.string() + "\" error"}; 152 | } 153 | } 154 | 155 | } // namespace fingerprint 156 | -------------------------------------------------------------------------------- /fingerprint/crypt/node_blf.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */ 2 | /* 3 | * Blowfish - a fast block cipher designed by Bruce Schneier 4 | * 5 | * Copyright 1997 Niels Provos 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. All advertising materials mentioning features or use of this software 17 | * must display the following acknowledgement: 18 | * This product includes software developed by Niels Provos. 19 | * 4. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | #ifndef _NODE_BLF_H_ 35 | #define _NODE_BLF_H_ 36 | 37 | #include 38 | 39 | /* Solaris compatibility */ 40 | #ifdef __sun 41 | #define u_int8_t uint8_t 42 | #define u_int16_t uint16_t 43 | #define u_int32_t uint32_t 44 | #define u_int64_t uint64_t 45 | #endif 46 | 47 | #ifdef _WIN32 48 | #define u_int8_t unsigned __int8 49 | #define u_int16_t unsigned __int16 50 | #define u_int32_t unsigned __int32 51 | #define u_int64_t unsigned __int64 52 | #endif 53 | 54 | /* Windows ssize_t compatibility */ 55 | #if defined(_WIN32) || defined(_WIN64) 56 | # if defined(_WIN64) 57 | typedef __int64 LONG_PTR; 58 | # else 59 | typedef long LONG_PTR; 60 | # endif 61 | typedef LONG_PTR SSIZE_T; 62 | typedef SSIZE_T ssize_t; 63 | #endif 64 | 65 | /* z/OS compatibility */ 66 | #ifdef __MVS__ 67 | typedef unsigned char u_int8_t; 68 | typedef unsigned short u_int16_t; 69 | typedef unsigned int u_int32_t; 70 | typedef unsigned long long u_int64_t; 71 | #endif 72 | 73 | #define BCRYPT_VERSION '2' 74 | #define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */ 75 | #define BCRYPT_BLOCKS 6 /* Ciphertext blocks */ 76 | #define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */ 77 | 78 | /* Schneier specifies a maximum key length of 56 bytes. 79 | * This ensures that every key bit affects every cipher 80 | * bit. However, the subkeys can hold up to 72 bytes. 81 | * Warning: For normal blowfish encryption only 56 bytes 82 | * of the key affect all cipherbits. 83 | */ 84 | 85 | #define BLF_N 16 /* Number of Subkeys */ 86 | #define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */ 87 | #define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */ 88 | 89 | #define _PASSWORD_LEN 128 /* max length, not counting NUL */ 90 | #define _SALT_LEN 32 /* max length */ 91 | 92 | /* Blowfish context */ 93 | typedef struct BlowfishContext { 94 | u_int32_t S[4][256]; /* S-Boxes */ 95 | u_int32_t P[BLF_N + 2]; /* Subkeys */ 96 | } blf_ctx; 97 | 98 | /* Raw access to customized Blowfish 99 | * blf_key is just: 100 | * Blowfish_initstate( state ) 101 | * Blowfish_expand0state( state, key, keylen ) 102 | */ 103 | 104 | void Blowfish_encipher(blf_ctx *, u_int32_t *, u_int32_t *); 105 | void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *); 106 | void Blowfish_initstate(blf_ctx *); 107 | void Blowfish_expand0state(blf_ctx *, const u_int8_t *, u_int16_t); 108 | void Blowfish_expandstate 109 | (blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t); 110 | 111 | /* Standard Blowfish */ 112 | 113 | void blf_key(blf_ctx *, const u_int8_t *, u_int16_t); 114 | void blf_enc(blf_ctx *, u_int32_t *, u_int16_t); 115 | void blf_dec(blf_ctx *, u_int32_t *, u_int16_t); 116 | 117 | void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t); 118 | void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t); 119 | 120 | void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); 121 | void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t); 122 | 123 | /* Converts u_int8_t to u_int32_t */ 124 | u_int32_t Blowfish_stream2word(const u_int8_t *, u_int16_t , u_int16_t *); 125 | 126 | /* bcrypt functions*/ 127 | void bcrypt_gensalt(char, u_int8_t, u_int8_t*, char *); 128 | void node_bcrypt(const char *, size_t key_len, const char *, char *); 129 | void encode_salt(char *, u_int8_t *, char, u_int16_t, u_int8_t); 130 | u_int32_t bcrypt_get_rounds(const char *); 131 | 132 | #endif -------------------------------------------------------------------------------- /fingerprint/crypt/twofish.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Fast, portable, and easy-to-use Twofish implementation, 3 | * Version 0.3. 4 | * Copyright (c) 2002 by Niels Ferguson. 5 | * 6 | * See the twofish.c file for the details of the how and why of this code. 7 | * 8 | * The author hereby grants a perpetual license to everybody to 9 | * use this code for any purpose as long as the copyright message is included 10 | * in the source code of this or any derived work. 11 | */ 12 | 13 | #include 14 | 15 | /* 16 | * PLATFORM FIXES 17 | * ============== 18 | * 19 | * The following definitions have to be fixed for each particular platform 20 | * you work on. If you have a multi-platform program, you no doubt have 21 | * portable definitions that you can substitute here without changing 22 | * the rest of the code. 23 | * 24 | * The defaults provided here should work on most PC compilers. 25 | */ 26 | 27 | 28 | /* 29 | * A Twofish_Byte must be an unsigned 8-bit integer. 30 | * It must also be the elementary data size of your C platform, 31 | * i.e. sizeof( Twofish_Byte ) == 1. 32 | */ 33 | typedef uint8_t Twofish_Byte; 34 | 35 | /* 36 | * A Twofish_UInt32 must be an unsigned integer of at least 32 bits. 37 | * 38 | * This type is used only internally in the implementation, so ideally it 39 | * would not appear in the header file, but it is used inside the 40 | * Twofish_key structure which means it has to be included here. 41 | */ 42 | typedef uint32_t Twofish_UInt32; 43 | 44 | 45 | /* 46 | * END OF PLATFORM FIXES 47 | * ===================== 48 | * 49 | * You should not have to touch the rest of this file, but the code 50 | * in twofish.c has a few things you need to fix too. 51 | */ 52 | 53 | 54 | /* 55 | * Structure that contains a prepared Twofish key. 56 | * A cipher key is used in two stages. In the first stage it is converted 57 | * form the original form to an internal representation. 58 | * This internal form is then used to encrypt and decrypt data. 59 | * This structure contains the internal form. It is rather large: 4256 bytes 60 | * on a platform with 32-bit unsigned values. 61 | * 62 | * Treat this as an opague structure, and don't try to manipulate the 63 | * elements in it. I wish I could hide the inside of the structure, 64 | * but C doesn't allow that. 65 | */ 66 | typedef 67 | struct 68 | { 69 | Twofish_UInt32 s[4][256]; /* pre-computed S-boxes */ 70 | Twofish_UInt32 K[40]; /* Round key words */ 71 | } 72 | Twofish_key; 73 | 74 | 75 | /* 76 | * Initialise and test the Twofish implementation. 77 | * 78 | * This function MUST be called before any other function in the 79 | * Twofish implementation is called. 80 | * It only needs to be called once. 81 | * 82 | * Apart from initialising the implementation it performs a self test. 83 | * If the Twofish_fatal function is not called, the code passed the test. 84 | * (See the twofish.c file for details on the Twofish_fatal function.) 85 | */ 86 | extern void Twofish_initialise(); 87 | 88 | 89 | /* 90 | * Convert a cipher key to the internal form used for 91 | * encryption and decryption. 92 | * 93 | * The cipher key is an array of bytes; the Twofish_Byte type is 94 | * defined above to a type suitable on your platform. 95 | * 96 | * Any key must be converted to an internal form in the Twofisk_key structure 97 | * before it can be used. 98 | * The encryption and decryption functions only work with the internal form. 99 | * The conversion to internal form need only be done once for each key value. 100 | * 101 | * Be sure to wipe all key storage, including the Twofish_key structure, 102 | * once you are done with the key data. 103 | * A simple memset( TwofishKey, 0, sizeof( TwofishKey ) ) will do just fine. 104 | * 105 | * Unlike most implementations, this one allows any key size from 0 bytes 106 | * to 32 bytes. According to the Twofish specifications, 107 | * irregular key sizes are handled by padding the key with zeroes at the end 108 | * until the key size is 16, 24, or 32 bytes, whichever 109 | * comes first. Note that each key of irregular size is equivalent to exactly 110 | * one key of 16, 24, or 32 bytes. 111 | * 112 | * WARNING: Short keys have low entropy, and result in low security. 113 | * Anything less than 8 bytes is utterly insecure. For good security 114 | * use at least 16 bytes. I prefer to use 32-byte keys to prevent 115 | * any collision attacks on the key. 116 | * 117 | * The key length argument key_len must be in the proper range. 118 | * If key_len is not in the range 0,...,32 this routine attempts to generate 119 | * a fatal error (depending on the code environment), 120 | * and at best (or worst) returns without having done anything. 121 | * 122 | * Arguments: 123 | * key Array of key bytes 124 | * key_len Number of key bytes, must be in the range 0,1,...,32. 125 | * xkey Pointer to an Twofish_key structure that will be filled 126 | * with the internal form of the cipher key. 127 | */ 128 | extern void Twofish_prepare_key( 129 | Twofish_Byte key[], 130 | int key_len, 131 | Twofish_key * xkey 132 | ); 133 | 134 | 135 | /* 136 | * Encrypt a single block of data. 137 | * 138 | * This function encrypts a single block of 16 bytes of data. 139 | * If you want to encrypt a larger or variable-length message, 140 | * you will have to use a cipher mode, such as CBC or CTR. 141 | * These are outside the scope of this implementation. 142 | * 143 | * The xkey structure is not modified by this routine, and can be 144 | * used for further encryption and decryption operations. 145 | * 146 | * Arguments: 147 | * xkey pointer to Twofish_key, internal form of the key 148 | * produces by Twofish_prepare_key() 149 | * p Plaintext to be encrypted 150 | * c Place to store the ciphertext 151 | */ 152 | extern void Twofish_encrypt( 153 | Twofish_key * xkey, 154 | Twofish_Byte p[16], 155 | Twofish_Byte c[16] 156 | ); 157 | 158 | 159 | /* 160 | * Decrypt a single block of data. 161 | * 162 | * This function decrypts a single block of 16 bytes of data. 163 | * If you want to decrypt a larger or variable-length message, 164 | * you will have to use a cipher mode, such as CBC or CTR. 165 | * These are outside the scope of this implementation. 166 | * 167 | * The xkey structure is not modified by this routine, and can be 168 | * used for further encryption and decryption operations. 169 | * 170 | * Arguments: 171 | * xkey pointer to Twofish_key, internal form of the key 172 | * produces by Twofish_prepare_key() 173 | * c Ciphertext to be decrypted 174 | * p Place to store the plaintext 175 | */ 176 | extern void Twofish_decrypt( 177 | Twofish_key * xkey, 178 | Twofish_Byte c[16], 179 | Twofish_Byte p[16] 180 | ); 181 | -------------------------------------------------------------------------------- /fingerprint/crypt/base64.cc: -------------------------------------------------------------------------------- 1 | /* 2 | base64.cpp and base64.h 3 | 4 | base64 encoding and decoding with C++. 5 | More information at 6 | https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp 7 | 8 | Version: 2.rc.09 (release candidate) 9 | 10 | Copyright (C) 2004-2017, 2020-2022 René Nyffenegger 11 | 12 | This source code is provided 'as-is', without any express or implied 13 | warranty. In no event will the author be held liable for any damages 14 | arising from the use of this software. 15 | 16 | Permission is granted to anyone to use this software for any purpose, 17 | including commercial applications, and to alter it and redistribute it 18 | freely, subject to the following restrictions: 19 | 20 | 1. The origin of this source code must not be misrepresented; you must not 21 | claim that you wrote the original source code. If you use this source code 22 | in a product, an acknowledgment in the product documentation would be 23 | appreciated but is not required. 24 | 25 | 2. Altered source versions must be plainly marked as such, and must not be 26 | misrepresented as being the original source code. 27 | 28 | 3. This notice may not be removed or altered from any source distribution. 29 | 30 | René Nyffenegger rene.nyffenegger@adp-gmbh.ch 31 | 32 | */ 33 | 34 | #include "base64.h" 35 | 36 | #include 37 | #include 38 | 39 | // 40 | // Depending on the url parameter in base64_chars, one of 41 | // two sets of base64 characters needs to be chosen. 42 | // They differ in their last two characters. 43 | // 44 | static const char* base64_chars[2] = { 45 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 46 | "abcdefghijklmnopqrstuvwxyz" 47 | "0123456789" 48 | "+/", 49 | 50 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 51 | "abcdefghijklmnopqrstuvwxyz" 52 | "0123456789" 53 | "-_"}; 54 | 55 | static unsigned int pos_of_char(const unsigned char chr) { 56 | // 57 | // Return the position of chr within base64_encode() 58 | // 59 | 60 | if (chr >= 'A' && chr <= 'Z') return chr - 'A'; 61 | else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1; 62 | else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2; 63 | else if (chr == '+' || chr == '-') return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters ( 64 | else if (chr == '/' || chr == '_') return 63; // Ditto for '/' and '_' 65 | else 66 | // 67 | // 2020-10-23: Throw std::exception rather than const char* 68 | //(Pablo Martin-Gomez, https://github.com/Bouska) 69 | // 70 | throw std::runtime_error("Input is not valid base64-encoded data."); 71 | } 72 | 73 | static std::string insert_linebreaks(std::string str, size_t distance) { 74 | // 75 | // Provided by https://github.com/JomaCorpFX, adapted by me. 76 | // 77 | if (!str.length()) { 78 | return ""; 79 | } 80 | 81 | size_t pos = distance; 82 | 83 | while (pos < str.size()) { 84 | str.insert(pos, "\n"); 85 | pos += distance + 1; 86 | } 87 | 88 | return str; 89 | } 90 | 91 | template 92 | static std::string encode_with_line_breaks(String s) { 93 | return insert_linebreaks(base64_encode(s, false), line_length); 94 | } 95 | 96 | template 97 | static std::string encode_pem(String s) { 98 | return encode_with_line_breaks(s); 99 | } 100 | 101 | template 102 | static std::string encode_mime(String s) { 103 | return encode_with_line_breaks(s); 104 | } 105 | 106 | template 107 | static std::string encode(String s, bool url) { 108 | return base64_encode(reinterpret_cast(s.data()), s.length(), url); 109 | } 110 | 111 | std::string base64_encode(unsigned char const* bytes_to_encode, size_t in_len, bool url) { 112 | 113 | size_t len_encoded = (in_len +2) / 3 * 4; 114 | 115 | unsigned char trailing_char = url ? '.' : '='; 116 | 117 | // 118 | // Choose set of base64 characters. They differ 119 | // for the last two positions, depending on the url 120 | // parameter. 121 | // A bool (as is the parameter url) is guaranteed 122 | // to evaluate to either 0 or 1 in C++ therefore, 123 | // the correct character set is chosen by subscripting 124 | // base64_chars with url. 125 | // 126 | const char* base64_chars_ = base64_chars[url]; 127 | 128 | std::string ret; 129 | ret.reserve(len_encoded); 130 | 131 | unsigned int pos = 0; 132 | 133 | while (pos < in_len) { 134 | ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]); 135 | 136 | if (pos+1 < in_len) { 137 | ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]); 138 | 139 | if (pos+2 < in_len) { 140 | ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]); 141 | ret.push_back(base64_chars_[ bytes_to_encode[pos + 2] & 0x3f]); 142 | } 143 | else { 144 | ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]); 145 | ret.push_back(trailing_char); 146 | } 147 | } 148 | else { 149 | 150 | ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]); 151 | ret.push_back(trailing_char); 152 | ret.push_back(trailing_char); 153 | } 154 | 155 | pos += 3; 156 | } 157 | 158 | 159 | return ret; 160 | } 161 | 162 | template 163 | static std::string decode(String const& encoded_string, bool remove_linebreaks) { 164 | // 165 | // decode(…) is templated so that it can be used with String = const std::string& 166 | // or std::string_view (requires at least C++17) 167 | // 168 | 169 | if (encoded_string.empty()) return std::string(); 170 | 171 | if (remove_linebreaks) { 172 | 173 | std::string copy(encoded_string); 174 | 175 | copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end()); 176 | 177 | return base64_decode(copy, false); 178 | } 179 | 180 | size_t length_of_string = encoded_string.length(); 181 | size_t pos = 0; 182 | 183 | // 184 | // The approximate length (bytes) of the decoded string might be one or 185 | // two bytes smaller, depending on the amount of trailing equal signs 186 | // in the encoded string. This approximation is needed to reserve 187 | // enough space in the string to be returned. 188 | // 189 | size_t approx_length_of_decoded_string = length_of_string / 4 * 3; 190 | std::string ret; 191 | ret.reserve(approx_length_of_decoded_string); 192 | 193 | while (pos < length_of_string) { 194 | // 195 | // Iterate over encoded input string in chunks. The size of all 196 | // chunks except the last one is 4 bytes. 197 | // 198 | // The last chunk might be padded with equal signs or dots 199 | // in order to make it 4 bytes in size as well, but this 200 | // is not required as per RFC 2045. 201 | // 202 | // All chunks except the last one produce three output bytes. 203 | // 204 | // The last chunk produces at least one and up to three bytes. 205 | // 206 | 207 | size_t pos_of_char_1 = pos_of_char(encoded_string.at(pos+1) ); 208 | 209 | // 210 | // Emit the first output byte that is produced in each chunk: 211 | // 212 | ret.push_back(static_cast( ( (pos_of_char(encoded_string.at(pos+0)) ) << 2 ) + ( (pos_of_char_1 & 0x30 ) >> 4))); 213 | 214 | if ( ( pos + 2 < length_of_string ) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045) 215 | encoded_string.at(pos+2) != '=' && 216 | encoded_string.at(pos+2) != '.' // accept URL-safe base 64 strings, too, so check for '.' also. 217 | ) 218 | { 219 | // 220 | // Emit a chunk's second byte (which might not be produced in the last chunk). 221 | // 222 | unsigned int pos_of_char_2 = pos_of_char(encoded_string.at(pos+2) ); 223 | ret.push_back(static_cast( (( pos_of_char_1 & 0x0f) << 4) + (( pos_of_char_2 & 0x3c) >> 2))); 224 | 225 | if ( ( pos + 3 < length_of_string ) && 226 | encoded_string.at(pos+3) != '=' && 227 | encoded_string.at(pos+3) != '.' 228 | ) 229 | { 230 | // 231 | // Emit a chunk's third byte (which might not be produced in the last chunk). 232 | // 233 | ret.push_back(static_cast( ( (pos_of_char_2 & 0x03 ) << 6 ) + pos_of_char(encoded_string.at(pos+3)) )); 234 | } 235 | } 236 | 237 | pos += 4; 238 | } 239 | 240 | return ret; 241 | } 242 | 243 | std::string base64_decode(std::string const& s, bool remove_linebreaks) { 244 | return decode(s, remove_linebreaks); 245 | } 246 | 247 | std::string base64_encode(std::string const& s, bool url) { 248 | return encode(s, url); 249 | } 250 | 251 | std::string base64_encode_pem (std::string const& s) { 252 | return encode_pem(s); 253 | } 254 | 255 | std::string base64_encode_mime(std::string const& s) { 256 | return encode_mime(s); 257 | } 258 | 259 | #if __cplusplus >= 201703L 260 | // 261 | // Interface with std::string_view rather than const std::string& 262 | // Requires C++17 263 | // Provided by Yannic Bonenberger (https://github.com/Yannic) 264 | // 265 | 266 | std::string base64_encode(std::string_view s, bool url) { 267 | return encode(s, url); 268 | } 269 | 270 | std::string base64_encode_pem(std::string_view s) { 271 | return encode_pem(s); 272 | } 273 | 274 | std::string base64_encode_mime(std::string_view s) { 275 | return encode_mime(s); 276 | } 277 | 278 | std::string base64_decode(std::string_view s, bool remove_linebreaks) { 279 | return decode(s, remove_linebreaks); 280 | } 281 | 282 | #endif // __cplusplus >= 201703L 283 | -------------------------------------------------------------------------------- /fingerprint/crypt/bcrypt.cc: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: bcrypt.c,v 1.31 2014/03/22 23:02:03 tedu Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1997 Niels Provos 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | /* This password hashing algorithm was designed by David Mazieres 20 | * and works as follows: 21 | * 22 | * 1. state := InitState () 23 | * 2. state := ExpandKey (state, salt, password) 24 | * 3. REPEAT rounds: 25 | * state := ExpandKey (state, 0, password) 26 | * state := ExpandKey (state, 0, salt) 27 | * 4. ctext := "OrpheanBeholderScryDoubt" 28 | * 5. REPEAT 64: 29 | * ctext := Encrypt_ECB (state, ctext); 30 | * 6. RETURN Concatenate (salt, ctext); 31 | * 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "fingerprint/crypt/bcrypt.h" 41 | #include "fingerprint/crypt/node_blf.h" 42 | #include "fingerprint/crypt/openbsd.h" 43 | 44 | #ifdef _WIN32 45 | #define snprintf _snprintf 46 | #endif 47 | 48 | //#if !defined(__APPLE__) && !defined(__MACH__) 49 | //#include "bsd/stdlib.h" 50 | //#endif 51 | 52 | /* This implementation is adaptable to current computing power. 53 | * You can have up to 2^31 rounds which should be enough for some 54 | * time to come. 55 | */ 56 | 57 | static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t); 58 | static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *); 59 | 60 | const static char* error = ":"; 61 | 62 | const static u_int8_t Base64Code[] = 63 | "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 64 | 65 | const static u_int8_t index_64[128] = { 66 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 67 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 68 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 69 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 70 | 255, 255, 255, 255, 255, 255, 0, 1, 54, 55, 71 | 56, 57, 58, 59, 60, 61, 62, 63, 255, 255, 72 | 255, 255, 255, 255, 255, 2, 3, 4, 5, 6, 73 | 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 74 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 75 | 255, 255, 255, 255, 255, 255, 28, 29, 30, 76 | 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 77 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 78 | 51, 52, 53, 255, 255, 255, 255, 255 79 | }; 80 | #define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)]) 81 | 82 | static void 83 | decode_base64(u_int8_t *buffer, u_int16_t len, u_int8_t *data) 84 | { 85 | u_int8_t *bp = buffer; 86 | u_int8_t *p = data; 87 | u_int8_t c1, c2, c3, c4; 88 | while (bp < buffer + len) { 89 | c1 = CHAR64(*p); 90 | c2 = CHAR64(*(p + 1)); 91 | 92 | /* Invalid data */ 93 | if (c1 == 255 || c2 == 255) 94 | break; 95 | 96 | *bp++ = (c1 << 2) | ((c2 & 0x30) >> 4); 97 | if (bp >= buffer + len) 98 | break; 99 | 100 | c3 = CHAR64(*(p + 2)); 101 | if (c3 == 255) 102 | break; 103 | 104 | *bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); 105 | if (bp >= buffer + len) 106 | break; 107 | 108 | c4 = CHAR64(*(p + 3)); 109 | if (c4 == 255) 110 | break; 111 | *bp++ = ((c3 & 0x03) << 6) | c4; 112 | 113 | p += 4; 114 | } 115 | } 116 | 117 | void 118 | encode_salt(char *salt, u_int8_t *csalt, char minor, u_int16_t clen, u_int8_t logr) 119 | { 120 | salt[0] = '$'; 121 | salt[1] = BCRYPT_VERSION; 122 | salt[2] = minor; 123 | salt[3] = '$'; 124 | 125 | // Max rounds are 31 126 | snprintf(salt + 4, 4, "%2.2u$", logr & 0x001F); 127 | 128 | encode_base64((u_int8_t *) salt + 7, csalt, clen); 129 | } 130 | 131 | 132 | /* Generates a salt for this version of crypt. 133 | Since versions may change. Keeping this here 134 | seems sensible. 135 | from: http://mail-index.netbsd.org/tech-crypto/2002/05/24/msg000204.html 136 | */ 137 | void 138 | bcrypt_gensalt(char minor, u_int8_t log_rounds, u_int8_t *seed, char *gsalt) 139 | { 140 | if (log_rounds < 4) 141 | log_rounds = 4; 142 | else if (log_rounds > 31) 143 | log_rounds = 31; 144 | 145 | encode_salt(gsalt, seed, minor, BCRYPT_MAXSALT, log_rounds); 146 | } 147 | 148 | /* We handle $Vers$log2(NumRounds)$salt+passwd$ 149 | i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */ 150 | 151 | void 152 | node_bcrypt(const char *key, size_t key_len, const char *salt, char *encrypted) 153 | { 154 | blf_ctx state; 155 | u_int32_t rounds, i, k; 156 | u_int16_t j; 157 | u_int8_t salt_len, logr, minor; 158 | u_int8_t ciphertext[4 * BCRYPT_BLOCKS+1] = "OrpheanBeholderScryDoubt"; 159 | u_int8_t csalt[BCRYPT_MAXSALT]; 160 | u_int32_t cdata[BCRYPT_BLOCKS]; 161 | int n; 162 | 163 | /* Discard "$" identifier */ 164 | salt++; 165 | 166 | if (*salt > BCRYPT_VERSION) { 167 | /* How do I handle errors ? Return ':' */ 168 | strcpy(encrypted, error); 169 | return; 170 | } 171 | 172 | /* Check for minor versions */ 173 | if (salt[1] != '$') { 174 | switch (salt[1]) { 175 | case 'a': /* 'ab' should not yield the same as 'abab' */ 176 | case 'b': /* cap input length at 72 bytes */ 177 | minor = salt[1]; 178 | salt++; 179 | break; 180 | default: 181 | strcpy(encrypted, error); 182 | return; 183 | } 184 | } else 185 | minor = 0; 186 | 187 | /* Discard version + "$" identifier */ 188 | salt += 2; 189 | 190 | if (salt[2] != '$') { 191 | /* Out of sync with passwd entry */ 192 | strcpy(encrypted, error); 193 | return; 194 | } 195 | 196 | /* Computer power doesn't increase linear, 2^x should be fine */ 197 | n = atoi(salt); 198 | if (n > 31 || n < 0) { 199 | strcpy(encrypted, error); 200 | return; 201 | } 202 | logr = (u_int8_t)n; 203 | if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS) { 204 | strcpy(encrypted, error); 205 | return; 206 | } 207 | 208 | /* Discard num rounds + "$" identifier */ 209 | salt += 3; 210 | 211 | if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT) { 212 | strcpy(encrypted, error); 213 | return; 214 | } 215 | 216 | /* We dont want the base64 salt but the raw data */ 217 | decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt); 218 | salt_len = BCRYPT_MAXSALT; 219 | if (minor <= 'a') 220 | key_len = (u_int8_t)(key_len + (minor >= 'a' ? 1 : 0)); 221 | else 222 | { 223 | /* cap key_len at the actual maximum supported 224 | * length here to avoid integer wraparound */ 225 | if (key_len > 72) 226 | key_len = 72; 227 | key_len++; /* include the NUL */ 228 | } 229 | 230 | 231 | /* Setting up S-Boxes and Subkeys */ 232 | Blowfish_initstate(&state); 233 | Blowfish_expandstate(&state, csalt, salt_len, 234 | (u_int8_t *) key, key_len); 235 | for (k = 0; k < rounds; k++) { 236 | Blowfish_expand0state(&state, (u_int8_t *) key, key_len); 237 | Blowfish_expand0state(&state, csalt, salt_len); 238 | } 239 | 240 | /* This can be precomputed later */ 241 | j = 0; 242 | for (i = 0; i < BCRYPT_BLOCKS; i++) 243 | cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j); 244 | 245 | /* Now do the encryption */ 246 | for (k = 0; k < 64; k++) 247 | blf_enc(&state, cdata, BCRYPT_BLOCKS / 2); 248 | 249 | for (i = 0; i < BCRYPT_BLOCKS; i++) { 250 | ciphertext[4 * i + 3] = cdata[i] & 0xff; 251 | cdata[i] = cdata[i] >> 8; 252 | ciphertext[4 * i + 2] = cdata[i] & 0xff; 253 | cdata[i] = cdata[i] >> 8; 254 | ciphertext[4 * i + 1] = cdata[i] & 0xff; 255 | cdata[i] = cdata[i] >> 8; 256 | ciphertext[4 * i + 0] = cdata[i] & 0xff; 257 | } 258 | 259 | i = 0; 260 | encrypted[i++] = '$'; 261 | encrypted[i++] = BCRYPT_VERSION; 262 | if (minor) 263 | encrypted[i++] = minor; 264 | encrypted[i++] = '$'; 265 | 266 | snprintf(encrypted + i, 4, "%2.2u$", logr & 0x001F); 267 | 268 | encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT); 269 | encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext, 270 | 4 * BCRYPT_BLOCKS - 1); 271 | memset(&state, 0, sizeof(state)); 272 | memset(ciphertext, 0, sizeof(ciphertext)); 273 | memset(csalt, 0, sizeof(csalt)); 274 | memset(cdata, 0, sizeof(cdata)); 275 | } 276 | 277 | u_int32_t bcrypt_get_rounds(const char * hash) 278 | { 279 | /* skip past the leading "$" */ 280 | if (!hash || *(hash++) != '$') return 0; 281 | 282 | /* skip past version */ 283 | if (0 == (*hash++)) return 0; 284 | if (*hash && *hash != '$') hash++; 285 | if (*hash++ != '$') return 0; 286 | 287 | return atoi(hash); 288 | } 289 | 290 | static void 291 | encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len) 292 | { 293 | u_int8_t *bp = buffer; 294 | u_int8_t *p = data; 295 | u_int8_t c1, c2; 296 | while (p < data + len) { 297 | c1 = *p++; 298 | *bp++ = Base64Code[(c1 >> 2)]; 299 | c1 = (c1 & 0x03) << 4; 300 | if (p >= data + len) { 301 | *bp++ = Base64Code[c1]; 302 | break; 303 | } 304 | c2 = *p++; 305 | c1 |= (c2 >> 4) & 0x0f; 306 | *bp++ = Base64Code[c1]; 307 | c1 = (c2 & 0x0f) << 2; 308 | if (p >= data + len) { 309 | *bp++ = Base64Code[c1]; 310 | break; 311 | } 312 | c2 = *p++; 313 | c1 |= (c2 >> 6) & 0x03; 314 | *bp++ = Base64Code[c1]; 315 | *bp++ = Base64Code[c2 & 0x3f]; 316 | } 317 | *bp = '\0'; 318 | } 319 | 320 | namespace fingerprint { 321 | 322 | std::string BcryptNewHash(std::string_view password, unsigned rounds) { 323 | unsigned char seed[17]{}; 324 | arc4random_init(); 325 | arc4random_buf(seed, 16); 326 | 327 | char salt[_SALT_LEN]; 328 | bcrypt_gensalt('b', rounds, seed, salt); 329 | 330 | std::string hash(61, '\0'); 331 | node_bcrypt(password.data(), password.size(), salt, &hash[0]); 332 | hash.resize(60); 333 | return hash; 334 | } 335 | 336 | bool BcryptCheckPass(std::string_view password, std::string_view hash) { 337 | std::string got(61, '\0'); 338 | node_bcrypt(password.data(), password.size(), hash.data(), &got[0]); 339 | got.resize(60); 340 | return hash == got; 341 | } 342 | 343 | } // namespace fingerprint 344 | -------------------------------------------------------------------------------- /fingerprint/crypt/blowfish.cc: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */ 2 | /* 3 | * Blowfish block cipher for OpenBSD 4 | * Copyright 1997 Niels Provos 5 | * All rights reserved. 6 | * 7 | * Implementation advice by David Mazieres . 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. All advertising materials mentioning features or use of this software 18 | * must display the following acknowledgement: 19 | * This product includes software developed by Niels Provos. 20 | * 4. The name of the author may not be used to endorse or promote products 21 | * derived from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | /* 36 | * This code is derived from section 14.3 and the given source 37 | * in section V of Applied Cryptography, second edition. 38 | * Blowfish is an unpatented fast block cipher designed by 39 | * Bruce Schneier. 40 | */ 41 | 42 | #include "fingerprint/crypt/node_blf.h" 43 | 44 | #undef inline 45 | #ifdef __GNUC__ 46 | #define inline __inline 47 | #else /* !__GNUC__ */ 48 | #define inline 49 | #endif /* !__GNUC__ */ 50 | 51 | /* Function for Feistel Networks */ 52 | 53 | #define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \ 54 | + (s)[0x100 + (((x)>>16)&0xFF)]) \ 55 | ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \ 56 | + (s)[0x300 + ( (x) &0xFF)]) 57 | 58 | #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) 59 | 60 | void 61 | Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) 62 | { 63 | u_int32_t Xl; 64 | u_int32_t Xr; 65 | u_int32_t *s = c->S[0]; 66 | u_int32_t *p = c->P; 67 | 68 | Xl = *xl; 69 | Xr = *xr; 70 | 71 | Xl ^= p[0]; 72 | BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); 73 | BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); 74 | BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); 75 | BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); 76 | BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); 77 | BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); 78 | BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); 79 | BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); 80 | 81 | *xl = Xr ^ p[17]; 82 | *xr = Xl; 83 | } 84 | 85 | void 86 | Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) 87 | { 88 | u_int32_t Xl; 89 | u_int32_t Xr; 90 | u_int32_t *s = c->S[0]; 91 | u_int32_t *p = c->P; 92 | 93 | Xl = *xl; 94 | Xr = *xr; 95 | 96 | Xl ^= p[17]; 97 | BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); 98 | BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); 99 | BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); 100 | BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); 101 | BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); 102 | BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); 103 | BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); 104 | BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); 105 | 106 | *xl = Xr ^ p[0]; 107 | *xr = Xl; 108 | } 109 | 110 | void 111 | Blowfish_initstate(blf_ctx *c) 112 | { 113 | /* P-box and S-box tables initialized with digits of Pi */ 114 | 115 | static const blf_ctx initstate = 116 | { { 117 | { 118 | 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 119 | 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 120 | 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 121 | 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 122 | 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 123 | 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 124 | 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 125 | 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 126 | 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 127 | 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 128 | 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 129 | 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 130 | 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 131 | 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 132 | 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 133 | 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 134 | 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 135 | 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 136 | 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 137 | 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 138 | 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 139 | 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 140 | 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 141 | 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 142 | 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 143 | 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 144 | 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 145 | 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 146 | 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 147 | 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 148 | 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 149 | 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 150 | 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 151 | 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 152 | 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 153 | 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 154 | 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 155 | 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 156 | 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 157 | 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 158 | 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 159 | 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 160 | 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 161 | 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 162 | 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 163 | 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 164 | 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 165 | 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 166 | 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 167 | 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 168 | 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 169 | 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 170 | 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 171 | 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 172 | 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 173 | 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 174 | 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 175 | 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 176 | 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 177 | 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 178 | 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 179 | 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 180 | 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 181 | 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, 182 | { 183 | 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 184 | 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 185 | 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 186 | 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 187 | 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 188 | 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 189 | 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 190 | 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 191 | 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 192 | 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 193 | 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 194 | 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 195 | 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 196 | 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 197 | 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 198 | 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 199 | 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 200 | 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 201 | 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 202 | 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 203 | 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 204 | 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 205 | 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 206 | 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 207 | 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 208 | 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 209 | 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 210 | 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 211 | 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 212 | 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 213 | 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 214 | 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 215 | 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 216 | 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 217 | 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 218 | 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 219 | 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 220 | 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 221 | 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 222 | 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 223 | 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 224 | 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 225 | 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 226 | 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 227 | 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 228 | 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 229 | 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 230 | 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 231 | 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 232 | 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 233 | 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 234 | 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 235 | 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 236 | 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 237 | 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 238 | 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 239 | 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 240 | 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 241 | 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 242 | 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 243 | 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 244 | 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 245 | 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 246 | 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, 247 | { 248 | 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 249 | 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 250 | 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 251 | 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 252 | 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 253 | 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 254 | 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 255 | 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 256 | 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 257 | 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 258 | 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 259 | 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 260 | 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 261 | 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 262 | 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 263 | 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 264 | 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 265 | 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 266 | 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 267 | 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 268 | 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 269 | 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 270 | 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 271 | 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 272 | 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 273 | 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 274 | 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 275 | 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 276 | 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 277 | 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 278 | 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 279 | 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 280 | 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 281 | 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 282 | 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 283 | 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 284 | 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 285 | 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 286 | 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 287 | 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 288 | 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 289 | 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 290 | 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 291 | 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 292 | 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 293 | 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 294 | 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 295 | 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 296 | 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 297 | 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 298 | 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 299 | 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 300 | 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 301 | 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 302 | 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 303 | 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 304 | 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 305 | 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 306 | 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 307 | 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 308 | 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 309 | 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 310 | 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 311 | 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, 312 | { 313 | 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 314 | 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 315 | 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 316 | 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 317 | 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 318 | 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 319 | 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 320 | 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 321 | 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 322 | 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 323 | 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 324 | 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 325 | 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 326 | 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 327 | 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 328 | 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 329 | 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 330 | 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 331 | 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 332 | 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 333 | 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 334 | 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 335 | 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 336 | 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 337 | 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 338 | 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 339 | 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 340 | 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 341 | 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 342 | 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 343 | 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 344 | 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 345 | 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 346 | 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 347 | 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 348 | 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, 349 | 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 350 | 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 351 | 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 352 | 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 353 | 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 354 | 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 355 | 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 356 | 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 357 | 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 358 | 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 359 | 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 360 | 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 361 | 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 362 | 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 363 | 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 364 | 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 365 | 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 366 | 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 367 | 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 368 | 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 369 | 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 370 | 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 371 | 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 372 | 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 373 | 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 374 | 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 375 | 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 376 | 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} 377 | }, 378 | { 379 | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 380 | 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 381 | 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 382 | 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 383 | 0x9216d5d9, 0x8979fb1b 384 | } }; 385 | 386 | *c = initstate; 387 | } 388 | 389 | u_int32_t 390 | Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, 391 | u_int16_t *current) 392 | { 393 | u_int8_t i; 394 | u_int16_t j; 395 | u_int32_t temp; 396 | 397 | temp = 0x00000000; 398 | j = *current; 399 | 400 | for (i = 0; i < 4; i++, j++) { 401 | if (j >= databytes) 402 | j = 0; 403 | temp = (temp << 8) | data[j]; 404 | } 405 | 406 | *current = j; 407 | return temp; 408 | } 409 | 410 | void 411 | Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes) 412 | { 413 | u_int16_t i; 414 | u_int16_t j; 415 | u_int16_t k; 416 | u_int32_t temp; 417 | u_int32_t datal; 418 | u_int32_t datar; 419 | 420 | j = 0; 421 | for (i = 0; i < BLF_N + 2; i++) { 422 | /* Extract 4 int8 to 1 int32 from keystream */ 423 | temp = Blowfish_stream2word(key, keybytes, &j); 424 | c->P[i] = c->P[i] ^ temp; 425 | } 426 | 427 | j = 0; 428 | datal = 0x00000000; 429 | datar = 0x00000000; 430 | for (i = 0; i < BLF_N + 2; i += 2) { 431 | Blowfish_encipher(c, &datal, &datar); 432 | 433 | c->P[i] = datal; 434 | c->P[i + 1] = datar; 435 | } 436 | 437 | for (i = 0; i < 4; i++) { 438 | for (k = 0; k < 256; k += 2) { 439 | Blowfish_encipher(c, &datal, &datar); 440 | 441 | c->S[i][k] = datal; 442 | c->S[i][k + 1] = datar; 443 | } 444 | } 445 | } 446 | 447 | 448 | void 449 | Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes, 450 | const u_int8_t *key, u_int16_t keybytes) 451 | { 452 | u_int16_t i; 453 | u_int16_t j; 454 | u_int16_t k; 455 | u_int32_t temp; 456 | u_int32_t datal; 457 | u_int32_t datar; 458 | 459 | j = 0; 460 | for (i = 0; i < BLF_N + 2; i++) { 461 | /* Extract 4 int8 to 1 int32 from keystream */ 462 | temp = Blowfish_stream2word(key, keybytes, &j); 463 | c->P[i] = c->P[i] ^ temp; 464 | } 465 | 466 | j = 0; 467 | datal = 0x00000000; 468 | datar = 0x00000000; 469 | for (i = 0; i < BLF_N + 2; i += 2) { 470 | datal ^= Blowfish_stream2word(data, databytes, &j); 471 | datar ^= Blowfish_stream2word(data, databytes, &j); 472 | Blowfish_encipher(c, &datal, &datar); 473 | 474 | c->P[i] = datal; 475 | c->P[i + 1] = datar; 476 | } 477 | 478 | for (i = 0; i < 4; i++) { 479 | for (k = 0; k < 256; k += 2) { 480 | datal ^= Blowfish_stream2word(data, databytes, &j); 481 | datar ^= Blowfish_stream2word(data, databytes, &j); 482 | Blowfish_encipher(c, &datal, &datar); 483 | 484 | c->S[i][k] = datal; 485 | c->S[i][k + 1] = datar; 486 | } 487 | } 488 | 489 | } 490 | 491 | void 492 | blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len) 493 | { 494 | /* Initialize S-boxes and subkeys with Pi */ 495 | Blowfish_initstate(c); 496 | 497 | /* Transform S-boxes and subkeys with key */ 498 | Blowfish_expand0state(c, k, len); 499 | } 500 | 501 | void 502 | blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks) 503 | { 504 | u_int32_t *d; 505 | u_int16_t i; 506 | 507 | d = data; 508 | for (i = 0; i < blocks; i++) { 509 | Blowfish_encipher(c, d, d + 1); 510 | d += 2; 511 | } 512 | } 513 | 514 | void 515 | blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks) 516 | { 517 | u_int32_t *d; 518 | u_int16_t i; 519 | 520 | d = data; 521 | for (i = 0; i < blocks; i++) { 522 | Blowfish_decipher(c, d, d + 1); 523 | d += 2; 524 | } 525 | } 526 | 527 | void 528 | blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) 529 | { 530 | u_int32_t l, r; 531 | u_int32_t i; 532 | 533 | for (i = 0; i < len; i += 8) { 534 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 535 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; 536 | Blowfish_encipher(c, &l, &r); 537 | data[0] = l >> 24 & 0xff; 538 | data[1] = l >> 16 & 0xff; 539 | data[2] = l >> 8 & 0xff; 540 | data[3] = l & 0xff; 541 | data[4] = r >> 24 & 0xff; 542 | data[5] = r >> 16 & 0xff; 543 | data[6] = r >> 8 & 0xff; 544 | data[7] = r & 0xff; 545 | data += 8; 546 | } 547 | } 548 | 549 | void 550 | blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) 551 | { 552 | u_int32_t l, r; 553 | u_int32_t i; 554 | 555 | for (i = 0; i < len; i += 8) { 556 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 557 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; 558 | Blowfish_decipher(c, &l, &r); 559 | data[0] = l >> 24 & 0xff; 560 | data[1] = l >> 16 & 0xff; 561 | data[2] = l >> 8 & 0xff; 562 | data[3] = l & 0xff; 563 | data[4] = r >> 24 & 0xff; 564 | data[5] = r >> 16 & 0xff; 565 | data[6] = r >> 8 & 0xff; 566 | data[7] = r & 0xff; 567 | data += 8; 568 | } 569 | } 570 | 571 | void 572 | blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len) 573 | { 574 | u_int32_t l, r; 575 | u_int32_t i, j; 576 | 577 | for (i = 0; i < len; i += 8) { 578 | for (j = 0; j < 8; j++) 579 | data[j] ^= iv[j]; 580 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 581 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; 582 | Blowfish_encipher(c, &l, &r); 583 | data[0] = l >> 24 & 0xff; 584 | data[1] = l >> 16 & 0xff; 585 | data[2] = l >> 8 & 0xff; 586 | data[3] = l & 0xff; 587 | data[4] = r >> 24 & 0xff; 588 | data[5] = r >> 16 & 0xff; 589 | data[6] = r >> 8 & 0xff; 590 | data[7] = r & 0xff; 591 | iv = data; 592 | data += 8; 593 | } 594 | } 595 | 596 | void 597 | blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len) 598 | { 599 | u_int32_t l, r; 600 | u_int8_t *iv; 601 | u_int32_t i, j; 602 | 603 | iv = data + len - 16; 604 | data = data + len - 8; 605 | for (i = len - 8; i >= 8; i -= 8) { 606 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 607 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; 608 | Blowfish_decipher(c, &l, &r); 609 | data[0] = l >> 24 & 0xff; 610 | data[1] = l >> 16 & 0xff; 611 | data[2] = l >> 8 & 0xff; 612 | data[3] = l & 0xff; 613 | data[4] = r >> 24 & 0xff; 614 | data[5] = r >> 16 & 0xff; 615 | data[6] = r >> 8 & 0xff; 616 | data[7] = r & 0xff; 617 | for (j = 0; j < 8; j++) 618 | data[j] ^= iv[j]; 619 | iv -= 8; 620 | data -= 8; 621 | } 622 | l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; 623 | r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; 624 | Blowfish_decipher(c, &l, &r); 625 | data[0] = l >> 24 & 0xff; 626 | data[1] = l >> 16 & 0xff; 627 | data[2] = l >> 8 & 0xff; 628 | data[3] = l & 0xff; 629 | data[4] = r >> 24 & 0xff; 630 | data[5] = r >> 16 & 0xff; 631 | data[6] = r >> 8 & 0xff; 632 | data[7] = r & 0xff; 633 | for (j = 0; j < 8; j++) 634 | data[j] ^= iva[j]; 635 | } 636 | 637 | #if 0 638 | void 639 | report(u_int32_t data[], u_int16_t len) 640 | { 641 | u_int16_t i; 642 | for (i = 0; i < len; i += 2) 643 | printf("Block %0hd: %08lx %08lx.\n", 644 | i / 2, data[i], data[i + 1]); 645 | } 646 | void 647 | main(void) 648 | { 649 | 650 | blf_ctx c; 651 | char key[] = "AAAAA"; 652 | char key2[] = "abcdefghijklmnopqrstuvwxyz"; 653 | 654 | u_int32_t data[10]; 655 | u_int32_t data2[] = 656 | {0x424c4f57l, 0x46495348l}; 657 | 658 | u_int16_t i; 659 | 660 | /* First test */ 661 | for (i = 0; i < 10; i++) 662 | data[i] = i; 663 | 664 | blf_key(&c, (u_int8_t *) key, 5); 665 | blf_enc(&c, data, 5); 666 | blf_dec(&c, data, 1); 667 | blf_dec(&c, data + 2, 4); 668 | printf("Should read as 0 - 9.\n"); 669 | report(data, 10); 670 | 671 | /* Second test */ 672 | blf_key(&c, (u_int8_t *) key2, strlen(key2)); 673 | blf_enc(&c, data2, 1); 674 | printf("\nShould read as: 0x324ed0fe 0xf413a203.\n"); 675 | report(data2, 2); 676 | blf_dec(&c, data2, 1); 677 | report(data2, 2); 678 | } 679 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /fingerprint/crypt/twofish.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Fast, portable, and easy-to-use Twofish implementation, 3 | * Version 0.3. 4 | * Copyright (c) 2002 by Niels Ferguson. 5 | * (See further down for the almost-unrestricted licensing terms.) 6 | * 7 | * -------------------------------------------------------------------------- 8 | * There are two files for this implementation: 9 | * - twofish.h, the header file. 10 | * - twofish.c, the code file. 11 | * 12 | * To incorporate this code into your program you should: 13 | * - Check the licensing terms further down in this comment. 14 | * - Fix the two type definitions in twofish.h to suit your platform. 15 | * - Fix a few definitions in twofish.c in the section marked 16 | * PLATFORM FIXES. There is one important ones that affects 17 | * functionality, and then a few definitions that you can optimise 18 | * for efficiency but those have no effect on the functionality. 19 | * Don't change anything else. 20 | * - Put the code in your project and compile it. 21 | * 22 | * To use this library you should: 23 | * - Call Twofish_initialise() in your program before any other function in 24 | * this library. 25 | * - Use Twofish_prepare_key(...) to convert a key to internal form. 26 | * - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt 27 | * data. 28 | * See the comments in the header file for details on these functions. 29 | * -------------------------------------------------------------------------- 30 | * 31 | * There are many Twofish implementation available for free on the web. 32 | * Most of them are hard to integrate into your own program. 33 | * As we like people to use our cipher, I thought I would make it easier. 34 | * Here is a free and easy-to-integrate Twofish implementation in C. 35 | * The latest version is always available from my personal home page at 36 | * http://niels.ferguson.net/ 37 | * 38 | * Integrating library code into a project is difficult because the library 39 | * header files interfere with the project's header files and code. 40 | * And of course the project's header files interfere with the library code. 41 | * I've tried to resolve these problems here. 42 | * The header file of this implementation is very light-weight. 43 | * It contains two typedefs, a structure, and a few function declarations. 44 | * All names it defines start with "Twofish_". 45 | * The header file is therefore unlikely to cause problems in your project. 46 | * The code file of this implementation doesn't need to include the header 47 | * files of the project. There is thus no danger of the project interfering 48 | * with all the definitions and macros of the Twofish code. 49 | * In most situations, all you need to do is fill in a few platform-specific 50 | * definitions in the header file and code file, 51 | * and you should be able to run the Twofish code in your project. 52 | * I estimate it should take you less than an hour to integrate this code 53 | * into your project, most of it spent reading the comments telling you what 54 | * to do. 55 | * 56 | * For people using C++: it is very easy to wrap this library into a 57 | * TwofishKey class. One of the big advantages is that you can automate the 58 | * wiping of the key material in the destructor. I have not provided a C++ 59 | * class because the interface depends too much on the abstract base class 60 | * you use for block ciphers in your program, which I don't know about. 61 | * 62 | * This implementation is designed for use on PC-class machines. It uses the 63 | * Twofish 'full' keying option which uses large tables. Total table size is 64 | * around 5-6 kB for static tables plus 4.5 kB for each pre-processed key. 65 | * If you need an implementation that uses less memory, 66 | * take a look at Brian Gladman's code on his web site: 67 | * http://fp.gladman.plus.com/cryptography_technology/aes/ 68 | * He has code for all AES candidates. 69 | * His Twofish code has lots of options trading off table size vs. speed. 70 | * You can also take a look at the optimised code by Doug Whiting on the 71 | * Twofish web site 72 | * http://www.counterpane.com/twofish.html 73 | * which has loads of options. 74 | * I believe these existing implementations are harder to re-use because they 75 | * are not clean libraries and they impose requirements on the environment. 76 | * This implementation is very careful to minimise those, 77 | * and should be easier to integrate into any larger program. 78 | * 79 | * The default mode of this implementation is fully portable as it uses no 80 | * behaviour not defined in the C standard. (This is harder than you think.) 81 | * If you have any problems porting the default mode, please let me know 82 | * so that I can fix the problem. (But only if this code is at fault, I 83 | * don't fix compilers.) 84 | * Most of the platform fixes are related to non-portable but faster ways 85 | * of implementing certain functions. 86 | * 87 | * In general I've tried to make the code as fast as possible, at the expense 88 | * of memory and code size. However, C does impose limits, and this 89 | * implementation will be slower than an optimised assembler implementation. 90 | * But beware of assembler implementations: a good Pentium implementation 91 | * uses completely different code than a good Pentium II implementation. 92 | * You basically have to re-write the assembly code for every generation of 93 | * processor. Unless you are severely pressed for speed, stick with C. 94 | * 95 | * The initialisation routine of this implementation contains a self-test. 96 | * If initialisation succeeds without calling the fatal routine, then 97 | * the implementation works. I don't think you can break the implementation 98 | * in such a way that it still passes the tests, unless you are malicious. 99 | * In other words: if the initialisation routine returns, 100 | * you have successfully ported the implementation. 101 | * (Or not implemented the fatal routine properly, but that is your problem.) 102 | * 103 | * I'm indebted to many people who helped me in one way or another to write 104 | * this code. During the design of Twofish and the AES process I had very 105 | * extensive discussions of all implementation issues with various people. 106 | * Doug Whiting in particular provided a wealth of information. The Twofish 107 | * team spent untold hours discussion various cipher features, and their 108 | * implementation. Brian Gladman implemented all AES candidates in C, 109 | * and we had some fruitful discussions on how to implement Twofish in C. 110 | * Jan Nieuwenhuizen tested this code on Linux using GCC. 111 | * 112 | * Now for the license: 113 | * The author hereby grants a perpetual license to everybody to 114 | * use this code for any purpose as long as the copyright message is included 115 | * in the source code of this or any derived work. 116 | * 117 | * Yes, this means that you, your company, your club, and anyone else 118 | * can use this code anywhere you want. You can change it and distribute it 119 | * under the GPL, include it in your commercial product without releasing 120 | * the source code, put it on the web, etc. 121 | * The only thing you cannot do is remove my copyright message, 122 | * or distribute any source code based on this implementation that does not 123 | * include my copyright message. 124 | * 125 | * I appreciate a mention in the documentation or credits, 126 | * but I understand if that is difficult to do. 127 | * I also appreciate it if you tell me where and why you used my code. 128 | * 129 | * Please send any questions or comments to niels@ferguson.net 130 | * 131 | * Have Fun! 132 | * 133 | * Niels 134 | */ 135 | 136 | /* 137 | * DISCLAIMER: As I'm giving away my work for free, I'm of course not going 138 | * to accept any liability of any form. This code, or the Twofish cipher, 139 | * might very well be flawed; you have been warned. 140 | * This software is provided as-is, without any kind of warrenty or 141 | * guarantee. And that is really all you can expect when you download 142 | * code for free from the Internet. 143 | * 144 | * I think it is really sad that disclaimers like this seem to be necessary. 145 | * If people only had a little bit more common sense, and didn't come 146 | * whining like little children every time something happens.... 147 | */ 148 | 149 | /* 150 | * Version history: 151 | * Version 0.0, 2002-08-30 152 | * First written. 153 | * Version 0.1, 2002-09-03 154 | * Added disclaimer. Improved self-tests. 155 | * Version 0.2, 2002-09-09 156 | * Removed last non-portabilities. Default now works completely within 157 | * the C standard. UInt32 can be larger than 32 bits without problems. 158 | * Version 0.3, 2002-09-28 159 | * Bugfix: use instead of to adhere to ANSI/ISO. 160 | * Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library 161 | * header already defines BIG_ENDIAN, even though it is not 162 | * supposed to. 163 | */ 164 | 165 | 166 | /* 167 | * Minimum set of include files. 168 | * You should not need any application-specific include files for this code. 169 | * In fact, adding you own header files could break one of the many macros or 170 | * functions in this file. Be very careful. 171 | * Standard include files will probably be ok. 172 | */ 173 | #include /* for memset(), memcpy(), and memcmp() */ 174 | 175 | #include "fingerprint/crypt/twofish.h" 176 | 177 | 178 | /* 179 | * PLATFORM FIXES 180 | * ============== 181 | * 182 | * Fix the type definitions in twofish.h first! 183 | * 184 | * The following definitions have to be fixed for each particular platform 185 | * you work on. If you have a multi-platform program, you no doubt have 186 | * portable definitions that you can substitute here without changing the 187 | * rest of the code. 188 | */ 189 | 190 | 191 | /* 192 | * Function called if something is fatally wrong with the implementation. 193 | * This fatal function is called when a coding error is detected in the 194 | * Twofish implementation, or when somebody passes an obviously erroneous 195 | * parameter to this implementation. There is not much you can do when 196 | * the code contains bugs, so we just stop. 197 | * 198 | * The argument is a string. Ideally the fatal function prints this string 199 | * as an error message. Whatever else this function does, it should never 200 | * return. A typical implementation would stop the program completely after 201 | * printing the error message. 202 | * 203 | * This default implementation is not very useful, 204 | * but does not assume anything about your environment. 205 | * It will at least let you know something is wrong.... 206 | * I didn't want to include any libraries to print and error or so, 207 | * as this makes the code much harder to integrate in a project. 208 | * 209 | * Note that the Twofish_fatal function may not return to the caller. 210 | * Unfortunately this is not something the self-test can test for, 211 | * so you have to make sure of this yourself. 212 | * 213 | * If you want to call an external function, be careful about including 214 | * your own header files here. This code uses a lot of macros, and your 215 | * header file could easily break it. Maybe the best solution is to use 216 | * a separate extern statement for your fatal function. 217 | */ 218 | #define Twofish_fatal( msg ) {for(;;);} 219 | 220 | 221 | /* 222 | * The rest of the settings are not important for the functionality 223 | * of this Twofish implementation. That is, their default settings 224 | * work on all platforms. You can change them to improve the 225 | * speed of the implementation on your platform. Erroneous settings 226 | * will result in erroneous implementations, but the self-test should 227 | * catch those. 228 | */ 229 | 230 | 231 | /* 232 | * Macros to rotate a Twofish_UInt32 value left or right by the 233 | * specified number of bits. This should be a 32-bit rotation, 234 | * and not rotation of, say, 64-bit values. 235 | * 236 | * Every encryption or decryption operation uses 32 of these rotations, 237 | * so it is a good idea to make these macros efficient. 238 | * 239 | * This fully portable definition has one piece of tricky stuff. 240 | * The UInt32 might be larger than 32 bits, so we have to mask 241 | * any higher bits off. The simplest way to do this is to 'and' the 242 | * value first with 0xffffffff and then shift it right. An optimising 243 | * compiler that has a 32-bit type can optimise this 'and' away. 244 | * 245 | * Unfortunately there is no portable way of writing the constant 246 | * 0xffffffff. You don't know which suffix to use (U, or UL?) 247 | * The UINT32_MASK definition uses a bit of trickery. Shift-left 248 | * is only defined if the shift amount is strictly less than the size 249 | * of the UInt32, so we can't use (1<<32). The answer it to take the value 250 | * 2, cast it to a UInt32, shift it left 31 positions, and subtract one. 251 | * Another example of how to make something very simple extremely difficult. 252 | * I hate C. 253 | * 254 | * The rotation macros are straightforward. 255 | * They are only applied to UInt32 values, which are _unsigned_ 256 | * so the >> operator must do a logical shift that brings in zeroes. 257 | * On most platforms you will only need to optimise the ROL32 macro; the 258 | * ROR32 macro is not inefficient on an optimising compiler as all rotation 259 | * amounts in this code are known at compile time. 260 | * 261 | * On many platforms there is a faster solution. 262 | * For example, MS compilers have the __rotl and __rotr functions 263 | * that generate x86 rotation instructions. 264 | */ 265 | #define UINT32_MASK ( (((UInt32)2)<<31) - 1 ) 266 | #define ROL32( x, n ) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) ) 267 | #define ROR32( x, n ) ROL32( (x), 32-(n) ) 268 | 269 | 270 | /* 271 | * Select data type for q-table entries. 272 | * 273 | * Larger entry types cost more memory (1.5 kB), and might be faster 274 | * or slower depending on the CPU and compiler details. 275 | * 276 | * This choice only affects the static data size and the key setup speed. 277 | * Functionality, expanded key size, or encryption speed are not affected. 278 | * Define to 1 to get large q-table entries. 279 | */ 280 | #define LARGE_Q_TABLE 0 /* default = 0 */ 281 | 282 | 283 | /* 284 | * Method to select a single byte from a UInt32. 285 | * WARNING: non-portable code if set; might not work on all platforms. 286 | * 287 | * Inside the inner loop of Twofish it is necessary to access the 4 288 | * individual bytes of a UInt32. This can be done using either shifts 289 | * and masks, or memory accesses. 290 | * 291 | * Set to 0 to use shift and mask operations for the byte selection. 292 | * This is more ALU intensive. It is also fully portable. 293 | * 294 | * Set to 1 to use memory accesses. The UInt32 is stored in memory and 295 | * the individual bytes are read from memory one at a time. 296 | * This solution is more memory-intensive, and not fully portable. 297 | * It might be faster on your platform, or not. If you use this option, 298 | * make sure you set the CPU_IS_BIG_ENDIAN flag appropriately. 299 | * 300 | * This macro does not affect the conversion of the inputs and outputs 301 | * of the cipher. See the CONVERT_USING_CASTS macro for that. 302 | */ 303 | #define SELECT_BYTE_FROM_UINT32_IN_MEMORY 0 /* default = 0 */ 304 | 305 | 306 | /* 307 | * Method used to read the input and write the output. 308 | * WARNING: non-portable code if set; might not work on all platforms. 309 | * 310 | * Twofish operates on 32-bit words. The input to the cipher is 311 | * a byte array, as is the output. The portable method of doing the 312 | * conversion is a bunch of rotate and mask operations, but on many 313 | * platforms it can be done faster using a cast. 314 | * This only works if your CPU allows UInt32 accesses to arbitrary Byte 315 | * addresses. 316 | * 317 | * Set to 0 to use the shift and mask operations. This is fully 318 | * portable. . 319 | * 320 | * Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a 321 | * UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN 322 | * macro) the byte order in the UInt32 is swapped. The reverse is done 323 | * to write the output of the encryption/decryption. Make sure you set 324 | * the CPU_IS_BIG_ENDIAN flag appropriately. 325 | * This option does not work unless a UInt32 is exactly 32 bits. 326 | * 327 | * This macro only changes the reading/writing of the plaintext/ciphertext. 328 | * See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which 329 | * a UInt32 is split into 4 bytes for the S-box selection. 330 | */ 331 | #define CONVERT_USING_CASTS 0 /* default = 0 */ 332 | 333 | 334 | /* 335 | * Endianness switch. 336 | * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or 337 | * CONVERT_USING_CASTS is set. 338 | * 339 | * Set to 1 on a big-endian machine, and to 0 on a little-endian machine. 340 | * Twofish uses the little-endian convention (least significant byte first) 341 | * and big-endian machines (using most significant byte first) 342 | * have to do a few conversions. 343 | * 344 | * CAUTION: This code has never been tested on a big-endian machine, 345 | * because I don't have access to one. Feedback appreciated. 346 | */ 347 | #define CPU_IS_BIG_ENDIAN 0 348 | 349 | 350 | /* 351 | * Macro to reverse the order of the bytes in a UInt32. 352 | * Used to convert to little-endian on big-endian machines. 353 | * This macro is always tested, but only used in the encryption and 354 | * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN 355 | * are both set. In other words: this macro is only speed-critical if 356 | * both these flags have been set. 357 | * 358 | * This default definition of SWAP works, but on many platforms there is a 359 | * more efficient implementation. 360 | */ 361 | #define BSWAP(x) ((ROL32((x),8) & 0x00ff00ff) | (ROR32((x),8) & 0xff00ff00)) 362 | 363 | 364 | /* 365 | * END OF PLATFORM FIXES 366 | * ===================== 367 | * 368 | * You should not have to touch the rest of this file. 369 | */ 370 | 371 | 372 | /* 373 | * Convert the external type names to some that are easier to use inside 374 | * this file. I didn't want to use the names Byte and UInt32 in the 375 | * header file, because many programs already define them and using two 376 | * conventions at once can be very difficult. 377 | * Don't change these definitions! Change the originals 378 | * in twofish.h instead. 379 | */ 380 | /* A Byte must be an unsigned integer, 8 bits long. */ 381 | typedef Twofish_Byte Byte; 382 | /* A UInt32 must be an unsigned integer at least 32 bits long. */ 383 | typedef Twofish_UInt32 UInt32; 384 | 385 | 386 | /* 387 | * Define a macro ENDIAN_CONVERT. 388 | * 389 | * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian 390 | * machines, and is the identity function on little-endian machines. 391 | * The code then uses this macro without considering the endianness. 392 | */ 393 | #if CPU_IS_BIG_ENDIAN 394 | #define ENDIAN_CONVERT(x) BSWAP(x) 395 | #else 396 | #define ENDIAN_CONVERT(x) (x) 397 | #endif 398 | 399 | 400 | /* 401 | * Compute byte offset within a UInt32 stored in memory. 402 | * 403 | * This is only used when SELECT_BYTE_FROM_UINT32_IN_MEMORY is set. 404 | * 405 | * The input is the byte number 0..3, 0 for least significant. 406 | * Note the use of sizeof() to support UInt32 types that are larger 407 | * than 4 bytes. 408 | */ 409 | #if CPU_IS_BIG_ENDIAN 410 | #define BYTE_OFFSET( n ) (sizeof(UInt32) - 1 - (n) ) 411 | #else 412 | #define BYTE_OFFSET( n ) (n) 413 | #endif 414 | 415 | 416 | /* 417 | * Macro to get Byte no. b from UInt32 value X. 418 | * We use two different definition, depending on the settings. 419 | */ 420 | #if SELECT_BYTE_FROM_UINT32_IN_MEMORY 421 | /* Pick the byte from the memory in which X is stored. */ 422 | #define SELECT_BYTE( X, b ) (((Byte *)(&(X)))[BYTE_OFFSET(b)]) 423 | #else 424 | /* Portable solution: Pick the byte directly from the X value. */ 425 | #define SELECT_BYTE( X, b ) (((X) >> 8*(b)) & 0xff) 426 | #endif 427 | 428 | 429 | /* Some shorthands because we use byte selection in large formulae. */ 430 | #define b0(X) SELECT_BYTE((X),0) 431 | #define b1(X) SELECT_BYTE((X),1) 432 | #define b2(X) SELECT_BYTE((X),2) 433 | #define b3(X) SELECT_BYTE((X),3) 434 | 435 | 436 | /* 437 | * We need macros to load and store UInt32 from/to byte arrays 438 | * using the least-significant-byte-first convention. 439 | * 440 | * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to 441 | * by p. 442 | * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form. 443 | */ 444 | #if CONVERT_USING_CASTS 445 | 446 | /* Get UInt32 from four bytes pointed to by p. */ 447 | #define GET32( p ) ENDIAN_CONVERT( *((UInt32 *)(p)) ) 448 | /* Put UInt32 into four bytes pointed to by p */ 449 | #define PUT32( v, p ) *((UInt32 *)(p)) = ENDIAN_CONVERT(v) 450 | 451 | #else 452 | 453 | /* Get UInt32 from four bytes pointed to by p. */ 454 | #define GET32( p ) \ 455 | ( \ 456 | (UInt32)((p)[0]) \ 457 | | (UInt32)((p)[1])<< 8\ 458 | | (UInt32)((p)[2])<<16\ 459 | | (UInt32)((p)[3])<<24\ 460 | ) 461 | /* Put UInt32 into four bytes pointed to by p */ 462 | #define PUT32( v, p ) \ 463 | (p)[0] = (Byte)(((v) ) & 0xff);\ 464 | (p)[1] = (Byte)(((v) >> 8) & 0xff);\ 465 | (p)[2] = (Byte)(((v) >> 16) & 0xff);\ 466 | (p)[3] = (Byte)(((v) >> 24) & 0xff) 467 | 468 | #endif 469 | 470 | 471 | /* 472 | * Test the platform-specific macros. 473 | * This function tests the macros defined so far to make sure the 474 | * definitions are appropriate for this platform. 475 | * If you make any mistake in the platform configuration, this should detect 476 | * that and inform you what went wrong. 477 | * Somewhere, someday, this is going to save somebody a lot of time, 478 | * because misbehaving macros are hard to debug. 479 | */ 480 | static void test_platform() 481 | { 482 | /* Buffer with test values. */ 483 | Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0}; 484 | UInt32 C; 485 | UInt32 x,y; 486 | int i; 487 | 488 | /* 489 | * Some sanity checks on the types that can't be done in compile time. 490 | * A smart compiler will just optimise these tests away. 491 | * The pre-processor doesn't understand different types, so we cannot 492 | * do these checks in compile-time. 493 | * 494 | * I hate C. 495 | * 496 | * The first check in each case is to make sure the size is correct. 497 | * The second check is to ensure that it is an unsigned type. 498 | */ 499 | if( ((UInt32) ((UInt32)1 << 31) == 0) || ((UInt32)-1 < 0) ) 500 | { 501 | Twofish_fatal( "Twofish code: Twofish_UInt32 type not suitable" ); 502 | } 503 | if( (sizeof( Byte ) != 1) || ((Byte)-1 < 0) ) 504 | { 505 | Twofish_fatal( "Twofish code: Twofish_Byte type not suitable" ); 506 | } 507 | 508 | /* 509 | * Sanity-check the endianness conversions. 510 | * This is just an aid to find problems. If you do the endianness 511 | * conversion macros wrong you will fail the full cipher test, 512 | * but that does not help you find the error. 513 | * Always make it easy to find the bugs! 514 | * 515 | * Detail: There is no fully portable way of writing UInt32 constants, 516 | * as you don't know whether to use the U or UL suffix. Using only U you 517 | * might only be allowed 16-bit constants. Using UL you might get 64-bit 518 | * constants which cannot be stored in a UInt32 without warnings, and 519 | * which generally behave subtly different from a true UInt32. 520 | * As long as we're just comparing with the constant, 521 | * we can always use the UL suffix and at worst lose some efficiency. 522 | * I use a separate '32-bit constant' macro in most of my other code. 523 | * 524 | * I hate C. 525 | * 526 | * Start with testing GET32. We test it on all positions modulo 4 527 | * to make sure we can handly any position of inputs. (Some CPUs 528 | * do not allow non-aligned accesses which we would do if you used 529 | * the CONVERT_USING_CASTS option. 530 | */ 531 | if( GET32( buf ) != 0x78563412UL || GET32(buf+1) != 0x9a785634UL 532 | || GET32( buf+2 ) != 0xbc9a7856UL || GET32(buf+3) != 0xdebc9a78UL ) 533 | { 534 | Twofish_fatal( "Twofish code: GET32 not implemented properly" ); 535 | } 536 | 537 | /* 538 | * We can now use GET32 to test PUT32. 539 | * We don't test the shifted versions. If GET32 can do that then 540 | * so should PUT32. 541 | */ 542 | C = GET32( buf ); 543 | PUT32( 3*C, buf ); 544 | if( GET32( buf ) != 0x69029c36UL ) 545 | { 546 | Twofish_fatal( "Twofish code: PUT32 not implemented properly" ); 547 | } 548 | 549 | 550 | /* Test ROL and ROR */ 551 | for( i=1; i<32; i++ ) 552 | { 553 | /* Just a simple test. */ 554 | x = ROR32( C, i ); 555 | y = ROL32( C, i ); 556 | x ^= (C>>i) ^ (C<<(32-i)); 557 | y ^= (C<>(32-i)); 558 | x |= y; 559 | /* 560 | * Now all we check is that x is zero in the least significant 561 | * 32 bits. Using the UL suffix is safe here, as it doesn't matter 562 | * if we get a larger type. 563 | */ 564 | if( (x & 0xffffffffUL) != 0 ) 565 | { 566 | Twofish_fatal( "Twofish ROL or ROR not properly defined." ); 567 | } 568 | } 569 | 570 | /* Test the BSWAP macro */ 571 | if( (BSWAP(C)) != 0x12345678UL ) 572 | { 573 | /* 574 | * The BSWAP macro should always work, even if you are not using it. 575 | * A smart optimising compiler will just remove this entire test. 576 | */ 577 | Twofish_fatal( "BSWAP not properly defined." ); 578 | } 579 | 580 | /* And we can test the b macros which use SELECT_BYTE. */ 581 | if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) ) 582 | { 583 | /* 584 | * There are many reasons why this could fail. 585 | * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value. 586 | */ 587 | Twofish_fatal( "Twofish code: SELECT_BYTE not implemented properly" ); 588 | } 589 | } 590 | 591 | 592 | /* 593 | * Finally, we can start on the Twofish-related code. 594 | * You really need the Twofish specifications to understand this code. The 595 | * best source is the Twofish book: 596 | * "The Twofish Encryption Algorithm", by Bruce Schneier, John Kelsey, 597 | * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson. 598 | * you can also use the AES submission document of Twofish, which is 599 | * available from my list of publications on my personal web site at 600 | * http://niels.ferguson.net/. 601 | * 602 | * The first thing we do is write the testing routines. This is what the 603 | * implementation has to satisfy in the end. We only test the external 604 | * behaviour of the implementation of course. 605 | */ 606 | 607 | 608 | /* 609 | * Perform a single self test on a (plaintext,ciphertext,key) triple. 610 | * Arguments: 611 | * key array of key bytes 612 | * key_len length of key in bytes 613 | * p plaintext 614 | * c ciphertext 615 | */ 616 | static void test_vector( Byte key[], int key_len, Byte p[16], Byte c[16] ) 617 | { 618 | Byte tmp[16]; /* scratch pad. */ 619 | Twofish_key xkey; /* The expanded key */ 620 | int i; 621 | 622 | 623 | /* Prepare the key */ 624 | Twofish_prepare_key( key, key_len, &xkey ); 625 | 626 | /* 627 | * We run the test twice to ensure that the xkey structure 628 | * is not damaged by the first encryption. 629 | * Those are hideous bugs to find if you get them in an application. 630 | */ 631 | for( i=0; i<2; i++ ) 632 | { 633 | /* Encrypt and test */ 634 | Twofish_encrypt( &xkey, p, tmp ); 635 | if( memcmp( c, tmp, 16 ) != 0 ) 636 | { 637 | Twofish_fatal( "Twofish encryption failure" ); 638 | } 639 | 640 | /* Decrypt and test */ 641 | Twofish_decrypt( &xkey, c, tmp ); 642 | if( memcmp( p, tmp, 16 ) != 0 ) 643 | { 644 | Twofish_fatal( "Twofish decryption failure" ); 645 | } 646 | } 647 | 648 | /* The test keys are not secret, so we don't need to wipe xkey. */ 649 | } 650 | 651 | 652 | /* 653 | * Check implementation using three (key,plaintext,ciphertext) 654 | * test vectors, one for each major key length. 655 | * 656 | * This is an absolutely minimal self-test. 657 | * This routine does not test odd-sized keys. 658 | */ 659 | static void test_vectors() 660 | { 661 | /* 662 | * We run three tests, one for each major key length. 663 | * These test vectors come from the Twofish specification. 664 | * One encryption and one decryption using randomish data and key 665 | * will detect almost any error, especially since we generate the 666 | * tables ourselves, so we don't have the problem of a single 667 | * damaged table entry in the source. 668 | */ 669 | 670 | /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */ 671 | static Byte k128[] = { 672 | 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 673 | 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A, 674 | }; 675 | static Byte p128[] = { 676 | 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 677 | 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 678 | }; 679 | static Byte c128[] = { 680 | 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 681 | 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 682 | }; 683 | 684 | /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */ 685 | static Byte k192[] = { 686 | 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 687 | 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, 688 | 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 689 | }; 690 | static Byte p192[] = { 691 | 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 692 | 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 693 | }; 694 | static Byte c192[] = { 695 | 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 696 | 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 697 | }; 698 | 699 | /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */ 700 | static Byte k256[] = { 701 | 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 702 | 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 703 | 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 704 | 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F 705 | }; 706 | static Byte p256[] = { 707 | 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 708 | 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 709 | }; 710 | static Byte c256[] = { 711 | 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 712 | 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA 713 | }; 714 | 715 | /* Run the actual tests. */ 716 | test_vector( k128, 16, p128, c128 ); 717 | test_vector( k192, 24, p192, c192 ); 718 | test_vector( k256, 32, p256, c256 ); 719 | } 720 | 721 | 722 | /* 723 | * Perform extensive test for a single key size. 724 | * 725 | * Test a single key size against the test vectors from section 726 | * B.2 in the Twofish book. This is a sequence of 49 encryptions 727 | * and decryptions. Each plaintext is equal to the ciphertext of 728 | * the previous encryption. The key is made up from the ciphertext 729 | * two and three encryptions ago. Both plaintext and key start 730 | * at the zero value. 731 | * We should have designed a cleaner recurrence relation for 732 | * these tests, but it is too late for that now. At least we learned 733 | * how to do it better next time. 734 | * For details see appendix B of the book. 735 | * 736 | * Arguments: 737 | * key_len Number of bytes of key 738 | * final_value Final plaintext value after 49 iterations 739 | */ 740 | static void test_sequence( int key_len, Byte final_value[] ) 741 | { 742 | Byte buf[ (50+3)*16 ]; /* Buffer to hold our computation values. */ 743 | Byte tmp[16]; /* Temp for testing the decryption. */ 744 | Twofish_key xkey; /* The expanded key */ 745 | int i; 746 | Byte * p; 747 | 748 | /* Wipe the buffer */ 749 | memset( buf, 0, sizeof( buf ) ); 750 | 751 | /* 752 | * Because the recurrence relation is done in an inconvenient manner 753 | * we end up looping backwards over the buffer. 754 | */ 755 | 756 | /* Pointer in buffer points to current plaintext. */ 757 | p = &buf[50*16]; 758 | for( i=1; i<50; i++ ) 759 | { 760 | /* 761 | * Prepare a key. 762 | * This automatically checks that key_len is valid. 763 | */ 764 | Twofish_prepare_key( p+16, key_len, &xkey ); 765 | 766 | /* Compute the next 16 bytes in the buffer */ 767 | Twofish_encrypt( &xkey, p, p-16 ); 768 | 769 | /* Check that the decryption is correct. */ 770 | Twofish_decrypt( &xkey, p-16, tmp ); 771 | if( memcmp( tmp, p, 16 ) != 0 ) 772 | { 773 | Twofish_fatal( "Twofish decryption failure in sequence" ); 774 | } 775 | /* Move on to next 16 bytes in the buffer. */ 776 | p -= 16; 777 | } 778 | 779 | /* And check the final value. */ 780 | if( memcmp( p, final_value, 16 ) != 0 ) 781 | { 782 | Twofish_fatal( "Twofish encryption failure in sequence" ); 783 | } 784 | 785 | /* None of the data was secret, so there is no need to wipe anything. */ 786 | } 787 | 788 | 789 | /* 790 | * Run all three sequence tests from the Twofish test vectors. 791 | * 792 | * This checks the most extensive test vectors currently available 793 | * for Twofish. The data is from the Twofish book, appendix B.2. 794 | */ 795 | static void test_sequences() 796 | { 797 | static Byte r128[] = { 798 | 0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57, 799 | 0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0 800 | }; 801 | static Byte r192[] = { 802 | 0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4, 803 | 0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41 804 | }; 805 | static Byte r256[] = { 806 | 0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75, 807 | 0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05 808 | }; 809 | 810 | /* Run the three sequence test vectors */ 811 | test_sequence( 16, r128 ); 812 | test_sequence( 24, r192 ); 813 | test_sequence( 32, r256 ); 814 | } 815 | 816 | 817 | /* 818 | * Test the odd-sized keys. 819 | * 820 | * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits. 821 | * The equivalent key is found by padding at the end with zero bytes 822 | * until a regular key size is reached. 823 | * 824 | * We just test that the key expansion routine behaves properly. 825 | * If the expanded keys are identical, then the encryptions and decryptions 826 | * will behave the same. 827 | */ 828 | static void test_odd_sized_keys() 829 | { 830 | Byte buf[32]; 831 | Twofish_key xkey; 832 | Twofish_key xkey_two; 833 | int i; 834 | 835 | /* 836 | * We first create an all-zero key to use as PRNG key. 837 | * Normally we would not have to fill the buffer with zeroes, as we could 838 | * just pass a zero key length to the Twofish_prepare_key function. 839 | * However, this relies on using odd-sized keys, and those are just the 840 | * ones we are testing here. We can't use an untested function to test 841 | * itself. 842 | */ 843 | memset( buf, 0, sizeof( buf ) ); 844 | Twofish_prepare_key( buf, 16, &xkey ); 845 | 846 | /* Fill buffer with pseudo-random data derived from two encryptions */ 847 | Twofish_encrypt( &xkey, buf, buf ); 848 | Twofish_encrypt( &xkey, buf, buf+16 ); 849 | 850 | /* Create all possible shorter keys that are prefixes of the buffer. */ 851 | for( i=31; i>=0; i-- ) 852 | { 853 | /* Set a byte to zero. This is the new padding byte */ 854 | buf[i] = 0; 855 | 856 | /* Expand the key with only i bytes of length */ 857 | Twofish_prepare_key( buf, i, &xkey ); 858 | 859 | /* Expand the corresponding padded key of regular length */ 860 | Twofish_prepare_key( buf, i<=16 ? 16 : i<= 24 ? 24 : 32, &xkey_two ); 861 | 862 | /* Compare the two */ 863 | if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 ) 864 | { 865 | Twofish_fatal( "Odd sized keys do not expand properly" ); 866 | } 867 | } 868 | 869 | /* None of the key values are secret, so we don't need to wipe them. */ 870 | } 871 | 872 | 873 | /* 874 | * Test the Twofish implementation. 875 | * 876 | * This routine runs all the self tests, in order of importance. 877 | * It is called by the Twofish_initialise routine. 878 | * 879 | * In almost all applications the cost of running the self tests during 880 | * initialisation is insignificant, especially 881 | * compared to the time it takes to load the application from disk. 882 | * If you are very pressed for initialisation performance, 883 | * you could remove some of the tests. Make sure you did run them 884 | * once in the software and hardware configuration you are using. 885 | */ 886 | static void self_test() 887 | { 888 | /* The three test vectors form an absolute minimal test set. */ 889 | test_vectors(); 890 | 891 | /* 892 | * If at all possible you should run these tests too. They take 893 | * more time, but provide a more thorough coverage. 894 | */ 895 | test_sequences(); 896 | 897 | /* Test the odd-sized keys. */ 898 | test_odd_sized_keys(); 899 | } 900 | 901 | 902 | /* 903 | * And now, the actual Twofish implementation. 904 | * 905 | * This implementation generates all the tables during initialisation. 906 | * I don't like large tables in the code, especially since they are easily 907 | * damaged in the source without anyone noticing it. You need code to 908 | * generate them anyway, and this way all the code is close together. 909 | * Generating them in the application leads to a smaller executable 910 | * (the code is smaller than the tables it generates) and a 911 | * larger static memory footprint. 912 | * 913 | * Twofish can be implemented in many ways. I have chosen to 914 | * use large tables with a relatively long key setup time. 915 | * If you encrypt more than a few blocks of data it pays to pre-compute 916 | * as much as possible. This implementation is relatively inefficient for 917 | * applications that need to re-key every block or so. 918 | */ 919 | 920 | /* 921 | * We start with the t-tables, directly from the Twofish definition. 922 | * These are nibble-tables, but merging them and putting them two nibbles 923 | * in one byte is more work than it is worth. 924 | */ 925 | static Byte t_table[2][4][16] = { 926 | { 927 | {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4}, 928 | {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD}, 929 | {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1}, 930 | {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA} 931 | }, 932 | { 933 | {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5}, 934 | {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8}, 935 | {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF}, 936 | {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA} 937 | } 938 | }; 939 | 940 | 941 | /* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */ 942 | #define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) ) 943 | 944 | /* 945 | * The q-boxes are only used during the key schedule computations. 946 | * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit 947 | * lookup tables as it is faster to load a 32-bit value than to load an 948 | * 8-bit value and zero the rest of the register. 949 | * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in 950 | * the q-tables. Here we just define the Qtype which is used to store 951 | * the entries of the q-tables. 952 | */ 953 | #if LARGE_Q_TABLE 954 | typedef UInt32 Qtype; 955 | #else 956 | typedef Byte Qtype; 957 | #endif 958 | 959 | /* 960 | * The actual q-box tables. 961 | * There are two q-boxes, each having 256 entries. 962 | */ 963 | static Qtype q_table[2][256]; 964 | 965 | 966 | /* 967 | * Now the function that converts a single t-table into a q-table. 968 | * 969 | * Arguments: 970 | * t[4][16] : four 4->4bit lookup tables that define the q-box 971 | * q[256] : output parameter: the resulting q-box as a lookup table. 972 | */ 973 | static void make_q_table( Byte t[4][16], Qtype q[256] ) 974 | { 975 | int ae,be,ao,bo; /* Some temporaries. */ 976 | int i; 977 | /* Loop over all input values and compute the q-box result. */ 978 | for( i=0; i<256; i++ ) { 979 | /* 980 | * This is straight from the Twofish specifications. 981 | * 982 | * The ae variable is used for the a_i values from the specs 983 | * with even i, and ao for the odd i's. Similarly for the b's. 984 | */ 985 | ae = i>>4; be = i&0xf; 986 | ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); 987 | ae = t[0][ao]; be = t[1][bo]; 988 | ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); 989 | ae = t[2][ao]; be = t[3][bo]; 990 | 991 | /* Store the result in the q-box table, the cast avoids a warning. */ 992 | q[i] = (Qtype) ((be<<4) | ae); 993 | } 994 | } 995 | 996 | 997 | /* 998 | * Initialise both q-box tables. 999 | */ 1000 | static void initialise_q_boxes() { 1001 | /* Initialise each of the q-boxes using the t-tables */ 1002 | make_q_table( t_table[0], q_table[0] ); 1003 | make_q_table( t_table[1], q_table[1] ); 1004 | } 1005 | 1006 | 1007 | /* 1008 | * Next up is the MDS matrix multiplication. 1009 | * The MDS matrix multiplication operates in the field 1010 | * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1. 1011 | * If you don't understand this, read a book on finite fields. You cannot 1012 | * follow the finite-field computations without some background. 1013 | * 1014 | * In this field, multiplication by x is easy: shift left one bit 1015 | * and if bit 8 is set then xor the result with 0x169. 1016 | * 1017 | * The MDS coefficients use a multiplication by 1/x, 1018 | * or rather a division by x. This is easy too: first make the 1019 | * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary, 1020 | * and then shift right one position. 1021 | * Even easier: shift right and xor with 0xb4 if the lsbit was set. 1022 | * 1023 | * The MDS coefficients are 1, EF, and 5B, and we use the fact that 1024 | * EF = 1 + 1/x + 1/x^2 1025 | * 5B = 1 + 1/x^2 1026 | * in this field. This makes multiplication by EF and 5B relatively easy. 1027 | * 1028 | * This property is no accident, the MDS matrix was designed to allow 1029 | * this implementation technique to be used. 1030 | * 1031 | * We have four MDS tables, each mapping 8 bits to 32 bits. 1032 | * Each table performs one column of the matrix multiplication. 1033 | * As the MDS is always preceded by q-boxes, each of these tables 1034 | * also implements the q-box just previous to that column. 1035 | */ 1036 | 1037 | /* The actual MDS tables. */ 1038 | static UInt32 MDS_table[4][256]; 1039 | 1040 | /* A small table to get easy conditional access to the 0xb4 constant. */ 1041 | static UInt32 mds_poly_divx_const[] = {0,0xb4}; 1042 | 1043 | /* Function to initialise the MDS tables. */ 1044 | static void initialise_mds_tables() 1045 | { 1046 | int i; 1047 | UInt32 q,qef,q5b; /* Temporary variables. */ 1048 | 1049 | /* Loop over all 8-bit input values */ 1050 | for( i=0; i<256; i++ ) 1051 | { 1052 | /* 1053 | * To save some work during the key expansion we include the last 1054 | * of the q-box layers from the h() function in these MDS tables. 1055 | */ 1056 | 1057 | /* We first do the inputs that are mapped through the q0 table. */ 1058 | q = q_table[0][i]; 1059 | /* 1060 | * Here we divide by x, note the table to get 0xb4 only if the 1061 | * lsbit is set. 1062 | * This sets qef = (1/x)*q in the finite field 1063 | */ 1064 | qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; 1065 | /* 1066 | * Divide by x again, and add q to get (1+1/x^2)*q. 1067 | * Note that (1+1/x^2) = 5B in the field, and addition in the field 1068 | * is exclusive or on the bits. 1069 | */ 1070 | q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; 1071 | /* 1072 | * Add q5b to qef to set qef = (1+1/x+1/x^2)*q. 1073 | * Again, (1+1/x+1/x^2) = EF in the field. 1074 | */ 1075 | qef ^= q5b; 1076 | 1077 | /* 1078 | * Now that we have q5b = 5B * q and qef = EF * q 1079 | * we can fill two of the entries in the MDS matrix table. 1080 | * See the Twofish specifications for the order of the constants. 1081 | */ 1082 | MDS_table[1][i] = q <<24 | q5b<<16 | qef<<8 | qef; 1083 | MDS_table[3][i] = q5b<<24 | qef<<16 | q <<8 | q5b; 1084 | 1085 | /* Now we do it all again for the two columns that have a q1 box. */ 1086 | q = q_table[1][i]; 1087 | qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; 1088 | q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; 1089 | qef ^= q5b; 1090 | 1091 | /* The other two columns use the coefficient in a different order. */ 1092 | MDS_table[0][i] = qef<<24 | qef<<16 | q5b<<8 | q ; 1093 | MDS_table[2][i] = qef<<24 | q <<16 | qef<<8 | q5b; 1094 | } 1095 | } 1096 | 1097 | 1098 | /* 1099 | * The h() function is the heart of the Twofish cipher. 1100 | * It is a complicated sequence of q-box lookups, key material xors, 1101 | * and finally the MDS matrix. 1102 | * We use lots of macros to make this reasonably fast. 1103 | */ 1104 | 1105 | /* First a shorthand for the two q-tables */ 1106 | #define q0 q_table[0] 1107 | #define q1 q_table[1] 1108 | 1109 | /* 1110 | * Each macro computes one column of the h for either 2, 3, or 4 stages. 1111 | * As there are 4 columns, we have 12 macros in all. 1112 | * 1113 | * The key bytes are stored in the Byte array L at offset 1114 | * 0,1,2,3, 8,9,10,11, [16,17,18,19, [24,25,26,27]] as this is the 1115 | * order we get the bytes from the user. If you look at the Twofish 1116 | * specs, you'll see that h() is applied to the even key words or the 1117 | * odd key words. The bytes of the even words appear in this spacing, 1118 | * and those of the odd key words too. 1119 | * 1120 | * These macros are the only place where the q-boxes and the MDS table 1121 | * are used. 1122 | */ 1123 | #define H02( y, L ) MDS_table[0][q0[q0[y]^L[ 8]]^L[0]] 1124 | #define H12( y, L ) MDS_table[1][q0[q1[y]^L[ 9]]^L[1]] 1125 | #define H22( y, L ) MDS_table[2][q1[q0[y]^L[10]]^L[2]] 1126 | #define H32( y, L ) MDS_table[3][q1[q1[y]^L[11]]^L[3]] 1127 | #define H03( y, L ) H02( q1[y]^L[16], L ) 1128 | #define H13( y, L ) H12( q1[y]^L[17], L ) 1129 | #define H23( y, L ) H22( q0[y]^L[18], L ) 1130 | #define H33( y, L ) H32( q0[y]^L[19], L ) 1131 | #define H04( y, L ) H03( q1[y]^L[24], L ) 1132 | #define H14( y, L ) H13( q0[y]^L[25], L ) 1133 | #define H24( y, L ) H23( q0[y]^L[26], L ) 1134 | #define H34( y, L ) H33( q1[y]^L[27], L ) 1135 | 1136 | /* 1137 | * Now we can define the h() function given an array of key bytes. 1138 | * This function is only used in the key schedule, and not to pre-compute 1139 | * the keyed S-boxes. 1140 | * 1141 | * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24) 1142 | * so we only provide k as an argument. 1143 | * 1144 | * Arguments: 1145 | * k input to the h() function. 1146 | * L pointer to array of key bytes at 1147 | * offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]] 1148 | * kCycles # key cycles, 2, 3, or 4. 1149 | */ 1150 | static UInt32 h( int k, Byte L[], int kCycles ) 1151 | { 1152 | switch( kCycles ) { 1153 | /* We code all 3 cases separately for speed reasons. */ 1154 | case 2: 1155 | return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L); 1156 | case 3: 1157 | return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L); 1158 | case 4: 1159 | return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L); 1160 | default: 1161 | /* This is always a coding error, which is fatal. */ 1162 | Twofish_fatal( "Twofish h(): Illegal argument" ); 1163 | } 1164 | } 1165 | 1166 | 1167 | /* 1168 | * Pre-compute the keyed S-boxes. 1169 | * Fill the pre-computed S-box array in the expanded key structure. 1170 | * Each pre-computed S-box maps 8 bits to 32 bits. 1171 | * 1172 | * The S argument contains half the number of bytes of the full key, but is 1173 | * derived from the full key. (See Twofish specifications for details.) 1174 | * S has the weird byte input order used by the Hxx macros. 1175 | * 1176 | * This function takes most of the time of a key expansion. 1177 | * 1178 | * Arguments: 1179 | * S pointer to array of 8*kCycles Bytes containing the S vector. 1180 | * kCycles number of key words, must be in the set {2,3,4} 1181 | * xkey pointer to Twofish_key structure that will contain the S-boxes. 1182 | */ 1183 | static void fill_keyed_sboxes( Byte S[], int kCycles, Twofish_key * xkey ) 1184 | { 1185 | int i; 1186 | switch( kCycles ) { 1187 | /* We code all 3 cases separately for speed reasons. */ 1188 | case 2: 1189 | for( i=0; i<256; i++ ) 1190 | { 1191 | xkey->s[0][i]= H02( i, S ); 1192 | xkey->s[1][i]= H12( i, S ); 1193 | xkey->s[2][i]= H22( i, S ); 1194 | xkey->s[3][i]= H32( i, S ); 1195 | } 1196 | break; 1197 | case 3: 1198 | for( i=0; i<256; i++ ) 1199 | { 1200 | xkey->s[0][i]= H03( i, S ); 1201 | xkey->s[1][i]= H13( i, S ); 1202 | xkey->s[2][i]= H23( i, S ); 1203 | xkey->s[3][i]= H33( i, S ); 1204 | } 1205 | break; 1206 | case 4: 1207 | for( i=0; i<256; i++ ) 1208 | { 1209 | xkey->s[0][i]= H04( i, S ); 1210 | xkey->s[1][i]= H14( i, S ); 1211 | xkey->s[2][i]= H24( i, S ); 1212 | xkey->s[3][i]= H34( i, S ); 1213 | } 1214 | break; 1215 | default: 1216 | /* This is always a coding error, which is fatal. */ 1217 | Twofish_fatal( "Twofish fill_keyed_sboxes(): Illegal argument" ); 1218 | } 1219 | } 1220 | 1221 | 1222 | /* A flag to keep track of whether we have been initialised or not. */ 1223 | static int Twofish_initialised = 0; 1224 | 1225 | /* 1226 | * Initialise the Twofish implementation. 1227 | * This function must be called before any other function in the 1228 | * Twofish implementation is called. 1229 | * This routine also does some sanity checks, to make sure that 1230 | * all the macros behave, and it tests the whole cipher. 1231 | */ 1232 | void Twofish_initialise() 1233 | { 1234 | /* First test the various platform-specific definitions. */ 1235 | test_platform(); 1236 | 1237 | /* We can now generate our tables, in the right order of course. */ 1238 | initialise_q_boxes(); 1239 | initialise_mds_tables(); 1240 | 1241 | /* We're finished with the initialisation itself. */ 1242 | Twofish_initialised = 1; 1243 | 1244 | /* 1245 | * And run some tests on the whole cipher. 1246 | * Yes, you need to do this every time you start your program. 1247 | * It is called assurance; you have to be certain that your program 1248 | * still works properly. 1249 | */ 1250 | self_test(); 1251 | } 1252 | 1253 | 1254 | /* 1255 | * The Twofish key schedule uses an Reed-Solomon code matrix multiply. 1256 | * Just like the MDS matrix, the RS-matrix is designed to be easy 1257 | * to implement. Details are below in the code. 1258 | * 1259 | * These constants make it easy to compute in the finite field used 1260 | * for the RS code. 1261 | * 1262 | * We use Bytes for the RS computation, but these are automatically 1263 | * widened to unsigned integers in the expressions. Having unsigned 1264 | * ints in these tables therefore provides the fastest access. 1265 | */ 1266 | static unsigned int rs_poly_const[] = {0, 0x14d}; 1267 | static unsigned int rs_poly_div_const[] = {0, 0xa6 }; 1268 | 1269 | 1270 | /* 1271 | * Prepare a key for use in encryption and decryption. 1272 | * Like most block ciphers, Twofish allows the key schedule 1273 | * to be pre-computed given only the key. 1274 | * Twofish has a fairly 'heavy' key schedule that takes a lot of time 1275 | * to compute. The main work is pre-computing the S-boxes used in the 1276 | * encryption and decryption. We feel that this makes the cipher much 1277 | * harder to attack. The attacker doesn't even know what the S-boxes 1278 | * contain without including the entire key schedule in the analysis. 1279 | * 1280 | * Unlike most Twofish implementations, this one allows any key size from 1281 | * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the 1282 | * specifications); the key is simply padded with zeroes to the next real 1283 | * key size of 16, 24, or 32 bytes. 1284 | * Each odd-sized key is thus equivalent to a single normal-sized key. 1285 | * 1286 | * Arguments: 1287 | * key array of key bytes 1288 | * key_len number of bytes in the key, must be in the range 0,...,32. 1289 | * xkey Pointer to an Twofish_key structure that will be filled 1290 | * with the internal form of the cipher key. 1291 | */ 1292 | void Twofish_prepare_key( Byte key[], int key_len, Twofish_key * xkey ) 1293 | { 1294 | /* We use a single array to store all key material in, 1295 | * to simplify the wiping of the key material at the end. 1296 | * The first 32 bytes contain the actual (padded) cipher key. 1297 | * The next 32 bytes contain the S-vector in its weird format, 1298 | * and we have 4 bytes of overrun necessary for the RS-reduction. 1299 | */ 1300 | Byte K[32+32+4]; 1301 | 1302 | int kCycles; /* # key cycles, 2,3, or 4. */ 1303 | 1304 | int i; 1305 | UInt32 A, B; /* Used to compute the round keys. */ 1306 | 1307 | Byte * kptr; /* Three pointers for the RS computation. */ 1308 | Byte * sptr; 1309 | Byte * t; 1310 | 1311 | Byte b,bx,bxx; /* Some more temporaries for the RS computation. */ 1312 | 1313 | /* Check that the Twofish implementation was initialised. */ 1314 | if( Twofish_initialised == 0 ) 1315 | { 1316 | /* 1317 | * You didn't call Twofish_initialise before calling this routine. 1318 | * This is a programming error, and therefore we call the fatal 1319 | * routine. 1320 | * 1321 | * I could of course call the initialisation routine here, 1322 | * but there are a few reasons why I don't. First of all, the 1323 | * self-tests have to be done at startup. It is no good to inform 1324 | * the user that the cipher implementation fails when he wants to 1325 | * write his data to disk in encrypted form. You have to warn him 1326 | * before he spends time typing his data. Second, the initialisation 1327 | * and self test are much slower than a single key expansion. 1328 | * Calling the initialisation here makes the performance of the 1329 | * cipher unpredictable. This can lead to really weird problems 1330 | * if you use the cipher for a real-time task. Suddenly it fails 1331 | * once in a while the first time you try to use it. Things like 1332 | * that are almost impossible to debug. 1333 | */ 1334 | Twofish_fatal( "Twofish implementation was not initialised." ); 1335 | 1336 | /* 1337 | * There is always a danger that the Twofish_fatal routine returns, 1338 | * in spite of the specifications that it should not. 1339 | * (A good programming rule: don't trust the rest of the code.) 1340 | * This would be disasterous. If the q-tables and MDS-tables have 1341 | * not been initialised, they are probably still filled with zeroes. 1342 | * Suppose the MDS-tables are all zero. The key expansion would then 1343 | * generate all-zero round keys, and all-zero s-boxes. The danger 1344 | * is that nobody would notice as the encryption function still 1345 | * mangles the input, and the decryption still 'decrypts' it, 1346 | * but now in a completely key-independent manner. 1347 | * To stop such security disasters, we use blunt force. 1348 | * If your program hangs here: fix the fatal routine! 1349 | */ 1350 | /*for(;;);*/ /* Infinite loop, which beats being insecure. */ 1351 | } 1352 | 1353 | /* Check for valid key length. */ 1354 | if( key_len < 0 || key_len > 32 ) 1355 | { 1356 | /* 1357 | * This can only happen if a programmer didn't read the limitations 1358 | * on the key size. 1359 | */ 1360 | Twofish_fatal( "Twofish_prepare_key: illegal key length" ); 1361 | /* 1362 | * A return statement just in case the fatal macro returns. 1363 | * The rest of the code assumes that key_len is in range, and would 1364 | * buffer-overflow if it wasn't. 1365 | * 1366 | * Why do we still use a programming language that has problems like 1367 | * buffer overflows, when these problems were solved in 1960 with 1368 | * the development of Algol? Have we not leared anything? 1369 | */ 1370 | /*return;*/ 1371 | } 1372 | 1373 | /* Pad the key with zeroes to the next suitable key length. */ 1374 | memcpy( K, key, key_len ); 1375 | memset( K+key_len, 0, sizeof(K)-key_len ); 1376 | 1377 | /* 1378 | * Compute kCycles: the number of key cycles used in the cipher. 1379 | * 2 for 128-bit keys, 3 for 192-bit keys, and 4 for 256-bit keys. 1380 | */ 1381 | kCycles = (key_len + 7) >> 3; 1382 | /* Handle the special case of very short keys: minimum 2 cycles. */ 1383 | if( kCycles < 2 ) 1384 | { 1385 | kCycles = 2; 1386 | } 1387 | 1388 | /* 1389 | * From now on we just pretend to have 8*kCycles bytes of 1390 | * key material in K. This handles all the key size cases. 1391 | */ 1392 | 1393 | /* 1394 | * We first compute the 40 expanded key words, 1395 | * formulas straight from the Twofish specifications. 1396 | */ 1397 | for( i=0; i<40; i+=2 ) 1398 | { 1399 | /* 1400 | * Due to the byte spacing expected by the h() function 1401 | * we can pick the bytes directly from the key K. 1402 | * As we use bytes, we never have the little/big endian 1403 | * problem. 1404 | * 1405 | * Note that we apply the rotation function only to simple 1406 | * variables, as the rotation macro might evaluate its argument 1407 | * more than once. 1408 | */ 1409 | A = h( i , K , kCycles ); 1410 | B = h( i+1, K+4, kCycles ); 1411 | B = ROL32( B, 8 ); 1412 | 1413 | /* Compute and store the round keys. */ 1414 | A += B; 1415 | B += A; 1416 | xkey->K[i] = A; 1417 | xkey->K[i+1] = ROL32( B, 9 ); 1418 | } 1419 | 1420 | /* Wipe variables that contained key material. */ 1421 | A=B=0; 1422 | 1423 | /* 1424 | * And now the dreaded RS multiplication that few seem to understand. 1425 | * The RS matrix is not random, and is specially designed to compute the 1426 | * RS matrix multiplication in a simple way. 1427 | * 1428 | * We work in the field GF(2)[x]/x^8+x^6+x^3+x^2+1. Note that this is a 1429 | * different field than used for the MDS matrix. 1430 | * (At least, it is a different representation because all GF(2^8) 1431 | * representations are equivalent in some form.) 1432 | * 1433 | * We take 8 consecutive bytes of the key and interpret them as 1434 | * a polynomial k_0 + k_1 y + k_2 y^2 + ... + k_7 y^7 where 1435 | * the k_i bytes are the key bytes and are elements of the finite field. 1436 | * We multiply this polynomial by y^4 and reduce it modulo 1437 | * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1. 1438 | * using straightforward polynomial modulo reduction. 1439 | * The coefficients of the result are the result of the RS 1440 | * matrix multiplication. When we wrote the Twofish specification, 1441 | * the original RS definition used the polynomials, 1442 | * but that requires much more mathematical knowledge. 1443 | * We were already using matrix multiplication in a finite field for 1444 | * the MDS matrix, so I re-wrote the RS operation as a matrix 1445 | * multiplication to reduce the difficulty of understanding it. 1446 | * Some implementors have not picked up on this simpler method of 1447 | * computing the RS operation, even though it is mentioned in the 1448 | * specifications. 1449 | * 1450 | * It is possible to perform these computations faster by using 32-bit 1451 | * word operations, but that is not portable and this is not a speed- 1452 | * critical area. 1453 | * 1454 | * We explained the 1/x computation when we did the MDS matrix. 1455 | * 1456 | * The S vector is stored in K[32..64]. 1457 | * The S vector has to be reversed, so we loop cross-wise. 1458 | * 1459 | * Note the weird byte spacing of the S-vector, to match the even 1460 | * or odd key words arrays. See the discussion at the Hxx macros for 1461 | * details. 1462 | */ 1463 | kptr = K + 8*kCycles; /* Start at end of key */ 1464 | sptr = K + 32; /* Start at start of S */ 1465 | 1466 | /* Loop over all key material */ 1467 | while( kptr > K ) 1468 | { 1469 | kptr -= 8; 1470 | /* 1471 | * Initialise the polynimial in sptr[0..12] 1472 | * The first four coefficients are 0 as we have to multiply by y^4. 1473 | * The next 8 coefficients are from the key material. 1474 | */ 1475 | memset( sptr, 0, 4 ); 1476 | memcpy( sptr+4, kptr, 8 ); 1477 | 1478 | /* 1479 | * The 12 bytes starting at sptr are now the coefficients of 1480 | * the polynomial we need to reduce. 1481 | */ 1482 | 1483 | /* Loop over the polynomial coefficients from high to low */ 1484 | t = sptr+11; 1485 | /* Keep looping until polynomial is degree 3; */ 1486 | while( t > sptr+3 ) 1487 | { 1488 | /* Pick up the highest coefficient of the poly. */ 1489 | b = *t; 1490 | 1491 | /* 1492 | * Compute x and (x+1/x) times this coefficient. 1493 | * See the MDS matrix implementation for a discussion of 1494 | * multiplication by x and 1/x. We just use different 1495 | * constants here as we are in a 1496 | * different finite field representation. 1497 | * 1498 | * These two statements set 1499 | * bx = (x) * b 1500 | * bxx= (x + 1/x) * b 1501 | */ 1502 | bx = (Byte)((b<<1) ^ rs_poly_const[ b>>7 ]); 1503 | bxx= (Byte)((b>>1) ^ rs_poly_div_const[ b&1 ] ^ bx); 1504 | 1505 | /* 1506 | * Subtract suitable multiple of 1507 | * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1 1508 | * from the polynomial, except that we don't bother 1509 | * updating t[0] as it will become zero anyway. 1510 | */ 1511 | t[-1] ^= bxx; 1512 | t[-2] ^= bx; 1513 | t[-3] ^= bxx; 1514 | t[-4] ^= b; 1515 | 1516 | /* Go to the next coefficient. */ 1517 | t--; 1518 | } 1519 | 1520 | /* Go to next S-vector word, obeying the weird spacing rules. */ 1521 | sptr += 8; 1522 | } 1523 | 1524 | /* Wipe variables that contained key material. */ 1525 | b = bx = bxx = 0; 1526 | 1527 | /* And finally, we can compute the key-dependent S-boxes. */ 1528 | fill_keyed_sboxes( &K[32], kCycles, xkey ); 1529 | 1530 | /* Wipe array that contained key material. */ 1531 | memset( K, 0, sizeof( K ) ); 1532 | } 1533 | 1534 | 1535 | /* 1536 | * We can now start on the actual encryption and decryption code. 1537 | * As these are often speed-critical we will use a lot of macros. 1538 | */ 1539 | 1540 | /* 1541 | * The g() function is the heart of the round function. 1542 | * We have two versions of the g() function, one without an input 1543 | * rotation and one with. 1544 | * The pre-computed S-boxes make this pretty simple. 1545 | */ 1546 | #define g0(X,xkey) \ 1547 | (xkey->s[0][b0(X)]^xkey->s[1][b1(X)]^xkey->s[2][b2(X)]^xkey->s[3][b3(X)]) 1548 | 1549 | #define g1(X,xkey) \ 1550 | (xkey->s[0][b3(X)]^xkey->s[1][b0(X)]^xkey->s[2][b1(X)]^xkey->s[3][b2(X)]) 1551 | 1552 | /* 1553 | * A single round of Twofish. The A,B,C,D are the four state variables, 1554 | * T0 and T1 are temporaries, xkey is the expanded key, and r the 1555 | * round number. 1556 | * 1557 | * Note that this macro does not implement the swap at the end of the round. 1558 | */ 1559 | #define ENCRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \ 1560 | T0 = g0(A,xkey); T1 = g1(B,xkey);\ 1561 | C ^= T0+T1+xkey->K[8+2*(r)]; C = ROR32(C,1);\ 1562 | D = ROL32(D,1); D ^= T0+2*T1+xkey->K[8+2*(r)+1] 1563 | 1564 | /* 1565 | * Encrypt a single cycle, consisting of two rounds. 1566 | * This avoids the swapping of the two halves. 1567 | * Parameter r is now the cycle number. 1568 | */ 1569 | #define ENCRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \ 1570 | ENCRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r) );\ 1571 | ENCRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)+1 ) 1572 | 1573 | /* Full 16-round encryption */ 1574 | #define ENCRYPT( A,B,C,D,T0,T1,xkey ) \ 1575 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 );\ 1576 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\ 1577 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\ 1578 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\ 1579 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\ 1580 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\ 1581 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\ 1582 | ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 ) 1583 | 1584 | /* 1585 | * A single round of Twofish for decryption. It differs from 1586 | * ENCRYTP_RND only because of the 1-bit rotations. 1587 | */ 1588 | #define DECRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \ 1589 | T0 = g0(A,xkey); T1 = g1(B,xkey);\ 1590 | C = ROL32(C,1); C ^= T0+T1+xkey->K[8+2*(r)];\ 1591 | D ^= T0+2*T1+xkey->K[8+2*(r)+1]; D = ROR32(D,1) 1592 | 1593 | /* 1594 | * Decrypt a single cycle, consisting of two rounds. 1595 | * This avoids the swapping of the two halves. 1596 | * Parameter r is now the cycle number. 1597 | */ 1598 | #define DECRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \ 1599 | DECRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)+1 );\ 1600 | DECRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r) ) 1601 | 1602 | /* Full 16-round decryption. */ 1603 | #define DECRYPT( A,B,C,D,T0,T1, xkey ) \ 1604 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 );\ 1605 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\ 1606 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\ 1607 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\ 1608 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\ 1609 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\ 1610 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\ 1611 | DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 ) 1612 | 1613 | /* 1614 | * A macro to read the state from the plaintext and do the initial key xors. 1615 | * The koff argument allows us to use the same macro 1616 | * for the decryption which uses different key words at the start. 1617 | */ 1618 | #define GET_INPUT( src, A,B,C,D, xkey, koff ) \ 1619 | A = GET32(src )^xkey->K[ koff]; B = GET32(src+ 4)^xkey->K[1+koff]; \ 1620 | C = GET32(src+ 8)^xkey->K[2+koff]; D = GET32(src+12)^xkey->K[3+koff] 1621 | 1622 | /* 1623 | * Similar macro to put the ciphertext in the output buffer. 1624 | * We xor the keys into the state variables before we use the PUT32 1625 | * macro as the macro might use its argument multiple times. 1626 | */ 1627 | #define PUT_OUTPUT( A,B,C,D, dst, xkey, koff ) \ 1628 | A ^= xkey->K[ koff]; B ^= xkey->K[1+koff]; \ 1629 | C ^= xkey->K[2+koff]; D ^= xkey->K[3+koff]; \ 1630 | PUT32( A, dst ); PUT32( B, dst+ 4 ); \ 1631 | PUT32( C, dst+8 ); PUT32( D, dst+12 ) 1632 | 1633 | 1634 | /* 1635 | * Twofish block encryption 1636 | * 1637 | * Arguments: 1638 | * xkey expanded key array 1639 | * p 16 bytes of plaintext 1640 | * c 16 bytes in which to store the ciphertext 1641 | */ 1642 | void Twofish_encrypt( Twofish_key * xkey, Byte p[16], Byte c[16]) 1643 | { 1644 | UInt32 A,B,C,D,T0,T1; /* Working variables */ 1645 | 1646 | /* Get the four plaintext words xorred with the key */ 1647 | GET_INPUT( p, A,B,C,D, xkey, 0 ); 1648 | 1649 | /* Do 8 cycles (= 16 rounds) */ 1650 | ENCRYPT( A,B,C,D,T0,T1,xkey ); 1651 | 1652 | /* Store them with the final swap and the output whitening. */ 1653 | PUT_OUTPUT( C,D,A,B, c, xkey, 4 ); 1654 | } 1655 | 1656 | 1657 | /* 1658 | * Twofish block decryption. 1659 | * 1660 | * Arguments: 1661 | * xkey expanded key array 1662 | * p 16 bytes of plaintext 1663 | * c 16 bytes in which to store the ciphertext 1664 | */ 1665 | void Twofish_decrypt( Twofish_key * xkey, Byte c[16], Byte p[16]) 1666 | { 1667 | UInt32 A,B,C,D,T0,T1; /* Working variables */ 1668 | 1669 | /* Get the four plaintext words xorred with the key */ 1670 | GET_INPUT( c, A,B,C,D, xkey, 4 ); 1671 | 1672 | /* Do 8 cycles (= 16 rounds) */ 1673 | DECRYPT( A,B,C,D,T0,T1,xkey ); 1674 | 1675 | /* Store them with the final swap and the output whitening. */ 1676 | PUT_OUTPUT( C,D,A,B, p, xkey, 0 ); 1677 | } 1678 | 1679 | /* 1680 | * Using the macros it is easy to make special routines for 1681 | * CBC mode, CTR mode etc. The only thing you might want to 1682 | * add is a XOR_PUT_OUTPUT which xors the outputs into the 1683 | * destinationa instead of overwriting the data. This requires 1684 | * a XOR_PUT32 macro as well, but that should all be trivial. 1685 | * 1686 | * I thought about including routines for the separate cipher 1687 | * modes here, but it is unclear which modes should be included, 1688 | * and each encryption or decryption routine takes up a lot of code space. 1689 | * Also, I don't have any test vectors for any cipher modes 1690 | * with Twofish. 1691 | */ 1692 | --------------------------------------------------------------------------------