xref: /openbsd/sbin/iked/chap_ms.c (revision 5af055cd)
1 /*	$OpenBSD: chap_ms.c,v 1.9 2015/08/21 11:59:27 reyk Exp $	*/
2 
3 /*
4  * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
5  * Copyright (c) 1997-2001 Brian Somers <brian@Awfulhak.org>
6  * Copyright (c) 1997 Gabor Kincses <gabor@acm.org>
7  * Copyright (c) 1995 Eric Rosenquist
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31   */
32 
33 #include <sys/types.h>
34 
35 #include <ctype.h>
36 #include <string.h>
37 #include <stdio.h>
38 
39 #include <openssl/evp.h>
40 #include <openssl/des.h>
41 #include <openssl/md4.h>
42 #include <openssl/md5.h>
43 #include <openssl/sha.h>
44 
45 #include "chap_ms.h"
46 
47 /*
48  * Documentation & specifications:
49  *
50  * MS-CHAP (CHAP80)	RFC2433
51  * MS-CHAP-V2 (CHAP81)	RFC2759
52  * MPPE key management	RFC3079
53  *
54  * Security analysis:
55  * Schneier/Mudge/Wagner, "MS-CHAP-v2", Oct 99
56  * "It is unclear to us why this protocol is so complicated."
57  */
58 
59 static uint8_t sha1_pad1[40] = {
60 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
64 };
65 
66 static uint8_t sha1_pad2[40] = {
67 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
68 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
69 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
70 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
71 };
72 
73 uint8_t		 get7bits(uint8_t *, int);
74 void		 mschap_des_addparity(uint8_t *, uint8_t *);
75 void		 mschap_des_encrypt(uint8_t *, uint8_t *, uint8_t *);
76 void		 mschap_challenge_response(uint8_t *, uint8_t *, uint8_t *);
77 
78 uint8_t
79 get7bits(uint8_t *in, int start)
80 {
81 	unsigned int	 word;
82 
83 	word = (unsigned int)in[start / 8] << 8;
84 	word |= (unsigned int)in[start / 8 + 1];
85 	word >>= 15 - (start % 8 + 7);
86 
87 	return (word & 0xfe);
88 }
89 
90 /* IN  56 bit DES key missing parity bits
91    OUT 64 bit DES key with parity bits added */
92 void
93 mschap_des_addparity(uint8_t *key, uint8_t *des_key)
94 {
95 	des_key[0] = get7bits(key,  0);
96 	des_key[1] = get7bits(key,  7);
97 	des_key[2] = get7bits(key, 14);
98 	des_key[3] = get7bits(key, 21);
99 	des_key[4] = get7bits(key, 28);
100 	des_key[5] = get7bits(key, 35);
101 	des_key[6] = get7bits(key, 42);
102 	des_key[7] = get7bits(key, 49);
103 
104 	DES_set_odd_parity((DES_cblock *)des_key);
105 }
106 
107 void
108 mschap_des_encrypt(uint8_t *clear, uint8_t *key, uint8_t *cipher)
109 {
110 	DES_cblock		des_key;
111 	DES_key_schedule	key_schedule;
112 
113 	mschap_des_addparity(key, des_key);
114 
115 	DES_set_key(&des_key, &key_schedule);
116 	DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher,
117 	    &key_schedule, 1);
118 }
119 
120 void
121 mschap_challenge_response(uint8_t *challenge, uint8_t *pwhash,
122     uint8_t *response)
123 {
124 	uint8_t		 padpwhash[21 + 1];
125 
126 	bzero(&padpwhash, sizeof(padpwhash));
127 	memcpy(padpwhash, pwhash, MSCHAP_HASH_SZ);
128 
129 	mschap_des_encrypt(challenge, padpwhash + 0, response + 0);
130 	mschap_des_encrypt(challenge, padpwhash + 7, response + 8);
131 	mschap_des_encrypt(challenge, padpwhash + 14, response + 16);
132 }
133 
134 void
135 mschap_ntpassword_hash(uint8_t *in, int inlen, uint8_t *hash)
136 {
137 	EVP_MD_CTX	 ctx;
138 	unsigned int	 mdlen;
139 
140 	EVP_DigestInit(&ctx, EVP_md4());
141 	EVP_DigestUpdate(&ctx, in, inlen);
142 	EVP_DigestFinal(&ctx, hash, &mdlen);
143 }
144 
145 void
146 mschap_challenge_hash(uint8_t *peer_challenge, uint8_t *auth_challenge,
147     uint8_t *username, int usernamelen, uint8_t *challenge)
148 {
149 	EVP_MD_CTX	 ctx;
150 	uint8_t		 md[SHA_DIGEST_LENGTH];
151 	unsigned int	 mdlen;
152 	uint8_t		*name;
153 
154 	if ((name = strrchr(username, '\\')) == NULL)
155 		name = username;
156 	else
157 		name++;
158 
159 	EVP_DigestInit(&ctx, EVP_sha1());
160 	EVP_DigestUpdate(&ctx, peer_challenge, MSCHAPV2_CHALLENGE_SZ);
161 	EVP_DigestUpdate(&ctx, auth_challenge, MSCHAPV2_CHALLENGE_SZ);
162 	EVP_DigestUpdate(&ctx, name, strlen(name));
163 	EVP_DigestFinal(&ctx, md, &mdlen);
164 
165 	memcpy(challenge, md, MSCHAP_CHALLENGE_SZ);
166 }
167 
168 void
169 mschap_nt_response(uint8_t *auth_challenge, uint8_t *peer_challenge,
170     uint8_t *username, int usernamelen, uint8_t *password, int passwordlen,
171     uint8_t *response)
172 {
173 	uint8_t		 challenge[MSCHAP_CHALLENGE_SZ];
174 	uint8_t		 password_hash[MSCHAP_HASH_SZ];
175 
176 	mschap_challenge_hash(peer_challenge, auth_challenge,
177 	    username, usernamelen, challenge);
178 
179 	mschap_ntpassword_hash(password, passwordlen, password_hash);
180 	mschap_challenge_response(challenge, password_hash, response);
181 }
182 
183 void
184 mschap_auth_response(uint8_t *password, int passwordlen,
185     uint8_t *ntresponse, uint8_t *auth_challenge, uint8_t *peer_challenge,
186     uint8_t *username, int usernamelen, uint8_t *auth_response)
187 {
188 	EVP_MD_CTX	 ctx;
189 	uint8_t		 password_hash[MSCHAP_HASH_SZ];
190 	uint8_t		 password_hash2[MSCHAP_HASH_SZ];
191 	uint8_t		 challenge[MSCHAP_CHALLENGE_SZ];
192 	uint8_t		 md[SHA_DIGEST_LENGTH], *ptr;
193 	unsigned int	 mdlen;
194 	int		 i;
195 	const uint8_t	 hex[] = "0123456789ABCDEF";
196 	static uint8_t	 magic1[39] = {
197 		0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
198 		0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
199 		0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
200 		0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
201 	};
202 	static uint8_t	 magic2[41] = {
203 		0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
204 		0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
205 		0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
206 		0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
207 		0x6E
208 	};
209 
210 	mschap_ntpassword_hash(password, passwordlen, password_hash);
211 	mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
212 
213 	EVP_DigestInit(&ctx, EVP_sha1());
214 	EVP_DigestUpdate(&ctx, password_hash2, sizeof(password_hash2));
215 	EVP_DigestUpdate(&ctx, ntresponse, 24);
216 	EVP_DigestUpdate(&ctx, magic1, 39);
217 	EVP_DigestFinal(&ctx, md, &mdlen);
218 
219 	mschap_challenge_hash(peer_challenge, auth_challenge,
220 	    username, usernamelen, challenge);
221 
222 	EVP_DigestInit(&ctx, EVP_sha1());
223 	EVP_DigestUpdate(&ctx, md, sizeof(md));
224 	EVP_DigestUpdate(&ctx, challenge, sizeof(challenge));
225 	EVP_DigestUpdate(&ctx, magic2, 41);
226 	EVP_DigestFinal(&ctx, md, &mdlen);
227 
228 	/*
229 	 * Encode the value of 'Digest' as "S=" followed by
230 	 * 40 ASCII hexadecimal digits and return it in
231 	 * AuthenticatorResponse.
232 	 * For example,
233 	 *   "S=0123456789ABCDEF0123456789ABCDEF01234567"
234 	 */
235 	ptr = auth_response;
236 	*ptr++ = 'S';
237 	*ptr++ = '=';
238 	for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
239 		*ptr++ = hex[md[i] >> 4];
240 		*ptr++ = hex[md[i] & 0x0f];
241 	}
242 }
243 
244 void
245 mschap_masterkey(uint8_t *password_hash2, uint8_t *ntresponse,
246     uint8_t *masterkey)
247 {
248 	uint8_t		 md[SHA_DIGEST_LENGTH];
249 	unsigned int	 mdlen;
250 	EVP_MD_CTX	 ctx;
251 	static uint8_t	 magic1[27] = {
252 		0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
253 		0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
254 		0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
255 	};
256 
257 	EVP_DigestInit(&ctx, EVP_sha1());
258 	EVP_DigestUpdate(&ctx, password_hash2, MSCHAP_HASH_SZ);
259 	EVP_DigestUpdate(&ctx, ntresponse, 24);
260 	EVP_DigestUpdate(&ctx, magic1, 27);
261 	EVP_DigestFinal(&ctx, md, &mdlen);
262 
263 	memcpy(masterkey, md, 16);
264 }
265 
266 void
267 mschap_asymetric_startkey(uint8_t *masterkey, uint8_t *sessionkey,
268     int sessionkeylen, int issend, int isserver)
269 {
270 	EVP_MD_CTX	 ctx;
271 	uint8_t		 md[SHA_DIGEST_LENGTH];
272 	unsigned int	 mdlen;
273 	uint8_t		*s;
274 	static uint8_t	 magic2[84] = {
275 		0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
276 		0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
277 		0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
278 		0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
279 		0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
280 		0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
281 		0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
282 		0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
283 		0x6b, 0x65, 0x79, 0x2e
284 	};
285 	static uint8_t	 magic3[84] = {
286 		0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
287 		0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
288 		0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
289 		0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
290 		0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
291 		0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
292 		0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
293 		0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
294 		0x6b, 0x65, 0x79, 0x2e
295 	};
296 
297 	if (issend)
298 		s = isserver ? magic3 : magic2;
299 	else
300 		s = isserver ? magic2 : magic3;
301 
302 	EVP_DigestInit(&ctx, EVP_sha1());
303 	EVP_DigestUpdate(&ctx, masterkey, 16);
304 	EVP_DigestUpdate(&ctx, sha1_pad1, 40);
305 	EVP_DigestUpdate(&ctx, s, 84);
306 	EVP_DigestUpdate(&ctx, sha1_pad2, 40);
307 	EVP_DigestFinal(&ctx, md, &mdlen);
308 
309 	memcpy(sessionkey, md, sessionkeylen);
310 }
311 
312 void
313 mschap_msk(uint8_t *password, int passwordlen,
314     uint8_t *ntresponse, uint8_t *msk)
315 {
316 	uint8_t		 password_hash[MSCHAP_HASH_SZ];
317 	uint8_t		 password_hash2[MSCHAP_HASH_SZ];
318 	uint8_t		 masterkey[MSCHAP_MASTERKEY_SZ];
319 	uint8_t		 sendkey[MSCHAP_MASTERKEY_SZ];
320 	uint8_t		 recvkey[MSCHAP_MASTERKEY_SZ];
321 
322 	mschap_ntpassword_hash(password, passwordlen, password_hash);
323 	mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
324 
325 	mschap_masterkey(password_hash2, ntresponse, masterkey);
326 	mschap_asymetric_startkey(masterkey, recvkey, sizeof(recvkey), 0, 1);
327 	mschap_asymetric_startkey(masterkey, sendkey, sizeof(sendkey), 1, 1);
328 
329 	/* 16 bytes receive key + 16 bytes send key + 32 bytes 0 padding */
330 	bzero(msk, MSCHAP_MSK_SZ);
331 	memcpy(msk, &recvkey, sizeof(recvkey));
332 	memcpy(msk + sizeof(recvkey), &sendkey, sizeof(sendkey));
333 }
334 
335 void
336 mschap_radiuskey(uint8_t *plain, const uint8_t *crypted,
337     const uint8_t *authenticator, const uint8_t *secret)
338 {
339 	EVP_MD_CTX	 ctx;
340 	uint8_t		 b[MD5_DIGEST_LENGTH], p[32];
341 	unsigned int	 i, mdlen;
342 
343 	EVP_DigestInit(&ctx, EVP_md5());
344 	EVP_DigestUpdate(&ctx, secret, strlen(secret));
345 	EVP_DigestUpdate(&ctx, authenticator, 16);
346 	EVP_DigestUpdate(&ctx, crypted, 2);
347 	EVP_DigestFinal(&ctx, b, &mdlen);
348 
349 	for (i = 0; i < mdlen; i++) {
350 		p[i] = b[i] ^ crypted[i+2];
351 	}
352 
353 	EVP_DigestInit(&ctx, EVP_md5());
354 	EVP_DigestUpdate(&ctx, secret, strlen(secret));
355 	EVP_DigestUpdate(&ctx, crypted + 2, mdlen);
356 	EVP_DigestFinal(&ctx, b, &mdlen);
357 
358 	for (i = 0; i < mdlen; i++) {
359 		p[i+16] = b[i] ^ crypted[i+18];
360 	}
361 
362 	memcpy(plain, p+1, 16);
363 }
364