1/*
2 * Copyright (c) 2001-2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef _EAP8021X_MSCHAP_H
25#define _EAP8021X_MSCHAP_H
26
27#include <stdint.h>
28#include <stdbool.h>
29
30enum {
31    kMSCHAP2_ERROR_RESTRICTED_LOGON_HOURS = 646,
32    kMSCHAP2_ERROR_ACCT_DISABLED = 647,
33    kMSCHAP2_ERROR_PASSWD_EXPIRED= 648,
34    kMSCHAP2_ERROR_NO_DIALIN_PERMISSION = 649,
35    kMSCHAP2_ERROR_AUTHENTICATION_FAILURE = 691,
36    kMSCHAP2_ERROR_CHANGING_PASSWORD = 709
37};
38
39#define NT_MAXPWLEN			256 	/* unicode chars */
40#define NT_MASTER_KEY_SIZE		16
41#define NT_SESSION_KEY_SIZE		16
42#define NT_PASSWORD_HASH_SIZE		16
43
44#define MSCHAP_NT_CHALLENGE_SIZE	8
45#define MSCHAP_NT_RESPONSE_SIZE		24
46#define MSCHAP_LM_RESPONSE_SIZE		24
47#define MSCHAP_FLAGS_SIZE		1
48#define MSCHAP_IDENT_SIZE		1
49
50#define MSCHAP2_CHALLENGE_SIZE		16
51#define MSCHAP2_RESERVED_SIZE		8
52#define MSCHAP2_AUTH_RESPONSE_SIZE	42
53
54typedef struct {
55    uint8_t		peer_challenge[MSCHAP2_CHALLENGE_SIZE];
56    uint8_t		reserved[MSCHAP2_RESERVED_SIZE];
57    uint8_t		nt_response[MSCHAP_NT_RESPONSE_SIZE];
58    uint8_t		flags[MSCHAP_FLAGS_SIZE];
59} MSCHAP2Response, * MSCHAP2ResponseRef;
60
61#define MSCHAP2_RESPONSE_LENGTH		(MSCHAP2_CHALLENGE_SIZE \
62			 		 + MSCHAP2_RESERVED_SIZE \
63				 	 + MSCHAP_NT_RESPONSE_SIZE \
64					 + MSCHAP_FLAGS_SIZE)
65typedef struct NTPasswordBlock_s {
66    uint8_t		password[NT_MAXPWLEN * 2];
67    uint8_t		password_length[4];
68} NTPasswordBlock, * NTPasswordBlockRef;
69
70#define NT_PASSWORD_BLOCK_SIZE		sizeof(NTPasswordBlock)
71
72void
73MSChap(const uint8_t challenge[MSCHAP_NT_CHALLENGE_SIZE],
74       const uint8_t * password, uint32_t password_len,
75       uint8_t response[MSCHAP_NT_RESPONSE_SIZE]);
76
77void
78MSChap_MPPE(const uint8_t challenge[MSCHAP_NT_CHALLENGE_SIZE],
79	    const uint8_t * password, uint32_t password_len,
80	    uint8_t response[MSCHAP_NT_RESPONSE_SIZE]);
81
82void
83NTSessionKey16(const uint8_t * password, uint32_t password_len,
84	       const uint8_t client_challenge[MSCHAP_NT_CHALLENGE_SIZE],
85	       const uint8_t server_response[MSCHAP_NT_RESPONSE_SIZE],
86	       const uint8_t server_challenge[MSCHAP_NT_CHALLENGE_SIZE],
87	       uint8_t key[NT_SESSION_KEY_SIZE]);
88
89void
90MSChap2(const uint8_t authenticator_challenge[MSCHAP2_CHALLENGE_SIZE],
91	const uint8_t peer_challenge[MSCHAP2_CHALLENGE_SIZE],
92	const uint8_t * username,
93	const uint8_t * password, uint32_t password_len,
94	uint8_t response[MSCHAP_NT_RESPONSE_SIZE]);
95
96bool
97MSChap2AuthResponseValid(const uint8_t * password, uint32_t password_len,
98			 const uint8_t nt_response[MSCHAP_NT_RESPONSE_SIZE],
99			 const uint8_t peer_challenge[MSCHAP2_CHALLENGE_SIZE],
100			 const uint8_t auth_challenge[MSCHAP2_CHALLENGE_SIZE],
101			 const uint8_t * username,
102			 const uint8_t response[MSCHAP2_AUTH_RESPONSE_SIZE]);
103
104void
105NTPasswordBlockEncryptNewPasswordWithOldHash(const uint8_t * new_password,
106					     uint32_t new_password_len,
107					     const uint8_t * old_password,
108					     uint32_t old_password_len,
109					     NTPasswordBlockRef pwblock);
110void
111NTPasswordHashEncryptOldWithNew(const uint8_t * new_password,
112				uint32_t new_password_len,
113				const uint8_t * old_password,
114				uint32_t old_password_len,
115				uint8_t encrypted_hash[NT_PASSWORD_HASH_SIZE]);
116void
117MSChapFillWithRandom(void * buf, uint32_t len);
118
119void
120MSChap2_MPPEGetMasterKey(const uint8_t * password, uint32_t password_len,
121			 const uint8_t NTResponse[MSCHAP_NT_RESPONSE_SIZE],
122			 uint8_t MasterKey[NT_MASTER_KEY_SIZE]);
123void
124MSChap2_MPPEGetAsymetricStartKey(const uint8_t MasterKey[NT_MASTER_KEY_SIZE],
125				 uint8_t SessionKey[NT_SESSION_KEY_SIZE],
126				 int SessionKeyLength,
127				 bool IsSend,
128				 bool IsServer);
129#endif /* _EAP8021X_MSCHAP_H */
130