diff --git a/compilers/concrete-compiler/compiler/CMakeLists.txt b/compilers/concrete-compiler/compiler/CMakeLists.txt index f66a7b172..cd23527e8 100644 --- a/compilers/concrete-compiler/compiler/CMakeLists.txt +++ b/compilers/concrete-compiler/compiler/CMakeLists.txt @@ -190,6 +190,27 @@ endif() # Unit tests # ------------------------------------------------------------------------------- option(CONCRETELANG_UNIT_TESTS "Enables the build of unittests" ON) +option( + CONCRETELANG_UNSECURE_DEBUG + "Totally unsecure mode where secret keys are filled with zeros. Useful to reveal the body of the ciphertexts when using tracing during debug." + OFF) +if(CONCRETELANG_UNSECURE_DEBUG) + message( + WARNING + " + ############################################################################# + ## ## + ## !!! WARNING !!! ## + ## ## + ## CONCRETELANG_UNSECURE_DEBUG option activated ! This means that the ## + ## secret keys generated will provide ZERO security. This should only be ## + ## used for debugging purpose, and NEVER in a production environment. ## + ## ## + ############################################################################# + ") + add_compile_definitions(CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS) + add_compile_definitions(CONCRETELANG_TEST_KEYCACHE_PATH="UnsecureKeySetCache") +endif() # ------------------------------------------------------------------------------- # Benchmarks diff --git a/compilers/concrete-compiler/compiler/lib/ClientLib/EvaluationKeys.cpp b/compilers/concrete-compiler/compiler/lib/ClientLib/EvaluationKeys.cpp index 84ed9f1ce..d985c0eed 100644 --- a/compilers/concrete-compiler/compiler/lib/ClientLib/EvaluationKeys.cpp +++ b/compilers/concrete-compiler/compiler/lib/ClientLib/EvaluationKeys.cpp @@ -7,6 +7,18 @@ #include "concrete-cpu.h" #include "concretelang/ClientLib/ClientParameters.h" +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS +inline void getApproval() { + std::cerr << "DANGER: You are generating an empty unsecure secret keys. " + "Enter \"y\" to continue: "; + char answer; + std::cin >> answer; + if (answer != 'y') { + std::abort(); + } +} +#endif + namespace concretelang { namespace clientlib { @@ -52,9 +64,17 @@ LweSecretKey::LweSecretKey(LweSecretKeyParam ¶meters, CSPRNG &csprng) // Allocate the buffer _buffer = std::make_shared>(); _buffer->resize(parameters.dimension); +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + // In insecure debug mode, the secret key is filled with zeros. + getApproval(); + for (uint64_t &val : *_buffer) { + val = 0; + } +#else // Initialize the lwe secret key buffer concrete_cpu_init_secret_key_u64(_buffer->data(), parameters.dimension, csprng.ptr, csprng.vtable); +#endif } void LweSecretKey::encrypt(uint64_t *ciphertext, uint64_t plaintext, diff --git a/compilers/concrete-compiler/compiler/lib/ClientLib/KeySetCache.cpp b/compilers/concrete-compiler/compiler/lib/ClientLib/KeySetCache.cpp index 211c61090..950038705 100644 --- a/compilers/concrete-compiler/compiler/lib/ClientLib/KeySetCache.cpp +++ b/compilers/concrete-compiler/compiler/lib/ClientLib/KeySetCache.cpp @@ -18,6 +18,18 @@ #include #include +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS +inline void getApproval() { + std::cerr << "DANGER: You are using an empty unsecure secret keys. Enter " + "\"y\" to continue: "; + char answer; + std::cin >> answer; + if (answer != 'y') { + std::abort(); + } +} +#endif + namespace concretelang { namespace clientlib { @@ -26,6 +38,10 @@ using StringError = concretelang::error::StringError; template outcome::checked loadKey(llvm::SmallString<0> &path, Key(deser)(std::istream &istream)) { + +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + getApproval(); +#endif std::ifstream in((std::string)path, std::ofstream::binary); if (in.fail()) { return StringError("Cannot access " + (std::string)path); @@ -40,6 +56,9 @@ outcome::checked loadKey(llvm::SmallString<0> &path, template outcome::checked saveKey(llvm::SmallString<0> &path, Key key) { +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + getApproval(); +#endif std::ofstream out((std::string)path, std::ofstream::binary); if (out.fail()) { return StringError("Cannot access " + (std::string)path); @@ -55,6 +74,9 @@ outcome::checked saveKey(llvm::SmallString<0> &path, outcome::checked, StringError> KeySetCache::loadKeys(ClientParameters ¶ms, uint64_t seed_msb, uint64_t seed_lsb, std::string folderPath) { +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + getApproval(); +#endif // Mark the folder as recently use. // e.g. so the CI can do some cleanup of unused keys. @@ -117,6 +139,10 @@ KeySetCache::loadKeys(ClientParameters ¶ms, uint64_t seed_msb, outcome::checked saveKeys(KeySet &key_set, llvm::SmallString<0> &folderPath) { +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + getApproval(); +#endif + llvm::SmallString<0> folderIncompletePath = folderPath; folderIncompletePath.append(".incomplete"); @@ -168,6 +194,10 @@ outcome::checked, StringError> KeySetCache::loadOrGenerateSave(ClientParameters ¶ms, uint64_t seed_msb, uint64_t seed_lsb) { +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + getApproval(); +#endif + llvm::SmallString<0> folderPath = llvm::SmallString<0>(this->backingDirectoryPath); @@ -235,6 +265,10 @@ outcome::checked, StringError> KeySetCache::generate(std::shared_ptr cache, ClientParameters ¶ms, uint64_t seed_msb, uint64_t seed_lsb) { +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + getApproval(); +#endif + __uint128_t seed = seed_msb; seed <<= 64; seed += seed_lsb; @@ -247,6 +281,10 @@ KeySetCache::generate(std::shared_ptr cache, outcome::checked, StringError> KeySetCache::generate(ClientParameters ¶ms, uint64_t seed_msb, uint64_t seed_lsb) { +#ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS + getApproval(); +#endif + return loadOrGenerateSave(params, seed_msb, seed_lsb); } diff --git a/compilers/concrete-compiler/compiler/tests/tests_tools/keySetCache.h b/compilers/concrete-compiler/compiler/tests/tests_tools/keySetCache.h index 82a8cdc88..459f886d1 100644 --- a/compilers/concrete-compiler/compiler/tests/tests_tools/keySetCache.h +++ b/compilers/concrete-compiler/compiler/tests/tests_tools/keySetCache.h @@ -1,16 +1,21 @@ #ifndef TEST_TOOLS_KEYSETCACHE_H #define TEST_TOOLS_KEYSETCACHE_H +#include "concretelang/ClientLib/KeySetCache.h" #include "llvm/Support/Path.h" -#include "concretelang/ClientLib/KeySetCache.h" +#ifdef CONCRETELANG_TEST_KEYCACHE_PATH +#define CACHE_PATH CONCRETELANG_TEST_KEYCACHE_PATH +#else +#define CACHE_PATH "KeySetCache" +#endif static inline std::optional getTestKeySetCache() { llvm::SmallString<0> cachePath; llvm::sys::path::system_temp_directory(true, cachePath); - llvm::sys::path::append(cachePath, "KeySetCache"); + llvm::sys::path::append(cachePath, CACHE_PATH); auto cachePathStr = std::string(cachePath);