diff options
| author | Mattias Andrée <m@maandree.se> | 2026-05-19 20:09:27 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-05-19 20:09:27 +0200 |
| commit | 43ae14745c588f31c9ceb058645577cf2a5ce810 (patch) | |
| tree | 7ecade8d4e57d6d346123121731da3ef1c305fff | |
| parent | Fix typo (diff) | |
| download | librecrypt-43ae14745c588f31c9ceb058645577cf2a5ce810.tar.gz librecrypt-43ae14745c588f31c9ceb058645577cf2a5ce810.tar.bz2 librecrypt-43ae14745c588f31c9ceb058645577cf2a5ce810.tar.xz | |
Add librecrypt_verify
Signed-off-by: Mattias Andrée <m@maandree.se>
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | README | 3 | ||||
| -rw-r--r-- | librecrypt.7 | 3 | ||||
| -rw-r--r-- | librecrypt.h | 59 | ||||
| -rw-r--r-- | librecrypt_crypt.3 | 1 | ||||
| -rw-r--r-- | librecrypt_equal.3 | 3 | ||||
| -rw-r--r-- | librecrypt_equal_binary.3 | 3 | ||||
| -rw-r--r-- | librecrypt_hash.3 | 1 | ||||
| -rw-r--r-- | librecrypt_hash_binary.3 | 12 | ||||
| -rw-r--r-- | librecrypt_hash_binary.c | 2 | ||||
| -rw-r--r-- | librecrypt_test_supported.c | 2 | ||||
| -rw-r--r-- | librecrypt_verify.3 | 128 | ||||
| -rw-r--r-- | librecrypt_verify.c | 71 |
13 files changed, 284 insertions, 9 deletions
@@ -14,7 +14,7 @@ include mk/$(OS).mk LIB_MAJOR = 1 -LIB_MINOR = 0 +LIB_MINOR = 1 LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR) LIB_NAME = recrypt @@ -47,7 +47,8 @@ OBJ_PUBLIC =\ librecrypt_hash_binary.o\ librecrypt_hash.o\ librecrypt_crypt.o\ - librecrypt_add_algorithm.o + librecrypt_add_algorithm.o\ + librecrypt_verify.o OBJ_PRIVATE =\ librecrypt_algorithms_.o\ @@ -41,6 +41,9 @@ DESCRIPTION librecrypt_hash_binary(3) Compute password hash in raw binary form. + librecrypt_verify(3) + Validate password against known password hash. + librecrypt_add_algorithm(3) Append an algorithm chain to a password hash string. diff --git a/librecrypt.7 b/librecrypt.7 index d576658..0530246 100644 --- a/librecrypt.7 +++ b/librecrypt.7 @@ -60,6 +60,9 @@ settings prefix. .BR librecrypt_hash_binary (3) Compute password hash in raw binary form. .TP +.BR librecrypt_verify (3) +Validate password against known password hash. +.TP .BR librecrypt_add_algorithm (3) Append an algorithm chain to a password hash string. .sp diff --git a/librecrypt.h b/librecrypt.h index ee94c40..628849e 100644 --- a/librecrypt.h +++ b/librecrypt.h @@ -445,6 +445,9 @@ librecrypt_wipe_str(char *string) * @return 1 if the `a` and `b` are equal in their * first `len` bytes, 0 otherwise * + * @seealso librecrypt_equal + * @seealso librecrypt_verify + * * This function is MT-Safe and AS-Safe * * @since 1.0 @@ -467,6 +470,9 @@ int librecrypt_equal_binary(const void *a, const void *b, size_t len); * @param b The other string to compare * @return 1 if the `a` and `b` are equal, 0 otherwise * + * @seealso librecrypt_equal_binary + * @seealso librecrypt_verify + * * This function is MT-Safe and AS-Safe * * @since 1.0 @@ -654,16 +660,18 @@ ssize_t librecrypt_make_settings(char *out_buffer, size_t size, const char *algo * * @seealso librecrypt_hash * @seealso librecrypt_crypt + * @seealso librecrypt_verify * @seealso librecrypt_test_supported * * This function is MT-Safe but AS-Unsafe * - * @since 1.0 + * @since 1.0 Initial version + * @since 1.1 First parameter is `void *` rather than `char *` */ 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(char *restrict out_buffer, size_t size, const char *phrase, size_t len, - const char *settings, void *reserved); +ssize_t librecrypt_hash_binary(void *restrict out_buffer, size_t size, const char *phrase, + size_t len, const char *settings, void *reserved); /** @@ -712,6 +720,7 @@ ssize_t librecrypt_hash_binary(char *restrict out_buffer, size_t size, const cha * * @seealso librecrypt_hash_binary * @seealso librecrypt_crypt + * @seealso librecrypt_verify * @seealso librecrypt_test_supported * * This function is MT-Safe but AS-Unsafe @@ -769,6 +778,7 @@ ssize_t librecrypt_hash(char *restrict out_buffer, size_t size, const char *phra * * @seealso librecrypt_hash_binary * @seealso librecrypt_hash + * @seealso librecrypt_verify * @seealso librecrypt_test_supported * * This function is MT-Safe but AS-Unsafe @@ -782,6 +792,47 @@ ssize_t librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phr /** + * Compare a password against a hash + * + * @param phrase The password to hash, may contain NUL bytes + * @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` + * @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 + * in the chain (either because of format or length issues)) + * @throws EINVAL `settings` uses asterisk-encoding to specify random salts + * @thorws EINVAL `settings` uses asterisk-encoding in place of a hash result + * @throws ERANGE `len` is too large or too small for the the selected + * initial algorithm in the algorithm chain + * @throws ENOMEM Failed to allocate internal scratch memory + * @throws ENOSYS A selected hash algorithm is either not recognised + * disabled at compile-time + * + * Any encountered `EINTR` is ignored + * + * @seealso librecrypt_hash_binary + * @seealso librecrypt_hash + * @seealso librecrypt_crypt + * @seealso librecrypt_equal + * @seealso librecrypt_equal_binary + * + * This function is MT-Safe but AS-Unsafe + * + * @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); + + +/** * Check whether a hash algorithm chain is supported, * for the given input, and that each algorithm * configuration is valid @@ -808,6 +859,8 @@ ssize_t librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phr * for the first algorithm in the chain, 0 is returned * * This function is MT-Safe and AS-Safe + * + * @since 1.0 */ 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); diff --git a/librecrypt_crypt.3 b/librecrypt_crypt.3 index fd4b03a..63d08da 100644 --- a/librecrypt_crypt.3 +++ b/librecrypt_crypt.3 @@ -131,4 +131,5 @@ function was introduced in version 1.0 of .BR librecrypt (7), .BR librecrypt_hash_binary (3), .BR librecrypt_hash (3), +.BR librecrypt_verify (3), .BR librecrypt_test_supported (3) diff --git a/librecrypt_equal.3 b/librecrypt_equal.3 index cc3a387..074e6ae 100644 --- a/librecrypt_equal.3 +++ b/librecrypt_equal.3 @@ -67,4 +67,5 @@ function was introduced in version 1.0 of .SH SEE ALSO .BR librecrypt (7), -.BR librecrypt_equal_binary (3) +.BR librecrypt_equal_binary (3), +.BR librecrypt_verify (3) diff --git a/librecrypt_equal_binary.3 b/librecrypt_equal_binary.3 index d441c5b..e60768b 100644 --- a/librecrypt_equal_binary.3 +++ b/librecrypt_equal_binary.3 @@ -62,4 +62,5 @@ function was introduced in version 1.0 of .SH SEE ALSO .BR librecrypt (7), -.BR librecrypt_equal (3) +.BR librecrypt_equal (3), +.BR librecrypt_verify (3) diff --git a/librecrypt_hash.3 b/librecrypt_hash.3 index 9c864fe..835a704 100644 --- a/librecrypt_hash.3 +++ b/librecrypt_hash.3 @@ -135,4 +135,5 @@ function was introduced in version 1.0 of .BR librecrypt (7), .BR librecrypt_hash_binary (3), .BR librecrypt_crypt (3), +.BR librecrypt_verify (3), .BR librecrypt_test_supported (3) diff --git a/librecrypt_hash_binary.3 b/librecrypt_hash_binary.3 index 855906a..759bfd7 100644 --- a/librecrypt_hash_binary.3 +++ b/librecrypt_hash_binary.3 @@ -6,7 +6,7 @@ librecrypt_hash_binary - Compute password hash in raw binary form .nf #include <librecrypt.h> -ssize_t \fBlibrecrypt_hash_binary\fP(char *restrict \fIout_buffer\fP, size_t \fIsize\fP, +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); .fi @@ -134,8 +134,18 @@ The function was introduced in version 1.0 of .BR librecrypt . +The type of the +.I out_buffer +parameter changed from +.I char * +to +.I void * +in version 1.1 of +.BR librecrypt . + .SH SEE ALSO .BR librecrypt (7), .BR librecrypt_hash (3), .BR librecrypt_crypt (3), +.BR librecrypt_verify (3), .BR librecrypt_test_supported (3) diff --git a/librecrypt_hash_binary.c b/librecrypt_hash_binary.c index 7efb81e..7539604 100644 --- a/librecrypt_hash_binary.c +++ b/librecrypt_hash_binary.c @@ -4,7 +4,7 @@ ssize_t -librecrypt_hash_binary(char *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, void *reserved) { return librecrypt_hash_(out_buffer, size, phrase, len, settings, reserved, BINARY_HASH); } diff --git a/librecrypt_test_supported.c b/librecrypt_test_supported.c index db5ac7c..b063f47 100644 --- a/librecrypt_test_supported.c +++ b/librecrypt_test_supported.c @@ -9,6 +9,8 @@ librecrypt_test_supported(const char *phrase, size_t len, int text, const char * const struct algorithm *algo; size_t n; + (void) reserved; + /* For each chained algorithm */ for (;;) { /* Measure until next '>' */ diff --git a/librecrypt_verify.3 b/librecrypt_verify.3 new file mode 100644 index 0000000..8c6e421 --- /dev/null +++ b/librecrypt_verify.3 @@ -0,0 +1,128 @@ +.TH LIBRECRYPT_VERIFY 3 LIBRECRYPT +.SH NAME +librecrypt_verify - Verify password against known password hash + +.SH SYNOPSIS +.nf +#include <librecrypt.h> + +int \fBlibrecrypt_verify\fP(const char *\fIphrase\fP, size_t \fIlen\fP, + const char *\fIsettings\fP, void *\fIreserved\fP); +.fi +.PP +Link with +.IR -lrecrypt . +Static linking may require additional flags +depending on enabled hash algorithms. + +.SH DESCRIPTION +The +.BR librecrypt_verify () +function computes the hash of a password and compares +it against a provided hash. +.PP +The password is provided in +.IR phrase +and can contain null bytes; its length is specified by +.IR len . +.PP +The password hash configuration string is provided in +.IR settings , +and shall include the hash result, that is, it shall +conform to the output of the +.BR librecrypt_crypt (3) +function. If +.I settings +contains a resulting hash, it is ignored. +If +.I settings +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 . +.PP +Any encountered +.BR EINTR +is ignored. +.PP +.I settings +must not be +.IR NULL . + +.SH RETURN VALUES +The +.BR librecrypt_hash () +function returns 1 if the hash of the input +password matches the provided hash, 0 otherwise. +On failure, -1 is returned and +.I errno +is set to describe the error. + +.SH ERRORS +The +.BR librecrypt_verify () +function will fail if: +.TP +.B EINVAL +.I reserved +is not +.IR NULL . +.TP +.B EINVAL +.I settings +is invalid. +.TP +.B EINVAL +.I settings +uses asterisk-encoding to specify random salts. +.TP +.B EINVAL +.I settings +uses asterisk-encoding in place of a hash result. +.TP +.B ERANGE +.I len +is too large or too small for the selected +initial algorithm. +.TP +.B ENOMEM +Failed to allocate internal scratch memory. +.TP +.B ENOSYS +A selected hash algorithm is not recognised or +was disabled at compile-time. + +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.PP +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR librecrypt_verify () +T} Thread safety MT-Safe +T{ +.BR librecrypt_verify () +T} Async-signal safety AS-Unsafe +.TE +.sp + +.SH HISTORY +The +.BR librecrypt_verify () +function was introduced in version 1.1 of +.BR librecrypt . + +.SH SEE ALSO +.BR librecrypt (7), +.BR librecrypt_hash_binary (3), +.BR librecrypt_hash (3), +.BR librecrypt_crypt (3), +.BR librecrypt_equal (3), +.BR librecrypt_equal_binary (3) diff --git a/librecrypt_verify.c b/librecrypt_verify.c new file mode 100644 index 0000000..18d8cd8 --- /dev/null +++ b/librecrypt_verify.c @@ -0,0 +1,71 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +librecrypt_verify(const char *phrase, size_t len, const char *settings, void *reserved) +{ + char *hash = NULL; + size_t size = 0u; + size_t off; + ssize_t n; + int ret, err; + + n = librecrypt_hash_(NULL, 0u, phrase, len, settings, reserved, ASCII_HASH); + if (n < 0) { + if (errno == EOVERFLOW) + errno = ENOMEM; + return -1; + } + + off = librecrypt_settings_prefix(hash, NULL, reserved); + if (hash[off] == '*') { + if ('0'> hash[off + 1u] || hash[off + 1u] > '9') { + errno = EINVAL; + return -1; + } + } + + size = (size_t)n + 128u; /* a little extra so the hasher don't need to allocate output scratch */ + hash = malloc(size); + if (!hash) + return -1; + + n = librecrypt_hash_(hash, size, phrase, len, settings, reserved, ASCII_HASH); + if (n < 0) { + err = errno; + librecrypt_wipe(hash, size); + free(hash); + if (err == EOVERFLOW) + err = ENOMEM; + errno = err; + return -1; + } + if ((size_t)n > size) + abort(); + + ret = librecrypt_equal(hash, &settings[off]); + librecrypt_wipe(hash, size); + free(hash); + return ret; +} + + +#else + + +int +main(void) +{ + SET_UP_ALARM(); + INIT_RESOURCE_TEST(); + + /* TODO test */ + + STOP_RESOURCE_TEST(); + return 0; +} + + +#endif |
