<!-- $Id$ -->
<!-- The FreeBSD Documentation Project -->
<!--
Copyright 1995 Massachusetts Institute of Technology

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that both the above copyright notice and this
permission notice appear in all copies, that both the above
copyright notice and this permission notice appear in all
supporting documentation, and that the name of M.I.T. not be used
in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.  M.I.T. makes
no representations about the suitability of this software for any
purpose.  It is provided "as is" without express or implied
warranty.

THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-->

<sect><heading>S/Key<label id="skey"></heading>

<p><em>Contributed by &a.wollman;<newline>25 September 1995.</em>

<p>S/Key is a one-time password scheme based on a one-way hash function
(in our version, this is MD4 for compatibility; other versions have
used MD5 and DES-MAC).  S/Key has been a standard part of all FreeBSD
distributions since version 1.1.5, and is also implemented on a large
and growing number of other systems.  S/Key is a registered trademark
of Bell Communications Research, Inc.

<!-- XXX - is there a better word to use than UNIX? -->
<p>There are three different sorts of passwords which we will talk about
in the discussion below.  The first is your usual UNIX-style or Kerberos
password; we will call this a ``UNIX password''.  The second sort is the
one-time password which is generated by the S/Key `<tt/key/' program and
accepted by the `<tt/keyinit/' program and the login prompt; we will call
this a ``one-time password''.  The final sort of password is the
secret password which you give to the `<tt/key/' program (and sometimes the
`<tt/keyinit/' program) which it uses to generate one-time passwords; we will
call it a ``secret password'' or just unqualified ``password''.  

<p>The secret password does not necessarily have anything to do with your
UNIX password (while they can be the same, this is not recommended).
While UNIX passwords are limited to eight characters in length, your
S/Key secret password can be as long as you like; I use seven-word
phrases.  In general, the S/Key system operates completely
independently of the UNIX password system.

<p>There are in addition two other sorts of data involved in the S/Key
system; one is called the ``seed'' or (confusingly) ``key'', and
consists of two letters and five digits, and the other is the
``iteration count'' and is a number between 100 and 1.  S/Key
constructs a one-time password from these components by concatenating
the seed and the secret password, then applying a one-way hash (the
RSA Data Security, Inc., MD4 secure hash function) iteration-count
times, and turning the result into six short English words.  The
`<tt/login/' and `<tt/su/' programs keep track of the last one-time
password used, and the user is authenticated if the hash of the
user-provided password is equal to the previous password.  Because a
one-way hash function is used, it is not possible to generate future
one-time passwords having overheard one which was successfully used;
the iteration count is decremented after each successful login to keep
the user and login program in sync.  (When you get the iteration count
down to 1, it is time to reinitialize S/Key.)

<p>There are four programs involved in the S/Key system which we will
discuss below.  The `<tt/key/' program accepts an iteration count, a
seed, and a secret password, and generates a one-time password.  The
`<tt/keyinit/' program is used to initialized S/Key, and to change
passwords, iteration counts, or seeds; it takes either a secret
password, or an iteration count, seed, and one-time password.  The
`<tt/keyinfo/' program examines the <tt>/etc/skeykeys</tt> file and
prints out the invoking user's current iteration count and seed.
Finally, the `<tt/login/' and `<tt/su/' programs contain the necessary
logic to accept S/Key one-time passwords for authentication.  The
`<tt/login/' program is also capable of disallowing the use of UNIX
passwords on connections coming from specified addresses.

<p>There are four different sorts of operations we will cover.  The first
is using the `<tt/keyinit/' program over a secure connection to set up
S/Key for the first time, or to change your password or seed.  The
second operation is using the `<tt/keyinit/' program over an insecure
connection, in conjunction with the `<tt/key/' program over a secure
connection, to do the same.  The third is using the `<tt/key/' program to
log in over an insecure connection.  The fourth is using the `<tt/key/'
program to generate a number of keys which can be written down or
printed out to carry with you when going to some location without
secure connections to anywhere (like at a conference).

<sect1><heading>Secure connection initialization</heading>

<p>To initialize S/Key, change your password, or change your seed while
logged in over a secure connection (e.g., on the console of a machine),
use the `<tt/keyinit/' command without any parameters while logged in as
yourself:

<tscreen><verb>
$ keyinit
Updating wollman:			) these will not appear if you
Old key: ha73895			) have not used S/Key before
Reminder - Only use this method if you are directly connected.
If you are using telnet or rlogin exit with no password and use keyinit -s.
Enter secret password:			) I typed my pass phrase here
Again secret password:			) I typed it again

ID wollman s/key is 99 ha73896		) discussed below
SAG HAS FONT GOUT FATE BOOM		)
</verb></tscreen>

<p>There is a lot of information here.  At the `Enter secret password:'
prompt, you should enter some password or phrase (I use phrases of
minimum seven words) which will be needed to generate login keys.  The
line starting `ID' gives the parameters of your particular S/Key
instance: your login name, the iteration count, and seed.  When
logging in with S/Key, the system will remember these parameters and
present them back to you so you do not have to remember them.  The last
line gives the particular one-time password which corresponds to those
parameters and your secret password; if you were to re-login
immediately, this one-time password is the one you would use.

<sect1><heading>Insecure connection initialization</heading>

<p>To initialize S/Key or change your password or seed over an insecure
connection, you will need to already have a secure connection to some
place where you can run the `<tt/key/' program; this might be in the form
of a desk accessory on a Macintosh, or a shell prompt on a machine you
trust (we will show the latter).  You will also need to make up an
iteration count (100 is probably a good value), and you may make up
your own seed or use a randomly-generated one.  Over on the insecure
connection (to the machine you are initializing), use the `<tt/keyinit -s/'
command:

<tscreen><verb>
$ keyinit -s 
Updating wollman:
Old key: kh94741
Reminder you need the 6 English words from the skey command.
Enter sequence count from 1 to 9999: 100	) I typed this
Enter new key [default kh94742]: 
s/key 100 kh94742
</verb></tscreen>

To accept the default seed (which the `keyinit' program confusingly
calls a `key'), press return.  Then move over to your secure
connection or S/Key desk accessory, and give it the same parameters:

<tscreen><verb>
$ key 100 kh94742
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: 				) I typed my secret password
HULL NAY YANG TREE TOUT VETO
</verb></tscreen>

Now switch back over to the insecure connection, and copy the one-time
password generated by `<tt/key/' over to the `<tt/keyinit/' program:

<tscreen><verb>
s/key access password: HULL NAY YANG TREE TOUT VETO

ID wollman s/key is 100 kh94742
HULL NAY YANG TREE TOUT VETO
</verb></tscreen>

The rest of the description from the previous section applies here as
well.

<sect1><heading>Diversion: a login prompt</heading>

<p>Before explaining how to generate one-time passwords, we should go
over an S/Key login prompt:

<tscreen><verb>
$ telnet himalia
Trying 18.26.0.186...
Connected to himalia.lcs.mit.edu.
Escape character is '^]'.
s/key 92 hi52030
Password:
</verb></tscreen>

Note that, before prompting for a password, the login program
prints out the iteration number and seed which you will need in order
to generate the appropriate key.  You will also find a useful feature
(not shown here): if you press return at the password prompt, the
login program will turn echo on, so you can see what you are typing.
This can be extremely useful if you are attempting to type in an S/Key
by hand, such as from a printout.

<p>If this machine were configured to disallow UNIX passwords over a
connection from my machine, the prompt would have also included the
annotation `<tt>(s/key required)</tt>', indicating that only S/Key one-time
passwords will be accepted.

<sect1><heading>Generating a single one-time password</heading>

<p>Now, to generate the one-time password needed to answer this login
prompt, we use a trusted machine and the `<tt/key/' program.  (There are
versions of the `<tt/key/' program from DOS and Windows machines, and there
is an S/Key desk accessory for Macintosh computers as well.)  The
command-line `<tt/key/' program takes as its parameters the iteration count
and seed; you can cut-and-paste right from the login prompt starting
at ``<tt/key/'' to the end of the line.  Thus:

<tscreen><verb>
$ key 92 hi52030				) pasted from previous section
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: 				) I typed my secret password
ADEN BED WOLF HAW HOT STUN
</verb></tscreen>

And in the other window:

<tscreen><verb>
s/key 92 hi52030				) from previous section
Password:
 (turning echo on)
Password:ADEN BED WOLF HAW HOT STUN
Last login: Wed Jun 28 15:31:00 from halloran-eldar.l
[etc.]
</verb></tscreen>

This is the easiest mechanism <em/if/ you have a trusted machine.

<sect1><heading>Generating multiple one-time passwords</heading>

<p>Sometimes we have to go places where no trusted machines or
connections are available.  In this case, it is possible to use the
`<tt/key/' command to generate a number of one-time passwords in the same
command; these can then be printed out.  For example:

<tscreen><verb>
$ key -n 25 57 zz99999
Reminder - Do not use this program while logged in via telnet or rlogin.
Enter secret password: 
33: WALT THY MALI DARN NIT HEAD  
34: ASK RICE BEAU GINA DOUR STAG 
[...]
56: AMOS BOWL LUG FAT CAIN INCH  
57: GROW HAYS TUN DISH CAR BALM  
</verb></tscreen>

The `<tt/-n 25/' requests twenty-five keys in sequence; the `<tt/57/' indicates
the <em/ending/ iteration number; and the rest is as before.  Note that
these are printed out in <em/reverse/ order of eventual use.  If you are
really paranoid, you might want to write the results down by hand;
otherwise you can cut-and-paste into `<tt/lpr/'.  Note that each line shows
both the iteration count and the one-time password; you may still find
it handy to scratch off passwords as you use them.

<sect1><heading>Restricting use of UNIX passwords</heading>

<p>The configuration file <tt>/etc/skey.access</tt> can be used to
configure restrictions on the use of UNIX passwords based on the host
name, user name, terminal port, or IP address of a login session.  The
complete format of the file is documented in the <em/skey.access/(5)
manual page; there are also some security cautions there which should
be read before depending on this file for security.

<p>If there is no <tt>/etc/skey.access</tt> file (which is the default
state as FreeBSD is shipped), then all users will be allowed to use
UNIX passwords.  If the file exists, however, then all users will be
required to use S/Key unless explicitly permitted to do otherwise by
configuration statements in the <tt/skey.access/ file.  In all cases,
UNIX passwords are permitted on the console.

<p>Here is a sample configuration file which illustrates the three most
common sorts of configuration statements:

<tscreen><verb>
permit internet 18.26.0.0 255.255.0.0
permit user jrl
permit port ttyd0
</verb></tscreen>

The first line (`<tt/permit internet/') allows users whose IP source
address (which is vulnerable to spoofing) matches the specified value
and mask, to use UNIX passwords.  This should not be considered a
security mechanism, but rather, a means to remind authorized users
that they are using an insecure network and need to use S/Key for
authentication.

<p>The second line (`<tt/permit user/') allows the specified user to
use UNIX passwords at any time.  Generally speaking, this should only
be used for people who are either unable to use the `<tt/key/'
program, like those with dumb terminals, or those who are uneducable.

<p>The third line (`<tt/permit port/') allows all users logging in on
the specified terminal line to use UNIX passwords; this would be used
for dial-ups.

