Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys/vfs_util: add vfs_file_<hash>() functions and md5sum, sha1sum and sha256sum shell commands #18040

Merged
merged 6 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ PSEUDOMODULES += mpu_stack_guard
## This is a protection mechanism which makes exploitation of buffer overflows significantly harder.
PSEUDOMODULES += mpu_noexec_ram

PSEUDOMODULES += md5sum
PSEUDOMODULES += mtd_write_page
PSEUDOMODULES += nanocoap_%
PSEUDOMODULES += netdev_default
Expand Down Expand Up @@ -196,6 +197,8 @@ PSEUDOMODULES += semtech_loramac_rx
PSEUDOMODULES += senml_cbor
PSEUDOMODULES += senml_phydat
PSEUDOMODULES += senml_saul
PSEUDOMODULES += sha1sum
PSEUDOMODULES += sha256sum
PSEUDOMODULES += shell_hooks
PSEUDOMODULES += slipdev_stdio
PSEUDOMODULES += slipdev_l2addr
Expand Down
5 changes: 5 additions & 0 deletions sys/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,11 @@ ifneq (,$(filter shell_commands,$(USEMODULE)))
endif
endif

ifneq (,$(filter md5sum sha1sum sha256sum,$(USEMODULE)))
USEMODULE += vfs_util
USEMODULE += hashes
endif

ifneq (,$(filter posix_semaphore,$(USEMODULE)))
USEMODULE += sema_deprecated
USEMODULE += ztimer64_usec
Expand Down
50 changes: 50 additions & 0 deletions sys/include/vfs_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,56 @@ int vfs_file_from_buffer(const char *file, const void *buf, size_t len);
*/
int vfs_file_to_buffer(const char* file, void* buf, size_t len);

#if MODULE_HASHES || DOXYGEN
/**
* @brief Compute the MD5 message digest of a file
*
* Requires the `hashes` module.
*
* @param[in] file Source file path
* @param[out] digest Destination buffer, must fit @ref MD5_DIGEST_LENGTH bytes
* @param[out] work_buf Work buffer
* @param[in] work_buf_len Size of the work buffer
*
* @return 0 on success
* @return negative error
*/
int vfs_file_md5(const char* file, void *digest,
void *work_buf, size_t work_buf_len);

/**
* @brief Compute the SHA1 message digest of a file
*
* Requires the `hashes` module.
*
* @param[in] file Source file path
* @param[out] digest Destination buffer, must fit @ref SHA1_DIGEST_LENGTH bytes
* @param[out] work_buf Work buffer
* @param[in] work_buf_len Size of the work buffer
*
* @return 0 on success
* @return negative error
*/
int vfs_file_sha1(const char* file, void *digest,
void *work_buf, size_t work_buf_len);

/**
* @brief Compute the SHA256 message digest of a file
*
* Requires the `hashes` module.
*
* @param[in] file Source file path
* @param[out] digest Destination buffer, must fit @ref SHA256_DIGEST_LENGTH bytes
* @param[out] work_buf Work buffer
* @param[in] work_buf_len Size of the work buffer
*
* @return 0 on success
* @return negative error
*/
int vfs_file_sha256(const char* file, void *digest,
void *work_buf, size_t work_buf_len);
#endif

#ifdef __cplusplus
}
#endif
Expand Down
92 changes: 92 additions & 0 deletions sys/shell/commands/sc_vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
#include <fcntl.h>

#include "vfs.h"
#if MODULE_VFS_UTIL
#include "vfs_util.h"
#endif

#define SHELL_VFS_BUFSIZE 256
static uint8_t _shell_vfs_data_buffer[SHELL_VFS_BUFSIZE];
Expand Down Expand Up @@ -634,4 +637,93 @@ int _vfs_handler(int argc, char **argv)
return 1;
}
}

static inline void _print_digest(const uint8_t *digest, size_t len, const char *file)
{
for (unsigned i = 0; i < len; ++i) {
printf("%02x", digest[i]);
}
printf(" %s\n", file);
}

#if MODULE_MD5SUM
#include "hashes/md5.h"
int _vfs_md5sum_cmd(int argc, char **argv)
{
int res;
uint8_t digest[MD5_DIGEST_LENGTH];

if (argc < 2) {
printf("usage: %s [file] …\n", argv[0]);
return -1;
}

for (int i = 1; i < argc; ++i) {
const char *file = argv[i];
res = vfs_file_md5(file, digest,
_shell_vfs_data_buffer, sizeof(_shell_vfs_data_buffer));
if (res < 0) {
printf("%s: error %d\n", file, res);
} else {
_print_digest(digest, sizeof(digest), file);
}
}

return 0;
}
#endif

#if MODULE_SHA1SUM
#include "hashes/sha1.h"
int _vfs_sha1sum_cmd(int argc, char **argv)
{
int res;
uint8_t digest[SHA1_DIGEST_LENGTH];

if (argc < 2) {
printf("usage: %s [file] …\n", argv[0]);
return -1;
}

for (int i = 1; i < argc; ++i) {
const char *file = argv[i];
res = vfs_file_sha1(file, digest,
_shell_vfs_data_buffer, sizeof(_shell_vfs_data_buffer));
if (res < 0) {
printf("%s: error %d\n", file, res);
} else {
_print_digest(digest, sizeof(digest), file);
}
}

return 0;
}
#endif

#if MODULE_SHA256SUM
#include "hashes/sha256.h"
int _vfs_sha256sum_cmd(int argc, char **argv)
{
int res;
uint8_t digest[SHA256_DIGEST_LENGTH];

if (argc < 2) {
printf("usage: %s [file] …\n", argv[0]);
return -1;
}

for (int i = 1; i < argc; ++i) {
const char *file = argv[i];
res = vfs_file_sha256(file, digest,
_shell_vfs_data_buffer, sizeof(_shell_vfs_data_buffer));
if (res < 0) {
printf("%s: error %d\n", file, res);
} else {
_print_digest(digest, sizeof(digest), file);
}
}

return 0;
}
#endif
#endif
21 changes: 21 additions & 0 deletions sys/shell/commands/shell_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,18 @@ extern int _bootloader_handler(int argc, char **argv);
extern int _gnrc_udp_cmd(int argc, char **argv);
#endif

#ifdef MODULE_MD5SUM
extern int _vfs_md5sum_cmd(int argc, char **argv);
#endif

#ifdef MODULE_SHA1SUM
extern int _vfs_sha1sum_cmd(int argc, char **argv);
#endif

#ifdef MODULE_SHA256SUM
extern int _vfs_sha256sum_cmd(int argc, char **argv);
#endif

const shell_command_t _shell_command_list[] = {
{"reboot", "Reboot the node", _reboot_handler},
{"version", "Prints current RIOT_VERSION", _version_handler},
Expand Down Expand Up @@ -268,6 +280,15 @@ const shell_command_t _shell_command_list[] = {
#ifdef MODULE_RTT_CMD
{"rtt", "control RTC peripheral interface", _rtt_handler},
#endif
#ifdef MODULE_MD5SUM
{"md5sum", "Compute and check MD5 message digest", _vfs_md5sum_cmd},
#endif
#ifdef MODULE_SHA1SUM
{"sha1sum", "Compute and check SHA1 message digest", _vfs_sha1sum_cmd},
#endif
#ifdef MODULE_SHA256SUM
{"sha256sum", "Compute and check SHA256 message digest", _vfs_sha256sum_cmd},
#endif
#ifdef MODULE_GNRC_IPV6_NIB
{"nib", "Configure neighbor information base", _gnrc_ipv6_nib},
#endif
Expand Down
75 changes: 75 additions & 0 deletions sys/vfs_util/vfs_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,78 @@ int vfs_file_to_buffer(const char* file, void* buf, size_t len)

return res;
}

#if MODULE_HASHES
#include "hashes/md5.h"
#include "hashes/sha1.h"
#include "hashes/sha256.h"

int vfs_file_md5(const char* file, void *digest,
void *work_buf, size_t work_buf_len)
{
md5_ctx_t ctx;

int res, fd = vfs_open(file, O_RDONLY, 0);

if (fd < 0) {
DEBUG("can't open %s for reading\n", file);
return fd;
}

md5_init(&ctx);
while ((res = vfs_read(fd, work_buf, work_buf_len)) > 0) {
md5_update(&ctx, work_buf, res);
}
md5_final(&ctx, digest);

vfs_close(fd);

return res > 0 ? 0 : res;
}

int vfs_file_sha1(const char* file, void *digest,
void *work_buf, size_t work_buf_len)
{
sha1_context ctx;
int res, fd = vfs_open(file, O_RDONLY, 0);

if (fd < 0) {
DEBUG("can't open %s for reading\n", file);
return fd;
}

sha1_init(&ctx);
while ((res = vfs_read(fd, work_buf, work_buf_len)) > 0) {
sha1_update(&ctx, work_buf, res);
}
sha1_final(&ctx, digest);

vfs_close(fd);

return res > 0 ? 0 : res;

}

int vfs_file_sha256(const char* file, void *digest,
void *work_buf, size_t work_buf_len)
{
sha256_context_t ctx;
int res, fd = vfs_open(file, O_RDONLY, 0);

if (fd < 0) {
DEBUG("can't open %s for reading\n", file);
return fd;
}

sha256_init(&ctx);
while ((res = vfs_read(fd, work_buf, work_buf_len)) > 0) {
sha256_update(&ctx, work_buf, res);
}
sha256_final(&ctx, digest);

vfs_close(fd);

return res > 0 ? 0 : res;

}
#endif /* MODULE_HASHES */