Added root block for filesystem authentication

This commit is contained in:
Daniele Lacamera 2019-10-26 15:48:15 +02:00
parent 68f86aa4f7
commit 113e100708
6 changed files with 135 additions and 26 deletions

View file

@ -2,4 +2,5 @@ test/test:
make -C test
clean:
rm -f src/*.o
make -C test clean

View file

@ -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 <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/sha256.h>
#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 <wolfssl/wolfcrypt/chacha.h>
#include <wolfssl/wolfcrypt/pwdbased.h>
#include <wolfssl/wolfcrypt/sha256.h>
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);
}

View file

@ -2,9 +2,12 @@
#define INC_USECFS
#define MAX_FILENAME 256
#define MAX_OPEN_FILES 16
#define UUID_LEN 64
#include <stdint.h>
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);

View file

@ -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;
}

View file

@ -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

View file

@ -1,64 +1,102 @@
#include "usecfs.h"
#include <stdio.h>
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);