freebsd_amp_hwpstate/libntp/a_md5encrypt.c

111 lines
2.5 KiB
C
Raw Normal View History

1999-12-09 13:01:21 +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"
#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
/*
* MD5authencrypt - generate message digest
1999-12-09 13:01:21 +00:00
*
* Returns length of MAC including key ID and digest.
1999-12-09 13:01:21 +00:00
*/
int
MD5authencrypt(
int type, /* hash algorithm */
u_char *key, /* key pointer */
1999-12-09 13:01:21 +00:00
u_int32 *pkt, /* packet pointer */
int length /* packet length */
1999-12-09 13:01:21 +00:00
)
{
u_char digest[EVP_MAX_MD_SIZE];
u_int len;
EVP_MD_CTX ctx;
1999-12-09 13:01:21 +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
*/
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
*
* Returns one if digest valid, zero if invalid.
1999-12-09 13:01:21 +00:00
*/
int
MD5authdecrypt(
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
)
{
u_char digest[EVP_MAX_MD_SIZE];
u_int len;
EVP_MD_CTX ctx;
1999-12-09 13:01:21 +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
*/
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);
}
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.
* The result is in network byte order.
2004-07-20 15:01:56 +00:00
*/
u_int32
addr2refid(sockaddr_u *addr)
2004-07-20 15:01:56 +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
if (IS_IPV4(addr))
return (NSRCADR(addr));
2004-07-20 15:01:56 +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));
EVP_DigestFinal(&ctx, digest, &len);
2004-07-20 15:01:56 +00:00
memcpy(&addr_refid, digest, 4);
return (addr_refid);
1999-12-09 13:01:21 +00:00
}