GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/isakmpd/hash.c Lines: 0 24 0.0 %
Date: 2016-12-06 Branches: 0 10 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: hash.c,v 1.24 2015/10/15 06:35:54 mmcc Exp $	 */
2
/* $EOM: hash.c,v 1.10 1999/04/17 23:20:34 niklas Exp $	 */
3
4
/*
5
 * Copyright (c) 1998 Niels Provos.  All rights reserved.
6
 * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved.
7
 *
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.
16
 *
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.
27
 */
28
29
/*
30
 * This code was written under funding by Ericsson Radio Systems.
31
 */
32
33
#include <sys/types.h>
34
#include <string.h>
35
#include <md5.h>
36
#include <sha1.h>
37
#include <sha2.h>
38
39
#include "hash.h"
40
#include "log.h"
41
42
void	hmac_init(struct hash *, unsigned char *, unsigned int);
43
void	hmac_final(unsigned char *, struct hash *);
44
45
/* Temporary hash contexts.  */
46
static union {
47
	MD5_CTX		md5ctx;
48
	SHA1_CTX        sha1ctx;
49
	SHA2_CTX	sha2ctx;
50
} Ctx, Ctx2;
51
52
/* Temporary hash digest.  */
53
static unsigned char digest[HASH_MAX];
54
55
/* Encapsulation of hash functions.  */
56
57
static struct hash hashes[] = {
58
    {
59
	HASH_MD5, 5, MD5_SIZE, (void *)&Ctx.md5ctx, digest,
60
	sizeof(MD5_CTX), (void *)&Ctx2.md5ctx,
61
	(void (*)(void *))MD5Init,
62
	(void (*)(void *, unsigned char *, unsigned int))MD5Update,
63
	(void (*)(unsigned char *, void *))MD5Final,
64
	hmac_init,
65
	hmac_final
66
    }, {
67
	HASH_SHA1, 6, SHA1_SIZE, (void *)&Ctx.sha1ctx, digest,
68
	sizeof(SHA1_CTX), (void *)&Ctx2.sha1ctx,
69
	(void (*)(void *))SHA1Init,
70
	(void (*)(void *, unsigned char *, unsigned int))SHA1Update,
71
	(void (*)(unsigned char *, void *))SHA1Final,
72
	hmac_init,
73
	hmac_final
74
    }, {
75
	HASH_SHA2_256, 7, SHA2_256_SIZE, (void *)&Ctx.sha2ctx, digest,
76
	sizeof(SHA2_CTX), (void *)&Ctx2.sha2ctx,
77
	(void (*)(void *))SHA256Init,
78
	(void (*)(void *, unsigned char *, unsigned int))SHA256Update,
79
	(void (*)(u_int8_t *, void *))SHA256Final,
80
	hmac_init,
81
	hmac_final
82
    }, {
83
	HASH_SHA2_384, 8, SHA2_384_SIZE, (void *)&Ctx.sha2ctx, digest,
84
	sizeof(SHA2_CTX), (void *)&Ctx2.sha2ctx,
85
	(void (*)(void *))SHA384Init,
86
	(void (*)(void *, unsigned char *, unsigned int))SHA384Update,
87
	(void (*)(u_int8_t *, void *))SHA384Final,
88
	hmac_init,
89
	hmac_final
90
    }, {
91
	HASH_SHA2_512, 9, SHA2_512_SIZE, (void *)&Ctx.sha2ctx, digest,
92
	sizeof(SHA2_CTX), (void *)&Ctx2.sha2ctx,
93
	(void (*)(void *))SHA512Init,
94
	(void (*)(void *, unsigned char *, unsigned int))SHA512Update,
95
	(void (*)(u_int8_t *, void *))SHA512Final,
96
	hmac_init,
97
	hmac_final
98
    }
99
};
100
101
struct hash *
102
hash_get(enum hashes hashtype)
103
{
104
	size_t	i;
105
106
	LOG_DBG((LOG_CRYPTO, 60, "hash_get: requested algorithm %d",
107
	    hashtype));
108
109
	for (i = 0; i < sizeof hashes / sizeof hashes[0]; i++)
110
		if (hashtype == hashes[i].type)
111
			return &hashes[i];
112
113
	return 0;
114
}
115
116
/*
117
 * Initial a hash for HMAC usage this requires a special init function.
118
 * ctx, ctx2 hold the contexts, if you want to use the hash object for
119
 * something else in the meantime, be sure to store the contexts somewhere.
120
 */
121
122
void
123
hmac_init(struct hash *hash, unsigned char *okey, unsigned int len)
124
{
125
	unsigned int    i, blocklen = HMAC_BLOCKLEN;
126
	unsigned char   key[HMAC_BLOCKLEN];
127
128
	bzero(key, blocklen);
129
	if (len > blocklen) {
130
		/* Truncate key down to blocklen */
131
		hash->Init(hash->ctx);
132
		hash->Update(hash->ctx, okey, len);
133
		hash->Final(key, hash->ctx);
134
	} else {
135
		memcpy(key, okey, len);
136
	}
137
138
	/* HMAC I and O pad computation */
139
	for (i = 0; i < blocklen; i++)
140
		key[i] ^= HMAC_IPAD_VAL;
141
142
	hash->Init(hash->ctx);
143
	hash->Update(hash->ctx, key, blocklen);
144
145
	for (i = 0; i < blocklen; i++)
146
		key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
147
148
	hash->Init(hash->ctx2);
149
	hash->Update(hash->ctx2, key, blocklen);
150
151
	explicit_bzero(key, blocklen);
152
}
153
154
/*
155
 * HMAC Final function
156
 */
157
158
void
159
hmac_final(unsigned char *dgst, struct hash *hash)
160
{
161
	hash->Final(dgst, hash->ctx);
162
	hash->Update(hash->ctx2, dgst, hash->hashsize);
163
	hash->Final(dgst, hash->ctx2);
164
}