]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Added SHA512 and SSHA512 password schemes.
authorTimo Sirainen <tss@iki.fi>
Thu, 18 Feb 2010 05:51:44 +0000 (07:51 +0200)
committerTimo Sirainen <tss@iki.fi>
Thu, 18 Feb 2010 05:51:44 +0000 (07:51 +0200)
Based on patch by Mark Washenberger.

--HG--
branch : HEAD

src/auth/password-scheme.c

index ca3698de7143c566f1aba061abf406ba8555887c..5ac8db1096f2d55145cd821b2368725b157a058e 100644 (file)
@@ -394,6 +394,19 @@ sha256_generate(const char *plaintext, const char *user ATTR_UNUSED,
        *size_r = SHA256_RESULTLEN;
 }
 
+static void
+sha512_generate(const char *plaintext, const char *user ATTR_UNUSED,
+               const unsigned char **raw_password_r, size_t *size_r)
+{
+       unsigned char *digest;
+
+       digest = t_malloc(SHA512_RESULTLEN);
+       sha512_get_digest(plaintext, strlen(plaintext), digest);
+
+       *raw_password_r = digest;
+       *size_r = SHA512_RESULTLEN;
+}
+
 static void
 ssha_generate(const char *plaintext, const char *user ATTR_UNUSED,
              const unsigned char **raw_password_r, size_t *size_r)
@@ -475,6 +488,47 @@ static bool ssha256_verify(const char *plaintext, const char *user,
        return memcmp(sha256_digest, raw_password, SHA256_RESULTLEN) == 0;
 }
 
+static void
+ssha512_generate(const char *plaintext, const char *user ATTR_UNUSED,
+                const unsigned char **raw_password_r, size_t *size_r)
+{
+#define SSHA512_SALT_LEN 4
+       unsigned char *digest, *salt;
+       struct sha512_ctx ctx;
+
+       digest = t_malloc(SHA512_RESULTLEN + SSHA512_SALT_LEN);
+       salt = digest + SHA512_RESULTLEN;
+       random_fill(salt, SSHA512_SALT_LEN);
+
+       sha512_init(&ctx);
+       sha512_loop(&ctx, plaintext, strlen(plaintext));
+       sha512_loop(&ctx, salt, SSHA512_SALT_LEN);
+       sha512_result(&ctx, digest);
+
+       *raw_password_r = digest;
+       *size_r = SHA512_RESULTLEN + SSHA512_SALT_LEN;
+}
+
+static bool ssha512_verify(const char *plaintext, const char *user,
+                          const unsigned char *raw_password, size_t size)
+{
+       unsigned char sha512_digest[SHA512_RESULTLEN];
+       struct sha512_ctx ctx;
+
+       /* format: <SHA512 hash><salt> */
+       if (size <= SHA512_RESULTLEN) {
+               i_error("ssha512_verify(%s): SSHA512 password too short", user);
+               return FALSE;
+       }
+
+       sha512_init(&ctx);
+       sha512_loop(&ctx, plaintext, strlen(plaintext));
+       sha512_loop(&ctx, raw_password + SHA512_RESULTLEN,
+                   size - SHA512_RESULTLEN);
+       sha512_result(&ctx, sha512_digest);
+       return memcmp(sha512_digest, raw_password, SHA512_RESULTLEN) == 0;
+}
+
 static void
 smd5_generate(const char *plaintext, const char *user ATTR_UNUSED,
              const unsigned char **raw_password_r, size_t *size_r)
@@ -675,9 +729,12 @@ static const struct password_scheme builtin_schemes[] = {
        { "SHA1", PW_ENCODING_BASE64, SHA1_RESULTLEN, NULL, sha1_generate },
        { "SHA256", PW_ENCODING_BASE64, SHA256_RESULTLEN,
          NULL, sha256_generate },
+       { "SHA512", PW_ENCODING_BASE64, SHA512_RESULTLEN,
+         NULL, sha512_generate },
        { "SMD5", PW_ENCODING_BASE64, 0, smd5_verify, smd5_generate },
        { "SSHA", PW_ENCODING_BASE64, 0, ssha_verify, ssha_generate },
        { "SSHA256", PW_ENCODING_BASE64, 0, ssha256_verify, ssha256_generate },
+       { "SSHA512", PW_ENCODING_BASE64, 0, ssha512_verify, ssha512_generate },
        { "PLAIN", PW_ENCODING_NONE, 0, NULL, plain_generate },
        { "CLEARTEXT", PW_ENCODING_NONE, 0, NULL, plain_generate },
        { "CRAM-MD5", PW_ENCODING_HEX, CRAM_MD5_CONTEXTLEN,