fix(generator): incorrect copying, no protections
All checks were successful
continuous-integration/drone/push Build is passing

* use try-catch whenever possible
* perform memcpy operations in the right direction
* make greater use of local constants
* use more of the braced initializations
* there were memcpy operations of incorrect sizes in place, particularly
  in regard to generator key (G.k) and counter (G.ctr), which resulted
  in key bytes being set to garbage
This commit is contained in:
surtur 2021-12-10 20:02:30 +01:00
parent 801d605e2a
commit 595245fbce
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D

View File

@ -53,18 +53,21 @@ auto Generator::get_state() -> G_state {
}
auto Generator::reseed(const std::string& s) -> void {
// TODO(me): proper concat - WIP below
// ref: https://www.cryptopp.com/wiki/SecBlock
std::string da_key(reinterpret_cast<const char*>(&G.k[0]), G.k.size());
std::string da_key(reinterpret_cast<const char*>(&G.k[0]),
G.k.SizeInBytes() * 8); // we need the size in bits
std::string to_be_hashed{da_key+s};
// fmt::print("s -> {}\n", s); // debugging
// fmt::print("da_key -> {}\n", da_key); // debugging
// fmt::print("concat \"da_key + s\" -> {}\n", to_be_hashed); // debugging
// TODO(me): wrap do_sha in a try-catch
std::string a{do_sha(to_be_hashed)};
std::memcpy(&a[0], &G.k[0], a.size());
++G.ctr;
try {
std::string a{do_sha(to_be_hashed)};
std::memcpy(&G.k[0], &a[0], G.k.SizeInBytes());
++G.ctr;
} catch(std::exception& e) {
fmt::print("{}", e.what());
}
}
auto Generator::do_sha(const std::string& k_n_s) -> std::string {
@ -125,7 +128,7 @@ auto Generator::do_crypto() -> std::string {
// 16 bytes --> 128bit
static constexpr const std::size_t ctr_length{16};
CryptoPP::FixedSizeSecBlock<CryptoPP::byte, ctr_length> ctr;
std::memcpy(&G.ctr, &ctr, sizeof(G.ctr));
std::memcpy(&ctr, &G.ctr, ctr_length);
try {
// fmt::print("plain text: {}\n", plain);
@ -168,6 +171,15 @@ auto Generator::generate_blocks(unsigned int k_blocks) -> std::string {
r += do_crypto();
++G.ctr;
}
try {
std::string da_key{""};
da_key.resize(G.k.size());
std::memcpy(&da_key[0], &G.k[0], G.k_length);
// TODO(me): assert reseed_time > 100ms
reseed(do_sha(da_key));
} catch(std::exception& e) {
fmt::print("{}", e.what());
}
// fmt::print("r from generate_blocks -> {}\n", r); // debugging
return r;
}
@ -183,30 +195,41 @@ auto Generator::generate_random_data(uint n) -> std::string {
throw std::invalid_argument("n cannot be > 2^20");
}
/* do magic to compute r
* r rst-n-bytes(GenerateBlocks(G, ceil(n/16) )) */
// n is number of bytes, i.e. pass n*8 to get number of bits
unsigned int how_many = (int)ceil((n*8)/16);
// fmt::print("how_many: {}\n", how_many); // debugging
std::string rr{generate_blocks(how_many)};
fmt::print("rr (output from generate_blocks): {}\n", rr);
// since we're truncating hex, we need to get twice more characters
std::string r{rr.substr(0,n*2)};
rr.erase();
std::string r;
try {
/* do magic to compute r
* r rst-n-bytes(GenerateBlocks(G, ceil(n/16) )) */
// n is number of bytes, i.e. pass n*8 to get number of bits
unsigned int how_many(static_cast<unsigned int>(ceil((n*8)/16)));
// fmt::print("how_many: {}\n", how_many); // debugging
std::string rr{generate_blocks(how_many)};
fmt::print("rr (output from generate_blocks): {}\n", rr);
// since we're truncating hex, we need to get twice more characters
r = rr.substr(0,n*2);
rr.erase();
} catch(std::exception& e) {
fmt::print("{}", e.what());
}
/* re-key */
std::string nu_G_k{generate_blocks(2)};
// fmt::print("nu_G_k: {}\n", nu_G_k); // debugging
std::string dst;
CryptoPP::StringSource str_s(
nu_G_k,true,new CryptoPP::HexDecoder(new CryptoPP::StringSink(dst))
);
try {
std::string nu_G_k{generate_blocks(2)};
// fmt::print("nu_G_k: {}\n", nu_G_k); // debugging
std::string dst;
CryptoPP::StringSource str_s(
nu_G_k,true,new CryptoPP::HexDecoder(new CryptoPP::StringSink(dst))
);
nu_G_k.erase();
nu_G_k.erase();
/* clear out the old key and set a new one */
std::memset(G.k, 0x00, G.k.size());
std::memcpy(&dst[0], &G.k[0], dst.size());
/* clear out the old key and set a new one */
std::memset(G.k, 0x00, G.k.size());
std::memcpy(&G.k[0], &dst[0], dst.size());
} catch(std::exception& e) {
fmt::print("{}", e.what());
}
return r;
};