author | Olivier Brunel
<jjk@jjacky.com> 2023-08-20 15:31:11 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-08-20 17:15:06 UTC |
parent | 4bcd4aac481861f2901ca0c9890e1e1466e5beb3 |
src/doc/ssp.1.md | +13 | -3 |
src/include/ssp.h | +3 | -1 |
src/ssp/add.c | +1 | -1 |
src/ssp/database.c | +1 | -1 |
src/ssp/ssp.c | +15 | -0 |
diff --git a/src/doc/ssp.1.md b/src/doc/ssp.1.md index 82145bc..c0e5f78 100644 --- a/src/doc/ssp.1.md +++ b/src/doc/ssp.1.md @@ -26,6 +26,15 @@ backup solution. <inc opt_help.md> +: *-I*, *--iter* `ITER` +:: Use `ITER` iterations when performing key derivation to write database. See +:: [[DATABASE]] below for more. Must be at least 50 000; Defaults to 500 000. +:: +:: Note that this only applies when writing database, not reading it (since the +:: number of iterations used is stored within the file), but since the database +:: is re-encrypted each time it is written, any operation requiring to write +:: the database will make use of this setting. + : *-q*, *--quiet* <inc autoopt_quiet.md> @@ -120,9 +129,10 @@ Anything else will be treated as-is. The database is written as a password-protected file. -More specifically, PBKDF2-HMAC-SHA3-256 is used with 500,000 iterations to -derive a key from the password and a randomly generated salt, said key is then -used to encrypt the database using ChaCha20-Poly1305. +More specifically, PBKDF2-HMAC-SHA3-256 is used with 500,000 iterations (by +default, can be changed using *--iter*) to derive a key from the password and a +randomly generated salt, said key is then used to encrypt the database using +ChaCha20-Poly1305. Whenever writing to the database, the actual file is not changed. Instead a new file is created, encrypted data is written to it and only once successfully diff --git a/src/include/ssp.h b/src/include/ssp.h index 60938a7..df7041e 100644 --- a/src/include/ssp.h +++ b/src/include/ssp.h @@ -19,7 +19,8 @@ enum { #define SALT_LEN 32 #define NONCE_LEN 12 #define PWD_MAX 136 -#define ITER 500000 +#define ITER_MIN 50000 +#define ITER_DEF 500000 struct ssp { stralloc sa; @@ -28,6 +29,7 @@ struct ssp { cdb_data val; size_t cdboff; unsigned int options; + u32 iter; u32 pos; char pwd[PWD_MAX + 1]; }; diff --git a/src/ssp/add.c b/src/ssp/add.c index f78e217..1054b39 100644 --- a/src/ssp/add.c +++ b/src/ssp/add.c @@ -47,7 +47,7 @@ validate_digits(const char *data, size_t dlen) int validate_counter(u64 *c, const char *data, size_t dlen) { - dbg("validating counter", ESC, PMLEN(data, dlen), ESC); + dbg("validating counter ", ESC, PMLEN(data, dlen), ESC); if (u64_scan(c, data) != dlen) { warn("invalid counter value: ", PMLEN(data, dlen)); return -1; diff --git a/src/ssp/database.c b/src/ssp/database.c index 04ce283..d300e78 100644 --- a/src/ssp/database.c +++ b/src/ssp/database.c @@ -200,7 +200,7 @@ write_db(char *data, size_t dlen, struct ssp *ctx) v.iov_len = dlen; if (!shldata_write(AT_FDCWD, db_file(ctx), SSP_MAGIC, 0, ctx->pwd, plen, - ALGO_SHA3_256, ITER, 1, &v, 1)) { + ALGO_SHA3_256, (ctx->iter) ? ctx->iter : ITER_DEF, 1, &v, 1)) { warnusys("write database to ", ESC, db_file(ctx), ESC); return 0; } diff --git a/src/ssp/ssp.c b/src/ssp/ssp.c index 2dd4904..6dbd89c 100644 --- a/src/ssp/ssp.c +++ b/src/ssp/ssp.c @@ -11,6 +11,7 @@ #include <limb/exitcode.h> #include <limb/loadopt.h> #include <limb/output.h> +#include <limb/u32.h> #include "ssp.h" #include "config.h" @@ -55,6 +56,7 @@ parse_cmdline(int *argc, const char **argv[], struct ssp *ctx) OPTION_ARG_OPT ( 0 , "debug", 0, OPTID_DEBUG), OPTION_ARG_REQ ('D', "database", OPT_PATH, OPTID_SHORTOPT), OPTION_ARG_NONE('h', "help", 0, OPTID_SHORTOPT), + OPTION_ARG_REQ ('I', "iter", 0, OPTID_SHORTOPT), OPTION_ARG_NONE('q', "quiet", 0, OPTID_SHORTOPT), OPTION_ARG_NONE( 0 , "version", 0, OPTID_VERSION), LOADOPT_STOP @@ -68,6 +70,18 @@ parse_cmdline(int *argc, const char **argv[], struct ssp *ctx) case 'h': ctx->options |= OPT_HELP; break; + case 'I': + { + u32 u; + if (!u32_scan0(&u, LO_ARG(&lo)) + || (errno = ERANGE, u < ITER_MIN)) { + warnsys("invalid iteration number: ", LO_ARG(&lo)); + dieusage(EX_USAGE, usage); + } + ctx->iter = u; + dbg("set iteration to ", PMUINT(ctx->iter)); + } + break; case 'q': autoopt_quiet(&options[LO_IDX(&lo)], LO_ARG(&lo)); break; @@ -87,6 +101,7 @@ parse_cmdline(int *argc, const char **argv[], struct ssp *ctx) if (LO_CUR(&lo) == *argc) dienocommand(EX_USAGE, usage, (ctx->options & OPT_HELP) ? " -D, --database FILE Use FILE as database [$HOME/ssp.db]\n" +" -I, --iter ITER Use ITER iterations (when writing database) [500000]\n" "\n" " -q, --quiet Enable quiet mode\n" " --debug[=[@[level]:]+FD|FILE] Enable debug output (to FD|FILE)\n"