summaryrefslogtreecommitdiff
path: root/keyexchange/isakmpd-20041012/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyexchange/isakmpd-20041012/hash.c')
-rw-r--r--keyexchange/isakmpd-20041012/hash.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/keyexchange/isakmpd-20041012/hash.c b/keyexchange/isakmpd-20041012/hash.c
new file mode 100644
index 0000000..84773f8
--- /dev/null
+++ b/keyexchange/isakmpd-20041012/hash.c
@@ -0,0 +1,145 @@
+/* $OpenBSD: hash.c,v 1.17 2004/06/14 09:55:41 ho Exp $ */
+/* $EOM: hash.c,v 1.10 1999/04/17 23:20:34 niklas Exp $ */
+
+/*
+ * Copyright (c) 1998 Niels Provos. All rights reserved.
+ * Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
+ *
+ * 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 above 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+/*
+ * This code was written under funding by Ericsson Radio Systems.
+ */
+
+#include <sys/param.h>
+#include <string.h>
+#if defined (__APPLE__)
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#else
+#include <md5.h>
+#include <sha1.h>
+#endif /* __APPLE__ */
+
+#include "sysdep.h"
+
+#include "hash.h"
+#include "log.h"
+
+void hmac_init(struct hash *, unsigned char *, unsigned int);
+void hmac_final(unsigned char *, struct hash *);
+
+/* Temporary hash contexts. */
+static union {
+ MD5_CTX md5ctx;
+ SHA1_CTX sha1ctx;
+} Ctx, Ctx2;
+
+/* Temporary hash digest. */
+static unsigned char digest[HASH_MAX];
+
+/* Encapsulation of hash functions. */
+
+static struct hash hashes[] = {
+ {
+ HASH_MD5, 5, MD5_SIZE, (void *)&Ctx.md5ctx, digest,
+ sizeof(MD5_CTX), (void *)&Ctx2.md5ctx,
+ (void (*)(void *))MD5Init,
+ (void (*)(void *, unsigned char *, unsigned int))MD5Update,
+ (void (*)(unsigned char *, void *))MD5Final,
+ hmac_init,
+ hmac_final
+ }, {
+ HASH_SHA1, 6, SHA1_SIZE, (void *)&Ctx.sha1ctx, digest,
+ sizeof(SHA1_CTX), (void *)&Ctx2.sha1ctx,
+ (void (*)(void *))SHA1Init,
+ (void (*)(void *, unsigned char *, unsigned int))SHA1Update,
+ (void (*)(unsigned char *, void *))SHA1Final,
+ hmac_init,
+ hmac_final
+ },
+};
+
+struct hash *
+hash_get(enum hashes hashtype)
+{
+ size_t i;
+
+ LOG_DBG((LOG_CRYPTO, 60, "hash_get: requested algorithm %d",
+ hashtype));
+
+ for (i = 0; i < sizeof hashes / sizeof hashes[0]; i++)
+ if (hashtype == hashes[i].type)
+ return &hashes[i];
+
+ return 0;
+}
+
+/*
+ * Initial a hash for HMAC usage this requires a special init function.
+ * ctx, ctx2 hold the contexts, if you want to use the hash object for
+ * something else in the meantime, be sure to store the contexts somewhere.
+ */
+
+void
+hmac_init(struct hash *hash, unsigned char *okey, unsigned int len)
+{
+ unsigned int i, blocklen = HMAC_BLOCKLEN;
+ unsigned char key[HMAC_BLOCKLEN];
+
+ memset(key, 0, blocklen);
+ if (len > blocklen) {
+ /* Truncate key down to blocklen */
+ hash->Init(hash->ctx);
+ hash->Update(hash->ctx, okey, len);
+ hash->Final(key, hash->ctx);
+ } else {
+ memcpy(key, okey, len);
+ }
+
+ /* HMAC I and O pad computation */
+ for (i = 0; i < blocklen; i++)
+ key[i] ^= HMAC_IPAD_VAL;
+
+ hash->Init(hash->ctx);
+ hash->Update(hash->ctx, key, blocklen);
+
+ for (i = 0; i < blocklen; i++)
+ key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
+
+ hash->Init(hash->ctx2);
+ hash->Update(hash->ctx2, key, blocklen);
+
+ memset(key, 0, blocklen);
+}
+
+/*
+ * HMAC Final function
+ */
+
+void
+hmac_final(unsigned char *dgst, struct hash *hash)
+{
+ hash->Final(dgst, hash->ctx);
+ hash->Update(hash->ctx2, dgst, hash->hashsize);
+ hash->Final(dgst, hash->ctx2);
+}