[patch 4/6] openssl.c: 3DES and AES support - Mailing list pgsql-patches

From Marko Kreen
Subject [patch 4/6] openssl.c: 3DES and AES support
Date
Msg-id 20050319234647.244194000@grue
Whole thread Raw
In response to [patch 0/6] pgcrypto update  (Marko Kreen <marko@l-t.ee>)
List 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/


--

pgsql-patches by date:

Previous
From: Marko Kreen
Date:
Subject: [patch 6/6] regression test updates
Next
From: "Magnus Hagander"
Date:
Subject: Re: [pgsql-hackers-win32] explain analyze timings