Files
AES256_Seed_Phrase_encryptor/AES256_Seed_Phrase_encryptor.ino
T
schauausgmbh ac6915443c Initial version of the firmware and tables
- Initial version of the firmware
- table for creating hexadecimal values with a 20 sided die
- table to note down encryption key and encrypted data to print on an A4 sheet in landscape format (including a cutting line to separate the data from the key)
2026-09-09 09:55:30 +00:00

209 lines
7.4 KiB
Arduino

/*
* Copyright (C) 2026 SCHAUAUS GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <Crypto.h>
#include <AES.h>
#include <string.h>
#define MAX_INPUT_LENGHT 256
//creating an object of AES256 class
AES256_ESP aes256;
void printHelp () {
Serial.println();
Serial.println("┌-----------------------------------------------------┐");
Serial.println("| Encrypt / Decrypt seed phrase with AES256 algorithm |");
Serial.println("└-----------------------------------------------------┘");
Serial.println();
Serial.println("WARNING: DO NOT USE THIS ON ANY NETWORK CONNECTED DEVICE AND ENSURE THE DECRYPTION IS WORKING PROPERLY!");
Serial.println("USE IN SECURE ENVIRONMENTS ONLY!");
Serial.println("This program is offered as it is and no warranties will be granted in any case!");
Serial.println("Review the source code thoroughly before using it for real application!");
Serial.println("Available commands:");
Serial.println("help - print this help to serial console");
Serial.println("key - generate random HEX key and print it to the serial console");
Serial.println("key <your 32byte key> - set key (hexadecimal or ascii) for encryption / decryption");
Serial.println("encrypt <12 or 24 word seed phrase> - encrypts your 12 ord 24 word plain text seed phrase to HEX string");
Serial.println("decrypt <encrypted HEX string> - decrypts your encrypted HEX string back to clear text seed phrase");
Serial.println("clear - clear all cryptographic information from memory");
Serial.println("restart - reboot the device for a fresh restart; any working data will be removed from memory");
}
void setCryptKey (String argKey) {
Serial.println();
Serial.println("Operation: setting encryption key");
argKey.trim();
String tempKey = argKey;
byte cryptKey[32];
tempKey.replace(" ", ""); // remove any spaces in between characters to check for hexadecimal values
if(argKey.length() != 32 && tempKey.length() / 2 != 32) { // there was no valid key given; keys need to consist of 32 characters (256bit)
Serial.println("No valid key handed over; generating new key:");
for(int i=0; i < 32; i++) {
cryptKey[i] = random(256);
}
for(size_t i=0; i<32; i++) {
if(cryptKey[i] < 16) Serial.print("0");
Serial.print(cryptKey[i], HEX);
Serial.print(" ");
}
Serial.println();
}
else { // process valid key provided
Serial.println("Valid key detected");
bool keyIsHex = true;
for(size_t i = 0; i < tempKey.length(); i++)
if ( !(tempKey[i] >= '0' && tempKey[i] <= '9') &&
!(tempKey[i] >= 'a' && tempKey[i] <= 'f') &&
!(tempKey[i] >= 'A' && tempKey[i] <= 'F') )
keyIsHex = false;
if (keyIsHex) { // input key is hexadecimal representation
String byteString = "";
for(size_t idx = 0; idx < tempKey.length(); idx += 2) {
byteString = tempKey.substring(idx, idx+2);
long byteValue = strtol(byteString.c_str(), NULL, 16);
cryptKey[idx / 2] = (byte)byteValue;
}
}
else { // input key is ASCII-representation
for(size_t i=0; i<32; i++) {
cryptKey[i] = argKey[i];
}
}
}
// set the final key for encryption / decryption
aes256.setKey(cryptKey, 32);
Serial.println("Key set for encryption / decryption");
}
void decryptData (String data) {
Serial.println();
Serial.println("Operation: decrypting data");
data.replace(" ", "");
byte dataBlock[aes256.blockSize()];
byte plainText[aes256.blockSize()];
String byteString = "";
// check whether the input data is a hexadecimal string
bool dataIsHex = true;
for(size_t i = 0; i < data.length(); i++)
if ( !(data[i] >= '0' && data[i] <= '9') &&
!(data[i] >= 'a' && data[i] <= 'f') &&
!(data[i] >= 'A' && data[i] <= 'F') )
dataIsHex = false;
if(!dataIsHex) {
Serial.println("Abort decryption! No valid input data!");
return;
}
Serial.println("decrypted data block: ");
for(int i=0; i < data.length(); i += aes256.blockSize() * 2) {
for(int j=0; j<aes256.blockSize() * 2; j+=2) {
byteString = data.substring(i + j, i + j + 2);
long byteValue = strtol(byteString.c_str(), NULL, 16);
dataBlock[j / 2] = (byte)byteValue;
}
aes256.decryptBlock(plainText, dataBlock);
for(int i=0; i<sizeof(plainText); i++){
if(plainText[i] == '\0') break;
Serial.write(plainText[i]);
}
}
Serial.println();
}
void encryptData (String data) {
Serial.println();
Serial.println("Operation: encrypting data");
byte dataBlock[aes256.blockSize()];
byte cypher[aes256.blockSize()];
Serial.println("encrypted data block: ");
for(int i=0; i<data.length(); i+=aes256.blockSize()) {
for(int j=0; j<aes256.blockSize(); j++) {
dataBlock[j] = data[i + j];
if((i + j) > data.length()) dataBlock[j] = '\0';
}
aes256.encryptBlock(cypher, dataBlock);
for(int j=0; j<sizeof(cypher); j++) {
if(cypher[j] < 16) Serial.print("0");
Serial.print(cypher[j], HEX);
Serial.print(" ");
}
}
Serial.println();
}
void clearCryptograficInformation () {
Serial.println();
Serial.println("Operation: clear all cryptographic information from memory");
aes256.clear();
Serial.println("Memory cleared");
}
void restartDevice () {
Serial.println("\r\nInitiating reboot of this device!\r\n");
ESP.restart();
}
void readCmd () {
Serial.println();
Serial.println("Waiting for command (send \"help\" for available commands)");
while (Serial.available() == 0) {} // wait until input on the serial console is available
String inp = Serial.readString();
inp.trim();
String cmd = "";
String arg = "";
if(inp.indexOf(' ') > 0) {
cmd = inp.substring(0, inp.indexOf(' '));
arg = inp.substring(inp.indexOf(' ') + 1);
arg.trim();
}
else
cmd = inp;
if (cmd == "help") printHelp();
else if(cmd == "key") setCryptKey(arg);
else if (cmd == "encrypt") encryptData(arg);
else if (cmd == "decrypt") decryptData(arg);
else if (cmd == "clear") clearCryptograficInformation();
else if (cmd == "restart") restartDevice();
else Serial.println("\r\nUnknown command! Try again!");
}
void setup() {
Serial.begin(115200);
printHelp();
}
void loop() {
readCmd();
}