idnits 2.17.1 draft-ietf-pppext-mschap-v2-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Looks like you're using RFC 2026 boilerplate. This must be updated to follow RFC 3978/3979, as updated by RFC 4748. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing expiration date. The document expiration date should appear on the first and last page. ** The document seems to lack a 1id_guidelines paragraph about 6 months document validity -- however, there's a paragraph with a matching beginning. Boilerplate error? == The page length should not exceed 58 lines per page, but there was 1 longer page, the longest (page 2) being 60 lines == It seems as if not all pages are separated by form feeds - found 0 form feeds but 21 pages Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** The document seems to lack separate sections for Informative/Normative References. All references will be assumed normative when checking for downward references. ** There are 4 instances of too long lines in the document, the longest one being 12 characters in excess of 72. ** The abstract seems to contain references ([3], [9], [1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == Line 281 has weird spacing: '...age> is human...' == The document seems to lack the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. (The document does seem to have the reference to RFC 2119 which the ID-Checklist requires). -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (April 1999) is 9143 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Informational ---------------------------------------------------------------------------- == Missing Reference: '39' is mentioned on line 498, but not defined == Missing Reference: '41' is mentioned on line 504, but not defined ** Obsolete normative reference: RFC 1320 (ref. '5') (Obsoleted by RFC 6150) ** Obsolete normative reference: RFC 1750 (ref. '7') (Obsoleted by RFC 4086) Summary: 9 errors (**), 0 flaws (~~), 6 warnings (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 G. Zorn 2 Internet-Draft Microsoft Corporation 3 Category: Informational April 1999 4 6 Microsoft PPP CHAP Extensions, Version 2 8 Status of this Memo 10 This document is an Internet-Draft and is in full conformance with all 11 provisions of Section 10 of RFC2026 except that the right to produce 12 derivative works is not granted. 14 Internet-Drafts are working documents of the Internet Engineering Task 15 Force (IETF), its areas, and its working groups. Note that other groups 16 may also distribute working documents as Internet-Drafts. 18 Internet-Drafts are draft documents valid for a maximum of six months 19 and may be updated, replaced, or obsoleted by other documents at any 20 time. It is inappropriate to use Internet- Drafts as reference material 21 or to cite them other than as "work in progress." 23 The list of current Internet-Drafts can be accessed at 24 http://www.ietf.org/ietf/1id-abstracts.txt 26 The list of Internet-Draft Shadow Directories can be accessed at 27 http://www.ietf.org/shadow.html. 29 This memo provides information for the Internet community. This memo 30 does not specify an Internet standard of any kind. The distribution of 31 this memo is unlimited. It is filed as and expires October 25, 1999. Please send comments to the 33 PPP Extensions Working Group mailing list (ietf-ppp@merit.edu) or to the 34 author (gwz@acm.org). 36 Abstract 38 The Point-to-Point Protocol (PPP) [1] provides a standard method for 39 transporting multi-protocol datagrams over point-to-point links. PPP 40 defines an extensible Link Control Protocol and a family of Network 41 Control Protocols (NCPs) for establishing and configuring different 42 network-layer protocols. 44 This document describes version two of Microsoft's PPP CHAP dialect (MS- 45 CHAP-V2). MS-CHAP-V2 is similar to, but incompatible with, MS-CHAP 46 version one (MS-CHAP-V1, described in [9]). In particular, certain 47 protocol fields have been deleted or reused but with different 48 semantics. In addition, MS-CHAP-V2 features mutual authentication. 50 The algorithms used in the generation of various MS-CHAP-V2 protocol 51 fields are described in section 8. Negotiation and hash generation 52 examples are provided in section 9. 54 Specification of Requirements 56 In this document, the key words "MAY", "MUST, "MUST NOT", "optional", 57 "recommended", "SHOULD", and "SHOULD NOT" are to be interpreted as 58 described in [3]. 60 Table of Contents 62 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . 5 64 2. LCP Configuration . . . . . . . . . . . . . . . . . . . . . . . . 5 66 4. Response Packet . . . . . . . . . . . . . . . . . . . . . . . . . 6 68 5. Success Packet . . . . . . . . . . . . . . . . . . . . . . . . . 6 70 6. Failure Packet . . . . . . . . . . . . . . . . . . . . . . . . . 7 72 7. Change-Password Packet . . . . . . . . . . . . . . . . . . . . . 8 74 8. Pseudocode . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 76 8.1. GenerateNTResponse() . . . . . . . . . . . . . . . . . . . . . 9 78 8.2. ChallengeHash() . . . . . . . . . . . . . . . . . . . . . . . . 10 80 8.3. NtPasswordHash() . . . . . . . . . . . . . . . . . . . . . . . 11 82 8.4. HashNtPasswordHash() . . . . . . . . . . . . . . . . . . . . . 11 84 8.5. ChallengeResponse() . . . . . . . . . . . . . . . . . . . . . . 11 86 8.6. DesEncrypt() . . . . . . . . . . . . . . . . . . . . . . . . . 12 88 8.7. GenerateAuthenticatorResponse() . . . . . . . . . . . . . . . . 12 90 8.8. CheckAuthenticatorResponse() . . . . . . . . . . . . . . . . . 13 92 8.9. NewPasswordEncryptedWithOldNtPasswordHash() . . . . . . . . . . 14 94 8.10. EncryptPwBlockWithPasswordHash() . . . . . . . . . . . . . . . 14 96 8.11. Rc4Encrypt() . . . . . . . . . . . . . . . . . . . . . . . . . 15 98 8.12. OldNtPasswordHashEncryptedWithNewNtPasswordHash() . . . . . . 15 100 8.13. NtPasswordHashEncryptedWithBlock() . . . . . . . . . . . . . . 16 102 9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 104 9.1. Negotiation Examples . . . . . . . . . . . . . . . . . . . . . 16 105 9.1.1. Successful authentication . . . . . . . . . . . . . . . . . . 16 107 9.1.2. Authenticator authentication failure . . . . . . . . . . . . 16 109 9.1.3. Failed authentication with no retry allowed . . . . . . . . . 17 111 9.1.4. Successful authentication after retry . . . . . . . . . . . . 17 113 9.1.5. Failed hack attack with 3 attempts allowed . . . . . . . . . 17 115 9.1.6. Successful authentication with password change . . . . . . . 17 117 9.1.7. Successful authentication with retry and password change 118 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 120 9.2. Hash Example . . . . . . . . . . . . . . . . . . . . . . . . . 18 122 9.3. Example of DES Key Generation . . . . . . . . . . . . . . . . . 19 124 10. Security Considerations . . . . . . . . . . . . . . . . . . . . 19 126 11. References . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 128 12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 20 130 13. Chair's Address . . . . . . . . . . . . . . . . . . . . . . . . 20 132 14. Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 21 134 15. Expiration Date . . . . . . . . . . . . . . . . . . . . . . . . 21 135 1. Introduction 137 Where possible, MS-CHAP-V2 is consistent with both MS-CHAP-V1 and 138 standard CHAP. Briefly, the differences between MS-CHAP-V2 and MS-CHAP- 139 V1 are: 141 * MS-CHAP-V2 is enabled by negotiating CHAP Algorithm 0x81 in LCP 142 option 3, Authentication Protocol. 144 * MS-CHAP-V2 provides mutual authentication between peers by 145 piggybacking a peer challenge on the Response packet and an 146 authenticator reponse on the Success packet. 148 * The calculation of the "Windows NT compatible challenge 149 response" sub-field in the Response packet has been changed 150 to include the peer challenge and the user name. 152 * In MS-CHAP-V1, the "LAN Manager compatible challenge response" 153 sub-field was always sent in the Response packet. This field 154 has been replaced in MS-CHAP-V2 by the Peer-Challenge field. 156 * The format of the Message field in the Failure packet has 157 been changed. 159 * The Change Password (version 1) and Change Password (version 2) 160 packets are no longer supported. They have been replaced with a 161 single Change-Password packet. 163 2. LCP Configuration 165 The LCP configuration for MS-CHAP-V2 is identical to that for standard 166 CHAP, except that the Algorithm field has value 0x81, rather than the 167 MD5 value 0x05. PPP implementations which do not support MS-CHAP-V2, 168 but correctly implement LCP Config-Rej, should have no problem dealing 169 with this non-standard option. 171 3. Challenge Packet 173 The MS-CHAP-V2 Challenge packet is identical in format to the standard 174 CHAP Challenge packet. 176 MS-CHAP-V2 authenticators send an 16-octet challenge Value field. Peers 177 need not duplicate Microsoft's algorithm for selecting the 16-octet 178 value, but the standard guidelines on randomness [1,2,7] SHOULD be 179 observed. 181 Microsoft authenticators do not currently provide information in the 182 Name field. This may change in the future. 184 4. Response Packet 186 The MS-CHAP-V2 Response packet is identical in format to the standard 187 CHAP Response packet. However, the Value field is sub-formatted 188 differently as follows: 190 16 octets: Peer-Challenge 191 8 octets: Reserved, must be zero 192 24 octets: NT-Response 193 1 octet : Flags 195 The Peer-Challenge field is a 16-octet random number. As the name 196 implies, it is generated by the peer and is used in the calculation of 197 the NT-Response field, below. Peers need not duplicate Microsoft's 198 algorithm for selecting the 16-octet value, but the standard guidelines 199 on randomness [1,2,7] SHOULD be observed. 201 The NT-Response field is an encoded function of the password, the user 202 name, the contents of the Peer-Challenge field and the received 203 challenge as output by the routine GenerateNTResponse() (see section 204 11.1, below). The Windows NT password is a string of 0 to 205 (theoretically) 256 case-sensitive Unicode [8] characters. Current 206 versions of Windows NT limit passwords to 14 characters, mainly for 207 compatibility reasons; this may change in the future. When computing 208 the NT-Response field contents, only the user name is used, without any 209 associated Windows NT domain name. This is true regardless of whether a 210 Windows NT domain name is present in the Name field (see below). 212 The Flag field is reserved for future use and MUST be zero. 214 The Name field is a string of 0 to (theoretically) 256 case-sensitive 215 ASCII characters which identifies the peer's user account name. The 216 Windows NT domain name may prefix the user's account name (e.g. 217 "BIGCO\johndoe" where "BIGCO" is a Windows NT domain containing the user 218 account "johndoe"). If a domain is not provided, the backslash should 219 also be omitted, (e.g. "johndoe"). 221 5. Success Packet 223 The Success packet is identical in format to the standard CHAP Success 224 packet. However, the Message field contains a 42-octet authenticator 225 response string and a printable message. The format of the message 226 field is illustrated below. 228 "S= M=" 230 The quantity is a 20 octet number encoded in ASCII as 40 231 hexadecimal digits. The hexadecimal digits A-F (if present) MUST be 232 uppercase. This number is derived from the challenge from the Challenge 233 packet, the Peer-Challenge and NT-Response fields from the Response 234 packet, and the peer password as output by the routine 235 GenerateAuthenticatorResponse() (see section 11.7, below). The 236 authenticating peer MUST verify the authenticator response when a 237 Success packet is received. The method for verifying the authenticator 238 is described in section 11.8, below. If the authenticator response is 239 either missing or incorrect, the peer MUST end the session. 241 The quantity is human-readable text in the appropriate charset 242 and language [12]. 244 6. Failure Packet 246 The Failure packet is identical in format to the standard CHAP Failure 247 packet. There is, however, formatted text stored in the Message field 248 which, contrary to the standard CHAP rules, does affect the operation of 249 the protocol. The Message field format is: 251 "E=eeeeeeeeee R=r C=cccccccccccccccccccccccccccccccc V=vvvvvvvvvv M=" 253 where 255 The "eeeeeeeeee" is the ASCII representation of a decimal error 256 code (need not be 10 digits) corresponding to one of those listed 257 below, though implementations should deal with codes not on this 258 list gracefully. 260 646 ERROR_RESTRICTED_LOGON_HOURS 261 647 ERROR_ACCT_DISABLED 262 648 ERROR_PASSWD_EXPIRED 263 649 ERROR_NO_DIALIN_PERMISSION 264 691 ERROR_AUTHENTICATION_FAILURE 265 709 ERROR_CHANGING_PASSWORD 267 The "r" is an ASCII flag set to '1' if a retry is allowed, and '0' 268 if not. When the authenticator sets this flag to '1' it disables 269 short timeouts, expecting the peer to prompt the user for new 270 credentials and resubmit the response. 272 The "cccccccccccccccccccccccccccccccc" is the ASCII representation 273 of a hexadecimal challenge value. This field MUST be exactly 32 274 octets long and MUST be present. 276 The "vvvvvvvvvv" is the ASCII representation of a decimal version 277 code (need not be 10 digits) indicating the password changing 278 protocol version supported on the server. For MS-CHAP-V2, this 279 value SHOULD always be 3. 281 is human-readable text in the appropriate charset and 282 language [12]. 284 7. Change-Password Packet 286 The Change-Password packet does not appear in either standard CHAP or 287 MS-CHAP-V1. It allows the peer to change the password on the account 288 specified in the preceding Response packet. The Change-Password packet 289 should be sent only if the authenticator reports ERROR_PASSWD_EXPIRED 290 (E=648) in the Message field of the Failure packet. 292 This packet type is supported by recent versions of Windows NT 4.0, 293 Windows 95 and Windows 98. It is not supported by Windows NT 3.5, 294 Windows NT 3.51, or early versions of Windows NT 4.0, Windows 95 and 295 Windows 98. 297 The format of this packet is as follows: 299 1 octet : Code 300 1 octet : Identifier 301 2 octets : Length 302 516 octets : Encrypted-Password 303 16 octets : Encrypted-Hash 304 16 octets : Peer-Challenge 305 8 octets : Reserved 306 24 octets : NT-Response 307 2-octet : Flags 309 Code 310 7 312 Identifier 313 The Identifier field is one octet and aids in matching requests 314 and replies. The value is the Identifier of the received Failure 315 packet to which this packet responds plus 1. 317 Length 318 586 320 Encrypted-Password 321 This field contains the PWBLOCK form of the new Windows NT 322 password encrypted with the old Windows NT password hash, as 323 output by the NewPasswordEncryptedWithOldNtPasswordHash() routine 324 (see section 11.9, below). 326 Encrypted-Hash 327 This field contains the old Windows NT password hash encrypted 328 with the new Windows NT password hash, as output by the 329 OldNtPasswordHashEncryptedWithNewNtPasswordHash() routine (see 330 section 11.12, below). 332 Peer-Challenge 333 A 16-octet random quantity, as described in the Response packet 334 description. 336 Reserved 337 8 octets, must be zero. 339 NT-Response 340 The NT-Response field (as described in the Response packet 341 description), but calculated on the new password and the challenge 342 received in the Failure packet. 344 Flags 345 This field is two octets in length. It is a bit field of option 346 flags where 0 is the least significant bit of the 16-bit quantity. 347 The format of this field is illustrated in the following diagram: 349 1 350 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 351 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 352 | | 353 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 355 Bits 0-15 356 Reserved, always clear (0). 358 8. Pseudocode 360 The routines mentioned in the text above are described in pseudocode in 361 the following sections. 363 8.1. GenerateNTResponse() 365 GenerateNTResponse( 366 IN 16-octet AuthenticatorChallenge, 367 IN 16-octet PeerChallenge, 368 IN 0-to-256-char UserName, 369 IN 0-to-256-unicode-char Password, 370 OUT 24-octet Response ) 371 { 372 8-octet Challenge 373 16-octet PasswordHash 375 ChallengeHash( PeerChallenge, AuthenticatorChallenge, UserName, 376 giving Challenge) 378 NtPasswordHash( Password, giving PasswordHash ) 379 ChallengeResponse( Challenge, PasswordHash, giving Response ) 380 } 382 8.2. ChallengeHash() 384 ChallengeHash( 385 IN 16-octet PeerChallenge, 386 IN 16-octet AuthenticatorChallenge, 387 IN 0-to-256-char UserName, 388 OUT 8-octet Challenge 389 { 391 /* 392 * SHAInit(), SHAUpdate() and SHAFinal() functions are an 393 * implementation of Secure Hash Algorithm (SHA-1) [11]. These are 394 * available in public domain or can be licensed from 395 * RSA Data Security, Inc. 396 */ 398 SHAInit(Context) 399 SHAUpdate(Context, PeerChallenge, 16) 400 SHAUpdate(Context, AuthenticatorChallenge, 16) 402 /* 403 * Only the user name (as presented by the peer and 404 * excluding any prepended domain name) 405 * is used as input to SHAUpdate(). 406 */ 408 SHAUpdate(Context, UserName, strlen(Username)) 409 SHAFinal(Context, Digest) 410 memcpy(Challenge, Digest, 8) 411 } 413 8.3. NtPasswordHash() 415 NtPasswordHash( 416 IN 0-to-256-unicode-char Password, 417 OUT 16-octet PasswordHash ) 418 { 419 /* 420 * Use the MD4 algorithm [5] to irreversibly hash Password 421 * into PasswordHash. Only the password is hashed without 422 * including any terminating 0. 423 */ 424 } 426 8.4. HashNtPasswordHash() 428 HashNtPasswordHash( 429 IN 16-octet PasswordHash, 430 OUT 16-octet PasswordHashHash ) 431 { 432 /* 433 * Use the MD4 algorithm [5] to irreversibly hash 434 * PasswordHash into PasswordHashHash. 435 */ 436 } 438 8.5. ChallengeResponse() 440 ChallengeResponse( 441 IN 8-octet Challenge, 442 IN 16-octet PasswordHash, 443 OUT 24-octet Response ) 444 { 445 Set ZPasswordHash to PasswordHash zero-padded to 21 octets 447 DesEncrypt( Challenge, 448 1st 7-octets of ZPasswordHash, 449 giving 1st 8-octets of Response ) 451 DesEncrypt( Challenge, 452 2nd 7-octets of ZPasswordHash, 453 giving 2nd 8-octets of Response ) 455 DesEncrypt( Challenge, 456 3rd 7-octets of ZPasswordHash, 457 giving 3rd 8-octets of Response ) 458 } 460 8.6. DesEncrypt() 462 DesEncrypt( 463 IN 8-octet Clear, 464 IN 7-octet Key, 465 OUT 8-octet Cypher ) 466 { 467 /* 468 * Use the DES encryption algorithm [4] in ECB mode [10] 469 * to encrypt Clear into Cypher such that Cypher can 470 * only be decrypted back to Clear by providing Key. 471 * Note that the DES algorithm takes as input a 64-bit 472 * stream where the 8th, 16th, 24th, etc. bits are 473 * parity bits ignored by the encrypting algorithm. 474 * Unless you write your own DES to accept 56-bit input 475 * without parity, you will need to insert the parity bits 476 * yourself. 477 */ 478 } 480 8.7. GenerateAuthenticatorResponse() 482 GenerateAuthenticatorResponse( 483 IN 0-to-256-unicode-char Password, 484 IN 24-octet NT-Response, 485 IN 16-octet PeerChallenge, 486 IN 16-octet AuthenticatorChallenge, 487 IN 0-to-256-char UserName, 488 OUT 42-octet AuthenticatorResponse ) 489 { 490 16-octet PasswordHash 491 16-octet PasswordHashHash 492 8-octet Challenge 494 /* 495 * "Magic" constants used in response generation 496 */ 498 Magic1[39] = 499 {0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 500 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 501 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 502 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74}; 504 Magic2[41] = 505 {0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 506 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 507 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 508 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 509 0x6E}; 511 /* 512 * Hash the password with MD4 513 */ 515 NtPasswordHash( Password, giving PasswordHash ) 517 /* 518 * Now hash the hash 519 */ 521 HashNtPasswordHash( PasswordHash, giving PasswordHashHash) 523 SHAInit(Context) 524 SHAUpdate(Context, PasswordHashHash, 16) 525 SHAUpdate(Context, NTResponse, 24) 526 SHAUpdate(Context, Magic1, 39) 527 SHAFinal(Context, Digest) 529 ChallengeHash( PeerChallenge, AuthenticatorChallenge, UserName, 530 giving Challenge) 532 SHAInit(Context) 533 SHAUpdate(Context, Digest, 20) 534 SHAUpdate(Context, Challenge, 8) 535 SHAUpdate(Context, Magic2, 41) 536 SHAFinal(Context, Digest) 538 /* 539 * Encode the value of 'Digest' as "S=" followed by 540 * 40 ASCII hexadecimal digits and return it in 541 * AuthenticatorResponse. 542 * For example, 543 * "S=0123456789ABCDEF0123456789ABCDEF01234567" 544 */ 546 } 548 8.8. CheckAuthenticatorResponse() 550 CheckAuthenticatorResponse( 551 IN 0-to-256-unicode-char Password, 552 IN 24-octet NtResponse, 553 IN 16-octet PeerChallenge, 554 IN 16-octet AuthenticatorChallenge, 555 IN 0-to-256-char UserName, 556 IN 42-octet ReceivedResponse, 557 OUT Boolean ResponseOK ) 558 { 560 20-octet MyResponse 562 set ResponseOK = FALSE 563 GenerateAuthenticatorResponse( Password, NtResponse, PeerChallenge, 564 AuthenticatorChallenge, UserName, 565 giving MyResponse) 567 if (MyResponse = ReceivedResponse) then set ResponseOK = TRUE 568 return ResponseOK 569 } 571 8.9. NewPasswordEncryptedWithOldNtPasswordHash() 573 datatype-PWBLOCK 574 { 575 256-unicode-char Password 576 4-octets PasswordLength 577 } 579 NewPasswordEncryptedWithOldNtPasswordHash( 580 IN 0-to-256-unicode-char NewPassword, 581 IN 0-to-256-unicode-char OldPassword, 582 OUT datatype-PWBLOCK EncryptedPwBlock ) 583 { 584 NtPasswordHash( OldPassword, giving PasswordHash ) 586 EncryptPwBlockWithPasswordHash( NewPassword, 587 PasswordHash, 588 giving EncryptedPwBlock ) 589 } 591 8.10. EncryptPwBlockWithPasswordHash() 593 EncryptPwBlockWithPasswordHash( 594 IN 0-to-256-unicode-char Password, 595 IN 16-octet PasswordHash, 596 OUT datatype-PWBLOCK PwBlock ) 597 { 599 Fill ClearPwBlock with random octet values 600 PwSize = lstrlenW( Password ) * sizeof( unicode-char ) 601 PwOffset = sizeof( ClearPwBlock.Password ) - PwSize 602 Move PwSize octets to (ClearPwBlock.Password + PwOffset ) from Password 603 ClearPwBlock.PasswordLength = PwSize 604 Rc4Encrypt( ClearPwBlock, 605 sizeof( ClearPwBlock ), 606 PasswordHash, 607 sizeof( PasswordHash ), 608 giving PwBlock ) 609 } 611 8.11. Rc4Encrypt() 613 Rc4Encrypt( 614 IN x-octet Clear, 615 IN integer ClearLength, 616 IN y-octet Key, 617 IN integer KeyLength, 618 OUT x-octet Cypher ) 619 { 620 /* 621 * Use the RC4 encryption algorithm [6] to encrypt Clear of 622 * length ClearLength octets into a Cypher of the same length 623 * such that the Cypher can only be decrypted back to Clear 624 * by providing a Key of length KeyLength octets. 625 */ 626 } 628 8.12. OldNtPasswordHashEncryptedWithNewNtPasswordHash() 630 OldNtPasswordHashEncryptedWithNewNtPasswordHash( 631 IN 0-to-256-unicode-char NewPassword, 632 IN 0-to-256-unicode-char OldPassword, 633 OUT 16-octet EncryptedPasswordHash ) 634 { 635 NtPasswordHash( OldPassword, giving OldPasswordHash ) 636 NtPasswordHash( NewPassword, giving NewPasswordHash ) 637 NtPasswordHashEncryptedWithBlock( OldPasswordHash, 638 NewPasswordHash, 639 giving EncryptedPasswordHash ) 640 } 642 8.13. NtPasswordHashEncryptedWithBlock() 644 NtPasswordHashEncryptedWithBlock( 645 IN 16-octet PasswordHash, 646 IN 16-octet Block, 647 OUT 16-octet Cypher ) 648 { 649 DesEncrypt( 1st 8-octets PasswordHash, 650 1st 7-octets Block, 651 giving 1st 8-octets Cypher ) 653 DesEncrypt( 2nd 8-octets PasswordHash, 654 2nd 7-octets Block, 655 giving 2nd 8-octets Cypher ) 656 } 658 9. Examples 660 The following sections include protocol negotiation and hash generation 661 examples. 663 9.1. Negotiation Examples 665 Here are some examples of typical negotiations. The peer is on the left 666 and the authenticator is on the right. 668 The packet sequence ID is incremented on each authentication retry 669 response and on the change password response. All cases where the 670 packet sequence ID is updated are noted below. 672 Response retry is never allowed after Change Password. Change Password 673 may occur after response retry. 675 9.1.1. Successful authentication 677 <- Authenticator Challenge 678 Peer Response/Challenge -> 679 <- Success/Authenticator Response 681 (Authenticator Response verification succeeds, call continues) 683 9.1.2. Authenticator authentication failure 685 <- Authenticator Challenge 686 Peer Response/Challenge -> 687 <- Success/Authenticator Response 689 (Authenticator Response verification fails, peer disconnects) 691 9.1.3. Failed authentication with no retry allowed 693 <- Authenticator Challenge 694 Peer Response/Challenge -> 695 <- Failure (E=691 R=0) 697 (Authenticator disconnects) 699 9.1.4. Successful authentication after retry 701 <- Authenticator Challenge 702 Peer Response/Challenge -> 703 <- Failure (E=691 R=1), disable short timeout 704 Response (++ID) to challenge in failure message -> 705 <- Success/Authenticator Response 707 (Authenticator Response verification succeeds, call continues) 709 9.1.5. Failed hack attack with 3 attempts allowed 711 <- Authenticator Challenge 712 Peer Response/Challenge -> 713 <- Failure (E=691 R=1), disable short timeout 714 Response (++ID) to challenge in Failure message -> 715 <- Failure (E=691 R=1), disable short timeout 716 Response (++ID) to challenge in Failure message -> 717 <- Failure (E=691 R=0) 719 9.1.6. Successful authentication with password change 721 <- Authenticator Challenge 722 Peer Response/Challenge -> 723 <- Failure (E=648 R=0 V=3), disable short timeout 724 ChangePassword (++ID) to challenge in Failure message -> 725 <- Success/Authenticator Response 727 (Authenticator Response verification succeeds, call continues) 728 9.1.7. Successful authentication with retry and password change 730 <- Authenticator Challenge 731 Peer Response/Challenge -> 732 <- Failure (E=691 R=1), disable short timeout 733 Response (++ID) to first challenge+23 -> 734 <- Failure (E=648 R=0 V=2), disable short timeout 735 ChangePassword (++ID) to first challenge+23 -> 736 <- Success/Authenticator Response 738 (Authenticator Response verification succeeds, call continues) 740 9.2. Hash Example 742 Intermediate values for user name "User" and password "clientPass". All 743 numeric values are hexadecimal. 745 0-to-256-char UserName: 746 55 73 65 72 748 0-to-256-unicode-char Password: 749 63 00 6C 00 69 00 65 00 6E 00 74 00 50 00 61 00 73 00 73 00 751 16-octet AuthenticatorChallenge: 752 5B 5D 7C 7D 7B 3F 2F 3E 3C 2C 60 21 32 26 26 28 754 16-octet PeerChallenge: 755 21 40 23 24 25 5E 26 2A 28 29 5F 2B 3A 33 7C 7E 757 8-octet Challenge: 758 D0 2E 43 86 BC E9 12 26 760 16-octet PasswordHash: 761 44 EB BA 8D 53 12 B8 D6 11 47 44 11 F5 69 89 AE 763 24 octet NT-Response: 764 82 30 9E CD 8D 70 8B 5E A0 8F AA 39 81 CD 83 54 42 33 11 4A 3D 85 D6 DF 766 16-octet PasswordHashHash: 767 41 C0 0C 58 4B D2 D9 1C 40 17 A2 A1 2F A5 9F 3F 769 42-octet AuthenticatorResponse: 770 "S=407A5589115FD0D6209F510FE9C04566932CDA56" 772 9.3. Example of DES Key Generation 774 DES uses 56-bit keys, expanded to 64 bits by the insertion of parity 775 bits. After the parity of the key has been fixed, every eighth bit is a 776 parity bit and the number of bits that are set (1) in each octet is odd; 777 i.e., odd parity. Note that many DES engines do not check parity, 778 however, simply stripping the parity bits. The following example 779 illustrates the values resulting from the use of the password "MyPw" to 780 generate a pair of DES keys (e.g., for use in the 781 NtPasswordHashEncryptedWithBlock() described in section 11.13). 783 0-to-256-unicode-char Password: 784 4D 79 50 77 786 16-octet PasswordHash: 787 FC 15 6A F7 ED CD 6C 0E DD E3 33 7D 42 7F 4E AC 789 First "raw" DES key (initial 7 octets of password hash): 790 FC 15 6A F7 ED CD 6C 792 First parity-corrected DES key (eight octets): 793 FD 0B 5B 5E 7F 6E 34 D9 795 Second "raw" DES key (second 7 octets of password hash) 796 0E DD E3 33 7D 42 7F 798 Second parity-corrected DES key (eight octets): 799 0E 6E 79 67 37 EA 08 FE 801 10. Security Considerations 803 As an implementation detail, the authenticator SHOULD limit the number 804 of password retries allowed to make brute-force password guessing 805 attacks more difficult. 807 11. References 809 [1] Simpson, W., "The Point-to-Point Protocol (PPP)", STD 51, RFC 1661, 810 July 1994 812 [2] Simpson, W., "PPP Challenge Handshake Authentication Protocol 813 (CHAP)", RFC 1994, August 1996 815 [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement 816 Levels", BCP 14, RFC 2119, March 1997 818 [4] "Data Encryption Standard (DES)", Federal Information Processing 819 Standard Publication 46-2, National Institute of Standards and 820 Technology, December 1993 822 [5] Rivest, R., "MD4 Message Digest Algorithm", RFC 1320, April 1992. 824 [6] RC4 is a proprietary encryption algorithm available under license 825 from RSA Data Security Inc. For licensing information, contact: 826 RSA Data Security, Inc. 827 100 Marine Parkway 828 Redwood City, CA 94065-1031 830 [7] Eastlake, D., et. al., "Randomness Recomnendations for Security", 831 RFC 1750, December 1994 833 [8] "The Unicode Standard, Version 2.0", The Unicode Consortium, 834 Addison-Wesley, 1996. ISBN 0-201-48345-9. 836 [9] Zorn, G. and Cobb, S., "Microsoft PPP CHAP Extensions", RFC 2433, 837 October 1998 839 [10] "DES Modes of Operation", Federal Information Processing Standards 840 Publication 81, National Institute of Standards and Technology, 841 December 1980 843 [11] "Secure Hash Standard", Federal Information Processing Standards 844 Publication 180-1, National Institute of Standards and Technology, 845 April 1995 847 [12] Zorn, G., "PPP LCP Internationalization Configuration Option", RFC 848 2484, January 1999 850 12. Acknowledgements 852 Thanks (in no particular order) to Bruce Johnson, Tony Bell, Paul Leach, 853 Terence Spies, Dan Simon, Narendra Gidwani, Gurdeep Singh Pall, Jody 854 Terrill, Brad Robel-Forrest, and Joe Davies for useful suggestions and 855 feedback. 857 13. Chair's Address 859 The PPP Extensions Working Group can be contacted via the current chair: 861 Karl Fox 862 Ascend Communications 863 3518 Riverside Drive 864 Suite 101 865 Columbus, OH 43221 867 Phone: +1 614 326 6841 868 Email: karl@ascend.com 870 14. Author's Address 872 Questions about this memo can also be directed to: 874 Glen Zorn 875 Microsoft Corporation 876 One Microsoft Way 877 Redmond, Washington 98052 879 Phone: +1 425 703 1559 880 FAX: +1 425 936 7329 881 EMail: gwz@acm.org 883 15. Expiration Date 885 This memo is filed as and expires 886 on October 25, 1999.