26
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
27
* SUCH DAMAGE.
28
28
*
29
- * $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.30 2006/10/04 00:29:46 momjian Exp $
29
+ * $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.31 2007/09/29 02:18:15 tgl Exp $
30
30
*/
31
31
32
32
#include "postgres.h"
70
70
#define AES_DECRYPT 0
71
71
#define AES_KEY rijndael_ctx
72
72
73
- #define AES_set_encrypt_key (key , kbits , ctx ) \
74
- aes_set_key((ctx), (key), (kbits), 1)
75
-
76
- #define AES_set_decrypt_key (key , kbits , ctx ) \
77
- aes_set_key((ctx), (key), (kbits), 0)
78
-
79
- #define AES_ecb_encrypt (src , dst , ctx , enc ) \
80
- do { \
81
- memcpy((dst), (src), 16); \
82
- if (enc) \
83
- aes_ecb_encrypt((ctx), (dst), 16); \
84
- else \
85
- aes_ecb_decrypt((ctx), (dst), 16); \
86
- } while (0)
87
-
88
- #define AES_cbc_encrypt (src , dst , len , ctx , iv , enc ) \
89
- do { \
90
- memcpy((dst), (src), (len)); \
91
- if (enc) { \
92
- aes_cbc_encrypt((ctx), (iv), (dst), (len)); \
93
- memcpy((iv), (dst) + (len) - 16, 16); \
94
- } else { \
95
- aes_cbc_decrypt((ctx), (iv), (dst), (len)); \
96
- memcpy(iv, (src) + (len) - 16, 16); \
97
- } \
98
- } while (0)
73
+ static int
74
+ AES_set_encrypt_key (const uint8 * key , int kbits , AES_KEY * ctx )
75
+ {
76
+ aes_set_key (ctx , key , kbits , 1 );
77
+ return 0 ;
78
+ }
79
+
80
+ static int
81
+ AES_set_decrypt_key (const uint8 * key , int kbits , AES_KEY * ctx )
82
+ {
83
+ aes_set_key (ctx , key , kbits , 0 );
84
+ return 0 ;
85
+ }
86
+
87
+ static void
88
+ AES_ecb_encrypt (const uint8 * src , uint8 * dst , AES_KEY * ctx , int enc )
89
+ {
90
+ memcpy (dst , src , 16 );
91
+ if (enc )
92
+ aes_ecb_encrypt (ctx , dst , 16 );
93
+ else
94
+ aes_ecb_decrypt (ctx , dst , 16 );
95
+ }
96
+
97
+ static void
98
+ AES_cbc_encrypt (const uint8 * src , uint8 * dst , int len , AES_KEY * ctx , uint8 * iv , int enc )
99
+ {
100
+ memcpy (dst , src , len );
101
+ if (enc ) {
102
+ aes_cbc_encrypt (ctx , iv , dst , len );
103
+ memcpy (iv , dst + len - 16 , 16 );
104
+ } else {
105
+ aes_cbc_decrypt (ctx , iv , dst , len );
106
+ memcpy (iv , src + len - 16 , 16 );
107
+ }
108
+ }
99
109
100
110
/*
101
111
* Emulate DES_* API
@@ -375,11 +385,56 @@ gen_ossl_free(PX_Cipher * c)
375
385
376
386
/* Blowfish */
377
387
388
+ /*
389
+ * Check if strong crypto is supported. Some openssl installations
390
+ * support only short keys and unfortunately BF_set_key does not return any
391
+ * error value. This function tests if is possible to use strong key.
392
+ */
393
+ static int
394
+ bf_check_supported_key_len (void )
395
+ {
396
+ static const uint8 key [56 ] = {
397
+ 0xf0 ,0xe1 ,0xd2 ,0xc3 ,0xb4 ,0xa5 ,0x96 ,0x87 ,0x78 ,0x69 ,
398
+ 0x5a ,0x4b ,0x3c ,0x2d ,0x1e ,0x0f ,0x00 ,0x11 ,0x22 ,0x33 ,
399
+ 0x44 ,0x55 ,0x66 ,0x77 ,0x04 ,0x68 ,0x91 ,0x04 ,0xc2 ,0xfd ,
400
+ 0x3b ,0x2f ,0x58 ,0x40 ,0x23 ,0x64 ,0x1a ,0xba ,0x61 ,0x76 ,
401
+ 0x1f ,0x1f ,0x1f ,0x1f ,0x0e ,0x0e ,0x0e ,0x0e ,0xff ,0xff ,
402
+ 0xff ,0xff ,0xff ,0xff ,0xff ,0xff
403
+ };
404
+
405
+ static const uint8 data [8 ] = {0xfe ,0xdc ,0xba ,0x98 ,0x76 ,0x54 ,0x32 ,0x10 };
406
+ static const uint8 res [8 ] = {0xc0 ,0x45 ,0x04 ,0x01 ,0x2e ,0x4e ,0x1f ,0x53 };
407
+ static uint8 out [8 ];
408
+
409
+ BF_KEY bf_key ;
410
+
411
+ /* encrypt with 448bits key and verify output */
412
+ BF_set_key (& bf_key , 56 , key );
413
+ BF_ecb_encrypt (data , out , & bf_key , BF_ENCRYPT );
414
+
415
+ if (memcmp (out , res , 8 ) != 0 )
416
+ return 0 ; /* Output does not match -> strong cipher is not supported */
417
+ return 1 ;
418
+ }
419
+
378
420
static int
379
421
bf_init (PX_Cipher * c , const uint8 * key , unsigned klen , const uint8 * iv )
380
422
{
381
423
ossldata * od = c -> ptr ;
424
+ static int bf_is_strong = -1 ;
425
+
426
+ /*
427
+ * Test if key len is supported. BF_set_key silently cut large keys and it could be
428
+ * be a problem when user transfer crypted data from one server to another.
429
+ */
430
+
431
+ if ( bf_is_strong == -1 )
432
+ bf_is_strong = bf_check_supported_key_len ();
433
+
434
+ if ( !bf_is_strong && klen > 16 )
435
+ return PXE_KEY_TOO_BIG ;
382
436
437
+ /* Key len is supported. We can use it. */
383
438
BF_set_key (& od -> u .bf .key , klen , key );
384
439
if (iv )
385
440
memcpy (od -> iv , iv , BF_BLOCK );
@@ -692,14 +747,26 @@ ossl_aes_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv)
692
747
return 0 ;
693
748
}
694
749
695
- static void
750
+ static int
696
751
ossl_aes_key_init (ossldata * od , int type )
697
752
{
753
+ int err ;
754
+ /*
755
+ * Strong key support could be missing on some openssl installations.
756
+ * We must check return value from set key function.
757
+ */
698
758
if (type == AES_ENCRYPT )
699
- AES_set_encrypt_key (od -> key , od -> klen * 8 , & od -> u .aes_key );
759
+ err = AES_set_encrypt_key (od -> key , od -> klen * 8 , & od -> u .aes_key );
700
760
else
701
- AES_set_decrypt_key (od -> key , od -> klen * 8 , & od -> u .aes_key );
702
- od -> init = 1 ;
761
+ err = AES_set_decrypt_key (od -> key , od -> klen * 8 , & od -> u .aes_key );
762
+
763
+ if (err == 0 )
764
+ {
765
+ od -> init = 1 ;
766
+ return 0 ;
767
+ }
768
+ od -> init = 0 ;
769
+ return PXE_KEY_TOO_BIG ;
703
770
}
704
771
705
772
static int
@@ -709,9 +776,11 @@ ossl_aes_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
709
776
unsigned bs = gen_ossl_block_size (c );
710
777
ossldata * od = c -> ptr ;
711
778
const uint8 * end = data + dlen - bs ;
779
+ int err ;
712
780
713
781
if (!od -> init )
714
- ossl_aes_key_init (od , AES_ENCRYPT );
782
+ if ((err = ossl_aes_key_init (od , AES_ENCRYPT )) != 0 )
783
+ return err ;
715
784
716
785
for (; data <= end ; data += bs , res += bs )
717
786
AES_ecb_encrypt (data , res , & od -> u .aes_key , AES_ENCRYPT );
@@ -725,9 +794,11 @@ ossl_aes_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
725
794
unsigned bs = gen_ossl_block_size (c );
726
795
ossldata * od = c -> ptr ;
727
796
const uint8 * end = data + dlen - bs ;
797
+ int err ;
728
798
729
799
if (!od -> init )
730
- ossl_aes_key_init (od , AES_DECRYPT );
800
+ if ((err = ossl_aes_key_init (od , AES_DECRYPT )) != 0 )
801
+ return err ;
731
802
732
803
for (; data <= end ; data += bs , res += bs )
733
804
AES_ecb_encrypt (data , res , & od -> u .aes_key , AES_DECRYPT );
@@ -739,10 +810,12 @@ ossl_aes_cbc_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
739
810
uint8 * res )
740
811
{
741
812
ossldata * od = c -> ptr ;
813
+ int err ;
742
814
743
815
if (!od -> init )
744
- ossl_aes_key_init (od , AES_ENCRYPT );
745
-
816
+ if ((err = ossl_aes_key_init (od , AES_ENCRYPT )) != 0 )
817
+ return err ;
818
+
746
819
AES_cbc_encrypt (data , res , dlen , & od -> u .aes_key , od -> iv , AES_ENCRYPT );
747
820
return 0 ;
748
821
}
@@ -752,9 +825,11 @@ ossl_aes_cbc_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
752
825
uint8 * res )
753
826
{
754
827
ossldata * od = c -> ptr ;
828
+ int err ;
755
829
756
830
if (!od -> init )
757
- ossl_aes_key_init (od , AES_DECRYPT );
831
+ if ((err = ossl_aes_key_init (od , AES_DECRYPT )) != 0 )
832
+ return err ;
758
833
759
834
AES_cbc_encrypt (data , res , dlen , & od -> u .aes_key , od -> iv , AES_DECRYPT );
760
835
return 0 ;
0 commit comments