aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-19 20:09:27 +0200
committerMattias Andrée <m@maandree.se>2026-05-19 20:09:27 +0200
commit43ae14745c588f31c9ceb058645577cf2a5ce810 (patch)
tree7ecade8d4e57d6d346123121731da3ef1c305fff
parentFix typo (diff)
downloadlibrecrypt-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--Makefile5
-rw-r--r--README3
-rw-r--r--librecrypt.73
-rw-r--r--librecrypt.h59
-rw-r--r--librecrypt_crypt.31
-rw-r--r--librecrypt_equal.33
-rw-r--r--librecrypt_equal_binary.33
-rw-r--r--librecrypt_hash.31
-rw-r--r--librecrypt_hash_binary.312
-rw-r--r--librecrypt_hash_binary.c2
-rw-r--r--librecrypt_test_supported.c2
-rw-r--r--librecrypt_verify.3128
-rw-r--r--librecrypt_verify.c71
13 files changed, 284 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 42e324d..b51cf7f 100644
--- a/Makefile
+++ b/Makefile
@@ -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\
diff --git a/README b/README
index 60b1050..60c4367 100644
--- a/README
+++ b/README
@@ -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