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 47extern __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 62static 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 69static 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 76uint8_t get7bits(uint8_t *, int); 77void mschap_des_addparity(uint8_t *, uint8_t *); 78void mschap_des_encrypt(uint8_t *, uint8_t *, uint8_t *); 79void mschap_challenge_response(uint8_t *, uint8_t *, uint8_t *); 80 81uint8_t 82get7bits(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 */ 95void 96mschap_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 110void 111mschap_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 123void 124mschap_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 137void 138mschap_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 152void 153mschap_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 179void 180mschap_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 194void 195mschap_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 259void 260mschap_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 285void 286mschap_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 335void 336mschap_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 358void 359mschap_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