Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Langley <agl@chromium.org>2014-06-20 23:00:00 +0400
committerAdam Langley <agl@chromium.org>2014-06-21 00:17:32 +0400
commit95c29f3cd1f6c08c6c0927868683392eea727ccb (patch)
tree012767320ced9abca61472a4daa4c4a56b7ebe2b /crypto/hmac
Inital import.
Initial fork from f2d678e6e89b6508147086610e985d4e8416e867 (1.0.2 beta). (This change contains substantial changes from the original and effectively starts a new history.)
Diffstat (limited to 'crypto/hmac')
-rw-r--r--crypto/hmac/CMakeLists.txt18
-rw-r--r--crypto/hmac/hmac.c208
-rw-r--r--crypto/hmac/hmac.h155
-rw-r--r--crypto/hmac/hmac_test.c151
4 files changed, 532 insertions, 0 deletions
diff --git a/crypto/hmac/CMakeLists.txt b/crypto/hmac/CMakeLists.txt
new file mode 100644
index 00000000..d647b0a6
--- /dev/null
+++ b/crypto/hmac/CMakeLists.txt
@@ -0,0 +1,18 @@
+include_directories(. .. ../../include)
+
+add_library(
+ hmac
+
+ OBJECT
+
+ hmac.c
+)
+
+
+add_executable(
+ hmac_test
+
+ hmac_test.c
+)
+
+target_link_libraries(hmac_test crypto)
diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
new file mode 100644
index 00000000..1d37b9e4
--- /dev/null
+++ b/crypto/hmac/hmac.c
@@ -0,0 +1,208 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/hmac.h>
+
+#include <assert.h>
+
+#include <openssl/mem.h>
+
+
+uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len,
+ const uint8_t *data, size_t data_len, uint8_t *out,
+ unsigned int *out_len) {
+ HMAC_CTX ctx;
+ static uint8_t static_out_buffer[EVP_MAX_MD_SIZE];
+
+ /* OpenSSL has traditionally supported using a static buffer if |out| is
+ * NULL. We maintain that but don't document it. This behaviour should be
+ * considered to be deprecated. */
+ if (out == NULL) {
+ out = static_out_buffer;
+ }
+
+ HMAC_CTX_init(&ctx);
+ if (!HMAC_Init(&ctx, key, key_len, evp_md) ||
+ !HMAC_Update(&ctx, data, data_len) ||
+ !HMAC_Final(&ctx, out, out_len)) {
+ out = NULL;
+ }
+
+ HMAC_CTX_cleanup(&ctx);
+ return out;
+}
+
+void HMAC_CTX_init(HMAC_CTX *ctx) {
+ EVP_MD_CTX_init(&ctx->i_ctx);
+ EVP_MD_CTX_init(&ctx->o_ctx);
+ EVP_MD_CTX_init(&ctx->md_ctx);
+}
+
+void HMAC_CTX_cleanup(HMAC_CTX *ctx) {
+ EVP_MD_CTX_cleanup(&ctx->i_ctx);
+ EVP_MD_CTX_cleanup(&ctx->o_ctx);
+ EVP_MD_CTX_cleanup(&ctx->md_ctx);
+ OPENSSL_cleanse(ctx, sizeof(ctx));
+}
+
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
+ const EVP_MD *md, ENGINE *impl) {
+ unsigned i, reset = 0;
+ uint8_t pad[HMAC_MAX_MD_CBLOCK];
+
+ if (md != NULL) {
+ reset = 1;
+ ctx->md = md;
+ } else {
+ md = ctx->md;
+ }
+
+ if (key != NULL) {
+ size_t block_size = EVP_MD_block_size(md);
+ reset = 1;
+ assert(block_size <= sizeof(ctx->key));
+ if (block_size < key_len) {
+ if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl) ||
+ !EVP_DigestUpdate(&ctx->md_ctx, key, key_len) ||
+ !EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key, &ctx->key_length)) {
+ goto err;
+ }
+ } else {
+ assert(key_len >= 0 && key_len <= sizeof(ctx->key));
+ memcpy(ctx->key, key, key_len);
+ ctx->key_length = key_len;
+ }
+ if (ctx->key_length != HMAC_MAX_MD_CBLOCK) {
+ memset(&ctx->key[ctx->key_length], 0, sizeof(ctx->key) - ctx->key_length);
+ }
+ }
+
+ if (reset) {
+ for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
+ pad[i] = 0x36 ^ ctx->key[i];
+ }
+ if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) ||
+ !EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) {
+ goto err;
+ }
+
+ for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
+ pad[i] = 0x5c ^ ctx->key[i];
+ }
+ if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) ||
+ !EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) {
+ goto err;
+ }
+ }
+
+ if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) {
+ goto err;
+ }
+
+ return 1;
+
+err:
+ return 0;
+}
+
+int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len) {
+ return EVP_DigestUpdate(&ctx->md_ctx, data, data_len);
+}
+
+int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len) {
+ unsigned int i;
+ uint8_t buf[EVP_MAX_MD_SIZE];
+
+ if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i) ||
+ !EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx) ||
+ !EVP_DigestUpdate(&ctx->md_ctx, buf, i) ||
+ !EVP_DigestFinal_ex(&ctx->md_ctx, out, out_len)) {
+ *out_len = 0;
+ return 0;
+ }
+
+ return 1;
+}
+
+size_t HMAC_size(const HMAC_CTX *ctx) {
+ return EVP_MD_size(ctx->md);
+}
+
+int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src) {
+ if (!EVP_MD_CTX_copy(&dest->i_ctx, &src->i_ctx) ||
+ !EVP_MD_CTX_copy(&dest->o_ctx, &src->o_ctx) ||
+ !EVP_MD_CTX_copy(&dest->md_ctx, &src->md_ctx)) {
+ return 0;
+ }
+
+ memcpy(dest->key, src->key, HMAC_MAX_MD_CBLOCK);
+ dest->key_length = src->key_length;
+ dest->md = src->md;
+ return 1;
+}
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) {
+ EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
+ EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
+ EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
+}
+
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md) {
+ if (key && md) {
+ HMAC_CTX_init(ctx);
+ }
+ return HMAC_Init_ex(ctx, key, key_len, md, NULL);
+}
diff --git a/crypto/hmac/hmac.h b/crypto/hmac/hmac.h
new file mode 100644
index 00000000..33c90615
--- /dev/null
+++ b/crypto/hmac/hmac.h
@@ -0,0 +1,155 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#ifndef OPENSSL_HEADER_HMAC_H
+#define OPENSSL_HEADER_HMAC_H
+
+#include <openssl/base.h>
+
+#include <openssl/digest.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* HMAC contains functions for constructing PRFs from Merkle–Damgård hash
+ * functions using HMAC. */
+
+
+/* One-shot operation. */
+
+/* HMAC calculates the HMAC of |data_len| bytes of |data|, using the given key
+ * and hash function, and writes the result to |out|. On entry, |out| must
+ * contain |EVP_MAX_MD_SIZE| bytes of space. The actual length of the result is
+ * written to |*out_len|. It returns |out| or NULL on error. */
+uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len,
+ const uint8_t *data, size_t data_len, uint8_t *out,
+ unsigned int *out_len);
+
+
+/* Incremental operation. */
+
+/* HMAC_CTX_init initialises |ctx| for use in an HMAC operation. It's assumed
+ * that HMAC_CTX objects will be allocated on the stack thus no allocation
+ * function is provided. If needed, allocate |sizeof(HMAC_CTX)| and call
+ * |HMAC_CTX_init| on it. */
+void HMAC_CTX_init(HMAC_CTX *ctx);
+
+/* HMAC_CTX_cleanup frees data owned by |ctx|. */
+void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+
+/* HMAC_Init_ex sets up an initialised |HMAC_CTX| to use |md| as the hash
+ * function and |key| as the key. Any of |md| or |key| can be NULL, in which
+ * case the previous value will be used. It returns one on success or zero
+ * otherwise. */
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
+ const EVP_MD *md, ENGINE *impl);
+
+/* HMAC_Update hashes |data_len| bytes from |data| into the current HMAC
+ * operation in |ctx|. It returns one on success and zero on error. */
+int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len);
+
+/* HMAC_Final completes the HMAC operation in |ctx| and writes the result to
+ * |out| and the sets |*out_len| to the length of the result. On entry, |out|
+ * must contain at least |EVP_MAX_MD_SIZE| bytes of space. It returns one on
+ * success or zero on error. */
+int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len);
+
+
+/* Utility functions. */
+
+/* HMAC_size returns the size, in bytes, of the HMAC that will be produced by
+ * |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. */
+size_t HMAC_size(const HMAC_CTX *ctx);
+
+/* HMAC_CTX_copy sets |dest| equal to |src|. On entry, |dest| must have been
+ * initialised by calling |HMAC_CTX_init|. It returns one on success and zero
+ * on error. */
+int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src);
+
+/* HMAC_CTX_set_flags ORs |flags| into the flags of the underlying digests of
+ * |ctx|, which must have been setup by a call to |HMAC_Init_ex|. See
+ * |EVP_MD_CTX_set_flags|.
+ *
+ * TODO(fork): remove? */
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
+
+
+/* Deprecated functions. */
+
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md);
+
+
+/* Private functions */
+
+#define HMAC_MAX_MD_CBLOCK 128 /* largest known is SHA512 */
+
+struct hmac_ctx_st {
+ const EVP_MD *md;
+ EVP_MD_CTX md_ctx;
+ EVP_MD_CTX i_ctx;
+ EVP_MD_CTX o_ctx;
+ unsigned int key_length;
+ unsigned char key[HMAC_MAX_MD_CBLOCK];
+} /* HMAC_CTX */;
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_HMAC_H */
diff --git a/crypto/hmac/hmac_test.c b/crypto/hmac/hmac_test.c
new file mode 100644
index 00000000..e2ae4a6f
--- /dev/null
+++ b/crypto/hmac/hmac_test.c
@@ -0,0 +1,151 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <stdio.h>
+
+#include <openssl/digest.h>
+#include <openssl/hmac.h>
+
+
+struct test_st {
+ unsigned char key[16];
+ unsigned key_len;
+ unsigned char data[64];
+ unsigned data_len;
+ const char *hex_digest;
+};
+
+#define NUM_TESTS 4
+
+static const struct test_st kTests[NUM_TESTS] = {
+ {
+ "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54,
+ "e9139d1e6ee064ef8cf514fc7dc83e86",
+ },
+ {
+ {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b,
+ },
+ 16,
+ "Hi There",
+ 8,
+ "9294727a3638bb1c13f48ef8158bfc9d",
+ },
+ {
+ "Jefe", 4, "what do ya want for nothing?", 28,
+ "750c783e6ab0b503eaa86e310a5db738",
+ },
+ {
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0xaa, 0xaa,
+ },
+ 16,
+ {
+ 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,
+ },
+ 50,
+ "56be34521d144c88dbb8c733f0e8b3f6",
+ },
+};
+
+static char *to_hex(const uint8_t *md, size_t md_len) {
+ size_t i;
+ static char buf[80];
+
+ for (i = 0; i < md_len; i++) {
+ sprintf(&(buf[i * 2]), "%02x", md[i]);
+ }
+ return buf;
+}
+
+int main(int argc, char *argv[]) {
+ unsigned i;
+ char *p;
+ int err = 0;
+ uint8_t out[EVP_MAX_MD_SIZE];
+ unsigned out_len;
+
+ for (i = 0; i < NUM_TESTS; i++) {
+ const struct test_st *test = &kTests[i];
+
+ if (NULL == HMAC(EVP_md5(), test->key, test->key_len, test->data,
+ test->data_len, out, &out_len)) {
+ printf("%u: HMAC failed.\n", i);
+ err++;
+ continue;
+ }
+
+ p = to_hex(out, out_len);
+
+ if (strcmp(p, test->hex_digest) != 0) {
+ printf("%u: got %s instead of %s\n", i, p, test->hex_digest);
+ err++;
+ }
+ }
+
+ if (err) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}