test: add test_hchacha
This commit is contained in:
parent
2a79e08343
commit
2e5886303d
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -33,3 +33,7 @@ html/
|
|||
mkfs.stpd
|
||||
*.gz
|
||||
*.pdf
|
||||
test_lzp
|
||||
test_base64
|
||||
*.trs
|
||||
stpdfs-fuse
|
|
@ -45,6 +45,7 @@ AC_CHECK_FUNCS(m4_normalize([
|
|||
AC_CONFIG_FILES([Makefile
|
||||
lib/Makefile
|
||||
tools/Makefile
|
||||
tests/Makefile
|
||||
linux/Makefile
|
||||
fuse/Makefile])
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
AM_CFLAGS = $(FUSE_CFLAGS)
|
||||
LDADD = $(FUSE_LIBS)
|
||||
AM_CFLAGS = $(FUSE_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)
|
||||
LDADD = $(FUSE_LIBS) ../lib/libstpdfs.a
|
||||
|
||||
bin_PROGRAMS = stpdfs-fuse
|
||||
|
||||
|
|
114
fuse/main.c
114
fuse/main.c
|
@ -1,19 +1,79 @@
|
|||
#include "stpdfs.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define FUSE_USE_VERSION 31
|
||||
#include <fuse.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
# include <libgen.h>
|
||||
#endif /* HAVE_LIBGEN_H */
|
||||
|
||||
static const char *prg_name;
|
||||
static int fd = -1;
|
||||
|
||||
static struct options {
|
||||
const char *filename;
|
||||
int show_help;
|
||||
int show_version;
|
||||
} options;
|
||||
|
||||
#define OPTION(t, p) { t, offsetof(struct options, p), 1 }
|
||||
|
||||
static const struct fuse_opt option_spec[] = {
|
||||
OPTION("--image=%s", filename),
|
||||
OPTION("-h", show_help),
|
||||
OPTION("--help", show_help),
|
||||
OPTION("-V", show_version),
|
||||
OPTION("--version", show_version),
|
||||
FUSE_OPT_END
|
||||
};
|
||||
|
||||
|
||||
static void *
|
||||
stpdfs_init(struct fuse_conn_info *conn,
|
||||
fuse_stpdfs_init(struct fuse_conn_info *conn,
|
||||
struct fuse_config *config)
|
||||
{
|
||||
(void)conn;
|
||||
struct stpdfs_sb sb;
|
||||
|
||||
(void)conn;
|
||||
(void)config;
|
||||
|
||||
fd = open(options.filename, O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
perror(options.filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
stpdfs_read(fd, 1, &sb, sizeof(struct stpdfs_sb));
|
||||
printf("StupidFS last opened: %s\n", asctime(localtime(&sb.time)));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fuse_stpdfs_destroy(void *data)
|
||||
{
|
||||
struct stpdfs_sb sb;
|
||||
|
||||
stpdfs_read(fd, 1, &sb, sizeof(struct stpdfs_sb)),
|
||||
sb.state = STPDFS_CLEANLY_UNMOUNTED;
|
||||
sb.time = time(NULL);
|
||||
|
||||
stpdfs_write(fd, 1, &sb, sizeof(struct stpdfs_sb));
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int
|
||||
stpdfs_getattr(const char *path, struct stat *stbuf,
|
||||
fuse_stpdfs_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
return (0);
|
||||
|
@ -21,7 +81,7 @@ stpdfs_getattr(const char *path, struct stat *stbuf,
|
|||
|
||||
|
||||
static int
|
||||
stpdfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
fuse_stpdfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
off_t offset, struct fuse_file_info *fi,
|
||||
enum fuse_readdir_flags flags)
|
||||
{
|
||||
|
@ -29,32 +89,64 @@ stpdfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
|||
}
|
||||
|
||||
static int
|
||||
stpdfs_open(const char *path, struct fuse_file_info *fi)
|
||||
fuse_stpdfs_open(const char *path, struct fuse_file_info *fi)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
stpdfs_read(const char *path, char *buf, size_t size, off_t offset,
|
||||
fuse_stpdfs_read(const char *path, char *buf, size_t size, off_t offset,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
return (size);
|
||||
}
|
||||
|
||||
static const struct fuse_operations stpdfs_oper = {
|
||||
.init = stpdfs_init,
|
||||
.getattr = stpdfs_getattr,
|
||||
.readdir = stpdfs_readdir,
|
||||
.open = stpdfs_open,
|
||||
.read = stpdfs_read
|
||||
.init = fuse_stpdfs_init,
|
||||
.destroy = fuse_stpdfs_destroy,
|
||||
.getattr = fuse_stpdfs_getattr,
|
||||
.readdir = fuse_stpdfs_readdir,
|
||||
.open = fuse_stpdfs_open,
|
||||
.read = fuse_stpdfs_read
|
||||
};
|
||||
|
||||
static void
|
||||
show_version(void)
|
||||
{
|
||||
printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
show_help(void)
|
||||
{
|
||||
printf("Usage: %s --image=<filename> <mountpoint>\n", prg_name);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
|
||||
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
prg_name = basename(argv[0]);
|
||||
#else
|
||||
prg_name = argv[0];
|
||||
#endif /* HAVE_LIBGEN_H */
|
||||
|
||||
if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
|
||||
{
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (options.show_version) show_version();
|
||||
if (options.show_help) show_help();
|
||||
|
||||
if (options.filename == NULL) show_help();
|
||||
|
||||
ret = fuse_main(args.argc, args.argv, &stpdfs_oper, NULL);
|
||||
fuse_opt_free_args(&args);
|
||||
return (ret);
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
noinst_LIBRARIES = libstpdfs.a
|
||||
libstpdfs_a_SOURCES = block.c superblock.c codec/base64.c compression/lzp.c
|
||||
libstpdfs_a_SOURCES = block.c superblock.c codec/base64.c compression/lzp.c crypto/hchacha.c
|
24
lib/crypto/chacha.h
Normal file
24
lib/crypto/chacha.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef STPDFS_CRYPTO_CHACHA_H
|
||||
# define STPDFS_CRYPTO_CHACHA_H 1
|
||||
|
||||
# define CHACHA_CONST1 "expa"
|
||||
# define CHACHA_CONST2 "nd 3"
|
||||
# define CHACHA_CONST3 "2-by"
|
||||
# define CHACHA_CONST4 "te k"
|
||||
|
||||
#define CHACHA_ROT_L(x, n) (((x) << (n))|((x) >> (32 - (n))))
|
||||
#define CHACHA_QUARTERROUND(a, b, c, d) do { \
|
||||
a += b; d ^= a; d = CHACHA_ROT_L(d, 16); \
|
||||
c += d; b ^= c; b = CHACHA_ROT_L(b, 12); \
|
||||
a += b; d ^= a; d = CHACHA_ROT_L(d, 8); \
|
||||
c += d; b ^= c; b = CHACHA_ROT_L(b, 7); \
|
||||
} while (0)
|
||||
|
||||
# define HCHACHA_KEY_BYTES 32
|
||||
# define HCHACHA_NONCE_BYTES 16
|
||||
# define HCHACHA_OUT_BYTES 32
|
||||
# define HCHACHA_CONST_BYTES 16
|
||||
|
||||
# define TO_LE_32(x) ((x)[0]) | ((x)[1] << 8) | ((x)[2] << 16) | ((x)[3] << 24)
|
||||
|
||||
#endif /* STPDFS_CRYPTO_CHACHA_H */
|
67
lib/crypto/hchacha.c
Normal file
67
lib/crypto/hchacha.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include <string.h>
|
||||
#include <endian.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "chacha.h"
|
||||
|
||||
void
|
||||
hchacha(uint8_t out[HCHACHA_OUT_BYTES],
|
||||
const uint8_t key[HCHACHA_KEY_BYTES],
|
||||
const uint8_t nonce[HCHACHA_NONCE_BYTES],
|
||||
int round)
|
||||
{
|
||||
int idx;
|
||||
|
||||
uint32_t state[4][4];
|
||||
|
||||
state[0][0] = TO_LE_32(CHACHA_CONST1);
|
||||
state[0][1] = TO_LE_32(CHACHA_CONST2);
|
||||
state[0][2] = TO_LE_32(CHACHA_CONST3);
|
||||
state[0][3] = TO_LE_32(CHACHA_CONST4);
|
||||
|
||||
state[1][0] = TO_LE_32(key);
|
||||
state[1][1] = TO_LE_32(key + 4);
|
||||
state[1][2] = TO_LE_32(key + 4 * 2);
|
||||
state[1][3] = TO_LE_32(key + 4 * 3);
|
||||
|
||||
state[2][0] = TO_LE_32(key + 16);
|
||||
state[2][1] = TO_LE_32(key + 16 + 4);
|
||||
state[2][2] = TO_LE_32(key + 16 + 4 * 2);
|
||||
state[2][3] = TO_LE_32(key + 16 + 4 * 3);
|
||||
|
||||
state[3][0] = TO_LE_32(nonce);
|
||||
state[3][1] = TO_LE_32(nonce + 4);
|
||||
state[3][2] = TO_LE_32(nonce + 8);
|
||||
state[3][3] = TO_LE_32(nonce + 12);
|
||||
|
||||
for (idx = 0; idx < round/2; idx++)
|
||||
{
|
||||
CHACHA_QUARTERROUND(state[0][0], state[1][0], state[2][0], state[3][0]);
|
||||
CHACHA_QUARTERROUND(state[0][1], state[1][1], state[2][1], state[3][1]);
|
||||
CHACHA_QUARTERROUND(state[0][2], state[1][2], state[2][2], state[3][2]);
|
||||
CHACHA_QUARTERROUND(state[0][3], state[1][3], state[2][3], state[3][3]);
|
||||
|
||||
CHACHA_QUARTERROUND(state[0][0], state[1][1], state[2][2], state[3][3]);
|
||||
CHACHA_QUARTERROUND(state[0][1], state[1][2], state[2][3], state[3][0]);
|
||||
CHACHA_QUARTERROUND(state[0][2], state[1][3], state[2][0], state[3][1]);
|
||||
CHACHA_QUARTERROUND(state[0][3], state[1][0], state[2][1], state[3][2]);
|
||||
}
|
||||
|
||||
*(uint32_t *)(out + 0) = htole32(state[0][0]);
|
||||
*(uint32_t *)(out + 4) = htole32(state[0][1]);
|
||||
*(uint32_t *)(out + 8) = htole32(state[0][2]);
|
||||
*(uint32_t *)(out + 12) = htole32(state[0][3]);
|
||||
|
||||
*(uint32_t *)(out + 16) = htole32(state[3][0]);
|
||||
*(uint32_t *)(out + 20) = htole32(state[3][1]);
|
||||
*(uint32_t *)(out + 24) = htole32(state[3][2]);
|
||||
*(uint32_t *)(out + 28) = htole32(state[3][3]);
|
||||
}
|
||||
|
||||
void
|
||||
hchacha12(uint8_t out[HCHACHA_OUT_BYTES],
|
||||
const uint8_t key[HCHACHA_KEY_BYTES],
|
||||
const uint8_t nonce[HCHACHA_NONCE_BYTES])
|
||||
{
|
||||
return (hchacha(out, key, nonce, 12));
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
AM_CPPFLAGS = -I$(top_srcdir)/lib
|
||||
|
||||
TESTS = test_lzp test_base64
|
||||
check_PROGRAMS = test_lzp test_base64
|
||||
TESTS = test_lzp test_base64 test_hchacha
|
||||
check_PROGRAMS = test_lzp test_base64 test_hchacha
|
||||
|
||||
LDADD = -lcmocka ../lib/libstpdfs.a
|
||||
|
||||
test_lzp_SOURCES = test_lzp.c
|
||||
|
||||
test_base64_SOURCES = test_base64.c
|
||||
|
||||
test_hchacha_SOURCES = test_hchacha.c
|
||||
|
|
48
tests/test_hchacha.c
Normal file
48
tests/test_hchacha.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
#include <crypto/chacha.h>
|
||||
|
||||
/* test from https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha-03#section-2.2 */
|
||||
|
||||
void
|
||||
hchacha(uint8_t out[HCHACHA_OUT_BYTES],
|
||||
const uint8_t key[HCHACHA_KEY_BYTES],
|
||||
const uint8_t nonce[HCHACHA_NONCE_BYTES],
|
||||
int round);
|
||||
|
||||
uint8_t key[HCHACHA_KEY_BYTES] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
||||
};
|
||||
|
||||
uint8_t nonce[HCHACHA_NONCE_BYTES] = {
|
||||
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x31, 0x41, 0x59, 0x27
|
||||
};
|
||||
|
||||
static void
|
||||
test_hchacha20(void **state)
|
||||
{
|
||||
uint8_t out[HCHACHA_OUT_BYTES];
|
||||
uint8_t expected[HCHACHA_OUT_BYTES] = {
|
||||
0x82, 0x41, 0x3b, 0x42, 0x27, 0xb2, 0x7b, 0xfe, 0xd3, 0x0e, 0x42, 0x50, 0x8a, 0x87, 0x7d, 0x73,
|
||||
0xa0, 0xf9, 0xe4, 0xd5, 0x8a, 0x74, 0xa8, 0x53, 0xc1, 0x2e, 0xc4, 0x13, 0x26, 0xd3, 0xec, 0xdc
|
||||
};
|
||||
|
||||
hchacha(out, key, nonce, 20);
|
||||
assert_memory_equal(expected, out, HCHACHA_OUT_BYTES);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_hchacha20),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
|
@ -10,6 +10,7 @@ void lzp_decompress(uint8_t *out, size_t *outsz, const uint8_t *in, size_t insz)
|
|||
static const char uncompress_data[298] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||
"abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
|
||||
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccabcabcabcabcabcabcabcabcabcabcabcabcabcabc";
|
||||
|
||||
static void
|
||||
test_lzp(void **state)
|
||||
{
|
||||
|
@ -18,6 +19,8 @@ test_lzp(void **state)
|
|||
size_t outsz;
|
||||
|
||||
lzp_compress(compressed, &outsz, (uint8_t *)uncompress_data, 298);
|
||||
assert_true(outsz < 298);
|
||||
|
||||
lzp_decompress((uint8_t *)result, &outsz, compressed, outsz);
|
||||
|
||||
assert_int_equal(298, outsz);
|
||||
|
|
46
tests/test_xchacha.c
Normal file
46
tests/test_xchacha.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
#include <crypto/chacha.h>
|
||||
|
||||
void
|
||||
hchacha(uint8_t out[HCHACHA_OUT_BYTES],
|
||||
const uint8_t key[HCHACHA_KEY_BYTES],
|
||||
const uint8_t nonce[HCHACHA_NONCE_BYTES],
|
||||
int round);
|
||||
|
||||
uint8_t key[HCHACHA_KEY_BYTES] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
||||
};
|
||||
|
||||
uint8_t nonce[HCHACHA_NONCE_BYTES] = {
|
||||
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x31, 0x41, 0x59, 0x27
|
||||
};
|
||||
|
||||
static void
|
||||
test_xchacha20(void **state)
|
||||
{
|
||||
uint8_t out[HCHACHA_OUT_BYTES];
|
||||
uint8_t expected[HCHACHA_OUT_BYTES] = {
|
||||
0x82, 0x41, 0x3b, 0x42, 0x27, 0xb2, 0x7b, 0xfe, 0xd3, 0x0e, 0x42, 0x50, 0x8a, 0x87, 0x7d, 0x73,
|
||||
0xa0, 0xf9, 0xe4, 0xd5, 0x8a, 0x74, 0xa8, 0x53, 0xc1, 0x2e, 0xc4, 0x13, 0x26, 0xd3, 0xec, 0xdc
|
||||
};
|
||||
|
||||
hchacha(out, key, nonce, 20);
|
||||
assert_memory_equal(expected, out, HCHACHA_OUT_BYTES);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_xchacha20),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
Loading…
Reference in a new issue