Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / libntp / a_md5encrypt.c
blob7ee57b27dbacf12737f59933ced0427d37f690eb
1 /* $NetBSD$ */
3 /*
4 * digest support for NTP, MD5 and with OpenSSL more
5 */
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
10 #include "ntp_fp.h"
11 #include "ntp_string.h"
12 #include "ntp_stdlib.h"
13 #include "ntp.h"
14 #ifdef OPENSSL
15 #include "openssl/evp.h"
16 #else
17 #include "ntp_md5.h"
18 #endif /* OPENSSSL */
21 * MD5authencrypt - generate message digest
23 * Returns length of MAC including key ID and digest.
25 int
26 MD5authencrypt(
27 int type, /* hash algorithm */
28 u_char *key, /* key pointer */
29 u_int32 *pkt, /* packet pointer */
30 int length /* packet length */
33 u_char digest[EVP_MAX_MD_SIZE];
34 u_int len;
35 #ifdef OPENSSL
36 EVP_MD_CTX ctx;
37 #else
38 MD5_CTX md5;
39 #endif /* OPENSSL */
42 * Compute digest of key concatenated with packet. Note: the
43 * key type and digest type have been verified when the key
44 * was creaded.
46 #ifdef OPENSSL
47 INIT_SSL();
48 EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
49 EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen);
50 EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
51 EVP_DigestFinal(&ctx, digest, &len);
52 #else /* OPENSSL */
53 MD5Init(&md5);
54 MD5Update(&md5, key, (u_int)cache_keylen);
55 MD5Update(&md5, (u_char *)pkt, (u_int)length);
56 MD5Final(digest, &md5);
57 len = 16;
58 #endif /* OPENSSL */
59 memmove((u_char *)pkt + length + 4, digest, len);
60 return (len + 4);
65 * MD5authdecrypt - verify MD5 message authenticator
67 * Returns one if digest valid, zero if invalid.
69 int
70 MD5authdecrypt(
71 int type, /* hash algorithm */
72 u_char *key, /* key pointer */
73 u_int32 *pkt, /* packet pointer */
74 int length, /* packet length */
75 int size /* MAC size */
78 u_char digest[EVP_MAX_MD_SIZE];
79 u_int len;
80 #ifdef OPENSSL
81 EVP_MD_CTX ctx;
82 #else
83 MD5_CTX md5;
84 #endif /* OPENSSL */
87 * Compute digest of key concatenated with packet. Note: the
88 * key type and digest type have been verified when the key
89 * was created.
91 #ifdef OPENSSL
92 INIT_SSL();
93 EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
94 EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen);
95 EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
96 EVP_DigestFinal(&ctx, digest, &len);
97 #else /* OPENSSL */
98 MD5Init(&md5);
99 MD5Update(&md5, key, (u_int)cache_keylen);
100 MD5Update(&md5, (u_char *)pkt, (u_int)length);
101 MD5Final(digest, &md5);
102 len = 16;
103 #endif /* OPENSSL */
104 if ((u_int)size != len + 4) {
105 msyslog(LOG_ERR,
106 "MAC decrypt: MAC length error");
107 return (0);
109 return (!memcmp(digest, (char *)pkt + length + 4, len));
113 * Calculate the reference id from the address. If it is an IPv4
114 * address, use it as is. If it is an IPv6 address, do a md5 on
115 * it and use the bottom 4 bytes.
117 u_int32
118 addr2refid(sockaddr_u *addr)
120 u_char digest[20];
121 u_int32 addr_refid;
122 #ifdef OPENSSL
123 EVP_MD_CTX ctx;
124 u_int len;
125 #else
126 MD5_CTX md5;
127 #endif /* OPENSSL */
129 if (IS_IPV4(addr))
130 return (NSRCADR(addr));
132 #ifdef OPENSSL
133 INIT_SSL();
134 EVP_DigestInit(&ctx, EVP_get_digestbynid(NID_md5));
135 EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr),
136 sizeof(struct in6_addr));
137 EVP_DigestFinal(&ctx, digest, &len);
138 #else
139 MD5Init(&md5);
140 MD5Update(&md5, (u_char *)PSOCK_ADDR6(addr),
141 sizeof(struct in6_addr));
142 MD5Final(digest, &md5);
143 #endif /* OPENSSL */
144 memcpy(&addr_refid, digest, 4);
145 return (addr_refid);