summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorx1b6e62020-09-02 19:38:04 +0700
committerx1b6e62020-09-02 20:12:14 +0700
commitb734c8b6bc3b8688810b2a64958026aad2611f7b (patch)
treeec6d2dae3fd69a8ee91a6263a9d45b9eae36d934
downloadaur-b734c8b6bc3b8688810b2a64958026aad2611f7b.tar.gz
Initial commit
Signed-off-by: x1b6e6 <ftdabcde@gmail.com>
-rw-r--r--.SRCINFO19
-rw-r--r--.gitignore6
-rw-r--r--CMakeLists.txt7
-rw-r--r--PKGBUILD34
-rw-r--r--aes.cc162
5 files changed, 228 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..7f8137e8824d
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,19 @@
+pkgbase = aes
+ pkgdesc = encryption utility with very simple interface
+ pkgver = 0.1.0
+ pkgrel = 1
+ url = https://github.com/x1b6e6/aes.git
+ arch = any
+ license = MIT
+ makedepends = gcc
+ makedepends = make
+ makedepends = cmake
+ depends = libgcrypt
+ depends = docopt
+ source = CMakeLists.txt
+ source = aes.cc
+ sha1sums = 4c656edb9888276841ab1849084b5beeb7221f7a
+ sha1sums = 6ab800f3769b1fcc393be977ba6eb32e750045cf
+
+pkgname = aes
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..1686ec54f0a2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+build
+*.aes
+src
+pkg
+*.tar.xz
+*.tar.zst
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000000..b07e9e9e51f3
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.15)
+project(aes VERSION 0.1.0 LANGUAGES CXX)
+
+add_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}")
+
+add_executable(aes aes.cc)
+target_link_libraries(aes gcrypt docopt)
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..dbe962f2253c
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,34 @@
+# Maintainer: x1b6e6 <ftdabcde@gmail.com>
+
+pkgname=aes
+pkgver=0.1.0
+pkgrel=1
+pkgdesc="encryption utility with very simple interface"
+arch=('any')
+url="https://github.com/x1b6e6/aes.git"
+license=("MIT")
+depends=("libgcrypt" "docopt")
+makedepends=("gcc" "make" "cmake")
+
+source=(
+ "CMakeLists.txt"
+ "aes.cc"
+)
+
+sha1sums=(
+ "4c656edb9888276841ab1849084b5beeb7221f7a"
+ "6ab800f3769b1fcc393be977ba6eb32e750045cf"
+)
+
+build(){
+ cd $srcdir
+ cmake -Bbuild -G "Unix Makefiles"
+ cmake --build build --target all
+}
+
+package() {
+ cd "$srcdir"
+ install -Dm755 "$srcdir/build/aes" "$pkgdir/usr/bin/aes"
+}
+
+# vim: set ts=4 sw=4 :
diff --git a/aes.cc b/aes.cc
new file mode 100644
index 000000000000..009cd0fd2853
--- /dev/null
+++ b/aes.cc
@@ -0,0 +1,162 @@
+#include <docopt/docopt.h>
+#include <docopt/docopt_value.h>
+#include <fcntl.h>
+#include <gcrypt.h>
+#include <termios.h>
+#include <unistd.h>
+#include <cstring>
+#include <iostream>
+#include <memory>
+#include <stdexcept>
+
+#ifndef PROJECT_VERSION
+#warning Use hardcoded version
+#define PROJECT_VERSION "0.1.0"
+#endif
+
+auto get_version() {
+ /* TODO */
+ return "aes v" PROJECT_VERSION;
+}
+
+auto get_usage() {
+ /* TODO */
+ return get_version() + std::string(R"(
+
+Usage:
+ aes [options]
+
+Options:
+ -d, --decrypt decrypt data
+ -p, --password=PASSWORD use password [default: prompt]
+ -k, --key=KEY use key instead password [default: ]
+ -l, --last=LAST size of last block [default: 0]
+ -b, --bits=BITS use aes with specified bits [default: 256]
+)");
+}
+
+gcry_error_t proccess_encrypt(gcry_cipher_hd_t hd,
+ const char* block_in,
+ char* block_out) {
+ return gcry_cipher_encrypt(hd, block_out, 16, block_in, 16);
+}
+
+gcry_error_t proccess_decrypt(gcry_cipher_hd_t hd,
+ const char* block_in,
+ char* block_out) {
+ return gcry_cipher_decrypt(hd, block_out, 16, block_in, 16);
+}
+
+void try_gcry(gcry_error_t err) {
+ auto code = gcry_err_code(err);
+
+ if (code != 0) {
+ throw std::runtime_error((const char*)gcry_err_source(err));
+ }
+}
+
+int main(int argc, const char** argv) {
+ auto args = docopt::docopt(get_usage(), {argv + 1, argv + argc}, true,
+ get_version());
+
+ auto decrypt = args.at("--decrypt").asBool();
+ auto password = args.at("--password").asString();
+ auto key = args.at("--key").asString();
+ auto bits = args.at("--bits").asLong();
+ auto last = args.at("--last").asLong();
+ try {
+ if (password != "prompt" && key != "") {
+ throw std::invalid_argument(
+ "using --password and --key at some time is imposible.");
+ }
+
+ if (last > 15 || last < 0) {
+ throw std::invalid_argument("--last should be between 0 and 15.");
+ }
+
+ if (bits != 256 && bits != 128) {
+ throw std::invalid_argument("--bits should be 128 or 256.");
+ }
+
+ if (key.size() != 0 && key.size() != (bits >> 1)) {
+ throw std::invalid_argument("--key size should be equal BITS/2");
+ }
+
+ if (decrypt == false && last != 0) {
+ std::cerr << "Note: using --last possible only with --decrypt\n";
+ }
+ } catch (const std::invalid_argument& e) {
+ std::cerr << e.what() << '\n';
+ return 1;
+ }
+
+ size_t key_size = bits >> 2;
+ std::unique_ptr<char[]> key_arr(new char[key_size]);
+
+ if (key == "") {
+ if (password == "prompt") {
+ password = getpass("Enter password:");
+ }
+ gcry_md_hd_t md_handle;
+ try_gcry(gcry_md_open(&md_handle, GCRY_MD_SHA512, 0));
+
+ gcry_md_write(md_handle, password.data(), password.size());
+
+ std::memcpy(key_arr.get(), gcry_md_read(md_handle, GCRY_MD_SHA512),
+ key_size);
+
+ gcry_md_close(md_handle);
+ } else {
+ for (size_t i = 0; i < key_size; ++i) {
+ char buf[3]{0, 0, 0};
+
+ buf[0] = key[(i << 1) + 0];
+ buf[1] = key[(i << 1) + 1];
+ buf[2] = 0;
+
+ key_arr[i] = std::strtol(buf, nullptr, 16);
+ }
+ }
+
+ int algo = GCRY_CIPHER_AES256;
+ if (bits == 128) {
+ algo = GCRY_CIPHER_AES128;
+ }
+
+ gcry_cipher_hd_t hd;
+ try_gcry(gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_XTS, 0));
+ try_gcry(gcry_cipher_setkey(hd, key_arr.get(), key_size));
+
+ auto proccess = decrypt ? proccess_decrypt : proccess_encrypt;
+
+ while (std::cin.good()) {
+ char block_in[16];
+ char block_out[16];
+
+ std::cin.read(block_in, 16);
+ size_t readed = std::cin.gcount();
+
+ if (readed == 0)
+ break;
+
+ if (readed != 16) {
+ std::cerr << "last block size: " << readed << '\n';
+ std::memset(block_in + readed, 0, 16 - readed);
+ }
+
+ try_gcry(proccess(hd, block_in, block_out));
+
+ if (std::cin.peek() == EOF) {
+ if (last != 0) {
+ std::cout.write(block_out, last);
+ break;
+ }
+ }
+
+ std::cout.write(block_out, 16);
+ }
+
+ gcry_cipher_close(hd);
+
+ return 0;
+}