$search
00001 /* 00002 * WPA Supplicant / shared MSCHAPV2 helper functions / RFC 2433 / RFC 2759 00003 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 #include "sha1.h" 00019 #include "ms_funcs.h" 00020 #include "crypto.h" 00021 00022 00032 static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge, 00033 const u8 *username, size_t username_len, 00034 u8 *challenge) 00035 { 00036 u8 hash[SHA1_MAC_LEN]; 00037 const unsigned char *addr[3]; 00038 size_t len[3]; 00039 00040 addr[0] = peer_challenge; 00041 len[0] = 16; 00042 addr[1] = auth_challenge; 00043 len[1] = 16; 00044 addr[2] = username; 00045 len[2] = username_len; 00046 00047 if (sha1_vector(3, addr, len, hash)) 00048 return -1; 00049 os_memcpy(challenge, hash, 8); 00050 return 0; 00051 } 00052 00053 00061 int nt_password_hash(const u8 *password, size_t password_len, 00062 u8 *password_hash) 00063 { 00064 u8 buf[512], *pos; 00065 size_t i, len; 00066 00067 if (password_len > 256) 00068 password_len = 256; 00069 00070 /* Convert password into unicode */ 00071 for (i = 0; i < password_len; i++) { 00072 buf[2 * i] = password[i]; 00073 buf[2 * i + 1] = 0; 00074 } 00075 00076 len = password_len * 2; 00077 pos = buf; 00078 return md4_vector(1, (const u8 **) &pos, &len, password_hash); 00079 } 00080 00081 00088 int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash) 00089 { 00090 size_t len = 16; 00091 return md4_vector(1, &password_hash, &len, password_hash_hash); 00092 } 00093 00094 00101 void challenge_response(const u8 *challenge, const u8 *password_hash, 00102 u8 *response) 00103 { 00104 u8 zpwd[7]; 00105 des_encrypt(challenge, password_hash, response); 00106 des_encrypt(challenge, password_hash + 7, response + 8); 00107 zpwd[0] = password_hash[14]; 00108 zpwd[1] = password_hash[15]; 00109 os_memset(zpwd + 2, 0, 5); 00110 des_encrypt(challenge, zpwd, response + 16); 00111 } 00112 00113 00125 int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge, 00126 const u8 *username, size_t username_len, 00127 const u8 *password, size_t password_len, 00128 u8 *response) 00129 { 00130 u8 challenge[8]; 00131 u8 password_hash[16]; 00132 00133 challenge_hash(peer_challenge, auth_challenge, username, username_len, 00134 challenge); 00135 if (nt_password_hash(password, password_len, password_hash)) 00136 return -1; 00137 challenge_response(challenge, password_hash, response); 00138 return 0; 00139 } 00140 00141 00152 int generate_nt_response_pwhash(const u8 *auth_challenge, 00153 const u8 *peer_challenge, 00154 const u8 *username, size_t username_len, 00155 const u8 *password_hash, 00156 u8 *response) 00157 { 00158 u8 challenge[8]; 00159 00160 if (challenge_hash(peer_challenge, auth_challenge, 00161 username, username_len, 00162 challenge)) 00163 return -1; 00164 challenge_response(challenge, password_hash, response); 00165 return 0; 00166 } 00167 00168 00181 int generate_authenticator_response_pwhash( 00182 const u8 *password_hash, 00183 const u8 *peer_challenge, const u8 *auth_challenge, 00184 const u8 *username, size_t username_len, 00185 const u8 *nt_response, u8 *response) 00186 { 00187 static const u8 magic1[39] = { 00188 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 00189 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 00190 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 00191 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 00192 }; 00193 static const u8 magic2[41] = { 00194 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 00195 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 00196 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 00197 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 00198 0x6E 00199 }; 00200 00201 u8 password_hash_hash[16], challenge[8]; 00202 const unsigned char *addr1[3]; 00203 const size_t len1[3] = { 16, 24, sizeof(magic1) }; 00204 const unsigned char *addr2[3]; 00205 const size_t len2[3] = { SHA1_MAC_LEN, 8, sizeof(magic2) }; 00206 00207 addr1[0] = password_hash_hash; 00208 addr1[1] = nt_response; 00209 addr1[2] = magic1; 00210 00211 addr2[0] = response; 00212 addr2[1] = challenge; 00213 addr2[2] = magic2; 00214 00215 if (hash_nt_password_hash(password_hash, password_hash_hash)) 00216 return -1; 00217 if (sha1_vector(3, addr1, len1, response)) 00218 return -1; 00219 00220 challenge_hash(peer_challenge, auth_challenge, username, username_len, 00221 challenge); 00222 return sha1_vector(3, addr2, len2, response); 00223 } 00224 00225 00239 int generate_authenticator_response(const u8 *password, size_t password_len, 00240 const u8 *peer_challenge, 00241 const u8 *auth_challenge, 00242 const u8 *username, size_t username_len, 00243 const u8 *nt_response, u8 *response) 00244 { 00245 u8 password_hash[16]; 00246 if (nt_password_hash(password, password_len, password_hash)) 00247 return -1; 00248 return generate_authenticator_response_pwhash( 00249 password_hash, peer_challenge, auth_challenge, 00250 username, username_len, nt_response, response); 00251 } 00252 00253 00262 int nt_challenge_response(const u8 *challenge, const u8 *password, 00263 size_t password_len, u8 *response) 00264 { 00265 u8 password_hash[16]; 00266 if (nt_password_hash(password, password_len, password_hash)) 00267 return -1; 00268 challenge_response(challenge, password_hash, response); 00269 return 0; 00270 } 00271 00272 00280 int get_master_key(const u8 *password_hash_hash, const u8 *nt_response, 00281 u8 *master_key) 00282 { 00283 static const u8 magic1[27] = { 00284 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 00285 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, 00286 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 00287 }; 00288 const unsigned char *addr[3]; 00289 const size_t len[3] = { 16, 24, sizeof(magic1) }; 00290 u8 hash[SHA1_MAC_LEN]; 00291 00292 addr[0] = password_hash_hash; 00293 addr[1] = nt_response; 00294 addr[2] = magic1; 00295 00296 if (sha1_vector(3, addr, len, hash)) 00297 return -1; 00298 os_memcpy(master_key, hash, 16); 00299 return 0; 00300 } 00301 00302 00312 int get_asymetric_start_key(const u8 *master_key, u8 *session_key, 00313 size_t session_key_len, int is_send, 00314 int is_server) 00315 { 00316 static const u8 magic2[84] = { 00317 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 00318 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 00319 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 00320 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 00321 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 00322 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 00323 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 00324 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 00325 0x6b, 0x65, 0x79, 0x2e 00326 }; 00327 static const u8 magic3[84] = { 00328 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 00329 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 00330 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 00331 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 00332 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 00333 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 00334 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 00335 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 00336 0x6b, 0x65, 0x79, 0x2e 00337 }; 00338 static const u8 shs_pad1[40] = { 00339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00343 }; 00344 00345 static const u8 shs_pad2[40] = { 00346 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 00347 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 00348 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 00349 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 00350 }; 00351 u8 digest[SHA1_MAC_LEN]; 00352 const unsigned char *addr[4]; 00353 const size_t len[4] = { 16, 40, 84, 40 }; 00354 00355 addr[0] = master_key; 00356 addr[1] = shs_pad1; 00357 if (is_send) { 00358 addr[2] = is_server ? magic3 : magic2; 00359 } else { 00360 addr[2] = is_server ? magic2 : magic3; 00361 } 00362 addr[3] = shs_pad2; 00363 00364 if (sha1_vector(4, addr, len, digest)) 00365 return -1; 00366 00367 if (session_key_len > SHA1_MAC_LEN) 00368 session_key_len = SHA1_MAC_LEN; 00369 os_memcpy(session_key, digest, session_key_len); 00370 return 0; 00371 } 00372 00373 00374 #define PWBLOCK_LEN 516 00375 00384 int encrypt_pw_block_with_password_hash( 00385 const u8 *password, size_t password_len, 00386 const u8 *password_hash, u8 *pw_block) 00387 { 00388 size_t i, offset; 00389 u8 *pos; 00390 00391 if (password_len > 256) 00392 return -1; 00393 00394 os_memset(pw_block, 0, PWBLOCK_LEN); 00395 offset = (256 - password_len) * 2; 00396 if (os_get_random(pw_block, offset) < 0) 00397 return -1; 00398 for (i = 0; i < password_len; i++) 00399 pw_block[offset + i * 2] = password[i]; 00400 /* 00401 * PasswordLength is 4 octets, but since the maximum password length is 00402 * 256, only first two (in little endian byte order) can be non-zero. 00403 */ 00404 pos = &pw_block[2 * 256]; 00405 WPA_PUT_LE16(pos, password_len * 2); 00406 rc4_skip(password_hash, 16, 0, pw_block, PWBLOCK_LEN); 00407 return 0; 00408 } 00409 00410 00420 int new_password_encrypted_with_old_nt_password_hash( 00421 const u8 *new_password, size_t new_password_len, 00422 const u8 *old_password, size_t old_password_len, 00423 u8 *encrypted_pw_block) 00424 { 00425 u8 password_hash[16]; 00426 00427 if (nt_password_hash(old_password, old_password_len, password_hash)) 00428 return -1; 00429 if (encrypt_pw_block_with_password_hash(new_password, new_password_len, 00430 password_hash, 00431 encrypted_pw_block)) 00432 return -1; 00433 return 0; 00434 } 00435 00436 00443 void nt_password_hash_encrypted_with_block(const u8 *password_hash, 00444 const u8 *block, u8 *cypher) 00445 { 00446 des_encrypt(password_hash, block, cypher); 00447 des_encrypt(password_hash + 8, block + 7, cypher + 8); 00448 } 00449 00450 00460 int old_nt_password_hash_encrypted_with_new_nt_password_hash( 00461 const u8 *new_password, size_t new_password_len, 00462 const u8 *old_password, size_t old_password_len, 00463 u8 *encrypted_password_hash) 00464 { 00465 u8 old_password_hash[16], new_password_hash[16]; 00466 00467 if (nt_password_hash(old_password, old_password_len, 00468 old_password_hash) || 00469 nt_password_hash(new_password, new_password_len, 00470 new_password_hash)) 00471 return -1; 00472 nt_password_hash_encrypted_with_block(old_password_hash, 00473 new_password_hash, 00474 encrypted_password_hash); 00475 return 0; 00476 }