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 $ */
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
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>
35 #if defined (__APPLE__)
36 #include <openssl/md5.h>
37 #include <openssl/sha.h>
41 #endif /* __APPLE__ */
48 void hmac_init(struct hash
*, unsigned char *, unsigned int);
49 void hmac_final(unsigned char *, struct hash
*);
51 /* Temporary hash contexts. */
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
,
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
,
83 hash_get(enum hashes hashtype
)
87 LOG_DBG((LOG_CRYPTO
, 60, "hash_get: requested algorithm %d",
90 for (i
= 0; i
< sizeof hashes
/ sizeof hashes
[0]; i
++)
91 if (hashtype
== hashes
[i
].type
)
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.
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
);
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
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
);