Skip site navigation (1) Skip section navigation (2)

[patch 4/6] openssl.c: 3DES and AES support

From: Marko Kreen <marko(at)l-t(dot)ee>
To: pgsql-patches(at)postgresql(dot)org
Subject: [patch 4/6] openssl.c: 3DES and AES support
Date: 2005-03-19 23:45:55
Message-ID: 20050319234647.244194000@grue (view raw or flat)
Thread:
Lists: pgsql-patches
* 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.


Index: pgsql/contrib/pgcrypto/openssl.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/openssl.c
--- pgsql/contrib/pgcrypto/openssl.c
***************
*** 36,41 ****
--- 36,49 ----
  #include <openssl/evp.h>
  
  /*
+  * Is OpenSSL compiled with AES? 
+  */
+ #undef GOT_AES
+ #ifdef AES_ENCRYPT
+ #define GOT_AES
+ #endif
+ 
+ /*
   * Hashes
   */
  static unsigned
*************** typedef struct
*** 165,171 ****
--- 173,186 ----
  		{
  			des_key_schedule key_schedule;
  		}			des;
+ 		struct
+ 		{
+ 			des_key_schedule k1, k2, k3;
+ 		}			des3;
  		CAST_KEY	cast_key;
+ #ifdef GOT_AES
+ 		AES_KEY		aes_key;
+ #endif
  	}			u;
  	uint8		key[EVP_MAX_KEY_LENGTH];
  	uint8		iv[EVP_MAX_IV_LENGTH];
*************** ossl_des_cbc_decrypt(PX_Cipher * c, cons
*** 362,367 ****
--- 377,467 ----
  	return 0;
  }
  
+ /* DES3 */
+ 
+ static int
+ ossl_des3_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv)
+ {
+ 	ossldata   *od = c->ptr;
+ 	des_cblock	xkey1,
+ 				xkey2,
+ 				xkey3;
+ 
+ 	memset(&xkey1, 0, sizeof(xkey1));
+ 	memset(&xkey2, 0, sizeof(xkey2));
+ 	memset(&xkey2, 0, sizeof(xkey2));
+ 	memcpy(&xkey1, key, klen > 8 ? 8 : klen);
+ 	if (klen > 8)
+ 		memcpy(&xkey2, key + 8, (klen - 8) > 8 ? 8 : (klen - 8));
+ 	if (klen > 16)
+ 		memcpy(&xkey3, key + 16, (klen - 16) > 8 ? 8 : (klen - 16));
+ 
+ 	DES_set_key(&xkey1, &od->u.des3.k1);
+ 	DES_set_key(&xkey2, &od->u.des3.k2);
+ 	DES_set_key(&xkey3, &od->u.des3.k3);
+ 	memset(&xkey1, 0, sizeof(xkey1));
+ 	memset(&xkey2, 0, sizeof(xkey2));
+ 	memset(&xkey3, 0, sizeof(xkey3));
+ 
+ 	if (iv)
+ 		memcpy(od->iv, iv, 8);
+ 	else
+ 		memset(od->iv, 0, 8);
+ 	return 0;
+ }
+ 
+ static int
+ ossl_des3_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					  uint8 *res)
+ {
+ 	unsigned	bs = gen_ossl_block_size(c);
+ 	unsigned	i;
+ 	ossldata   *od = c->ptr;
+ 
+ 	for (i = 0; i < dlen / bs; i++)
+ 		DES_ecb3_encrypt(data + i * bs, res + i * bs,
+ 						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 1);
+ 	return 0;
+ }
+ 
+ static int
+ ossl_des3_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					  uint8 *res)
+ {
+ 	unsigned	bs = gen_ossl_block_size(c);
+ 	unsigned	i;
+ 	ossldata   *od = c->ptr;
+ 
+ 	for (i = 0; i < dlen / bs; i++)
+ 		DES_ecb3_encrypt(data + i * bs, res + i * bs,
+ 						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 0);
+ 	return 0;
+ }
+ 
+ static int
+ ossl_des3_cbc_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					  uint8 *res)
+ {
+ 	ossldata   *od = c->ptr;
+ 
+ 	DES_ede3_cbc_encrypt(data, res, dlen,
+ 						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
+ 						 (des_cblock *) od->iv, 1);
+ 	return 0;
+ }
+ 
+ static int
+ ossl_des3_cbc_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					  uint8 *res)
+ {
+ 	ossldata   *od = c->ptr;
+ 
+ 	DES_ede3_cbc_encrypt(data, res, dlen,
+ 						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
+ 						 (des_cblock *) od->iv, 0);
+ 	return 0;
+ }
+ 
  /* CAST5 */
  
  static int
*************** ossl_cast_cbc_decrypt(PX_Cipher * c, con
*** 420,425 ****
--- 520,622 ----
  	return 0;
  }
  
+ /* AES */
+ 
+ #ifdef GOT_AES
+ 
+ static int
+ ossl_aes_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv)
+ {
+ 	ossldata   *od = c->ptr;
+ 	unsigned	bs = gen_ossl_block_size(c);
+ 
+ 	if (klen <= 128/8)
+ 		od->klen = 128/8;
+ 	else if (klen <= 192/8)
+ 		od->klen = 192/8;
+ 	else if (klen <= 256/8)
+ 		od->klen = 256/8;
+ 	else
+ 		return PXE_KEY_TOO_BIG;
+ 
+ 	memcpy(od->key, key, klen);
+ 
+ 	if (iv)
+ 		memcpy(od->iv, iv, bs);
+ 	else
+ 		memset(od->iv, 0, bs);
+ 	return 0;
+ }
+ 
+ static void
+ ossl_aes_key_init(ossldata * od, int type)
+ {
+ 	if (type == AES_ENCRYPT)
+ 		AES_set_encrypt_key(od->key, od->klen * 8, &od->u.aes_key);
+ 	else
+ 		AES_set_decrypt_key(od->key, od->klen * 8, &od->u.aes_key);
+ 	od->init = 1;
+ }
+ 
+ static int
+ ossl_aes_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					 uint8 *res)
+ {
+ 	unsigned	bs = gen_ossl_block_size(c);
+ 	ossldata   *od = c->ptr;
+ 	const uint8 *end = data + dlen - bs;
+ 
+ 	if (!od->init)
+ 		ossl_aes_key_init(od, AES_ENCRYPT);
+ 
+ 	for (; data <= end; data += bs, res += bs)
+ 		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_ENCRYPT);
+ 	return 0;
+ }
+ 
+ static int
+ ossl_aes_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					 uint8 *res)
+ {
+ 	unsigned	bs = gen_ossl_block_size(c);
+ 	ossldata   *od = c->ptr;
+ 	const uint8 *end = data + dlen - bs;
+ 
+ 	if (!od->init)
+ 		ossl_aes_key_init(od, AES_DECRYPT);
+ 
+ 	for (; data <= end; data += bs, res += bs)
+ 		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_DECRYPT);
+ 	return 0;
+ }
+ 
+ static int
+ ossl_aes_cbc_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					 uint8 *res)
+ {
+ 	ossldata   *od = c->ptr;
+ 
+ 	if (!od->init)
+ 		ossl_aes_key_init(od, AES_ENCRYPT);
+ 
+ 	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_ENCRYPT);
+ 	return 0;
+ }
+ 
+ static int
+ ossl_aes_cbc_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen,
+ 					 uint8 *res)
+ {
+ 	ossldata   *od = c->ptr;
+ 
+ 	if (!od->init)
+ 		ossl_aes_key_init(od, AES_DECRYPT);
+ 
+ 	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_DECRYPT);
+ 	return 0;
+ }
+ #endif
+ 
  /*
   * aliases
   */
*************** static PX_Alias ossl_aliases[] = {
*** 431,437 ****
--- 628,641 ----
  	{"blowfish-ecb", "bf-ecb"},
  	{"blowfish-cfb", "bf-cfb"},
  	{"des", "des-cbc"},
+ 	{"3des", "des3-cbc"},
+ 	{"3des-ecb", "des3-ecb"},
+ 	{"3des-cbc", "des3-cbc"},
  	{"cast5", "cast5-cbc"},
+ 	{"aes", "aes-cbc"},
+ 	{"rijndael", "aes-cbc"},
+ 	{"rijndael-cbc", "aes-cbc"},
+ 	{"rijndael-ecb", "aes-ecb"},
  	{NULL}
  };
  
*************** static const struct ossl_cipher ossl_des
*** 460,465 ****
--- 664,679 ----
  	64 / 8, 64 / 8, 0
  };
  
+ static const struct ossl_cipher ossl_des3_ecb = {
+ 	ossl_des3_init, ossl_des3_ecb_encrypt, ossl_des3_ecb_decrypt,
+ 	64 / 8, 192 / 8, 0
+ };
+ 
+ static const struct ossl_cipher ossl_des3_cbc = {
+ 	ossl_des3_init, ossl_des3_cbc_encrypt, ossl_des3_cbc_decrypt,
+ 	64 / 8, 192 / 8, 0
+ };
+ 
  static const struct ossl_cipher ossl_cast_ecb = {
  	ossl_cast_init, ossl_cast_ecb_encrypt, ossl_cast_ecb_decrypt,
  	64 / 8, 128 / 8, 0
*************** static const struct ossl_cipher ossl_cas
*** 470,475 ****
--- 684,701 ----
  	64 / 8, 128 / 8, 0
  };
  
+ #ifdef GOT_AES
+ static const struct ossl_cipher ossl_aes_ecb = {
+ 	ossl_aes_init, ossl_aes_ecb_encrypt, ossl_aes_ecb_decrypt,
+ 	128 / 8, 256 / 8, 0
+ };
+ 
+ static const struct ossl_cipher ossl_aes_cbc = {
+ 	ossl_aes_init, ossl_aes_cbc_encrypt, ossl_aes_cbc_decrypt,
+ 	128 / 8, 256 / 8, 0
+ };
+ #endif
+ 
  /*
   * Special handlers
   */
*************** static const struct ossl_cipher_lookup o
*** 485,492 ****
--- 711,724 ----
  	{"bf-cfb", &ossl_bf_cfb},
  	{"des-ecb", &ossl_des_ecb},
  	{"des-cbc", &ossl_des_cbc},
+ 	{"des3-ecb", &ossl_des3_ecb},
+ 	{"des3-cbc", &ossl_des3_cbc},
  	{"cast5-ecb", &ossl_cast_ecb},
  	{"cast5-cbc", &ossl_cast_cbc},
+ #ifdef GOT_AES
+ 	{"aes-ecb", &ossl_aes_ecb},
+ 	{"aes-cbc", &ossl_aes_cbc},
+ #endif
  	{NULL}
  };
  
Index: pgsql/contrib/pgcrypto/README.pgcrypto
===================================================================
*** pgsql.orig/contrib/pgcrypto/README.pgcrypto
--- pgsql/contrib/pgcrypto/README.pgcrypto
*************** internal (default):
*** 178,187 ****
      Ciphers: Blowfish, Rijndael-128
  
  
! OpenSSL (0.9.6):
      Hashes:	MD5, SHA1, RIPEMD160, MD2   
!     Ciphers:	DES, DESX, DES3, RC5, RC4, RC2, IDEA,
! 		Blowfish, CAST5
      License:	BSD-like with strong advertisement
      Url:	http://www.openssl.org/
  
--- 178,186 ----
      Ciphers: Blowfish, Rijndael-128
  
  
! 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/
  

--

In response to

pgsql-patches by date

Next:From: Marko KreenDate: 2005-03-19 23:45:56
Subject: [patch 5/6] pseudo random bytes
Previous:From: Marko KreenDate: 2005-03-19 23:45:54
Subject: [patch 3/6] better error handling

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group