diff options
37 files changed, 858 insertions, 243 deletions
@@ -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 =\ @@ -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, ¶ms, &ctx)) + if (libar2_hash(scratch ? scratch : out_buffer, REMOVE_CONST(phrase), len, ¶ms, &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 @@ -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); |
