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