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 */ 33 int 34 MD5authencrypt( 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 */ 60 int 61 MD5authdecrypt( 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 */ 88 u_int32 89 addr2refid(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 (addr_refid); 104 } 105