From 842a90e02644d08ecf6d7a76a2183cef1247e42f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 29 Jan 2020 16:03:50 +0100 Subject: [PATCH] [libcalamares] Add an Entropy service for getting random data - Tries to get the "best" random data - Reports the quality of the random data it got --- src/libcalamares/CMakeLists.txt | 3 +- src/libcalamares/utils/Entropy.cpp | 75 ++++++++++++++++++++++++++++++ src/libcalamares/utils/Entropy.h | 44 ++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/libcalamares/utils/Entropy.cpp create mode 100644 src/libcalamares/utils/Entropy.h diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 8b4233659..0e7f7c6e7 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -39,7 +39,7 @@ set( libSources # Modules modulesystem/InstanceKey.cpp - + # Network service network/Manager.cpp @@ -50,6 +50,7 @@ set( libSources utils/CalamaresUtilsSystem.cpp utils/CommandList.cpp utils/Dirs.cpp + utils/Entropy.cpp utils/Logger.cpp utils/PluginFactory.cpp utils/Retranslator.cpp diff --git a/src/libcalamares/utils/Entropy.cpp b/src/libcalamares/utils/Entropy.cpp new file mode 100644 index 000000000..adba7478c --- /dev/null +++ b/src/libcalamares/utils/Entropy.cpp @@ -0,0 +1,75 @@ +/* === This file is part of Calamares - === + * + * Copyright 2019-2020, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#include "Entropy.h" + +#include + +#include + +CalamaresUtils::EntropySource +CalamaresUtils::getEntropy( int size, QByteArray& b ) +{ + b.clear(); + b.resize( size ); + char* buffer = b.data(); + std::fill( buffer, buffer + size, 0xcb ); + + int readSize = 0; + QFile urandom( "/dev/urandom" ); + if ( urandom.exists() && urandom.open( QIODevice::ReadOnly ) ) + { + readSize = urandom.read( buffer, size ); + urandom.close(); + } + + if ( readSize >= size ) + { + return EntropySource::URandom; + } + + // If it wasn't available, or did not return enough bytes, + // complete it with twister (and tell the client). + std::random_device r; + std::seed_seq seed { r(), r(), r(), r(), r(), r(), r(), r() }; + std::mt19937_64 twister( seed ); + + std::uint64_t next = 0; + + do + { + next = twister(); + // Eight times, for a 64-bit next +#define GET_ONE_BYTE \ + if ( readSize < size ) \ + { \ + buffer[ readSize++ ] = next & 0xff; \ + next = next >> 8; \ + } + GET_ONE_BYTE + GET_ONE_BYTE + GET_ONE_BYTE + GET_ONE_BYTE + GET_ONE_BYTE + GET_ONE_BYTE + GET_ONE_BYTE + GET_ONE_BYTE + } while ( readSize < size ); + + return EntropySource::Twister; +} diff --git a/src/libcalamares/utils/Entropy.h b/src/libcalamares/utils/Entropy.h new file mode 100644 index 000000000..da2236266 --- /dev/null +++ b/src/libcalamares/utils/Entropy.h @@ -0,0 +1,44 @@ +/* === This file is part of Calamares - === + * + * Copyright 2019-2020, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#ifndef UTILS_ENTROPY_H +#define UTILS_ENTROPY_H + +#include "DllMacro.h" + +#include + +namespace CalamaresUtils +{ +/// @brief Which entropy source was actually used for the entropy. +enum class EntropySource +{ + URandom, ///< Read from /dev/urandom + Twister ///< Generated by pseudo-random +}; + +/** @brief Fill buffer @p b with exactly @p size random bytes + * + * The array is cleared and resized, then filled with 0xcb + * "just in case", after which it is filled with random + * bytes from a suitable source. Returns which source was used. + */ +DLLEXPORT EntropySource getEntropy( int size, QByteArray& b ); +} // namespace CalamaresUtils + +#endif