xref: /openbsd-src/sbin/iked/chap_ms.c (revision 08c24fdd6abd7a4c82cb96d2b3e6778a0ffceb07)
1 /*	$OpenBSD: chap_ms.c,v 1.10 2021/02/04 19:59:15 tobhe 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 extern __dead void fatalx(const char *, ...)
48 	    __attribute__((__format__ (printf, 1, 2)));
49 
50 /*
51  * Documentation & specifications:
52  *
53  * MS-CHAP (CHAP80)	RFC2433
54  * MS-CHAP-V2 (CHAP81)	RFC2759
55  * MPPE key management	RFC3079
56  *
57  * Security analysis:
58  * Schneier/Mudge/Wagner, "MS-CHAP-v2", Oct 99
59  * "It is unclear to us why this protocol is so complicated."
60  */
61 
62 static uint8_t sha1_pad1[40] = {
63 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
67 };
68 
69 static uint8_t sha1_pad2[40] = {
70 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
71 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
72 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
73 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
74 };
75 
76 uint8_t		 get7bits(uint8_t *, int);
77 void		 mschap_des_addparity(uint8_t *, uint8_t *);
78 void		 mschap_des_encrypt(uint8_t *, uint8_t *, uint8_t *);
79 void		 mschap_challenge_response(uint8_t *, uint8_t *, uint8_t *);
80 
81 uint8_t
get7bits(uint8_t * in,int start)82 get7bits(uint8_t *in, int start)
83 {
84 	unsigned int	 word;
85 
86 	word = (unsigned int)in[start / 8] << 8;
87 	word |= (unsigned int)in[start / 8 + 1];
88 	word >>= 15 - (start % 8 + 7);
89 
90 	return (word & 0xfe);
91 }
92 
93 /* IN  56 bit DES key missing parity bits
94    OUT 64 bit DES key with parity bits added */
95 void
mschap_des_addparity(uint8_t * key,uint8_t * des_key)96 mschap_des_addparity(uint8_t *key, uint8_t *des_key)
97 {
98 	des_key[0] = get7bits(key,  0);
99 	des_key[1] = get7bits(key,  7);
100 	des_key[2] = get7bits(key, 14);
101 	des_key[3] = get7bits(key, 21);
102 	des_key[4] = get7bits(key, 28);
103 	des_key[5] = get7bits(key, 35);
104 	des_key[6] = get7bits(key, 42);
105 	des_key[7] = get7bits(key, 49);
106 
107 	DES_set_odd_parity((DES_cblock *)des_key);
108 }
109 
110 void
mschap_des_encrypt(uint8_t * clear,uint8_t * key,uint8_t * cipher)111 mschap_des_encrypt(uint8_t *clear, uint8_t *key, uint8_t *cipher)
112 {
113 	DES_cblock		des_key;
114 	DES_key_schedule	key_schedule;
115 
116 	mschap_des_addparity(key, des_key);
117 
118 	DES_set_key(&des_key, &key_schedule);
119 	DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher,
120 	    &key_schedule, 1);
121 }
122 
123 void
mschap_challenge_response(uint8_t * challenge,uint8_t * pwhash,uint8_t * response)124 mschap_challenge_response(uint8_t *challenge, uint8_t *pwhash,
125     uint8_t *response)
126 {
127 	uint8_t		 padpwhash[21 + 1];
128 
129 	bzero(&padpwhash, sizeof(padpwhash));
130 	memcpy(padpwhash, pwhash, MSCHAP_HASH_SZ);
131 
132 	mschap_des_encrypt(challenge, padpwhash + 0, response + 0);
133 	mschap_des_encrypt(challenge, padpwhash + 7, response + 8);
134 	mschap_des_encrypt(challenge, padpwhash + 14, response + 16);
135 }
136 
137 void
mschap_ntpassword_hash(uint8_t * in,int inlen,uint8_t * hash)138 mschap_ntpassword_hash(uint8_t *in, int inlen, uint8_t *hash)
139 {
140 	EVP_MD_CTX	 *ctx;
141 	unsigned int	 mdlen;
142 
143 	ctx = EVP_MD_CTX_new();
144 	if (ctx == NULL)
145 		fatalx("%s: EVP_MD_CTX_NEW()", __func__);
146 	EVP_DigestInit(ctx, EVP_md4());
147 	EVP_DigestUpdate(ctx, in, inlen);
148 	EVP_DigestFinal(ctx, hash, &mdlen);
149 	EVP_MD_CTX_free(ctx);
150 }
151 
152 void
mschap_challenge_hash(uint8_t * peer_challenge,uint8_t * auth_challenge,uint8_t * username,int usernamelen,uint8_t * challenge)153 mschap_challenge_hash(uint8_t *peer_challenge, uint8_t *auth_challenge,
154     uint8_t *username, int usernamelen, uint8_t *challenge)
155 {
156 	EVP_MD_CTX	*ctx;
157 	uint8_t		 md[SHA_DIGEST_LENGTH];
158 	unsigned int	 mdlen;
159 	uint8_t		*name;
160 
161 	if ((name = strrchr(username, '\\')) == NULL)
162 		name = username;
163 	else
164 		name++;
165 
166 	ctx = EVP_MD_CTX_new();
167 	if (ctx == NULL)
168 		fatalx("%s: EVP_MD_CTX_NEW()", __func__);
169 	EVP_DigestInit(ctx, EVP_sha1());
170 	EVP_DigestUpdate(ctx, peer_challenge, MSCHAPV2_CHALLENGE_SZ);
171 	EVP_DigestUpdate(ctx, auth_challenge, MSCHAPV2_CHALLENGE_SZ);
172 	EVP_DigestUpdate(ctx, name, strlen(name));
173 	EVP_DigestFinal(ctx, md, &mdlen);
174 	EVP_MD_CTX_free(ctx);
175 
176 	memcpy(challenge, md, MSCHAP_CHALLENGE_SZ);
177 }
178 
179 void
mschap_nt_response(uint8_t * auth_challenge,uint8_t * peer_challenge,uint8_t * username,int usernamelen,uint8_t * password,int passwordlen,uint8_t * response)180 mschap_nt_response(uint8_t *auth_challenge, uint8_t *peer_challenge,
181     uint8_t *username, int usernamelen, uint8_t *password, int passwordlen,
182     uint8_t *response)
183 {
184 	uint8_t		 challenge[MSCHAP_CHALLENGE_SZ];
185 	uint8_t		 password_hash[MSCHAP_HASH_SZ];
186 
187 	mschap_challenge_hash(peer_challenge, auth_challenge,
188 	    username, usernamelen, challenge);
189 
190 	mschap_ntpassword_hash(password, passwordlen, password_hash);
191 	mschap_challenge_response(challenge, password_hash, response);
192 }
193 
194 void
mschap_auth_response(uint8_t * password,int passwordlen,uint8_t * ntresponse,uint8_t * auth_challenge,uint8_t * peer_challenge,uint8_t * username,int usernamelen,uint8_t * auth_response)195 mschap_auth_response(uint8_t *password, int passwordlen,
196     uint8_t *ntresponse, uint8_t *auth_challenge, uint8_t *peer_challenge,
197     uint8_t *username, int usernamelen, uint8_t *auth_response)
198 {
199 	EVP_MD_CTX	*ctx;
200 	uint8_t		 password_hash[MSCHAP_HASH_SZ];
201 	uint8_t		 password_hash2[MSCHAP_HASH_SZ];
202 	uint8_t		 challenge[MSCHAP_CHALLENGE_SZ];
203 	uint8_t		 md[SHA_DIGEST_LENGTH], *ptr;
204 	unsigned int	 mdlen;
205 	int		 i;
206 	const uint8_t	 hex[] = "0123456789ABCDEF";
207 	static uint8_t	 magic1[39] = {
208 		0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
209 		0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
210 		0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
211 		0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
212 	};
213 	static uint8_t	 magic2[41] = {
214 		0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
215 		0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
216 		0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
217 		0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
218 		0x6E
219 	};
220 
221 	ctx = EVP_MD_CTX_new();
222 	if (ctx == NULL)
223 		fatalx("%s: EVP_MD_CTX_NEW()", __func__);
224 	mschap_ntpassword_hash(password, passwordlen, password_hash);
225 	mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
226 
227 	EVP_DigestInit(ctx, EVP_sha1());
228 	EVP_DigestUpdate(ctx, password_hash2, sizeof(password_hash2));
229 	EVP_DigestUpdate(ctx, ntresponse, 24);
230 	EVP_DigestUpdate(ctx, magic1, 39);
231 	EVP_DigestFinal(ctx, md, &mdlen);
232 
233 	mschap_challenge_hash(peer_challenge, auth_challenge,
234 	    username, usernamelen, challenge);
235 
236 	EVP_DigestInit(ctx, EVP_sha1());
237 	EVP_DigestUpdate(ctx, md, sizeof(md));
238 	EVP_DigestUpdate(ctx, challenge, sizeof(challenge));
239 	EVP_DigestUpdate(ctx, magic2, 41);
240 	EVP_DigestFinal(ctx, md, &mdlen);
241 	EVP_MD_CTX_free(ctx);
242 
243 	/*
244 	 * Encode the value of 'Digest' as "S=" followed by
245 	 * 40 ASCII hexadecimal digits and return it in
246 	 * AuthenticatorResponse.
247 	 * For example,
248 	 *   "S=0123456789ABCDEF0123456789ABCDEF01234567"
249 	 */
250 	ptr = auth_response;
251 	*ptr++ = 'S';
252 	*ptr++ = '=';
253 	for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
254 		*ptr++ = hex[md[i] >> 4];
255 		*ptr++ = hex[md[i] & 0x0f];
256 	}
257 }
258 
259 void
mschap_masterkey(uint8_t * password_hash2,uint8_t * ntresponse,uint8_t * masterkey)260 mschap_masterkey(uint8_t *password_hash2, uint8_t *ntresponse,
261     uint8_t *masterkey)
262 {
263 	uint8_t		 md[SHA_DIGEST_LENGTH];
264 	unsigned int	 mdlen;
265 	EVP_MD_CTX	*ctx;
266 	static uint8_t	 magic1[27] = {
267 		0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
268 		0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
269 		0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
270 	};
271 
272 	ctx = EVP_MD_CTX_new();
273 	if (ctx == NULL)
274 		fatalx("%s: EVP_MD_CTX_NEW()", __func__);
275 	EVP_DigestInit(ctx, EVP_sha1());
276 	EVP_DigestUpdate(ctx, password_hash2, MSCHAP_HASH_SZ);
277 	EVP_DigestUpdate(ctx, ntresponse, 24);
278 	EVP_DigestUpdate(ctx, magic1, 27);
279 	EVP_DigestFinal(ctx, md, &mdlen);
280 	EVP_MD_CTX_free(ctx);
281 
282 	memcpy(masterkey, md, 16);
283 }
284 
285 void
mschap_asymetric_startkey(uint8_t * masterkey,uint8_t * sessionkey,int sessionkeylen,int issend,int isserver)286 mschap_asymetric_startkey(uint8_t *masterkey, uint8_t *sessionkey,
287     int sessionkeylen, int issend, int isserver)
288 {
289 	EVP_MD_CTX	*ctx;
290 	uint8_t		 md[SHA_DIGEST_LENGTH];
291 	unsigned int	 mdlen;
292 	uint8_t		*s;
293 	static uint8_t	 magic2[84] = {
294 		0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
295 		0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
296 		0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
297 		0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
298 		0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
299 		0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
300 		0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
301 		0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
302 		0x6b, 0x65, 0x79, 0x2e
303 	};
304 	static uint8_t	 magic3[84] = {
305 		0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
306 		0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
307 		0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
308 		0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
309 		0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
310 		0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
311 		0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
312 		0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
313 		0x6b, 0x65, 0x79, 0x2e
314 	};
315 
316 	if (issend)
317 		s = isserver ? magic3 : magic2;
318 	else
319 		s = isserver ? magic2 : magic3;
320 
321 	ctx = EVP_MD_CTX_new();
322 	if (ctx == NULL)
323 		fatalx("%s: EVP_MD_CTX_NEW()", __func__);
324 	EVP_DigestInit(ctx, EVP_sha1());
325 	EVP_DigestUpdate(ctx, masterkey, 16);
326 	EVP_DigestUpdate(ctx, sha1_pad1, 40);
327 	EVP_DigestUpdate(ctx, s, 84);
328 	EVP_DigestUpdate(ctx, sha1_pad2, 40);
329 	EVP_DigestFinal(ctx, md, &mdlen);
330 	EVP_MD_CTX_free(ctx);
331 
332 	memcpy(sessionkey, md, sessionkeylen);
333 }
334 
335 void
mschap_msk(uint8_t * password,int passwordlen,uint8_t * ntresponse,uint8_t * msk)336 mschap_msk(uint8_t *password, int passwordlen,
337     uint8_t *ntresponse, uint8_t *msk)
338 {
339 	uint8_t		 password_hash[MSCHAP_HASH_SZ];
340 	uint8_t		 password_hash2[MSCHAP_HASH_SZ];
341 	uint8_t		 masterkey[MSCHAP_MASTERKEY_SZ];
342 	uint8_t		 sendkey[MSCHAP_MASTERKEY_SZ];
343 	uint8_t		 recvkey[MSCHAP_MASTERKEY_SZ];
344 
345 	mschap_ntpassword_hash(password, passwordlen, password_hash);
346 	mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
347 
348 	mschap_masterkey(password_hash2, ntresponse, masterkey);
349 	mschap_asymetric_startkey(masterkey, recvkey, sizeof(recvkey), 0, 1);
350 	mschap_asymetric_startkey(masterkey, sendkey, sizeof(sendkey), 1, 1);
351 
352 	/* 16 bytes receive key + 16 bytes send key + 32 bytes 0 padding */
353 	bzero(msk, MSCHAP_MSK_SZ);
354 	memcpy(msk, &recvkey, sizeof(recvkey));
355 	memcpy(msk + sizeof(recvkey), &sendkey, sizeof(sendkey));
356 }
357 
358 void
mschap_radiuskey(uint8_t * plain,const uint8_t * crypted,const uint8_t * authenticator,const uint8_t * secret)359 mschap_radiuskey(uint8_t *plain, const uint8_t *crypted,
360     const uint8_t *authenticator, const uint8_t *secret)
361 {
362 	EVP_MD_CTX	*ctx;
363 	uint8_t		 b[MD5_DIGEST_LENGTH], p[32];
364 	unsigned int	 i, mdlen;
365 
366 	ctx = EVP_MD_CTX_new();
367 	if (ctx == NULL)
368 		fatalx("%s: EVP_MD_CTX_NEW()", __func__);
369 	EVP_DigestInit(ctx, EVP_md5());
370 	EVP_DigestUpdate(ctx, secret, strlen(secret));
371 	EVP_DigestUpdate(ctx, authenticator, 16);
372 	EVP_DigestUpdate(ctx, crypted, 2);
373 	EVP_DigestFinal(ctx, b, &mdlen);
374 
375 	for (i = 0; i < mdlen; i++) {
376 		p[i] = b[i] ^ crypted[i+2];
377 	}
378 
379 	EVP_DigestInit(ctx, EVP_md5());
380 	EVP_DigestUpdate(ctx, secret, strlen(secret));
381 	EVP_DigestUpdate(ctx, crypted + 2, mdlen);
382 	EVP_DigestFinal(ctx, b, &mdlen);
383 	EVP_MD_CTX_free(ctx);
384 
385 	for (i = 0; i < mdlen; i++) {
386 		p[i+16] = b[i] ^ crypted[i+18];
387 	}
388 
389 	memcpy(plain, p+1, 16);
390 }
391