[erlang-patches] Patch to add Blowfish cfb64 to crypto app

Raimo Niskanen <>
Wed Jul 1 10:52:35 CEST 2009


On Sat, Jun 27, 2009 at 11:45:24AM +0100, Paul Oliver wrote:
> Hi all,
> 
> Please find attached a patch to add Blowfish cfb64 to the crypto app.
> This has been tested on Linux only.
> 
> Patch is against R13B01.
> 
> Any feedback greatly appreciated.

Thank you very much!

Generally these kind of patches (tested on Linux) create
problems for us since we strive to support also Solaris,
{Free,Open}BSD, etc... and sometimes they lag behind
in OpenSSL version. Furthermore the crypto application
is not yet dynamic about what it can do. It could be
made but that remains to be done.

But Blowfish CFB64 is as far as I can see supported
on all openssl versions we have to be prepared for...

We will try to squeeze your patch into R13B02.

> 
> Cheers,
> Paul.

> *** /tmp/erlang-otp/lib/crypto/c_src/crypto_drv.c	2009-06-25 08:29:05.000000000 +0100
> --- lib/crypto/c_src/crypto_drv.c	2009-06-25 16:21:54.000000000 +0100
> ***************
> *** 52,57 ****
> --- 52,58 ----
>   #include <openssl/objects.h>
>   #include <openssl/rc4.h>
>   #include <openssl/rc2.h>
> + #include <openssl/blowfish.h>
>   
>   #ifdef DEBUG
>   #  define ASSERT(e) \
> *************** static ErlDrvEntry crypto_driver_entry =
> *** 209,214 ****
> --- 210,218 ----
>   #define DRV_SHA512_FINAL        58
>   #endif
>   
> + #define DRV_BF_CFB64_ENCRYPT     59
> + #define DRV_BF_CFB64_DECRYPT     60
> + 
>   /* #define DRV_CBC_IDEA_ENCRYPT    34 */
>   /* #define DRV_CBC_IDEA_DECRYPT    35 */
>   
> *************** static int control(ErlDrvData drv_data, 
> *** 354,360 ****
>       int prime_len, generator;
>       int privkey_len, pubkey_len, dh_p_len, dh_g_len;
>       unsigned int rsa_s_len, j;
> !     char *key, *key2, *dbuf, *p;
>       const_DES_cblock *des_key, *des_key2, *des_key3;
>       const unsigned char *des_dbuf;
>       BIGNUM *bn_from, *bn_to, *bn_rand, *bn_result;
> --- 358,364 ----
>       int prime_len, generator;
>       int privkey_len, pubkey_len, dh_p_len, dh_g_len;
>       unsigned int rsa_s_len, j;
> !     char *key, *key2, *dbuf, *p, *ivec;
>       const_DES_cblock *des_key, *des_key2, *des_key3;
>       const unsigned char *des_dbuf;
>       BIGNUM *bn_from, *bn_to, *bn_rand, *bn_result;
> *************** static int control(ErlDrvData drv_data, 
> *** 369,374 ****
> --- 373,388 ----
>   /*     IDEA_KEY_SCHEDULE idea, idea2; */
>       unsigned char hmacbuf[SHA_DIGEST_LENGTH];
>       unsigned char *rsa_s, *dsa_s;
> +     /* blowfish ivec */
> +     unsigned char bf_tkey[8];
> +     /* blowfish ivec pos */
> +     int bf_n;
> +     /* blowfish direction */
> +     int bf_direction;
> +     /* blowfish input data */
> +     const unsigned char *bf_dbuf;
> +     /* blowfish key 8 */
> +     BF_KEY bf_key;
>       /* char hmacbuf[SHA_LEN]; */
>   #if SSL_VERSION_0_9_8
>       SHA256_CTX sha256_ctx;
> *************** static int control(ErlDrvData drv_data, 
> *** 503,508 ****
> --- 517,541 ----
>                            (command == DRV_CBC_DES_ENCRYPT));
>           return dlen;
>   
> +     case DRV_BF_CFB64_ENCRYPT:
> +     case DRV_BF_CFB64_DECRYPT:
> +       /* buf = klen[4] key ivec[8] data */
> +       klen = get_int32(buf);
> +       key = buf + 4;
> +       ivec = key + klen;
> +       bf_dbuf = ivec + 8;
> +       dlen = len - 4 - klen - 8;
> +       if (dlen < 0)
> + 	return -1;
> +       BF_set_key(&bf_key, klen, key);
> +       memcpy(bf_tkey, ivec, 8);
> +       bin = return_binary(rbuf,rlen,dlen);
> +       if (bin==NULL) return -1;
> +       bf_direction = command == DRV_BF_CFB64_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT;
> +       bf_n = 0;
> +       BF_cfb64_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, &bf_n, bf_direction);
> +       return dlen;
> + 
>   /*     case DRV_CBC_IDEA_ENCRYPT: */
>   /*     case DRV_CBC_IDEA_DECRYPT: */
>            /* buf = key[16] ivec[8] data */
> *** /tmp/erlang-otp/lib/crypto/doc/src/crypto.xml	2009-06-25 08:29:05.000000000 +0100
> --- lib/crypto/doc/src/crypto.xml	2009-06-27 10:51:47.000000000 +0100
> *************** Mpint() = <![CDATA[<<ByteLen:32/integer-
> *** 324,329 ****
> --- 324,359 ----
>         </desc>
>       </func>
>       <func>
> +       <name>blowfish_cfb64_encrypt(Key, IVec, Text) -> Cipher</name>
> +       <fsummary>Encrypt <c>Text</c>using Blowfish in CFB mode with 64
> +         bit feedback</fsummary>
> +       <type>
> +         <v>Key = Text = iolist() | binary()</v>
> +         <v>IVec = Cipher = binary()</v>
> +       </type>
> +       <desc>
> +         <p>Encrypts <c>Text</c> using Blowfish in CFB mode with 64 bit
> +           feedback. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an
> +           arbitrary initializing vector. The length of <c>IVec</c>
> +           must be 64 bits (8 bytes).</p>
> +       </desc>
> +     </func>
> +     <func>
> +       <name>blowfish_cfb64_decrypt(Key, IVec, Text) -> Cipher</name>
> +       <fsummary>Decrypt <c>Text</c>using Blowfish in CFB mode with 64
> +         bit feedback</fsummary>
> +       <type>
> +         <v>Key = Text = iolist() | binary()</v>
> +         <v>IVec = Cipher = binary()</v>
> +       </type>
> +       <desc>
> +         <p>Decrypts <c>Text</c> using Blowfish in CFB mode with 64 bit
> +           feedback. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an
> +           arbitrary initializing vector. The length of <c>IVec</c>
> +           must be 64 bits (8 bytes).</p>
> +       </desc>
> +     </func>
> +     <func>
>         <name>aes_cfb_128_encrypt(Key, IVec, Text) -> Cipher</name>
>         <name>aes_cbc_128_encrypt(Key, IVec, Text) -> Cipher</name>
>         <fsummary>Encrypt <c>Text</c>according to AES in Cipher Feedback  mode or Cipher Block Chaining mode</fsummary>
> *** /tmp/erlang-otp/lib/crypto/src/crypto.erl	2009-06-25 08:29:05.000000000 +0100
> --- lib/crypto/src/crypto.erl	2009-06-27 10:53:24.000000000 +0100
> ***************
> *** 30,35 ****
> --- 30,36 ----
>   -export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac_96/2]).
>   -export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]).
>   -export([des3_cbc_encrypt/5, des3_cbc_decrypt/5]).
> + -export([blowfish_cfb64_encrypt/3,blowfish_cfb64_decrypt/3]).
>   -export([des_ede3_cbc_encrypt/5, des_ede3_cbc_decrypt/5]).
>   -export([aes_cfb_128_encrypt/3, aes_cfb_128_decrypt/3]).
>   -export([exor/2]).
> ***************
> *** 111,116 ****
> --- 112,119 ----
>   %% -define(SHA512_UPDATE,	 57).
>   %% -define(SHA512_FINAL,	 58).
>   
> + -define(BF_CFB64_ENCRYPT, 59).
> + -define(BF_CFB64_DECRYPT, 60).
>   
>   %% -define(IDEA_CBC_ENCRYPT, 34).
>   %% -define(IDEA_CBC_DECRYPT, 35).
> *************** des_ede3_cbc_decrypt(Key1, Key2, Key3, I
> *** 297,302 ****
> --- 300,314 ----
>       control(?DES_EDE3_CBC_DECRYPT, [Key1, Key2, Key3, IVec, Data]).
>   
>   %%
> + %% Blowfish
> + %%
> + blowfish_cfb64_encrypt(Key, IVec, Data) ->
> +     control_bin(?BF_CFB64_ENCRYPT, Key, list_to_binary([IVec, Data])).
> + 
> + blowfish_cfb64_decrypt(Key, IVec, Data) ->
> +     control_bin(?BF_CFB64_DECRYPT, Key, list_to_binary([IVec, Data])).
> + 
> + %%
>   %% AES in cipher feedback mode (CFB)
>   %%
>   aes_cfb_128_encrypt(Key, IVec, Data) ->

> 
> ________________________________________________________________
> erlang-patches mailing list. See http://www.erlang.org/faq.html
> erlang-patches (at) erlang.org

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


More information about the erlang-patches mailing list