head	1.20;
access;
symbols
	REL7_4_29:1.7
	REL8_0_25:1.7
	REL8_1_21:1.14.2.1
	REL8_2_17:1.18
	REL7_4_28:1.7
	REL8_0_24:1.7
	REL8_1_20:1.14.2.1
	REL8_2_16:1.18
	REL7_4_27:1.7
	REL8_0_23:1.7
	REL8_1_19:1.14.2.1
	REL8_2_15:1.18
	REL7_4_26:1.7
	REL8_0_22:1.7
	REL8_1_18:1.14.2.1
	REL8_2_14:1.18
	REL7_4_25:1.7
	REL8_0_21:1.7
	REL8_1_17:1.14.2.1
	REL8_2_13:1.18
	REL7_4_24:1.7
	REL8_0_20:1.7
	REL8_1_16:1.14.2.1
	REL8_2_12:1.18
	REL7_4_23:1.7
	REL8_0_19:1.7
	REL8_1_15:1.14.2.1
	REL8_2_11:1.18
	REL7_4_22:1.7
	REL8_0_18:1.7
	REL8_1_14:1.14.2.1
	REL8_2_10:1.18
	REL7_4_21:1.7
	REL8_0_17:1.7
	REL8_1_13:1.14.2.1
	REL8_2_9:1.18
	REL7_4_20:1.7
	REL8_0_16:1.7
	REL8_1_12:1.14.2.1
	REL8_2_8:1.18
	REL8_2_7:1.18
	REL7_3_21:1.7
	REL7_4_19:1.7
	REL8_0_15:1.7
	REL8_1_11:1.14.2.1
	REL8_2_6:1.18
	REL8_3_BETA2:1.19
	REL8_3_BETA1:1.19
	REL7_3_20:1.7
	REL7_4_18:1.7
	REL8_0_14:1.7
	REL8_1_10:1.14.2.1
	REL8_2_5:1.18
	REL7_3_19:1.7
	REL7_4_17:1.7
	REL8_0_13:1.7
	REL8_1_9:1.14.2.1
	REL8_2_4:1.18
	REL8_0_12:1.7
	REL8_1_8:1.14.2.1
	REL8_2_3:1.18
	REL7_3_18:1.7
	REL7_4_16:1.7
	REL8_0_11:1.7
	REL8_1_7:1.14.2.1
	REL8_2_2:1.18
	REL8_0_10:1.7
	REL8_1_6:1.14.2.1
	REL8_2_1:1.18
	REL7_4_15:1.7
	REL7_3_17:1.7
	REL8_2_STABLE:1.18.0.2
	REL8_2_0:1.18
	REL8_2_RC1:1.18
	REL8_2_BETA3:1.18
	REL8_2_BETA2:1.18
	REL8_1_5:1.14.2.1
	REL8_0_9:1.7
	REL7_4_14:1.7
	REL7_3_16:1.7
	REL8_2_BETA1:1.18
	REL7_3_15:1.7
	REL7_4_13:1.7
	REL8_0_8:1.7
	REL8_1_4:1.14
	REL7_3_14:1.7
	REL7_4_12:1.7
	REL8_0_7:1.7
	REL8_1_3:1.14
	REL7_3_13:1.7
	REL7_4_11:1.7
	REL8_0_6:1.7
	REL8_1_2:1.14
	REL7_3_12:1.7
	REL7_4_10:1.7
	REL8_0_5:1.7
	REL8_1_1:1.14
	REL8_1_STABLE:1.14.0.2
	REL8_1_0:1.14
	REL8_1_0RC1:1.13
	REL8_1_0BETA4:1.13
	REL8_1_0BETA3:1.13
	REL7_3_11:1.7
	REL7_4_9:1.7
	REL8_0_4:1.7
	REL8_1_0BETA2:1.13
	REL8_1_0BETA1:1.13
	REL7_2_8:1.7
	REL7_3_10:1.7
	REL7_4_8:1.7
	REL8_0_3:1.7
	REL8_0_2:1.7
	REL7_2_7:1.7
	REL7_3_9:1.7
	REL7_4_7:1.7
	REL8_0_1:1.7
	REL8_0_STABLE:1.7.0.12
	REL8_0_0:1.7.0.10
	REL8_0_0RC5:1.7
	REL8_0_0RC4:1.7
	REL8_0_0RC3:1.7
	REL8_0_0RC2:1.7
	REL8_0_0RC1:1.7
	REL8_0_0BETA5:1.7
	REL8_0_0BETA4:1.7
	REL7_4_6:1.7
	REL7_3_8:1.7
	REL7_2_6:1.7
	REL8_0_0BETA3:1.7
	REL8_0_0BETA2:1.7
	REL7_2_5:1.7
	REL7_4_5:1.7
	REL7_3_7:1.7
	REL7_4_4:1.7
	REL8_0_0BETA1:1.7
	REL7_4_3:1.7
	REL7_4_2:1.7
	REL7_3_6:1.7
	REL7_4_1:1.7
	REL7_3_5:1.7
	REL7_4:1.7
	REL7_4_RC2:1.7
	REL7_4_STABLE:1.7.0.8
	REL7_4_RC1:1.7
	REL7_4_BETA5:1.7
	REL7_4_BETA4:1.7
	REL7_4_BETA3:1.7
	REL7_4_BETA2:1.7
	WIN32_DEV:1.7.0.6
	REL7_4_BETA1:1.7
	REL7_3_4:1.7
	REL7_3_2:1.7
	REL7_2_4:1.7
	REL7_3_STABLE:1.7.0.4
	REL7_2_3:1.7
	REL7_2_STABLE:1.7.0.2
	REL7_2:1.7
	REL7_2_RC2:1.7
	REL7_2_RC1:1.7
	REL7_2_BETA5:1.7
	REL7_2_BETA4:1.7
	REL7_2_BETA3:1.7
	REL7_2_BETA2:1.7
	REL7_2_BETA1:1.7
	REL7_1_2:1.3
	REL7_1_STABLE:1.3.0.2
	REL7_1_BETA:1.1
	REL7_1_BETA3:1.1
	REL7_1_BETA2:1.1
	REL7_1:1.3;
locks; strict;
comment	@# @;


1.20
date	2007.11.10.23.30.46;	author momjian;	state dead;
branches;
next	1.19;

1.19
date	2007.03.28.22.48.58;	author neilc;	state Exp;
branches;
next	1.18;

1.18
date	2006.09.05.21.26.48;	author tgl;	state Exp;
branches;
next	1.17;

1.17
date	2006.08.05.00.29.11;	author neilc;	state Exp;
branches;
next	1.16;

1.16
date	2006.07.19.17.05.50;	author neilc;	state Exp;
branches;
next	1.15;

1.15
date	2006.07.13.04.15.24;	author neilc;	state Exp;
branches;
next	1.14;

1.14
date	2005.11.03.02.54.07;	author tgl;	state Exp;
branches
	1.14.2.1;
next	1.13;

1.13
date	2005.08.13.02.06.20;	author momjian;	state Exp;
branches;
next	1.12;

1.12
date	2005.07.18.17.17.12;	author tgl;	state Exp;
branches;
next	1.11;

1.11
date	2005.07.10.03.57.55;	author momjian;	state Exp;
branches;
next	1.10;

1.10
date	2005.05.03.03.10.01;	author neilc;	state Exp;
branches;
next	1.9;

1.9
date	2005.03.21.05.21.04;	author neilc;	state Exp;
branches;
next	1.8;

1.8
date	2005.03.21.05.17.16;	author neilc;	state Exp;
branches;
next	1.7;

1.7
date	2001.09.30.22.18.29;	author momjian;	state Exp;
branches;
next	1.6;

1.6
date	2001.09.29.03.11.58;	author momjian;	state Exp;
branches;
next	1.5;

1.5
date	2001.09.23.04.12.44;	author momjian;	state Exp;
branches;
next	1.4;

1.4
date	2001.08.21.00.42.41;	author momjian;	state Exp;
branches;
next	1.3;

1.3
date	2001.03.16.17.42.56;	author tgl;	state Exp;
branches;
next	1.2;

1.2
date	2001.01.24.03.46.16;	author momjian;	state Exp;
branches;
next	1.1;

1.1
date	2000.10.31.13.11.28;	author petere;	state Exp;
branches;
next	;

1.14.2.1
date	2006.08.05.00.29.14;	author neilc;	state Exp;
branches;
next	;


desc
@@


1.20
log
@Move most /contrib README files into SGML.  Some still need conversion
or will never be converted.
@
text
@pgcrypto - cryptographic functions for PostgreSQL
=================================================
Marko Kreen <markokr@@gmail.com>

// Note: this document is in asciidoc format.


1.  Installation
-----------------

Run following commands:

    make
    make install
    make installcheck

The `make installcheck` command is important.  It runs regression tests
for the module.  They make sure the functions here produce correct
results.

Next, to put the functions into a particular database, run the commands in
file pgcrypto.sql, which has been installed into the shared files directory.

Example using psql:

    psql -d DBNAME -f pgcrypto.sql


2.  Notes
----------

2.1.  Configuration
~~~~~~~~~~~~~~~~~~~~

pgcrypto configures itself according to the findings of main PostgreSQL
`configure` script.  The options that affect it are `--with-zlib` and
`--with-openssl`.

When compiled with zlib, PGP encryption functions are able to
compress data before encrypting.

When compiled with OpenSSL there will be more algorithms available.
Also public-key encryption functions will be faster as OpenSSL
has more optimized BIGNUM functions.

Summary of functionality with and without OpenSSL:

`----------------------------`---------`------------
 Functionality                built-in   OpenSSL
----------------------------------------------------
 MD5                          yes       yes
 SHA1                         yes       yes
 SHA224/256/384/512           yes       yes (3)
 Any other digest algo        no        yes (1)
 Blowfish                     yes       yes
 AES                          yes       yes (2)
 DES/3DES/CAST5               no        yes
 Raw encryption               yes       yes
 PGP Symmetric encryption     yes       yes
 PGP Public-Key encryption    yes       yes
----------------------------------------------------

1. Any digest algorithm OpenSSL supports is automatically picked up.
   This is not possible with ciphers, which need to be supported
   explicitly.

2. AES is included in OpenSSL since version 0.9.7.  If pgcrypto is
   compiled against older version, it will use built-in AES code,
   so it has AES always available.

3. SHA2 algorithms were added to OpenSSL in version 0.9.8.  For
   older versions, pgcrypto will use built-in code.


2.2.  NULL handling
~~~~~~~~~~~~~~~~~~~~

As standard in SQL, all functions return NULL, if any of the arguments
are NULL.  This may create security risks on careless usage.


2.3.  Security
~~~~~~~~~~~~~~~

All the functions here run inside database server.  That means that all
the data and passwords move between pgcrypto and client application in
clear-text.  Thus you must:

1.  Connect locally or use SSL connections.
2.  Trust both system and database administrator.

If you cannot, then better do crypto inside client application.


3.  General hashing
--------------------

3.1.  digest(data, type)
~~~~~~~~~~~~~~~~~~~~~~~~~

  digest(data text, type text) RETURNS bytea
  digest(data bytea, type text) RETURNS bytea

Type is here the algorithm to use.  Standard algorithms are `md5` and
`sha1`, although there may be more supported, depending on build
options.

Returns binary hash.

If you want hexadecimal string, use `encode()` on result.  Example:

    CREATE OR REPLACE FUNCTION sha1(bytea) RETURNS text AS $$
      SELECT encode(digest($1, 'sha1'), 'hex')
    $$ LANGUAGE SQL STRICT IMMUTABLE;


3.2.  hmac(data, key, type)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  hmac(data text, key text, type text) RETURNS bytea
  hmac(data bytea, key text, type text) RETURNS bytea

Calculates Hashed MAC over data.  `type` is the same as in `digest()`.
If the key is larger than hash block size it will first hashed and the
hash will be used as key.

It is similar to digest() but the hash can be recalculated only knowing
the key.  This avoids the scenario of someone altering data and also
changing the hash.

Returns binary hash.



4.  Password hashing
---------------------

The functions `crypt()` and `gen_salt()` are specifically designed
for hashing passwords.  `crypt()` does the hashing and `gen_salt()`
prepares algorithm parameters for it.

The algorithms in `crypt()` differ from usual hashing algorithms like
MD5 or SHA1 in following respects:

1. They are slow.  As the amount of data is so small, this is only
   way to make brute-forcing passwords hard.
2. Include random 'salt' with result, so that users having same
   password would have different crypted passwords.  This is also
   additional defense against reversing the algorithm.
3. Include algorithm type in the result, so passwords hashed with
   different algorithms can co-exist.
4. Some of them are adaptive - that means after computers get
   faster, you can tune the algorithm to be slower, without
   introducing incompatibility with existing passwords.

Supported algorithms:
`------`-------------`---------`----------`---------------------------
 Type   Max password  Adaptive  Salt bits  Description
----------------------------------------------------------------------
`bf`     72           yes         128      Blowfish-based, variant 2a
`md5`    unlimited    no           48      md5-based crypt()
`xdes`   8            yes          24      Extended DES
`des`    8            no           12      Original UNIX crypt
----------------------------------------------------------------------


4.1.  crypt(password, salt)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  crypt(password text, salt text) RETURNS text

Calculates UN*X crypt(3) style hash of password.  When storing new
password, you need to use function `gen_salt()` to generate new salt.
When checking password you should use existing hash as salt.

Example - setting new password:

    UPDATE .. SET pswhash = crypt('new password', gen_salt('md5'));

Example - authentication:

    SELECT pswhash = crypt('entered password', pswhash) WHERE .. ;

returns true or false whether the entered password is correct.
It also can return NULL if `pswhash` field is NULL.


4.2.  gen_salt(type)
~~~~~~~~~~~~~~~~~~~~~

  gen_salt(type text) RETURNS text

Generates a new random salt for usage in `crypt()`.  For adaptible
algorithms, it uses the default iteration count.

Accepted types are: `des`, `xdes`, `md5` and `bf`.


4.3.  gen_salt(type, rounds)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  gen_salt(type text, rounds integer) RETURNS text

Same as above, but lets user specify iteration count for some
algorithms.  The higher the count, the more time it takes to hash
the password and therefore the more time to break it.  Although with
too high count the time to calculate a hash may be several years
- which is somewhat impractical.

Number is algorithm specific:

`-----'---------'-----'----------
 type   default   min   max
---------------------------------
 `xdes`     725     1   16777215
 `bf`         6     4         31
---------------------------------

In case of xdes there is a additional limitation that the count must be
a odd number.

Notes:

- Original DES crypt was designed to have the speed of 4 hashes per
  second on the hardware of that time.
- Slower than 4 hashes per second would probably dampen usability.
- Faster than 100 hashes per second is probably too fast.
- See next section about possible values for `crypt-bf`.


4.4.  Comparison of crypt and regular hashes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Here is a table that should give overview of relative slowness
of different hashing algorithms.

* The goal is to crack a 8-character password, which consists:
  1.  Only of lowercase letters
  2.  Numbers, lower- and uppercase letters.
* The table below shows how much time it would take to try all
  combinations of characters.
* The `crypt-bf` is featured in several settings - the number
  after slash is the `rounds` parameter of `gen_salt()`.

`------------'----------'--------------'--------------------
Algorithm     Hashes/sec  Chars: [a-z]   Chars: [A-Za-z0-9]
------------------------------------------------------------
crypt-bf/8            28     246 years         251322 years
crypt-bf/7            57     121 years         123457 years
crypt-bf/6           112      62 years          62831 years
crypt-bf/5           211      33 years          33351 years
crypt-md5           2681     2.6 years           2625 years
crypt-des         362837        7 days             19 years
sha1              590223        4 days             12 years
md5              2345086         1 day              3 years
------------------------------------------------------------

* The machine used is 1.5GHz Pentium 4.
* crypt-des and crypt-md5 algorithm numbers are taken from
  John the Ripper v1.6.38 `-test` output.
* MD5 numbers are from mdcrack 1.2.
* SHA1 numbers are from lcrack-20031130-beta.
* `crypt-bf` numbers are taken using simple program that loops
  over 1000 8-character passwords.  That way I can show the speed with
  different number of rounds.  For reference: `john -test` shows 213
  loops/sec for crypt-bf/5.  (The small difference in results is in
  accordance to the fact that the `crypt-bf` implementation in pgcrypto
  is same one that is used in John the Ripper.)

Note that "try all combinations" is not a realistic exercise.
Usually password cracking is done with the help of dictionaries, which
contain both regular words and various mutations of them.  So, even
somewhat word-like passwords could be cracked much faster than the above
numbers suggest, and a 6-character non-word like password may escape
cracking.  Or not.


5.  PGP encryption
-------------------

The functions here implement the encryption part of OpenPGP (RFC2440)
standard.   Supported are both symmetric-key and public-key encryption.


5.1.  Overview
~~~~~~~~~~~~~~~

Encrypted PGP message consists of 2 packets:

- Packet for session key - either symmetric- or public-key encrypted.
- Packet for session-key encrypted data.

When encrypting with password:

1. Given password is hashed using String2Key (S2K) algorithm.  This
   is rather similar to `crypt()` algorithm - purposefully slow
   and with random salt - but it produces a full-length binary key.
2. If separate session key is requested, new random key will be
   generated.  Otherwise S2K key will be used directly as session key.
3. If S2K key is to be used directly, then only S2K settings will be put
   into session key packet.  Otherwise session key will be encrypted with
   S2K key and put into session key packet.

When encrypting with public key:

1. New random session key is generated.
2. It is encrypted using public key and put into session key packet.

Now common part, the session-key encrypted data packet:

1. Optional data-manipulation: compression, conversion to UTF-8,
   conversion of line-endings.
2. Data is prefixed with block of random bytes.  This is equal
   to using random IV.
3. A SHA1 hash of random prefix and data is appended.
4. All this is encrypted with session key.


5.2.  pgp_sym_encrypt(data, psw)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  pgp_sym_encrypt(data text, psw text [, options text] ) RETURNS bytea
  pgp_sym_encrypt_bytea(data bytea, psw text [, options text] ) RETURNS bytea

Return a symmetric-key encrypted PGP message.

Options are described in section 5.8.


5.3. pgp_sym_decrypt(msg, psw)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  pgp_sym_decrypt(msg bytea, psw text [, options text] ) RETURNS text
  pgp_sym_decrypt_bytea(msg bytea, psw text [, options text] ) RETURNS bytea

Decrypt a symmetric-key encrypted PGP message.

Decrypting bytea data with `pgp_sym_decrypt` is disallowed.
This is to avoid outputting invalid character data.  Decrypting
originally textual data with `pgp_sym_decrypt_bytea` is fine.

Options are described in section 5.8.


5.4.  pgp_pub_encrypt(data, pub_key)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  pgp_pub_encrypt(data text, key bytea [, options text] ) RETURNS bytea
  pgp_pub_encrypt_bytea(data bytea, key bytea [, options text] ) RETURNS bytea

Encrypt data with a public key.  Giving this function a secret key will
produce a error.

Options are described in section 5.8.


5.5.  pgp_pub_decrypt(msg, sec_key [, psw])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text]] ) \
  RETURNS text
  pgp_pub_decrypt_bytea(msg bytea, key bytea [,psw text [, options text]] ) \
  RETURNS bytea

Decrypt a public-key encrypted message with secret key.  If the secret
key is password-protected, you must give the password in `psw`.  If
there is no password, but you want to specify option for function, you
need to give empty password.

Decrypting bytea data with `pgp_pub_decrypt` is disallowed.
This is to avoid outputting invalid character data.  Decrypting
originally textual data with `pgp_pub_decrypt_bytea` is fine.

Options are described in section 5.8.


5.6.  pgp_key_id(key / msg)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  pgp_key_id(key or msg bytea) RETURNS text

It shows you either key ID if given PGP public or secret key.  Or it
gives the key ID that was used for encrypting the data, if given
encrypted message.

It can return 2 special key IDs:

SYMKEY::
   The data is encrypted with symmetric key.

ANYKEY::
   The data is public-key encrypted, but the key ID is cleared.
   That means you need to try all your secret keys on it to see
   which one decrypts it.  pgcrypto itself does not produce such
   messages.

Note that different keys may have same ID.   This is rare but normal
event.  Client application should then try to decrypt with each one,
to see which fits - like handling ANYKEY.


5.7.  armor / dearmor
~~~~~~~~~~~~~~~~~~~~~~

  armor(data bytea) RETURNS text
  dearmor(data text) RETURNS bytea

Those wrap/unwrap data into PGP Ascii Armor which is basically Base64
with CRC and additional formatting.


5.8.  Options for PGP functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Options are named to be similar to GnuPG.  Values should be given after
an equal sign; separate options from each other with commas.  Example:

  pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256')

All of the options except `convert-crlf` apply only to encrypt
functions.  Decrypt functions get the parameters from PGP data.

Most interesting options are probably `compression-algo` and
`unicode-mode`.  The rest should have reasonable defaults.


cipher-algo::
  What cipher algorithm to use.

  Values: bf, aes128, aes192, aes256 (OpenSSL-only: `3des`, `cast5`)
  Default: aes128
  Applies: pgp_sym_encrypt, pgp_pub_encrypt

compress-algo::
  Which compression algorithm to use.  Needs building with zlib.

  Values:
    0 - no compression
    1 - ZIP compression
    2 - ZLIB compression [=ZIP plus meta-data and block-CRC's]
  Default: 0
  Applies: pgp_sym_encrypt, pgp_pub_encrypt

compress-level::
  How much to compress.  Bigger level compresses smaller but is slower.
  0 disables compression.

  Values: 0, 1-9
  Default: 6
  Applies: pgp_sym_encrypt, pgp_pub_encrypt

convert-crlf::
  Whether to convert `\n` into `\r\n` when encrypting and `\r\n` to `\n`
  when decrypting.  RFC2440 specifies that text data should be stored
  using `\r\n` line-feeds.  Use this to get fully RFC-compliant
  behavior.

  Values: 0, 1
  Default: 0
  Applies: pgp_sym_encrypt, pgp_pub_encrypt, pgp_sym_decrypt, pgp_pub_decrypt

disable-mdc::
  Do not protect data with SHA-1.  Only good reason to use this
  option is to achieve compatibility with ancient PGP products, as the
  SHA-1 protected packet is from upcoming update to RFC2440.  (Currently
  at version RFC2440bis-14.) Recent gnupg.org and pgp.com software
  supports it fine.

  Values: 0, 1
  Default: 0
  Applies: pgp_sym_encrypt, pgp_pub_encrypt

enable-session-key::
  Use separate session key.  Public-key encryption always uses separate
  session key, this is for symmetric-key encryption, which by default
  uses S2K directly.

  Values: 0, 1
  Default: 0
  Applies: pgp_sym_encrypt

s2k-mode::
  Which S2K algorithm to use.

  Values:
    0 - Without salt.  Dangerous!
    1 - With salt but with fixed iteration count.
    3 - Variable iteration count.
  Default: 3
  Applies: pgp_sym_encrypt

s2k-digest-algo::
  Which digest algorithm to use in S2K calculation.

  Values: md5, sha1
  Default: sha1
  Applies: pgp_sym_encrypt

s2k-cipher-algo::
  Which cipher to use for encrypting separate session key.

  Values: bf, aes, aes128, aes192, aes256
  Default: use cipher-algo.
  Applies: pgp_sym_encrypt

unicode-mode::
  Whether to convert textual data from database internal encoding to
  UTF-8 and back.  If your database already is UTF-8, no conversion will
  be done, only the data will be tagged as UTF-8.  Without this option
  it will not be.

  Values: 0, 1
  Default: 0
  Applies: pgp_sym_encrypt, pgp_pub_encrypt


5.9.  Generating keys with GnuPG
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Generate a new key:

    gpg --gen-key

The preferred key type is "DSA and Elgamal".

For RSA encryption you must create either DSA or RSA sign-only key
as master and then add RSA encryption subkey with `gpg --edit-key`.

List keys:

    gpg --list-secret-keys

Export ascii-armored public key:

    gpg -a --export KEYID > public.key

Export ascii-armored secret key:

    gpg -a --export-secret-keys KEYID > secret.key

You need to use `dearmor()` on them before giving them to
pgp_pub_* functions.  Or if you can handle binary data, you can drop
"-a" from gpg.

For more details see `man gpg`, http://www.gnupg.org/gph/en/manual.html[
The GNU Privacy Handbook] and other docs on http://www.gnupg.org[] site.


5.10.  Limitations of PGP code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- No support for signing.  That also means that it is not checked
  whether the encryption subkey belongs to master key.

- No support for encryption key as master key.  As such practice
  is generally discouraged, it should not be a problem.

- No support for several subkeys.  This may seem like a problem, as this
  is common practice.  On the other hand, you should not use your regular
  GPG/PGP keys with pgcrypto, but create new ones, as the usage scenario
  is rather different.


6.  Raw encryption
-------------------

Those functions only run a cipher over data, they don't have any advanced
features of PGP encryption.  Therefore they have some major problems:

1. They use user key directly as cipher key.
2. They don't provide any integrity checking, to see
   if the encrypted data was modified.
3. They expect that users manage all encryption parameters
   themselves, even IV.
4. They don't handle text.

So, with the introduction of PGP encryption, usage of raw
encryption functions is discouraged.


    encrypt(data bytea, key bytea, type text) RETURNS bytea
    decrypt(data bytea, key bytea, type text) RETURNS bytea

    encrypt_iv(data bytea, key bytea, iv bytea, type text) RETURNS bytea
    decrypt_iv(data bytea, key bytea, iv bytea, type text) RETURNS bytea

Encrypt/decrypt data with cipher, padding data if needed.

`type` parameter description in pseudo-noteup:

    algo ['-' mode] ['/pad:' padding]

Supported algorithms:

* `bf`		- Blowfish
* `aes`		- AES (Rijndael-128)

Modes:

* `cbc` - next block depends on previous. (default)
* `ecb` - each block is encrypted separately.
          (for testing only)

Padding:

* `pkcs` - data may be any length (default)
* `none` - data must be multiple of cipher block size.

IV is initial value for mode, defaults to all zeroes.  It is ignored for
ECB.  It is clipped or padded with zeroes if not exactly block size.

So, example:

	encrypt(data, 'fooz', 'bf')

is equal to

	encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')


7.  Random bytes
-----------------

    gen_random_bytes(count integer)

Returns `count` cryptographically strong random bytes as bytea value.
There can be maximally 1024 bytes extracted at a time.  This is to avoid
draining the randomness generator pool.


8.  Credits
------------

I have used code from following sources:

`--------------------`-------------------------`-------------------------------
  Algorithm            Author                    Source origin
-------------------------------------------------------------------------------
  DES crypt()          David Burren and others   FreeBSD libcrypt
  MD5 crypt()          Poul-Henning Kamp         FreeBSD libcrypt
  Blowfish crypt()     Solar Designer            www.openwall.com
  Blowfish cipher      Simon Tatham              PuTTY
  Rijndael cipher      Brian Gladman             OpenBSD sys/crypto
  MD5 and SHA1         WIDE Project              KAME kame/sys/crypto
  SHA256/384/512       Aaron D. Gifford          OpenBSD sys/crypto
  BIGNUM math          Michael J. Fromberger     dartmouth.edu/~sting/sw/imath
-------------------------------------------------------------------------------


9.  Legalese
-------------

* I owe a beer to Poul-Henning.


10.  References/Links
----------------------

10.1.  Useful reading
~~~~~~~~~~~~~~~~~~~~~~

http://www.gnupg.org/gph/en/manual.html[]::
	The GNU Privacy Handbook

http://www.openwall.com/crypt/[]::
	Describes the crypt-blowfish algorithm.

http://www.stack.nl/~galactus/remailers/passphrase-faq.html[]::
	How to choose good password.

http://world.std.com/~reinhold/diceware.html[]::
	Interesting idea for picking passwords.

http://www.interhack.net/people/cmcurtin/snake-oil-faq.html[]::
	Describes good and bad cryptography.


10.2.  Technical references
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

http://www.ietf.org/rfc/rfc2440.txt[]::
	OpenPGP message format

http://www.imc.org/draft-ietf-openpgp-rfc2440bis[]::
	New version of RFC2440.

http://www.ietf.org/rfc/rfc1321.txt[]::
	The MD5 Message-Digest Algorithm

http://www.ietf.org/rfc/rfc2104.txt[]::
	HMAC: Keyed-Hashing for Message Authentication

http://www.usenix.org/events/usenix99/provos.html[]::
	Comparison of crypt-des, crypt-md5 and bcrypt algorithms.

http://csrc.nist.gov/cryptval/des.htm[]::
	Standards for DES, 3DES and AES.

http://en.wikipedia.org/wiki/Fortuna_(PRNG)[]::
	Description of Fortuna CSPRNG.

http://jlcooke.ca/random/[]::
	Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.

http://www.cs.ut.ee/~helger/crypto/[]::
	Collection of cryptology pointers.


// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.19 2007/03/28 22:48:58 neilc Exp $
@


1.19
log
@Replace 4-clause licensed blf.[ch] with blowfish implementation
from PuTTY with is under minimal BSD/MIT license. Marko Kreen.
@
text
@d709 1
a709 1
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.18 2006/09/05 21:26:48 tgl Exp $
@


1.18
log
@Remove pgcrypto functions that were deprecated and slated for removal.
Marko Kreen
@
text
@d642 1
a642 1
  Blowfish cipher      Niels Provos              OpenBSD sys/crypto
a653 1
* This product includes software developed by Niels Provos.
d709 1
a709 1
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.17 2006/08/05 00:29:11 neilc Exp $
@


1.17
log
@Fix references to the Options section in the pgcrypto documentation.
Patch from Michael Fuhr.
@
text
@d3 1
a3 1
Marko Kreen <marko@@l-t.ee>
d82 1
a82 8
2.3.  Deprecated functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The `digest_exists()`, `hmac_exists()` and `cipher_exists()` functions
are deprecated.  The plan is to remove them in PostgreSQL 8.2.


2.4.  Security
d710 1
a710 1
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.16 2006/07/19 17:05:50 neilc Exp $
@


1.16
log
@pgcrypto merge cleanup:

  - Few README fixes
  - Keep imath Id string, put $PostgreSQL$ separately.

Patch from Marko Kreen.
@
text
@d334 1
a334 1
Options are described in section 5.7.
d349 1
a349 1
Options are described in section 5.7.
d361 1
a361 1
Options are described in section 5.7.
d381 1
a381 1
Options are described in section 5.7.
d717 1
a717 1
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.15 2006/07/13 04:15:24 neilc Exp $
@


1.15
log
@"Annual" pgcrypto update from Marko Kreen:

Few cleanups and couple of new things:

 - add SHA2 algorithm to older OpenSSL
 - add BIGNUM math to have public-key cryptography work on non-OpenSSL
   build.
 - gen_random_bytes() function

The status of SHA2 algoritms and public-key encryption can now be
changed to 'always available.'

That makes pgcrypto functionally complete and unless there will be new
editions of AES, SHA2 or OpenPGP standards, there is no major changes
planned.
@
text
@d39 2
a40 2
Without zlib, the PGP functions will not support compressed data inside
PGP encrypted packets.
d42 3
a44 2
Without OpenSSL, public-key encryption does not work, as pgcrypto does
not yet contain math functions for large integers.
d46 1
a46 1
There are some other differences with and without OpenSSL:
d425 1
a425 1
  pgp_sym_encrypt(data, psw, 'compress-also=1, cipher-algo=aes256')
d575 1
a575 1
features of PGP encryption.  In addition, they have some major problems:
d717 1
a717 1
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.14 2005/11/03 02:54:07 tgl Exp $
@


1.14
log
@pgcrypto documentation polishing from Marko Kreen, and a small amount
of copy-editing from myself.
@
text
@d52 1
a52 1
 SHA256/384/512               yes       since 0.9.8
d59 1
a59 1
 PGP Public-Key encryption    no        yes
d70 3
d627 11
a637 1
7.  Credits
d642 1
a642 1
`--------------------`-------------------------`----------------------
d644 1
a644 1
----------------------------------------------------------------------
d652 2
a653 1
----------------------------------------------------------------------
d656 1
a656 1
8.  Legalese
d663 2
a664 2
9.  References/Links
---------------------
d666 2
a667 2
9.1.  Useful reading
~~~~~~~~~~~~~~~~~~~~~
d685 2
a686 2
9.2.  Technical references
~~~~~~~~~~~~~~~~~~~~~~~~~~~
d716 1
a716 1
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.13 2005/08/13 02:06:20 momjian Exp $
@


1.14.2.1
log
@Fix references to the Options section in the pgcrypto documentation.
Patch from Michael Fuhr.
@
text
@d330 1
a330 1
Options are described in section 5.8.
d345 1
a345 1
Options are described in section 5.8.
d357 1
a357 1
Options are described in section 5.8.
d377 1
a377 1
Options are described in section 5.8.
d702 1
a702 1
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.14 2005/11/03 02:54:07 tgl Exp $
@


1.13
log
@The large one adds support for RSA keys and reorganizes
the pubkey functions a bit.  The actual RSA-specific code
there is tiny, most of the patch consists of reorg of the
pubkey code, as lots of it was written as elgamal-only.

---------------------------------------------------------------------------

The SHLIB section was copy-pasted from somewhere and contains
several unnecessary libs.  This cleans it up a bit.

 -lcrypt
   we don't use system crypt()

 -lssl, -lssleay32
   no SSL here

 -lz in win32 section
   already added on previous line

 -ldes
   The chance anybody has it is pretty low.
   And the chance pgcrypto works with it is even lower.

Also trim the win32 section.

---------------------------------------------------------------------------

It is already disabled in Makefile, remove code too.

---------------------------------------------------------------------------

I was bit hasty making the random exponent 'k' a prime.  Further researh
shows that Elgamal encryption has no specific needs in respect to k,
any random number is fine.

It is bit different for signing, there it needs to be 'relatively prime'
to p - 1,  that means GCD(k, p-1) == 1, which is also a lot lighter than
full primality.  As we don't do signing, this can be ignored.

This brings major speedup to Elgamal encryption.

---------------------------------------------------------------------------

o  pgp_mpi_free: Accept NULLs
o  pgp_mpi_cksum: result should be 16bit
o  Remove function name from error messages - to be similar to other
   SQL functions, and it does not match anyway the called function
o  remove couple junk lines

---------------------------------------------------------------------------

o  Support for RSA encryption
o  Big reorg to better separate generic and algorithm-specific code.
o  Regression tests for RSA.

---------------------------------------------------------------------------

o  Tom stuck a CVS id into file.  I doubt the usefulness of it,
   but if it needs to be in the file then rather at the end.
   Also tag it as comment for asciidoc.
o  Mention bytea vs. text difference
o  Couple clarifications

---------------------------------------------------------------------------

There is a choice whether to update it with pgp functions or
remove it.  I decided to remove it, updating is pointless.

I've tried to keep the core of pgcrypto relatively independent
from main PostgreSQL, to make it easy to use externally if needed,
and that is good.  Eg. that made development of PGP functions much
nicer.

But I have no plans to release it as generic library, so keeping such
doc
up-to-date is waste of time.  If anyone is interested in using it in
other products, he can probably bother to read the source too.

Commented source is another thing - I'll try to make another pass
over code to see if there is anything non-obvious that would need
more comments.

---------------------------------------------------------------------------

Marko Kreen
@
text
@a0 1

d5 2
d21 7
d82 1
a82 1
are deprecated.  The plan is to remove those in PostgreSQL 8.2.
d151 1
a151 1
   password would have different crypted passwords.  This also
d209 1
a209 1
ti password and therefore the more time to break it.  Although with
d228 3
a230 3
  second on the hardware that time.
- Slower that 4 hashes per second would probably damper usability.
- Faster that 100 hashes per second is probably too fast.
d241 1
a241 1
  1.  Only from lowercase letters
a258 1
password       143781000       25 mins              18 days
a265 2
* MySQL password() numbers are from my own tests.
  (http://grue.l-t.ee/~marko/src/mypass/)
d273 1
a273 1
Note that the "try all combinations" is not a realistic exercise.
d276 1
a276 1
somewhat word-like passwords will be cracked much faster than the above
d278 1
a278 1
cracking.  Or may not.
d300 1
a300 1
   and with random salt - but is produces a full-length binary key.
d386 1
a386 1
gives the key ID what was used for encrypting the data, if given
d389 1
a389 1
It can return 2 special key ID's:
d418 2
a419 2
Option are named to be similar to GnuPG.  Values should be given after
equal sign, different options from each other with commas.  Example:
d466 1
a466 1
  Do not protect data with SHA-1.  Only good reason to use is this
d489 1
a489 1
    0 - Dangerous!  Without salt.
d544 1
a544 1
You need to use `dearmor()` on them before giving giving them to
d604 1
a604 1
* `ecb` - each block in encrypted separately.
d702 1
a702 2
// $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.12 2005/07/18 17:17:12 tgl Exp $

@


1.12
log
@pgcrypto documentation update.  Marko Kreen
@
text
@a0 1
$PostgreSQL$
d280 1
a280 1
standard.
d336 4
d368 4
a431 1

d501 1
a501 1
  Default: same as cipher-algo.
d522 4
a525 1
You need to pick "DSA and Elgamal" key type, others are sign-only.
d543 3
d553 2
a554 1
- No support for RSA keys.  Only Elgamal encryption keys are supported
d556 4
a559 1
- No support for several encryption subkeys.
d650 3
d695 4
@


1.11
log
@Major pgcrypto changes:

of password-based encryption from RFC2440 (OpenPGP).

The goal of this code is to be more featureful encryption solution
than current encrypt(), which only functionality is running cipher
over data.

Compared to encrypt(), pgp_encrypt() does following:

* It uses the equvialent of random Inital Vector to get cipher
  into random state before it processes user data
* Stores SHA-1 of the data into result so any modification
  will be detected.
* Remembers if data was text or binary - thus it can decrypt
  to/from text data.  This was a major nuisance for encrypt().
* Stores info about used algorithms with result, so user needs
  not remember them - more user friendly!
* Uses String2Key algorithms (similar to crypt()) with random salt
  to generate full-length binary key to be used for encrypting.
* Uses standard format for data - you can feed it to GnuPG, if needed.

Optional features (off by default):

* Can use separate session key - user data will be encrypted
  with totally random key, which will be encrypted with S2K
  generated key and attached to result.
* Data compression with zlib.
* Can convert between CRLF<->LF line-endings - to get fully
  RFC2440-compliant behaviour.  This is off by default as
  pgcrypto does not know the line-endings of user data.

Interface is simple:


    pgp_encrypt(data text, key text) returns bytea
    pgp_decrypt(data text, key text) returns text
    pgp_encrypt_bytea(data bytea, key text) returns bytea
    pgp_decrypt_bytea(data bytea, key text) returns bytea

To change parameters (cipher, compression, mdc):

    pgp_encrypt(data text, key text, parms text) returns bytea
    pgp_decrypt(data text, key text, parms text) returns text
    pgp_encrypt_bytea(data bytea, key text, parms text) returns bytea
    pgp_decrypt_bytea(data bytea, key text, parms text) returns bytea

Parameter names I lifted from gpg:

   pgp_encrypt('message', 'key', 'compress-algo=1,cipher-algo=aes256')

For text data, pgp_encrypt simply encrypts the PostgreSQL internal data.

This maps to RFC2440 data type 't' - 'extenally specified encoding'.
But this may cause problems if data is dumped and reloaded into database
which as different internal encoding.  My next goal is to implement data
type 'u' - which means data is in UTF-8 encoding by converting internal
encoding to UTF-8 and back.  And there wont be any compatibility
problems with current code, I think its ok to submit this without UTF-8
encoding by converting internal encoding to UTF-8 and back.  And there
wont be any compatibility problems with current code, I think its ok to
submit this without UTF-8 support.


Here is v4 of PGP encrypt.  This depends on previously sent
Fortuna-patch, as it uses the px_add_entropy function.

- New function: pgp_key_id() for finding key id's.
- Add SHA1 of user data and key into RNG pools.  We need to get
  randomness from somewhere, and it is in user best interests
  to contribute.
- Regenerate pgp-armor test for SQL_ASCII database.
- Cleanup the key handling so that the pubkey support is less
  hackish.

Marko Kreen
@
text
@d1 1
d3 3
a5 3
pgcrypto 0.4 - cryptographic functions for PostgreSQL.
======================================================
by Marko Kreen <marko@@l-t.ee>
d8 2
a9 2
INSTALLATION
============
d11 1
a11 1
Edit makefile, if you want to use any external library.
d13 3
a15 6
NB!  Default randomness source is libc random() function.  This
is so only to get pgcrypto build everywhere.  Randomness is
needed for gen_salt() and pgp_encrypt() functions.  So if you plan
using those, you should definitely change that by editing Makefile.
You can should use urandom device if your OS supports it, otherwise
link pgcrypto against OpenSSL library and use its PRNG.
d17 3
a19 1
After editing Makefile:
a20 2
make
make install
d22 2
a23 2
To run regression tests, install both PostgreSQL and pgcrypto
and then run
d25 2
a26 1
make installcheck
d28 3
a30 2
SQL FUNCTIONS
=============
d32 2
a33 1
	If any of arguments are NULL they return NULL.
d35 2
a36 1
digest(data::bytea, type::text)::bytea
d38 1
a38 2
	Type is here the algorithm to use. E.g. 'md5', 'sha1', ...
	Returns binary hash.
d40 14
a53 1
digest_exists(type::text)::bool
d55 3
a57 1
	Returns BOOL whether given hash exists.
d59 3
a61 1
hmac(data::bytea, key::bytea, type::text)::bytea
a62 7
	Calculates Hashed MAC over data.  type is the same as
	in digest().  Returns binary hash.  Similar to digest()
	but noone can alter data and re-calculate hash without
	knowing key.  If the key is larger than hash blocksize
	it will first hashed and the hash will be used as key.
	
	[ HMAC is described in RFC2104. ]
d64 2
a65 3
hmac_exists(type::text)::bool
	Returns BOOL.  It is separate function because all hashes
	cannot be used in HMAC.
d67 2
a68 1
crypt(password::text, salt::text)::text
a69 3
	Calculates UN*X crypt(3) style hash.  Useful for storing
	passwords.  For generating salt you should use the
	gen_salt() function.  Usage:
d71 2
a72 5
	New password:
	
	  UPDATE .. SET pswhash = crypt(new_psw, gen_salt('md5'));
	
	Authentication:
d74 2
a75 5
	  SELECT pswhash = crypt(given_psw, pswhash) WHERE .. ;
	
	returns BOOL whether the given_psw is correct.  DES crypt
	has max key of 8 bytes, MD5 has max key at least 2^32-1
	bytes but may be larger on some platforms...
a76 2
	Builtin crypt() supports DES, Extended DES, MD5 and Blowfish
	(variant 2a) algorithms.
d78 2
a79 1
gen_salt(type::text)::text
d81 3
a83 6
	Generates a new random salt for usage in crypt().  Type
	
	'des'	- Old UNIX, not recommended
	'md5'	- md5-based crypt()
	'xdes'	- 'Extended DES'
	'bf'	- Blowfish-based, variant 2a
d85 2
a86 2
	When you use --enable-system-crypt then note that system
	libcrypt may not support them all.
d88 1
a88 1
gen_salt(type::text, rounds::int4)::text
a89 2
	same as above, but lets user specify iteration count
	for algorithm.  Number is algorithm specific:
d91 2
a92 4
	type	default	min	max
	---------------------------------
	xdes	725	1	16777215
	bf	6	4	31
d94 2
a95 2
	In case of xdes there is a additional limitation that the
	count must be a odd number.
d97 2
a98 4
	The higher the count, the more time it takes to calculate
	crypt and therefore the more time to break it.  But beware!
	With too high count it takes a _very_long_ time to
	calculate it.
d100 3
a102 2
	For maximum security, you should choose the 'bf' crypt
	and use maximum number of rounds you can still tolerate.
d104 1
a104 2
armor(bytea)::text
dearmor(text)::bytea
d106 1
a106 2
	Those wrap/unwrap data into PGP Ascii Armor which
	is basically Base64 with CRC and additional formatting.
d108 3
a110 4
pgp_sym_encrypt(data::text, key::text)::bytea
pgp_sym_encrypt(data::text, key::text, arg::text)::bytea
pgp_sym_encrypt_bytea(data::bytea, key::text)::bytea
pgp_sym_encrypt_bytea(data::bytea, key::text, arg::text)::bytea
a111 4
pgp_sym_decrypt(data::bytea, key::text)::text
pgp_sym_decrypt(data::bytea, key::text, arg::text)::text
pgp_sym_decrypt_bytea(data::text, key::text)::bytea
pgp_sym_decrypt_bytea(data::text, key::text, arg::text)::bytea
d113 2
a114 2
	Encrypt data into OpenPGP Symmetrically Encrypted Data
	message.  And decrypt it from it.
d116 2
a117 5
	Note that the pgp_sym_encrypt_bytea functions tag the data
	as binary, as the pgp_sym_encrypt will tag the data as text.
	You can not decrypt the binary data as text.  But you can
	decrypt text data as binary.  This rule avoids having
	broken textual data in PostgreSQL.
d119 3
a121 6
	Both encrypt and decrypt accept also third argument, which
	is parameters to the function in following format:
	
	  parm=val[,parm=val]...
	
	Example:
d123 3
a125 2
	  select pgp_sym_encrypt('data', 'psw',
			'compress-algo=2, unicode-mode=1');
d127 1
a127 1
	Accepted parameters are:
a128 11
	cipher-algo: bf, aes, aes128, aes192, aes256
	  Cipher algorithm to use.  OpenSSL gives additional algorithms:
	  3des, cast5
	  Default: aes128
	
	compress-algo: 0, 1, 2
	  Which compression algorithm to use.
	    0 - no compression
	    1 - ZIP compression
	    2 - ZLIB compression [=ZIP plus meta-data and block-CRC's]
	  Default: 0
a129 4
	compress-level: 0, 1-9
	  How much to compress.  Bigger level compresses smaller
	  but also slower.  0 disables compression.
	  Default: 6
d131 2
a132 6
	convert-crlf: 0, 1
	  Whether to convert \n into \r\n when encrypting and
	  \r\n to \n when decrypting.  RFC2440 specifies that
	  text packets should use "\r\n" line-feeds.
	  Use this to get fully RFC-compliant behaviour.
	  Default: 0
d134 3
a136 19
	disable-mdc: 0, 1
	  Do not protect data with SHA-1.  Note that SHA-1 protected
	  packet is from upcoming update to RFC2440.  (Currently at
	  version RFC2440bis-13.)  You need to disable it if you need
	  compatibility with ancient PGP products.  Recent gnupg.org
	  and pgp.com software supports it fine.
	  Default: 0
	
	enable-session-key: 0, 1
	  Use separate session key.
	  Default: 0
	
	s2k-mode: 0, 1, 3
	  Which S2K algorithm to use.  0 is dangerous - without salt.
	  Default: 3
	
	s2k-digest-algo: md5, sha1
	  Which digest algorithm to use in S2K calculation.
	  Default: SHA-1
d138 2
a139 3
	s2k-cipher-algo: bf, aes, aes128, aes192, aes256
	  Which cipher to use for encrypting separate session key.
	  Default: same as cipher-algo.
d141 10
a150 4
	unicode-mode: 0, 1
	  Whether to convert textual data from database internal
	  encoding to UTF-8 and back.
	  Default: 0
d152 9
a160 9
	Only 'convert-crlf' applies to both encrypt and decrypt,
	all others apply only to encrypt - decrypt gets the
	settings from PGP data.
	
	
pgp_pub_encrypt(data::text, key::bytea)::bytea
pgp_pub_encrypt(data::text, key::bytea, arg::text)::bytea
pgp_pub_encrypt_bytea(data::bytea, bytea::text)::bytea
pgp_pub_encrypt_bytea(data::bytea, bytea::text, arg::text)::bytea
a161 6
pgp_pub_decrypt(data::bytea, key::bytea)::text
pgp_pub_decrypt(data::bytea, key::bytea, psw::text)::text
pgp_pub_decrypt(data::bytea, key::bytea, psw::text, arg::text)::text
pgp_pub_decrypt_bytea(data::text, key::bytea)::bytea
pgp_pub_decrypt_bytea(data::text, key::bytea, psw::text)::bytea
pgp_pub_decrypt_bytea(data::text, key::bytea, psw::text, arg::bytea)::bytea
d163 2
a164 3
	Encrypt data into OpenPGP Public-Key Encrypted Data
	message.  And decrypt it from it.  The arg parameter is
	described in pgp_sym_* section.
d166 1
a166 5
	The key must be a public-key packet for pgp_pub_encrypt
	functions and a secret key packet for pgp_pub_decrypt
	functions.  Trying to encrypt with secret key gives a error.
	While being technically possible, it is probably a sign of
	user error and leaking secret keys.
d168 3
a170 8
	Here is a example how to generate them:
	
	Generate a new key:
	
	  gpg --gen-key
	
	You need to pick "DSA and Elgamal" key type, others
	are sign-only.
d172 1
a172 3
	List keys:
	
	  gpg --list-secret-keys
d174 1
a174 1
	Export ascii-armored public key:
d176 1
a176 3
	  gpg -a --export KEYID > public.key
	
	Export ascii-armored secret key:
d178 1
a178 1
	  gpg -a --export-secret-keys KEYID > secret.key
d180 2
a181 3
	You need to use dearmor() on them before giving giving
	them to pgp_pub_* functions.  Ofcourse, if you can handle
	binary data, you can drop "-a" from gpg.
d184 2
a185 1
pgp_key_id(key / data)
d187 1
a187 3
	It shows you either key ID if given PGP public or secret
	key.  Or it gives the key ID what was used for encrypting
	the data, if given encrypted data.
d189 2
a190 1
	It can return 2 special key ID's:
d192 1
a192 3
	  SYMKEY - it got symmetrically encrypted data.
	  ANYKEY - the data packet key ID is clear.  That means
		   you should try all you secret keys on it.
a193 4
encrypt(data::bytea, key::bytea, type::text)::bytea
decrypt(data::bytea, key::bytea, type::text)::bytea
encrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea
decrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea
d195 2
a196 1
	Encrypt/decrypt data with cipher, padding data if needed.
d198 1
a198 1
	Pseudo-noteup:
d200 5
a204 1
	algo ['-' mode] ['/pad:' padding]
d206 1
a206 4
	Supported algorithms:
	
		bf		- Blowfish
		aes, rijndael	- Rijndael-128
d208 6
a213 2
	Others depend on library and are not tested enough, so
	play on your own risk.
d215 2
a216 2
	Modes: 'cbc' (default), 'ecb'.  Again, library may support
	more.
d218 1
a218 2
	Padding is 'pkcs' (default), 'none'.  'none' is mostly for
	testing ciphers, you should not need it.
d220 5
a224 1
	So, example:
a225 3
		encrypt(data, 'fooz', 'bf')
	
	is equal to
d227 2
a228 1
		encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')
d230 2
a231 3
	IV is initial value for mode, defaults to all zeroes.
	It is ignored for ECB.  It is clipped or padded with zeroes
	if not exactly block size.
d233 7
d241 13
a253 2
ALGORITHMS
==========
d255 13
a267 1
The standard functionality at the moment consists of
d269 6
a274 3
Hashes: md5, sha1
Ciphers: bf, aes
Modes: cbc, ecb
a275 1
TODO: write standard names for optional ciphers too.
d277 2
a278 2
LIBRARIES
=========
d280 2
a281 1
* crypt()
a282 1
    internal: des, xdes, md5, bf
d284 2
a285 1
    -lcrypt: ??? (whatever you have)
d287 1
a287 1
* other:
d289 2
a290 4
[ This only lists stuff that the libraries claim to support.  So
  pgcrypto may work with all of them.  But ATM tested are only the
  standard ciphers.  On others pgcrypto and library may mess something
  up. You have been warned.  ]
d292 1
a292 3
internal (default):
    Hashes: MD5, SHA1
    Ciphers: Blowfish, Rijndael-128
d294 8
d303 1
a303 5
OpenSSL (0.9.7):
    Hashes:	MD5, SHA1, RIPEMD160, MD2   
    Ciphers:	Blowfish, AES, CAST5, DES, 3DES
    License:	BSD-like with strong advertisement
    Url:	http://www.openssl.org/
d305 2
d308 297
a604 2
CREDITS
=======
d608 11
a618 6
DES crypt() by David Burren and others	FreeBSD libcrypt
MD5 crypt() by Poul-Henning Kamp	FreeBSD libcrypt
Blowfish crypt() by Solar Designer	www.openwall.com
Blowfish cipher by Niels Provos		OpenBSD sys/crypto
Rijndael cipher by Brian Gladman	OpenBSD sys/crypto
MD5 and SHA1 by WIDE Project		KAME kame/sys/crypto
d620 3
a622 2
LEGALESE
========
d625 2
d628 42
a669 1
* This product includes software developed by Niels Provos.
d671 2
d674 2
@


1.10
log
@Fix typos in documentation.
@
text
@d14 4
a17 4
needed for gen_salt() function.  So if you plan using it, you
should definitely change that by editing Makefile.  You should
be using urandom device if your OS supports it, otherwise link
pgcrypto against OpenSSL library and use its PRNG.
d111 155
@


1.9
log
@pgcrypto update:

* openssl.c: Add 3des and AES support
* README.pgcrypto: list only supported ciphers for openssl

OpenSSL has pre-processor symbol OPENSSL_NO_AES, which
isn't that helpful for detecting if it _does_ exist.
Thus the hack with AES_ENCRYPT.

Marko Kreen
@
text
@d93 1
a93 1
	for algorithm.  Number is algotithm specific:
d152 1
a152 1
The standard functionality at the moment consist of
d158 1
a158 1
TODO: write stardard names for optional ciphers too.
d171 2
a172 2
[ This only list of stuff libraries claim to support.  So
  pgcrypto may work with all of them.  But ATM tested aree only the
@


1.8
log
@Remove support for libmhash/libmcrypt.

libmcrypt seems to dead, maintainer address bounces,
and cast-128 fails on 2 of the 3 test vectors from RFC2144.

So I see no reason to keep around stuff I don't trust
anymore.

Support for several crypto libraries is probably only
confusing to users, although it was good for initial
developing - it helped to find hidden assumptions and
forced me to create regression tests for all functionality.

Marko Kreen
@
text
@d181 1
a181 1
OpenSSL (0.9.6):
d183 1
a183 2
    Ciphers:	DES, DESX, DES3, RC5, RC4, RC2, IDEA,
		Blowfish, CAST5
@


1.7
log
@* regression tests
* minor doc updates

Marko Kreen
@
text
@a188 11
mhash (0.8.9) + mcrypt (2.4.16):
    Hashes:	MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160,
		HAVAL(256,224,192,160,128)
    Ciphers:	DES, DES3, CAST-128(CAST5), CAST-256, xTEA, 3-way,
    		SKIPJACK, Blowfish, Twofish, LOKI97, RC2, RC4, RC6,
		Rijndael-128/192/256, MARS, PANAMA, WAKE, Serpent, IDEA, GOST,
		SAFER, SAFER+, Enigma
    License:	LGPL
    Url:	http://mcrypt.sourceforge.org/
    Url:	http://mhash.sourceforge.org/

@


1.6
log
@I noticed that the contrib Makefiles were reorganized.
Converted pgcrypto one too.

* Changed default randomness source to libc random()
  That way pgcrypto does not have any external dependencies
  and should work everywhere.
* Re-enabled pgcrypto build in contrib/makefile
* contrib/README update - there is more stuff than
  only 'hash functions'
* Noted the libc random fact in README.pgcrypto


Marko Kreen
@
text
@d24 5
d189 1
a189 1
mhash (0.8.9) + mcrypt (2.4.11):
@


1.5
log
@Big thanks to Solar Designer who pointed out a bug in bcrypt
salt generation code.  He also urged using better random source
and making possible to choose using bcrypt and xdes rounds more
easily.  So, here's patch:

* For all salt generation, use Solar Designer's own code.  This
  is mostly due fact that his code is more fit for get_random_bytes()
  style interface.
* New function: gen_salt(type, rounds).  This lets specify iteration
  count for algorithm.
* random.c: px_get_random_bytes() function.
  Supported randomness soure: /dev/urandom, OpenSSL PRNG, libc random()
  Default: /dev/urandom.
* Draft description of C API for pgcrypto functions.

New files: API, crypt-gensalt.c, random.c

Marko Kreen
@
text
@d12 6
a17 4
NB!  Default randomness source is /dev/urandom device.  If you
do not have it, you also need to edit Makefile to let pgcrypto
use either OpenSSL PRNG or libc random() PRNG.  Using libc random()
is discouraged.
@


1.4
log
@/contrib/pgcrypto:

* remove support for encode() as it is in main tree now
* remove krb5.c
* new 'PX library' architecture
* remove BSD license from my code to let the general
  PostgreSQL one to apply
* md5, sha1: ANSIfy, use const where appropriate
* various other formatting and clarity changes
* hmac()
* UN*X-like crypt() - system or internal crypt
* Internal crypt: DES, Extended DES, MD5, Blowfish
  crypt-des.c, crypt-md5.c from FreeBSD
  crypt-blowfish.c from Solar Designer
* gen_salt() for crypt() -  Blowfish, MD5, DES, Extended DES
* encrypt(), decrypt(), encrypt_iv(), decrypt_iv()
* Cipher support in mhash.c, openssl.c
* internal: Blowfish, Rijndael-128 ciphers
* blf.[ch], rijndael.[ch] from OpenBSD
* there will be generated file rijndael-tbl.inc.

Marko Kreen
@
text
@d12 7
d82 21
@


1.3
log
@Documentation update from Marko Kreen.
@
text
@d2 3
a4 1
DESCRIPTION
a5 2
  Here are various cryptographic and otherwise useful
  functions for PostgreSQL.
d7 2
a8 3
    encode(data, type)
        encodes binary data into ASCII-only representation.
	Types supported are 'hex' and 'base64'.
d10 1
a10 2
    decode(data, type)
    	decodes the data processed by encode()
d12 2
a13 3
    digest(data::text, hash_name::text)
	which returns cryptographic checksum over data by
	specified algorithm. eg
d15 2
a16 2
	> select encode(digest('blah', 'sha1'), 'hex');
	5bf1fd927dfb8679496a2e6cf00cbe50c1c87145
d18 1
a18 2
    digest_exists(hash_name::text)::bool
	which reports if particular hash type exists.
d20 1
a20 1
  If any of arguments are NULL they return NULL.
d22 2
a23 1
HASHES
d25 1
a25 1
  For choosing library you must edit Makefile.
d27 1
a27 2
  standalone (default):
	MD5, SHA1
d29 1
a29 3
	(the code is from KAME project.  Actually I hate code
	duplication, but I also want to quarantee that MD5 and
	SHA1 exist)
d31 7
a37 3
  mhash (0.8.1):
	MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160,
	HAVAL(256,224,192,160,128)
d39 3
a41 2
  openssl:
	MD5, SHA1, RIPEMD160, MD2
d43 1
a43 2
  kerberos5 (heimdal):
	MD5, SHA1
d45 3
a47 1
ENCRYPTION
d49 5
a53 2
  There is experimental version out with encryption, HMAC
  and UN*X crypt() support in
d55 5
a59 1
    http://www.l-t.ee/marko/pgsql/
d61 122
a182 1
  Current latest release is pgcrypto-0.3.tar.gz.
@


1.2
log
@I would like to do a interface change in pgcrypto.  (Good
timing, I know :))  At the moment the digest() function returns
hexadecimal coded hash, but I want it to return pure binary.  I
have also included functions encode() and decode() which support
'base64' and 'hex' encodings, so if anyone needs digest() in hex
he can do encode(digest(...), 'hex').

Main reason for it is "to do one thing and do it well" :)

Another reason is if someone needs really lot of digesting, in
the end he wants to store the binary not the hexadecimal result.
It is really silly to convert it to hex then back to binary
again.  As I said if someone needs hex he can get it.

Well, and the real reason that I am doing encrypt()/decrypt()
functions and _they_ return binary.  For testing I like to see
it in hex occasionally, but it is really wrong to let them
return hex.  Only now it caught my eye that hex-coding in
digest() is wrong.  When doing digest() I thought about 'common
case' but hacking with psql is probably _not_ the common case :)

Marko Kreen
@
text
@d47 9
@


1.1
log
@Hashing functions from Marko Kreen <marko@@l-t.ee>
@
text
@d4 9
a12 2
  Here is a implementation of crypto hashes for PostgreSQL.
  It exports 2 functions to SQL level:
d15 1
a15 1
	which returns hexadecimal coded hash over data by
d18 1
a18 1
	> select digest('blah', 'sha1');
@
