This patch introduces a fssum option to the erofs-utils fsck tool, enabling checksum calculation for erofs image files.
Signed-off-by: Jiawei Wang <[email protected]> --- fsck/fssum.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fsck/main.c | 30 +++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 fsck/fssum.h diff --git a/fsck/fssum.h b/fsck/fssum.h new file mode 100644 index 0000000..0203169 --- /dev/null +++ b/fsck/fssum.h @@ -0,0 +1,57 @@ +#ifndef EROFS_FSSUM_H +#define EROFS_FSSUM_H +#include "erofs/dir.h" + +#define CS_SIZE 16 +#define CHUNKS 128 + +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +#define OUT(dst, src) \ + (dst)[0] = (unsigned char)(src); \ + (dst)[1] = (unsigned char)((src) >> 8); \ + (dst)[2] = (unsigned char)((src) >> 16); \ + (dst)[3] = (unsigned char)((src) >> 24); + +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) +#endif + +typedef unsigned int MD5_u32plus; + +struct erofs_MD5_CTX { + MD5_u32plus lo, hi; + MD5_u32plus a, b, c, d; + unsigned char buffer[64]; + MD5_u32plus block[16]; +}; + +struct erofs_sum_t { + struct erofs_MD5_CTX md5; + unsigned char out[16]; +}; + +int erofs_fssum_calculate(struct erofs_dir_context *ctx); + +#endif diff --git a/fsck/main.c b/fsck/main.c index 28f1e7e..051b74f 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -13,6 +13,7 @@ #include "erofs/compress.h" #include "erofs/decompress.h" #include "erofs/dir.h" +#include "fssum.h" #include "../lib/compressor.h" static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid); @@ -31,6 +32,7 @@ struct erofsfsck_cfg { bool overwrite; bool preserve_owner; bool preserve_perms; + bool checksum; }; static struct erofsfsck_cfg fsckcfg; @@ -48,6 +50,7 @@ static struct option long_options[] = { {"no-preserve-owner", no_argument, 0, 10}, {"no-preserve-perms", no_argument, 0, 11}, {"offset", required_argument, 0, 12}, + {"fssum", no_argument, 0, 13}, {0, 0, 0, 0}, }; @@ -98,6 +101,7 @@ static void usage(int argc, char **argv) " --extract[=X] check if all files are well encoded, optionally\n" " extract to X\n" " --offset=# skip # bytes at the beginning of IMAGE\n" + " --fssum calculate the checksum of iamge\n" "\n" " -a, -A, -y no-op, for compatibility with fsck of other filesystems\n" "\n" @@ -225,6 +229,9 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv) return -EINVAL; } break; + case 13: + fsckcfg.checksum = true; + break; default: return -EINVAL; } @@ -932,6 +939,23 @@ out: return ret; } +static int erofsfsck_sum_image(struct erofs_sb_info *sbi) +{ + int ret = 0; + struct erofs_dir_context ctx = { + .flags = 0, + .pnid = 0, + .dir = NULL, + .de_nid = sbi->root_nid, + .dname = "", + .de_namelen = 0, + }; + + ret = erofs_fssum_calculate(&ctx); + + return ret; +} + #ifdef FUZZING int erofsfsck_fuzz_one(int argc, char *argv[]) #else @@ -953,6 +977,7 @@ int main(int argc, char *argv[]) fsckcfg.check_decomp = false; fsckcfg.force = false; fsckcfg.overwrite = false; + fsckcfg.checksum = false; fsckcfg.preserve_owner = fsckcfg.superuser; fsckcfg.preserve_perms = fsckcfg.superuser; @@ -1017,6 +1042,11 @@ int main(int argc, char *argv[]) } } + if (fsckcfg.checksum) { + err = erofsfsck_sum_image(&g_sbi); + if (err) + erofs_err("fssum calculation for image falied"); + } exit_hardlink: if (fsckcfg.extract_path) erofsfsck_hardlink_exit(); -- 2.34.1
