a_md5encrypt.c revision 132451
1/*
2 *	MD5 interface for rsaref2.0
3 *
4 * These routines implement an interface for the RSA Laboratories
5 * implementation of the Message Digest 5 (MD5) algorithm. This
6 * algorithm is included in the rsaref2.0 package available from RSA in
7 * the US and foreign countries. Further information is available at
8 * www.rsa.com.
9 */
10
11#ifdef HAVE_CONFIG_H
12#include <config.h>
13#endif
14
15#include "ntp_fp.h"
16#include "ntp_string.h"
17#include "ntp_stdlib.h"
18
19/* Disable the openssl md5 includes, because they'd clash with ours. */
20/* #define NO_MD5 */
21/* #define OPENSSL_NO_MD5 */
22#undef OPENSSL
23
24#include "ntp.h"
25#include "global.h"
26#include "ntp_md5.h"
27
28/*
29 * MD5authencrypt - generate MD5 message authenticator
30 *
31 * Returns length of authenticator field.
32 */
33int
34MD5authencrypt(
35	u_char *key,		/* key pointer */
36	u_int32 *pkt,		/* packet pointer */
37	int length		/* packet length */
38	)
39{
40	MD5_CTX md5;
41	u_char digest[16];
42
43	/*
44	 * MD5 with key identifier concatenated with packet.
45	 */
46	MD5Init(&md5);
47	MD5Update(&md5, key, (u_int)cache_keylen);
48	MD5Update(&md5, (u_char *)pkt, (u_int)length);
49	MD5Final(digest, &md5);
50	memmove((u_char *)pkt + length + 4, digest, 16);
51	return (16 + 4);
52}
53
54
55/*
56 * MD5authdecrypt - verify MD5 message authenticator
57 *
58 * Returns one if authenticator valid, zero if invalid.
59 */
60int
61MD5authdecrypt(
62	u_char *key,		/* key pointer */
63	u_int32 *pkt,		/* packet pointer */
64	int length,	 	/* packet length */
65	int size		/* MAC size */
66	)
67{
68	MD5_CTX md5;
69	u_char digest[16];
70
71	/*
72	 * MD5 with key identifier concatenated with packet.
73	 */
74	MD5Init(&md5);
75	MD5Update(&md5, key, (u_int)cache_keylen);
76	MD5Update(&md5, (u_char *)pkt, (u_int)length);
77	MD5Final(digest, &md5);
78	if (size != 16 + 4)
79		return (0);
80	return (!memcmp(digest, (char *)pkt + length + 4, 16));
81}
82
83/*
84 * Calculate the reference id from the address. If it is an IPv4
85 * address, use it as is. If it is an IPv6 address, do a md5 on
86 * it and use the bottom 4 bytes.
87 */
88u_int32
89addr2refid(struct sockaddr_storage *addr)
90{
91	MD5_CTX md5;
92	u_char digest[16];
93	u_int32 addr_refid;
94
95	if (addr->ss_family == AF_INET)
96		return (GET_INADDR(*addr));
97
98	MD5Init(&md5);
99	MD5Update(&md5, (u_char *)&GET_INADDR6(*addr),
100	    sizeof(struct in6_addr));
101	MD5Final(digest, &md5);
102	memcpy(&addr_refid, digest, 4);
103	return (htonl(addr_refid));
104}
105