]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#8575 Add a libsodium based implementation
authorOndřej Kuzník <ondra@mistotebe.net>
Mon, 11 Nov 2019 17:42:03 +0000 (17:42 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 21 Apr 2020 19:40:21 +0000 (19:40 +0000)
contrib/slapd-modules/passwd/argon2/Makefile
contrib/slapd-modules/passwd/argon2/pw-argon2.c

index 3e7aa2dd351716a6e732197a2ad57c8f458e792e..b35d7a36f96e7c4076c71dab7f41500e1069ac4a 100644 (file)
@@ -12,7 +12,19 @@ OPT = -g -O2 -Wall
 #DEFS = -DSLAPD_ARGON2_DEBUG
 
 INCS = $(LDAP_INC)
-LIBS = $(LDAP_LIB) -largon2
+LIBS = $(LDAP_LIB)
+
+implementation = sodium
+
+ifeq ($(implementation),argon2)
+LIBS += -largon2
+DEFS += -DSLAPD_ARGON2_USE_ARGON2
+else ifeq ($(implementation),sodium)
+LIBS += -lsodium
+DEFS += -DSLAPD_ARGON2_USE_SODIUM
+else
+$(error Unsupported implementation $(implementation))
+endif
 
 PROGRAMS = pw-argon2.la
 LTVER = 0:0:0
index df0f715c1f716d6f9e4b3a8c7f3ad247832f1664..ea44033ac6b78cb6f87975525df1e71328d58268 100644 (file)
  * <http://www.OpenLDAP.org/license.html>.
  */
 
-#define _GNU_SOURCE
-
 #include "portable.h"
 #include "ac/string.h"
 #include "lber_pvt.h"
 #include "lutil.h"
 
-#include <argon2.h>
 #include <stdint.h>
 #include <stdlib.h>
 
+#ifdef SLAPD_ARGON2_USE_ARGON2
+#include <argon2.h>
+
 /*
  * For now, we hardcode the default values from the argon2 command line tool
  * (as of argon2 release 20161029)
  */
 #define SLAPD_ARGON2_ITERATIONS 3
-#define SLAPD_ARGON2_MEMORY 12
+#define SLAPD_ARGON2_MEMORY (1 << 12)
 #define SLAPD_ARGON2_PARALLELISM 1
 #define SLAPD_ARGON2_SALT_LENGTH 16
 #define SLAPD_ARGON2_HASH_LENGTH 32
 
-const struct berval slapd_argon2_scheme = BER_BVC("{ARGON2}");
+#else /* !SLAPD_ARGON2_USE_ARGON2 */
+#include <sodium.h>
 
-static int slapd_argon2_hash(
-  const struct berval *scheme,
-  const struct berval *passwd,
-  struct berval *hash,
-  const char **text) {
-
-  /*
-   * Duplicate these values here so future code which allows
-   * configuration has an easier time.
-   */
-  uint32_t iterations = SLAPD_ARGON2_ITERATIONS;
-  uint32_t memory = (1 << SLAPD_ARGON2_MEMORY);
-  uint32_t parallelism = SLAPD_ARGON2_PARALLELISM;
-  uint32_t salt_length = SLAPD_ARGON2_SALT_LENGTH;
-  uint32_t hash_length = SLAPD_ARGON2_HASH_LENGTH;
-
-  size_t encoded_length = argon2_encodedlen(iterations, memory, parallelism,
-                            salt_length, hash_length, Argon2_i);
-
-  /*
-   * Gather random bytes for our salt
-   */
-  struct berval salt;
-  salt.bv_len = salt_length;
-  salt.bv_val = ber_memalloc(salt.bv_len);
-
-  int rc = lutil_entropy((unsigned char*)salt.bv_val, salt.bv_len);
-
-  if(rc) {
-    ber_memfree(salt.bv_val);
-    return LUTIL_PASSWD_ERR;
-  }
-
-  struct berval encoded;
-  encoded.bv_len = encoded_length;
-  encoded.bv_val = ber_memalloc(encoded.bv_len);
-  /*
-   * Do the actual heavy lifting
-   */
-  rc = argon2i_hash_encoded(iterations, memory, parallelism,
-            passwd->bv_val, passwd->bv_len, salt.bv_val, salt_length, hash_length,
-            encoded.bv_val, encoded_length);
-  ber_memfree(salt.bv_val);
-
-  if(rc) {
-    ber_memfree(encoded.bv_val);
-    return LUTIL_PASSWD_ERR;
-  }
-
-  hash->bv_len = scheme->bv_len + encoded_length;
-  hash->bv_val = ber_memalloc(hash->bv_len);
-
-  AC_MEMCPY(hash->bv_val, scheme->bv_val, scheme->bv_len);
-  AC_MEMCPY(hash->bv_val + scheme->bv_len, encoded.bv_val, encoded.bv_len);
-
-  ber_memfree(encoded.bv_val);
-
-  return LUTIL_PASSWD_OK;
-}
+/*
+ * Or libsodium moderate settings
+ */
+#define SLAPD_ARGON2_ITERATIONS crypto_pwhash_OPSLIMIT_INTERACTIVE
+#define SLAPD_ARGON2_MEMORY crypto_pwhash_MEMLIMIT_INTERACTIVE
+#define SLAPD_ARGON2_PARALLELISM 1
+#define SLAPD_ARGON2_SALT_LENGTH crypto_pwhash_SALTBYTES
+#define SLAPD_ARGON2_HASH_LENGTH 32
 
-static int slapd_argon2_verify(
-  const struct berval *scheme,
-  const struct berval *passwd,
-  const struct berval *cred,
-  const char **text) {
+#endif
 
-  int rc = argon2i_verify(passwd->bv_val, cred->bv_val, cred->bv_len);
+const struct berval slapd_argon2_scheme = BER_BVC("{ARGON2}");
+
+static int
+slapd_argon2_hash(
+               const struct berval *scheme,
+               const struct berval *passwd,
+               struct berval *hash,
+               const char **text )
+{
+
+       /*
+        * Duplicate these values here so future code which allows
+        * configuration has an easier time.
+        */
+       uint32_t iterations, memory, parallelism, salt_length, hash_length;
+       char *p;
+       int rc = LUTIL_PASSWD_ERR;
+
+#ifdef SLAPD_ARGON2_USE_ARGON2
+       struct berval salt;
+       size_t encoded_length;
+
+       iterations = SLAPD_ARGON2_ITERATIONS;
+       memory = SLAPD_ARGON2_MEMORY;
+       parallelism = SLAPD_ARGON2_PARALLELISM;
+       salt_length = SLAPD_ARGON2_SALT_LENGTH;
+       hash_length = SLAPD_ARGON2_HASH_LENGTH;
+
+       encoded_length = argon2_encodedlen( iterations, memory, parallelism,
+                       salt_length, hash_length, Argon2_id );
+
+       salt.bv_len = salt_length;
+       salt.bv_val = ber_memalloc( salt.bv_len );
+
+       if ( salt.bv_val == NULL ) {
+               return LUTIL_PASSWD_ERR;
+       }
+
+       if ( lutil_entropy( (unsigned char*)salt.bv_val, salt.bv_len ) ) {
+               ber_memfree( salt.bv_val );
+               return LUTIL_PASSWD_ERR;
+       }
+
+       p = hash->bv_val = ber_memalloc( scheme->bv_len + encoded_length );
+       if ( p == NULL ) {
+               ber_memfree( salt.bv_val );
+               return LUTIL_PASSWD_ERR;
+       }
+
+       AC_MEMCPY( p, scheme->bv_val, scheme->bv_len );
+       p += scheme->bv_len;
+
+       /*
+        * Do the actual heavy lifting
+        */
+       if ( argon2i_hash_encoded( iterations, memory, parallelism,
+                               passwd->bv_val, passwd->bv_len,
+                               salt.bv_val, salt_length, hash_length,
+                               p, encoded_length ) == 0 ) {
+               rc = LUTIL_PASSWD_OK;
+       }
+       hash->bv_len = scheme->bv_len + encoded_length;
+       ber_memfree( salt.bv_val );
+
+#else /* !SLAPD_ARGON2_USE_ARGON2 */
+       iterations = SLAPD_ARGON2_ITERATIONS;
+       memory = SLAPD_ARGON2_MEMORY;
+       /* Not exposed by libsodium
+       parallelism = SLAPD_ARGON2_PARALLELISM;
+       salt_length = SLAPD_ARGON2_SALT_LENGTH;
+       hash_length = SLAPD_ARGON2_HASH_LENGTH;
+       */
+
+       p = hash->bv_val = ber_memalloc( scheme->bv_len + crypto_pwhash_STRBYTES );
+       if ( p == NULL ) {
+               return LUTIL_PASSWD_ERR;
+       }
+
+       AC_MEMCPY( hash->bv_val, scheme->bv_val, scheme->bv_len );
+       p += scheme->bv_len;
+
+       if ( crypto_pwhash_str( p, passwd->bv_val, passwd->bv_len,
+                               iterations, memory ) == 0 ) {
+               hash->bv_len = strlen( hash->bv_val );
+               rc = LUTIL_PASSWD_OK;
+       }
+#endif
+
+       if ( rc ) {
+               ber_memfree( hash->bv_val );
+               return LUTIL_PASSWD_ERR;
+       }
+
+       return LUTIL_PASSWD_OK;
+}
 
-  if (rc) {
-    return LUTIL_PASSWD_ERR;
-  }
-  return LUTIL_PASSWD_OK;
+static int
+slapd_argon2_verify(
+               const struct berval *scheme,
+               const struct berval *passwd,
+               const struct berval *cred,
+               const char **text )
+{
+       int rc = LUTIL_PASSWD_ERR;
+
+#ifdef SLAPD_ARGON2_USE_ARGON2
+       if ( strncmp( passwd->bv_val, "$argon2i$", STRLENOF("$argon2i$") ) == 0 ) {
+               rc = argon2i_verify( passwd->bv_val, cred->bv_val, cred->bv_len );
+       } else if ( strncmp( passwd->bv_val, "$argon2d$", STRLENOF("$argon2d$") ) == 0 ) {
+               rc = argon2d_verify( passwd->bv_val, cred->bv_val, cred->bv_len );
+       } else if ( strncmp( passwd->bv_val, "$argon2id$", STRLENOF("$argon2id$") ) == 0 ) {
+               rc = argon2id_verify( passwd->bv_val, cred->bv_val, cred->bv_len );
+       }
+#else /* !SLAPD_ARGON2_USE_ARGON2 */
+       rc = crypto_pwhash_str_verify( passwd->bv_val, cred->bv_val, cred->bv_len );
+#endif
+
+       if ( rc ) {
+               return LUTIL_PASSWD_ERR;
+       }
+       return LUTIL_PASSWD_OK;
 }
 
-int init_module(int argc, char *argv[]) {
-  return lutil_passwd_add((struct berval *)&slapd_argon2_scheme,
-              slapd_argon2_verify, slapd_argon2_hash);
+int init_module( int argc, char *argv[] )
+{
+       return lutil_passwd_add( (struct berval *)&slapd_argon2_scheme,
+                       slapd_argon2_verify, slapd_argon2_hash );
 }