00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "sha1.h"
00020 #include "ms_funcs.h"
00021 #include "crypto.h"
00022
00023
00034 static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
00035 const u8 *username, size_t username_len,
00036 u8 *challenge)
00037 {
00038 u8 hash[SHA1_MAC_LEN];
00039 const unsigned char *addr[3];
00040 size_t len[3];
00041
00042 addr[0] = peer_challenge;
00043 len[0] = 16;
00044 addr[1] = auth_challenge;
00045 len[1] = 16;
00046 addr[2] = username;
00047 len[2] = username_len;
00048
00049 if (sha1_vector(3, addr, len, hash))
00050 return -1;
00051 os_memcpy(challenge, hash, 8);
00052 return 0;
00053 }
00054
00055
00064 int nt_password_hash(const u8 *password, size_t password_len,
00065 u8 *password_hash)
00066 {
00067 u8 buf[512], *pos;
00068 size_t i, len;
00069
00070 if (password_len > 256)
00071 password_len = 256;
00072
00073
00074 for (i = 0; i < password_len; i++) {
00075 buf[2 * i] = password[i];
00076 buf[2 * i + 1] = 0;
00077 }
00078
00079 len = password_len * 2;
00080 pos = buf;
00081 return md4_vector(1, (const u8 **) &pos, &len, password_hash);
00082 }
00083
00084
00092 int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash)
00093 {
00094 size_t len = 16;
00095 return md4_vector(1, &password_hash, &len, password_hash_hash);
00096 }
00097
00098
00106 void challenge_response(const u8 *challenge, const u8 *password_hash,
00107 u8 *response)
00108 {
00109 u8 zpwd[7];
00110 des_encrypt(challenge, password_hash, response);
00111 des_encrypt(challenge, password_hash + 7, response + 8);
00112 zpwd[0] = password_hash[14];
00113 zpwd[1] = password_hash[15];
00114 os_memset(zpwd + 2, 0, 5);
00115 des_encrypt(challenge, zpwd, response + 16);
00116 }
00117
00118
00131 int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
00132 const u8 *username, size_t username_len,
00133 const u8 *password, size_t password_len,
00134 u8 *response)
00135 {
00136 u8 challenge[8];
00137 u8 password_hash[16];
00138
00139 challenge_hash(peer_challenge, auth_challenge, username, username_len,
00140 challenge);
00141 if (nt_password_hash(password, password_len, password_hash))
00142 return -1;
00143 challenge_response(challenge, password_hash, response);
00144 return 0;
00145 }
00146
00147
00159 int generate_nt_response_pwhash(const u8 *auth_challenge,
00160 const u8 *peer_challenge,
00161 const u8 *username, size_t username_len,
00162 const u8 *password_hash,
00163 u8 *response)
00164 {
00165 u8 challenge[8];
00166
00167 if (challenge_hash(peer_challenge, auth_challenge,
00168 username, username_len,
00169 challenge))
00170 return -1;
00171 challenge_response(challenge, password_hash, response);
00172 return 0;
00173 }
00174
00175
00189 int generate_authenticator_response_pwhash(
00190 const u8 *password_hash,
00191 const u8 *peer_challenge, const u8 *auth_challenge,
00192 const u8 *username, size_t username_len,
00193 const u8 *nt_response, u8 *response)
00194 {
00195 static const u8 magic1[39] = {
00196 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
00197 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
00198 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
00199 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
00200 };
00201 static const u8 magic2[41] = {
00202 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
00203 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
00204 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
00205 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
00206 0x6E
00207 };
00208
00209 u8 password_hash_hash[16], challenge[8];
00210 const unsigned char *addr1[3];
00211 const size_t len1[3] = { 16, 24, sizeof(magic1) };
00212 const unsigned char *addr2[3];
00213 const size_t len2[3] = { SHA1_MAC_LEN, 8, sizeof(magic2) };
00214
00215 addr1[0] = password_hash_hash;
00216 addr1[1] = nt_response;
00217 addr1[2] = magic1;
00218
00219 addr2[0] = response;
00220 addr2[1] = challenge;
00221 addr2[2] = magic2;
00222
00223 if (hash_nt_password_hash(password_hash, password_hash_hash))
00224 return -1;
00225 if (sha1_vector(3, addr1, len1, response))
00226 return -1;
00227
00228 challenge_hash(peer_challenge, auth_challenge, username, username_len,
00229 challenge);
00230 return sha1_vector(3, addr2, len2, response);
00231 }
00232
00233
00248 int generate_authenticator_response(const u8 *password, size_t password_len,
00249 const u8 *peer_challenge,
00250 const u8 *auth_challenge,
00251 const u8 *username, size_t username_len,
00252 const u8 *nt_response, u8 *response)
00253 {
00254 u8 password_hash[16];
00255 if (nt_password_hash(password, password_len, password_hash))
00256 return -1;
00257 return generate_authenticator_response_pwhash(
00258 password_hash, peer_challenge, auth_challenge,
00259 username, username_len, nt_response, response);
00260 }
00261
00262
00272 int nt_challenge_response(const u8 *challenge, const u8 *password,
00273 size_t password_len, u8 *response)
00274 {
00275 u8 password_hash[16];
00276 if (nt_password_hash(password, password_len, password_hash))
00277 return -1;
00278 challenge_response(challenge, password_hash, response);
00279 return 0;
00280 }
00281
00282
00291 int get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
00292 u8 *master_key)
00293 {
00294 static const u8 magic1[27] = {
00295 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
00296 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
00297 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
00298 };
00299 const unsigned char *addr[3];
00300 const size_t len[3] = { 16, 24, sizeof(magic1) };
00301 u8 hash[SHA1_MAC_LEN];
00302
00303 addr[0] = password_hash_hash;
00304 addr[1] = nt_response;
00305 addr[2] = magic1;
00306
00307 if (sha1_vector(3, addr, len, hash))
00308 return -1;
00309 os_memcpy(master_key, hash, 16);
00310 return 0;
00311 }
00312
00313
00324 int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
00325 size_t session_key_len, int is_send,
00326 int is_server)
00327 {
00328 static const u8 magic2[84] = {
00329 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
00330 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
00331 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
00332 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
00333 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
00334 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
00335 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
00336 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
00337 0x6b, 0x65, 0x79, 0x2e
00338 };
00339 static const u8 magic3[84] = {
00340 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
00341 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
00342 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
00343 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
00344 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
00345 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
00346 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
00347 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
00348 0x6b, 0x65, 0x79, 0x2e
00349 };
00350 static const u8 shs_pad1[40] = {
00351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00355 };
00356
00357 static const u8 shs_pad2[40] = {
00358 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
00359 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
00360 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
00361 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
00362 };
00363 u8 digest[SHA1_MAC_LEN];
00364 const unsigned char *addr[4];
00365 const size_t len[4] = { 16, 40, 84, 40 };
00366
00367 addr[0] = master_key;
00368 addr[1] = shs_pad1;
00369 if (is_send) {
00370 addr[2] = is_server ? magic3 : magic2;
00371 } else {
00372 addr[2] = is_server ? magic2 : magic3;
00373 }
00374 addr[3] = shs_pad2;
00375
00376 if (sha1_vector(4, addr, len, digest))
00377 return -1;
00378
00379 if (session_key_len > SHA1_MAC_LEN)
00380 session_key_len = SHA1_MAC_LEN;
00381 os_memcpy(session_key, digest, session_key_len);
00382 return 0;
00383 }
00384
00385
00386 #define PWBLOCK_LEN 516
00387
00397 int encrypt_pw_block_with_password_hash(
00398 const u8 *password, size_t password_len,
00399 const u8 *password_hash, u8 *pw_block)
00400 {
00401 size_t i, offset;
00402 u8 *pos;
00403
00404 if (password_len > 256)
00405 return -1;
00406
00407 os_memset(pw_block, 0, PWBLOCK_LEN);
00408 offset = (256 - password_len) * 2;
00409 if (os_get_random(pw_block, offset) < 0)
00410 return -1;
00411 for (i = 0; i < password_len; i++)
00412 pw_block[offset + i * 2] = password[i];
00413
00414
00415
00416
00417 pos = &pw_block[2 * 256];
00418 WPA_PUT_LE16(pos, password_len * 2);
00419 rc4_skip(password_hash, 16, 0, pw_block, PWBLOCK_LEN);
00420 return 0;
00421 }
00422
00423
00434 int new_password_encrypted_with_old_nt_password_hash(
00435 const u8 *new_password, size_t new_password_len,
00436 const u8 *old_password, size_t old_password_len,
00437 u8 *encrypted_pw_block)
00438 {
00439 u8 password_hash[16];
00440
00441 if (nt_password_hash(old_password, old_password_len, password_hash))
00442 return -1;
00443 if (encrypt_pw_block_with_password_hash(new_password, new_password_len,
00444 password_hash,
00445 encrypted_pw_block))
00446 return -1;
00447 return 0;
00448 }
00449
00450
00458 void nt_password_hash_encrypted_with_block(const u8 *password_hash,
00459 const u8 *block, u8 *cypher)
00460 {
00461 des_encrypt(password_hash, block, cypher);
00462 des_encrypt(password_hash + 8, block + 7, cypher + 8);
00463 }
00464
00465
00476 int old_nt_password_hash_encrypted_with_new_nt_password_hash(
00477 const u8 *new_password, size_t new_password_len,
00478 const u8 *old_password, size_t old_password_len,
00479 u8 *encrypted_password_hash)
00480 {
00481 u8 old_password_hash[16], new_password_hash[16];
00482
00483 if (nt_password_hash(old_password, old_password_len,
00484 old_password_hash) ||
00485 nt_password_hash(new_password, new_password_len,
00486 new_password_hash))
00487 return -1;
00488 nt_password_hash_encrypted_with_block(old_password_hash,
00489 new_password_hash,
00490 encrypted_password_hash);
00491 return 0;
00492 }
00493