From 113e100708ab57af019330aefe2951e91830a6c2 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Sat, 26 Oct 2019 15:48:15 +0200 Subject: [PATCH] Added root block for filesystem authentication --- Makefile | 1 + src/usecfs.c | 76 +++++++++++++++++++++++++++++++++++++++---- src/usecfs.h | 5 ++- src/usecfs_dev_test.c | 11 +++++-- test/Makefile | 2 +- test/main.c | 66 +++++++++++++++++++++++++++++-------- 6 files changed, 135 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index e5cc79c..ffe7709 100644 --- a/Makefile +++ b/Makefile @@ -2,4 +2,5 @@ test/test: make -C test clean: + rm -f src/*.o make -C test clean diff --git a/src/usecfs.c b/src/usecfs.c index b6fac5d..ee74669 100644 --- a/src/usecfs.c +++ b/src/usecfs.c @@ -18,9 +18,10 @@ #define MAX_INLINE_SIZE ((MAX_BLOCKS_0 - 1) * 4) /* Max data size for self-contained block */ #define INLINE_PAYLOAD(x) ((uint8_t *)(&x->blk[1])) /* Macro to access INLINE paylaod */ -#ifdef CRYPTO #include #include +#include +#ifdef CRYPTO #define CRYPTO_BLOCK_SIZE 16 uint8_t crypto_tmp[CRYPTO_BLOCK_SIZE]; @@ -28,12 +29,14 @@ uint8_t crypto_iv[CRYPTO_BLOCK_SIZE]; #include #include -#include static ChaCha chacha; #define CRYPTO_KEY_SIZE 32 #endif +#define HASH_LEN 32 +#define MAGIC 0x5AFED15C + static uint8_t cache[BLOCK_SIZE]; static uint8_t inline_buffer_copy[MAX_INLINE_SIZE]; @@ -51,11 +54,19 @@ struct __attribute__((packed)) inode { char filename[MAX_FILENAME]; }; +struct __attribute__((packed)) root_block { + uint32_t magic; + uint32_t blk[((BLOCK_SIZE - MAX_FILENAME) / 4) - 3]; + uint32_t fs_size; /* unused */ + uint32_t nextfile; + uint8_t uuid[UUID_LEN]; + uint8_t hash[HASH_LEN]; +}; + + /* One-sector cache, single entry point for read/write * on blocks */ - - static uint32_t cached_block = NO_BLOCK; void *blockdev = NULL; @@ -140,6 +151,13 @@ static uint32_t get_free_block(uint32_t *fs_tail) uint32_t cur_inode_0 = 0; int i; cache_load(0); + if (ci->nextfile == NO_BLOCK) { + if (fs_tail) + *fs_tail = 0; + return 1; + } + cur_inode_0 = ci->nextfile; + cache_load(cur_inode_0); while (1) { for (i = 0; i < MAX_BLOCKS_0; i++) { @@ -187,6 +205,7 @@ static uint32_t new_inode(void) cache_load(fs_tail); ci->nextfile = new_block; cache_load(new_block); + memset(cache, 0xFF, BLOCK_SIZE); ci->nextfile = NO_BLOCK; return new_block; } @@ -291,6 +310,42 @@ static void file_grow(uint32_t node0, uint32_t newsize) ci->size = newsize; } +/* Public interface */ + +int usecfs_format(const uint8_t *uuid) +{ + struct root_block *rb = (struct root_block *)cache; + wc_Sha256 sha; + cache_load(0); + memset(cache, 0xFF, BLOCK_SIZE); + rb->magic = MAGIC; + rb->blk[0] = 0; + memcpy(rb->uuid, uuid, UUID_LEN); + wc_InitSha256(&sha); + wc_Sha256Update(&sha, uuid, UUID_LEN); + wc_Sha256Final(&sha, rb->hash); + cache_commit(); + return 0; +} + +int usecfs_mount(uint8_t *uuid) +{ + struct root_block *rb = (struct root_block *)cache; + wc_Sha256 sha; + uint8_t hash[HASH_LEN]; + cache_load(0); + if (rb->magic != MAGIC) + return -1; + wc_InitSha256(&sha); + wc_Sha256Update(&sha, rb->uuid, UUID_LEN); + wc_Sha256Final(&sha, hash); + if (memcmp(hash, rb->hash, HASH_LEN) != 0) + return -1; + if (uuid) + memcpy(uuid, rb->uuid, UUID_LEN); + return 0; +} + int usecfs_read(int fd, void *data, uint32_t len) { int r = 0; @@ -505,7 +560,7 @@ int usecfs_truncate(int fd, uint32_t newsize) cache_load(new_idx_block); if (idx_block != new_idx_block) ci->extra = NO_BLOCK; - if (idx_off <= MAX_BLOCKS_0) { + if (idx_block <= MAX_BLOCKS_0) { idx_off = new_idx_block; for (i = idx_off; i < MAX_BLOCKS_N; i++) ce->blk[i] = NO_BLOCK; @@ -551,6 +606,7 @@ int usecfs_close(int fd) cache_commit(); OpenFiles[fd].blk = NO_BLOCK; } + return 0; } #ifdef CRYPTO @@ -562,7 +618,7 @@ const uint8_t password_salt[SALT_LEN] = { }; #endif -int usecfs_init(const char *password) +int usecfs_init(const char *password, int format, uint8_t *uuid) { blockdev = block_open(BLOCKDEV_OPEN_ARGS); if (!blockdev) @@ -576,5 +632,11 @@ int usecfs_init(const char *password) wc_Chacha_SetKey(&chacha, chacha_key, CRYPTO_KEY_SIZE); } #endif - return 0; + if (format) { + if (!uuid) + return -1; + else + return usecfs_format(uuid); + } else + return usecfs_mount(uuid); } diff --git a/src/usecfs.h b/src/usecfs.h index c149031..6c4b1aa 100644 --- a/src/usecfs.h +++ b/src/usecfs.h @@ -2,9 +2,12 @@ #define INC_USECFS #define MAX_FILENAME 256 #define MAX_OPEN_FILES 16 +#define UUID_LEN 64 #include -int usecfs_init(const char *password); +int usecfs_init(const char *password, int format, uint8_t *uuid); +int usecfs_format(const uint8_t *uuid); +int usecfs_mount(uint8_t *uuid); int usecfs_open(const char *name); int usecfs_creat(const char *name); int usecfs_read(int fd, void *data, uint32_t len); diff --git a/src/usecfs_dev_test.c b/src/usecfs_dev_test.c index 7851018..c7a25e1 100644 --- a/src/usecfs_dev_test.c +++ b/src/usecfs_dev_test.c @@ -12,11 +12,16 @@ void *block_open(void *args) char *file = (char *)args; int i; uint8_t ff = 0xFF; - fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0660); + fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0660); + if (fd >= 0) { + for (i = 0; i < FS_SIZE; i++) + write(fd, &ff, 1); + } else { + fd = open(file, O_RDWR); + } if (fd < 0) return NULL; - for (i = 0; i < FS_SIZE; i++) - write(fd, &ff, 1); + lseek(fd, 0, SEEK_SET); return &fd; } diff --git a/test/Makefile b/test/Makefile index 89fec2e..7eb5ddc 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,4 +6,4 @@ test: main.o ../src/usecfs.o ../src/usecfs_dev_test.o gcc -o $@ $^ -lwolfssl clean: - @rm -f main.o ../src/*.o + @rm -f test main.o ../src/*.o diff --git a/test/main.c b/test/main.c index befc705..77b440e 100644 --- a/test/main.c +++ b/test/main.c @@ -1,64 +1,102 @@ #include "usecfs.h" #include +const uint8_t test_uuid[UUID_LEN] = { + 0xb3, 0x6b, 0x82, 0x05, 0xb6, 0xcd, 0x28, 0xaa, 0xc7, 0x81, 0x2e, 0x2d, + 0xfd, 0xdd, 0x5e, 0x70, 0x3f, 0xbf, 0x09, 0x03, 0x1b, 0x5f, 0xbe, 0xc6, + 0x09, 0x62, 0xa8, 0x23, 0xe9, 0x99, 0x5e, 0xcb, 0xb4, 0xab, 0x28, 0xdc, + 0x14, 0xca, 0x35, 0xb4, 0x7d, 0xfe, 0x26, 0x81, 0x33, 0xd0, 0x4b, 0xc2, + 0x49, 0x53, 0x05, 0xc3, 0xe7, 0xbd, 0x9a, 0x50, 0xb8, 0x01, 0x30, 0x0b, + 0x62, 0x58, 0xad, 0xbf +}; + int main(void) { int fd; int buf[40] = { }; + int uuid[UUID_LEN]; - if (usecfs_init("sEcret") < 0) + if (usecfs_init("sEcret", 0, NULL) < 0) { - printf("error.\n"); - return 1; + printf("Filesystem is not formatted. Formatting.\n"); + if (usecfs_init("sEcret", 1, test_uuid) != 0) { + printf("Format failed.\n"); + return 1; + } } + printf("Creating file 'file1' \n"); fd = usecfs_creat("file1"); if (fd < 0) { - printf("error: creat.\n"); - return 1; + printf("could not create file (this is OK unless open fails)\n"); + fd = usecfs_open("file1"); + if (fd < 0) { + printf("error: open\n"); + return 1; + } } - if (usecfs_write(fd, "test string file 1 content", 26) < 0) { + printf("Writing to file 'file1' \n"); + if (usecfs_write(fd, "test string file 1 content\n", 27) < 0) { printf("error: write.\n"); return 1; } usecfs_close(fd); + printf("Re-opening\n"); fd = usecfs_open("file1"); if (fd < 0) { printf("error: open\n"); return 1; } - if (usecfs_read(fd, buf, 26) != 26) { + printf("Reading file...\n"); + if (usecfs_read(fd, buf, 27) != 27) { printf("error: read.\n"); return 1; } - printf("%s", buf); - if (usecfs_write(fd, "test string2", 12) < 0) { + printf("content of file 'file1': "); + printf("%s\n", buf); + + printf("appending 'test string2'\n"); + if (usecfs_write(fd, "test string2\n", 13) < 0) { printf("error: write.\n"); return 1; } + printf("seek to 0\n"); if (usecfs_seek(fd, 0, 0) != 0) { printf("error: seek.\n"); return 1; } - if (usecfs_read(fd, buf, 36) != 36) { + printf("Reading...\n"); + if (usecfs_read(fd, buf, 40) < 0) { printf("error: read.\n"); return 1; } printf("%s", buf); usecfs_close(fd); + printf("Creating file 'file2' \n"); fd = usecfs_creat("file2"); if (fd < 0) { - printf("error: creat2.\n"); - return 1; + printf("could not create file (this is OK unless open fails)\n"); + fd = usecfs_open("file2"); + if (fd < 0) { + printf("error: open\n"); + return 1; + } } usecfs_close(fd); + printf("Creating file 'file3' \n"); fd = usecfs_creat("file3"); if (fd < 0) { - printf("error: creat2.\n"); - return 1; + if (fd < 0) { + printf("could not create file (this is OK unless open fails)\n"); + fd = usecfs_open("file3"); + if (fd < 0) { + printf("error: open\n"); + return 1; + } + } } usecfs_close(fd);