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 #include "ntp_machine.h" 12 13 #ifdef HAVE_CONFIG_H 14 #include <config.h> 15 #endif 16 17 #ifdef MD5 18 #include <stdio.h> 19 20 #include "ntp_types.h" 21 #include "ntp_fp.h" 22 #include "ntp_string.h" 23 #include "global.h" 24 #include "md5.h" 25 #include "ntp_stdlib.h" 26 27 #define BLOCK_OCTETS 16 /* message digest size */ 28 #define NTP_MAXKEY 65535 /* max identifier from ntp.h */ 29 30 31 /* 32 * MD5authencrypt - generate MD5 message authenticator 33 * 34 * Returns length of authenticator field. 35 */ 36 int 37 MD5authencrypt( 38 u_char *key, /* key pointer */ 39 u_int32 *pkt, /* packet pointer */ 40 int length /* packet length */ 41 ) 42 { 43 MD5_CTX ctx; 44 u_char digest[BLOCK_OCTETS]; 45 int i; 46 47 /* 48 * MD5 with key identifier concatenated with packet. 49 */ 50 MD5Init(&ctx); 51 MD5Update(&ctx, key, (u_int)cache_keylen); 52 MD5Update(&ctx, (u_char *)pkt, (u_int)length); 53 MD5Final(digest, &ctx); 54 i = length / 4; 55 memmove((char *)&pkt[i + 1], (char *)digest, BLOCK_OCTETS); 56 return (BLOCK_OCTETS + 4); 57 } 58 59 60 /* 61 * MD5authdecrypt - verify MD5 message authenticator 62 * 63 * Returns one if authenticator valid, zero if invalid. 64 */ 65 int 66 MD5authdecrypt( 67 u_char *key, /* key pointer */ 68 u_int32 *pkt, /* packet pointer */ 69 int length, /* packet length */ 70 int size /* MAC size */ 71 ) 72 { 73 MD5_CTX ctx; 74 u_char digest[BLOCK_OCTETS]; 75 76 /* 77 * MD5 with key identifier concatenated with packet. 78 */ 79 if (size != BLOCK_OCTETS + 4) 80 return (0); 81 MD5Init(&ctx); 82 MD5Update(&ctx, key, (u_int)cache_keylen); 83 MD5Update(&ctx, (u_char *)pkt, (u_int)length); 84 MD5Final(digest, &ctx); 85 return (!memcmp((char *)digest, (char *)pkt + length + 4, 86 BLOCK_OCTETS)); 87 } 88 89 90 /* 91 * session_key - generate session key from supplied plaintext. 92 * 93 * Returns hashed session key for validation. 94 */ 95 u_long 96 session_key( 97 u_int32 srcadr, /* source address */ 98 u_int32 dstadr, /* destination address */ 99 u_long keyno, /* key identifier */ 100 u_long lifetime /* key lifetime */ 101 ) 102 { 103 MD5_CTX ctx; 104 u_int32 header[3]; 105 u_long keyid; 106 u_char digest[BLOCK_OCTETS]; 107 108 /* 109 * Generate the session key and retrieve the hash for later. If 110 * the lifetime is greater than zero, call the key trusted. 111 */ 112 header[0] = htonl(srcadr); 113 header[1] = htonl(dstadr); 114 header[2] = htonl(keyno); 115 MD5Init(&ctx); 116 MD5Update(&ctx, (u_char *)header, sizeof(header)); 117 MD5Final(digest, &ctx); 118 memcpy(&keyid, digest, 4); 119 if (lifetime != 0) { 120 MD5auth_setkey(keyno, digest, BLOCK_OCTETS); 121 authtrust(keyno, (int)lifetime); 122 } 123 #ifdef DEBUG 124 if (debug > 1) 125 printf( 126 "session_key: from %s to %s keyid %08lx hash %08lx life %ld\n", 127 numtoa(htonl(srcadr)), numtoa(htonl(dstadr)), keyno, 128 keyid, lifetime); 129 #endif 130 return (keyid); 131 } 132 #endif /* MD5 */ 133