Skip to content

Commit

Permalink
Merge pull request #33 from dbitbox/security-fixes
Browse files Browse the repository at this point in the history
Security fixes
  • Loading branch information
dbitbox committed Jul 28, 2015
2 parents f0c02d6 + 5c73cdb commit ab96b29
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 87 deletions.
24 changes: 19 additions & 5 deletions src/commander.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ static int commander_process_backup_create(const char *filename, const char *enc
free(enc);
return ERROR;
}
ret = sd_write(filename, strlens(filename), enc, enc_len);
ret = sd_write(filename, strlens(filename), enc, enc_len, NO_REPLACE);
if (ret != SUCCESS) {
commander_fill_report("backup", FLAG_ERR_SD_WRITE, ERROR);
} else {
Expand All @@ -315,7 +315,7 @@ static int commander_process_backup_create(const char *filename, const char *enc
free(enc);
return ret;
} else {
ret = sd_write(filename, strlens(filename), text, strlens(text));
ret = sd_write(filename, strlens(filename), text, strlens(text), NO_REPLACE);
if (ret != SUCCESS) {
commander_fill_report("backup", FLAG_ERR_SD_WRITE, ERROR);
} else {
Expand Down Expand Up @@ -407,14 +407,28 @@ static void commander_process_seed(yajl_val json_node)
if (strcmp(src, ATTR_STR[ATTR_create_]) == 0) {

if (sd_list() != SUCCESS) {
commander_clear_report();
commander_fill_report("seed", FLAG_ERR_SEED_SD, ERROR);
return;
}

char file[strlens(AUTOBACKUP_FILENAME) + 8];
int count = 1;
do {
if (count > AUTOBACKUP_NUM) {
commander_clear_report();
commander_fill_report("seed", FLAG_ERR_SEED_SD_NUM, ERROR);
return;
}
memset(file, 0, sizeof(file));
snprintf(file, sizeof(file), "%s%i.aes", AUTOBACKUP_FILENAME, count++);
} while (sd_load(file, strlens(file)));

ret = wallet_master_from_mnemonic(NULL, 0, salt, strlens(salt));
if (ret == SUCCESS) {
if (commander_process_backup_create(AUTOBACKUP_FILENAME, AUTOBACKUP_ENCRYPT) != SUCCESS) {
if (commander_process_backup_create(file, AUTOBACKUP_ENCRYPT) != SUCCESS) {
memory_erase_seed();
ret = ERROR;
return;
}
}

Expand Down Expand Up @@ -552,7 +566,7 @@ static void commander_process_verifypass(const char *value)
} else if (strcmp(value, ATTR_STR[ATTR_export_]) == 0) {
memcpy(text, utils_uint8_to_hex(memory_read_aeskey(PASSWORD_VERIFY), 32), 64 + 1);
utils_clear_buffers();
ret = sd_write(VERIFYPASS_FILENAME, sizeof(VERIFYPASS_FILENAME), text, 64 + 1);
ret = sd_write(VERIFYPASS_FILENAME, sizeof(VERIFYPASS_FILENAME), text, 64 + 1, REPLACE);
if (ret != SUCCESS) {
commander_fill_report(ATTR_STR[ATTR_export_], FLAG_ERR_SD_WRITE, ERROR);
memset(text, 0, sizeof(text));
Expand Down
3 changes: 2 additions & 1 deletion src/commander.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@
#define VERIFYPASS_FILENAME "verification.txt"
#define COMMANDER_MAX_ATTEMPTS 5// max attempts before device reset

#define AUTOBACKUP_FILENAME "autobackup.aes"
#define AUTOBACKUP_FILENAME "autobackup_"
#define AUTOBACKUP_ENCRYPT "yes"
#define AUTOBACKUP_NUM 10

char *aes_cbc_b64_encrypt(const unsigned char *in, int inlen, int *out_b64len,
PASSWORD_ID id);
Expand Down
10 changes: 6 additions & 4 deletions src/flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ enum REPORT_FLAGS {
TOUCHED, NOT_TOUCHED,
RESET,
INITIALIZE, ITERATE,
ERASED, NOT_ERASED
ERASED, NOT_ERASED,
REPLACE, NO_REPLACE
};


Expand Down Expand Up @@ -141,20 +142,21 @@ enum REPORT_FLAGS {
#define FLAG_ERR_SIGN "Could not sign."
#define FLAG_ERR_SALT_LEN "Salt must be less than " STRINGIFY(SALT_LEN_MAX) " characters."
#define FLAG_ERR_SEED_SD "Seed creation requires an SD card for automatic encrypted backup of the seed."
#define FLAG_ERR_SEED_SD_NUM "Too many backup files. Please remove one from the SD card."
#define FLAG_ERR_SEED_MEM "Could not allocate memory for seed."
#define FLAG_ERR_ENCRYPT_MEM "Could not encrypt."
#define FLAG_ERR_ATAES "Chip communication error."
#define FLAG_ERR_FLASH "Could not read flash."
#define FLAG_ERR_NO_MCU "Ignored for non-embedded testing."
#define FLAG_ERR_SD_CARD "Please insert SD card."
#define FLAG_ERR_SD_MOUNT "Could not mount the SD card."
#define FLAG_ERR_SD_OPEN "Could not open the file."
#define FLAG_ERR_SD_OPEN "Could not open a file to write - it may already exist."
#define FLAG_ERR_SD_OPEN_DIR "Could not open the directory."
#define FLAG_ERR_SD_FILE_CORRUPT "Corrupted file."
#define FLAG_ERR_SD_WRITE "Could not write the file."
#define FLAG_ERR_SD_WRITE_LEN "Text to write is too large."
#define FLAG_ERR_SD_READ "Could not read the file."
#define FLAG_ERR_SD_NO_FILE "No files to erase in base directory."
#define FLAG_ERR_SD_FILE_EXISTS "File exists."
#define FLAG_ERR_SD_ERASE "May not have erased all files (or no file present)."
#define FLAG_ERR_NUM_FILES "Too many files to read. The list is truncated."
#define FLAG_ERR_PASSWORD_ID "Invalid password ID."

Expand Down
168 changes: 99 additions & 69 deletions src/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,23 @@ uint32_t sd_fs_found = 0;
uint32_t sd_listing_pos = 0;
uint32_t sd_num_files = 0;

static char ROOTDIR[] = "0:/DigitalBitboxFiles";

FATFS fs;


uint8_t sd_write(const char *f, uint16_t f_len, const char *t, uint16_t t_len)
uint8_t sd_write(const char *f, uint16_t f_len, const char *t, uint16_t t_len,
uint8_t replace)
{
char file[256] = {0};
memcpy(file, "0:", 2);
memcpy(file + 2, f, (f_len < 256 - 2) ? f_len : 256 - 2);
char file[256];
memset(file, 0, sizeof(file));
memcpy(file, ROOTDIR, strlen(ROOTDIR));
strncat(file, "/", 1);
strncat(file, f, (f_len < sizeof(file) - strlen(file)) ? f_len : sizeof(file) - strlen(
file));

char text[256] = {0};
if (t_len > 256) {
char text[512] = {0};
if (t_len > sizeof(text) - 1) {
commander_fill_report("sd_write", FLAG_ERR_SD_WRITE_LEN, ERROR);
goto err;
}
Expand All @@ -70,15 +76,17 @@ uint8_t sd_write(const char *f, uint16_t f_len, const char *t, uint16_t t_len)
goto err;
}

file[0] = LUN_ID_SD_MMC_0_MEM + '0';
res = f_open(&file_object, (char const *)file, FA_CREATE_NEW | FA_WRITE);
f_mkdir(ROOTDIR);

res = f_open(&file_object, (char const *)file,
(replace == REPLACE ? FA_OPEN_EXISTING : FA_CREATE_NEW) | FA_WRITE);
if (res != FR_OK) {
commander_fill_report("sd_write", FLAG_ERR_SD_FILE_EXISTS, ERROR);
commander_fill_report("sd_write", FLAG_ERR_SD_OPEN, ERROR);
f_mount(LUN_ID_SD_MMC_0_MEM, NULL);
goto err;
}

memcpy(text, t, t_len);
memcpy(text, t, (t_len < sizeof(text) - 1) ? t_len : sizeof(text) - 1);
if (0 == f_puts(text, &file_object)) {
commander_fill_report("sd_write", FLAG_ERR_SD_WRITE, ERROR);
f_close(&file_object);
Expand All @@ -104,11 +112,15 @@ uint8_t sd_write(const char *f, uint16_t f_len, const char *t, uint16_t t_len)

char *sd_load(const char *f, uint16_t f_len)
{
char file[256] = {0};
memcpy(file, "0:", 2);
memcpy(file + 2, f, (f_len < 256 - 2) ? f_len : 256 - 2);
FIL file_object;
char file[256];
memset(file, 0, sizeof(file));
memcpy(file, ROOTDIR, strlen(ROOTDIR));
strncat(file, "/", 1);
strncat(file, f, (f_len < sizeof(file) - strlen(file)) ? f_len : sizeof(file) - strlen(
file));

static char text[256];
static char text[512];
memset(text, 0, sizeof(text));

sd_mmc_init();
Expand All @@ -120,23 +132,23 @@ char *sd_load(const char *f, uint16_t f_len)
}

FRESULT res;
FIL file_object;
memset(&fs, 0, sizeof(FATFS));
res = f_mount(LUN_ID_SD_MMC_0_MEM, &fs);
if (FR_INVALID_DRIVE == res) {
commander_fill_report("sd_load", FLAG_ERR_SD_MOUNT, ERROR);
goto err;
}

file[0] = LUN_ID_SD_MMC_0_MEM + '0';
res = f_open(&file_object, (char const *)file, FA_OPEN_EXISTING | FA_READ);
if (res != FR_OK) {
commander_fill_report("sd_load", FLAG_ERR_SD_OPEN, ERROR);
f_mount(LUN_ID_SD_MMC_0_MEM, NULL);
goto err;
}

if (0 == f_gets(text, sizeof(text), &file_object)) {
UINT text_read;
res = f_read(&file_object, text, file_object.fsize, &text_read);
if (res != FR_OK) {
commander_fill_report("sd_load", FLAG_ERR_SD_READ, ERROR);
f_close(&file_object);
f_mount(LUN_ID_SD_MMC_0_MEM, NULL);
Expand All @@ -160,7 +172,6 @@ uint8_t sd_list(void)
{
FILINFO fno;
DIR dir;
const char *path = "0:";
#if _USE_LFN
char c_lfn[_MAX_LFN + 1];
fno.lfname = c_lfn;
Expand Down Expand Up @@ -189,7 +200,7 @@ uint8_t sd_list(void)
}

// Open the directory
res = f_opendir(&dir, path);
res = f_opendir(&dir, ROOTDIR);
if (res == FR_OK) {
for (;;) {
char *pc_fn;
Expand All @@ -203,7 +214,10 @@ uint8_t sd_list(void)
#else
pc_fn = fno.fname;
#endif
if (*pc_fn == '.') {
if (*pc_fn == '.' && *(pc_fn + 1) == '\0') {
continue;
}
if (*pc_fn == '.' && *(pc_fn + 1) == '.' && *(pc_fn + 2) == '\0') {
continue;
}

Expand All @@ -221,6 +235,8 @@ uint8_t sd_list(void)

pos += 1;
}
} else {
commander_fill_report("sd_list debug", "could not open dir", ERROR);
}

commander_fill_report("sd_list", files, SUCCESS);
Expand All @@ -236,42 +252,30 @@ uint8_t sd_list(void)
}



uint8_t sd_erase(void)
static uint8_t delete_files(char *path)
{
int failed = 0;
FRESULT res;
FILINFO fno;
DIR dir;
const char *path = "0:";
#if _USE_LFN
char c_lfn[_MAX_LFN + 1];
fno.lfname = c_lfn;
fno.lfsize = sizeof(c_lfn);
static char lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof lfn;
#endif

sd_mmc_init();
sd_listing_pos = 0;

if (CTRL_FAIL == sd_mmc_test_unit_ready(0)) {
commander_fill_report("sd_erase", FLAG_ERR_SD_CARD, ERROR);
return ERROR;
}

FRESULT res;
memset(&fs, 0, sizeof(FATFS));
res = f_mount(LUN_ID_SD_MMC_0_MEM, &fs);
if (FR_INVALID_DRIVE == res) {
commander_fill_report("sd_erase", FLAG_ERR_SD_MOUNT, ERROR);
return ERROR;
}

// Open the directory
res = f_opendir(&dir, path);
if (res == FR_OK) {
for (;;) {

char *pc_fn;
res = f_readdir(&dir, &fno);
if (res != FR_OK || fno.fname[0] == 0) {
if (res != FR_OK) {
failed++;
break;
}

if (fno.fname[0] == 0) { // no more files or directories
break;
}

Expand All @@ -280,43 +284,69 @@ uint8_t sd_erase(void)
#else
pc_fn = fno.fname;
#endif
if (*pc_fn == '.') {
if (*pc_fn == '.' && *(pc_fn + 1) == '\0') {
continue;
}

char file[256] = {0};
memcpy(file, "0:", 2);
memcpy(file + 2, pc_fn, (strlen(pc_fn) < 256 - 2) ? strlen(pc_fn) : 256 - 2);

FIL file_object;
file[0] = LUN_ID_SD_MMC_0_MEM + '0';
res = f_open(&file_object, (char const *)file, FA_OPEN_EXISTING | FA_WRITE);
if (res != FR_OK) {
commander_fill_report("sd_erase", FLAG_ERR_SD_OPEN, ERROR);
failed = 1;
break;
}

DWORD f_ps, fsize = file_object.fsize;
for (f_ps = 0; f_ps < fsize; f_ps++) {
f_putc(0xAC, &file_object); // overwrite data
if (*pc_fn == '.' && *(pc_fn + 1) == '.' && *(pc_fn + 2) == '\0') {
continue;
}

if (f_close(&file_object) != FR_OK) {
failed++;
char file[1024];
snprintf(file, sizeof(file), "%s/%s", path, pc_fn);

if (fno.fattrib & AM_DIR) { // is a directory
failed += delete_files(file);
} else { // is a file
FIL file_object;
res = f_open(&file_object, (char const *)file, FA_OPEN_EXISTING | FA_WRITE);
if (res != FR_OK) {
failed++;
} else {
DWORD f_ps, fsize = file_object.fsize;
for (f_ps = 0; f_ps < fsize; f_ps++) {
f_putc(0xAC, &file_object); // overwrite data
}
if (f_close(&file_object) != FR_OK) {
failed++;
}
}
}

if (f_unlink(pc_fn) != FR_OK) {
if (f_unlink(file + 2) != FR_OK) {
failed++;
}
}
}
return failed;
}

// Unmount
f_mount(LUN_ID_SD_MMC_0_MEM, NULL);

uint8_t sd_erase(void)
{
int failed = 0;
char *path = ROOTDIR;

sd_mmc_init();
sd_listing_pos = 0;

if (CTRL_FAIL == sd_mmc_test_unit_ready(0)) {
commander_fill_report("sd_erase", FLAG_ERR_SD_CARD, ERROR);
return ERROR;
}

FRESULT res;
memset(&fs, 0, sizeof(FATFS));
res = f_mount(LUN_ID_SD_MMC_0_MEM, &fs);
if (FR_INVALID_DRIVE == res) {
commander_fill_report("sd_erase", FLAG_ERR_SD_MOUNT, ERROR);
return ERROR;
}

failed = delete_files(path);

f_mount(LUN_ID_SD_MMC_0_MEM, NULL); // Unmount

if (failed) {
commander_fill_report("sd_erase", FLAG_ERR_SD_NO_FILE, ERROR);
commander_fill_report("sd_erase", FLAG_ERR_SD_ERASE, ERROR);
return ERROR;
} else {
commander_fill_report("sd_erase", "success", SUCCESS);
Expand Down
Loading

0 comments on commit ab96b29

Please sign in to comment.