1999-12-09 13:01:21 +00:00
|
|
|
/*
|
2013-12-04 21:33:17 +00:00
|
|
|
* digest support for NTP, MD5 and with OpenSSL more
|
1999-12-09 13:01:21 +00:00
|
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2004-07-20 15:01:56 +00:00
|
|
|
#include "ntp_fp.h"
|
1999-12-09 13:01:21 +00:00
|
|
|
#include "ntp_string.h"
|
|
|
|
#include "ntp_stdlib.h"
|
2004-07-20 15:01:56 +00:00
|
|
|
#include "ntp.h"
|
2013-12-04 21:33:17 +00:00
|
|
|
#ifdef OPENSSL
|
|
|
|
# include "openssl/evp.h"
|
|
|
|
#else
|
|
|
|
# include "ntp_md5.h" /* provides clone of OpenSSL MD5 API */
|
|
|
|
#endif
|
1999-12-09 13:01:21 +00:00
|
|
|
|
|
|
|
/*
|
2013-12-04 21:33:17 +00:00
|
|
|
* MD5authencrypt - generate message digest
|
1999-12-09 13:01:21 +00:00
|
|
|
*
|
2013-12-04 21:33:17 +00:00
|
|
|
* Returns length of MAC including key ID and digest.
|
1999-12-09 13:01:21 +00:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
MD5authencrypt(
|
2013-12-04 21:33:17 +00:00
|
|
|
int type, /* hash algorithm */
|
|
|
|
u_char *key, /* key pointer */
|
1999-12-09 13:01:21 +00:00
|
|
|
u_int32 *pkt, /* packet pointer */
|
2013-12-04 21:33:17 +00:00
|
|
|
int length /* packet length */
|
1999-12-09 13:01:21 +00:00
|
|
|
)
|
|
|
|
{
|
2013-12-04 21:33:17 +00:00
|
|
|
u_char digest[EVP_MAX_MD_SIZE];
|
|
|
|
u_int len;
|
|
|
|
EVP_MD_CTX ctx;
|
1999-12-09 13:01:21 +00:00
|
|
|
|
|
|
|
/*
|
2013-12-04 21:33:17 +00:00
|
|
|
* Compute digest of key concatenated with packet. Note: the
|
|
|
|
* key type and digest type have been verified when the key
|
|
|
|
* was creaded.
|
1999-12-09 13:01:21 +00:00
|
|
|
*/
|
2013-12-04 21:33:17 +00:00
|
|
|
INIT_SSL();
|
|
|
|
EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
|
|
|
|
EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen);
|
|
|
|
EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
|
|
|
|
EVP_DigestFinal(&ctx, digest, &len);
|
|
|
|
memmove((u_char *)pkt + length + 4, digest, len);
|
|
|
|
return (len + 4);
|
1999-12-09 13:01:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MD5authdecrypt - verify MD5 message authenticator
|
|
|
|
*
|
2013-12-04 21:33:17 +00:00
|
|
|
* Returns one if digest valid, zero if invalid.
|
1999-12-09 13:01:21 +00:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
MD5authdecrypt(
|
2013-12-04 21:33:17 +00:00
|
|
|
int type, /* hash algorithm */
|
|
|
|
u_char *key, /* key pointer */
|
|
|
|
u_int32 *pkt, /* packet pointer */
|
|
|
|
int length, /* packet length */
|
|
|
|
int size /* MAC size */
|
1999-12-09 13:01:21 +00:00
|
|
|
)
|
|
|
|
{
|
2013-12-04 21:33:17 +00:00
|
|
|
u_char digest[EVP_MAX_MD_SIZE];
|
|
|
|
u_int len;
|
|
|
|
EVP_MD_CTX ctx;
|
1999-12-09 13:01:21 +00:00
|
|
|
|
|
|
|
/*
|
2013-12-04 21:33:17 +00:00
|
|
|
* Compute digest of key concatenated with packet. Note: the
|
|
|
|
* key type and digest type have been verified when the key
|
|
|
|
* was created.
|
1999-12-09 13:01:21 +00:00
|
|
|
*/
|
2013-12-04 21:33:17 +00:00
|
|
|
INIT_SSL();
|
|
|
|
EVP_DigestInit(&ctx, EVP_get_digestbynid(type));
|
|
|
|
EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen);
|
|
|
|
EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length);
|
|
|
|
EVP_DigestFinal(&ctx, digest, &len);
|
|
|
|
if ((u_int)size != len + 4) {
|
|
|
|
msyslog(LOG_ERR,
|
|
|
|
"MAC decrypt: MAC length error");
|
1999-12-09 13:01:21 +00:00
|
|
|
return (0);
|
2013-12-04 21:33:17 +00:00
|
|
|
}
|
|
|
|
return (!memcmp(digest, (char *)pkt + length + 4, len));
|
2004-07-20 15:01:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate the reference id from the address. If it is an IPv4
|
|
|
|
* address, use it as is. If it is an IPv6 address, do a md5 on
|
|
|
|
* it and use the bottom 4 bytes.
|
2013-12-04 21:33:17 +00:00
|
|
|
* The result is in network byte order.
|
2004-07-20 15:01:56 +00:00
|
|
|
*/
|
|
|
|
u_int32
|
2013-12-04 21:33:17 +00:00
|
|
|
addr2refid(sockaddr_u *addr)
|
2004-07-20 15:01:56 +00:00
|
|
|
{
|
2013-12-04 21:33:17 +00:00
|
|
|
u_char digest[20];
|
|
|
|
u_int32 addr_refid;
|
|
|
|
EVP_MD_CTX ctx;
|
|
|
|
u_int len;
|
2004-07-20 15:01:56 +00:00
|
|
|
|
2013-12-04 21:33:17 +00:00
|
|
|
if (IS_IPV4(addr))
|
|
|
|
return (NSRCADR(addr));
|
2004-07-20 15:01:56 +00:00
|
|
|
|
2013-12-04 21:33:17 +00:00
|
|
|
INIT_SSL();
|
|
|
|
EVP_DigestInit(&ctx, EVP_get_digestbynid(NID_md5));
|
|
|
|
EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr),
|
2004-07-20 15:01:56 +00:00
|
|
|
sizeof(struct in6_addr));
|
2013-12-04 21:33:17 +00:00
|
|
|
EVP_DigestFinal(&ctx, digest, &len);
|
2004-07-20 15:01:56 +00:00
|
|
|
memcpy(&addr_refid, digest, 4);
|
2008-08-18 14:26:05 +00:00
|
|
|
return (addr_refid);
|
1999-12-09 13:01:21 +00:00
|
|
|
}
|