]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add support for SHA3 Fixes #2045
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 24 Aug 2017 06:29:21 +0000 (14:29 +0800)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 24 Aug 2017 06:29:33 +0000 (14:29 +0800)
configure
configure.ac
man/man5/rlm_pap.5
share/dictionary.freeradius.internal
src/include/autoconf.h.in
src/modules/rlm_expr/rlm_expr.c
src/modules/rlm_pap/rlm_pap.c

index 49c8bcab01e3d2e9c5d2f569f267363457d47057..4faba84838eb5ab784ef74d7d40198478c010925 100755 (executable)
--- a/configure
+++ b/configure
@@ -10300,6 +10300,7 @@ fi
     for ac_func in \
       SSL_get_client_random \
       SSL_get_server_random \
+      EVP_sha3_512 \
 
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
index a6fa2b707175d0f16d66fa58563f288aa676e851..d8e3df90a33bf24be09c1bc7e7dcff6df06a5e0a 100644 (file)
@@ -1089,6 +1089,7 @@ if test "x$WITH_OPENSSL" = xyes; then
     AC_CHECK_FUNCS( \
       SSL_get_client_random \
       SSL_get_server_random \
+      EVP_sha3_512 \
     )
 
     CPPFLAGS="$old_CPPFLAGS"
index 425da7306a0eea28f10638a201becedd544ba81a..ea02020cfa72accaad5b165e56aade3fd824ff2d 100644 (file)
@@ -68,11 +68,17 @@ Header       Attribute           Description
 .br
              SSHA1-Password      SHA1 hashed passwords, with a salt
 .br
-{ssh2}       SHA2-Password       SHA2 hashed passwords
+{ssha2}      SHA2-Password       SHA2 hashed passwords
 .br
-{ssh256}     SHA2-Password       SHA2 hashed passwords
+{ssha256}    SHA2-Password       SHA2 hashed passwords, with a salt
 .br
-{ssh512}     SHA2-Password       SHA2 hashed passwords
+{ssha512}    SHA2-Password       SHA2 hashed passwords, with a salt
+.br
+{ssha3}      SHA2-Password       SHA3 hashed passwords
+.br
+{ssha3-256}  SHA3-Password       SHA3 hashed passwords, with a salt
+.br
+{ssha3-512}  SHA3-Password       SHA3 hashed passwords, with a salt
 .br
 {nt}         NT-Password         Windows NT hashed passwords
 .br
index 59df629be9835764d9af47d1d331fe28f8420010..75e27a9ab16a3042293dd64d9b14803338baa091 100644 (file)
@@ -290,8 +290,15 @@ ATTRIBUTE  SSHA2-224-Password                      1180    octets
 ATTRIBUTE      SSHA2-256-Password                      1181    octets
 ATTRIBUTE      SSHA2-384-Password                      1182    octets
 ATTRIBUTE      SSHA2-512-Password                      1183    octets
-ATTRIBUTE      PBKDF2-Password                         1184    octets
-ATTRIBUTE      Session-State-User-Name                 1185    string
+
+ATTRIBUTE      SHA3-Password                           1184    octets
+ATTRIBUTE      SSHA3-224-Password                      1185    octets
+ATTRIBUTE      SSHA3-256-Password                      1186    octets
+ATTRIBUTE      SSHA3-384-Password                      1187    octets
+ATTRIBUTE      SSHA3-512-Password                      1188    octets
+
+ATTRIBUTE      PBKDF2-Password                         1188    octets
+ATTRIBUTE      Session-State-User-Name                 1189    string
 
 ATTRIBUTE      Exec-Export                             1190    string
 
index e29d8185c8b7caaf626457333245788fb97b91fa..5694650029add282e38902ae5210e18a83182a00 100644 (file)
@@ -95,6 +95,9 @@
 /* Define to 1 if you have the <errno.h> header file. */
 #undef HAVE_ERRNO_H
 
+/* Define to 1 if you have the `EVP_sha3_512' function. */
+#undef HAVE_EVP_SHA3_512
+
 /* define this if we have <execinfo.h> and symbols */
 #undef HAVE_EXECINFO
 
index c4c31ca7ceb7fb02f44809f43ca1226ae0a6449f..28d15d874fd36835d17b7b4c1240644fa14ef39a 100644 (file)
@@ -1159,6 +1159,11 @@ static ssize_t _md##_xlat(TALLOC_CTX *ctx, char **out, size_t outlen,\
 
 EVP_MD_XLAT(sha256)
 EVP_MD_XLAT(sha512)
+
+#  ifdef HAVE_EVP_SHA3_512
+EVP_MD_XLAT(sha3_256)
+EVP_MD_XLAT(sha3_512)
+#  endif
 #endif
 
 /** Generate the HMAC-MD5 of a string or attribute
index 4c1b7865c4b9b99d32b73c577c5b8688ffa39a47..c6dc4a53af6f29b947711d5ff5eedd197b9d533f 100644 (file)
@@ -85,6 +85,12 @@ static const FR_NAME_NUMBER header_names[] = {
        { "{ssha256}",          FR_SSHA2_256_PASSWORD },
        { "{ssha384}",          FR_SSHA2_384_PASSWORD },
        { "{ssha512}",          FR_SSHA2_512_PASSWORD },
+#  ifdef HAVE_EVP_SHA3_512
+       { "{ssha3-224}",        FR_SSHA3_224_PASSWORD },
+       { "{ssha3-256}",        FR_SSHA3_256_PASSWORD },
+       { "{ssha3-384}",        FR_SSHA3_384_PASSWORD },
+       { "{ssha3-512}",        FR_SSHA3_512_PASSWORD },
+#  endif
        { "{x-pbkdf2}",         FR_PBKDF2_PASSWORD },
 #endif
        { "{sha}",              FR_SHA_PASSWORD },
@@ -106,6 +112,12 @@ static const FR_NAME_NUMBER pbkdf2_crypt_names[] = {
        { "HMACSHA2+256",       FR_SSHA2_256_PASSWORD },
        { "HMACSHA2+384",       FR_SSHA2_384_PASSWORD },
        { "HMACSHA2+512",       FR_SSHA2_512_PASSWORD },
+#  ifdef HAVE_EVP_SHA3_512
+       { "HMACSHA3+224",       FR_SSHA3_224_PASSWORD },
+       { "HMACSHA3+256",       FR_SSHA3_256_PASSWORD },
+       { "HMACSHA3+384",       FR_SSHA3_384_PASSWORD },
+       { "HMACSHA3+512",       FR_SSHA3_512_PASSWORD },
+#  endif
        { NULL, 0 }
 };
 
@@ -113,6 +125,7 @@ static const FR_NAME_NUMBER pbkdf2_passlib_names[] = {
        { "sha1",               FR_SSHA_PASSWORD },
        { "sha256",             FR_SSHA2_256_PASSWORD },
        { "sha512",             FR_SSHA2_512_PASSWORD },
+
        { NULL, 0 }
 };
 #endif
@@ -437,6 +450,43 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, UNUSED void *t
                        found_pw = true;
                        break;
 
+#  ifdef HAVE_EVP_SHA3_512
+               case FR_SHA3_PASSWORD:
+                       if (inst->normify) {
+                               normify(request, vp, 28); /* ensure it's in the right format */
+                       }
+                       found_pw = true;
+                       break;
+
+               case FR_SSHA3_224_PASSWORD:
+                       if (inst->normify) {
+                               normify(request, vp, 28); /* ensure it's in the right format */
+                       }
+                       found_pw = true;
+                       break;
+
+               case FR_SSHA3_256_PASSWORD:
+                       if (inst->normify) {
+                               normify(request, vp, 32); /* ensure it's in the right format */
+                       }
+                       found_pw = true;
+                       break;
+
+               case FR_SSHA3_384_PASSWORD:
+                       if (inst->normify) {
+                               normify(request, vp, 48); /* ensure it's in the right format */
+                       }
+                       found_pw = true;
+                       break;
+
+               case FR_SSHA3_512_PASSWORD:
+                       if (inst->normify) {
+                               normify(request, vp, 64); /* ensure it's in the right format */
+                       }
+                       found_pw = true;
+                       break;
+#  endif
+
                case FR_PBKDF2_PASSWORD:
                        found_pw = true; /* Already base64 standardized */
                        break;
@@ -681,7 +731,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_ssha(rlm_pap_t const *inst, REQUEST
 }
 
 #ifdef HAVE_OPENSSL_EVP_H
-static rlm_rcode_t CC_HINT(nonnull) pap_auth_sha2(rlm_pap_t const *inst, REQUEST *request, VALUE_PAIR *vp)
+static rlm_rcode_t CC_HINT(nonnull) pap_auth_sha_evp(rlm_pap_t const *inst, REQUEST *request, VALUE_PAIR *vp)
 {
        EVP_MD_CTX *ctx;
        EVP_MD const *md;
@@ -693,41 +743,86 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_sha2(rlm_pap_t const *inst, REQUEST
 
        if (inst->normify) normify(request, vp, 28);
 
-       /*
-        *      All the SHA-2 algorithms produce digests of different lengths,
-        *      so it's trivial to determine which EVP_MD to use.
-        */
-       switch (vp->vp_length) {
-       /* SHA-224 */
-       case 28:
-               name = "SHA2-224";
-               md = EVP_sha224();
-               break;
+       switch (vp->da->attr) {
+       case FR_SHA2_PASSWORD:
+               /*
+                *      All the SHA-2 algorithms produce digests of different lengths,
+                *      so it's trivial to determine which EVP_MD to use.
+                */
+               switch (vp->vp_length) {
+               /* SHA-224 */
+               case 28:
+                       name = "SHA2-224";
+                       md = EVP_sha224();
+                       break;
 
-       /* SHA-256 */
-       case 32:
-               name = "SHA2-256";
-               md = EVP_sha256();
-               break;
+               /* SHA-256 */
+               case 32:
+                       name = "SHA2-256";
+                       md = EVP_sha256();
+                       break;
 
-       /* SHA-384 */
-       case 48:
-               name = "SHA2-384";
-               md = EVP_sha384();
+               /* SHA-384 */
+               case 48:
+                       name = "SHA2-384";
+                       md = EVP_sha384();
+                       break;
+
+               /* SHA-512 */
+               case 64:
+                       name = "SHA2-512";
+                       md = EVP_sha512();
+                       break;
+
+               default:
+                       REDEBUG("\"known good\" digest length (%zu) does not match output length of any SHA-2 digests",
+                               vp->vp_length);
+                       return RLM_MODULE_INVALID;
+               }
                break;
 
-       /* SHA-512 */
-       case 64:
-               name = "SHA2-512";
-               md = EVP_sha512();
+# ifdef HAVE_EVP_SHA3_512
+       case FR_SHA3_PASSWORD:
+               /*
+                *      All the SHA-3 algorithms produce digests of different lengths,
+                *      so it's trivial to determine which EVP_MD to use.
+                */
+               switch (vp->vp_length) {
+               /* SHA-224 */
+               case 28:
+                       name = "SHA3-224";
+                       md = EVP_sha3_224();
+                       break;
+
+               /* SHA-256 */
+               case 32:
+                       name = "SHA3-256";
+                       md = EVP_sha3_256();
+                       break;
+
+               /* SHA-384 */
+               case 48:
+                       name = "SHA3-384";
+                       md = EVP_sha3_384();
+                       break;
+
+               /* SHA-512 */
+               case 64:
+                       name = "SHA3-512";
+                       md = EVP_sha3_512();
+                       break;
+
+               default:
+                       REDEBUG("\"known good\" digest length (%zu) does not match output length of any SHA-2 digests",
+                               vp->vp_length);
+                       return RLM_MODULE_INVALID;
+               }
                break;
+#  endif
 
        default:
-               REDEBUG("\"known good\" digest length (%zu) does not match output length of any SHA-2 digests",
-                       vp->vp_length);
-               return RLM_MODULE_INVALID;
+               rad_assert(0);
        }
-
        ctx = EVP_MD_CTX_create();
        EVP_DigestInit_ex(ctx, md, NULL);
        EVP_DigestUpdate(ctx, request->password->vp_octets, request->password->vp_length);
@@ -744,7 +839,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_sha2(rlm_pap_t const *inst, REQUEST
        return RLM_MODULE_OK;
 }
 
-static rlm_rcode_t CC_HINT(nonnull) pap_auth_ssha2(rlm_pap_t const *inst, REQUEST *request, VALUE_PAIR *vp)
+static rlm_rcode_t CC_HINT(nonnull) pap_auth_ssha_evp(rlm_pap_t const *inst, REQUEST *request, VALUE_PAIR *vp)
 {
        EVP_MD_CTX *ctx;
        EVP_MD const *md = NULL;
@@ -777,6 +872,32 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_ssha2(rlm_pap_t const *inst, REQUES
                md = EVP_sha512();
                break;
 
+#ifdef HAVE_EVP_SHA3_512
+       case FR_SSHA3_224_PASSWORD:
+               name = "SSHA3-224";
+               md = EVP_sha3_224();
+               min_len = 28;
+               break;
+
+       case FR_SSHA3_256_PASSWORD:
+               name = "SSHA3-256";
+               md = EVP_sha3_256();
+               min_len = 32;
+               break;
+
+       case FR_SSHA3_384_PASSWORD:
+               name = "SSHA3-384";
+               md = EVP_sha3_384();
+               min_len = 48;
+               break;
+
+       case FR_SSHA3_512_PASSWORD:
+               name = "SSHA3-512";
+               min_len = 64;
+               md = EVP_sha3_512();
+               break;
+#endif
+
        default:
                rad_assert(0);
        }
@@ -784,7 +905,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_auth_ssha2(rlm_pap_t const *inst, REQUES
        RDEBUG("Comparing with \"known-good\" %s-Password", name);
 
        /*
-        *      Unlike plain SHA2 we already know what length
+        *      Unlike plain SHA2/3 we already know what length
         *      to expect, so can be more specific with the
         *      minimum digest length.
         */
@@ -892,6 +1013,28 @@ static inline rlm_rcode_t CC_HINT(nonnull) pap_auth_pbkdf2_parse(REQUEST *reques
                digest_len = 64;
                break;
 
+#  ifdef HAVE_EVP_SHA3_512
+       case FR_SSHA3_224_PASSWORD:
+               evp_md = EVP_sha3_224();
+               digest_len = 28;
+               break;
+
+       case FR_SSHA3_256_PASSWORD:
+               evp_md = EVP_sha3_256();
+               digest_len = 32;
+               break;
+
+       case FR_SSHA3_384_PASSWORD:
+               evp_md = EVP_sha3_384();
+               digest_len = 48;
+               break;
+
+       case FR_SSHA3_512_PASSWORD:
+               evp_md = EVP_sha3_512();
+               digest_len = 64;
+               break;
+#  endif
+
        default:
                REDEBUG("Unknown PBKDF2 hash method \"%.*s\"", (int)(q - p), p);
                goto finish;
@@ -1264,14 +1407,23 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, UNUSED void
 
 #ifdef HAVE_OPENSSL_EVP_H
                case FR_SHA2_PASSWORD:
-                       auth_func = &pap_auth_sha2;
+#  ifdef HAVE_EVP_SHA3_512
+               case FR_SHA3_PASSWORD:
+#  endif
+                       auth_func = &pap_auth_sha_evp;
                        break;
 
                case FR_SSHA2_224_PASSWORD:
                case FR_SSHA2_256_PASSWORD:
                case FR_SSHA2_384_PASSWORD:
                case FR_SSHA2_512_PASSWORD:
-                       auth_func = &pap_auth_ssha2;
+#  ifdef HAVE_EVP_SHA3_512
+               case FR_SSHA3_224_PASSWORD:
+               case FR_SSHA3_256_PASSWORD:
+               case FR_SSHA3_384_PASSWORD:
+               case FR_SSHA3_512_PASSWORD:
+#  endif
+                       auth_func = &pap_auth_ssha_evp;
                        break;
 
                case FR_PBKDF2_PASSWORD: