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