GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/iked/chap_ms.c Lines: 0 124 0.0 %
Date: 2017-11-13 Branches: 0 10 0.0 %

Line Branch Exec Source
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
}