Added root block for filesystem authentication
This commit is contained in:
parent
68f86aa4f7
commit
113e100708
6 changed files with 135 additions and 26 deletions
1
Makefile
1
Makefile
|
@ -2,4 +2,5 @@ test/test:
|
||||||
make -C test
|
make -C test
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
rm -f src/*.o
|
||||||
make -C test clean
|
make -C test clean
|
||||||
|
|
76
src/usecfs.c
76
src/usecfs.c
|
@ -18,9 +18,10 @@
|
||||||
#define MAX_INLINE_SIZE ((MAX_BLOCKS_0 - 1) * 4) /* Max data size for self-contained block */
|
#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 */
|
#define INLINE_PAYLOAD(x) ((uint8_t *)(&x->blk[1])) /* Macro to access INLINE paylaod */
|
||||||
|
|
||||||
#ifdef CRYPTO
|
|
||||||
#include <wolfssl/wolfcrypt/settings.h>
|
#include <wolfssl/wolfcrypt/settings.h>
|
||||||
#include <wolfssl/options.h>
|
#include <wolfssl/options.h>
|
||||||
|
#include <wolfssl/wolfcrypt/sha256.h>
|
||||||
|
#ifdef CRYPTO
|
||||||
#define CRYPTO_BLOCK_SIZE 16
|
#define CRYPTO_BLOCK_SIZE 16
|
||||||
|
|
||||||
uint8_t crypto_tmp[CRYPTO_BLOCK_SIZE];
|
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/chacha.h>
|
||||||
#include <wolfssl/wolfcrypt/pwdbased.h>
|
#include <wolfssl/wolfcrypt/pwdbased.h>
|
||||||
#include <wolfssl/wolfcrypt/sha256.h>
|
|
||||||
|
|
||||||
static ChaCha chacha;
|
static ChaCha chacha;
|
||||||
#define CRYPTO_KEY_SIZE 32
|
#define CRYPTO_KEY_SIZE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define HASH_LEN 32
|
||||||
|
#define MAGIC 0x5AFED15C
|
||||||
|
|
||||||
static uint8_t cache[BLOCK_SIZE];
|
static uint8_t cache[BLOCK_SIZE];
|
||||||
static uint8_t inline_buffer_copy[MAX_INLINE_SIZE];
|
static uint8_t inline_buffer_copy[MAX_INLINE_SIZE];
|
||||||
|
|
||||||
|
@ -51,11 +54,19 @@ struct __attribute__((packed)) inode {
|
||||||
char filename[MAX_FILENAME];
|
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
|
/* One-sector cache, single entry point for read/write
|
||||||
* on blocks
|
* on blocks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static uint32_t cached_block = NO_BLOCK;
|
static uint32_t cached_block = NO_BLOCK;
|
||||||
void *blockdev = NULL;
|
void *blockdev = NULL;
|
||||||
|
|
||||||
|
@ -140,6 +151,13 @@ static uint32_t get_free_block(uint32_t *fs_tail)
|
||||||
uint32_t cur_inode_0 = 0;
|
uint32_t cur_inode_0 = 0;
|
||||||
int i;
|
int i;
|
||||||
cache_load(0);
|
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) {
|
while (1) {
|
||||||
for (i = 0; i < MAX_BLOCKS_0; i++)
|
for (i = 0; i < MAX_BLOCKS_0; i++)
|
||||||
{
|
{
|
||||||
|
@ -187,6 +205,7 @@ static uint32_t new_inode(void)
|
||||||
cache_load(fs_tail);
|
cache_load(fs_tail);
|
||||||
ci->nextfile = new_block;
|
ci->nextfile = new_block;
|
||||||
cache_load(new_block);
|
cache_load(new_block);
|
||||||
|
memset(cache, 0xFF, BLOCK_SIZE);
|
||||||
ci->nextfile = NO_BLOCK;
|
ci->nextfile = NO_BLOCK;
|
||||||
return new_block;
|
return new_block;
|
||||||
}
|
}
|
||||||
|
@ -291,6 +310,42 @@ static void file_grow(uint32_t node0, uint32_t newsize)
|
||||||
ci->size = 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 usecfs_read(int fd, void *data, uint32_t len)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
@ -505,7 +560,7 @@ int usecfs_truncate(int fd, uint32_t newsize)
|
||||||
cache_load(new_idx_block);
|
cache_load(new_idx_block);
|
||||||
if (idx_block != new_idx_block)
|
if (idx_block != new_idx_block)
|
||||||
ci->extra = NO_BLOCK;
|
ci->extra = NO_BLOCK;
|
||||||
if (idx_off <= MAX_BLOCKS_0) {
|
if (idx_block <= MAX_BLOCKS_0) {
|
||||||
idx_off = new_idx_block;
|
idx_off = new_idx_block;
|
||||||
for (i = idx_off; i < MAX_BLOCKS_N; i++)
|
for (i = idx_off; i < MAX_BLOCKS_N; i++)
|
||||||
ce->blk[i] = NO_BLOCK;
|
ce->blk[i] = NO_BLOCK;
|
||||||
|
@ -551,6 +606,7 @@ int usecfs_close(int fd)
|
||||||
cache_commit();
|
cache_commit();
|
||||||
OpenFiles[fd].blk = NO_BLOCK;
|
OpenFiles[fd].blk = NO_BLOCK;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CRYPTO
|
#ifdef CRYPTO
|
||||||
|
@ -562,7 +618,7 @@ const uint8_t password_salt[SALT_LEN] = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int usecfs_init(const char *password)
|
int usecfs_init(const char *password, int format, uint8_t *uuid)
|
||||||
{
|
{
|
||||||
blockdev = block_open(BLOCKDEV_OPEN_ARGS);
|
blockdev = block_open(BLOCKDEV_OPEN_ARGS);
|
||||||
if (!blockdev)
|
if (!blockdev)
|
||||||
|
@ -576,5 +632,11 @@ int usecfs_init(const char *password)
|
||||||
wc_Chacha_SetKey(&chacha, chacha_key, CRYPTO_KEY_SIZE);
|
wc_Chacha_SetKey(&chacha, chacha_key, CRYPTO_KEY_SIZE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
if (format) {
|
||||||
|
if (!uuid)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return usecfs_format(uuid);
|
||||||
|
} else
|
||||||
|
return usecfs_mount(uuid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
#define INC_USECFS
|
#define INC_USECFS
|
||||||
#define MAX_FILENAME 256
|
#define MAX_FILENAME 256
|
||||||
#define MAX_OPEN_FILES 16
|
#define MAX_OPEN_FILES 16
|
||||||
|
#define UUID_LEN 64
|
||||||
#include <stdint.h>
|
#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_open(const char *name);
|
||||||
int usecfs_creat(const char *name);
|
int usecfs_creat(const char *name);
|
||||||
int usecfs_read(int fd, void *data, uint32_t len);
|
int usecfs_read(int fd, void *data, uint32_t len);
|
||||||
|
|
|
@ -12,11 +12,16 @@ void *block_open(void *args)
|
||||||
char *file = (char *)args;
|
char *file = (char *)args;
|
||||||
int i;
|
int i;
|
||||||
uint8_t ff = 0xFF;
|
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)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < FS_SIZE; i++)
|
|
||||||
write(fd, &ff, 1);
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
return &fd;
|
return &fd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,4 @@ test: main.o ../src/usecfs.o ../src/usecfs_dev_test.o
|
||||||
gcc -o $@ $^ -lwolfssl
|
gcc -o $@ $^ -lwolfssl
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f main.o ../src/*.o
|
@rm -f test main.o ../src/*.o
|
||||||
|
|
66
test/main.c
66
test/main.c
|
@ -1,64 +1,102 @@
|
||||||
#include "usecfs.h"
|
#include "usecfs.h"
|
||||||
#include <stdio.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 main(void)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int buf[40] = { };
|
int buf[40] = { };
|
||||||
|
int uuid[UUID_LEN];
|
||||||
|
|
||||||
if (usecfs_init("sEcret") < 0)
|
if (usecfs_init("sEcret", 0, NULL) < 0)
|
||||||
{
|
{
|
||||||
printf("error.\n");
|
printf("Filesystem is not formatted. Formatting.\n");
|
||||||
return 1;
|
if (usecfs_init("sEcret", 1, test_uuid) != 0) {
|
||||||
|
printf("Format failed.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Creating file 'file1' \n");
|
||||||
fd = usecfs_creat("file1");
|
fd = usecfs_creat("file1");
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
printf("error: creat.\n");
|
printf("could not create file (this is OK unless open fails)\n");
|
||||||
return 1;
|
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");
|
printf("error: write.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
usecfs_close(fd);
|
usecfs_close(fd);
|
||||||
|
|
||||||
|
printf("Re-opening\n");
|
||||||
fd = usecfs_open("file1");
|
fd = usecfs_open("file1");
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
printf("error: open\n");
|
printf("error: open\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (usecfs_read(fd, buf, 26) != 26) {
|
printf("Reading file...\n");
|
||||||
|
if (usecfs_read(fd, buf, 27) != 27) {
|
||||||
printf("error: read.\n");
|
printf("error: read.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf("%s", buf);
|
printf("content of file 'file1': ");
|
||||||
if (usecfs_write(fd, "test string2", 12) < 0) {
|
printf("%s\n", buf);
|
||||||
|
|
||||||
|
printf("appending 'test string2'\n");
|
||||||
|
if (usecfs_write(fd, "test string2\n", 13) < 0) {
|
||||||
printf("error: write.\n");
|
printf("error: write.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
printf("seek to 0\n");
|
||||||
if (usecfs_seek(fd, 0, 0) != 0) {
|
if (usecfs_seek(fd, 0, 0) != 0) {
|
||||||
printf("error: seek.\n");
|
printf("error: seek.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (usecfs_read(fd, buf, 36) != 36) {
|
printf("Reading...\n");
|
||||||
|
if (usecfs_read(fd, buf, 40) < 0) {
|
||||||
printf("error: read.\n");
|
printf("error: read.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf("%s", buf);
|
printf("%s", buf);
|
||||||
usecfs_close(fd);
|
usecfs_close(fd);
|
||||||
|
printf("Creating file 'file2' \n");
|
||||||
fd = usecfs_creat("file2");
|
fd = usecfs_creat("file2");
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
printf("error: creat2.\n");
|
printf("could not create file (this is OK unless open fails)\n");
|
||||||
return 1;
|
fd = usecfs_open("file2");
|
||||||
|
if (fd < 0) {
|
||||||
|
printf("error: open\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
usecfs_close(fd);
|
usecfs_close(fd);
|
||||||
|
printf("Creating file 'file3' \n");
|
||||||
fd = usecfs_creat("file3");
|
fd = usecfs_creat("file3");
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
printf("error: creat2.\n");
|
if (fd < 0) {
|
||||||
return 1;
|
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);
|
usecfs_close(fd);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue