Re: My own little replacement for the Unix crypt

From: AE (hidden_at_nospam.com)
Date: 02/29/04


Date: Sun, 29 Feb 2004 13:48:00 +0100

My suggestion:

1. Get password from the user
2. if a cryptographically strong /dev/rand is available (this depends on
    the operating-system and should be a compile-time option)
       get 160 bit from this source
    else
       get hostid, time and PID and hash it using SHA
3. if flag "no-key-strengthening" is set
       Hash the password using SHA and use the output as your key.
       if flag "fixed-IV" is set
          set IV to a value given by the user or (if none is given) set
          IV=0.
       else
          Write 64bit (for Skipjack) or 128bit (for AES or Camellia)
          of the PRN created in step 2 in the output stream and use this
          value as IV.
    else-if "fast-key-creation" is set
       Write the PRN created in step 2 in the output stream and use the
       last 64bit (for Skipjack or the last 128bit (for AES or Camellia)
       as IV.
       Concatenate the PRN created in step 2 with the password, hash it
       using SHA and use the output as your key.
    else
       Write the PRN created in step 2 in the output stream and use the
       last 64bit (for Skipjack) or the last 128bit (for AES or Camellia)
       as IV.
       Concatenate the PRN created in step 2 with the password and hash
       it using SHA.
       Concatenate this value with the password ans hash it using SHA.
       Repeat this step 2^16 times to add effectively 16bit of strength
       to the password.
       Use the output of the last step as your key.
4. if flag "hmac" is set
       hash the current 160bit-key with a fixed value (for example
       "hmac") to get a key for hmac-sha1 and and with another fixed
       value (for example "encrypt" to get a key for encryption.
5. For Skipjack use the full 160bit key and create an 80 bit
    Skipjack-key according to the description in the original paper.
    For AES or Camellia use 128 bit of the key.
6. if flags "fixed-IV" is set and not provided by the user and length of
    data stream is at least 1 block
       encrypt the first block in ECB-mode and the remaining stream in
       CFB-mode, using the first block as IV for the CFB-encrypted data
    else
       encrypt stdin using Skipjack, AES128 or Camellia128 in CFB mode,
       using the random or pseudo-random IV
    if flag "hmac" is set
     Calculate as well hmac-sha1 of the encrypted data stream including
     the prepended bits.
     Write 160bit hmac-sha1 to stdout once stdin gets closed.

A "fixed-IV" and "no-key-strengthening" should not be used, but this
might be necessary to preserve the precise length of the data stream.
This option exists only for compatiblity with crypt(1). It is dangerous
especially if a stream of less than 1 block is encrypted and there's no
user-provided IV since in this case the cipher is reduced to an only
key-dependent XOR-map.

Since key-strengthening requires 2^16 hash calculations this can be
switched off or replaced with a fast key creation step can be used.

Default is usage of key-strengthening and of a random or pseudo-random IV.

Optional calculation of HMAC allows authentication of the data-stream
and kind of a password-check (since authentication fails in case the
wrong password was provided).

It is possible to use DMAC-AES or -Camellia and the Miyaguchi-Preneel
hashing scheme to simplify the whole program by using only one
cryptographic algorithm.

Maybe it would be interesting to add a flag to run the cipher in CBC-mode.