diff --git a/PKGBUILD_amd64 b/PKGBUILD_amd64 new file mode 100644 index 0000000..50228e7 --- /dev/null +++ b/PKGBUILD_amd64 @@ -0,0 +1,20 @@ +pkgname=passman +pkgver=1.0.0 +pkgrel=1 +pkgdesc="A Simple Password Manager with AES-256 Encryption" +arch=('x86_64') +license=('GPLv3') + +build() { + qmake .. + make +} + +package() { + mkdir -p $pkgdir/usr/bin + mkdir -p $pkgdir/usr/share/applications + mkdir -p $pkgdir/opt/aslan/icons + cp passman $pkgdir/usr/bin/passman + cp ../passman.desktop $pkgdir/usr/share/applications/passman.desktop + cp ../passman_icon.svg $pkgdir/opt/aslan/icons/passman_icon.svg +} diff --git a/PKGBUILD_arm64 b/PKGBUILD_arm64 new file mode 100644 index 0000000..298c832 --- /dev/null +++ b/PKGBUILD_arm64 @@ -0,0 +1,20 @@ +pkgname=passman +pkgver=1.0.0 +pkgrel=1 +pkgdesc="A Simple Password Manager with AES-256 Encryption" +arch=('aarch64') +license=('GPLv3') + +build() { + qmake .. + make +} + +package() { + mkdir -p $pkgdir/usr/bin + mkdir -p $pkgdir/usr/share/applications + mkdir -p $pkgdir/opt/aslan/icons + cp passman $pkgdir/usr/bin/passman + cp ../passman.desktop $pkgdir/usr/share/applications/passman.desktop + cp ../passman_icon.svg $pkgdir/opt/aslan/icons/passman_icon.svg +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..bbcf262 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# AsloEngine +A Simple Password Manager with AES-256 Encryption + +Version 1.0.0 + + +## How To Compile + +### Debian Linux: +Run **makedebpkg.sh** script with parameter (arm64/amd64) +This will make .deb package + +Example: **makedebpkg.sh amd64** + +### Arch Linux: +Run **makearchpkg.sh** script with parameter (arm64/amd64) +This will make .tar.xz package + +Example: **makearchpkg.sh amd64** + +### Windows: +Use QT Creator + +### Mac OS: +Use QT Creator diff --git a/control_amd64 b/control_amd64 new file mode 100644 index 0000000..0cb2d47 --- /dev/null +++ b/control_amd64 @@ -0,0 +1,9 @@ +Package: passman +Version: 1.0.0 +Section: utils +Priority: optional +Architecture: amd64 +Essential: no +Installed-Size: 132 +Maintainer: Aslan2142 +Description: A Simple Password Manager with AES-256 Encryption diff --git a/control_arm64 b/control_arm64 new file mode 100644 index 0000000..9dd9221 --- /dev/null +++ b/control_arm64 @@ -0,0 +1,9 @@ +Package: passman +Version: 1.0.0 +Section: utils +Priority: optional +Architecture: arm64 +Essential: no +Installed-Size: 132 +Maintainer: Aslan2142 +Description: A Simple Password Manager with AES-256 Encryption diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..66b54ac --- /dev/null +++ b/main.cpp @@ -0,0 +1,103 @@ +#include +#include +#include "mainwindow.h" +#include "passman.h" +#include "parameterparser.h" + +int main(int argc, char *argv[]) +{ + QString version = "1.0.0"; + + if (argc == 1) + { + QApplication a(argc, argv); + MainWindow w(version); + w.show(); + w.check_database(); + + return a.exec(); + } + + + + //Logic for CLI + + parameterparser parameter_parser(argc, argv); + passman password_manager; + + std::string password = parameter_parser.get_value("pass", 'p'); + if (password.compare("-") == 0) + { + std::cin >> password; + } + password_manager.key = QString::fromStdString(password); + + if (parameter_parser.has_parameter("create-database", 'd')) + { + if (password_manager.database_exists()) + { + std::cerr << "Error Creating Database (database already exists)" << std::endl; + return 4; + } + + if (password.length() > 0) + { + password_manager.encrypt(); + password_manager.save(); + } else { + std::cerr << "Error Creating Database (blank password)" << std::endl; + return 3; + } + } + + if (!password_manager.load()) + { + std::cerr << "Error Loading Database" << std::endl; + return 1; + } + if (!password_manager.decrypt()) + { + std::cerr << "Error Decrypting Database" << std::endl; + return 2; + } + + std::string new_entry = parameter_parser.get_value("new", 'n'); + if (new_entry.compare("-") != 0) + { + QStringList entry = QString::fromStdString(new_entry).split(","); + + password_manager.add_entry(entry[0], entry[1], entry[2], entry[3]); + password_manager.encrypt(); + password_manager.save(); + } + + if (parameter_parser.has_parameter("backup", 'b')) + { + password_manager.backup(); + } + + if (parameter_parser.has_parameter("show-all", 'a')) + { + const std::vector> database = password_manager.get_database_copy(); + for (const std::array& entry : database) + { + std::cout << "|| " << entry[0].toStdString() << " | " << entry[1].toStdString() << " | " << entry[2].toStdString() << " | " << entry[3].toStdString() << " ||" << std::endl; + } + } + + std::string show_website = parameter_parser.get_value("show", 's'); + if (show_website.compare("-") != 0) + { + const std::vector> database = password_manager.get_database_copy(); + for (const std::array& entry : database) + { + if (entry[0].toStdString().compare(show_website) != 0) + { + continue; + } + std::cout << "|| " << entry[0].toStdString() << " | " << entry[1].toStdString() << " | " << entry[2].toStdString() << " | " << entry[3].toStdString() << " ||" << std::endl; + } + } + + return 0; +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..68f95cd --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,257 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QString version, QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + setWindowTitle("PassMan v" + version); + + connect(ui->pushButtonUnlock, SIGNAL(clicked()), this, SLOT(decrypt_database())); + connect(ui->pushButtonBackup, SIGNAL(clicked()), this, SLOT(backup_database())); + connect(ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(save_database())); + connect(ui->pushButtonAddEntry, SIGNAL(clicked()), this, SLOT(add_entry())); + connect(ui->pushButtonRemoveEntry, SIGNAL(clicked()), this, SLOT(remove_entry())); + connect(ui->pushButtonGeneratePassword, SIGNAL(clicked()), this, SLOT(generate_password())); + connect(ui->lineEditSearch, SIGNAL(textChanged(QString)), this, SLOT(search(QString))); + + ui->lineEditEncryptionKey->setFocus(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::decrypt_database() +{ + //Load and Decrypt Database + password_manager.key = ui->lineEditEncryptionKey->text(); + + if (!password_manager.load()) + { + ui->labelDatabaseInfo->setText("Database could not be Loaded"); + ui->labelEncryptionInfo->setText(""); + return; + } + if (!password_manager.decrypt()) + { + ui->labelDatabaseInfo->setText("Database Loaded"); + ui->labelEncryptionInfo->setText("Database could not be Decrypted"); + return; + } + + ui->labelDatabaseInfo->setText("Database Loaded"); + ui->labelEncryptionInfo->setText("Database Decrypted"); + + //Fill up the Table + std::vector> database = password_manager.get_database_copy(); + + ui->tableWidgetCredentials->clear(); + ui->tableWidgetCredentials->setRowCount(static_cast(database.size())); + ui->tableWidgetCredentials->setColumnCount(4); + + for (ulong i = 0; i < database.size(); i++) + { + for (ulong j = 0; j < database[i].size(); j++) + { + ui->tableWidgetCredentials->setItem(static_cast(i), static_cast(j), new QTableWidgetItem(database[i][j])); + } + } + + saved = true; + + //Enable/Disable UI Elements + ui->pushButtonUnlock->setEnabled(false); + ui->lineEditEncryptionKey->setEnabled(false); + + ui->pushButtonBackup->setEnabled(true); + ui->pushButtonSave->setEnabled(true); + ui->pushButtonAddEntry->setEnabled(true); + ui->pushButtonRemoveEntry->setEnabled(true); + ui->pushButtonGeneratePassword->setEnabled(true); + ui->spinBoxPasswordLength->setEnabled(true); + ui->lineEditSearch->setEnabled(true); + ui->tableWidgetCredentials->setEnabled(true); + + ui->tableWidgetCredentials->setHorizontalHeaderLabels({"Website", "Username", "Password", "Note"}); + ui->tableWidgetCredentials->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); +} + +void MainWindow::backup_database() +{ + if (password_manager.backup()) + { + ui->labelDatabaseInfo->setText("Database Backup Complete"); + } else { + ui->labelDatabaseInfo->setText("Database could not be Backed Up"); + } +} + +void MainWindow::save_database() +{ + password_manager.clear_database(); + + std::array tmp_row; + for (int i = 0; i < ui->tableWidgetCredentials->rowCount(); i++) + { + for (int j = 0; j < 4; j++) + { + tmp_row[static_cast(j)] = ui->tableWidgetCredentials->item(i, j)->text(); + } + password_manager.add_entry(tmp_row[0], tmp_row[1], tmp_row[2], tmp_row[3]); + } + + password_manager.encrypt(); + password_manager.save(); + + saved = true; +} + +void MainWindow::add_entry() +{ + int row_count = ui->tableWidgetCredentials->rowCount(); + + ui->tableWidgetCredentials->insertRow(row_count); + ui->tableWidgetCredentials->scrollToItem(ui->tableWidgetCredentials->takeItem(row_count, 0)); + + ui->tableWidgetCredentials->setItem(row_count, 0, new QTableWidgetItem("")); + ui->tableWidgetCredentials->setItem(row_count, 1, new QTableWidgetItem("")); + ui->tableWidgetCredentials->setItem(row_count, 2, new QTableWidgetItem(password_manager.generate_password(password_length))); + ui->tableWidgetCredentials->setItem(row_count, 3, new QTableWidgetItem("")); + + saved = false; +} + +void MainWindow::remove_entry() +{ + QList selected = ui->tableWidgetCredentials->selectedItems(); + + saved = selected.size() <= 0; + + for (QTableWidgetItem* item : selected) + { + ui->tableWidgetCredentials->removeRow(item->row()); + } +} + +void MainWindow::generate_password() +{ + QList selected = ui->tableWidgetCredentials->selectedItems(); + + saved = selected.size() <= 0; + + for (QTableWidgetItem* item : selected) + { + std::array entry = password_manager.get_entry_copy(item->row()); + ui->tableWidgetCredentials->setItem(item->row(), 2, new QTableWidgetItem(password_manager.generate_password(password_length))); + } +} + +void MainWindow::search(const QString &input) +{ + //Show all rows + for (int i = 0; i < ui->tableWidgetCredentials->rowCount(); i++) + { + ui->tableWidgetCredentials->showRow(i); + } + + //End if not searching + if (input.size() == 0) + { + return; + } + + //Hide rows that don't contain searched text + for (int i = 0; i < ui->tableWidgetCredentials->rowCount(); i++) + { + if (!ui->tableWidgetCredentials->item(i, 0)->text().contains(input)) + { + ui->tableWidgetCredentials->hideRow(i); + } + } +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + if (saved) + { + event->accept(); + return; + } + + QMessageBox exit_message_box; + exit_message_box.setIcon(QMessageBox::Warning); + exit_message_box.setText("You didn't save!"); + exit_message_box.setInformativeText("Do you want to save before exiting?"); + exit_message_box.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + exit_message_box.setDefaultButton(QMessageBox::Yes); + + switch (exit_message_box.exec()) { + case QMessageBox::Save: + save_database(); + event->accept(); + break; + case QMessageBox::Discard: + event->accept(); + break; + case QMessageBox::Cancel: + event->ignore(); + break; + default: + event->ignore(); + break; + } +} + +void MainWindow::check_database() +{ + + if (password_manager.database_exists()) + { + return; + } + + QInputDialog input_dialog; + input_dialog.resize(400, 200); + input_dialog.setWindowTitle("Database not Found"); + input_dialog.setLabelText("Enter Password for your new Database:"); + + if (input_dialog.exec() == 0) + { + close(); + return; + } + + QString password = input_dialog.textValue(); + + if (password.length() > 0) + { + password_manager.key = password; + password_manager.encrypt(); + password_manager.save(); + } + + check_database(); +} + +void MainWindow::on_spinBoxPasswordLength_valueChanged(int arg1) +{ + password_length = arg1; +} + +void MainWindow::on_tableWidgetCredentials_itemChanged() +{ + saved = false; +} + +void MainWindow::on_tableWidgetCredentials_itemSelectionChanged() +{ + if (ui->tableWidgetCredentials->selectedItems().size() > 1) + { + ui->pushButtonRemoveEntry->setText("Remove Selected Entries"); + } else { + ui->pushButtonRemoveEntry->setText("Remove Selected Entry"); + } +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..70fe17d --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,48 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include "passman.h" + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QString version, QWidget *parent = nullptr); + ~MainWindow() override; + void check_database(); + +protected: + passman password_manager; + bool saved = true; + int password_length = 20; + void closeEvent(QCloseEvent *event) override; + +protected slots: + void decrypt_database(); + void backup_database(); + void save_database(); + void add_entry(); + void remove_entry(); + void generate_password(); + void search(const QString &input); + +private slots: + void on_spinBoxPasswordLength_valueChanged(int arg1); + void on_tableWidgetCredentials_itemChanged(); + void on_tableWidgetCredentials_itemSelectionChanged(); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..991eabb --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,312 @@ + + + MainWindow + + + + 0 + 0 + 870 + 484 + + + + + 620 + 420 + + + + PassMan + + + + :/icons/passman_icon.svg:/icons/passman_icon.svg + + + QTabWidget::Rounded + + + + + + + + + + + + + false + + + Qt::AlignCenter + + + Enter Website Name to Search + + + + + + + + + false + + + QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed + + + Qt::NoPen + + + false + + + 0 + + + 100 + + + 41 + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + false + + + Backup Database + + + + + + + false + + + Save Database + + + + + + + false + + + Add New Entry + + + + + + + false + + + Remove Selected Entry + + + + + + + false + + + Generate New Password + + + + + + + + + false + + + + + + Password Length: + + + 1000 + + + 20 + + + 10 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Database Encrypted + + + Qt::AlignCenter + + + true + + + + + + + QFrame::NoFrame + + + Enter Encryption Key + + + Qt::AutoText + + + Qt::AlignCenter + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + + QLineEdit::Password + + + Qt::AlignCenter + + + Encryption Key + + + + + + + + 230 + 0 + + + + Decrypt Database + + + + + + + + + + + + + + + + + + lineEditEncryptionKey + returnPressed() + pushButtonUnlock + click() + + + 734 + 418 + + + 734 + 450 + + + + + diff --git a/makearchpkg.sh b/makearchpkg.sh new file mode 100644 index 0000000..dbe8862 --- /dev/null +++ b/makearchpkg.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# Copy PKGBUILD for given Architecture +cp PKGBUILD_$1 PKGBUILD + +# Make Package +makepkg -f + +# Remove PKGBUILD for given Architecture +rm PKGBUILD diff --git a/makedebpkg.sh b/makedebpkg.sh new file mode 100644 index 0000000..d5900c6 --- /dev/null +++ b/makedebpkg.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# Compile +mkdir build +cd build +qmake .. +make +cd .. + +# Make Folders +mkdir -p build/passman_debian/DEBIAN +mkdir -p build/passman_debian/usr/bin +mkdir -p build/passman_debian/usr/share/applications +mkdir -p build/passman_debian/opt/aslan/icons + +# Copy files +cp control_$1 build/passman_debian/DEBIAN/control +cp build/passman build/passman_debian/usr/bin/passman +cp passman.desktop build/passman_debian/usr/share/applications/passman.desktop +cp passman_icon.svg build/passman_debian/opt/aslan/icons/passman_icon.svg + +# Make Package +dpkg-deb --build build/passman_debian +mv build/passman_debian.deb passman_debian_$1.deb diff --git a/parameterparser.cpp b/parameterparser.cpp new file mode 100644 index 0000000..93ff994 --- /dev/null +++ b/parameterparser.cpp @@ -0,0 +1,57 @@ +#include "parameterparser.h" +#include +parameterparser::parameterparser(int argc, char *argv[]) +{ + parse(argc, argv); +} + +void parameterparser::parse(int argc, char *argv[]) +{ + arg_names.emplace_back("program"); + arg_values.emplace_back(""); + + for (int i = 1; i < argc; i++) + { + if (argv[i][0] == '-' && argv[i][1] == '-') + { + //Parameter ex.(--parameter) + arg_names.emplace_back(argv[i]); + arg_values.emplace_back(""); + } else if (argv[i][0] == '-') { + //Parameter ex.(-p) + for (int j = 1; argv[i][j] != '\0'; j++) + { + arg_names.emplace_back(std::string(1, argv[i][j])); + arg_values.emplace_back(""); + } + } else { + //Parameter Value + arg_values[arg_values.size() - 1] = argv[i]; + } + } +} + + +bool parameterparser::has_parameter(std::string parameter_name, char parameter_abbr) +{ + return get_value(parameter_name, parameter_abbr) == "-" ? false : true; +} + +std::string parameterparser::get_value(std::string parameter_name, char parameter_abbr) +{ + parameter_name = "--" + parameter_name; + + for (unsigned long i = 0; i < arg_names.size(); i++) + { + if (arg_names[i].compare(parameter_name) == 0) + { + return arg_values[i]; + } + if (arg_names[i].compare(std::string(1, parameter_abbr)) == 0) + { + return arg_values[i]; + } + } + + return "-"; +} diff --git a/parameterparser.h b/parameterparser.h new file mode 100644 index 0000000..e7008f1 --- /dev/null +++ b/parameterparser.h @@ -0,0 +1,19 @@ +#ifndef PARAMETERPARSER_H +#define PARAMETERPARSER_H + +#include +#include + +class parameterparser +{ +public: + parameterparser(int argc, char *argv[]); + bool has_parameter(std::string parameter_name, char parameter_abbr); + std::string get_value(std::string parameter_name, char parameter_abbr); +protected: + std::vector arg_names; + std::vector arg_values; + void parse(int argc, char *argv[]); +}; + +#endif // PARAMETERPARSER_H diff --git a/passman-1.0.0.tar.xz.txt b/passman-1.0.0.tar.xz.txt new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/passman-1.0.0.tar.xz.txt @@ -0,0 +1 @@ + diff --git a/passman.cpp b/passman.cpp new file mode 100644 index 0000000..05067df --- /dev/null +++ b/passman.cpp @@ -0,0 +1,175 @@ +#include "passman.h" + +passman::passman() : encryption(new QAESEncryption(QAESEncryption::AES_256, QAESEncryption::CBC)) { } + +//Save Database to Disk +void passman::save() const +{ + QFile output_file(database_path); + output_file.open(QIODevice::WriteOnly); + output_file.write(encrypted_data); + output_file.close(); +} + +//Load Database from Disk +bool passman::load() +{ + if (!database_exists()) + { + return false; + } + + QFile input_file(database_path); + input_file.open(QIODevice::ReadOnly); + encrypted_data = input_file.readAll(); + input_file.close(); + + return true; +} + +//Encrypt Database +void passman::encrypt() +{ + QByteArray data = QString("passwords\n").toLocal8Bit(); + + //Convert Database into Byte Array + for (std::array& entry_row : decrypted_entries) + { + for (QString& entry_column : entry_row) + { + data.append((entry_column + '\t').toLocal8Bit()); + } + data.append(QString('\n').toLocal8Bit()); + } + + //Encrypt data for every iv + for (int i = 0; i < ivs.size(); i++) + { + data = encryption->encode(data, QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256), QCryptographicHash::hash((ivs[i] + key).toLocal8Bit(), QCryptographicHash::Md5)); + } + encrypted_data = data; +} + +//Decrypt Database +bool passman::decrypt() +{ + QByteArray data = encrypted_data; + + //Decrypt data for every iv + for (int i = ivs.size() - 1; i >= 0; i--) + { + data = encryption->decode(data, QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256), QCryptographicHash::hash((ivs[i] + key).toLocal8Bit(), QCryptographicHash::Md5)); + } + + decrypted_entries.clear(); + + //Convert Byte Array into Database + QString stringData = QString::fromLocal8Bit(data); + QString line = ""; + for (QChar& ch : stringData) + { + if (ch == '\n') + { + if (line == "password") + { + line = ""; + continue; + } + + QStringList columns = line.split('\t'); + std::array row; + if (columns.length() == 5) + { + for (int i = 0; i < 4; i++) + { + row[static_cast(i)] = columns[i]; + } + decrypted_entries.emplace_back(row); + } + + line = ""; + continue; + } + line += ch; + } + + return stringData.startsWith("password"); +} + +//Make Database Backup +bool passman::backup() const +{ + if (!database_exists()) + { + return false; + } + + QFile input_file(database_path); + input_file.open(QIODevice::ReadOnly); + QByteArray data = input_file.readAll(); + input_file.close(); + + QFile output_file(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/credentials_backup.database"); + output_file.open(QIODevice::WriteOnly); + output_file.write(data); + output_file.close(); + + return true; +} + +void passman::add_entry(QString website_name, QString username, QString password, QString note) +{ + std::array row; + row[0] = website_name; + row[1] = username; + row[2] = password; + row[3] = note; + decrypted_entries.emplace_back(row); +} + +void passman::remove_entry(int index) +{ + decrypted_entries.erase(decrypted_entries.begin() + index); +} + +void passman::alter_entry(int index, QString new_website_name, QString new_username, QString new_password, QString new_note) +{ + std::array& row = decrypted_entries[static_cast(index)]; + row[0] = new_website_name; + row[1] = new_username; + row[2] = new_password; + row[3] = new_note; +} + +void passman::clear_database() +{ + decrypted_entries.clear(); +} + +std::array passman::get_entry_copy(int index) const +{ + return decrypted_entries[static_cast(index)]; +} + +std::vector> passman::get_database_copy() const +{ + return decrypted_entries; +} + +QString passman::generate_password(int length) const +{ + QRandomGenerator rand = QRandomGenerator::securelySeeded(); + + QString output = ""; + for (int i = 0; i < length; i++) + { + output += characters[rand.bounded(0, characters.length())]; + } + + return output; +} + +bool passman::database_exists() const +{ + return QFile::exists(database_path); +} diff --git a/passman.desktop b/passman.desktop new file mode 100755 index 0000000..1d20759 --- /dev/null +++ b/passman.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Comment[en_US]= +Comment= +Exec=/usr/bin/passman +GenericName[en_US]=Password Manager +GenericName=Password Manager +Icon=/opt/aslan/icons/passman_icon +MimeType= +Name[en_US]=Passman +Name=Passman +Path= +StartupNotify=true +Terminal=false +TerminalOptions= +Type=Application +X-DBUS-ServiceName= +X-DBUS-StartupType= +X-KDE-SubstituteUID=false +X-KDE-Username= diff --git a/passman.h b/passman.h new file mode 100644 index 0000000..14a6765 --- /dev/null +++ b/passman.h @@ -0,0 +1,53 @@ +#ifndef PASSMAN_H +#define PASSMAN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "qaesencryption.h" + +class passman +{ +public: + passman(); + QString database_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/credentials.database"; + QString key = ""; + void save() const; + bool load(); + void encrypt(); + bool decrypt(); + bool backup() const; + void add_entry(QString website_name, QString username, QString password, QString note); + void remove_entry(int index); + void alter_entry(int index, QString new_website_name, QString new_username, QString new_password, QString new_note); + void clear_database(); + std::array get_entry_copy(int index) const; + std::vector> get_database_copy() const; + QString generate_password(int length) const; + bool database_exists() const; + +protected: + QAESEncryption *encryption; + QByteArray encrypted_data; //Encrypted Database + std::vector> decrypted_entries; //Database Entries + QString characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:;.,/=-+*<>{}()[]_%#$@!?^&"; + QStringList ivs = { + "jW2jT]%0k2#-2R1.d(7'6V0Z|4=-HX2G9@F;561.07@21,NHq42)*896M(18R+9w080*Hs^,45G?;]5R7}'*0Z67?Y7|%SFI**0g", + ")OR2*711+M)*a,5D/qB}/#]|fN*30oA<#;>]B80>,4J9@<<;J5;#wL*]p$G9D0i1860;Y}b;|h)]6h6.O(n(*R)j87WrfZJ%>DM635u68i/s7@<*=/[V562&46E}P)/+8pZ$0c/3)690A/t.8eJ+4gJxf1&q?99%AP{)c71", + "6J00^0cZ-X16a=Z+K<_{8J34#1@9*Tb@3B4_^5'k0+YY[^--IZ71y0^62T&w>9}o738zAj7p1.%NA)+3^246X|F61I3<+I.8Z3tE4,HE_56o{[*7;*rf^", + "@F7L-7$;'h*|?0io3Zo}063)193|3'o/6-E+877Tr[vW87sNc8q<6,69-IS72cz6|2I/p{I8D6W520/$&6*Y3&%v,*0/85(ikK!J", + "72|/3;10O@!(|t)]8}02Gf126N)+6*w6e2P57/dWd*JW5+aR?h31e/=4o58!$l9!4?6_,7L%4}z3Lu8;sb^q}9%lVy6I57L]8<,-ho?310Dd_h|y1#iz%3]rN'zr5T1Bc2uQ5cb!K39386)50c0+%.w.X'", + "2-n$rL3v4T/*/22F%2tN}.yDX78#50z3Z9-B10X5*4]97+R-OK'2^F%7$>95c8jLu531C==1|V7Cd=o;5L6/B17jF2C9<1]R4'DY", + }; +}; + +#endif // PASSMAN_H diff --git a/passman.pro b/passman.pro new file mode 100644 index 0000000..892dd0e --- /dev/null +++ b/passman.pro @@ -0,0 +1,50 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2019-12-11T18:51:02 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = passman +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +CONFIG += c++11 + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + qaesencryption.cpp \ + passman.cpp \ + parameterparser.cpp + +HEADERS += \ + mainwindow.h \ + parameterparser.h \ + qaesencryption.h \ + passman.h \ + parameterparser.h + +FORMS += \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + resources.qrc diff --git a/passman_icon.svg b/passman_icon.svg new file mode 100644 index 0000000..f8e0bfd --- /dev/null +++ b/passman_icon.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/qaesencryption.cpp b/qaesencryption.cpp new file mode 100644 index 0000000..8aaaed8 --- /dev/null +++ b/qaesencryption.cpp @@ -0,0 +1,492 @@ +#include "qaesencryption.h" + +/* + * Static Functions + * */ +QByteArray QAESEncryption::Crypt(QAESEncryption::AES level, QAESEncryption::MODE mode, const QByteArray &rawText, + const QByteArray &key, const QByteArray &iv, QAESEncryption::PADDING padding) +{ + return QAESEncryption(level, mode, padding).encode(rawText, key, iv); +} + +QByteArray QAESEncryption::Decrypt(QAESEncryption::AES level, QAESEncryption::MODE mode, const QByteArray &rawText, + const QByteArray &key, const QByteArray &iv, QAESEncryption::PADDING padding) +{ + return QAESEncryption(level, mode, padding).decode(rawText, key, iv); +} + +QByteArray QAESEncryption::ExpandKey(QAESEncryption::AES level, QAESEncryption::MODE mode, const QByteArray &key) +{ + return QAESEncryption(level, mode).expandKey(key); +} + +QByteArray QAESEncryption::RemovePadding(const QByteArray &rawText, QAESEncryption::PADDING padding) +{ + QByteArray ret(rawText); + switch (padding) + { + case PADDING::ZERO: + //Works only if the last byte of the decoded array is not zero + while (ret.at(ret.length()-1) == 0x00) + ret.remove(ret.length()-1, 1); + break; + case PADDING::PKCS7: + ret.remove(ret.length() - ret.at(ret.length()-1), ret.at(ret.length()-1)); + break; + case PADDING::ISO: + ret.truncate(ret.lastIndexOf(0x80)); + break; + default: + //do nothing + break; + } + return ret; +} +/* + * End Static function declarations + * */ + +/* + * Inline Functions + * */ + +inline quint8 xTime(quint8 x){ + return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); +} + +inline quint8 multiply(quint8 x, quint8 y){ + return (((y & 1) * x) ^ ((y>>1 & 1) * xTime(x)) ^ ((y>>2 & 1) * xTime(xTime(x))) ^ ((y>>3 & 1) + * xTime(xTime(xTime(x)))) ^ ((y>>4 & 1) * xTime(xTime(xTime(xTime(x)))))); +} + +/* + * End Inline functions + * */ + + +QAESEncryption::QAESEncryption(QAESEncryption::AES level, QAESEncryption::MODE mode, PADDING padding) + : m_nb(4), m_blocklen(16), m_level(level), m_mode(mode), m_padding(padding) +{ + m_state = NULL; + + switch (level) + { + case AES_128: { + AES128 aes; + m_nk = aes.nk; + m_keyLen = aes.keylen; + m_nr = aes.nr; + m_expandedKey = aes.expandedKey; + } + break; + case AES_192: { + AES192 aes; + m_nk = aes.nk; + m_keyLen = aes.keylen; + m_nr = aes.nr; + m_expandedKey = aes.expandedKey; + } + break; + case AES_256: { + AES256 aes; + m_nk = aes.nk; + m_keyLen = aes.keylen; + m_nr = aes.nr; + m_expandedKey = aes.expandedKey; + } + break; + default: { + AES128 aes; + m_nk = aes.nk; + m_keyLen = aes.keylen; + m_nr = aes.nr; + m_expandedKey = aes.expandedKey; + } + break; + } + +} +QByteArray QAESEncryption::getPadding(int currSize, int alignment) +{ + QByteArray ret(0); + int size = (alignment - currSize % alignment) % alignment; + if (size == 0) return ret; + switch(m_padding) + { + case PADDING::ZERO: + ret.insert(0, size, 0x00); + break; + case PADDING::PKCS7: + ret.insert(0, size, size); + break; + case PADDING::ISO: + ret.insert(0, 0x80); + ret.insert(1, size, 0x00); + break; + default: + ret.insert(0, size, 0x00); + break; + } + return ret; +} + +QByteArray QAESEncryption::expandKey(const QByteArray &key) +{ + int i, k; + quint8 tempa[4]; // Used for the column/row operations + QByteArray roundKey(key); + + // The first round key is the key itself. + // ... + + // All other round keys are found from the previous round keys. + //i == Nk + for(i = m_nk; i < m_nb * (m_nr + 1); i++) + { + tempa[0] = (quint8) roundKey.at((i-1) * 4 + 0); + tempa[1] = (quint8) roundKey.at((i-1) * 4 + 1); + tempa[2] = (quint8) roundKey.at((i-1) * 4 + 2); + tempa[3] = (quint8) roundKey.at((i-1) * 4 + 3); + + if (i % m_nk == 0) + { + // This function shifts the 4 bytes in a word to the left once. + // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] + + // Function RotWord() + k = tempa[0]; + tempa[0] = tempa[1]; + tempa[1] = tempa[2]; + tempa[2] = tempa[3]; + tempa[3] = k; + + // Function Subword() + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + + tempa[0] = tempa[0] ^ Rcon[i/m_nk]; + } + if (m_level == AES_256 && i % m_nk == 4) + { + // Function Subword() + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + roundKey.insert(i * 4 + 0, (quint8) roundKey.at((i - m_nk) * 4 + 0) ^ tempa[0]); + roundKey.insert(i * 4 + 1, (quint8) roundKey.at((i - m_nk) * 4 + 1) ^ tempa[1]); + roundKey.insert(i * 4 + 2, (quint8) roundKey.at((i - m_nk) * 4 + 2) ^ tempa[2]); + roundKey.insert(i * 4 + 3, (quint8) roundKey.at((i - m_nk) * 4 + 3) ^ tempa[3]); + } + return roundKey; +} + +// This function adds the round key to state. +// The round key is added to the state by an XOR function. +void QAESEncryption::addRoundKey(const quint8 round, const QByteArray expKey) +{ + QByteArray::iterator it = m_state->begin(); + for(int i=0; i < 16; ++i) + it[i] = (quint8) it[i] ^ (quint8) expKey.at(round * m_nb * 4 + (i/4) * m_nb + (i%4)); +} + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +void QAESEncryption::subBytes() +{ + QByteArray::iterator it = m_state->begin(); + for(int i = 0; i < 16; i++) + it[i] = getSBoxValue((quint8) it[i]); +} + +// The ShiftRows() function shifts the rows in the state to the left. +// Each row is shifted with different offset. +// Offset = Row number. So the first row is not shifted. +void QAESEncryption::shiftRows() +{ + QByteArray::iterator it = m_state->begin(); + quint8 temp; + //Keep in mind that QByteArray is column-driven!! + + //Shift 1 to left + temp = (quint8)it[1]; + it[1] = (quint8)it[5]; + it[5] = (quint8)it[9]; + it[9] = (quint8)it[13]; + it[13] = (quint8)temp; + + //Shift 2 to left + temp = (quint8)it[2]; + it[2] = (quint8)it[10]; + it[10] = (quint8)temp; + temp = (quint8)it[6]; + it[6] = (quint8)it[14]; + it[14] = (quint8)temp; + + //Shift 3 to left + temp = (quint8)it[3]; + it[3] = (quint8)it[15]; + it[15] = (quint8)it[11]; + it[11] = (quint8)it[7]; + it[7] = (quint8)temp; +} + +// MixColumns function mixes the columns of the state matrix +//optimized!! +void QAESEncryption::mixColumns() +{ + QByteArray::iterator it = m_state->begin(); + quint8 tmp, tm, t; + + for(int i = 0; i < 16; i += 4){ + t = (quint8)it[i]; + tmp = (quint8)it[i] ^ (quint8)it[i+1] ^ (quint8)it[i+2] ^ (quint8)it[i+3] ; + + tm = xTime( (quint8)it[i] ^ (quint8)it[i+1] ); + it[i] = (quint8)it[i] ^ (quint8)tm ^ (quint8)tmp; + + tm = xTime( (quint8)it[i+1] ^ (quint8)it[i+2]); + it[i+1] = (quint8)it[i+1] ^ (quint8)tm ^ (quint8)tmp; + + tm = xTime( (quint8)it[i+2] ^ (quint8)it[i+3]); + it[i+2] =(quint8)it[i+2] ^ (quint8)tm ^ (quint8)tmp; + + tm = xTime((quint8)it[i+3] ^ (quint8)t); + it[i+3] =(quint8)it[i+3] ^ (quint8)tm ^ (quint8)tmp; + } +} + +// MixColumns function mixes the columns of the state matrix. +// The method used to multiply may be difficult to understand for the inexperienced. +// Please use the references to gain more information. +void QAESEncryption::invMixColumns() +{ + QByteArray::iterator it = m_state->begin(); + quint8 a,b,c,d; + for(int i = 0; i < 16; i+=4){ + a = (quint8) it[i]; + b = (quint8) it[i+1]; + c = (quint8) it[i+2]; + d = (quint8) it[i+3]; + + it[i] = (quint8) (multiply(a, 0x0e) ^ multiply(b, 0x0b) ^ multiply(c, 0x0d) ^ multiply(d, 0x09)); + it[i+1] = (quint8) (multiply(a, 0x09) ^ multiply(b, 0x0e) ^ multiply(c, 0x0b) ^ multiply(d, 0x0d)); + it[i+2] = (quint8) (multiply(a, 0x0d) ^ multiply(b, 0x09) ^ multiply(c, 0x0e) ^ multiply(d, 0x0b)); + it[i+3] = (quint8) (multiply(a, 0x0b) ^ multiply(b, 0x0d) ^ multiply(c, 0x09) ^ multiply(d, 0x0e)); + } +} + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +void QAESEncryption::invSubBytes() +{ + QByteArray::iterator it = m_state->begin(); + for(int i = 0; i < 16; ++i) + it[i] = getSBoxInvert((quint8) it[i]); +} + +void QAESEncryption::invShiftRows() +{ + QByteArray::iterator it = m_state->begin(); + uint8_t temp; + + //Keep in mind that QByteArray is column-driven!! + + //Shift 1 to right + temp = (quint8)it[13]; + it[13] = (quint8)it[9]; + it[9] = (quint8)it[5]; + it[5] = (quint8)it[1]; + it[1] = (quint8)temp; + + //Shift 2 + temp = (quint8)it[10]; + it[10] = (quint8)it[2]; + it[2] = (quint8)temp; + temp = (quint8)it[14]; + it[14] = (quint8)it[6]; + it[6] = (quint8)temp; + + //Shift 3 + temp = (quint8)it[15]; + it[15] = (quint8)it[3]; + it[3] = (quint8)it[7]; + it[7] = (quint8)it[11]; + it[11] = (quint8)temp; +} + +QByteArray QAESEncryption::byteXor(const QByteArray &a, const QByteArray &b) +{ + QByteArray::const_iterator it_a = a.begin(); + QByteArray::const_iterator it_b = b.begin(); + QByteArray ret; + + for(int i = 0; i < m_blocklen; i++) + ret.insert(i,it_a[i] ^ it_b[i]); + + return ret; +} + +// Cipher is the main function that encrypts the PlainText. +QByteArray QAESEncryption::cipher(const QByteArray &expKey, const QByteArray &in) +{ + + //m_state is the input buffer... + QByteArray output(in); + m_state = &output; + + // Add the First round key to the state before starting the rounds. + addRoundKey(0, expKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr-1 rounds are executed in the loop below. + for(quint8 round = 1; round < m_nr; ++round){ + subBytes(); + shiftRows(); + mixColumns(); + addRoundKey(round, expKey); + } + + // The last round is given below. + // The MixColumns function is not here in the last round. + subBytes(); + shiftRows(); + addRoundKey(m_nr, expKey); + + return output; +} + +QByteArray QAESEncryption::invCipher(const QByteArray &expKey, const QByteArray &in) +{ + //m_state is the input buffer.... handle it! + QByteArray output(in); + m_state = &output; + + // Add the First round key to the state before starting the rounds. + addRoundKey(m_nr, expKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr-1 rounds are executed in the loop below. + for(quint8 round=m_nr-1; round>0 ; round--){ + invShiftRows(); + invSubBytes(); + addRoundKey(round, expKey); + invMixColumns(); + } + + // The last round is given below. + // The MixColumns function is not here in the last round. + invShiftRows(); + invSubBytes(); + addRoundKey(0, expKey); + + return output; +} + +QByteArray QAESEncryption::encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv) +{ + if (m_mode >= CBC && (iv.isNull() || iv.size() != m_blocklen)) + return QByteArray(); + + QByteArray ret; + QByteArray expandedKey = expandKey(key); + QByteArray alignedText(rawText); + QByteArray ivTemp(iv); + + //Fill array with padding + alignedText.append(getPadding(rawText.size(), m_blocklen)); + + //Preparation for CFB + if (m_mode == CFB) + ret.append(byteXor(alignedText.mid(0, m_blocklen), cipher(expandedKey, iv))); + + //Looping thru all blocks + for(int i=0; i < alignedText.size(); i+= m_blocklen){ + switch(m_mode) + { + case ECB: + ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); + break; + case CBC: + alignedText.replace(i, m_blocklen, byteXor(alignedText.mid(i, m_blocklen),ivTemp)); + ret.append(cipher(expandedKey, alignedText.mid(i, m_blocklen))); + ivTemp = ret.mid(i, m_blocklen); + break; + case CFB: + if (i+m_blocklen < alignedText.size()) + ret.append(byteXor(alignedText.mid(i+m_blocklen, m_blocklen), + cipher(expandedKey, ret.mid(i, m_blocklen)))); + break; + default: + //do nothing + break; + } + } + return ret; +} + +QByteArray QAESEncryption::decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv) +{ + if (m_mode >= CBC && (iv.isNull() || iv.size() != m_blocklen)) + return QByteArray(); + + QByteArray ret; + QByteArray expandedKey = expandKey(key); + QByteArray ivTemp(iv); + + //Preparation for CFB + if (m_mode == CFB) + ret.append(byteXor(rawText.mid(0, m_blocklen), cipher(expandedKey, iv))); + + for(int i=0; i < rawText.size(); i+= m_blocklen){ + switch(m_mode) + { + case ECB: + ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); + break; + case CBC: + ret.append(invCipher(expandedKey, rawText.mid(i, m_blocklen))); + ret.replace(i, m_blocklen, byteXor(ret.mid(i, m_blocklen),ivTemp)); + ivTemp = rawText.mid(i, m_blocklen); + break; + case CFB: + if (i+m_blocklen < rawText.size()){ + ret.append(byteXor(rawText.mid(i+m_blocklen, m_blocklen), + cipher(expandedKey, rawText.mid(i, m_blocklen)))); + } + break; + default: + //do nothing + break; + } + } + return ret; +} + +QByteArray QAESEncryption::removePadding(const QByteArray &rawText) +{ + QByteArray ret(rawText); + switch (m_padding) + { + case PADDING::ZERO: + //Works only if the last byte of the decoded array is not zero + while (ret.at(ret.length()-1) == 0x00) + ret.remove(ret.length()-1, 1); + break; + case PADDING::PKCS7: + ret.remove(ret.length() - ret.at(ret.length()-1), ret.at(ret.length()-1)); + break; + case PADDING::ISO: + ret.truncate(ret.lastIndexOf(0x80)); + break; + default: + //do nothing + break; + } + return ret; +} diff --git a/qaesencryption.h b/qaesencryption.h new file mode 100644 index 0000000..0065cf1 --- /dev/null +++ b/qaesencryption.h @@ -0,0 +1,154 @@ +#ifndef QAESENCRYPTION_H +#define QAESENCRYPTION_H + +#include +#include + +class QAESEncryption : public QObject +{ + Q_OBJECT +public: + enum AES { + AES_128, + AES_192, + AES_256 + }; + + enum MODE { + ECB, + CBC, + CFB + }; + + enum PADDING { + ZERO, + PKCS7, + ISO + }; + + static QByteArray Crypt(QAESEncryption::AES level, QAESEncryption::MODE mode, const QByteArray &rawText, const QByteArray &key, + const QByteArray &iv = NULL, QAESEncryption::PADDING padding = QAESEncryption::ISO); + static QByteArray Decrypt(QAESEncryption::AES level, QAESEncryption::MODE mode, const QByteArray &rawText, const QByteArray &key, + const QByteArray &iv = NULL, QAESEncryption::PADDING padding = QAESEncryption::ISO); + static QByteArray ExpandKey(QAESEncryption::AES level, QAESEncryption::MODE mode, const QByteArray &key); + static QByteArray RemovePadding(const QByteArray &rawText, QAESEncryption::PADDING padding); + + QAESEncryption(QAESEncryption::AES level, QAESEncryption::MODE mode, QAESEncryption::PADDING padding = QAESEncryption::ISO); + + QByteArray encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv = NULL); + QByteArray decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv = NULL); + QByteArray removePadding(const QByteArray &rawText); + QByteArray expandKey(const QByteArray &key); + +signals: + +public slots: + +private: + int m_nb; + int m_blocklen; + int m_level; + int m_mode; + int m_nk; + int m_keyLen; + int m_nr; + int m_expandedKey; + int m_padding; + QByteArray* m_state; + + struct AES256{ + int nk = 8; + int keylen = 32; + int nr = 14; + int expandedKey = 240; + }; + + struct AES192{ + int nk = 6; + int keylen = 24; + int nr = 12; + int expandedKey = 209; + }; + + struct AES128{ + int nk = 4; + int keylen = 16; + int nr = 10; + int expandedKey = 176; + }; + + quint8 getSBoxValue(quint8 num){return sbox[num];} + quint8 getSBoxInvert(quint8 num){return rsbox[num];} + + void addRoundKey(const quint8 round, const QByteArray expKey); + void subBytes(); + void shiftRows(); + void mixColumns(); + void invMixColumns(); + void invSubBytes(); + void invShiftRows(); + QByteArray getPadding(int currSize, int alignment); + QByteArray cipher(const QByteArray &expKey, const QByteArray &plainText); + QByteArray invCipher(const QByteArray &expKey, const QByteArray &plainText); + QByteArray byteXor(const QByteArray &in, const QByteArray &iv); + + const quint8 sbox[256] = { + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; + + const quint8 rsbox[256] = + { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; + + // The round constant word array, Rcon[i], contains the values given by + // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) + //Only the first 14 elements are needed + const quint8 Rcon[256] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, /*0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, + 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, + 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, + 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, + 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, + 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, + 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, + 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, + 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, + 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, + 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, + 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, + 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d */}; +}; + +#endif // QAESENCRYPTION_H diff --git a/resources.qrc b/resources.qrc new file mode 100644 index 0000000..0b7f0e6 --- /dev/null +++ b/resources.qrc @@ -0,0 +1,5 @@ + + + passman_icon.svg + +