static void GenerateAuthenticatorResponse(char *secret, int secret_len, u_char NTResponse[24], u_char PeerChallenge[16], u_char *rchallenge, char *username, u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { /* * "Magic" constants used in response generation, from RFC 2759. */ u_char Magic1[39] = /* "Magic server to client signing constant" */ { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E }; int i; SHA1_CTX sha1Context; u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; u_char Digest[SHA1_SIGNATURE_SIZE]; u_char Challenge[8]; /* Hash (x2) the Unicode version of the secret (== password). */ ascii2unicode(secret, secret_len, unicodePassword); NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); SHA1_Init(&sha1Context); SHA1_Update(&sha1Context, PasswordHashHash, sizeof(PasswordHashHash)); SHA1_Update(&sha1Context, NTResponse, 24); SHA1_Update(&sha1Context, Magic1, sizeof(Magic1)); SHA1_Final(Digest, &sha1Context); ChallengeHash(PeerChallenge, rchallenge, username, Challenge); SHA1_Init(&sha1Context); SHA1_Update(&sha1Context, Digest, sizeof(Digest)); SHA1_Update(&sha1Context, Challenge, sizeof(Challenge)); SHA1_Update(&sha1Context, Magic2, sizeof(Magic2)); SHA1_Final(Digest, &sha1Context); /* Convert to ASCII hex string. */ for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); }
static void GenerateAuthResponse(uint8_t * password, uint32_t password_len, const uint8_t nt_response[MSCHAP_NT_RESPONSE_SIZE], const uint8_t peer_challenge[MSCHAP2_CHALLENGE_SIZE], const uint8_t auth_challenge[MSCHAP2_CHALLENGE_SIZE], const uint8_t * username, uint8_t auth_response[MSCHAP2_AUTH_RESPONSE_SIZE]) { uint8_t challenge[MSCHAP_NT_CHALLENGE_SIZE]; CC_SHA1_CTX context; int i; uint8_t hash[CC_SHA1_DIGEST_LENGTH]; uint8_t password_hash[NT_PASSWORD_HASH_SIZE]; uint8_t * scan; NTPasswordHashHash(password, password_len, password_hash); CC_SHA1_Init(&context); CC_SHA1_Update(&context, password_hash, NT_PASSWORD_HASH_SIZE); CC_SHA1_Update(&context, nt_response, MSCHAP_NT_RESPONSE_SIZE); CC_SHA1_Update(&context, magic1, 39); CC_SHA1_Final(hash, &context); ChallengeHash(peer_challenge, auth_challenge, username, challenge); CC_SHA1_Init(&context); CC_SHA1_Update(&context, hash, CC_SHA1_DIGEST_LENGTH); CC_SHA1_Update(&context, challenge, MSCHAP_NT_CHALLENGE_SIZE); CC_SHA1_Update(&context, magic2, 41); CC_SHA1_Final(hash, &context); /* * Encode the value of 'hash' as "S=" followed by * 40 ASCII hexadecimal digits and return it in * 'auth_response'. * For example, * "S=0123456789ABCDEF0123456789ABCDEF01234567" */ auth_response[0] = 'S'; auth_response[1] = '='; for (i = 0, scan = auth_response + 2; i < CC_SHA1_DIGEST_LENGTH; i++, scan +=2) { char hexstr[3]; snprintf(hexstr, 3, "%02X", hash[i]); scan[0] = hexstr[0]; scan[1] = hexstr[1]; } return; }
static void ChapMS2_NT(const u_char *rchallenge, const u_char PeerChallenge[16], const char *username, const char *secret, int secret_len, u_char NTResponse[24]) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_SIGNATURE_SIZE]; u_char Challenge[8]; ChallengeHash(PeerChallenge, rchallenge, username, Challenge); /* Hash the Unicode version of the secret (== password). */ ascii2unicode(secret, secret_len, unicodePassword); NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); ChallengeResponse(Challenge, PasswordHash, NTResponse); }
void MSChap2(const uint8_t auth_challenge[MSCHAP2_CHALLENGE_SIZE], const uint8_t peer_challenge[MSCHAP2_CHALLENGE_SIZE], const uint8_t * username, const uint8_t * password, uint32_t password_len, uint8_t response[MSCHAP_NT_RESPONSE_SIZE]) { uint8_t unicode_password[NT_MAXPWLEN * 2]; uint8_t challenge[MSCHAP_NT_CHALLENGE_SIZE]; ChallengeHash(peer_challenge, auth_challenge, username, challenge); password_len = password_to_unicode(password, password_len, unicode_password); NTChallengeResponse(challenge, unicode_password, password_len, response); return; }
static void GenerateAuthenticatorResponse(const u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], const u_char PeerChallenge[16], const u_char *rchallenge, const char *username, u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { /* * "Magic" constants used in response generation, from RFC 2759. */ static const u_char Magic1[39] = /* "Magic server to client signing constant" */ { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; static const u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E }; int i; lwip_sha1_context sha1Context; u_char Digest[SHA1_SIGNATURE_SIZE]; u_char Challenge[8]; lwip_sha1_init(&sha1Context); lwip_sha1_starts(&sha1Context); lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); lwip_sha1_update(&sha1Context, NTResponse, 24); lwip_sha1_update(&sha1Context, Magic1, sizeof(Magic1)); lwip_sha1_finish(&sha1Context, Digest); lwip_sha1_free(&sha1Context); ChallengeHash(PeerChallenge, rchallenge, username, Challenge); lwip_sha1_init(&sha1Context); lwip_sha1_starts(&sha1Context); lwip_sha1_update(&sha1Context, Digest, sizeof(Digest)); lwip_sha1_update(&sha1Context, Challenge, sizeof(Challenge)); lwip_sha1_update(&sha1Context, Magic2, sizeof(Magic2)); lwip_sha1_finish(&sha1Context, Digest); lwip_sha1_free(&sha1Context); /* Convert to ASCII hex string. */ for (i = 0; i < LWIP_MAX((MS_AUTH_RESPONSE_LENGTH / 2), (int)sizeof(Digest)); i++) sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); }