mixed boob

This commit is contained in:
malloc 2018-03-20 17:42:26 -05:00
parent 922f801c96
commit 75495fc976
10 changed files with 281 additions and 22 deletions

View file

@ -4,7 +4,7 @@ project(server)
file(GLOB_RECURSE server_src
"src/*.hpp"
"src/*.cpp"
)
)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -static")

View file

@ -3,14 +3,18 @@
#define B64_IGNORE 0xFE
#define B64_PADDING 0xFF
std::string sosc::cgc::base64_encode(const std::string& data) {
std::string sosc::cgc::base64_encode(const std::string& data, bool unix) {
return base64_encode(data.c_str(), data.length());
}
std::string sosc::cgc::base64_encode(const void* raw, size_t length) {
std::string sosc::cgc::base64_encode
(const void* raw, size_t length, bool unix)
{
uint8_t* data = (uint8_t*)raw;
const std::string char_table
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
= (unix)
? "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string encoded;
for(size_t i = 0; i < length; i += 3) {
@ -27,14 +31,30 @@ std::string sosc::cgc::base64_encode(const void* raw, size_t length) {
for(int j = 0; j < 4 - padding; ++j)
encoded += char_table[(index >> (6 * (3 - j))) & 0x3F];
for(int j = 0; j < padding; ++j)
encoded += '=';
if(!unix)
for(int j = 0; j < padding; ++j)
encoded += '=';
}
return encoded;
}
static uint8_t radix64_decode_char(char c) {
if(c >= '0' && c <= '9')
return c - '0' + 2;
else if(c >= 'A' && c <= 'Z')
return c - 'A' + 12;
else if(c >= 'a' && c <= 'z')
return c - 'a' + 38;
else if(c == '.')
return 0;
else if(c == '/')
return 1;
else
return B64_IGNORE;
}
static uint8_t base64_decode_char(char c) {
if(c >= 'A' && c <= 'Z')
return c - 'A';
@ -62,12 +82,13 @@ static void base64_decode_append(std::string* decoded, int data) {
*decoded += (char)data;
}
std::string sosc::cgc::base64_decode(const std::string& data) {
std::string sosc::cgc::base64_decode(const std::string& data, bool unix) {
std::string decoded;
int index = 0, j = 0;
for(std::string::size_type i = 0; i < data.length(); ++i) {
int sextet = base64_decode_char(data[i]);
int sextet = unix ? radix64_decode_char(data[i])
: base64_decode_char(data[i]);
if(sextet == B64_IGNORE || sextet == B64_PADDING) {
if(sextet == B64_PADDING && i >= data.length() - 2 && j > 1)

View file

@ -7,10 +7,10 @@
namespace sosc {
namespace cgc {
std::string base64_encode(const std::string& data);
std::string base64_encode(const void* raw, size_t length);
std::string base64_encode(const std::string& data, bool unix = false);
std::string base64_encode(const void* raw, size_t length, bool unix = false);
std::string base64_decode(const std::string& data);
std::string base64_decode(const std::string& data, bool unix = false);
}}
#endif

View file

@ -0,0 +1,15 @@
#include "bcrypt.hpp"
std::string sosc::cgc::bcrypt_hash(const std::string& input) {
std::string salt = csprng::next_bytes(16),
input_t = input.substr(0, 72);
Blowfish bfish;
std::stringstream stream;
stream << "$2b$" << BCRYPT_COST << "$"
<< base64_encode(salt, true)
<< "b";
return stream.str();
}

View file

@ -0,0 +1,18 @@
#ifndef SOSC_CRYPTO_BCRYPT_H
#define SOSC_CRYPTO_BCRYPT_H
#include <sstream>
#include <string>
#include "base64.hpp"
#include "bfish.hpp"
#include "../utils/csprng.hpp"
#define BCRYPT_COST 10
namespace sosc {
namespace cgc {
std::string bcrypt_hash(const std::string& input);
bool bcrypt_check(std::string input, std::string hash);
}}
#endif

View file

@ -184,14 +184,48 @@ static const uint32_t init_sbox[4][256] = {
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
};
static void swap(uint32_t& a, uint32_t& b) {
uint32_t temp = a;
a = b;
b = temp;
}
static void pack_bytes
(const std::string& data, std::string::size_type i,
uint32_t& left, uint32_t& right)
{
left = right = 0;
for(int j = 0; j < 8; ++j) {
if(j < 4)
left = (left << 8) | (data[(i + j) % data.length()] & 0xFF);
else
right = (right << 8) | (data[(i + j) % data.length()] & 0xFF);
}
}
static void unpack_bytes
(std::string& data, std::string::size_type i,
uint32_t left, uint32_t right)
{
for(int j = 0; j < 8; ++j) {
if(j < 4) {
data[i + (3 - j)] = left & 0xFF;
left >>= 8;
} else {
data[i + (7 - j + 4)] = right & 0xFF;
right >>= 8;
}
}
}
sosc::cgc::Blowfish::Blowfish(const std::string& key) {
std::memcpy(this->parr, init_parr, sizeof(init_parr));
std::memcpy(this->sbox, init_sbox, sizeof(init_sbox));
this->SetKey(key.c_str(), key.length());
}
void sosc::cgc::Blowfish::SetKey(const char* key, size_t length) {
std::memcpy(this->parr, init_parr, sizeof(init_parr));
std::memcpy(this->sbox, init_sbox, sizeof(init_sbox));
for(int i = 0; i < 18; ++i) {
uint32_t data = 0;
for(int j = 0; j < 4; ++j)
@ -216,19 +250,99 @@ void sosc::cgc::Blowfish::SetKey(const char* key, size_t length) {
}
}
void sosc::cgc::Blowfish::SetEksKey
(const std::string& data, const std::string& key)
{
for(int i = 0; i < 18; ++i) {
uint32_t pack = 0;
for(int j = 0; j < 4; ++j)
pack = (pack << 8) | key[(i * 4 + j) % key.length()];
this->parr[i] ^= pack;
}
for(int i = 0; i < 18; i += 2) {
}
}
std::string sosc::cgc::Blowfish::Encrypt(std::string data) const {
size_t pad_length = data.size() % sizeof(uint64_t);
int pad_length = data.length() % sizeof(uint64_t);
pad_length = sizeof(uint64_t) - pad_length;
for(size_t i = 0; i < pad_length; ++i)
for(int i = 0; i < pad_length; ++i)
data.push_back(0);
for(int i = 0; i < data.size() / sizeof(uint64_t); ++i) {
uint32_t* left = &(((uint32_t*)data.data())[i * 2]);
uint32_t* right = &(((uint32_t*)data.data())[i * 2 + 1]);
for(std::string::size_type i = 0; i < data.size(); i += 8) {
uint32_t left, right;
EncryptBlock(left, right);
pack_bytes(data, i, left, right);
this->EncryptBlock(&left, &right);
unpack_bytes(data, i, left, right);
}
return data;
}
std::string sosc::cgc::Blowfish::Decrypt(std::string data) const {
if(data.length() % sizeof(uint64_t) != 0)
return "";
for(std::string::size_type i = 0; i < data.size(); i += 8) {
uint32_t left, right;
pack_bytes(data, i, left, right);
this->DecryptBlock(&left, &right);
unpack_bytes(data, i, left, right);
}
int i = 0;
for(;; i++)
if(data[data.length() - i - 1] != 0)
break;
data.resize(data.length() - i);
return data;
}
void sosc::cgc::Blowfish::EncryptBlock
(uint32_t* left, uint32_t* right) const
{
uint32_t left_t = *left,
right_t = *right;
for(int i = 0; i < 16; ++i) {
left_t ^= this->parr[i];
right_t ^= this->Feistel(left_t);
swap(left_t, right_t);
}
swap(left_t, right_t);
right_t ^= this->parr[16];
left_t ^= this->parr[17];
*left = left_t;
*right = right_t;
}
void sosc::cgc::Blowfish::DecryptBlock
(uint32_t* left, uint32_t* right) const
{
uint32_t left_t = *left,
right_t = *right;
for(int i = 17; i > 1; --i) {
left_t ^= this->parr[i];
right_t ^= this->Feistel(left_t);
swap(left_t, right_t);
}
swap(left_t, right_t);
right_t ^= this->parr[1];
left_t ^= this->parr[0];
*left = left_t;
*right = right_t;
}
uint32_t sosc::cgc::Blowfish::Feistel(uint32_t input) const {

View file

@ -3,6 +3,7 @@
#include <string>
#include <cstring>
#include "bcrypt.hpp"
namespace sosc {
namespace cgc {
@ -11,9 +12,11 @@ public:
Blowfish(const std::string& key);
std::string Encrypt(std::string data) const;
std::string Decrypt(const std::string& data) const;
std::string Decrypt(std::string data) const;
private:
Blowfish();
void SetKey(const char* key, size_t length);
void SetEksKey(const std::string& data, const std::string& key);
void EncryptBlock(uint32_t* left, uint32_t* right) const;
void DecryptBlock(uint32_t* left, uint32_t* right) const;
@ -21,6 +24,8 @@ private:
uint32_t parr[18];
uint32_t sbox[4][256];
friend std::string sosc::cgc::bcrypt_hash(const std::string&);
};
}}

View file

@ -7,6 +7,8 @@
#include "sock/tcpsock.hpp"
#include "crypto/sha1.hpp"
#include "crypto/base64.hpp"
#include "crypto/bfish.hpp"
#include "utils/csprng.hpp"
int main(int argc, char **argv) {
//auto sock = sosc::TcpClient();
@ -32,5 +34,12 @@ int main(int argc, char **argv) {
//std::string a = sosc::cgc::sha1("test", true);
sosc::cgc::Blowfish fish("");
std::string test = fish.Encrypt("imagine a test");
std::string testd = fish.Decrypt(test);
uint32_t teest = sosc::csprng::next<uint32_t>();
return 0;
}

View file

@ -0,0 +1,58 @@
#include "csprng.hpp"
#ifdef _WIN32
// TODO update win32 code to use csprng in advapi32.lib
// NOTE RUNNING ON WINDOWS IS INSECURE DO NOT DOD !!!
#include <ctime>
static struct __rng_ctx {
std::default_random_engine rng;
std::mutex rng_mtx;
__rng_ctx() : rng(time(NULL)) { }
} _rng_ctx;
std::string sosc::csprng::next_bytes(std::string::size_type count) {
_rng_ctx.rng_mtx.lock();
std::string rand_bytes;
for(std::string::size_type i = 0; i < count; ++i)
rand_bytes += (char)_rng_ctx.rng();
_rng_ctx.rng_mtx.unlock();
return rand_bytes;
}
#else
static struct __rng_ctx {
std::ifstream urand;
std::mutex rng_mtx;
__rng_ctx() {
this->urand.open("/dev/urandom",
std::ifstream::in | std::ifstream::binary);
if(!this->urand.good())
throw "Could not establish csprng context.";
}
~__rng_ctx() {
this->urand.close();
}
} _rng_ctx;
std::string sosc::csprng::next_bytes(std::string::size_type count) {
_rng_ctx.rng_mtx.lock();
char* buffer = new char[count];
_rng_ctx.urand.read(buffer, count);
std::string rand_bytes(buffer, count);
delete[] buffer;
_rng_ctx.rng_mtx.unlock();
return rand_bytes;
}
#endif

View file

@ -0,0 +1,19 @@
#ifndef SOSC_UTIL_CSPRNG_H
#define SOSC_UTIL_CSPRNG_H
#include <fstream>
#include <string>
#include <mutex>
#include <random>
namespace sosc {
namespace csprng {
std::string next_bytes(std::string::size_type count);
template<typename T>
T next() {
return *((T*)(next_bytes(sizeof(T)).c_str()));
}
}}
#endif