00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
00402
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 }