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 */ 25int 26MD5authencrypt( 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 */ 57int 58MD5authdecrypt( 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 */ 94u_int32 95addr2refid(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