diff options
-rw-r--r-- | contrib/pgcrypto/expected/rijndael.out | 118 | ||||
-rw-r--r-- | contrib/pgcrypto/openssl.c | 39 | ||||
-rw-r--r-- | contrib/pgcrypto/sql/rijndael.sql | 53 | ||||
-rw-r--r-- | doc/src/sgml/pgcrypto.sgml | 8 |
4 files changed, 217 insertions, 1 deletions
diff --git a/contrib/pgcrypto/expected/rijndael.out b/contrib/pgcrypto/expected/rijndael.out index 015ba4430d9..28e28b989fd 100644 --- a/contrib/pgcrypto/expected/rijndael.out +++ b/contrib/pgcrypto/expected/rijndael.out @@ -135,3 +135,121 @@ select encode(decrypt(encrypt('Lets try a longer message.', '0123456789', 'aes') Lets try a longer message. (1 row) +-- cfb +SELECT encrypt( +'\x00112233445566778899aabbccddeeff', +'\x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', +'aes-cfb/pad:none'); + encrypt +------------------------------------ + \xf28122856e1cf9a7216a30d111f3997f +(1 row) + +-- without padding, input not multiple of block size +SELECT encrypt( +'\x00112233445566778899aabbccddeeff00', +'\x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', +'aes-cfb/pad:none'); + encrypt +-------------------------------------- + \xf28122856e1cf9a7216a30d111f3997fcb +(1 row) + +-- key padding +SELECT encrypt( +'\x0011223344', +'\x000102030405', +'aes-cfb'); + encrypt +-------------- + \x8145d1a0ef +(1 row) + +SELECT encrypt( +'\x0011223344', +'\x000102030405060708090a0b0c0d0e0f10111213', +'aes-cfb'); + encrypt +-------------- + \x52642c3b9c +(1 row) + +SELECT encrypt( +'\x0011223344', +'\x000102030405060708090a0b0c0d0e0f101112131415161718191a1b', +'aes-cfb'); + encrypt +-------------- + \xc93b4468a4 +(1 row) + +-- empty data +select encrypt('', 'foo', 'aes-cfb'); + encrypt +--------- + \x +(1 row) + +-- 10 bytes key +select encrypt('foo', '0123456789', 'aes-cfb'); + encrypt +---------- + \x6f8ced +(1 row) + +-- 22 bytes key +select encrypt('foo', '0123456789012345678901', 'aes-cfb'); + encrypt +---------- + \xfb47d2 +(1 row) + +-- decrypt +select encode(decrypt(encrypt('foo', '0123456', 'aes-cfb'), '0123456', 'aes-cfb'), 'escape'); + encode +-------- + foo +(1 row) + +-- data not multiple of block size +select encode(decrypt(encrypt('foo', '0123456', 'aes-cfb') || '\x00'::bytea, '0123456', 'aes-cfb'), 'escape'); + encode +--------- + foo\337 +(1 row) + +-- bad padding +-- (The input value is the result of encrypt_iv('abcdefghijklmnopqrstuvwxyz', '0123456', 'abcd', 'aes-cfb') +-- with the 16th byte changed (s/c5/d5/) to corrupt the padding of the last block.) +select encode(decrypt_iv('\xf9ad6817cb58d31dd9ba6571fbc4f55d56f65b631f0f437cb828', '0123456', 'abcd', 'aes-cfb'), 'escape'); + encode +------------------------------------------------- + abcdefghijklmnoq\243:\205o\x7F\x05z\276\x07\332 +(1 row) + +-- iv +select encrypt_iv('foo', '0123456', 'abcd', 'aes-cfb'); + encrypt_iv +------------ + \xfea064 +(1 row) + +select encode(decrypt_iv('\xfea064', '0123456', 'abcd', 'aes-cfb'), 'escape'); + encode +-------- + foo +(1 row) + +-- long message +select encrypt('Lets try a longer message.', '0123456789', 'aes-cfb'); + encrypt +-------------------------------------------------------- + \x4586f6c6351055051f723b1b0aad52c877eaf0c421d18fd73a28 +(1 row) + +select encode(decrypt(encrypt('Lets try a longer message.', '0123456789', 'aes-cfb'), '0123456789', 'aes-cfb'), 'escape'); + encode +---------------------------- + Lets try a longer message. +(1 row) + diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index 75f40a2d034..f179e80c842 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -617,6 +617,36 @@ ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv return err; } +static int +ossl_aes_cfb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) +{ + OSSLCipher *od = c->ptr; + int err; + + err = ossl_aes_init(c, key, klen, iv); + if (err) + return err; + + switch (od->klen) + { + case 128 / 8: + od->evp_ciph = EVP_aes_128_cfb(); + break; + case 192 / 8: + od->evp_ciph = EVP_aes_192_cfb(); + break; + case 256 / 8: + od->evp_ciph = EVP_aes_256_cfb(); + break; + default: + /* shouldn't happen */ + err = PXE_CIPHER_INIT; + break; + } + + return err; +} + /* * aliases */ @@ -636,6 +666,7 @@ static PX_Alias ossl_aliases[] = { {"rijndael", "aes-cbc"}, {"rijndael-cbc", "aes-cbc"}, {"rijndael-ecb", "aes-ecb"}, + {"rijndael-cfb", "aes-cfb"}, {NULL} }; @@ -707,6 +738,13 @@ static const struct ossl_cipher ossl_aes_cbc = { 128 / 8, 256 / 8 }; +static const struct ossl_cipher ossl_aes_cfb = { + ossl_aes_cfb_init, + NULL, /* EVP_aes_XXX_cfb(), determined in init + * function */ + 128 / 8, 256 / 8 +}; + /* * Special handlers */ @@ -728,6 +766,7 @@ static const struct ossl_cipher_lookup ossl_cipher_types[] = { {"cast5-cbc", &ossl_cast_cbc}, {"aes-ecb", &ossl_aes_ecb}, {"aes-cbc", &ossl_aes_cbc}, + {"aes-cfb", &ossl_aes_cfb}, {NULL} }; diff --git a/contrib/pgcrypto/sql/rijndael.sql b/contrib/pgcrypto/sql/rijndael.sql index a2766419980..de4e4da5e29 100644 --- a/contrib/pgcrypto/sql/rijndael.sql +++ b/contrib/pgcrypto/sql/rijndael.sql @@ -70,3 +70,56 @@ select encode(decrypt_iv('\x2c24cb7da91d6d5699801268b0f5adad', '0123456', 'abcd' -- long message select encrypt('Lets try a longer message.', '0123456789', 'aes'); select encode(decrypt(encrypt('Lets try a longer message.', '0123456789', 'aes'), '0123456789', 'aes'), 'escape'); + +-- cfb +SELECT encrypt( +'\x00112233445566778899aabbccddeeff', +'\x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', +'aes-cfb/pad:none'); + +-- without padding, input not multiple of block size +SELECT encrypt( +'\x00112233445566778899aabbccddeeff00', +'\x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', +'aes-cfb/pad:none'); + +-- key padding + +SELECT encrypt( +'\x0011223344', +'\x000102030405', +'aes-cfb'); + +SELECT encrypt( +'\x0011223344', +'\x000102030405060708090a0b0c0d0e0f10111213', +'aes-cfb'); + +SELECT encrypt( +'\x0011223344', +'\x000102030405060708090a0b0c0d0e0f101112131415161718191a1b', +'aes-cfb'); + +-- empty data +select encrypt('', 'foo', 'aes-cfb'); +-- 10 bytes key +select encrypt('foo', '0123456789', 'aes-cfb'); +-- 22 bytes key +select encrypt('foo', '0123456789012345678901', 'aes-cfb'); + +-- decrypt +select encode(decrypt(encrypt('foo', '0123456', 'aes-cfb'), '0123456', 'aes-cfb'), 'escape'); +-- data not multiple of block size +select encode(decrypt(encrypt('foo', '0123456', 'aes-cfb') || '\x00'::bytea, '0123456', 'aes-cfb'), 'escape'); +-- bad padding +-- (The input value is the result of encrypt_iv('abcdefghijklmnopqrstuvwxyz', '0123456', 'abcd', 'aes-cfb') +-- with the 16th byte changed (s/c5/d5/) to corrupt the padding of the last block.) +select encode(decrypt_iv('\xf9ad6817cb58d31dd9ba6571fbc4f55d56f65b631f0f437cb828', '0123456', 'abcd', 'aes-cfb'), 'escape'); + +-- iv +select encrypt_iv('foo', '0123456', 'abcd', 'aes-cfb'); +select encode(decrypt_iv('\xfea064', '0123456', 'abcd', 'aes-cfb'), 'escape'); + +-- long message +select encrypt('Lets try a longer message.', '0123456789', 'aes-cfb'); +select encode(decrypt(encrypt('Lets try a longer message.', '0123456789', 'aes-cfb'), '0123456789', 'aes-cfb'), 'escape'); diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml index a4d035eabdd..f87668dfaed 100644 --- a/doc/src/sgml/pgcrypto.sgml +++ b/doc/src/sgml/pgcrypto.sgml @@ -1084,6 +1084,11 @@ decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea </listitem> <listitem> <para> + <literal>cfb</literal> — next block depends on previous encrypted block + </para> + </listitem> + <listitem> + <para> <literal>ecb</literal> — each block is encrypted separately (for testing only) </para> @@ -1112,7 +1117,8 @@ encrypt(data, 'fooz', 'bf-cbc/pad:pkcs') </para> <para> In <function>encrypt_iv</function> and <function>decrypt_iv</function>, the - <parameter>iv</parameter> parameter is the initial value for the CBC mode; + <parameter>iv</parameter> parameter is the initial value for the CBC and + CFB mode; it is ignored for ECB. It is clipped or padded with zeroes if not exactly block size. It defaults to all zeroes in the functions without this parameter. |