1 /* $NetBSD: a_md5encrypt.c,v 1.1.1.2 2012/01/31 21:23:56 kardel Exp $ */ 2 3 /* 4 * digest support for NTP, MD5 and with OpenSSL more 5 */ 6 #ifdef HAVE_CONFIG_H 7 #include <config.h> 8 #endif 9 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" /* provides clone of OpenSSL MD5 API */ 18 #endif 19 20 /* 21 * MD5authencrypt - generate message digest 22 * 23 * Returns length of MAC including key ID and digest. 24 */ 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 */ 31 ) 32 { 33 u_char digest[EVP_MAX_MD_SIZE]; 34 u_int len; 35 EVP_MD_CTX ctx; 36 37 /* 38 * Compute digest of key concatenated with packet. Note: the 39 * key type and digest type have been verified when the key 40 * was creaded. 41 */ 42 INIT_SSL(); 43 EVP_DigestInit(&ctx, EVP_get_digestbynid(type)); 44 EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen); 45 EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length); 46 EVP_DigestFinal(&ctx, digest, &len); 47 memmove((u_char *)pkt + length + 4, digest, len); 48 return (len + 4); 49 } 50 51 52 /* 53 * MD5authdecrypt - verify MD5 message authenticator 54 * 55 * Returns one if digest valid, zero if invalid. 56 */ 57 int 58 MD5authdecrypt( 59 int type, /* hash algorithm */ 60 u_char *key, /* key pointer */ 61 u_int32 *pkt, /* packet pointer */ 62 int length, /* packet length */ 63 int size /* MAC size */ 64 ) 65 { 66 u_char digest[EVP_MAX_MD_SIZE]; 67 u_int len; 68 EVP_MD_CTX ctx; 69 70 /* 71 * Compute digest of key concatenated with packet. Note: the 72 * key type and digest type have been verified when the key 73 * was created. 74 */ 75 INIT_SSL(); 76 EVP_DigestInit(&ctx, EVP_get_digestbynid(type)); 77 EVP_DigestUpdate(&ctx, key, (u_int)cache_keylen); 78 EVP_DigestUpdate(&ctx, (u_char *)pkt, (u_int)length); 79 EVP_DigestFinal(&ctx, digest, &len); 80 if ((u_int)size != len + 4) { 81 msyslog(LOG_ERR, 82 "MAC decrypt: MAC length error"); 83 return (0); 84 } 85 return (!memcmp(digest, (char *)pkt + length + 4, len)); 86 } 87 88 /* 89 * Calculate the reference id from the address. If it is an IPv4 90 * address, use it as is. If it is an IPv6 address, do a md5 on 91 * it and use the bottom 4 bytes. 92 * The result is in network byte order. 93 */ 94 u_int32 95 addr2refid(sockaddr_u *addr) 96 { 97 u_char digest[20]; 98 u_int32 addr_refid; 99 EVP_MD_CTX ctx; 100 u_int len; 101 102 if (IS_IPV4(addr)) 103 return (NSRCADR(addr)); 104 105 INIT_SSL(); 106 EVP_DigestInit(&ctx, EVP_get_digestbynid(NID_md5)); 107 EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr), 108 sizeof(struct in6_addr)); 109 EVP_DigestFinal(&ctx, digest, &len); 110 memcpy(&addr_refid, digest, 4); 111 return (addr_refid); 112 } 113