a_md5encrypt.c revision 54359
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 */ 36int 37MD5authencrypt( 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 */ 65int 66MD5authdecrypt( 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 */ 95u_long 96session_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