ms_funcs.c

Go to the documentation of this file.
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         /* Convert password into unicode */
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          * PasswordLength is 4 octets, but since the maximum password length is
00415          * 256, only first two (in little endian byte order) can be non-zero.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:50 2009 for hostapd by  doxygen 1.6.1