aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-20 23:04:11 +0200
committerMattias Andrée <m@maandree.se>2026-05-20 23:04:11 +0200
commitc35b47228f5494f4d806e9166628110af6dd2469 (patch)
tree3b5a123af999a5e047b8565efee293a5d95c3f6c
parentPrepare for supporting custom algorithms (diff)
downloadlibrecrypt-c35b47228f5494f4d806e9166628110af6dd2469.tar.gz
librecrypt-c35b47228f5494f4d806e9166628110af6dd2469.tar.bz2
librecrypt-c35b47228f5494f4d806e9166628110af6dd2469.tar.xz
Add (so far untested and undocument) support for pepperHEADmaster
Signed-off-by: Mattias Andrée <m@maandree.se>
-rw-r--r--Makefile9
-rw-r--r--TODO2
-rw-r--r--argon2/argon2.h2
-rw-r--r--argon2/hash.c66
-rw-r--r--common.h80
-rw-r--r--librecrypt.h222
-rw-r--r--librecrypt_add_algorithm.334
-rw-r--r--librecrypt_add_algorithm.c26
-rw-r--r--librecrypt_context_get_pepper_.c63
-rw-r--r--librecrypt_context_get_user_data.c29
-rw-r--r--librecrypt_context_set_pepper.c37
-rw-r--r--librecrypt_context_set_user_data.c29
-rw-r--r--librecrypt_create_context.c47
-rw-r--r--librecrypt_crypt.335
-rw-r--r--librecrypt_crypt.c5
-rw-r--r--librecrypt_find_first_algorithm_.c12
-rw-r--r--librecrypt_free_context.c30
-rw-r--r--librecrypt_get_encoding.334
-rw-r--r--librecrypt_get_encoding.c16
-rw-r--r--librecrypt_hash.334
-rw-r--r--librecrypt_hash.c5
-rw-r--r--librecrypt_hash_.c21
-rw-r--r--librecrypt_hash_algorithm_end.c27
-rw-r--r--librecrypt_hash_binary.334
-rw-r--r--librecrypt_hash_binary.c5
-rw-r--r--librecrypt_is_enabled.33
-rw-r--r--librecrypt_is_enabled.c1
-rw-r--r--librecrypt_make_settings.334
-rw-r--r--librecrypt_make_settings.c19
-rw-r--r--librecrypt_realise_salts.334
-rw-r--r--librecrypt_realise_salts.c16
-rw-r--r--librecrypt_settings_prefix.324
-rw-r--r--librecrypt_settings_prefix.c6
-rw-r--r--librecrypt_test_supported.329
-rw-r--r--librecrypt_test_supported.c6
-rw-r--r--librecrypt_verify.317
-rw-r--r--librecrypt_verify.c8
37 files changed, 858 insertions, 243 deletions
diff --git a/Makefile b/Makefile
index 03f302a..57453a5 100644
--- a/Makefile
+++ b/Makefile
@@ -38,7 +38,13 @@ OBJ_PUBLIC_NO_FUZZ =\
librecrypt_wipe_str.o\
librecrypt_equal_binary.o\
librecrypt_equal.o\
- librecrypt_is_enabled.o
+ librecrypt_is_enabled.o\
+ librecrypt_hash_algorithm_end.o\
+ librecrypt_create_context.o\
+ librecrypt_free_context.o\
+ librecrypt_context_set_user_data.o\
+ librecrypt_context_get_user_data.o\
+ librecrypt_context_set_pepper.o
OBJ_PUBLIC =\
$(OBJ_PUBLIC_FUZZ)\
@@ -58,6 +64,7 @@ OBJ_PRIVATE =\
librecrypt_fill_with_random_.o\
librecrypt_find_first_algorithm_.o\
librecrypt_check_settings_.o\
+ librecrypt_context_get_pepper_.o\
$(OBJ_COMMON_RFC4848S4)
USE_OBJ_COMMON_RFC4848S4 =\
diff --git a/TODO b/TODO
index 43a833f..2919334 100644
--- a/TODO
+++ b/TODO
@@ -17,4 +17,4 @@ Add support for descrypt.
Add support for bigcrypt.
Add support for NT Hash.
Add support for custom hash functions.
-Add support (via the "reserved" parameter) for pepper.
+Add support (via the "ctx" parameter) for pepper.
diff --git a/argon2/argon2.h b/argon2/argon2.h
index cd149da..a14e782 100644
--- a/argon2/argon2.h
+++ b/argon2/argon2.h
@@ -82,7 +82,7 @@ HIDDEN ssize_t librecrypt__argon2ds__make_settings(char *out_buffer, size_t size
# define argon2__STRICT_PAD 0
# define argon2__PAD '='
HIDDEN int librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
- const char *settings, size_t prefix, void *reserved);
+ const char *settings, size_t prefix, LIBRECRYPT_CONTEXT *ctx);
HIDDEN PURE int librecrypt__argon2__test_supported(const char *phrase, size_t len, int text,
const char *settings, size_t prefix, size_t *len_out);
# ifndef REQUIRES_COMMON_RFC4848S4
diff --git a/argon2/hash.c b/argon2/hash.c
index 2a41c69..e498d35 100644
--- a/argon2/hash.c
+++ b/argon2/hash.c
@@ -91,19 +91,21 @@ init_context(struct libar2_context *ctxp)
int
librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
- const char *settings, size_t prefix, void *reserved)
+ const char *settings, size_t prefix, LIBRECRYPT_CONTEXT *ctx)
{
+ enum librecrypt_hash_algorithm algo_v10, algo_v13, algo;
struct libar2_argon2_parameters params;
- struct libar2_context ctx;
+ struct libar2_context ar2ctx;
const char *type, *version, *salt_encoded;
uintmax_t mcost, tcost, lanes, saltlen, hashlen;
void *salt = NULL, *scratch = NULL;
size_t scratch_size;
+ struct pepper *pepper = NULL;
ssize_t r;
int saved_errno;
/* Not yet used */
- (void) reserved;
+ (void) ctx;
/* Parse `settings` */
r = librecrypt_scan_settings_(settings, prefix,
@@ -140,14 +142,14 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
/* Gives us memory allocation and threading support;
* so we don't have to implement any of that ourselves */
- libar2simplified_init_context(&ctx);
+ libar2simplified_init_context(&ar2ctx);
/* Configure automatic erasure of input memory */
- ctx.autoerase_message = 0; /* allows `phrase` to be read-only */
- ctx.autoerase_secret = 0; /* alloes to params.key, which we are not using, but maybe in the future */
- ctx.autoerase_associated_data = 0; /* alloes to params.ad, which we are not using, but maybe in the future */
- ctx.autoerase_salt = 1; /* since we are decoding the salt, we do a memory allocation,
- * and our testing always checks that allocated memory is earse;
- * it doesn't really matter, but it's paranoid, and that's good */
+ ar2ctx.autoerase_message = 0; /* allows `phrase` to be read-only */
+ ar2ctx.autoerase_secret = 0; /* allows params.key to be read-only */
+ ar2ctx.autoerase_associated_data = 0; /* allows params.ad to be read-only, which we are not using, but maybe in the future */
+ ar2ctx.autoerase_salt = 1; /* since we are decoding the salt, we do a memory allocation,
+ * and our testing always checks that allocated memory is earse;
+ * it doesn't really matter, but it's paranoid, and that's good */
/* Decode salt */
if (!salt_encoded) /* this would be if asterisk-notation is used, but it is not */
@@ -181,13 +183,47 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
params.version = !*version ? LIBAR2_ARGON2_VERSION_10 :
version[3u] == '9' ? LIBAR2_ARGON2_VERSION_13 : /* 19 = 0x13 = 1.3 */
LIBAR2_ARGON2_VERSION_10; /* 16 = 0x10 = 1.0 */
+ if (!ctx)
+ goto no_pepper;
+ switch (params.type) {
+ case LIBAR2_ARGON2I:
+ algo_v10 = LIBRECRYPT_ARGON2I_V1_0;
+ algo_v13 = LIBRECRYPT_ARGON2I_V1_3;
+ break;
+ case LIBAR2_ARGON2D:
+ algo_v10 = LIBRECRYPT_ARGON2D_V1_0;
+ algo_v13 = LIBRECRYPT_ARGON2D_V1_3;
+ break;
+ case LIBAR2_ARGON2ID:
+ algo_v10 = LIBRECRYPT_ARGON2ID_V1_0;
+ algo_v13 = LIBRECRYPT_ARGON2ID_V1_3;
+ break;
+ case LIBAR2_ARGON2DS:
+ algo_v10 = LIBRECRYPT_ARGON2DS_V1_0;
+ algo_v13 = LIBRECRYPT_ARGON2DS_V1_3;
+ break;
+ default:
+ abort(); /* $covered$ (impossible) */
+ }
+ switch (params.version) {
+ case LIBAR2_ARGON2_VERSION_10:
+ algo = algo_v10;
+ break;
+ case LIBAR2_ARGON2_VERSION_13:
+ algo = algo_v13;
+ break;
+ default:
+ abort(); /* $covered$ (impossible) */
+ }
+ pepper = librecrypt_context_get_pepper_(ctx, algo, 0u);
+no_pepper:
params.t_cost = (uint_least32_t)tcost;
params.m_cost = (uint_least32_t)mcost;
params.lanes = (uint_least32_t)lanes;
params.salt = salt;
params.saltlen = (size_t)saltlen;
- params.key = NULL;
- params.keylen = 0u;
+ params.key = pepper ? REMOVE_CONST(pepper->data) : NULL;
+ params.keylen = pepper ? pepper->len : 0u;
params.ad = NULL;
params.adlen = 0u;
params.hashlen = hashlen ? (size_t)hashlen : argon2__HASH_SIZE;
@@ -215,7 +251,7 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
/* Calculate hash */
#ifndef FUZZ
- if (libar2_hash(scratch ? scratch : out_buffer, REMOVE_CONST(phrase), len, &params, &ctx))
+ if (libar2_hash(scratch ? scratch : out_buffer, REMOVE_CONST(phrase), len, &params, &ar2ctx))
goto fail;
#else
memset(scratch ? scratch : out_buffer, '5', scratch_size);
@@ -223,7 +259,7 @@ librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phr
if (scratch && out_buffer)
memcpy(out_buffer, scratch, MIN(params.hashlen, size));
- /* same rationale as for `ctx.autoerase_salt = 1;` */
+ /* same rationale as for `ar2ctx.autoerase_salt = 1;` */
if (scratch) {
librecrypt_wipe(scratch, scratch_size);
free(scratch);
@@ -431,6 +467,8 @@ main(void)
STOP_RESOURCE_TEST();
return 0;
}
+/* TODO check with pepper */
+/* TODO check with context but no pepper */
#endif
diff --git a/common.h b/common.h
index b498943..b329fca 100644
--- a/common.h
+++ b/common.h
@@ -109,6 +109,40 @@ enum action {
/**
+ * Pepper for a hash algorithm
+ */
+struct pepper {
+ /**
+ * The binary pepper
+ */
+ const void *data;
+
+ /**
+ * The number of bytes in `.data`
+ */
+ size_t len;
+};
+
+
+/**
+ * The real type of `LIBRECRYPT_CONTEXT`
+ */
+struct librecrypt_context {
+ /**
+ * Application-defined data
+ */
+ void *user_data;
+
+ /**
+ * Per hash algorithm peppers
+ */
+ struct pepper peppers[LIBRECRYPT_HASH_ALGORITHM_END];
+ /* TODO we probably don't want slots allocated for
+ * algorithms that have been disabled */
+};
+
+
+/**
* Hash algorithm information and implementation
*
* Current limitations:
@@ -168,14 +202,14 @@ struct librecrypt_algorithm {
* @param settings See `librecrypt_hash_binary`,
* will not contains asterisk-encoding
* @param prefix The length of `settings`, in bytes
- * @param reserved See `librecrypt_hash_binary`
+ * @param ctx See `librecrypt_hash_binary`
* @return 0 on success, -1 on failure
* @throws See `librecrypt_hash_binary`
*
* This function shall be MT-Safe but may be AS-Unsafe
*/
int (*hash)(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
- const char *settings, size_t prefix, void *reserved);
+ const char *settings, size_t prefix, LIBRECRYPT_CONTEXT *ctx);
/**
* Check whether the hash algorithm is supported for given
@@ -198,7 +232,8 @@ struct librecrypt_algorithm {
*
* This function shall be MT-Safe and AS-Safe
*/
- int (*test_supported)(const char *phrase, size_t len, int text, const char *settings, size_t prefix, size_t *len_out);
+ int (*test_supported)(const char *phrase, size_t len, int text, const char *settings,
+ size_t prefix, size_t *len_out);
/**
* See `librecrypt_make_settings`
@@ -219,8 +254,9 @@ struct librecrypt_algorithm {
*
* This function shall be MT-Safe but may be AS-Safe
*/
- ssize_t (*make_settings)(char *out_buffer, size_t size, const char *algorithm, size_t memcost, uintmax_t timecost,
- int gensalt, ssize_t (*rng)(void *out, size_t n, void *user), void *user);
+ ssize_t (*make_settings)(char *out_buffer, size_t size, const char *algorithm,
+ size_t memcost, uintmax_t timecost, int gensalt,
+ ssize_t (*rng)(void *out, size_t n, void *user), void *user);
/**
* Expected argument for the `lut` parameter
@@ -359,7 +395,7 @@ extern void (*volatile librecrypt_explicit_____)(unsigned char); /* librecrypt_e
* @param len The number of bytes in `phrase`
* @param settings The password hash configuration string,
* may contain resulting hash, which will be ignored
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @param action The function this function shall implement
* @return The number of bytes that would have been written to `out_buffer`
* if `size` was sufficiently large, excluding a terminating
@@ -371,7 +407,7 @@ extern void (*volatile librecrypt_explicit_____)(unsigned char); /* librecrypt_e
LIBRECRYPT_WRITE_MEM__(1, 2) LIBRECRYPT_READ_MEM__(3, 4)
LIBRECRYPT_READ_STR__(6) LIBRECRYPT_NONNULL_I__(5) LIBRECRYPT_WUR__ HIDDEN
ssize_t librecrypt_hash_(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
- const char *settings, void *reserved, enum action action);
+ const char *settings, LIBRECRYPT_CONTEXT *ctx, enum action action);
/**
@@ -427,6 +463,7 @@ int librecrypt_fill_with_random_(void *out, size_t n, ssize_t (*rng)(void *out,
*
* @param settings The password has string
* @param len The number of bytes in `settings`
+ * @param ctx Library configuration
* @return Pointer to the algorithm information,
* `NULL` if not found
*
@@ -436,8 +473,33 @@ int librecrypt_fill_with_random_(void *out, size_t n, ssize_t (*rng)(void *out,
*
* This function is MT-Safe And AS-Safe
*/
-LIBRECRYPT_READ_MEM__(1, 2) LIBRECRYPT_NONNULL__ LIBRECRYPT_WUR__ HIDDEN
-const struct librecrypt_algorithm *librecrypt_find_first_algorithm_(const char *settings, size_t len);
+LIBRECRYPT_READ_MEM__(1, 2) LIBRECRYPT_NONNULL_1__ LIBRECRYPT_WUR__ HIDDEN
+const struct librecrypt_algorithm *librecrypt_find_first_algorithm_(const char *settings, size_t len,
+ LIBRECRYPT_CONTEXT *ctx);
+
+
+/**
+ * Sets the pepper for a hash algorithm
+ *
+ * @param ctx The library configuration object
+ * @param algo The hash algorithm to apply the pepper to
+ * @param len Pepper size to test support for, or 0 to not
+ * test (0 is always supported for algorithms that
+ * support pepper as it means no pepper)
+ * @return Pointer to the pepper configuration for
+ * `algo` in `ctx`; `NULL` on failure
+ *
+ * @throws ENOSYS The hash algorithm `algo` is either not
+ * recognised or was disabled at compile-time
+ * @throws ENOSUP The hash algorithm `algo` does not support
+ * peppers; the application is instead adviced
+ * to, itself, append or prepend the pepper
+ * to the password
+ * @throws EINVAL The size of the pepper is unsupported
+ * for the hash algorithm `algo`
+ */
+LIBRECRYPT_NONNULL_1__
+struct pepper *librecrypt_context_get_pepper_(LIBRECRYPT_CONTEXT *ctx, enum librecrypt_hash_algorithm algo, size_t len);
/**
diff --git a/librecrypt.h b/librecrypt.h
index d526e1d..a9e3a37 100644
--- a/librecrypt.h
+++ b/librecrypt.h
@@ -14,12 +14,14 @@
# define LIBRECRYPT_NONNULL__ __attribute__((__nonnull__))
# define LIBRECRYPT_NONNULL_I__(I) __attribute__((__nonnull__(I)))
# define LIBRECRYPT_WUR__ __attribute__((__warn_unused_result__))
+# define LIBRECRYPT_MALLOC__(D, D_ARG) __attribute__((__malloc__(D, D_ARG)))
#else
# define LIBRECRYPT_PURE__
# define LIBRECRYPT_CONST__
# define LIBRECRYPT_NONNULL__
# define LIBRECRYPT_NONNULL_I__(I)
# define LIBRECRYPT_WUR__
+# define LIBRECRYPT_MALLOC__(D, D_ARG)
#endif
#if defined(__GNUC__) && !defined(__clang__)
# define LIBRECRYPT_READ_STR__(S) __attribute__((__access__(read_only, S)))
@@ -60,53 +62,103 @@
/**
+ * Opaque structure for library tweaking
+ *
+ * @seealso librecrypt_create_context
+ *
+ * @since 1.1
+ */
+typedef struct librecrypt_context LIBRECRYPT_CONTEXT;
+
+
+/**
* Hash algorithms that the library might support
+ *
+ * @seealso librecrypt_hash_algorithm_end
+ *
+ * @since 1.1
*/
enum librecrypt_hash_algorithm {
/**
* Argon2i, version 1.0 ("$argon2i$v=13$", optionally without "$v=13")
+ *
+ * @since 1.1
*/
LIBRECRYPT_ARGON2I_V1_0,
/**
* Argon2i, version 1.3 ("$argon2i$v=19$")
+ *
+ * @since 1.1
*/
LIBRECRYPT_ARGON2I_V1_3,
/**
* Argon2d, version 1.0 ("$argon2d$v=13$", optionally without "$v=13")
+ *
+ * @since 1.1
*/
LIBRECRYPT_ARGON2D_V1_0,
/**
* Argon2d, version 1.3 ("$argon2d$v=19$")
+ *
+ * @since 1.1
*/
LIBRECRYPT_ARGON2D_V1_3,
/**
* Argon2id, version 1.0 ("$argon2id$v=13$", optionally without "$v=13")
+ *
+ * @since 1.1
*/
LIBRECRYPT_ARGON2ID_V1_0,
/**
* Argon2id, version 1.3 ("$argon2id$v=19$")
+ *
+ * @since 1.1
*/
LIBRECRYPT_ARGON2ID_V1_3,
/**
* Argon2ds, version 1.0 ("$argon2ds$v=13$", optionally without "$v=13")
+ *
+ * @since 1.1
*/
LIBRECRYPT_ARGON2DS_V1_0,
/**
* Argon2ds, version 1.3 ("$argon2ds$v=19$")
+ *
+ * @since 1.1
+ */
+ LIBRECRYPT_ARGON2DS_V1_3,
+
+ /** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - **/
+
+ /**
+ * Marks the end of this enum, so you can iterate over it
+ *
+ * @since 1.1
*/
- LIBRECRYPT_ARGON2DS_V1_3
+ LIBRECRYPT_HASH_ALGORITHM_END
};
/**
+ * The value `LIBRECRYPT_HASH_ALGORITHM_END` as in the
+ * version of the library the application is linked against
+ * (rather than compiled against)
+ *
+ * @since 1.1
+ */
+extern enum librecrypt_hash_algorithm librecrypt_hash_algorithm_end; /* TODO man */
+
+
+
+/**
* Get number of bytes in a password hash string
* that make up the algorithm configuration
*
@@ -130,7 +182,7 @@ enum librecrypt_hash_algorithm {
* return `strlen(hash)` if `hash` is properly
* formatted) the value 0 is stored, indicating
* that a default hash size shall be used
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return The number of bytes, from the front of `hash`,
* that make up the algorithm configuration; may be 0
*
@@ -140,9 +192,10 @@ enum librecrypt_hash_algorithm {
* This function is MT-Safe and AS-Safe
*
* @since 1.0
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`
*/
LIBRECRYPT_READ_STR__(1) LIBRECRYPT_NONNULL_1__ LIBRECRYPT_WUR__ LIBRECRYPT_PURE__
-size_t librecrypt_settings_prefix(const char *hash, size_t *hashsize_out, void *reserved);
+size_t librecrypt_settings_prefix(const char *hash, size_t *hashsize_out, LIBRECRYPT_CONTEXT *ctx);
/**
@@ -409,7 +462,7 @@ ssize_t librecrypt_decode(void *out_buffer, size_t size, const char *ascii, size
* @param decoding 0 if the returned pointer should be useful for,
* `librecrypt_encode`, otherwise it will be useful
* for `librecrypt_decode`
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return If `decoding` is 0:
* the encoding alphabet, consisting of 64 characters,
* repeated 4 times;
@@ -420,8 +473,6 @@ ssize_t librecrypt_decode(void *out_buffer, size_t size, const char *ascii, size
* and any other character to the value `0xFF`;
* but `NULL` on failure
*
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws ENOSYS The last algorithm in `settings` is not recognised
* or was disabled at compile-time
*
@@ -442,11 +493,13 @@ ssize_t librecrypt_decode(void *out_buffer, size_t size, const char *ascii, size
* This function is MT-Safe and AS-Safe
*
* @since 1.0
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`;
+ * provided `NULL` to this parameter no longer causes `EINVAL`-failure
*/
LIBRECRYPT_READ_STR__(1) LIBRECRYPT_NONNULL_I__(1) LIBRECRYPT_NONNULL_I__(3)
LIBRECRYPT_NONNULL_I__(4) LIBRECRYPT_WUR__
const void *librecrypt_get_encoding(const char *settings, size_t len, char *pad_out,
- int *strict_pad_out, int decoding, void *reserved);
+ int *strict_pad_out, int decoding, LIBRECRYPT_CONTEXT *ctx);
/**
@@ -553,11 +606,9 @@ librecrypt_equal(const char *a, const char *b)
* the number of generated bytes, or -1 on failure
* @param user Passed as the third argument to `*rng` for user-defined
* purposes, ignored if `rng` is `NULL`
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return The number of bytes that would have been written to `out_buffer`,
* if `size` was sufficiently large, -1 on failure
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws ERANGE The expected return value is greater than {SSIZE_MAX}
* @throws ENOSYS `settings` contain an algorithm that is not recognised
* or was disabled at compile-time
@@ -591,11 +642,13 @@ librecrypt_equal(const char *a, const char *b)
* `rng` is `NULL`, this function is MT-Safe but AS-Unsafe
*
* @since 1.0
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`;
+ * provided `NULL` to this parameter no longer causes `EINVAL`-failure
*/
LIBRECRYPT_WRITE_MEM__(1, 2) LIBRECRYPT_READ_STR__(3) LIBRECRYPT_WUR__
ssize_t librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *settings,
ssize_t (*rng)(void *out, size_t n, void *user), void *user,
- void *reserved);
+ LIBRECRYPT_CONTEXT *ctx);
/**
@@ -627,12 +680,10 @@ ssize_t librecrypt_realise_salts(char *restrict out_buffer, size_t size, const c
* ignored if `gensalt` is zero
* @param user Passed as the third argument to `*rng` for user-defined
* purposes, ignored if `rng` is `NULL` or if `gensalt` is zero
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return The number of bytes that would have been written to
* `out_buffer`, if `size` was sufficiently large, -1 on failure
*
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws EINVAL `algorithm` represents a chain of algorithms
* @throws ENOSYS `algorithm` represents an algorithm that is not
* recognised or was disabled at compile-time
@@ -662,12 +713,14 @@ ssize_t librecrypt_realise_salts(char *restrict out_buffer, size_t size, const c
* This function is MT-Safe but AS-Unsafe
*
* @since 1.0
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`;
+ * provided `NULL` to this parameter no longer causes `EINVAL`-failure
*/
LIBRECRYPT_WRITE_MEM__(1, 2) LIBRECRYPT_READ_STR__(3) LIBRECRYPT_WUR__
ssize_t librecrypt_make_settings(char *out_buffer, size_t size, const char *algorithm,
size_t memcost, uintmax_t timecost, int gensalt,
ssize_t (*rng)(void *out, size_t n, void *user), void *user,
- void *reserved);
+ LIBRECRYPT_CONTEXT *ctx);
/**
@@ -681,12 +734,10 @@ ssize_t librecrypt_make_settings(char *out_buffer, size_t size, const char *algo
* @param len The number of bytes in `phrase`
* @param settings The password hash configuration string,
* may contain resulting hash, which will be ignored
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return The number of bytes that would have been written to `out_buffer`
* if `size` was sufficiently large; -1 on failure
*
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws EINVAL `settings` is invalid (invalid algorithm configuration,
* invalid configuration syntax, or the output from one
* chained hash algorithm cannot be input the next algorithm
@@ -716,11 +767,13 @@ ssize_t librecrypt_make_settings(char *out_buffer, size_t size, const char *algo
*
* @since 1.0 Initial version
* @since 1.1 First parameter is `void *` rather than `char *`
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`;
+ * provided `NULL` to this parameter no longer causes `EINVAL`-failure
*/
LIBRECRYPT_WRITE_MEM__(1, 2) LIBRECRYPT_READ_MEM__(3, 4) LIBRECRYPT_READ_STR__(5)
LIBRECRYPT_NONNULL_I__(5) LIBRECRYPT_WUR__
ssize_t librecrypt_hash_binary(void *restrict out_buffer, size_t size, const char *phrase,
- size_t len, const char *settings, void *reserved);
+ size_t len, const char *settings, LIBRECRYPT_CONTEXT *ctx);
/**
@@ -735,13 +788,11 @@ ssize_t librecrypt_hash_binary(void *restrict out_buffer, size_t size, const cha
* @param len The number of bytes in `phrase`
* @param settings The password hash configuration string,
* may contain resulting hash, which will be ignored
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return The number of bytes that would have been written to `out_buffer`
* if `size` was sufficiently large, excluding a terminating
* NUL byte; -1 on failure
*
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws EINVAL `settings` is invalid (invalid algorithm configuration,
* invalid configuration syntax, or the output from one
* chained hash algorithm cannot be input the next algorithm
@@ -775,11 +826,13 @@ ssize_t librecrypt_hash_binary(void *restrict out_buffer, size_t size, const cha
* This function is MT-Safe but AS-Unsafe
*
* @since 1.0
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`;
+ * provided `NULL` to this parameter no longer causes `EINVAL`-failure
*/
LIBRECRYPT_WRITE_MEM__(1, 2) LIBRECRYPT_READ_MEM__(3, 4) LIBRECRYPT_READ_STR__(5)
LIBRECRYPT_NONNULL_I__(5) LIBRECRYPT_WUR__
ssize_t librecrypt_hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
- const char *settings, void *reserved);
+ const char *settings, LIBRECRYPT_CONTEXT *ctx);
/**
@@ -794,13 +847,11 @@ ssize_t librecrypt_hash(char *restrict out_buffer, size_t size, const char *phra
* @param len The number of bytes in `phrase`
* @param settings The password hash configuration string,
* may contain resulting hash, which will be ignored
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return The number of bytes that would have been written to `out_buffer`
* if `size` was sufficiently large, excluding a terminating
* NUL byte; -1 on failure
*
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws EINVAL `settings` is invalid (invalid algorithm configuration,
* invalid configuration syntax, or the output from one
* chained hash algorithm cannot be input the next algorithm
@@ -837,7 +888,7 @@ ssize_t librecrypt_hash(char *restrict out_buffer, size_t size, const char *phra
LIBRECRYPT_WRITE_MEM__(1, 2) LIBRECRYPT_READ_MEM__(3, 4) LIBRECRYPT_READ_STR__(5)
LIBRECRYPT_NONNULL_I__(5) LIBRECRYPT_WUR__
ssize_t librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
- const char *settings, void *reserved);
+ const char *settings, LIBRECRYPT_CONTEXT *ctx);
/**
@@ -847,12 +898,10 @@ ssize_t librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phr
* @param len The number of bytes in `phrase`
* @param settings The password hash configuration string,
* may contain resulting hash, which will be ignored
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return 1 if the password is correct and 0 if the password
* is incorrect; -1 on failure
*
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws EINVAL `settings` is invalid (invalid algorithm configuration,
* invalid configuration syntax, or the output from one
* chained hash algorithm cannot be input the next algorithm
@@ -879,7 +928,7 @@ ssize_t librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phr
* @since 1.1
*/
LIBRECRYPT_READ_MEM__(1, 2) LIBRECRYPT_READ_STR__(3) LIBRECRYPT_NONNULL_I__(3) LIBRECRYPT_WUR__
-int librecrypt_verify(const char *phrase, size_t len, const char *settings, void *reserved);
+int librecrypt_verify(const char *phrase, size_t len, const char *settings, LIBRECRYPT_CONTEXT *ctx);
/**
@@ -897,7 +946,7 @@ int librecrypt_verify(const char *phrase, size_t len, const char *settings, void
* iff non-zero; ignored if `phrase` is non-`NULL`
* @param settings The password hash string; it is allowed for algorithm
* tuning parameters, and the hash result, to be omitted
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return 1 if the configuration is supported, 0 otherwise, which
* means part of the string is invalid: the algorithm does
* not exist, supported was disabled at compile-time, or an
@@ -913,9 +962,11 @@ int librecrypt_verify(const char *phrase, size_t len, const char *settings, void
* This function is MT-Safe and AS-Safe
*
* @since 1.0
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`;
+ * provided `NULL` to this parameter no longer causes `EINVAL`-failure
*/
LIBRECRYPT_READ_STR__(4) LIBRECRYPT_NONNULL_I__(4) LIBRECRYPT_WUR__
-int librecrypt_test_supported(const char *phrase, size_t len, int text, const char *settings, void *reserved);
+int librecrypt_test_supported(const char *phrase, size_t len, int text, const char *settings, LIBRECRYPT_CONTEXT *ctx);
/**
@@ -957,13 +1008,11 @@ int librecrypt_is_enabled(enum librecrypt_hash_algorithm algo);
* @param augment Password hash setting string describing the additional
* hashing to perform; if it contains a hash result, that
* part will be ignored
- * @param reserved Reserved for future use, should be `NULL`
+ * @param ctx Library configuration
* @return The number of bytes that would have been written to `out_buffer`
* if `size` was sufficiently large, excluding a terminating
* NUL byte; -1 on failure
*
- * @throws EINVAL `reserved` is non-`NULL` (this case will be removed
- * once `reserved` as being used by the library)
* @throws EINVAL `settings` is invalid (invalid algorithm configuration,
* invalid configuration syntax, or the output from one
* chained hash algorithm cannot be input the next algorithm
@@ -989,11 +1038,110 @@ int librecrypt_is_enabled(enum librecrypt_hash_algorithm algo);
* This function is MT-Safe but AS-Unsafe
*
* @since 1.0
+ * @since 1.1 `void *reserved` was replaced with `LIBRECRYPT_CONTEXT *ctx`;
+ * provided `NULL` to this parameter no longer causes `EINVAL`-failure
*/
LIBRECRYPT_WRITE_MEM__(1, 2) LIBRECRYPT_READ_STR__(3) LIBRECRYPT_READ_STR__(4)
LIBRECRYPT_NONNULL_I__(3) LIBRECRYPT_NONNULL_I__(4) LIBRECRYPT_WUR__
ssize_t librecrypt_add_algorithm(char *out_buffer, size_t size, const char *augend,
- const char *restrict augment, void *reserved);
+ const char *restrict augment, LIBRECRYPT_CONTEXT *ctx);
+
+
+/**
+ * Deallocate object created with `librecrypt_create_context`
+ *
+ * @param ctx The object to deallocate
+ *
+ * @since 1.1
+ */
+void librecrypt_free_context(LIBRECRYPT_CONTEXT *ctx); /* TODO man */
+
+
+/**
+ * Create a new library configuration object
+ *
+ * @return The configuration object, shall be deallocated
+ * using `librecrypt_free_context` when no longer
+ * needed; `NULL` on failuare
+ *
+ * @throws ENOMEM Failed to allocate enough memory
+ *
+ * @seealso librecrypt_context_set_user_data
+ * @seealso librecrypt_context_set_pepper
+ *
+ * @since 1.1
+ */
+LIBRECRYPT_MALLOC__(librecrypt_free_context, 1) LIBRECRYPT_WUR__
+LIBRECRYPT_CONTEXT *librecrypt_create_context(void); /* TODO man */
+
+
+/**
+ * Set application-defined data in a library configuration object
+ *
+ * The data can be used by application-defined hash functions
+ *
+ * @param ctx The library configuration object
+ * @param user The application-defined data
+ *
+ * The caller is responsible for the lifetime of `user`:
+ * deallocating it will deallocate it for `ctx` as it
+ * only holds a reference to `user`, not a copy of it
+ *
+ * @seealso librecrypt_create_context
+ * @seealso librecrypt_context_get_user_data
+ *
+ * @since 1.1
+ */
+LIBRECRYPT_NONNULL_1__
+void librecrypt_context_set_user_data(LIBRECRYPT_CONTEXT *ctx, void *user); /* TODO man */
+
+
+/**
+ * Get application-defined data, in a library configuration object,
+ * which was set using the `librecrypt_context_set_user_data` function
+ *
+ * @param ctx The library configuration object
+ * @return user The application-defined data, `NULL` if
+ * it hasn't been set (or if it was set to `NULL`)
+ *
+ * @seealso librecrypt_create_context
+ * @seealso librecrypt_context_set_user_data
+ *
+ * @since 1.1
+ */
+LIBRECRYPT_NONNULL_1__ LIBRECRYPT_PURE__
+void *librecrypt_context_get_user_data(LIBRECRYPT_CONTEXT *ctx); /* TODO man */
+
+
+/**
+ * Sets the pepper for a hash algorithm
+ *
+ * @param ctx The library configuration object
+ * @param algo The hash algorithm to apply the pepper to
+ * @param data The pepper
+ * @param len The number of bytes in `data`
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS The hash algorithm `algo` is either not
+ * recognised or was disabled at compile-time
+ * @throws ENOSUP The hash algorithm `algo` does not support
+ * peppers; the application is instead adviced
+ * to, itself, append or prepend the pepper
+ * to the password
+ * @throws EINVAL The size of the pepper is unsupported
+ * for the hash algorithm `algo`
+ *
+ * The caller is responsible for the lifetime of `data`:
+ * deallocating it will deallocate it for `ctx` as it
+ * only holds a reference to `data`, not a copy of it
+ *
+ * @seealso librecrypt_create_context
+ * @seealso librecrypt_hash_algorithm_end
+ *
+ * @since 1.1
+ */
+LIBRECRYPT_NONNULL_1__
+int librecrypt_context_set_pepper(LIBRECRYPT_CONTEXT *ctx, enum librecrypt_hash_algorithm algo, const void *data, size_t len); /* TODO man */
#if defined(__clang__)
diff --git a/librecrypt_add_algorithm.3 b/librecrypt_add_algorithm.3
index 8eaabfd..702b30a 100644
--- a/librecrypt_add_algorithm.3
+++ b/librecrypt_add_algorithm.3
@@ -8,7 +8,7 @@ librecrypt_add_algorithm - Append an algorithm chain to a password hash string
ssize_t \fBlibrecrypt_add_algorithm\fP(char *\fIout_buffer\fP, size_t \fIsize\fP,
const char *\fIaugend\fP, const char *restrict \fIaugment\fP,
- void *\fIreserved\fP);
+ LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -37,9 +37,13 @@ the additional hashing to perform.
If it contains a hash result, that part is ignored.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
On successful completion, if
.I size
@@ -84,11 +88,6 @@ The
function will fail if:
.TP
.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
-.B EINVAL
.I augend
or
.I augment
@@ -153,6 +152,23 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_add_algorithm ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_crypt (3),
diff --git a/librecrypt_add_algorithm.c b/librecrypt_add_algorithm.c
index 5501f8d..4056041 100644
--- a/librecrypt_add_algorithm.c
+++ b/librecrypt_add_algorithm.c
@@ -9,7 +9,8 @@
ssize_t
-librecrypt_add_algorithm(char *out_buffer, size_t size, const char *augend, const char *restrict augment, void *reserved)
+librecrypt_add_algorithm(char *out_buffer, size_t size, const char *augend,
+ const char *restrict augment, LIBRECRYPT_CONTEXT *ctx)
{
size_t prefix1, prefix2, min, ret, len, phraselen;
size_t hashsize1, hashsize2;
@@ -18,12 +19,6 @@ librecrypt_add_algorithm(char *out_buffer, size_t size, const char *augend, cons
const unsigned char *lut;
ssize_t r;
- /* Ensure the reserved parameter is NULL */
- if (reserved != NULL) {
- errno = EINVAL;
- return -1;
- }
-
/* Reserve space for NUL-termination */
if (size) {
nul_term = 1;
@@ -33,8 +28,8 @@ librecrypt_add_algorithm(char *out_buffer, size_t size, const char *augend, cons
}
/* Get the prefix and hash size in `augend` and `augment` */
- prefix1 = librecrypt_settings_prefix(augend, &hashsize1, reserved);
- prefix2 = librecrypt_settings_prefix(augment, &hashsize2, reserved);
+ prefix1 = librecrypt_settings_prefix(augend, &hashsize1, ctx);
+ prefix2 = librecrypt_settings_prefix(augment, &hashsize2, ctx);
/* If `augend` specifies a hash size rather than a hash, include it as the prefix */
if (augend[prefix1] == '*') {
@@ -128,7 +123,7 @@ librecrypt_add_algorithm(char *out_buffer, size_t size, const char *augend, cons
len = strlen(&augend[prefix1]);
/* Get encoding information */
- lut = librecrypt_get_encoding(augend, prefix1 + len, &pad, &strict_pad, 1, reserved);
+ lut = librecrypt_get_encoding(augend, prefix1 + len, &pad, &strict_pad, 1, ctx);
if (!lut)
return -1;
@@ -170,7 +165,7 @@ librecrypt_add_algorithm(char *out_buffer, size_t size, const char *augend, cons
}
/* Chain the hash algorithms: write `augment` and hash */
- r = librecrypt_crypt(out_buffer, nul_term ? size + 1u : 0u, phrase, phraselen, augment, reserved);
+ r = librecrypt_crypt(out_buffer, nul_term ? size + 1u : 0u, phrase, phraselen, augment, ctx);
if (r <= 0) {
librecrypt_wipe(phrase, phraselen);
free(phrase);
@@ -205,7 +200,6 @@ main(void)
#define HASH1 "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTYVWXYZ/+"
#define ASTRA "*48"
- char reserved[1] = {0};
char buf[1024], phrase[sizeof(buf)], expected[sizeof(buf)], pad;
size_t i, min, phraselen;
int strict_pad;
@@ -270,16 +264,8 @@ main(void)
}\
} while (0)
- errno = 0;
- EXPECT(librecrypt_add_algorithm(NULL, 0u, "", "", reserved) == -1);
- EXPECT(errno == EINVAL);
-
#if defined(SUPPORT_ARGON2I) && defined(SUPPORT_ARGON2D)
- errno = 0;
- EXPECT(librecrypt_add_algorithm(NULL, 0u, "$argon2d$v=16$m=8,t=1,p=1$*16$*40", "$argon2d$v=16$m=8,t=1,p=1$*16$*40", reserved) == -1);
- EXPECT(errno == EINVAL);
-
CHECK("$argon2d$v=16$m=8,t=1,p=1$*16$*40", "$argon2i$v=19$m=16,t=4,p=2$*18$*50",
"$argon2d$v=16$m=8,t=1,p=1$*16$*40>" "$argon2i$v=19$m=16,t=4,p=2$*18$*50");
diff --git a/librecrypt_context_get_pepper_.c b/librecrypt_context_get_pepper_.c
new file mode 100644
index 0000000..69373f5
--- /dev/null
+++ b/librecrypt_context_get_pepper_.c
@@ -0,0 +1,63 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+struct pepper *
+librecrypt_context_get_pepper_(LIBRECRYPT_CONTEXT *ctx, enum librecrypt_hash_algorithm algo, size_t len)
+{
+ struct pepper *pepper;
+ size_t index = (size_t)algo;
+
+ switch (algo) {
+
+#if defined(SUPPORT_ARGON2I) || defined(SUPPORT_ARGON2D) || defined(SUPPORT_ARGON2ID) || defined(SUPPORT_ARGON2DS)
+# if defined(SUPPORT_ARGON2I)
+ case LIBRECRYPT_ARGON2I_V1_0:
+ case LIBRECRYPT_ARGON2I_V1_3:
+# endif
+# if defined(SUPPORT_ARGON2D)
+ case LIBRECRYPT_ARGON2D_V1_0:
+ case LIBRECRYPT_ARGON2D_V1_3:
+# endif
+# if defined(SUPPORT_ARGON2ID)
+ case LIBRECRYPT_ARGON2ID_V1_0:
+ case LIBRECRYPT_ARGON2ID_V1_3:
+# endif
+# if defined(SUPPORT_ARGON2DS)
+ case LIBRECRYPT_ARGON2DS_V1_0:
+ case LIBRECRYPT_ARGON2DS_V1_3:
+# endif
+# if SIZE_MAX > UINT32_MAX /* LIBAR2_MAX_KEYLEN is just UINT32_MAX cast to size_t; keep it simple: don't include <libar2.h> */
+ if (len > UINT32_MAX) {
+ errno = EINVAL;
+ return NULL;
+ }
+# endif
+ return &ctx->peppers[algo];
+#endif
+
+ default:
+ errno = ENOSYS;
+ return NULL;
+ }
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+
+ /* TODO test */
+
+ STOP_RESOURCE_TEST();
+ return 0;
+}
+
+
+#endif
diff --git a/librecrypt_context_get_user_data.c b/librecrypt_context_get_user_data.c
new file mode 100644
index 0000000..b49b42d
--- /dev/null
+++ b/librecrypt_context_get_user_data.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+void *
+librecrypt_context_get_user_data(LIBRECRYPT_CONTEXT *ctx)
+{
+ return ctx->user_data;
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+
+ /* TODO test */
+
+ STOP_RESOURCE_TEST();
+ return 0;
+}
+
+
+#endif
diff --git a/librecrypt_context_set_pepper.c b/librecrypt_context_set_pepper.c
new file mode 100644
index 0000000..a5d6151
--- /dev/null
+++ b/librecrypt_context_set_pepper.c
@@ -0,0 +1,37 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+int
+librecrypt_context_set_pepper(LIBRECRYPT_CONTEXT *ctx, enum librecrypt_hash_algorithm algo, const void *data, size_t len)
+{
+ struct pepper *pepper;
+
+ pepper = librecrypt_context_get_pepper_(ctx, algo, len);
+ if (!pepper)
+ return -1;
+
+ pepper->data = data;
+ pepper->len = len;
+ return 0;
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+
+ /* TODO test */
+
+ STOP_RESOURCE_TEST();
+ return 0;
+}
+
+
+#endif
diff --git a/librecrypt_context_set_user_data.c b/librecrypt_context_set_user_data.c
new file mode 100644
index 0000000..f1be75f
--- /dev/null
+++ b/librecrypt_context_set_user_data.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+void
+librecrypt_context_set_user_data(LIBRECRYPT_CONTEXT *ctx, void *user)
+{
+ ctx->user_data = user;
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+
+ /* TODO test */
+
+ STOP_RESOURCE_TEST();
+ return 0;
+}
+
+
+#endif
diff --git a/librecrypt_create_context.c b/librecrypt_create_context.c
new file mode 100644
index 0000000..c9696d7
--- /dev/null
+++ b/librecrypt_create_context.c
@@ -0,0 +1,47 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+LIBRECRYPT_CONTEXT *
+librecrypt_create_context(void)
+{
+ LIBRECRYPT_CONTEXT *ret;
+ size_t i;
+
+ ret = calloc(1u, sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ /* calloc, sets all bytes to 0, but NULL isn't necessarily
+ * presented by all zeroes even though assigning 0 to a
+ * pointer assigns it NULL, therefore we have to manually
+ * set all pointers to NULL; just to be defensive, we
+ * set all pointers to NULL, even ones that have a length
+ * (zeroed) associated with them */
+
+ ret->user_data = NULL;
+ for (i = 0u; i < ELEMSOF(ret->peppers); i++)
+ ret->peppers[i].data = NULL;
+
+ return ret;
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+
+ /* TODO test */
+
+ STOP_RESOURCE_TEST();
+ return 0;
+}
+
+
+#endif
diff --git a/librecrypt_crypt.3 b/librecrypt_crypt.3
index 63d08da..c7cba43 100644
--- a/librecrypt_crypt.3
+++ b/librecrypt_crypt.3
@@ -8,7 +8,7 @@ librecrypt_crypt - Compute password hash encoded in ASCII with settings prefix
ssize_t \fBlibrecrypt_crypt\fP(char *restrict \fIout_buffer\fP, size_t \fIsize\fP,
const char *\fIphrase\fP, size_t \fIlen\fP,
- const char *\fIsettings\fP, void *\fIreserved\fP);
+ const char *\fIsettings\fP, LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -39,10 +39,13 @@ If
contains a resulting hash, it is ignored.
.PP
The
-.I reserved
-parameter is reserved for future use and
-should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
On successful completion, if
.I size
@@ -80,11 +83,6 @@ The
function will fail if:
.TP
.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
-.B EINVAL
.I settings
is invalid.
.TP
@@ -127,6 +125,23 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_crypt ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_hash_binary (3),
diff --git a/librecrypt_crypt.c b/librecrypt_crypt.c
index c3f441b..af46520 100644
--- a/librecrypt_crypt.c
+++ b/librecrypt_crypt.c
@@ -4,9 +4,10 @@
ssize_t
-librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phrase, size_t len, const char *settings, void *reserved)
+librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phrase,
+ size_t len, const char *settings, LIBRECRYPT_CONTEXT *ctx)
{
- return librecrypt_hash_(out_buffer, size, phrase, len, settings, reserved, ASCII_CRYPT);
+ return librecrypt_hash_(out_buffer, size, phrase, len, settings, ctx, ASCII_CRYPT);
}
diff --git a/librecrypt_find_first_algorithm_.c b/librecrypt_find_first_algorithm_.c
index 2a33b5e..ebe3699 100644
--- a/librecrypt_find_first_algorithm_.c
+++ b/librecrypt_find_first_algorithm_.c
@@ -4,12 +4,14 @@
const struct librecrypt_algorithm *
-librecrypt_find_first_algorithm_(const char *settings, size_t len)
+librecrypt_find_first_algorithm_(const char *settings, size_t len, LIBRECRYPT_CONTEXT *ctx)
{
unsigned r, priority = 0;
const struct librecrypt_algorithm *algo, *found = NULL;
size_t i;
+ (void) ctx; /* TODO */
+
for (i = 0u;; i++) {
/* Get next algorithm in the list */
algo = &librecrypt_algorithms_[i];
@@ -45,10 +47,10 @@ librecrypt_find_first_algorithm_(const char *settings, size_t len)
#define CHECK(ALGO)\
do {\
- algo = librecrypt_find_first_algorithm_(ALGO, sizeof(ALGO) - 1u);\
+ algo = librecrypt_find_first_algorithm_(ALGO, sizeof(ALGO) - 1u, NULL);\
EXPECT(algo != NULL);\
EXPECT((*algo->is_algorithm)(ALGO, sizeof(ALGO) - 1u) > 0u);\
- EXPECT(librecrypt_find_first_algorithm_(ALGO">"NSA, sizeof(ALGO">"NSA) - 1u) == algo);\
+ EXPECT(librecrypt_find_first_algorithm_(ALGO">"NSA, sizeof(ALGO">"NSA) - 1u, NULL) == algo);\
} while (0)
@@ -60,8 +62,8 @@ main(void)
SET_UP_ALARM();
INIT_RESOURCE_TEST();
- EXPECT(librecrypt_find_first_algorithm_(NSA, sizeof(NSA) - 1u) == NULL);
- EXPECT(librecrypt_find_first_algorithm_(NSA">", sizeof(NSA">") - 1u) == NULL);
+ EXPECT(librecrypt_find_first_algorithm_(NSA, sizeof(NSA) - 1u, NULL) == NULL);
+ EXPECT(librecrypt_find_first_algorithm_(NSA">", sizeof(NSA">") - 1u, NULL) == NULL);
IF__argon2i__SUPPORTED(CHECK("$argon2i$"));
IF__argon2d__SUPPORTED(CHECK("$argon2d$"));
diff --git a/librecrypt_free_context.c b/librecrypt_free_context.c
new file mode 100644
index 0000000..481282f
--- /dev/null
+++ b/librecrypt_free_context.c
@@ -0,0 +1,30 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+void
+librecrypt_free_context(LIBRECRYPT_CONTEXT *ctx)
+{
+ librecrypt_wipe(ctx, sizeof(*ctx));
+ free(ctx);
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+
+ /* TODO test */
+
+ STOP_RESOURCE_TEST();
+ return 0;
+}
+
+
+#endif
diff --git a/librecrypt_get_encoding.3 b/librecrypt_get_encoding.3
index 5e8d0c5..a3f3d41 100644
--- a/librecrypt_get_encoding.3
+++ b/librecrypt_get_encoding.3
@@ -7,7 +7,7 @@ librecrypt_get_encoding - Get encoding alphabet for the last algorithm in a chai
#include <librecrypt.h>
const void *\fBlibrecrypt_get_encoding\fP(const char *\fIsettings\fP, size_t \fIlen\fP, char *\fIpad_out\fP,
- int *\fIstrict_pad_out\fP, int \fIdecoding\fP, void *\fIreserved\fP);
+ int *\fIstrict_pad_out\fP, int \fIdecoding\fP, LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -45,9 +45,13 @@ alphabet and any other character to
.BR 0xFFu .
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
On successful completion,
.IR *pad_out
@@ -82,11 +86,6 @@ The
.BR librecrypt_get_encoding ()
function will fail if:
.TP
-.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
.B ENOSYS
The last algorithm in
.I settings
@@ -116,6 +115,23 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_get_encoding ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_encode (3),
diff --git a/librecrypt_get_encoding.c b/librecrypt_get_encoding.c
index cad16df..c1cf64c 100644
--- a/librecrypt_get_encoding.c
+++ b/librecrypt_get_encoding.c
@@ -4,17 +4,12 @@
const void *
-librecrypt_get_encoding(const char *settings, size_t len, char *pad_out, int *strict_pad_out, int decoding, void *reserved)
+librecrypt_get_encoding(const char *settings, size_t len, char *pad_out, int *strict_pad_out,
+ int decoding, LIBRECRYPT_CONTEXT *ctx)
{
size_t i, start = 0u;
const struct librecrypt_algorithm *algo;
- /* Ensure the reserved parameter is NULL */
- if (reserved != NULL) {
- errno = EINVAL;
- return NULL;
- }
-
/* Find last algorithm in the chain */
for (i = 0u; i < len; i++)
if (settings[i] == LIBRECRYPT_ALGORITHM_LINK_DELIMITER)
@@ -23,7 +18,7 @@ librecrypt_get_encoding(const char *settings, size_t len, char *pad_out, int *st
len -= start;
/* Identify the algorithm */
- algo = librecrypt_find_first_algorithm_(settings, len);
+ algo = librecrypt_find_first_algorithm_(settings, len, ctx);
if (!algo) {
errno = ENOSYS;
return NULL;
@@ -110,7 +105,6 @@ check_decoding_lut(const unsigned char *lut, const char *alpha)
int
main(void)
{
- char reserved[1] = {0};
const char *elut;
const unsigned char *dlut;
char pad;
@@ -120,10 +114,6 @@ main(void)
INIT_RESOURCE_TEST();
errno = 0;
- EXPECT(librecrypt_get_encoding("$argon2i$", sizeof("$argon2i$") - 1u, &pad, &strict_pad, 0, reserved) == NULL);
- EXPECT(errno == EINVAL);
-
- errno = 0;
EXPECT(librecrypt_get_encoding(NSA, sizeof(NSA) - 1u, &pad, &strict_pad, 0, NULL) == NULL);
EXPECT(errno == ENOSYS);
diff --git a/librecrypt_hash.3 b/librecrypt_hash.3
index 835a704..5be93c7 100644
--- a/librecrypt_hash.3
+++ b/librecrypt_hash.3
@@ -8,7 +8,7 @@ librecrypt_hash - Compute password hash encoded in ASCII without settings prefix
ssize_t \fBlibrecrypt_hash\fP(char *restrict \fIout_buffer\fP, size_t \fIsize\fP,
const char *\fIphrase\fP, size_t \fIlen\fP,
- const char *\fIsettings\fP, void *\fIreserved\fP);
+ const char *\fIsettings\fP, LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -40,9 +40,13 @@ uses asterisk-encoding to specify random salts,
the function fails.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
On successful completion, if
.I size
@@ -80,11 +84,6 @@ The
function will fail if:
.TP
.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
-.B EINVAL
.I settings
is invalid.
.TP
@@ -131,6 +130,23 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_hash ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_hash_binary (3),
diff --git a/librecrypt_hash.c b/librecrypt_hash.c
index e00c35b..06bfe65 100644
--- a/librecrypt_hash.c
+++ b/librecrypt_hash.c
@@ -4,9 +4,10 @@
ssize_t
-librecrypt_hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len, const char *settings, void *reserved)
+librecrypt_hash(char *restrict out_buffer, size_t size, const char *phrase,
+ size_t len, const char *settings, LIBRECRYPT_CONTEXT *ctx)
{
- return librecrypt_hash_(out_buffer, size, phrase, len, settings, reserved, ASCII_HASH);
+ return librecrypt_hash_(out_buffer, size, phrase, len, settings, ctx, ASCII_HASH);
}
diff --git a/librecrypt_hash_.c b/librecrypt_hash_.c
index e240c81..8b1ab1d 100644
--- a/librecrypt_hash_.c
+++ b/librecrypt_hash_.c
@@ -44,7 +44,7 @@ has_asterisk_encoded_salt(const char *settings)
ssize_t
librecrypt_hash_(char *restrict out_buffer, size_t size, const char *phrase, size_t len,
- const char *settings, void *reserved, enum action action)
+ const char *settings, LIBRECRYPT_CONTEXT *ctx, enum action action)
{
const struct librecrypt_algorithm *algo;
ssize_t (*rng)(void *out, size_t n, void *user) = NULL;
@@ -58,10 +58,6 @@ librecrypt_hash_(char *restrict out_buffer, size_t size, const char *phrase, siz
int r, saved_errno;
void *new;
- /* Ensure the reserved parameter is NULL */
- if (reserved != NULL)
- goto einval;
-
/* Realise asterisk-encoded salts */
if (has_asterisk_encoded_salt(settings)) {
/* Only `librecrypt_crypt` outputs the configrations,
@@ -80,7 +76,7 @@ librecrypt_hash_(char *restrict out_buffer, size_t size, const char *phrase, siz
rng = &zero_generator;
/* Generate the salts */
- r_len = librecrypt_realise_salts(out_buffer, size, settings, rng, NULL, reserved);
+ r_len = librecrypt_realise_salts(out_buffer, size, settings, rng, NULL, ctx);
if (r_len < 0) {
if (errno == ERANGE) {
errno = ENOMEM;
@@ -91,7 +87,7 @@ librecrypt_hash_(char *restrict out_buffer, size_t size, const char *phrase, siz
settings_scratch = malloc((size_t)r_len + 1u);
if (!settings_scratch)
return -1;
- if (librecrypt_realise_salts(settings_scratch, (size_t)r_len + 1u, settings, rng, NULL, reserved) != r_len)
+ if (librecrypt_realise_salts(settings_scratch, (size_t)r_len + 1u, settings, rng, NULL, ctx) != r_len)
abort(); /* $covered$ (impossible) */
settings = settings_scratch;
}
@@ -107,7 +103,7 @@ next:
}
/* Identify the algorithm */
- algo = librecrypt_find_first_algorithm_(settings, n);
+ algo = librecrypt_find_first_algorithm_(settings, n, ctx);
if (!algo) {
errno = ENOSYS;
goto fail;
@@ -214,11 +210,11 @@ next:
hash_to_scratch:
r = (*algo->hash)(size ? phrase_scratches[phrase_scratch_i] : NULL,
size ? phrase_scratch_sizes[phrase_scratch_i] : 0u,
- phrase, len, settings, n, reserved);
+ phrase, len, settings, n, ctx);
} else if (action == BINARY_HASH) {
/* Final hash in binary: write immediate to output */
hash_to_output:
- r = (*algo->hash)(out_buffer, size, phrase, len, settings, n, reserved);
+ r = (*algo->hash)(out_buffer, size, phrase, len, settings, n, ctx);
} else if (size < hash_size) {
/* Final hash in ASCII: write to scratch if output is truncated,
* because it will be converted to ASCII later */
@@ -378,16 +374,11 @@ main(void)
char sbuf[160];
size_t i, n;
ssize_t r, r1, r1b, r1c, r2, r3;
- char reserved[1] = {0};
SET_UP_ALARM();
INIT_RESOURCE_TEST();
errno = 0;
- EXPECT(librecrypt_hash_(NULL, 0u, NULL, 0u, "$~no~such~algorithm~$", reserved, ASCII_CRYPT) == -1);
- EXPECT(errno == EINVAL);
-
- errno = 0;
EXPECT(librecrypt_hash_(NULL, 0u, NULL, 0u, "$~no~such~algorithm~$", NULL, ASCII_CRYPT) == -1);
EXPECT(errno == ENOSYS);
diff --git a/librecrypt_hash_algorithm_end.c b/librecrypt_hash_algorithm_end.c
new file mode 100644
index 0000000..adb1555
--- /dev/null
+++ b/librecrypt_hash_algorithm_end.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+enum librecrypt_hash_algorithm librecrypt_hash_algorithm_end = LIBRECRYPT_HASH_ALGORITHM_END;
+
+
+#else
+
+
+int
+main(void)
+{
+ SET_UP_ALARM();
+ INIT_RESOURCE_TEST();
+
+ assert(librecrypt_hash_algorithm_end == LIBRECRYPT_HASH_ALGORITHM_END);
+ /* LIBRECRYPT_HASH_ALGORITHM_END having the corret value is tested
+ * in librecrypt_is_enabled.c */
+
+ STOP_RESOURCE_TEST();
+ return 0;
+}
+
+
+#endif
diff --git a/librecrypt_hash_binary.3 b/librecrypt_hash_binary.3
index 759bfd7..9956f83 100644
--- a/librecrypt_hash_binary.3
+++ b/librecrypt_hash_binary.3
@@ -8,7 +8,7 @@ librecrypt_hash_binary - Compute password hash in raw binary form
ssize_t \fBlibrecrypt_hash_binary\fP(void *restrict \fIout_buffer\fP, size_t \fIsize\fP,
const char *\fIphrase\fP, size_t \fIlen\fP,
- const char *\fIsettings\fP, void *\fIreserved\fP);
+ const char *\fIsettings\fP, LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -39,9 +39,13 @@ uses asterisk-encoding to specify random salts,
the function fails.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
On successful completion, up to
.I size
@@ -83,11 +87,6 @@ The
function will fail if:
.TP
.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
-.B EINVAL
.I settings
is invalid.
.TP
@@ -143,6 +142,23 @@ to
in version 1.1 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_bash_binary ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_hash (3),
diff --git a/librecrypt_hash_binary.c b/librecrypt_hash_binary.c
index 7539604..b9ca93c 100644
--- a/librecrypt_hash_binary.c
+++ b/librecrypt_hash_binary.c
@@ -4,9 +4,10 @@
ssize_t
-librecrypt_hash_binary(void *restrict out_buffer, size_t size, const char *phrase, size_t len, const char *settings, void *reserved)
+librecrypt_hash_binary(void *restrict out_buffer, size_t size, const char *phrase,
+ size_t len, const char *settings, LIBRECRYPT_CONTEXT *ctx)
{
- return librecrypt_hash_(out_buffer, size, phrase, len, settings, reserved, BINARY_HASH);
+ return librecrypt_hash_(out_buffer, size, phrase, len, settings, ctx, BINARY_HASH);
}
diff --git a/librecrypt_is_enabled.3 b/librecrypt_is_enabled.3
index b7570aa..2827180 100644
--- a/librecrypt_is_enabled.3
+++ b/librecrypt_is_enabled.3
@@ -14,7 +14,8 @@ enum librecrypt_hash_algorithm {
LIBRECRYPT_ARGON2ID_V1_0,
LIBRECRYPT_ARGON2ID_V1_3,
LIBRECRYPT_ARGON2DS_V1_0,
- LIBRECRYPT_ARGON2DS_V1_3
+ LIBRECRYPT_ARGON2DS_V1_3,
+ LIBRECRYPT_HASH_ALGORITHM_END /* end of enum marker (always last) */
};
int \fBlibrecrypt_is_enabled\fP(enum librecrypt_hash_algorithm \fIalgo\fP);
diff --git a/librecrypt_is_enabled.c b/librecrypt_is_enabled.c
index 1bc9429..7921075 100644
--- a/librecrypt_is_enabled.c
+++ b/librecrypt_is_enabled.c
@@ -74,6 +74,7 @@ main(void)
CHECK(LIBRECRYPT_ARGON2ID_V1_3, IF__argon2i__SUPPORTED(1 + ) 0);
CHECK(LIBRECRYPT_ARGON2DS_V1_0, IF__argon2i__SUPPORTED(1 + ) 0);
CHECK(LIBRECRYPT_ARGON2DS_V1_3, IF__argon2i__SUPPORTED(1 + ) 0);
+ assert((enum librecrypt_hash_algorithm)(highest + 1) == LIBRECRYPT_HASH_ALGORITHM_END);
for (i = 0; i < 1024 && highest != INT_MAX; i++)
CHECK((enum librecrypt_hash_algorithm)(highest + 1), 0);
diff --git a/librecrypt_make_settings.3 b/librecrypt_make_settings.3
index ca31417..9b39bd9 100644
--- a/librecrypt_make_settings.3
+++ b/librecrypt_make_settings.3
@@ -9,7 +9,7 @@ librecrypt_make_settings - Generate a password hash settings string
ssize_t \fBlibrecrypt_make_settings\fP(char *\fIout_buffer\fP, size_t \fIsize\fP, const char *\fIalgorithm\fP,
size_t \fImemcost\fP, uintmax_t \fItimecost\fP, int \fIgensalt\fP,
ssize_t (*\fIrng\fP)(void *\fIout\fP, size_t \fIn\fP, void *\fIuser\fP),
- void *\fIuser\fP, void *\fIreserved\fP);
+ void *\fIuser\fP, LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -78,9 +78,13 @@ with the same name, as is and may be used by
for user-defined purposes.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
On successful completion, if
.I size
@@ -120,11 +124,6 @@ The
function will fail if:
.TP
.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
-.B EINVAL
.I algorithm
represents a chain of algorithms.
.TP
@@ -183,6 +182,23 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_make_settings ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_realise_salts (3)
diff --git a/librecrypt_make_settings.c b/librecrypt_make_settings.c
index b883e4f..075d2a6 100644
--- a/librecrypt_make_settings.c
+++ b/librecrypt_make_settings.c
@@ -4,17 +4,13 @@
ssize_t
-librecrypt_make_settings(char *out_buffer, size_t size, const char *algorithm, size_t memcost, uintmax_t timecost,
- int gensalt, ssize_t (*rng)(void *out, size_t n, void *user), void *user, void *reserved)
+librecrypt_make_settings(char *out_buffer, size_t size, const char *algorithm,
+ size_t memcost, uintmax_t timecost, int gensalt,
+ ssize_t (*rng)(void *out, size_t n, void *user), void *user,
+ LIBRECRYPT_CONTEXT *ctx)
{
const struct librecrypt_algorithm *algo;
- /* Ensure the reserved parameter is NULL */
- if (reserved != NULL) {
- errno = EINVAL;
- return -1;
- }
-
/* Get algorithm */
if (!algorithm) {
/* Select best algorithm if `NULL` is specified */
@@ -28,7 +24,7 @@ librecrypt_make_settings(char *out_buffer, size_t size, const char *algorithm, s
return -1;
}
/* Identify the algorithm */
- algo = librecrypt_find_first_algorithm_(algorithm, strlen(algorithm));
+ algo = librecrypt_find_first_algorithm_(algorithm, strlen(algorithm), ctx);
if (!algo)
goto enosys;
}
@@ -81,7 +77,6 @@ main(void)
int any_supported = 0;
int any_salted = 0;
ssize_t r;
- char reserved[1] = {0};
SET_UP_ALARM();
INIT_RESOURCE_TEST();
@@ -103,10 +98,6 @@ main(void)
EXPECT(errno == ENOSYS);
#if defined(SUPPORT_ARGON2I)
- errno = 0;
- EXPECT(librecrypt_make_settings(NULL, 0u, "$argon2id$", 0u, 0u, 0, NULL, NULL, reserved) == -1);
- EXPECT(errno == EINVAL);
-
saltbyte = 0u;
CANARY_FILL(buf);
r = librecrypt_make_settings(buf, sizeof(buf), "$argon2i$", 8192u << 10, (uintmax_t)81920u, 1, &saltgen, &saltbyte, NULL);
diff --git a/librecrypt_realise_salts.3 b/librecrypt_realise_salts.3
index 7900a4f..dba21b1 100644
--- a/librecrypt_realise_salts.3
+++ b/librecrypt_realise_salts.3
@@ -8,7 +8,7 @@ librecrypt_realise_salts - Realise asterisk-encoded random salts in a settings s
ssize_t \fBlibrecrypt_realise_salts\fP(char *restrict \fIout_buffer\fP, size_t \fIsize\fP, const char *\fIsettings\fP,
ssize_t (*\fIrng\fP)(void *\fIout\fP, size_t \fIn\fP, void *\fIuser\fP), void *\fIuser\fP,
- void *\fIreserved\fP);
+ LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -65,9 +65,13 @@ and return the number of generated bytes, or
-1 on failure.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
On successful completion, if
.I size
@@ -109,11 +113,6 @@ The
.BR librecrypt_realise_salts ()
function will fail if:
.TP
-.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
.B ERANGE
The expected return value is greater than {SSIZE_MAX}.
.TP
@@ -164,6 +163,23 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_realise_salts ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_make_settings (3)
diff --git a/librecrypt_realise_salts.c b/librecrypt_realise_salts.c
index eca3c4a..64d65c4 100644
--- a/librecrypt_realise_salts.c
+++ b/librecrypt_realise_salts.c
@@ -5,7 +5,8 @@
ssize_t
librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *settings,
- ssize_t (*rng)(void *out, size_t n, void *user), void *user, void *reserved)
+ ssize_t (*rng)(void *out, size_t n, void *user), void *user,
+ LIBRECRYPT_CONTEXT *ctx)
{
const char *lut;
char pad;
@@ -13,12 +14,6 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set
size_t i, min, nasterisks, prefix, ret = 0u;
size_t count, digit, q, r, left, mid, right;
- /* Ensure the reserved parameter is NULL */
- if (reserved != NULL) {
- errno = EINVAL;
- return -1;
- }
-
/* If we are doing output, it should be NUL-terminated */
if (size) {
nul_term = 1;
@@ -46,7 +41,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set
}
/* Get binary data encoding format */
- lut = librecrypt_get_encoding(settings, prefix, &pad, &strict_pad, 0, reserved);
+ lut = librecrypt_get_encoding(settings, prefix, &pad, &strict_pad, 0, ctx);
if (!lut)
return -1;
pad = strict_pad ? pad : '\0';
@@ -209,7 +204,6 @@ main(void)
char buf[1024], buf2[1024], conf[128];
size_t i;
int r;
- char reserved[1] = {0};
SET_UP_ALARM();
INIT_RESOURCE_TEST();
@@ -232,10 +226,6 @@ main(void)
#if defined(ALGO)
- errno = 0;
- EXPECT(librecrypt_realise_salts(NULL, 0u, ALGO, NULL, NULL, reserved) == -1);
- EXPECT(errno == EINVAL);
-
# define CHECK(IN, OUT)\
do {\
EXPECT(librecrypt_realise_salts(NULL, 0u, (IN), NULL, NULL, NULL) == (ssize_t)sizeof(OUT) - 1);\
diff --git a/librecrypt_settings_prefix.3 b/librecrypt_settings_prefix.3
index 8981133..8e425a8 100644
--- a/librecrypt_settings_prefix.3
+++ b/librecrypt_settings_prefix.3
@@ -6,7 +6,8 @@ librecrypt_settings_prefix - Get length of settings prefix in a password hash st
.nf
#include <librecrypt.h>
-size_t \fBlibrecrypt_settings_prefix\fP(const char *\fIhash\fP, size_t *\fIhashsize_out\fP, void *\fIreserved\fP);
+size_t \fBlibrecrypt_settings_prefix\fP(const char *\fIhash\fP, size_t *\fIhashsize_out\fP,
+ LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -45,9 +46,13 @@ See the
section for more information.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
.I hash
must not be
@@ -110,6 +115,17 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_settings_prefix ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ).
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_chain_length (3)
diff --git a/librecrypt_settings_prefix.c b/librecrypt_settings_prefix.c
index c8fed53..89bb5ae 100644
--- a/librecrypt_settings_prefix.c
+++ b/librecrypt_settings_prefix.c
@@ -4,15 +4,13 @@
size_t
-librecrypt_settings_prefix(const char *hash, size_t *hashsize_out, void *reserved)
+librecrypt_settings_prefix(const char *hash, size_t *hashsize_out, LIBRECRYPT_CONTEXT *ctx)
{
size_t i, len, ret = 0u;
size_t last_offset = 0u;
const struct librecrypt_algorithm *algo;
uintmax_t hashsize;
- (void) reserved;
-
/* Find last algorithm, and beginning of result */
for (i = 0u; hash[i]; i++) {
if (hash[i] == LIBRECRYPT_HASH_COMPOSITION_DELIMITER)
@@ -34,7 +32,7 @@ librecrypt_settings_prefix(const char *hash, size_t *hashsize_out, void *reserve
if (ret == i)
goto zero;
/* Return 0 as hash size if algorithm cannot be identified or has fixed hash size */
- algo = librecrypt_find_first_algorithm_(&hash[last_offset], len - last_offset);
+ algo = librecrypt_find_first_algorithm_(&hash[last_offset], len - last_offset, ctx);
if (!algo)
goto zero;
if (!algo->flexible_hash_size)
diff --git a/librecrypt_test_supported.3 b/librecrypt_test_supported.3
index 9cb1ec4..86dcc7a 100644
--- a/librecrypt_test_supported.3
+++ b/librecrypt_test_supported.3
@@ -7,7 +7,7 @@ librecrypt_test_supported - Check whether an algorithm chain is supported
#include <librecrypt.h>
int \fBlibrecrypt_test_supported\fP(const char *\fIphrase\fP, size_t \fIlen\fP, int \fItext\fP,
- const char *\fIsettings\fP, void *\fIreserved\fP);
+ const char *\fIsettings\fP, LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -47,9 +47,13 @@ is zero. If
is non-zero, UTF-8 without null bytes is assumed.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
If
.I phrase
@@ -97,6 +101,23 @@ The
function was introduced in version 1.0 of
.BR librecrypt .
+Since version 1.1 of the
+.BR librecrypt_test_supported ()
+function, the
+.I ctx
+parameter (previously called
+.IR reserved )
+has the type
+.B LIBRECRYPT_CONTEXT *
+(previously
+.BR "void *" ),
+and setting it to
+.RI non- NULL
+no longer causes failure with
+.I errno
+set to
+.IR EINVAL .
+
.SH SEE ALSO
.BR librecrypt (7),
.BR librecrypt_test_supported (3),
diff --git a/librecrypt_test_supported.c b/librecrypt_test_supported.c
index 6d2a7a6..9cc8bd5 100644
--- a/librecrypt_test_supported.c
+++ b/librecrypt_test_supported.c
@@ -4,13 +4,11 @@
int
-librecrypt_test_supported(const char *phrase, size_t len, int text, const char *settings, void *reserved)
+librecrypt_test_supported(const char *phrase, size_t len, int text, const char *settings, LIBRECRYPT_CONTEXT *ctx)
{
const struct librecrypt_algorithm *algo;
size_t n;
- (void) reserved;
-
/* For each chained algorithm */
for (;;) {
/* Measure until next '>' */
@@ -19,7 +17,7 @@ librecrypt_test_supported(const char *phrase, size_t len, int text, const char *
break;
/* Identify algorithm */
- algo = librecrypt_find_first_algorithm_(settings, n);
+ algo = librecrypt_find_first_algorithm_(settings, n, ctx);
if (!algo)
return 0;
diff --git a/librecrypt_verify.3 b/librecrypt_verify.3
index 1ee86d2..743ddd4 100644
--- a/librecrypt_verify.3
+++ b/librecrypt_verify.3
@@ -7,7 +7,7 @@ librecrypt_verify - Verify password against known password hash
#include <librecrypt.h>
int \fBlibrecrypt_verify\fP(const char *\fIphrase\fP, size_t \fIlen\fP,
- const char *\fIsettings\fP, void *\fIreserved\fP);
+ const char *\fIsettings\fP, LIBRECRYPT_CONTEXT *\fIctx\fP);
.fi
.PP
Link with
@@ -40,9 +40,13 @@ uses asterisk-encoding to specify random salts,
the function fails.
.PP
The
-.I reserved
-parameter is reserved for future use and should be
-.IR NULL .
+.I ctx
+parameter is used for providing library
+configurations, see
+.BR librecrypt_create_context (3)
+for more information; used
+.I NULL
+for default configurations.
.PP
Any encountered
.BR EINTR
@@ -67,11 +71,6 @@ The
function will fail if:
.TP
.B EINVAL
-.I reserved
-is not
-.IR NULL .
-.TP
-.B EINVAL
.I settings
is invalid.
.TP
diff --git a/librecrypt_verify.c b/librecrypt_verify.c
index 990f37e..04efff4 100644
--- a/librecrypt_verify.c
+++ b/librecrypt_verify.c
@@ -4,7 +4,7 @@
int
-librecrypt_verify(const char *phrase, size_t len, const char *settings, void *reserved)
+librecrypt_verify(const char *phrase, size_t len, const char *settings, LIBRECRYPT_CONTEXT *ctx)
{
char *hash = NULL;
size_t size = 0u;
@@ -13,7 +13,7 @@ librecrypt_verify(const char *phrase, size_t len, const char *settings, void *re
int ret, err;
/* Measure base64 hash size */
- n = librecrypt_hash_(NULL, 0u, phrase, len, settings, reserved, ASCII_HASH);
+ n = librecrypt_hash_(NULL, 0u, phrase, len, settings, ctx, ASCII_HASH);
if (n < 0) {
if (errno == EOVERFLOW)
errno = ENOMEM; /* $covered$ (on 32-bit) */
@@ -21,7 +21,7 @@ librecrypt_verify(const char *phrase, size_t len, const char *settings, void *re
}
/* Get position of hash in `settings` */
- off = librecrypt_settings_prefix(settings, NULL, reserved);
+ off = librecrypt_settings_prefix(settings, NULL, ctx);
if (settings[off] == '*') {
if ('0' <= settings[off + 1u] && settings[off + 1u] <= '9') {
errno = EINVAL;
@@ -39,7 +39,7 @@ librecrypt_verify(const char *phrase, size_t len, const char *settings, void *re
return -1;
/* Calculate password hash and encode to base64 */
- n = librecrypt_hash_(hash, size, phrase, len, settings, reserved, ASCII_HASH);
+ n = librecrypt_hash_(hash, size, phrase, len, settings, ctx, ASCII_HASH);
if (n < 0) {
err = errno;
librecrypt_wipe(hash, size);