xref: /netbsd/external/bsd/libbind/dist/dst/hmac_link.c (revision e6e30c83)
1*e6e30c83Schristos /*	$NetBSD: hmac_link.c,v 1.1.1.2 2012/09/09 16:07:47 christos Exp $	*/
2b5677b36Schristos 
3b5677b36Schristos #ifdef HMAC_MD5
4b5677b36Schristos #ifndef LINT
5b5677b36Schristos static const char rcsid[] = "Header: /proj/cvs/prod/libbind/dst/hmac_link.c,v 1.8 2007/09/24 17:18:25 each Exp ";
6b5677b36Schristos #endif
7b5677b36Schristos /*
8b5677b36Schristos  * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
9b5677b36Schristos  *
10b5677b36Schristos  * Permission to use, copy modify, and distribute this software for any
11b5677b36Schristos  * purpose with or without fee is hereby granted, provided that the above
12b5677b36Schristos  * copyright notice and this permission notice appear in all copies.
13b5677b36Schristos  *
14b5677b36Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
15b5677b36Schristos  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
16b5677b36Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL
17b5677b36Schristos  * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
18b5677b36Schristos  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
19b5677b36Schristos  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20b5677b36Schristos  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21b5677b36Schristos  * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
22b5677b36Schristos  */
23b5677b36Schristos 
24b5677b36Schristos /*%
25b5677b36Schristos  * This file contains an implementation of the HMAC-MD5 algorithm.
26b5677b36Schristos  */
27b5677b36Schristos #include "port_before.h"
28b5677b36Schristos 
29b5677b36Schristos #include <stdio.h>
30b5677b36Schristos #include <unistd.h>
31b5677b36Schristos #include <stdlib.h>
32b5677b36Schristos #include <string.h>
33b5677b36Schristos #include <memory.h>
34b5677b36Schristos #include <sys/param.h>
35b5677b36Schristos #include <sys/time.h>
36b5677b36Schristos #include <netinet/in.h>
37b5677b36Schristos #include <arpa/nameser.h>
38b5677b36Schristos #include <resolv.h>
39b5677b36Schristos 
40b5677b36Schristos #include "dst_internal.h"
41b5677b36Schristos 
42b5677b36Schristos #ifdef USE_MD5
43b5677b36Schristos # ifndef HAVE_MD5
44b5677b36Schristos #  include "md5.h"
45b5677b36Schristos # else
46b5677b36Schristos #  ifdef SOLARIS2
47b5677b36Schristos #   include <sys/md5.h>
48b5677b36Schristos #  endif
49b5677b36Schristos # endif
50b5677b36Schristos # ifndef _MD5_H_
51b5677b36Schristos #  define _MD5_H_ 1	/*%< make sure we do not include rsaref md5.h file */
52b5677b36Schristos # endif
53b5677b36Schristos #endif
54b5677b36Schristos 
55b5677b36Schristos #include "port_after.h"
56b5677b36Schristos 
57b5677b36Schristos 
58b5677b36Schristos #define HMAC_LEN	64
59b5677b36Schristos #define HMAC_IPAD	0x36
60b5677b36Schristos #define HMAC_OPAD	0x5c
61b5677b36Schristos #define MD5_LEN		16
62b5677b36Schristos 
63b5677b36Schristos 
64b5677b36Schristos typedef struct hmackey {
65b5677b36Schristos 	u_char hk_ipad[64], hk_opad[64];
66b5677b36Schristos } HMAC_Key;
67b5677b36Schristos 
68b5677b36Schristos 
69b5677b36Schristos /**************************************************************************
70b5677b36Schristos  * dst_hmac_md5_sign
71b5677b36Schristos  *     Call HMAC signing functions to sign a block of data.
72b5677b36Schristos  *     There are three steps to signing, INIT (initialize structures),
73b5677b36Schristos  *     UPDATE (hash (more) data), FINAL (generate a signature).  This
74b5677b36Schristos  *     routine performs one or more of these steps.
75b5677b36Schristos  * Parameters
76b5677b36Schristos  *     mode	SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL.
77b5677b36Schristos  *     priv_key    key to use for signing.
78b5677b36Schristos  *     context   the context to be used in this digest
79b5677b36Schristos  *     data	data to be signed.
80b5677b36Schristos  *     len	 length in bytes of data.
81b5677b36Schristos  *     signature   location to store signature.
82b5677b36Schristos  *     sig_len     size of the signature location
83b5677b36Schristos  * returns
84b5677b36Schristos  *	N  Success on SIG_MODE_FINAL = returns signature length in bytes
85b5677b36Schristos  *	0  Success on SIG_MODE_INIT  and UPDATE
86b5677b36Schristos  *	 <0  Failure
87b5677b36Schristos  */
88b5677b36Schristos 
89b5677b36Schristos static int
dst_hmac_md5_sign(const int mode,DST_KEY * d_key,void ** context,const u_char * data,const int len,u_char * signature,const int sig_len)90b5677b36Schristos dst_hmac_md5_sign(const int mode, DST_KEY *d_key, void **context,
91b5677b36Schristos 		  const u_char *data, const int len,
92b5677b36Schristos 		  u_char *signature, const int sig_len)
93b5677b36Schristos {
94b5677b36Schristos 	HMAC_Key *key;
95b5677b36Schristos 	int sign_len = 0;
96b5677b36Schristos 	MD5_CTX *ctx = NULL;
97b5677b36Schristos 
98b5677b36Schristos 	if (d_key == NULL || d_key->dk_KEY_struct == NULL)
99b5677b36Schristos 		return (-1);
100b5677b36Schristos 
101b5677b36Schristos 	if (mode & SIG_MODE_INIT)
102b5677b36Schristos 		ctx = (MD5_CTX *) malloc(sizeof(*ctx));
103b5677b36Schristos 	else if (context)
104b5677b36Schristos 		ctx = (MD5_CTX *) *context;
105b5677b36Schristos 	if (ctx == NULL)
106b5677b36Schristos 		return (-1);
107b5677b36Schristos 
108b5677b36Schristos 	key = (HMAC_Key *) d_key->dk_KEY_struct;
109b5677b36Schristos 
110b5677b36Schristos 	if (mode & SIG_MODE_INIT) {
111b5677b36Schristos 		MD5Init(ctx);
112b5677b36Schristos 		MD5Update(ctx, key->hk_ipad, HMAC_LEN);
113b5677b36Schristos 	}
114b5677b36Schristos 
115b5677b36Schristos 	if ((mode & SIG_MODE_UPDATE) && (data && len > 0))
116b5677b36Schristos 		MD5Update(ctx, data, len);
117b5677b36Schristos 
118b5677b36Schristos 	if (mode & SIG_MODE_FINAL) {
119b5677b36Schristos 		if (signature == NULL || sig_len < MD5_LEN)
120b5677b36Schristos 			return (SIGN_FINAL_FAILURE);
121b5677b36Schristos 		MD5Final(signature, ctx);
122b5677b36Schristos 
123b5677b36Schristos 		/* perform outer MD5 */
124b5677b36Schristos 		MD5Init(ctx);
125b5677b36Schristos 		MD5Update(ctx, key->hk_opad, HMAC_LEN);
126b5677b36Schristos 		MD5Update(ctx, signature, MD5_LEN);
127b5677b36Schristos 		MD5Final(signature, ctx);
128b5677b36Schristos 		sign_len = MD5_LEN;
129b5677b36Schristos 		SAFE_FREE(ctx);
130b5677b36Schristos 	}
131b5677b36Schristos 	else {
132b5677b36Schristos 		if (context == NULL)
133b5677b36Schristos 			return (-1);
134b5677b36Schristos 		*context = (void *) ctx;
135b5677b36Schristos 	}
136b5677b36Schristos 	return (sign_len);
137b5677b36Schristos }
138b5677b36Schristos 
139b5677b36Schristos 
140b5677b36Schristos /**************************************************************************
141b5677b36Schristos  * dst_hmac_md5_verify()
142b5677b36Schristos  *     Calls HMAC verification routines.  There are three steps to
143b5677b36Schristos  *     verification, INIT (initialize structures), UPDATE (hash (more) data),
144b5677b36Schristos  *     FINAL (generate a signature).  This routine performs one or more of
145b5677b36Schristos  *     these steps.
146b5677b36Schristos  * Parameters
147b5677b36Schristos  *     mode	SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL.
148b5677b36Schristos  *     dkey	key to use for verify.
149b5677b36Schristos  *     data	data signed.
150b5677b36Schristos  *     len	 length in bytes of data.
151b5677b36Schristos  *     signature   signature.
152b5677b36Schristos  *     sig_len     length in bytes of signature.
153b5677b36Schristos  * returns
154b5677b36Schristos  *     0  Success
155b5677b36Schristos  *    <0  Failure
156b5677b36Schristos  */
157b5677b36Schristos 
158b5677b36Schristos static int
dst_hmac_md5_verify(const int mode,DST_KEY * d_key,void ** context,const u_char * data,const int len,const u_char * signature,const int sig_len)159b5677b36Schristos dst_hmac_md5_verify(const int mode, DST_KEY *d_key, void **context,
160b5677b36Schristos 		const u_char *data, const int len,
161b5677b36Schristos 		const u_char *signature, const int sig_len)
162b5677b36Schristos {
163b5677b36Schristos 	HMAC_Key *key;
164b5677b36Schristos 	MD5_CTX *ctx = NULL;
165b5677b36Schristos 
166b5677b36Schristos 	if (d_key == NULL || d_key->dk_KEY_struct == NULL)
167b5677b36Schristos 		return (-1);
168b5677b36Schristos 
169b5677b36Schristos 	if (mode & SIG_MODE_INIT)
170b5677b36Schristos 		ctx = (MD5_CTX *) malloc(sizeof(*ctx));
171b5677b36Schristos 	else if (context)
172b5677b36Schristos 		ctx = (MD5_CTX *) *context;
173b5677b36Schristos 	if (ctx == NULL)
174b5677b36Schristos 		return (-1);
175b5677b36Schristos 
176b5677b36Schristos 	key = (HMAC_Key *) d_key->dk_KEY_struct;
177b5677b36Schristos 	if (mode & SIG_MODE_INIT) {
178b5677b36Schristos 		MD5Init(ctx);
179b5677b36Schristos 		MD5Update(ctx, key->hk_ipad, HMAC_LEN);
180b5677b36Schristos 	}
181b5677b36Schristos 	if ((mode & SIG_MODE_UPDATE) && (data && len > 0))
182b5677b36Schristos 		MD5Update(ctx, data, len);
183b5677b36Schristos 
184b5677b36Schristos 	if (mode & SIG_MODE_FINAL) {
185b5677b36Schristos 		u_char digest[MD5_LEN];
186b5677b36Schristos 		if (signature == NULL || key == NULL || sig_len != MD5_LEN)
187b5677b36Schristos 			return (VERIFY_FINAL_FAILURE);
188b5677b36Schristos 		MD5Final(digest, ctx);
189b5677b36Schristos 
190b5677b36Schristos 		/* perform outer MD5 */
191b5677b36Schristos 		MD5Init(ctx);
192b5677b36Schristos 		MD5Update(ctx, key->hk_opad, HMAC_LEN);
193b5677b36Schristos 		MD5Update(ctx, digest, MD5_LEN);
194b5677b36Schristos 		MD5Final(digest, ctx);
195b5677b36Schristos 
196b5677b36Schristos 		SAFE_FREE(ctx);
197b5677b36Schristos 		if (memcmp(digest, signature, MD5_LEN) != 0)
198b5677b36Schristos 			return (VERIFY_FINAL_FAILURE);
199b5677b36Schristos 	}
200b5677b36Schristos 	else {
201b5677b36Schristos 		if (context == NULL)
202b5677b36Schristos 			return (-1);
203b5677b36Schristos 		*context = (void *) ctx;
204b5677b36Schristos 	}
205b5677b36Schristos 	return (0);
206b5677b36Schristos }
207b5677b36Schristos 
208b5677b36Schristos 
209b5677b36Schristos /**************************************************************************
210b5677b36Schristos  * dst_buffer_to_hmac_md5
211b5677b36Schristos  *     Converts key from raw data to an HMAC Key
212b5677b36Schristos  *     This function gets in a pointer to the data
213b5677b36Schristos  * Parameters
214b5677b36Schristos  *     hkey	the HMAC key to be filled in
215b5677b36Schristos  *     key	the key in raw format
216b5677b36Schristos  *     keylen	the length of the key
217b5677b36Schristos  * Return
218b5677b36Schristos  *	0	Success
219b5677b36Schristos  *	<0	Failure
220b5677b36Schristos  */
221b5677b36Schristos static int
dst_buffer_to_hmac_md5(DST_KEY * dkey,const u_char * key,const int keylen)222b5677b36Schristos dst_buffer_to_hmac_md5(DST_KEY *dkey, const u_char *key, const int keylen)
223b5677b36Schristos {
224b5677b36Schristos 	int i;
225b5677b36Schristos 	HMAC_Key *hkey = NULL;
226b5677b36Schristos 	MD5_CTX ctx;
227b5677b36Schristos 	int local_keylen = keylen;
228b5677b36Schristos 	u_char tk[MD5_LEN];
229b5677b36Schristos 
230b5677b36Schristos 	if (dkey == NULL || key == NULL || keylen < 0)
231b5677b36Schristos 		return (-1);
232b5677b36Schristos 
233b5677b36Schristos 	if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL)
234b5677b36Schristos 		  return (-2);
235b5677b36Schristos 
236b5677b36Schristos 	memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad));
237b5677b36Schristos 	memset(hkey->hk_opad, 0, sizeof(hkey->hk_opad));
238b5677b36Schristos 
239b5677b36Schristos 	/* if key is longer than HMAC_LEN bytes reset it to key=MD5(key) */
240b5677b36Schristos 	if (keylen > HMAC_LEN) {
241b5677b36Schristos 		MD5Init(&ctx);
242b5677b36Schristos 		MD5Update(&ctx, key, keylen);
243b5677b36Schristos 		MD5Final(tk, &ctx);
244b5677b36Schristos 		memset((void *) &ctx, 0, sizeof(ctx));
245b5677b36Schristos 		key = tk;
246b5677b36Schristos 		local_keylen = MD5_LEN;
247b5677b36Schristos 	}
248b5677b36Schristos 	/* start out by storing key in pads */
249b5677b36Schristos 	memcpy(hkey->hk_ipad, key, local_keylen);
250b5677b36Schristos 	memcpy(hkey->hk_opad, key, local_keylen);
251b5677b36Schristos 
252b5677b36Schristos 	/* XOR key with hk_ipad and opad values */
253b5677b36Schristos 	for (i = 0; i < HMAC_LEN; i++) {
254b5677b36Schristos 		hkey->hk_ipad[i] ^= HMAC_IPAD;
255b5677b36Schristos 		hkey->hk_opad[i] ^= HMAC_OPAD;
256b5677b36Schristos 	}
257b5677b36Schristos 	dkey->dk_key_size = local_keylen;
258b5677b36Schristos 	dkey->dk_KEY_struct = (void *) hkey;
259b5677b36Schristos 	return (1);
260b5677b36Schristos }
261b5677b36Schristos 
262b5677b36Schristos 
263b5677b36Schristos /**************************************************************************
264b5677b36Schristos  *  dst_hmac_md5_key_to_file_format
265b5677b36Schristos  *	Encodes an HMAC Key into the portable file format.
266b5677b36Schristos  *  Parameters
267b5677b36Schristos  *	hkey      HMAC KEY structure
268b5677b36Schristos  *	buff      output buffer
269b5677b36Schristos  *	buff_len  size of output buffer
270b5677b36Schristos  *  Return
271b5677b36Schristos  *	0  Failure - null input hkey
272b5677b36Schristos  *     -1  Failure - not enough space in output area
273b5677b36Schristos  *	N  Success - Length of data returned in buff
274b5677b36Schristos  */
275b5677b36Schristos 
276b5677b36Schristos static int
dst_hmac_md5_key_to_file_format(const DST_KEY * dkey,char * buff,const int buff_len)277b5677b36Schristos dst_hmac_md5_key_to_file_format(const DST_KEY *dkey, char *buff,
278b5677b36Schristos 			        const int buff_len)
279b5677b36Schristos {
280b5677b36Schristos 	char *bp;
281b5677b36Schristos 	int len, i, key_len;
282b5677b36Schristos 	u_char key[HMAC_LEN];
283b5677b36Schristos 	HMAC_Key *hkey;
284b5677b36Schristos 
285b5677b36Schristos 	if (dkey == NULL || dkey->dk_KEY_struct == NULL)
286b5677b36Schristos 		return (0);
287b5677b36Schristos 	/*
288b5677b36Schristos 	 * Using snprintf() would be so much simpler here.
289b5677b36Schristos 	 */
290b5677b36Schristos 	if (buff == NULL ||
291b5677b36Schristos 	    buff_len <= (int)(strlen(key_file_fmt_str) +
292b5677b36Schristos 			      strlen(KEY_FILE_FORMAT) + 4))
293b5677b36Schristos 		return (-1);	/*%< no OR not enough space in output area */
294b5677b36Schristos 	hkey = (HMAC_Key *) dkey->dk_KEY_struct;
295b5677b36Schristos 	memset(buff, 0, buff_len);	/*%< just in case */
296b5677b36Schristos 	/* write file header */
297b5677b36Schristos 	sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_HMAC_MD5, "HMAC");
298b5677b36Schristos 
299b5677b36Schristos 	bp = buff + strlen(buff);
300b5677b36Schristos 
301b5677b36Schristos 	memset(key, 0, HMAC_LEN);
302b5677b36Schristos 	for (i = 0; i < HMAC_LEN; i++)
303b5677b36Schristos 		key[i] = hkey->hk_ipad[i] ^ HMAC_IPAD;
304b5677b36Schristos 	for (i = HMAC_LEN - 1; i >= 0; i--)
305b5677b36Schristos 		if (key[i] != 0)
306b5677b36Schristos 			break;
307b5677b36Schristos 	key_len = i + 1;
308b5677b36Schristos 
309b5677b36Schristos 	if (buff_len - (bp - buff) < 6)
310b5677b36Schristos 		return (-1);
311b5677b36Schristos 	strcat(bp, "Key: ");
312b5677b36Schristos 	bp += strlen("Key: ");
313b5677b36Schristos 
314b5677b36Schristos 	len = b64_ntop(key, key_len, bp, buff_len - (bp - buff));
315b5677b36Schristos 	if (len < 0)
316b5677b36Schristos 		return (-1);
317b5677b36Schristos 	bp += len;
318b5677b36Schristos 	if (buff_len - (bp - buff) < 2)
319b5677b36Schristos 		return (-1);
320b5677b36Schristos 	*(bp++) = '\n';
321b5677b36Schristos 	*bp = '\0';
322b5677b36Schristos 
323b5677b36Schristos 	return (bp - buff);
324b5677b36Schristos }
325b5677b36Schristos 
326b5677b36Schristos 
327b5677b36Schristos /**************************************************************************
328b5677b36Schristos  * dst_hmac_md5_key_from_file_format
329b5677b36Schristos  *     Converts contents of a key file into an HMAC key.
330b5677b36Schristos  * Parameters
331b5677b36Schristos  *     hkey    structure to put key into
332b5677b36Schristos  *     buff       buffer containing the encoded key
333b5677b36Schristos  *     buff_len   the length of the buffer
334b5677b36Schristos  * Return
335b5677b36Schristos  *     n >= 0 Foot print of the key converted
336b5677b36Schristos  *     n <  0 Error in conversion
337b5677b36Schristos  */
338b5677b36Schristos 
339b5677b36Schristos static int
dst_hmac_md5_key_from_file_format(DST_KEY * dkey,const char * buff,const int buff_len)340b5677b36Schristos dst_hmac_md5_key_from_file_format(DST_KEY *dkey, const char *buff,
341b5677b36Schristos 			      const int buff_len)
342b5677b36Schristos {
343b5677b36Schristos 	const char *p = buff, *eol;
344b5677b36Schristos 	u_char key[HMAC_LEN+1];	/* b64_pton needs more than 64 bytes do decode
345b5677b36Schristos 				 * it should probably be fixed rather than doing
346b5677b36Schristos 				 * this
347b5677b36Schristos 				 */
348b5677b36Schristos 	u_char *tmp;
349b5677b36Schristos 	int key_len, len;
350b5677b36Schristos 
351b5677b36Schristos 	if (dkey == NULL)
352b5677b36Schristos 		return (-2);
353b5677b36Schristos 	if (buff == NULL || buff_len < 0)
354b5677b36Schristos 		return (-1);
355b5677b36Schristos 
356b5677b36Schristos 	memset(key, 0, sizeof(key));
357b5677b36Schristos 
358b5677b36Schristos 	if (!dst_s_verify_str(&p, "Key: "))
359b5677b36Schristos 		return (-3);
360b5677b36Schristos 
361b5677b36Schristos 	eol = strchr(p, '\n');
362b5677b36Schristos 	if (eol == NULL)
363b5677b36Schristos 		return (-4);
364b5677b36Schristos 	len = eol - p;
365b5677b36Schristos 	tmp = malloc(len + 2);
366b5677b36Schristos 	if (tmp == NULL)
367b5677b36Schristos 		return (-5);
368b5677b36Schristos 	memcpy(tmp, p, len);
369b5677b36Schristos 	*(tmp + len) = 0x0;
370b5677b36Schristos 	key_len = b64_pton((char *)tmp, key, HMAC_LEN+1);	/*%< see above */
371b5677b36Schristos 	SAFE_FREE2(tmp, len + 2);
372b5677b36Schristos 
373b5677b36Schristos 	if (dst_buffer_to_hmac_md5(dkey, key, key_len) < 0) {
374b5677b36Schristos 		return (-6);
375b5677b36Schristos 	}
376b5677b36Schristos 	return (0);
377b5677b36Schristos }
378b5677b36Schristos 
379b5677b36Schristos /*%
380b5677b36Schristos  * dst_hmac_md5_to_dns_key()
381b5677b36Schristos  *         function to extract hmac key from DST_KEY structure
382b5677b36Schristos  * intput:
383b5677b36Schristos  *      in_key:  HMAC-MD5 key
384b5677b36Schristos  * output:
385b5677b36Schristos  *	out_str: buffer to write ot
386b5677b36Schristos  *      out_len: size of output buffer
387b5677b36Schristos  * returns:
388b5677b36Schristos  *      number of bytes written to output buffer
389b5677b36Schristos  */
390b5677b36Schristos static int
dst_hmac_md5_to_dns_key(const DST_KEY * in_key,u_char * out_str,const int out_len)391b5677b36Schristos dst_hmac_md5_to_dns_key(const DST_KEY *in_key, u_char *out_str,
392b5677b36Schristos 			const int out_len)
393b5677b36Schristos {
394b5677b36Schristos 
395b5677b36Schristos 	HMAC_Key *hkey;
396b5677b36Schristos 	int i;
397b5677b36Schristos 
398b5677b36Schristos 	if (in_key == NULL || in_key->dk_KEY_struct == NULL ||
399b5677b36Schristos 	    out_len <= in_key->dk_key_size || out_str == NULL)
400b5677b36Schristos 		return (-1);
401b5677b36Schristos 
402b5677b36Schristos 	hkey = (HMAC_Key *) in_key->dk_KEY_struct;
403b5677b36Schristos 	for (i = 0; i < in_key->dk_key_size; i++)
404b5677b36Schristos 		out_str[i] = hkey->hk_ipad[i] ^ HMAC_IPAD;
405b5677b36Schristos 	return (i);
406b5677b36Schristos }
407b5677b36Schristos 
408b5677b36Schristos /**************************************************************************
409b5677b36Schristos  *  dst_hmac_md5_compare_keys
410b5677b36Schristos  *	Compare two keys for equality.
411b5677b36Schristos  *  Return
412b5677b36Schristos  *	0	  The keys are equal
413b5677b36Schristos  *	NON-ZERO   The keys are not equal
414b5677b36Schristos  */
415b5677b36Schristos 
416b5677b36Schristos static int
dst_hmac_md5_compare_keys(const DST_KEY * key1,const DST_KEY * key2)417b5677b36Schristos dst_hmac_md5_compare_keys(const DST_KEY *key1, const DST_KEY *key2)
418b5677b36Schristos {
419b5677b36Schristos 	HMAC_Key *hkey1 = (HMAC_Key *) key1->dk_KEY_struct;
420b5677b36Schristos 	HMAC_Key *hkey2 = (HMAC_Key *) key2->dk_KEY_struct;
421b5677b36Schristos 	return memcmp(hkey1->hk_ipad, hkey2->hk_ipad, HMAC_LEN);
422b5677b36Schristos }
423b5677b36Schristos 
424b5677b36Schristos /**************************************************************************
425b5677b36Schristos  * dst_hmac_md5_free_key_structure
426b5677b36Schristos  *     Frees all (none) dynamically allocated structures in hkey
427b5677b36Schristos  */
428b5677b36Schristos 
429b5677b36Schristos static void *
dst_hmac_md5_free_key_structure(void * key)430b5677b36Schristos dst_hmac_md5_free_key_structure(void *key)
431b5677b36Schristos {
432b5677b36Schristos 	HMAC_Key *hkey = key;
433b5677b36Schristos 	SAFE_FREE(hkey);
434b5677b36Schristos 	return (NULL);
435b5677b36Schristos }
436b5677b36Schristos 
437b5677b36Schristos 
438b5677b36Schristos /***************************************************************************
439b5677b36Schristos  * dst_hmac_md5_generate_key
440b5677b36Schristos  *     Creates a HMAC key of size size with a maximum size of 63 bytes
441b5677b36Schristos  *     generating a HMAC key larger than 63 bytes makes no sense as that key
442b5677b36Schristos  *     is digested before use.
443b5677b36Schristos  */
444b5677b36Schristos 
445b5677b36Schristos static int
dst_hmac_md5_generate_key(DST_KEY * key,const int nothing)446b5677b36Schristos dst_hmac_md5_generate_key(DST_KEY *key, const int nothing)
447b5677b36Schristos {
448b5677b36Schristos 	(void)key;
449b5677b36Schristos 	(void)nothing;
450b5677b36Schristos 	return (-1);
451b5677b36Schristos }
452b5677b36Schristos 
453b5677b36Schristos /*%
454b5677b36Schristos  * dst_hmac_md5_init()  Function to answer set up function pointers for HMAC
455b5677b36Schristos  *	   related functions
456b5677b36Schristos  */
457b5677b36Schristos int
458b5677b36Schristos #ifdef	SUNW_LIBMD5
dst_md5_hmac_init()459b5677b36Schristos dst_md5_hmac_init()
460b5677b36Schristos #else
461b5677b36Schristos dst_hmac_md5_init()
462b5677b36Schristos #endif
463b5677b36Schristos {
464b5677b36Schristos 	if (dst_t_func[KEY_HMAC_MD5] != NULL)
465b5677b36Schristos 		return (1);
466b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func));
467b5677b36Schristos 	if (dst_t_func[KEY_HMAC_MD5] == NULL)
468b5677b36Schristos 		return (0);
469b5677b36Schristos 	memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func));
470b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->sign = dst_hmac_md5_sign;
471b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->verify = dst_hmac_md5_verify;
472b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->compare = dst_hmac_md5_compare_keys;
473b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->generate = dst_hmac_md5_generate_key;
474b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->destroy = dst_hmac_md5_free_key_structure;
475b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->to_dns_key = dst_hmac_md5_to_dns_key;
476b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->from_dns_key = dst_buffer_to_hmac_md5;
477b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->to_file_fmt = dst_hmac_md5_key_to_file_format;
478b5677b36Schristos 	dst_t_func[KEY_HMAC_MD5]->from_file_fmt = dst_hmac_md5_key_from_file_format;
479b5677b36Schristos 	return (1);
480b5677b36Schristos }
481b5677b36Schristos 
482b5677b36Schristos #else
483b5677b36Schristos #define	dst_hmac_md5_init	__dst_hmac_md5_init
484b5677b36Schristos 
485b5677b36Schristos int
dst_hmac_md5_init()486b5677b36Schristos dst_hmac_md5_init(){
487b5677b36Schristos 	return (0);
488b5677b36Schristos }
489b5677b36Schristos #endif
490b5677b36Schristos 
491b5677b36Schristos /*! \file */
492