                               Rephrase
                             -------------
                              Version 0.2


    README (what it does, what it doesn't, how to use it, how to complain)
    Copyright (C) 2003, 2014  Phil Lanch

    This file is part of Rephrase.

    Rephrase is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 3.

    Rephrase is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.


About
-----

Rephrase[1] is a specialized passphrase recovery tool for GnuPG[2], and
for Cryptsetup/LUKS[3].  If you can nearly remember your passphrase -
but not quite - then Rephrase may be able to help.

Tell Rephrase the parts of the passphrase you know, and any number of
alternatives for the parts you're not sure about; and Rephrase will try
all the alternatives, in all possible combinations, and tell you which
combination (if any) gives you the correct passphrase.  You could try
all the combinations yourself, of course, if there are just a handful of
them; but if there are more, that might be impractical.

On the other hand, if you need to try a huge number of possible
passphrases, Rephrase might be too slow; it is far from being an
efficient passphrase cracker.  E.g. Rephrase can try out about 2600
possible GnuPG passphrases per minute on my 1GHz Athlon (with other
processes doing nothing very heavy at the same time).  And
Cryptsetup/LUKS passphrases are much slower.  How many passphrases
Rephrase can try depends on how long you are prepared to wait!  Rephrase
can reasonably be run for a long time; e.g. it *won't* use more memory
the longer it runs.

It would be a Bad Thing to leave your passphrase (or part of it, or your
guesses at it) lying around on your hard drive; since a passphrase is
supposed to be an extra line of defence if an attacker obtains access to
your secret keyring (which you presumably *do* keep on your hard drive).
That's why Rephrase keeps all the information about your passphrase that
you give it in secure memory (and then pipes each possible passphrase to
a child gpg/cryptsetup process).  For this reason, Rephrase is likely to
be more secure than alternative solutions that involve generating a list
of possible passphrases in a file and then testing them.

[1]The latest version of Rephrase can always (for some value of
   "always") be found at http://www.roguedaemon.net/rephrase/ .

[2]For more information about GnuPG, see https://www.gnupg.org/ .

[3]For more information about Cryptsetup/LUKS, see
   https://code.google.com/p/cryptsetup/ .


Prerequisites
-------------

* If you want to recover GnuPG passphrases: GnuPG

* If you want to recover LUKS passphrases: Cryptsetup, and a kernel with
  the relevant modules

* C compiler

* POSIX (i.e. a Unix-like system)

For portability issues, see below, under "Bugs".


Installation
------------

Um, did you download and unpack the tarball?

It takes 2 commands to install Rephrase.

(1) make

    There are 3 arguments you might need to add.

    (a) If gpg is not installed at /usr/local/bin/gpg, then you need to
        specify its full path e.g.

        make GPG=/usr/bin/gpg

    (b) If cryptsetup is not installed at /sbin/cryptsetup, then you
        need to specify its full path e.g.

        make CRYPTSETUP=/usr/sbin/cryptsetup

    (c) If you might want to type in a pattern (patterns are explained
        below, under "Manual") longer than 512 characters, then you need
        (help and) to specify a maximum pattern length e.g.

        make PATTERN_MAX=1024

    So if both (a) and (c) apply, then this command could become e.g.

        make GPG=/usr/bin/gpg PATTERN_MAX=1024

    If you need to re-make with different arguments, then you first need
    to

        make clean

(2) make install

    You *must* run this command as root.

    There are a few arguments you might need to add.

    (a) You can adjust the ownership and permissions on the installed
        binary by setting binowner, bingroup and binmode.  For instance,
        you could restrict execution of the (setuid-root) rephrase
        binary to users in the `trusted' group (assuming a group with
        that name already exists) like this:

        make install bingroup=trusted binmode=4710

    (b) If you don't want rephrase installed in /usr/local/bin, then
        specify an alternative installation directory e.g.

        make install bindir=/usr/bin


Manual
------

Usage:

    rephrase <key> | --gpg-key <key> | --gpg-symmetric <encrypted_file> | --luks <block_device>

Let's go through those options separately ...

    rephrase <key>
    rephrase --gpg-key <key>

These 2 usages are equivalent, and are used to recover the passphrase of
a GnuPG private key.  <key> is the key whose passphrase you want to
recover; you can identify it in any of the ways that GnuPG understands.
(To make sure you're using a sensible value for <key>, you could first
try

    gpg --list-secret-keys <key>

which should list exactly 1 key.)

    rephrase --gpg-symmetric <encrypted_file>

The above is to recover the passphrase of a file encrypted using
'gpg --symmetric'.  You can use an absolute or relative path for
<encrypted_file>.  You should make sure that the file exists and really
was symmetrically encrypted with gpg.

    rephrase --luks <block_device>

This is to recover the passphraes of a LUKS encrypted volume.
<block_device> would usually begin with /dev/mapper/ .

Next, and this applies to all the different usage cases ...

You will be prompted to enter a pattern (the pattern is not echoed to
the screen as you type it).  So what's a pattern?  Suppose you know that
your passphrase was something like "super-secret", but you're not sure
if you changed some (or all) of the "e"s into "3"s, or any of the
consonants into upper case, or indeed changed the "c" into "k" or "K" or
even "|<", or changed the "-" into " " or just omitted it.  Then you
could enter this pattern:

    (s|S)u(p|P)(e|3)(r|R)(-| |)(s|S)(e|3)(c|C|k|K|\|<)(r|R)(e|3)(t|T)

The pattern is your passphrase - except that 4 characters have special
meanings.  Brackets - "(" and ")" - are used to group alternatives
wherever you're not sure what characters are correct; "|" is used inside
a pair of brackets to separate the alternatives; and "\" is used to
escape any of the 4 special characters when you need to use it
literally.

Rephrase will tell you if your pattern contains a syntax error.  That
happens if there are unbalanced brackets (i.e. they aren't in proper
pairs); or if the pattern ends with "\" (because then there's nothing
for it to escape).  It also happens (and these cases are limitations in
Rephrase's simple pattern parser) if you try to nest pairs of brackets;
or if you try to use "|" anywhere that's not inside a pair of brackets.

If the pattern contains no syntax errors, Rephrase will try each
possible passphrase matching the pattern in turn.  If the correct
passphrase is found, Rephrase won't actually tell you what it is (in
case someone's looking over your shoulder), but will tell you a string
of numbers: you can work out the correct passphrase from these numbers
and the pattern you entered.  E.g.

    2 1 2 1 2 1 1 5 1 2 2

The first number - 2 - means that at the first pair of brackets in the
pattern - "(s|S)" - you must take the second alternative - viz. "S".
The second number - 1 - means that at the seconds pair of brackets -
"(p|P)" - you must take the first alternative - viz. "p".  And so forth.
So in this case the correct passphrase is "Sup3r se|<r3T".

If the correct passphrase is not found from the pattern, Rephrase tells
you so.  (Note that you will also get this result if you specified <key>
(or <encrypted_file>) incorretly; how to check that the value of <key>
is OK is explained above.)

Rephrase's exit status is 0 if the passphrase is found, 1 if it's not
found, or other values if an error occurs.


Security
--------

The good news is that Rephrase uses mlock() in order to keep the
information about passphrases that it's given as secure as possible.
The bad news is that using mlock() requires root privileges, so Rephrase
needs to be setuid root.  However, it does drop root privileges very
quickly, as soon as it has called mlock().

It's also debatable whether mlock() is a proper way to protect sensitive
information.  According to POSIX, mlock()ing a page guarantees that it
*is* in memory (useful for realtime applications), not that it *isn't*
in the swap (useful for security applications).  Possibly an encrypted
swap partition (or no swap partition) is a better solution.  Anyway,
GnuPG itself uses mlock(), which makes it sensible for Rephrase to
follow suit.


Bugs
----

Rephrase has been used on various GNU/Linux and FreeBSD systems.  It may
work on other Unix-like systems; but portability has not been thoroughly
tested.  (For Unix-unlike systems, you're on your own.)

If mlock() fails (probably because Rephrase is not setuid root),
Rephrase refuses to proceed: it would be better to issue a warning and
continue, since that's what GnuPG does.

Before it asks you to enter a pattern, Rephrase should check that the
<key> argument does refer to exactly 1 key and that that key is
available.

The "limitations in Rephrase's simple pattern parser" (see above, under
"Manual") should be eliminated.

If you'd like Rephrase to be faster, then it's too slow.  (But if you're
happy with it, then it's fast enough.)  How could Rephrase be faster?
Currently Rephrase spawns a new gpg/cryptsetup process for every
possible passphrase it tries; it would be much more efficient to build
the relevant bits of GnuPG's/Cryptsetup's code into Rephrase itself.
Rephrase is also single-threaded, so it does not fully utilize modern
multi-core CPUs.

The standard --version and --help options are unimplemented.

Please send bug reports to me at

    Phil Lanch <phil@roguedaemon.net>

I'm especially interested in reports of

* successes or failures on different operating systems (including full
  details of the system, the version of Rephrase, and what did or didn't
  work)

* anyone who cares about the other bugs listed above (if you care about
  them, I might fix them) 

* new bugs
