working version with crypto
[anytun.git] / keyexchange / isakmpd-20041012 / hash.c
blob84773f875b03c97ef2c555233a8932e4329026bc
1 /* $OpenBSD: hash.c,v 1.17 2004/06/14 09:55:41 ho Exp $ */
2 /* $EOM: hash.c,v 1.10 1999/04/17 23:20:34 niklas Exp $ */
4 /*
5 * Copyright (c) 1998 Niels Provos. All rights reserved.
6 * Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * This code was written under funding by Ericsson Radio Systems.
33 #include <sys/param.h>
34 #include <string.h>
35 #if defined (__APPLE__)
36 #include <openssl/md5.h>
37 #include <openssl/sha.h>
38 #else
39 #include <md5.h>
40 #include <sha1.h>
41 #endif /* __APPLE__ */
43 #include "sysdep.h"
45 #include "hash.h"
46 #include "log.h"
48 void hmac_init(struct hash *, unsigned char *, unsigned int);
49 void hmac_final(unsigned char *, struct hash *);
51 /* Temporary hash contexts. */
52 static union {
53 MD5_CTX md5ctx;
54 SHA1_CTX sha1ctx;
55 } Ctx, Ctx2;
57 /* Temporary hash digest. */
58 static unsigned char digest[HASH_MAX];
60 /* Encapsulation of hash functions. */
62 static struct hash hashes[] = {
64 HASH_MD5, 5, MD5_SIZE, (void *)&Ctx.md5ctx, digest,
65 sizeof(MD5_CTX), (void *)&Ctx2.md5ctx,
66 (void (*)(void *))MD5Init,
67 (void (*)(void *, unsigned char *, unsigned int))MD5Update,
68 (void (*)(unsigned char *, void *))MD5Final,
69 hmac_init,
70 hmac_final
71 }, {
72 HASH_SHA1, 6, SHA1_SIZE, (void *)&Ctx.sha1ctx, digest,
73 sizeof(SHA1_CTX), (void *)&Ctx2.sha1ctx,
74 (void (*)(void *))SHA1Init,
75 (void (*)(void *, unsigned char *, unsigned int))SHA1Update,
76 (void (*)(unsigned char *, void *))SHA1Final,
77 hmac_init,
78 hmac_final
82 struct hash *
83 hash_get(enum hashes hashtype)
85 size_t i;
87 LOG_DBG((LOG_CRYPTO, 60, "hash_get: requested algorithm %d",
88 hashtype));
90 for (i = 0; i < sizeof hashes / sizeof hashes[0]; i++)
91 if (hashtype == hashes[i].type)
92 return &hashes[i];
94 return 0;
98 * Initial a hash for HMAC usage this requires a special init function.
99 * ctx, ctx2 hold the contexts, if you want to use the hash object for
100 * something else in the meantime, be sure to store the contexts somewhere.
103 void
104 hmac_init(struct hash *hash, unsigned char *okey, unsigned int len)
106 unsigned int i, blocklen = HMAC_BLOCKLEN;
107 unsigned char key[HMAC_BLOCKLEN];
109 memset(key, 0, blocklen);
110 if (len > blocklen) {
111 /* Truncate key down to blocklen */
112 hash->Init(hash->ctx);
113 hash->Update(hash->ctx, okey, len);
114 hash->Final(key, hash->ctx);
115 } else {
116 memcpy(key, okey, len);
119 /* HMAC I and O pad computation */
120 for (i = 0; i < blocklen; i++)
121 key[i] ^= HMAC_IPAD_VAL;
123 hash->Init(hash->ctx);
124 hash->Update(hash->ctx, key, blocklen);
126 for (i = 0; i < blocklen; i++)
127 key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
129 hash->Init(hash->ctx2);
130 hash->Update(hash->ctx2, key, blocklen);
132 memset(key, 0, blocklen);
136 * HMAC Final function
139 void
140 hmac_final(unsigned char *dgst, struct hash *hash)
142 hash->Final(dgst, hash->ctx);
143 hash->Update(hash->ctx2, dgst, hash->hashsize);
144 hash->Final(dgst, hash->ctx2);