Skip to content

Commit

Permalink
headless fixes (pr3y#107), added some serial cmds (pr3y#64), initial …
Browse files Browse the repository at this point in the history
…encrypted files support (pr3y#123)
  • Loading branch information
eadmaster committed Aug 20, 2024
1 parent ea92912 commit 2b590cb
Show file tree
Hide file tree
Showing 12 changed files with 584 additions and 107 deletions.
29 changes: 19 additions & 10 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,16 @@ build_flags =
-DEEPROMSIZE=128
-DLH=8
-DLW=6
-DCONFIG_FILE='"/config.conf"'
-DCONFIG_FILE='"/bruce.conf"'
-w
!echo '-DGIT_COMMIT_HASH=\\"'$(git describe --always --dirty)'\\"'
; rtl_433_ESP flags https://github.com/NorthernMan54/rtl_433_ESP/blob/main/example/OOK_Receiver/platformio.ini
;-DOOK_MODULATION=true ; False is FSK, True is OOK
;-DRF_CC1101="CC1101"
;-DRF_MODULE_GDO0=9 ; CC1101 pin GDO0
;-DRF_MODULE_GDO2=14 ; CC1101 pin GDO2
;-DRF_MODULE_GDO2=RADIOLIB_NC ; CC1101 pin GDO2
;-DRF_MODULE_INIT_STATUS=true

lib_deps =
WireGuard-ESP32
Expand All @@ -53,6 +61,7 @@ lib_deps =
;lsatan/SmartRC-CC1101-Driver-Lib@^2.5.7
SmartRC-CC1101-Driver-Lib=https://github.com/bmorcelli/SmartRC-CC1101-Driver-Lib/archive/refs/heads/Bruce.zip
h2zero/NimBLE-Arduino@^1.4.0
;https://github.com/eadmaster/rtl_433_ESP

[env:m5stack-cplus2]
platform = espressif32
Expand Down Expand Up @@ -320,14 +329,14 @@ build_flags =
;Radio Frequency (one pin modules) pin setting
-DRF_TX_PINS='{ {"M5 RF433T", GROVE_SDA}, {"Groove W", GROVE_SCL}, {"GROVE Y", GROVE_SDA}}'
-DRF_RX_PINS='{ {"M5 RF433R", GROVE_SCL}, {"Groove W", GROVE_SCL}, {"GROVE Y", GROVE_SDA}}'
; connection pins using microSD sniffer module https://www.sparkfun.com/products/9419 https://docs.m5stack.com/en/core/Cardputer
-DUSE_CC1101_VIA_SPI
-DCC1101_GDO0_PIN=GROVE_SDA
-DCC1101_SS_PIN=GROVE_SCL ; chip select
-DCC1101_MOSI_PIN=14
-DCC1101_SCK_PIN=40
-DCC1101_MISO_PIN=39
;-DCC1101_GDO2_PIN=-1
; connection pins using microSD sniffer module https://www.sparkfun.com/products/9419 https://docs.m5stack.com/en/core/Cardputer
-DUSE_CC1101_VIA_SPI
-DCC1101_GDO0_PIN=GROVE_SDA ; 2
-DCC1101_SS_PIN=GROVE_SCL ; 1 = chip select
-DCC1101_MOSI_PIN=14 ; CMD on SDsniffer
-DCC1101_SCK_PIN=40 ; CLK on SDsniffer
-DCC1101_MISO_PIN=39 ; DAT0 on SDsniffer
;-DCC1101_GDO2_PIN=-1

;Screen Setup
-DHAS_SCREEN=1
Expand Down Expand Up @@ -741,7 +750,7 @@ build_flags =
; grove pins
; defaults from https://github.com/espressif/arduino-esp32/blob/master/variants/esp32s3/pins_arduino.h
-DGROVE_SDA=8 ; default RF TX pin
-DGROVE_SCL=9 ; default IR/RF RX pin
-DGROVE_SCL=46 ; default IR/RF RX pin
;-DALLOW_ALL_GPIO_FOR_IR_RF=1 ; Set this option to make use of all GPIOs, from 1 to 44 to be chosen, except TFT and SD pins

; ir led pin
Expand Down
2 changes: 2 additions & 0 deletions src/core/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ extern int RfModule;

extern float RfFreq;

extern String cachedPassword;

// Screen sleep control variables
extern unsigned long previousMillis;
extern bool isSleeping;
Expand Down
38 changes: 38 additions & 0 deletions src/core/passwords.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "mbedtls/aes.h"
#include "mbedtls/md.h"
#include "mbedtls/pkcs5.h"
#include <Arduino.h>


String aes_decrypt(uint8_t* inputData, size_t fileSize, const String& password_str) {
// generate key, iv, salt
const char *password = password_str.c_str();
unsigned char key[32];
unsigned char iv[16];
unsigned char salt[8] = { /* The salt used by OpenSSL during encryption */ };

mbedtls_md_context_t md_ctx;
mbedtls_md_init(&md_ctx);
mbedtls_md_setup(&md_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1);

// Derive key and IV using PBKDF2
mbedtls_pkcs5_pbkdf2_hmac(&md_ctx, (unsigned char*)password, strlen(password), salt, 8, 10000, 32, key);
mbedtls_pkcs5_pbkdf2_hmac(&md_ctx, (unsigned char*)password, strlen(password), salt, 8, 10000, 16, iv);

mbedtls_md_free(&md_ctx);

unsigned char *outputData = new unsigned char[fileSize];
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_dec(&aes, key, 256);

mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, fileSize, iv, inputData, outputData);

mbedtls_aes_free(&aes);

// Convert the decrypted data to a string
String decryptedText = String(outputData, fileSize);
free(outputData);

return decryptedText;
}
2 changes: 2 additions & 0 deletions src/core/passwords.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

String aes_decrypt(uint8_t* inputData, size_t fileSize, const String& password_str);
156 changes: 147 additions & 9 deletions src/core/sd_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#include "sd_functions.h"
#include "mykeyboard.h" // usinf keyboard when calling rename
#include "display.h" // using displayRedStripe as error msg
#include "passwords.h"
#include "modules/others/audio.h"
#include "modules/rf/rf.h"
#include "modules/ir/TV-B-Gone.h"
#include "modules/others/bad_usb.h"
#include "modules/others/qrcode_menu.h"

struct FilePage {
int pageIndex;
Expand Down Expand Up @@ -284,6 +286,111 @@ String readLineFromFile(File myFile) {
return line;
}


/***************************************************************************************
** Function name: readSmallFile
** Description: read a small (<3KB) file and return its contents as a single string
** on any error returns an empty string
***************************************************************************************/
String readSmallFile(FS &fs, String filepath) {
String fileContent = "";
File file;

file = fs.open(filepath, FILE_READ);
if (!file) return "";

size_t fileSize = file.size();
if(fileSize > 1024*3) { // 3K is the max
displayError("File is too big");
Serial.println("File is too big");
return "";
}

fileContent = file.readString();

file.close();
return fileContent;
}

/***************************************************************************************
** Function name: getFileSize
** Description: get a file size without opening
***************************************************************************************/
size_t getFileSize(FS &fs, String filepath) {
if(&fs == &SD) filepath = "/sd" + filepath;
else if(&fs == &LittleFS) filepath = "/littlefs" + filepath;
else return 0; // not found
struct stat st;
memset(&st, 0, sizeof(struct stat));
if (stat(filepath.c_str(), &st) != 0) return 0; // stat error
// else
return st.st_size;
}

bool is_valid_ascii(const String &text) {
for (int i = 0; i < text.length(); i++) {
char c = text[i];
// Check if the character is within the printable ASCII range or is a newline/carriage return
if (!(c >= 32 && c <= 126) && c != 10 && c != 13) {
return false; // Invalid character found
}
}
return true; // All characters are valid
}

String readDecryptedAesFile(FS &fs, String filepath) {
File file;

file = fs.open(filepath, FILE_READ);
if (!file) return "";

size_t fileSize = file.size();
if(fileSize > 1024*3) { // 3K is the max
displayError("File is too big");
return "";
}

char buffer[fileSize];
size_t bytesRead = file.readBytes(buffer, fileSize);
//Serial.print("fileSize:");
//Serial.println(fileSize);
//Serial.println(bytesRead);

/*
// read the whole file with a single call
char buffer[fileSize + 1];
size_t bytesRead = file.readBytes(buffer, fileSize);
buffer[bytesRead] = '\0'; // Null-terminate the string
return String(buffer);
*/

if (bytesRead==0) {
Serial.println("empty cypherText");
return "";
}
// else

if(cachedPassword.length()==0) {
cachedPassword = keyboard("", 32, "password");
if(cachedPassword.length()==0) return ""; // cancelled
}

// else try to decrypt
String plaintext = aes_decrypt((uint8_t*)buffer, bytesRead, cachedPassword);

// check if really plaintext
if(!is_valid_ascii(plaintext)) {
// invalidate cached password -> will ask again on the next try
cachedPassword = "";
Serial.println("invalid password");
Serial.println(plaintext);
return "";
}
// else
return plaintext;
}


/***************************************************************************************
** Function name: sortList
** Description: sort files for name
Expand Down Expand Up @@ -434,16 +541,14 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) {
closeSdCard();
setupSdCard();
bool exit = false;
returnToMenu=true; // make sure menu is redrawn when quitting in any point

readFs(fs, Folder, fileList, allowed_ext);

for(int i=0; i<MAXFILES; i++) if(fileList[i][2]!="") maxFiles++; else break;
while(1){
//if(returnToMenu) break; // stop this loop and retur to the previous loop
if(exit){
returnToMenu=true;
break; // stop this loop and retur to the previous loop
}
if(exit) break; // stop this loop and retur to the previous loop

if(redraw) {
if(strcmp(PreFolder.c_str(),Folder.c_str()) != 0 || reload){
Expand Down Expand Up @@ -539,20 +644,53 @@ String loopSD(FS &fs, bool filePicker, String allowed_ext) {
txSubFile(&fs, filepath);
}});
#if defined(USB_as_HID)
if(filepath.endsWith(".txt")) options.insert(options.begin(), {"BadUSB Run", [&]() {
Kb.begin();
USB.begin();
if(filepath.endsWith(".txt")) {
options.push_back({"BadUSB Run", [&]() {
Kb.begin(); USB.begin();
// TODO: set default keyboard layout
key_input(fs, filepath);
}});
/*
options.push_back({"USB HID Type", [&]() {
Kb.begin(); USB.begin();
Kb.print(readSmallFile(fs, filepath).c_str()); // buggy?
//String t = readSmallFile(fs, filepath).c_str();
//Kb.write((const uint8_t*) t.c_str(), t.length());
}});*/
}
if(filepath.endsWith(".aes") || filepath.endsWith(".enc")) { // aes encrypted files
options.insert(options.begin(), {"Decrypt+Type", [&]() {
String plaintext = readDecryptedAesFile(fs, filepath);
if(plaintext.length()==0) return displayError("invalid password");; // file is too big or cannot read, or cancelled
// else
Kb.begin(); USB.begin();
Kb.print(plaintext.c_str());
}});
}
#endif
if(filepath.endsWith(".aes") || filepath.endsWith(".enc")) { // aes encrypted files
options.insert(options.begin(), {"Decrypt+Show", [&]() {
String plaintext = readDecryptedAesFile(fs, filepath);
if(plaintext.length()==0) return; // file is too big or cannot read, or cancelled
// else
displaySuccess(plaintext);
delay(2000);
// TODO: loop and wait for user input?
}});
}
#if defined(HAS_NS4168_SPKR)
if(isAudioFile(filepath)) options.insert(options.begin(), {"Play Audio", [&]() {
delay(200);
playAudioFile(&fs, filepath);
setup_gpio(); //TODO: remove after fix select loop
}});
#endif

// generate qr codes from small files (<10K)
size_t filesize = getFileSize(fs, filepath); // TODO: check filesize without opening
if(filesize < 3*1024) options.push_back({"QR code", [&]() {
delay(200);
qrcode_display(readSmallFile(fs, filepath));
}});
options.push_back({"Main Menu", [&]() { exit = true; }});
delay(200);
if(!filePicker) loopOptions(options);
Expand Down Expand Up @@ -740,4 +878,4 @@ bool checkLittleFsSizeNM() {
if((LittleFS.totalBytes() - LittleFS.usedBytes()) < 4096) {
return false;
} else return true;
}
}
6 changes: 5 additions & 1 deletion src/core/sd_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ bool createFolder(FS fs, String path);

String readLineFromFile(File myFile);

String readSmallFile(FS &fs, String filepath);

String readDecryptedAesFile(FS &fs, String filepath);

void readFs(FS fs, String folder, String result[][3], String allowed_ext = "*");

void sortList(String fileList[][3], int fileListCount);
Expand All @@ -39,4 +43,4 @@ int createFilePages(String fileContent);

bool checkLittleFsSize();

bool checkLittleFsSizeNM(); //Don't display msg
bool checkLittleFsSizeNM(); //Don't display msg
Loading

0 comments on commit 2b590cb

Please sign in to comment.