]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Update hmac_sha1 and hmac_md5 to use the EVP API
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 1 Oct 2021 17:34:13 +0000 (12:34 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 2 Oct 2021 18:26:40 +0000 (13:26 -0500)
Calling the HMAC functions directly is deprecated in OpenSSL 3.0

src/lib/util/all.mk
src/lib/util/hmac_md5.c
src/lib/util/hmac_sha1.c
src/lib/util/hmac_tests.c [new file with mode: 0644]
src/lib/util/hmac_tests.mk [new file with mode: 0644]

index 3ebbe514fcb5abebfd168d854ab1bb97216d2c73..733d0f8d2e53a48fad7d4e23d7d739b274d0eb35 100644 (file)
@@ -5,6 +5,7 @@ SUBMAKEFILES := \
        dcursor_tests.mk \
        dlist_tests.mk \
        heap_tests.mk \
+       hmac_tests.mk \
        libfreeradius-util.mk \
        lst_tests.mk \
        pair_legacy_tests.mk \
index fcfc32c7756199f8e0eccdaf9d13fc8ac5c526aa..913bceeaa3e46005477f9e134ab36fda12cccb86 100644 (file)
  */
 RCSID("$Id$")
 
-#include <freeradius-devel/util/md5.h>
 #include <freeradius-devel/util/atexit.h>
+#include <freeradius-devel/util/md5.h>
+#include <freeradius-devel/util/strerror.h>
 
 #ifdef HAVE_OPENSSL_EVP_H
 #  include <openssl/hmac.h>
 
-static _Thread_local HMAC_CTX *md5_hmac_ctx;
+static _Thread_local EVP_MD_CTX *md5_hmac_ctx;
 
 static void _hmac_md5_ctx_free_on_exit(void *arg)
 {
-       HMAC_CTX_free(arg);
+       EVP_MD_CTX_free(arg);
 }
 
 /** Calculate HMAC using OpenSSL's MD5 implementation
@@ -50,30 +51,56 @@ static void _hmac_md5_ctx_free_on_exit(void *arg)
  * @param inlen length of data stream.
  * @param key Pointer to authentication key.
  * @param key_len Length of authentication key.
- *
+ * @return
+ *     - 0 on success.
+ *      - -1 on error.
  */
-void fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
-                uint8_t const *key, size_t key_len)
+int fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
+               uint8_t const *key, size_t key_len)
 {
-       HMAC_CTX *ctx;
+       EVP_MD_CTX *ctx;
+       EVP_PKEY *pkey;
 
        if (unlikely(!md5_hmac_ctx)) {
-               ctx = HMAC_CTX_new();
-               if (unlikely(!ctx)) return;
+               ctx = EVP_MD_CTX_new();
+               if (unlikely(!ctx)) {
+                       fr_strerror_const("Failed allocating EVP_MD_CTX for HMAC-MD5");
+                       return -1;
+               }
+               EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
                fr_atexit_thread_local(md5_hmac_ctx, _hmac_md5_ctx_free_on_exit, ctx);
        } else {
                ctx = md5_hmac_ctx;
        }
 
-#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
-       /* Since MD5 is not allowed by FIPS, explicitly allow it. */
-       HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-#endif /* EVP_MD_CTX_FLAG_NON_FIPS_ALLOW */
+       pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, key_len);
+       if (unlikely(pkey == NULL)) {
+               fr_strerror_const("Failed allocating pkey for HMAC-MD5");
+               return -1;
+       }
 
-       HMAC_Init_ex(ctx, key, key_len, EVP_md5(), NULL);
-       HMAC_Update(ctx, in, inlen);
-       HMAC_Final(ctx, digest, NULL);
-       HMAC_CTX_reset(ctx);
+       if (unlikely(EVP_DigestSignInit(ctx, NULL, EVP_md5(), NULL, pkey) != 1)) {
+               fr_strerror_const("Failed initialising EVP_MD_CTX for HMAC-MD5");
+       error:
+               EVP_PKEY_free(pkey);
+               return -1;
+       }
+       if (unlikely(EVP_DigestSignUpdate(ctx, in, inlen) != 1)) {
+               fr_strerror_const("Failed ingesting data for HMAC-MD5");
+               goto error;
+       }
+       /*
+        *      OpenSSL <= 1.1.1 requires a non-null pointer for len
+        */
+       if (unlikely(EVP_DigestSignFinal(ctx, digest, &(size_t){ 0 }) != 1)) {
+               fr_strerror_const("Failed finalising HMAC-MD5");
+               goto error;
+       }
+
+       EVP_PKEY_free(pkey);
+       EVP_MD_CTX_reset(ctx);
+
+       return 0;
 }
 #else
 /** Calculate HMAC using internal MD5 implementation
@@ -83,10 +110,12 @@ void fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t in
  * @param inlen length of data stream.
  * @param key Pointer to authentication key.
  * @param key_len Length of authentication key.
- *
+ * @return
+ *     - 0 on success.
+ *      - -1 on error.
  */
-void fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
-                uint8_t const *key, size_t key_len)
+int fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
+               uint8_t const *key, size_t key_len)
 {
        fr_md5_ctx_t    *ctx;
        uint8_t         k_ipad[65];    /* inner padding - key XORd with ipad */
@@ -146,64 +175,7 @@ void fr_hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH], uint8_t const *in, size_t in
        fr_md5_final(digest, ctx);              /* finish up 2nd pass */
 
        fr_md5_ctx_free(&ctx);
-}
-#endif /* HAVE_OPENSSL_EVP_H */
-
-/*
-Test Vectors (Trailing '\0' of a character string not included in test):
-
-  key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
-  key_len =     16 bytes
-  data =       "Hi There"
-  data_len =    8  bytes
-  digest =      0x9294727a3638bb1c13f48ef8158bfc9d
-
-  key =         "Jefe"
-  data =       "what do ya want for nothing?"
-  data_len =    28 bytes
-  digest =      0x750c783e6ab0b503eaa86e310a5db738
-
-  key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-
-  key_len       16 bytes
-  data =       0xDDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD
-  data_len =    50 bytes
-  digest =      0x56be34521d144c88dbb8c733f0e8b3f6
-*/
-
-#ifdef TESTING
-/*
- *  cc -DTESTING -I ../include/ hmac.c md5.c -o hmac
- *
- *  ./hmac Jefe "what do ya want for nothing?"
- */
-int main(int argc, char **argv)
-{
-       uint8_t digest[16];
-       char *key;
-       int key_len;
-       char *text;
-       int text_len;
-       int i;
-
-       key = argv[1];
-       key_len = strlen(key);
-
-       text = argv[2];
-       text_len = strlen(text);
-
-       fr_hmac_md5(digest, text, text_len, key, key_len);
-
-       for (i = 0; i < 16; i++) {
-               printf("%02x", digest[i]);
-       }
-       printf("\n");
 
        return 0;
 }
-
-#endif
+#endif /* HAVE_OPENSSL_EVP_H */
index a87ec020bcf4f38381bd3531bf64449a4504b21d..698d8f63df075791328e46e62bbbfe26d6378e3d 100644 (file)
@@ -33,6 +33,7 @@ RCSID("$Id$")
 
 #include <freeradius-devel/util/sha1.h>
 #include <freeradius-devel/util/atexit.h>
+#include <freeradius-devel/util/strerror.h>
 
 #ifdef HMAC_SHA1_DATA_PROBLEMS
 unsigned int sha1_data_problems = 0;
@@ -41,11 +42,11 @@ unsigned int sha1_data_problems = 0;
 #ifdef HAVE_OPENSSL_EVP_H
 #  include <openssl/hmac.h>
 
-static _Thread_local HMAC_CTX *sha1_hmac_ctx;
+static _Thread_local EVP_MD_CTX *sha1_hmac_ctx;
 
 static void _hmac_sha1_ctx_free_on_exit(void *arg)
 {
-       HMAC_CTX_free(arg);
+       EVP_MD_CTX_free(arg);
 }
 
 /** Calculate HMAC using OpenSSL's SHA1 implementation
@@ -55,25 +56,56 @@ static void _hmac_sha1_ctx_free_on_exit(void *arg)
  * @param inlen length of data stream.
  * @param key Pointer to authentication key.
  * @param key_len Length of authentication key.
-
+ * @return
+ *     - 0 on success.
+ *      - -1 on error.
  */
-void fr_hmac_sha1(uint8_t digest[SHA1_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
-                 uint8_t const *key, size_t key_len)
+int fr_hmac_sha1(uint8_t digest[SHA1_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
+               uint8_t const *key, size_t key_len)
 {
-       HMAC_CTX *ctx;
+       EVP_MD_CTX      *ctx;
+       EVP_PKEY        *pkey;
 
        if (unlikely(!sha1_hmac_ctx)) {
-               ctx = HMAC_CTX_new();
-               if (unlikely(!ctx)) return;
+               ctx = EVP_MD_CTX_new();
+               if (unlikely(!ctx)) {
+                       fr_strerror_const("Failed allocating EVP_MD_CTX for HMAC-SHA1");
+                       return -1;
+               }
+               EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
                fr_atexit_thread_local(sha1_hmac_ctx, _hmac_sha1_ctx_free_on_exit, ctx);
        } else {
                ctx = sha1_hmac_ctx;
        }
 
-       HMAC_Init_ex(ctx, key, key_len, EVP_sha1(), NULL);
-       HMAC_Update(ctx, in, inlen);
-       HMAC_Final(ctx, digest, NULL);
-       HMAC_CTX_reset(ctx);
+       pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, key_len);
+       if (unlikely(pkey == NULL)) {
+               fr_strerror_const("Failed allocating pkey for HMAC-SHA1");
+               return -1;
+       }
+
+       if (unlikely(EVP_DigestSignInit(ctx, NULL, EVP_sha1(), NULL, pkey) != 1)) {
+               fr_strerror_const("Failed initialising EVP_MD_CTX for HMAC-SHA1");
+       error:
+               EVP_PKEY_free(pkey);
+               return -1;
+       }
+       if (unlikely(EVP_DigestSignUpdate(ctx, in, inlen) != 1)) {
+               fr_strerror_const("Failed ingesting data for HMAC-SHA1");
+               goto error;
+       }
+       /*
+        *      OpenSSL <= 1.1.1 requires a non-null pointer for len
+        */
+       if (unlikely(EVP_DigestSignFinal(ctx, digest, &(size_t){ 0 }) != 1)) {
+               fr_strerror_const("Failed finalising HMAC-SHA1");
+               goto error;
+       }
+
+       EVP_PKEY_free(pkey);
+       EVP_MD_CTX_reset(ctx);
+
+       return 0;
 }
 #else
 /** Calculate HMAC using internal SHA1 implementation
@@ -83,9 +115,12 @@ void fr_hmac_sha1(uint8_t digest[SHA1_DIGEST_LENGTH], uint8_t const *in, size_t
  * @param inlen length of data stream.
  * @param key Pointer to authentication key.
  * @param key_len Length of authentication key.
+ * @return
+ *     - 0 on success.
+ *      - -1 on error.
  */
-void fr_hmac_sha1(uint8_t digest[static SHA1_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
-                 uint8_t const *key, size_t key_len)
+int fr_hmac_sha1(uint8_t digest[static SHA1_DIGEST_LENGTH], uint8_t const *in, size_t inlen,
+                uint8_t const *key, size_t key_len)
 {
        fr_sha1_ctx ctx;
        uint8_t k_ipad[65];    /* inner padding - key XORd with ipad */
@@ -200,58 +235,6 @@ void fr_hmac_sha1(uint8_t digest[static SHA1_DIGEST_LENGTH], uint8_t const *in,
                printf("\n");
        }
 #endif
-}
-#endif /* HAVE_OPENSSL_EVP_H */
-
-/*
-Test Vectors (Trailing '\0' of a character string not included in test):
-
-  key =         "Jefe"
-  data =       "what do ya want for nothing?"
-  data_len =    28 bytes
-  digest =     effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
-
-  key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-
-  key_len       16 bytes
-  data =       0xDDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD...
-               ..DDDDDDDDDDDDDDDDDDDD
-  data_len =    50 bytes
-  digest =      0x56be34521d144c88dbb8c733f0e8b3f6
-*/
-
-#ifdef TESTING
-/*
- *  cc -DTESTING -I ../include/ hmac.c sha1.c -o hmac
- *
- *  ./hmac Jefe "what do ya want for nothing?"
- */
-int main(int argc, char **argv)
-{
-       uint8_t digest[20];
-       char *key;
-       int key_len;
-       char *text;
-       int text_len;
-       int i;
-
-       key = argv[1];
-       key_len = strlen(key);
-
-       text = argv[2];
-       text_len = strlen(text);
-
-       fr_hmac_sha1(digest, text, text_len, key, key_len);
-
-       for (i = 0; i < 20; i++) {
-               printf("%02x", digest[i]);
-       }
-       printf("\n");
-
        return 0;
 }
-
-#endif
+#endif /* HAVE_OPENSSL_EVP_H */
diff --git a/src/lib/util/hmac_tests.c b/src/lib/util/hmac_tests.c
new file mode 100644 (file)
index 0000000..1c96b7f
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Lesser General Public
+ *   License as published by the Free Software Foundation; either
+ *   version 2.1 of the License, or (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/** Tests for the internal hmac functions
+ *
+ * @file src/lib/util/hmac_tests.c
+ *
+ * @copyright 2021 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ */
+
+#include <freeradius-devel/util/acutest.h>
+#include <freeradius-devel/util/acutest_helpers.h>
+#include <freeradius-devel/util/md5.h>
+#include <freeradius-devel/util/sha1.h>
+
+/*
+Test Vectors (Trailing '\0' of a character string not included in test):
+
+  key =  0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+  key_len =     16 bytes
+  data =       "Hi There"
+  data_len =    8  bytes
+  digest =      0x9294727a3638bb1c13f48ef8158bfc9d
+
+  key =         "Jefe"
+  data =       "what do ya want for nothing?"
+  data_len =    28 bytes
+  digest =      0x750c783e6ab0b503eaa86e310a5db738
+
+  key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+  key_len       16 bytes
+  data =       0xDDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD
+  data_len =    50 bytes
+  digest =      0x56be34521d144c88dbb8c733f0e8b3f6
+*/
+static void test_hmac_md5(void)
+{
+       uint8_t digest[16];
+       uint8_t const *key;
+       int key_len;
+       uint8_t const *text;
+       int text_len;
+
+       /*
+        *      Test 1
+        */
+       key = (uint8_t[]){
+               0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+               0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+               0x00
+       };
+       key_len = strlen((char const *)key);
+
+       text = (uint8_t const *)"Hi There";
+       text_len = strlen((char const *)text);
+
+       fr_hmac_md5(digest, text, text_len, key, key_len);
+
+       TEST_CHECK_RET(memcmp(digest,
+                             (uint8_t[]){
+                                       0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
+                                       0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
+                             },
+                             sizeof(digest)), 0);
+
+       /*
+        *      Test 2
+        */
+       key = (uint8_t const *)"Jefe";
+       key_len = strlen((char const *)key);
+
+       text = (uint8_t const *)"what do ya want for nothing?";
+       text_len = strlen((char const *)text);
+
+       fr_hmac_md5(digest, text, text_len, key, key_len);
+
+       TEST_CHECK_RET(memcmp(digest,
+                             (uint8_t[]){
+                                       0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+                                       0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38
+                             },
+                             sizeof(digest)), 0);
+
+       /*
+        *      Test 3
+        */
+       key = (uint8_t[]){
+               0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+               0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+               0x00
+       };
+       key_len = strlen((char const *)key);
+
+       text = (uint8_t[]){
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0x00
+       };
+       text_len = strlen((char const *)text);
+
+       fr_hmac_md5(digest, text, text_len, key, key_len);
+
+       TEST_CHECK_RET(memcmp(digest,
+                             (uint8_t[]){
+                                       0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
+                                       0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6
+                             },
+                             sizeof(digest)), 0);
+}
+
+/*
+Test Vectors (Trailing '\0' of a character string not included in test):
+
+  key =         "Jefe"
+  data =       "what do ya want for nothing?"
+  data_len =    28 bytes
+  digest =     0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79
+
+  key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+  key_len       16 bytes
+  data =       0xDDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD...
+               ..DDDDDDDDDDDDDDDDDDDD
+  data_len =    50 bytes
+  digest =      0xd730594d167e35d5956fd8003d0db3d3f46dc7bb
+*/
+static void test_hmac_sha1(void)
+{
+
+       uint8_t digest[20];
+       uint8_t const *key;
+       int key_len;
+       uint8_t const *text;
+       int text_len;
+
+       /*
+        *      Test 1
+        */
+       key = (uint8_t const *)"Jefe";
+       key_len = strlen((char const *)key);
+
+       text = (uint8_t const *)"what do ya want for nothing?";
+       text_len = strlen((char const *)text);
+
+       fr_hmac_sha1(digest, text, text_len, key, key_len);
+
+       TEST_CHECK_RET(memcmp(digest,
+                             (uint8_t[]){
+                                       0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74,
+                                       0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79
+                             },
+                             sizeof(digest)), 0);
+
+       /*
+        *      Test 2
+        */
+       key = (uint8_t[]){
+               0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+               0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+               0x00
+       };
+       key_len = strlen((char const *)key);
+
+       text = (uint8_t[]){
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+               0x00
+       };
+       text_len = strlen((char const *)text);
+
+       fr_hmac_sha1(digest, text, text_len, key, key_len);
+
+       TEST_CHECK_RET(memcmp(digest,
+                             (uint8_t[]){
+                                       0xd7, 0x30, 0x59, 0x4d, 0x16, 0x7e, 0x35, 0xd5, 0x95, 0x6f,
+                                       0xd8, 0x00, 0x3d, 0x0d, 0xb3, 0xd3, 0xf4, 0x6d, 0xc7, 0xbb
+                             },
+                             sizeof(digest)), 0);
+}
+
+TEST_LIST = {
+       /*
+        *      Allocation and management
+        */
+       { "hmac-md5",                   test_hmac_md5   },
+       { "hmac-sha1",                  test_hmac_sha1  },
+
+       { NULL }
+};
diff --git a/src/lib/util/hmac_tests.mk b/src/lib/util/hmac_tests.mk
new file mode 100644 (file)
index 0000000..3a6cbf2
--- /dev/null
@@ -0,0 +1,7 @@
+TARGET         := hmac_tests
+
+SOURCES                := hmac_tests.c
+
+TGT_LDLIBS     := $(LIBS)
+TGT_LDFLAGS    := $(LDFLAGS)
+TGT_PREREQS    := libfreeradius-util.a