1/*	$OpenBSD: chap_ms.c,v 1.9 2022/01/07 07:33:35 tb 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
59static u_int8_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
66static u_int8_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
73u_int8_t	 get7bits(u_int8_t *, int);
74void		 mschap_des_addparity(u_int8_t *, u_int8_t *);
75void		 mschap_des_encrypt(u_int8_t *, u_int8_t *, u_int8_t *);
76void		 mschap_challenge_response(u_int8_t *, u_int8_t *, u_int8_t *);
77
78u_int8_t
79get7bits(u_int8_t *in, int start)
80{
81	u_int	 word;
82
83	word = (u_int)in[start / 8] << 8;
84	word |= (u_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 */
92void
93mschap_des_addparity(u_int8_t *key, u_int8_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
107void
108mschap_des_encrypt(u_int8_t *clear, u_int8_t *key, u_int8_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
120void
121mschap_challenge_response(u_int8_t *challenge, u_int8_t *pwhash,
122    u_int8_t *response)
123{
124	u_int8_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
134void
135mschap_ntpassword_hash(u_int8_t *in, int inlen, u_int8_t *hash)
136{
137	EVP_MD_CTX	*ctx;
138	u_int		 mdlen;
139
140	ctx = EVP_MD_CTX_new();
141	EVP_DigestInit_ex(ctx, EVP_md4(), NULL);
142	EVP_DigestUpdate(ctx, in, inlen);
143	EVP_DigestFinal_ex(ctx, hash, &mdlen);
144	EVP_MD_CTX_free(ctx);
145}
146
147void
148mschap_challenge_hash(u_int8_t *peer_challenge, u_int8_t *auth_challenge,
149    u_int8_t *username, int usernamelen, u_int8_t *challenge)
150{
151	EVP_MD_CTX	*ctx;
152	u_int8_t	 md[SHA_DIGEST_LENGTH];
153	u_int		 mdlen;
154	u_int8_t	*name;
155
156	if ((name = strrchr(username, '\\')) == NULL)
157		name = username;
158	else
159		name++;
160
161	ctx = EVP_MD_CTX_new();
162	EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
163	EVP_DigestUpdate(ctx, peer_challenge, MSCHAPV2_CHALLENGE_SZ);
164	EVP_DigestUpdate(ctx, auth_challenge, MSCHAPV2_CHALLENGE_SZ);
165	EVP_DigestUpdate(ctx, name, strlen(name));
166	EVP_DigestFinal_ex(ctx, md, &mdlen);
167	EVP_MD_CTX_free(ctx);
168
169	memcpy(challenge, md, MSCHAP_CHALLENGE_SZ);
170}
171
172void
173mschap_nt_response(u_int8_t *auth_challenge, u_int8_t *peer_challenge,
174    u_int8_t *username, int usernamelen, u_int8_t *password, int passwordlen,
175    u_int8_t *response)
176{
177	u_int8_t challenge[MSCHAP_CHALLENGE_SZ];
178	u_int8_t password_hash[MSCHAP_HASH_SZ];
179
180	mschap_challenge_hash(peer_challenge, auth_challenge,
181	    username, usernamelen, challenge);
182
183	mschap_ntpassword_hash(password, passwordlen, password_hash);
184	mschap_challenge_response(challenge, password_hash, response);
185}
186
187void
188mschap_auth_response(u_int8_t *password, int passwordlen,
189    u_int8_t *ntresponse, u_int8_t *auth_challenge, u_int8_t *peer_challenge,
190    u_int8_t *username, int usernamelen, u_int8_t *auth_response)
191{
192	EVP_MD_CTX	*ctx;
193	u_int8_t	 password_hash[MSCHAP_HASH_SZ];
194	u_int8_t	 password_hash2[MSCHAP_HASH_SZ];
195	u_int8_t	 challenge[MSCHAP_CHALLENGE_SZ];
196	u_int8_t	 md[SHA_DIGEST_LENGTH], *ptr;
197	u_int		 mdlen;
198	int		 i;
199	const u_int8_t	 hex[] = "0123456789ABCDEF";
200	static u_int8_t	 magic1[39] = {
201		0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
202		0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
203		0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
204		0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
205	};
206	static u_int8_t	 magic2[41] = {
207		0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
208		0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
209		0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
210		0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
211		0x6E
212	};
213
214	mschap_ntpassword_hash(password, passwordlen, password_hash);
215	mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
216
217	ctx = EVP_MD_CTX_new();
218	EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
219	EVP_DigestUpdate(ctx, password_hash2, sizeof(password_hash2));
220	EVP_DigestUpdate(ctx, ntresponse, 24);
221	EVP_DigestUpdate(ctx, magic1, 39);
222	EVP_DigestFinal_ex(ctx, md, &mdlen);
223
224	mschap_challenge_hash(peer_challenge, auth_challenge,
225	    username, usernamelen, challenge);
226
227	EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
228	EVP_DigestUpdate(ctx, md, sizeof(md));
229	EVP_DigestUpdate(ctx, challenge, sizeof(challenge));
230	EVP_DigestUpdate(ctx, magic2, 41);
231	EVP_DigestFinal_ex(ctx, md, &mdlen);
232	EVP_MD_CTX_free(ctx);
233
234	/*
235	 * Encode the value of 'Digest' as "S=" followed by
236	 * 40 ASCII hexadecimal digits and return it in
237	 * AuthenticatorResponse.
238	 * For example,
239	 *   "S=0123456789ABCDEF0123456789ABCDEF01234567"
240	 */
241	ptr = auth_response;
242	*ptr++ = 'S';
243	*ptr++ = '=';
244	for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
245		*ptr++ = hex[md[i] >> 4];
246		*ptr++ = hex[md[i] & 0x0f];
247	}
248}
249
250void
251mschap_masterkey(u_int8_t *password_hash2, u_int8_t *ntresponse,
252    u_int8_t *masterkey)
253{
254	u_int8_t	 md[SHA_DIGEST_LENGTH];
255	u_int		 mdlen;
256	EVP_MD_CTX	*ctx;
257	static u_int8_t	 magic1[27] = {
258		0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
259		0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
260		0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
261	};
262
263	ctx = EVP_MD_CTX_new();
264	EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
265	EVP_DigestUpdate(ctx, password_hash2, MSCHAP_HASH_SZ);
266	EVP_DigestUpdate(ctx, ntresponse, 24);
267	EVP_DigestUpdate(ctx, magic1, 27);
268	EVP_DigestFinal_ex(ctx, md, &mdlen);
269	EVP_MD_CTX_free(ctx);
270
271	memcpy(masterkey, md, 16);
272}
273
274void
275mschap_asymetric_startkey(u_int8_t *masterkey, u_int8_t *sessionkey,
276    int sessionkeylen, int issend, int isserver)
277{
278	EVP_MD_CTX	*ctx;
279	u_int8_t	 md[SHA_DIGEST_LENGTH];
280	u_int		 mdlen;
281	u_int8_t	*s;
282	static u_int8_t	 magic2[84] = {
283		0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
284		0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
285		0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
286		0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
287		0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
288		0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
289		0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
290		0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
291		0x6b, 0x65, 0x79, 0x2e
292	};
293	static u_int8_t	 magic3[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, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
298		0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
299		0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
300		0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
301		0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
302		0x6b, 0x65, 0x79, 0x2e
303	};
304
305	if (issend)
306		s = isserver ? magic3 : magic2;
307	else
308		s = isserver ? magic2 : magic3;
309
310	ctx = EVP_MD_CTX_new();
311	EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
312	EVP_DigestUpdate(ctx, masterkey, 16);
313	EVP_DigestUpdate(ctx, sha1_pad1, 40);
314	EVP_DigestUpdate(ctx, s, 84);
315	EVP_DigestUpdate(ctx, sha1_pad2, 40);
316	EVP_DigestFinal_ex(ctx, md, &mdlen);
317	EVP_MD_CTX_free(ctx);
318
319	memcpy(sessionkey, md, sessionkeylen);
320}
321
322void
323mschap_msk(u_int8_t *password, int passwordlen,
324    u_int8_t *ntresponse, u_int8_t *msk)
325{
326	u_int8_t	 password_hash[MSCHAP_HASH_SZ];
327	u_int8_t	 password_hash2[MSCHAP_HASH_SZ];
328	u_int8_t	 masterkey[MSCHAP_MASTERKEY_SZ];
329	u_int8_t	 sendkey[MSCHAP_MASTERKEY_SZ];
330	u_int8_t	 recvkey[MSCHAP_MASTERKEY_SZ];
331
332	mschap_ntpassword_hash(password, passwordlen, password_hash);
333	mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
334
335	mschap_masterkey(password_hash2, ntresponse, masterkey);
336	mschap_asymetric_startkey(masterkey, recvkey, sizeof(recvkey), 0, 1);
337	mschap_asymetric_startkey(masterkey, sendkey, sizeof(sendkey), 1, 1);
338
339	/* 16 bytes receive key + 16 bytes send key + 32 bytes 0 padding */
340	bzero(msk, MSCHAP_MSK_SZ);
341	memcpy(msk, &recvkey, sizeof(recvkey));
342	memcpy(msk + sizeof(recvkey), &sendkey, sizeof(sendkey));
343}
344
345void
346mschap_radiuskey(u_int8_t *plain, const u_int8_t *encrypted,
347    const u_int8_t *authenticator, const u_int8_t *secret)
348{
349	EVP_MD_CTX	*ctx;
350	u_int8_t	 b[MD5_DIGEST_LENGTH], p[32];
351	u_int		 i, mdlen;
352
353	ctx = EVP_MD_CTX_new();
354	EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
355	EVP_DigestUpdate(ctx, secret, strlen(secret));
356	EVP_DigestUpdate(ctx, authenticator, 16);
357	EVP_DigestUpdate(ctx, encrypted, 2);
358	EVP_DigestFinal_ex(ctx, b, &mdlen);
359
360	for (i = 0; i < mdlen; i++) {
361		p[i] = b[i] ^ encrypted[i+2];
362	}
363
364	EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
365	EVP_DigestUpdate(ctx, secret, strlen(secret));
366	EVP_DigestUpdate(ctx, encrypted + 2, mdlen);
367	EVP_DigestFinal_ex(ctx, b, &mdlen);
368	EVP_MD_CTX_free(ctx);
369
370	for (i = 0; i < mdlen; i++) {
371		p[i+16] = b[i] ^ encrypted[i+18];
372	}
373
374	memcpy(plain, p+1, 16);
375}
376