6 Network Working Group C. Newman
7 Internet Draft: SCRAM-MD5 SASL Mechanism Innosoft
8 Document: draft-newman-auth-scram-03.txt March 1998
12 Salted Challenge Response Authentication Mechanism (SCRAM)
17 This document is an Internet-Draft. Internet-Drafts are working
18 documents of the Internet Engineering Task Force (IETF), its areas,
19 and its working groups. Note that other groups may also distribute
20 working documents as Internet-Drafts.
22 Internet-Drafts are draft documents valid for a maximum of six
23 months and may be updated, replaced, or obsoleted by other
24 documents at any time. It is inappropriate to use Internet-Drafts
25 as reference material or to cite them other than as "work in
28 To view the entire list of current Internet-Drafts, please check
29 the "1id-abstracts.txt" listing contained in the Internet-Drafts
30 Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net
31 (Europe), munnari.oz.au (Pacific Rim), ds.internic.net (US East
32 Coast), or ftp.isi.edu (US West Coast).
37 SCRAM is a simple passphrase-based SASL [SASL] authentication
38 mechanism suitable for a wide variety of usage scenarios. It
39 combines good properties of CRAM-MD5 [CRAM-MD5] and OTP [OTP], adds
40 some management features and some protection from active attacks
41 without a significant increase in complexity. SCRAM is intended
42 for use with services which need a simple, fast and flexible
43 authentication mechanism.
45 [NOTE: Public discussion of this mechanism may take place on the
46 ietf-sasl@imc.org mailing list with a subscription address of
47 ietf-sasl-request@imc.org. Private comments may be sent to the
51 1. How to Read This Document
53 This document has information for several different audiences.
59 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
62 Section 2 provides an introduction to SCRAM. Sections 3-6 and 9
63 are intended for implementors. Section 7 is intended for system
64 administrators. Sections 7-10 are intended for security
67 The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT" and "MAY"
68 in this document are to be interpreted as defined in "Key words for
69 use in RFCs to Indicate Requirement Levels" [KEYWORDS].
74 This section describes the design goals, an overview of how SCRAM
75 operates and the intended use of SCRAM in comparison to OTP.
80 The perfect authentication mechanism would be simple, fast, strong,
81 use publicly available source code and be backwards compatible with
82 deployed back-end authentication databases. It is impossible to
83 achieve all these goals so tradeoffs must be made. SCRAM has
84 simplicity, speed and protection from passive and active attacks on
85 the connection (with the exception of dictionary attacks) as
86 primary design goals. It has managability, backwards compatibility
87 with CRAM-MD5 intermediate HMAC state verifiers, some protection
88 from a compromised authentication database and publicly
89 distributable source code as secondary design goals.
91 SCRAM has the following characteristics:
93 o It is a simple passphrase-based mechanism which does not require
94 complicated infrastructures or public key technology. The
95 majority of the source code necessary to implement SCRAM is
96 included in the MD5 specification [MD5] and Appendices B and C
97 of this specification.
99 o It does not require plain-text-equivalent verifiers on the
100 server, so it improves network security over traditional
101 plain-text password systems without eliminating security of the
102 server authentication database.
104 o It supports proxy authentication by including an authorization
105 identity (user to login as) separate from the authentication
106 identity (server authentication database entry to use).
108 o It supports mutual authentication.
115 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
118 o It supports a limited service trust management model. This
119 means a centralized authentication server could restrict the
120 services offered by application servers.
122 o It is backwards-compatible with CRAM-MD5 server authentication
125 o It includes an optional SASL integrity protection layer for
126 lightweight protection from many active attacks.
129 2.2. Basic Operation of SCRAM
131 SCRAM is built using only a simple one-way hash function, the HMAC
132 [HMAC] construction and the exclusive-or operation. There are
133 three fundamental components to the exchange:
135 o the client key which is derived from the passphrase and salt
137 o the client verifier which is simply the one-way hash function
138 applied to the client key
140 o the server key which is also derived from the passphrase and
143 The server has access to the salt, client verifier and server key
144 for each user. The salt and client verifier are used to
145 authenticate the client to the server and the salt and server key
146 are used to authenticate the server to the client.
148 The mechanism relies on the one-way characteristic of the hash
149 function to assure that the client key can't be derived from the
150 client verifier and that the server key can't be derived from
151 either the client key or client verifier.
153 SCRAM uses HMAC to sign client and server nonces with the client
154 verifier to produce a shared key. The client exclusive-ors the
155 shared key with the client key and sends that to the server which
156 uses the shared key to reverse the exclusive-or operation, extract
157 the client key, and then verify that the hash function applied to
158 the client key matches the client verifier. The server uses HMAC
159 to sign the client and server nonces with the server key and sends
160 that to the client to authenticate.
164 SCRAM is designed for a usage scenario where simplicity and/or
165 speed is important, frequent authentications may occur and the
171 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
174 primary threat is passive and active network attacks. A good
175 example of protocols whose usage and threat model fit SCRAM are
176 IMAP [IMAP4] and POP3 [POP3]. SCRAM provides limited protection
177 against threats to the server authentication database, but OTP
178 [OTP] may be preferable for usage scenarios where the threat to the
179 server is more serious and active attacks are not an issue.
182 3. Client Implementation of SCRAM-MD5
184 This section includes a step-by-step guide for client implementors.
185 Section 6 contains the formal definition of the syntax and is the
186 authoritative reference in case of errors here.
188 When used with SASL the mechanism name is "SCRAM-MD5". The
189 mechanism does not provide a privacy layer, but does include an
190 optional integrity protection layer.
192 The client begins by sending a message to the server containing the
193 following three pieces of information.
195 (1) An authorization identity. When the empty string is used, this
196 defaults to the authentication identity. This is used by system
197 administrators or proxy servers to login with a different user
198 identity. This field may be up to 255 octets and is terminated by
199 a NUL (0) octet. US-ASCII printable characters are preferred,
200 although UTF-8 [UTF-8] printable characters are permitted to
201 support international names. Use of character sets other than
202 US-ASCII and UTF-8 is forbidden.
204 (2) An authentication identity. The identity whose passphrase will
205 be used. This field may be up to 255 octets and is terminated by a
206 NUL (0) octet. US-ASCII printable characters are preferred,
207 although UTF-8 [UTF-8] printable characters are permitted to
208 support international names. Use of character sets other than
209 US-ASCII and UTF-8 is forbidden.
211 (3) A "client nonce." It is important that this be globally
212 unique. One common technique for generating globally unique
213 identifiers combines a process identifier with the system clock, a
214 sequence number, a random number and the client's domain name. The
215 random number is important as clocks are often synchronized using
216 insecure protocols and are predictable. Advice for generating good
217 random numbers can be found in [RANDOM].
219 The server responds by sending a message containing three pieces of
227 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
230 (4) An 8-octet salt value, specific to the authentication identity.
232 (5) A one-octet bit-mask specifying security layers supported by
233 the server. Bit 0 (value 1) indicates support for no security
234 layer and bit 1 (value 2) indicates support for an integrity
235 protection layer. The other bits are reserved for future use (the
236 server MUST set them to zero until they are defined in a standards
237 track specification). If the client doesn't support a security
238 layer and bit 0 is cleared, then the authentication immediately
241 (6) A three-octet number in network byte order (big endian),
242 containing the maximum cipher-text buffer size the server is able
243 to receive. This may be 0 if the server supports no security
246 (7) A service id consisting of the service name of the protocol's
247 SASL profile followed by an "@" followed by the domain name of the
248 server and terminated by NUL. The client SHOULD verify this is
251 (8) A "server nonce". As the domain name is included in (7), this
252 only has to be unique to the server.
254 The client then does the following:
256 (A) Create a buffer containing the user's passphrase. The client
257 MUST support passphrases of at least 64 octets. US-ASCII
258 characters are preferred, although UTF-8 characters are permitted.
259 Character sets other than US-ASCII and UTF-8 MUST NOT be used.
261 (B) Apply the HMAC-MD5 function with (A) as the key and the 8-octet
262 salt as the data, producing a 16-octet result. Once this is done,
263 (A) SHOULD be erased from memory.
265 (C) Apply the MD5 function to the result of (B). This produces a
268 (D) Apply the MD5 function to the result of (C). This produces a
271 (E) Create a buffer containing the server's response (4)-(8),
272 immediately followed by the initial client message (1)-(3) and the
273 client's security layer selection (9)-(10) below.
275 (F) Apply the HMAC-MD5 function with the result of (D) as the key
276 and the buffer from (E) as the data. This produces a 16-octet
283 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
286 (G) Create a 16-octet buffer containing the exclusive-or of (C) and
289 The client then sends a message to the server containing the
292 (9) A bit-mask indicating the client selected security layer from
293 step (5). This has a value of 01 for no security layer and 02 for
294 an integrity protection layer.
296 (10) A three octet number indicating the maximum cipher-text buffer
297 size the client is able to receive in network byte order. If the
298 client doesn't select a security layer, this may be all zeros.
300 (11) The 16-octet result of step (G).
302 The server will respond with:
304 (12) A 16-octet server authentication verifier.
306 The client SHOULD verify this with the following procedure:
308 (H) Apply the HMAC-MD5 function with the result of (B) as the key
309 and the 8-octet salt as the data. This produces a 16-octet result.
311 (I) Create a buffer containing the initial client message (1)-(3)
312 immediately followed by the initial server response (4)-(8) and the
313 client's security layer selection (9)-(10).
315 (J) Apply the HMAC-MD5 function with the result of (H) as the key
316 and the buffer from (I) as the data.
318 (K) If the result of (J) matches (12), the server is authenticated.
320 A secured client MAY store the result of (B) to re-authenticate to
321 services using the same salt, or the intermediate HMAC state from
322 (B) to re-authenticate to any service. Clients SHOULD NOT store
323 the passphrase itself.
325 If integrity protection is negotiated on, the following procedure
326 is applied to each SASL security layer packet sent by the client:
328 (L) Apply the HMAC-MD5 function with the output of step (C) as the
329 key and the buffer from step (E) as the value.
331 (M) A buffer is created containing a four octet client packet
332 number in network byte order followed by the 16-octet output of
333 step (L). The first packet sent under the SASL security layer is
339 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
344 (N) Apply the HMAC-MD5 function with (M) as the key and the
345 contents of the packet as the data. The result is appended to the
348 The integrity protection on packets from the server is verified as
351 (O) A buffer is created containing a four octet server packet
352 number in network byte order followed by the 16-octet output of
353 step (L) above. This first packet sent under the SASL security
354 layer is given number 1.
356 (P) Apply the HMAC-MD5 function with (O) as the key and all but the
357 last 16 octets of the packet as the value.
359 (Q) Compare the last 16 octets of the packet to the output of (P).
360 If they do not match, an integrity error is produced.
363 4. Server Implementation of SCRAM-MD5
365 The section includes a step-by-step guide for server implementors
366 building on the previous section. Section 6 contains the formal
367 definition of the syntax and is the authoritative reference in case
370 The server's authentication database contains an 8-octet salt,
371 16-octet client verifier and a 16-octet server key for each local
372 user. The server MUST support "user@host" syntax for the
373 authentication identity at least to the extent of stripping "@host"
374 when it matches the local host name or rejecting the authentication
375 if the host name doesn't match. The server MAY support remote user
376 authentication using this syntax.
378 The stored client verifier is equal to the result of step (D)
379 above, and the stored server key is equal to the result of step (H)
380 above. To create its initial response, the server simply looks up
381 the authentication identity to fetch the salt, and generates an 8
382 to 248 octet nonce. This nonce MUST be unique for the server to
383 prevent replay attacks. It can be generated by appending a system
384 clock to a process and/or thread identifier and a random number
385 [RANDOM]. To verify the client's credentials, the server performs
388 (a) Generate a buffer identical to step (E) above.
395 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
398 (b) Apply the HMAC-MD5 function with the stored client verifier as
399 the key and the result of (a) as the data. This produces a
400 16-octet result equal to step (F) above.
402 (c) Exclusive-or the result of (b) with message (11) from the
403 client. This produces a 16-octet result which should be equal to
404 the result of step (C) above.
406 (d) Apply the MD5 function to the output of step (c). This
407 produces a 16-octet result which should be equal to the result of
410 (e) if the result of (d) is equal to the stored verifier, then the
411 user is authenticated.
413 If no client challenge was provided in step (3), the server is now
414 done and responds with the appropriate status code. Otherwise the
415 server continues as follows:
417 (f) Generate a buffer identical to step (I) above.
419 (g) Apply the HMAC-MD5 function with the stored server verifier as
420 the key and the buffer from (f) as the data. This produces a
423 The result of (g) is sent to the client to authenticate the server.
425 If integrity protection is negotiated on, the integrity key is
428 (h) Apply the HMAC-MD5 function with the output of step (c) as the
429 key and the buffer from step (a) as the data.
431 Integrity generation and verification works in the same fashion as
437 In these examples, "C:" represents lines sent from the client to
438 the server and "S:" represents lines sent from the server to the
439 client. The wrapped lines are for editorial clarity -- there are
440 no actual newlines in the middle of the messages.
442 The following is an example of the SCRAM-MD5 mechanism using the
443 IMAP [IMAP4] profile of SASL. For this example, the user "chris",
444 with an empty authorization identity is using the passphrase
445 "secret stuff". The client nonce is
451 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
454 "<t4n4Pab9HB0Am/QLXB72eg@eleanor.innosoft.com>" and the server
455 nonce is "jhcNZlRuPbziFp+vLV+NCw". No security layer is supported,
456 the salt is "testsalt" and the service identity is
457 "imap@eleanor.innosoft.com". The complete 40 octet verifier stored
458 on the server, in hexadecimal is "74657374 73616c74 16484d56
459 7ee02f47 ac5f8a5a d5795570 90d55334 d2002df6 24cb8c8b 75708f4e."
461 C: a001 AUTHENTICATE SCRAM-MD5
463 C: AGNocmlzADx0NG40UGFiOUhCMEFtL1FMWEI3MmVnQGVsZWFub3IuaW
465 S: + dGVzdHNhbHQBAAAAaW1hcEBlbGVhbm9yLmlubm9zb2Z0LmNvbQBq
466 aGNOWmxSdVBiemlGcCt2TFYrTkN3
467 C: AQAAAMg9jU8CeB4KOfk7sUhSQPs=
468 S: + U0odqYw3B7XIIW0oSz65OQ==
470 S: a001 OK AUTHENTICATE completed
472 Note that base64 encoding and the lack of an initial client
473 response with the first command are characteristics of the IMAP
474 profile of SASL and not characteristics of SASL or SCRAM-MD5. Here
475 is another example using the ACAP [ACAP] profile of SASL. This
476 uses the same salt, passphrase and verifier as the previous
477 example. In this example, binary data is represented as
478 hexadecimal digits enclosed in square brackets:
480 C: a001 AUTHENTICATE "SCRAM-MD5" {52}
481 C: [00]chris[00]<HSMDKNj0yFGa8f5swzqznw@eleanor.innosoft.com>
483 S: testsalt[01000000]acap@eleanor.innosoft.com[00]
484 m6HdEYWZA5W8keNbiY40aA
486 C: [01000000 19b66406 4ce8138a e0af7b0b f0ed20ea]
487 S: a001 OK (SASL {16}
488 S: [44d7c1c4 0630fea6 5c49cb40 717a2ba5]) "Successful"
490 Note that arbitrary binary values may be used for the salt and
491 nonces, as long as the client nonce is globally unique.
494 6. Formal Syntax of SCRAM-MD5 Messages
496 This is the formal syntactic definition of the client and server
497 messages. This uses ABNF [ABNF] notation including the core rules.
499 client-msg-1 = [authorize-id] NUL authenticate-id NUL nonce
501 server-msg-1 = salt security-info service-id NUL nonce
507 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
510 client-msg-2 = security-info client-proof
512 server-msg-2 = server-proof
514 passphrase = *UTF8-SAFE
515 ;; At least 64 octets MUST be supported
517 authorize-id = *UTF8-PRINT
518 ;; No more than 255 octets
520 authenticate-id = *UTF8-PRINT
521 ;; No more than 255 octets
523 security-info = secbits bufsize
526 ;; in network byte order (big-endian)
529 ;; bit 0 = no protection, bit 1 = integrity,
530 ;; other bits set to 0 and reserved
532 service-id = service-name "@" server-domain
534 service-name = *VCHAR
535 ;; a SASL/GSSAPI service name
537 server-domain = *VCHAR
538 ;; an internet domain name
544 client-proof = 16OCTET
546 server-proof = 16OCTET
548 NUL = %x00 ;; US-ASCII NUL character
550 UTF8-SAFE = %x01-09 / %x0B-0C / %x0E-7F / UTF8-MULTI
551 ;; Any character except CR, LF, NUL
553 UTF8-PRINT = %x20-7E / UTF8-MULTI
554 ;; Any character except CTLs
556 UTF8-MULTI = UTF8-2 / UTF8-3 / UTF8-4 / UTF8-5 / UTF8-6
557 ;; UTF-8 Multi-octet characters
563 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
568 UTF8-2 = %xC0-DF UTF8-1
570 UTF8-3 = %xE0-EF 2UTF8-1
572 UTF8-4 = %xF0-F7 3UTF8-1
574 UTF8-5 = %xF8-FB 4UTF8-1
576 UTF8-6 = %xFC-FD 5UTF8-1
579 7. System Administrator Advice
581 This section includes advice for system administrators using this
584 A SCRAM server stores three pieces of information for each user: a
585 salt, a client verifier and server key. The latter two are derived
586 from the salt and the user's passphrase.
588 The salt prevents global dictionary attacks, similar to the salt
589 used in Unix /etc/passwd files. As the 12 bits of salt in Unix
590 /etc/passwd has proved to be insufficient, SCRAM uses 64 bits of
591 salt. See [SCHNEIER] for a good discussion of salt and dictionary
592 attacks. In a multi-server site, security can be increased by
593 using a different salt on each server.
595 Although the verifiers used by SCRAM-MD5 have roughly comparable
596 security to those used by current plain-text mechanisms (such as
597 Unix /etc/passwd), it is still very important to keep them secret.
598 Just as tools exist to try common passwords against Unix
599 /etc/passwd files, it is also possible to build such tools for
600 SCRAM-MD5. In addition, once a SCRAM-MD5 verifier is stolen, a
601 passive (undetectable) eavesdropper of that user logging in gains
602 the output of step (C) above, which is sufficient to impersonate
603 the user to all services with the same salt. This is better than
604 current plain-text mechanisms where a passive eavesdropper always
605 recovers the user's password, but is still a serious concern.
607 Verifiers SHOULD be kept hidden from all users on the server.
608 Sites which distribute verifiers among multiple servers, SHOULD
609 encrypt them when transferring them over the network.
611 SCRAM-MD5 is only a good mechanism if passphrases are well chosen.
612 For this reason, implementations should use the term "passphrase"
613 rather than "password" and when a user's passphrase is set, site
619 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
622 policy restrictions should be applied. A reasonably secure site
623 policy would require passphrases of at least 10 characters with at
624 least one non-alphanumeric character.
626 SCRAM-MD5 doesn't protect the privacy of data exchanged after
627 authentication. Use of TLS [TLS], IP security ESP [IPESP] or a
628 stronger SASL mechanism such as Kerberos is encouraged if this
629 functionality is needed.
632 8. SCRAM Functional Notation
634 This section is designed to provide a quick understanding of SCRAM
635 for those who like functional notation.
637 + octet concatenation
638 XOR the exclusive-or function
639 AU is the authentication user identity (NUL terminated)
640 AZ is the authorization user identity (NUL terminated)
641 if AZ is the same as AU, a single NUL is used instead.
642 csecinfo client security layer option bits and buffer size
643 ssecinfo server security layer option bits and buffer size
644 service is the name of the service and server (NUL terminated)
645 pass is the plain-text passphrase
646 H(x) is a one-way hash function applied to "x", such as MD5
647 MAC(x,y) is a message authentication code (MAC) such as HMAC-MD5
648 "y" is the key and "x" is the text signed by the key.
649 salt is a per-user salt value the server stores
650 Us is a unique nonce the server sends to the client
651 Uc is a unique nonce the client sends to the server
653 The SCRAM computations and exchange are as follows:
655 client-msg-1 = AZ + AU + Uc
656 (1) client -> server: client-msg-1
657 server-msg-1 = salt + ssecinfo + service + Us
658 (2) server -> client: server-msg-1
659 salted-pass = MAC(salt, pass)
660 client-key = H(salted-pass)
661 client-verifier = H(client-key)
662 shared-key = MAC(server-msg-1 + client-msg-1 + csecinfo,
664 client-proof = client-key XOR shared-key
665 (3) client -> server: csecinfo + client-proof
666 server-key = MAC(salt, salted-pass)
667 server-proof = MAC(client-msg-1 + server-msg-1 + csecinfo,
669 (4) server -> client: server-proof
675 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
678 integrity-key = MAC(server-msg-1 + client-msg-1 + csecinfo,
681 The server stores the salt, client-verifier and server-key. It
682 authenticates the client by computing:
684 H(client-proof XOR shared-key)
686 after step 3 and comparing it to the stored client-verifier. The
687 server computes the integrity-key with:
689 MAC(server-msg-1 + client-msg-1, client-proof XOR shared-key)
691 The client verifies the server by computing the server-proof
692 directly and comparing.
695 9. Security Considerations
697 Security considerations are discussed throughout this document.
698 The security considerations of MD5 [MD5] and HMAC [HMAC] also
699 apply. SCRAM relies primarily on the one-way characteristic of MD5
700 and HMAC-MD5 for security. The weaknesses found in MD5 are not
701 believed to impact this use. In the interest of avoiding
702 proliferation of authentication mechanisms, it is hoped that it
703 will be easy to deploy public-key technology before a hash function
704 upgrade becomes necessary.
706 SCRAM does use the output of an HMAC function and exclusive-or to
707 construct a simple 16-octet encryption function. While
708 constructing an encryption function from a hash function is
709 normally a questionable practice [SCHNEIER], in this case both the
710 key and the data are outputs of a one-way hash function with a good
711 bit-distribution and the key is used only once (as long as the
712 combined nonces are unique).
714 An analysis of different attacks follows:
716 Passive Network Attacks
718 SCRAM is resistant to replay attacks as long as the appropriate
721 SCRAM is not resistant to passive dictionary attacks. User
722 education, passphrase setting policy and external confidentiality
723 services can be used to protect against such attacks.
725 SCRAM does not protect against session data eavesdropping. An
731 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
734 external confidentiality service is necessary to protect against
735 eavesdropping. TLS [TLS] and IP security ESP [IPESP] are examples
736 of IETF standards-track mechanisms to provide confidentiality.
738 Active Network Attacks
740 If the client fails to verify the server proof, then SCRAM provides
741 no protection from active attacks.
743 SCRAM protects against server impersonation with the server mutual
746 An attacker could use SCRAM to probe for users by trying each user
747 name twice to see if the salt varies. The server can prevent this
748 attack by inventing consistent salt values for non-users. One way
749 to do this would be to store a random secret and generate the salt
750 using HMAC(user-name, random-secret).
752 SASL is susceptible to downgrade active attacks which reduce the
753 advertised authentication mechanisms to the weakest the server
754 offers. If SCRAM is the weakest mechanism, such attacks can be
755 detected if integrity protection is negotiated on and the client
756 requests a duplicate copy of the server's capability list after
757 authentication (e.g., by re-issuing the CAPABILITY command in
758 IMAP). For a protocol such as ACAP [ACAP], the server SHOULD
759 repeat the greeting line immediately after authentication is
760 completed whenever integrity protection is negotiated on.
762 SCRAM can detect insertion, deletion and modification of session
763 data only if integrity protection is negotiated on. TLS [TLS] or
764 IP security services [IPAUTH, IPESP] may also be used to protect
765 against such tampering. If TLS or IP security integrity protection
766 is active, then the SCRAM integrity layer is unnecessary and SHOULD
769 Upper level security services, such as SCRAM and TLS, can not
770 protect against denial of service attacks on the TCP/IP layer. In
771 addition, if no integrity layer is used, then SCRAM is vulnerable
772 to TCP session stealing attacks [CERT-IPSPOOF]. IP security
773 services [IPAUTH, IPESP] can protect against many of these attacks.
775 SCRAM is not susceptible to the race and denial of service attacks
776 mentioned in section 9 of the OTP specification [OTP].
780 A server implementation which does not tolerate input of any length
781 with any content may be susceptible to attacks which permit
787 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
790 privileged access to the server. For this reason server
791 implementations MUST be able to accept input of any length with any
792 content although server implementations MAY refuse to authenticate
793 the client if messages exceed the specified maximum lengths. Note
794 that the ANSI C gets() library function does not meet this
797 An attacker which has access to both the SCRAM verifier and a
798 client exchange for a particular user gains the ability to
799 impersonate that user to other servers using the same salt. An
800 external confidentiality service can make it more difficult to
801 obtain the client exchange, but can not defend against installation
802 of a trojan horse on a compromised server.
804 In the process of authentication, the server gains access to the
805 client-key which is sufficient to impersonate the user to other
806 services with the same salt.
808 The limited service trust feature (step 7 above) includes the
809 service name and the server host name. A server host which is
810 authorized to provide one service can impersonate that service at
811 other hosts in the same realm by an active attack on the DNS system
812 when used by the client. Use of secure DNS [DNSSEC] on the client
813 limits this vulnerability.
817 As SCRAM is designed for user entry of a plain-text passphrase, it
818 is vulnerable to passphrase hijacking by trojan horse clients. OTP
819 [OTP] with an external portable OTP calculator can limit the
820 vulnerability to a single session.
823 10. Intellectual Property Issues and Prior Art
825 The author is not aware of any patents or pending patents which
826 apply to this mechanism.
828 This is primarily a derivative of simple hash-based challenge
829 response systems. The hash-based challenge response idea has
830 existed since at least 1992, when the RIPE project published the
831 SKID algorithm according to [SCHNEIER].
833 The repeated-hash idea used to verify the client's authenticator is
834 derived from S/KEY [SKEY].
836 The idea of using salt to protect against global dictionary attacks
837 dates back to at least the Unix /etc/passwd system. There is some
843 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
846 discussion of this in [SCHNEIER].
848 SCRAM combines these techniques. The author of this specification
849 first proposed this idea on a public mailing list on July 16, 1997.
852 11. Multinational Considerations
854 As remote access is a crucial service, users are encouraged to
855 restrict user names and passphrases to the US-ASCII character set.
856 However, if characters outside the US-ASCII character set are used
857 in user names and passphrases, then they are interpreted according
858 to UTF-8 [UTF-8] and it is a protocol error to include any octet
859 sequences not legal for UTF-8. Servers are encouraged to enforce
860 this restriction to discourage clients which use unlabeled
861 character sets in this context.
866 [ABNF] Crocker, Overell, "Augmented BNF for Syntax Specifications:
867 ABNF", RFC 2234, Internet Mail Consortium, Demon Internet Ltd,
870 [ACAP] Newman, Myers, "ACAP -- Application Configuration Access
871 Protocol", RFC 2244, Innosoft, Netscape, November 1997.
873 [CERT-IPSPOOF] CERT, "TCP SYN Flooding and IP Spoofing Attacks",
874 CERT CA-96.21, CERT, September 1996.
876 [CRAM-MD5] Klensin, Catoe, Krumviede, "IMAP/POP AUTHorize Extension
877 for Simple Challenge/Response", RFC 2195, MCI, September 1997.
879 [DNSSEC] Eastlake, Kaufman, "Domain Name System Security
880 Extensions", RFC 2065, CyberCash, Iris, January 1997.
882 [HMAC] Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for Message
883 Authentication", RFC 2104, IBM, UCSD, February 1997.
885 [IMAP4] Crispin, M., "Internet Message Access Protocol - Version
886 4rev1", RFC 2060, University of Washington, December 1996.
888 [IPAUTH] Atkinson, "IP Authentication Header", RFC 1826, Naval
889 Research Laboratory, August 1995.
891 [IPESP] Atkinson, "IP Encapsulating Security Payload (ESP)", RFC
892 1827, Naval Research Laboratory, August 1995.
899 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
902 [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate
903 Requirement Levels", RFC 2119, Harvard University, March 1997.
905 [MD5] Rivest, "The MD5 Message Digest Algorithm", RFC 1321, MIT
906 Laboratory for Computer Science, April 1992.
908 [OTP] Haller, Metz, "A One-Time Password System", RFC 1938,
909 Bellcore, Kaman Sciences Corporation, May 1996.
911 [OTP-EXT] Metz, "OTP Extended Responses", RFC 2243, The Inner Net,
914 [POP3] Myers, J., Rose, M., "Post Office Protocol - Version 3", RFC
915 1939, Carnegie Mellon, Dover Beach Consulting, Inc., May 1996.
917 [RANDOM] Eastlake, Crocker, Schiller, "Randomness Recommendations
918 for Security", RFC 1750, DEC, Cybercash, MIT, December 1994.
920 [SASL] Myers, "Simple Authentication and Security Layer (SASL)",
921 RFC 2222, Netscape Communications, October 1997.
923 [SCHNEIER] Schneier, "Applied Cryptography: Protocols, Algorithms
924 and Source Code in C," John Wiley and Sons, Inc., 1996.
926 [SKEY] Haller, Neil M. "The S/Key One-Time Password System", RFC
927 1760, Bellcore, February 1995.
929 [TLS] Dierks, Allen, "The TLS Protocol Version 1.0", Work in
932 [UTF8] Yergeau, F. "UTF-8, a transformation format of ISO 10646",
933 RFC 2279, Alis Technologies, January 1998.
939 Innosoft International, Inc.
941 West Covina, CA 91790 USA
943 Email: chris.newman@innosoft.com
946 A. Appendix - Additional Services
948 Several additional services are needed to make SCRAM useful in more
949 usage scenarios. These include remote authentication database
955 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
958 support for servers, authentication database APIs for servers,
959 remote passphrase change support for clients, single-sign-on APIs
960 for clients and management tools. The service-id and server-key
961 are included to facilitate the remote authentication database
962 service. Otherwise these issues are deferred for future work.
964 B. Appendix - HMAC-MD5 Sample Source Code
966 The following sample C source code calls the source code in the MD5
967 specification [MD5] and is derived from the source code in [HMAC].
968 It is needed by the SCRAM source code in the next section.
970 The client may call hmac_md5_precalc() to save the intermediate
971 HMAC result for later use in hmac_md5_import(). This can be used
972 by a CRAM-MD5 [CRAM-MD5] or a SCRAM-MD5 [SCRAM-MD5] client to save
973 an intermediate result suitable for use with any server without
974 saving the plain-text passphrase.
976 /* hmac-md5.h -- HMAC_MD5 functions
978 #define HMAC_MD5_SIZE 16
980 /* intermediate MD5 context */
981 typedef struct HMAC_MD5_CTX_s {
985 /* intermediate HMAC state
986 * values stored in network byte order (Big Endian)
988 typedef struct HMAC_MD5_STATE_s {
993 /* One step hmac computation
995 * digest may be same as text or key
997 void hmac_md5(const unsigned char *text, int text_len,
998 const unsigned char *key, int key_len,
999 unsigned char digest[HMAC_MD5_SIZE]);
1001 /* create context from key
1003 void hmac_md5_init(HMAC_MD5_CTX *hmac,
1004 const unsigned char *key, int key_len);
1011 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1014 /* precalculate intermediate state from key
1016 void hmac_md5_precalc(HMAC_MD5_STATE *hmac,
1017 const unsigned char *key, int key_len);
1019 /* initialize context from intermediate state
1021 void hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state);
1023 #define hmac_md5_update(hmac, text, text_len) \
1024 MD5Update(&(hmac)->ictx, (text), (text_len))
1026 /* finish hmac from intermediate result.
1027 * Intermediate result is erased.
1029 void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
1030 HMAC_MD5_CTX *hmac);
1033 /* hmac-md5.c -- HMAC MD5 Keyed-Hashing by Chris Newman
1034 * derived from RFC 2104 by H. Krawczyk, M. Bellare, R.Canetti
1039 #include "hmac-md5.h"
1041 /* for htonl() and ntohl() */
1042 #include <sys/types.h>
1043 #include <netinet/in.h>
1045 /* MD5 block size */
1046 #define BLOCK_SIZE 64
1048 void hmac_md5_init(HMAC_MD5_CTX *hmac,
1049 const unsigned char *key, int key_len)
1051 unsigned char k_pad[BLOCK_SIZE]; /* padded key */
1054 /* if key longer than BLOCK_SIZE bytes reset to MD5(key) */
1055 if (key_len > BLOCK_SIZE) {
1056 MD5Init(&hmac->ictx);
1057 MD5Update(&hmac->ictx, key, key_len);
1058 MD5Final(k_pad, &hmac->ictx);
1060 key_len = HMAC_MD5_SIZE;
1067 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1071 /* XOR padded key with inner pad value */
1072 for (i = 0; i < key_len; i++) {
1073 k_pad[i] = key[i] ^ 0x36;
1075 while (i < BLOCK_SIZE) {
1079 /* Begin inner MD5 */
1080 MD5Init(&hmac->ictx);
1081 MD5Update(&hmac->ictx, k_pad, BLOCK_SIZE);
1083 /* XOR padded key with outer pad value */
1084 for (i = 0; i < BLOCK_SIZE; ++i) {
1085 k_pad[i] ^= (0x36 ^ 0x5c);
1088 /* Begin outer MD5 */
1089 MD5Init(&hmac->octx);
1090 MD5Update(&hmac->octx, k_pad, BLOCK_SIZE);
1092 /* clean up workspace */
1093 memset(k_pad, 0, BLOCK_SIZE);
1096 void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
1099 /* finish inner MD5 */
1100 MD5Final(digest, &hmac->ictx);
1101 /* finish outer MD5 */
1102 MD5Update(&hmac->octx, digest, HMAC_MD5_SIZE);
1103 MD5Final(digest, &hmac->octx);
1104 /* MD5Final zeros context */
1107 void hmac_md5(const unsigned char *text, int text_len,
1108 const unsigned char *key, int key_len,
1109 unsigned char digest[HMAC_MD5_SIZE])
1113 hmac_md5_init(&hmac, key, key_len);
1114 hmac_md5_update(&hmac, text, text_len);
1115 hmac_md5_final(digest, &hmac);
1123 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1126 void hmac_md5_precalc(HMAC_MD5_STATE *ctx,
1127 const unsigned char *pass, int passlen)
1131 if (passlen == 0) passlen = strlen((const char *) pass);
1132 hmac_md5_init(&hctx, pass, passlen);
1133 ctx->istate[0] = htonl(hctx.ictx.state[0]);
1134 ctx->istate[1] = htonl(hctx.ictx.state[1]);
1135 ctx->istate[2] = htonl(hctx.ictx.state[2]);
1136 ctx->istate[3] = htonl(hctx.ictx.state[3]);
1137 ctx->ostate[0] = htonl(hctx.octx.state[0]);
1138 ctx->ostate[1] = htonl(hctx.octx.state[1]);
1139 ctx->ostate[2] = htonl(hctx.octx.state[2]);
1140 ctx->ostate[3] = htonl(hctx.octx.state[3]);
1141 memset(&hctx, 0, sizeof (hctx));
1145 void hmac_md5_import(HMAC_MD5_CTX *hctx, HMAC_MD5_STATE *ctx)
1147 hctx->ictx.state[0] = ntohl(ctx->istate[0]);
1148 hctx->ictx.state[1] = ntohl(ctx->istate[1]);
1149 hctx->ictx.state[2] = ntohl(ctx->istate[2]);
1150 hctx->ictx.state[3] = ntohl(ctx->istate[3]);
1151 hctx->octx.state[0] = ntohl(ctx->ostate[0]);
1152 hctx->octx.state[1] = ntohl(ctx->ostate[1]);
1153 hctx->octx.state[2] = ntohl(ctx->ostate[2]);
1154 hctx->octx.state[3] = ntohl(ctx->ostate[3]);
1155 hctx->ictx.count[0] = hctx->octx.count[0] = BLOCK_SIZE << 3;
1156 hctx->ictx.count[1] = hctx->octx.count[1] = 0;
1179 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1182 C. Appendix - SCRAM sample source code
1184 The following sample source code implements SCRAM itself for both
1187 Please note the lines marked "XXX: ..." as they need to be
1188 translated from English to computer readable code.
1190 A client implementation simply calls scram_md5_generate() with the
1191 passphrase after receiving the first server reply. The cproof
1192 parameter will hold the message to send to the server and the
1193 sproof parameter will hold the expected server mutual
1194 authentication. The clidata parameter holds the client's security
1195 layer selections. A client may also call hmac_md5_precalc() to
1196 turn a passphrase into CRAM/SCRAM credentials for later use in
1197 scram_md5_generate().
1199 A server implementation simply calls scram_md5_generate() with the
1200 stored verifier, the second client message and the SCRAM_VERIFY
1201 option. Server verifiers are generated by creating a random salt
1202 and calling scram_md5_vgen() with either the passphrase or
1203 CRAM/SCRAM credentials.
1205 If integrity protection is desired, the integrity_key parameter may
1206 be provided to scram_md5_generate() and will receive the resulting
1207 key. Generating an verifying the integrity protection is left as
1208 an exercise to the reader.
1210 /* scram.h -- scram utility functions
1212 /* size of SCRAM_MD5 salt and verifier */
1213 #define SCRAM_MD5_SALTSIZE 8
1214 #define SCRAM_MD5_DATASIZE 16
1216 /* SCRAM verifier */
1217 typedef struct SCRAM_MD5_VRFY_s {
1218 unsigned char salt[SCRAM_MD5_SALTSIZE];
1219 unsigned char clidata[SCRAM_MD5_DATASIZE];
1220 unsigned char svrdata[SCRAM_MD5_DATASIZE];
1223 /* Client proof message */
1224 typedef struct SCRAM_MD5_CLIENT_s {
1225 unsigned char secprops[4];
1226 unsigned char cproof[SCRAM_MD5_DATASIZE];
1229 /* generate SCRAM-MD5 verifier
1235 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1238 * vptr -- gets result
1239 * salt -- contains salt of SCRAM_MD5_SALTSIZE
1240 * pass -- passphrase or verifier
1241 * passlen -- len of pass/verifier (0 ok if NUL terminated)
1242 * plainflag -- 1 = plaintext passphrase,
1243 * 0 = result of hmac_md5_precalc()
1244 * clientkey -- cache for client proof, usually NULL
1246 void scram_md5_vgen(SCRAM_MD5_VRFY *vptr,
1247 const unsigned char *salt,
1248 const char *pass, int passlen, int plainflag,
1249 unsigned char *clientkey);
1251 /* scram secret action type */
1252 #define SCRAM_CREDENTIAL 0 /* generate replies using credentials */
1253 #define SCRAM_PLAINTEXT 1 /* generate replies using plaintext */
1254 #define SCRAM_VERIFY 2 /* use SCRAM_MD5_VRFY to verify client,
1255 and generate server reply */
1257 /* generate or verify SCRAM-MD5
1259 * cchal -- client challenge string
1260 * cchallen -- length of client challenge
1261 * schal -- server challenge string
1262 * schallen -- length of server challenge
1263 * secret -- passphrase, credentials, or verifier
1264 * secretlen -- length of passphrase (0 ok if NUL terminated)
1265 * action -- see above
1267 * clidata -- client data for client response
1269 * sproof -- server proof of length SCRAM_MD5_DATASIZE
1270 * integrity_key -- integrity key of length SCRAM_MD5_DATASIZE
1271 * caller may pass NULL if no integrity needed
1273 * -2 if params invalid
1274 * -1 if verify fails
1277 int scram_md5_generate(const char *cchal, int cchallen,
1278 const char *schal, int schallen,
1279 const char *secret, int secretlen,
1281 SCRAM_MD5_CLIENT *clidata,
1282 unsigned char *sproof,
1283 unsigned char *integrity_key);
1291 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1294 /* scram.c -- routines for SCRAM-MD5 calculations
1300 #include "hmac-md5.h"
1303 void scram_md5_vgen(SCRAM_MD5_VRFY *vptr,
1304 const unsigned char *salt,
1305 const char *pass, int passlen, int plainflag,
1306 unsigned char *clientkey)
1310 if (clientkey == NULL) clientkey = vptr->clidata;
1314 if (passlen == 0) passlen = strlen(pass);
1315 hmac_md5_init(&hctx, (const unsigned char *) pass,
1318 hmac_md5_import(&hctx, (HMAC_MD5_STATE *) pass);
1321 /* generate salted passphrase */
1322 hmac_md5_update(&hctx, salt, SCRAM_MD5_SALTSIZE);
1323 hmac_md5_final(vptr->clidata, &hctx);
1325 /* generate server proof */
1326 hmac_md5(salt, SCRAM_MD5_SALTSIZE, vptr->clidata,
1327 sizeof (vptr->clidata), vptr->svrdata);
1329 /* generate client key and client verifier */
1330 MD5Init(&hctx.ictx);
1331 MD5Update(&hctx.ictx, vptr->clidata, sizeof (vptr->clidata));
1332 MD5Final(clientkey, &hctx.ictx);
1333 MD5Init(&hctx.ictx);
1334 MD5Update(&hctx.ictx, clientkey, SCRAM_MD5_DATASIZE);
1335 MD5Final(vptr->clidata, &hctx.ictx);
1337 /* copy salt to verifier */
1338 if (salt != vptr->salt) {
1339 memcpy(vptr->salt, salt, SCRAM_MD5_SALTSIZE);
1347 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1350 int scram_md5_generate(const char *cchal, int cchallen,
1351 const char *schal, int schallen,
1352 const char *secret, int secretlen,
1354 SCRAM_MD5_CLIENT *clidata,
1355 unsigned char *sproof,
1356 unsigned char *integrity_key)
1358 SCRAM_MD5_VRFY verifier, *vptr;
1360 unsigned char clientkey[HMAC_MD5_SIZE];
1361 unsigned char sharedkey[HMAC_MD5_SIZE];
1365 if ((action == SCRAM_CREDENTIAL
1366 && secretlen != sizeof (HMAC_MD5_STATE))
1367 || (action == SCRAM_VERIFY
1368 && secretlen != sizeof (verifier))
1369 || schallen < SCRAM_MD5_SALTSIZE) {
1374 if (action == SCRAM_VERIFY) {
1375 vptr = (SCRAM_MD5_VRFY *) secret;
1377 scram_md5_vgen(&verifier, (const unsigned char *) schal,
1378 secret, secretlen, action, clientkey);
1382 /* calculate shared key */
1383 hmac_md5_init(&hctx, vptr->clidata, sizeof (vptr->clidata));
1384 hmac_md5_update(&hctx, (unsigned char *) schal, schallen);
1385 hmac_md5_update(&hctx, (unsigned char *) cchal, cchallen);
1386 hmac_md5_update(&hctx, clidata->secprops, 4);
1387 hmac_md5_final(sharedkey, &hctx);
1389 if (action == SCRAM_VERIFY) {
1390 /* verify client proof */
1391 for (i = 0; i < HMAC_MD5_SIZE; ++i) {
1392 XXX: the line which belongs here is omitted due to
1393 U.S. export regulations, but it exclusive-ors the
1394 "sharedkey" with the "clidata->cproof" and places the
1395 result in "clientkey" (see step (c) above)
1397 MD5Init(&hctx.ictx);
1403 Internet Draft SCRAM-MD5 SASL Mechanism March 1998
1406 MD5Update(&hctx.ictx, clientkey, sizeof (clientkey));
1407 MD5Final(sharedkey, &hctx.ictx);
1408 if (memcmp(sharedkey, vptr->clidata,
1409 sizeof (sharedkey)) != 0) {
1413 /* generate client proof */
1414 for (i = 0; i < HMAC_MD5_SIZE; ++i) {
1415 XXX: the line which belongs here is omitted due to
1416 U.S. export regulations, but it exclusive-ors the
1417 "sharedkey" with the "clientkey" and places the
1418 result in "clidata->cproof" (see step (G) above)
1422 /* calculate integrity key */
1423 if (integrity_key != NULL) {
1424 hmac_md5_init(&hctx, clientkey, HMAC_MD5_SIZE);
1425 hmac_md5_update(&hctx, (unsigned char *) schal, schallen);
1426 hmac_md5_update(&hctx, (unsigned char *) cchal, cchallen);
1427 hmac_md5_update(&hctx, clidata->secprops, 4);
1428 hmac_md5_final(integrity_key, &hctx);
1431 /* calculate server result */
1433 hmac_md5_init(&hctx, vptr->svrdata, HMAC_MD5_SIZE);
1434 hmac_md5_update(&hctx, (unsigned char *) cchal, cchallen);
1435 hmac_md5_update(&hctx, (unsigned char *) schal, schallen);
1436 hmac_md5_update(&hctx, clidata->secprops, 4);
1437 hmac_md5_final(sproof, &hctx);
1440 /* cleanup workspace */
1441 memset(clientkey, 0, sizeof (clientkey));
1442 memset(sharedkey, 0, sizeof (sharedkey));
1443 if (vptr == &verifier) memset(&verifier, 0, sizeof (verifier));