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