QuickLogic standalone cryptographic library and CLI for protecting FPGA
device-data IP at rest. Provides authenticated AES-256-GCM file encryption
in a versioned .en container format, a hardened key database, and a
command-line tool. Consumed by FOEDAG and VTR/VPR as a git submodule.
Pre-1.0. API and .en format are stable for the v2 specification but
public API may receive non-breaking additions before v1.0.0 is tagged.
See CHANGELOG.md for release history and docs/ARCHITECTURE.md for the internal design.
- AES-256-GCM authenticated encryption with per-file random nonces (NIST SP 800-38D compliant).
- Versioned
.encontainer — self-describing 27-byte header (magic, version, cipher, nonce, plaintext length). - Backward-compatible v1 decryption for legacy FOEDAG packages.
- Decryption cache (
Processor) — every distinct file decrypts at most once per process lifetime; satisfies the "decrypt once per run" invariant required by VPR. - Key fingerprinting (8-byte SHA-256 prefix) for per-customer leak attribution.
- Secure memory hygiene —
SecByteBlockfor keys,SecureWipeBufferfor plaintext caches, optionalmlock/madvise(MADV_DONTDUMP)/VirtualLockon supported platforms. - CLI tool (
qlcrypt) with git-style subcommands:keygen,encrypt,decrypt,inspect,verify,fingerprint,rotate.
- CMake ≥ 3.15
- C++17 compiler: GCC ≥ 9, Clang ≥ 10, MSVC ≥ 2019
- Crypto++ ≥ 8.7.0 (system package or vendored)
- cereal 1.3.x (vendored via FetchContent by default)
- CLI11 2.4.x (vendored single-header)
- GoogleTest 1.14.x (FetchContent, test build only)
On Ubuntu / Debian:
sudo apt install cmake g++ libcrypto++-dev libcrypto++-utils pkg-configOn macOS:
brew install cmake cryptopp pkg-configgit clone https://github.com/QuickLogic-Corp/qlcrypt.git
cd qlcrypt
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc 2>/dev/null || sysctl -n hw.ncpu)
ctest --test-dir build --output-on-failure| Option | Default | Purpose |
|---|---|---|
QLCRYPT_BUILD_TESTS |
ON standalone, OFF via add_subdirectory |
Build unit + integration tests |
QLCRYPT_BUILD_TOOL |
ON standalone, OFF via add_subdirectory |
Build qlcrypt CLI binary |
QLCRYPT_BUILD_BENCH |
OFF |
Build Google Benchmark suite |
QLCRYPT_BUILD_FUZZ |
OFF |
Build libFuzzer harnesses (requires Clang) |
QLCRYPT_ENABLE_ASAN |
OFF |
Address sanitizer |
QLCRYPT_ENABLE_UBSAN |
OFF |
UB sanitizer |
QLCRYPT_ENABLE_MSAN |
OFF |
Memory sanitizer (Clang only) |
QLCRYPT_ENABLE_COVERAGE |
OFF |
lcov / gcov instrumentation |
QLCRYPT_WARNINGS_AS_ERRORS |
OFF (CI: ON) |
Treat warnings as errors |
add_subdirectory(third_party/qlcrypt)
target_link_libraries(my_target PRIVATE qlcrypt::qlcrypt)find_package(qlcrypt 0.1 REQUIRED)
target_link_libraries(my_target PRIVATE qlcrypt::qlcrypt)#include <qlcrypt/qlcrypt.hpp>
#include <iostream>
int main() {
qlcrypt::KeyDB key_db;
if (auto s = qlcrypt::KeyDB::load("device/_Supp.db", key_db); !qlcrypt::ok(s)) {
std::cerr << "Load failed: " << qlcrypt::toString(s) << '\n';
return 1;
}
qlcrypt::Processor processor(std::move(key_db));
std::string_view yaml_view;
if (auto s = processor.decryptFile("device/SB_MAPS.yml.en", yaml_view); !qlcrypt::ok(s)) {
std::cerr << "Decrypt failed: " << qlcrypt::toString(s) << '\n';
return 1;
}
// yaml_view is valid for the lifetime of `processor`.
// The same call again will hit the cache (no re-decrypt).
}# Create a key database (with optional customer tag)
qlcrypt keygen --out device/_Supp.db --customer-id ACME-001
# Encrypt a file
qlcrypt encrypt --key-db device/_Supp.db \
--in device/SB_MAPS.yml --out device/SB_MAPS.yml.en
# Encrypt a directory in place (matching pattern)
qlcrypt encrypt --key-db device/_Supp.db \
--in device/CSV --in-place --include '*.csv'
# Decrypt to stdout
qlcrypt decrypt --key-db device/_Supp.db --in device/SB_MAPS.yml.en
# Inspect header (no key required)
qlcrypt inspect device/SB_MAPS.yml.en --format json
# Verify integrity (auth tag check, no plaintext written)
qlcrypt verify --key-db device/_Supp.db --in device/SB_MAPS.yml.en
# Print key fingerprint
qlcrypt fingerprint device/_Supp.db
# Rotate keys across a directory
qlcrypt rotate --old-key-db old/_Supp.db --new-key-db new/_Supp.db --dir deviceSee docs/CLI.md and man qlcrypt for the full reference.
- docs/ARCHITECTURE.md — internal design
- docs/FILE_FORMAT.md —
.env2 specification (canonical) - docs/API.md — public API reference
- docs/CLI.md — CLI reference
- docs/SECURITY.md — threat model and disclosure policy
- docs/CONSUMER_GUIDE.md — integration guide for FOEDAG / VTR