From 0babe1cf4ee9b58e54de8d8f3afa4af0c6033ee8 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Tue, 10 Oct 2017 17:58:03 +0300 Subject: [PATCH] libpassword: Add support for ARGON2 scheme --- src/auth/Makefile.am | 7 ++-- src/auth/password-scheme-sodium.c | 53 +++++++++++++++++++++++++++++++ src/auth/password-scheme.c | 3 ++ src/auth/password-scheme.h | 4 +++ src/doveadm/Makefile.am | 1 + 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/auth/password-scheme-sodium.c diff --git a/src/auth/Makefile.am b/src/auth/Makefile.am index b6e9f291bc..2a9468ef93 100644 --- a/src/auth/Makefile.am +++ b/src/auth/Makefile.am @@ -51,7 +51,9 @@ libpassword_la_SOURCES = \ password-scheme-scram.c \ password-scheme-otp.c \ password-scheme-rpa.c \ - password-scheme-pbkdf2.c + password-scheme-pbkdf2.c \ + password-scheme-sodium.c +libpassword_la_CFLAGS = $(AM_CPPFLAGS) $(LIBSODIUM_CFLAGS) auth_libs = \ libauth.la \ @@ -59,7 +61,8 @@ auth_libs = \ libpassword.la \ ../lib-ntlm/libntlm.la \ ../lib-otp/libotp.la \ - $(LIBDOVECOT_SQL) + $(LIBDOVECOT_SQL) \ + $(LIBSODIUM_LIBS) auth_CPPFLAGS = $(AM_CPPFLAGS) $(BINARY_CFLAGS) auth_LDADD = $(auth_libs) $(LIBDOVECOT) $(AUTH_LIBS) $(BINARY_LDFLAGS) diff --git a/src/auth/password-scheme-sodium.c b/src/auth/password-scheme-sodium.c new file mode 100644 index 0000000000..03d5b725a6 --- /dev/null +++ b/src/auth/password-scheme-sodium.c @@ -0,0 +1,53 @@ +#include "lib.h" +#include "password-scheme.h" + +#ifdef HAVE_LIBSODIUM +#include + +static void +generate_argon2(const char *plaintext, const struct password_generate_params *params, + const unsigned char **raw_password_r, size_t *size_r) +{ + unsigned long long rounds = params->rounds; + size_t memlimit; + char result[crypto_pwhash_STRBYTES]; + + if (rounds == 0) + rounds = crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE; + + if (rounds >= crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE) + memlimit = crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE; + else if (rounds >= crypto_pwhash_argon2i_OPSLIMIT_MODERATE) + memlimit = crypto_pwhash_argon2i_MEMLIMIT_MODERATE; + else + memlimit = crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE; + + if (crypto_pwhash_str(result, plaintext, strlen(plaintext), rounds, memlimit) < 0) + i_fatal("crypto_pwhash_str failed"); + *raw_password_r = (const unsigned char*)t_strdup(result); + *size_r = strlen(result); +} + +static int +verify_argon2(const char *plaintext, const struct password_generate_params *params ATTR_UNUSED, + const unsigned char *raw_password, size_t size, + const char **error_r ATTR_UNUSED) +{ + const char *passwd = t_strndup(raw_password, size); + if (crypto_pwhash_str_verify(passwd, plaintext, strlen(plaintext)) < 0) + return 0; + return 1; +} + + +static const struct password_scheme sodium_schemes[] = { + { "ARGON2", PW_ENCODING_NONE, 0, verify_argon2, + generate_argon2 }, +}; + +void password_scheme_register_sodium(void) +{ + for(size_t i = 0; i < N_ELEMENTS(sodium_schemes); i++) + password_scheme_register(&sodium_schemes[i]); +} +#endif diff --git a/src/auth/password-scheme.c b/src/auth/password-scheme.c index 10ca0fbc3a..de6c763db6 100644 --- a/src/auth/password-scheme.c +++ b/src/auth/password-scheme.c @@ -868,6 +868,9 @@ void password_schemes_init(void) for (i = 0; i < N_ELEMENTS(builtin_schemes); i++) password_scheme_register(&builtin_schemes[i]); password_scheme_register_crypt(); +#ifdef HAVE_LIBSODIUM + password_scheme_register_sodium(); +#endif } void password_schemes_deinit(void) diff --git a/src/auth/password-scheme.h b/src/auth/password-scheme.h index 6c94dd6d0d..d305946576 100644 --- a/src/auth/password-scheme.h +++ b/src/auth/password-scheme.h @@ -110,4 +110,8 @@ int pbkdf2_verify(const char *plaintext, const struct password_generate_params * supported by the used libc's/glibc's crypt() */ void password_scheme_register_crypt(void); +#ifdef HAVE_LIBSODIUM +void password_scheme_register_sodium(void); +#endif + #endif diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am index cda12ade2b..05d792a434 100644 --- a/src/doveadm/Makefile.am +++ b/src/doveadm/Makefile.am @@ -49,6 +49,7 @@ doveadm_LDADD = \ $(CRYPT_LIBS) \ $(LIBDOVECOT_STORAGE) \ $(LIBDOVECOT) \ + $(LIBSODIUM_LIBS) \ $(BINARY_LDFLAGS) doveadm_DEPENDENCIES = \ -- 2.47.3