aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Oliver <[email protected]>2009-12-02 21:53:04 +0000
committerBjörn Gustavsson <[email protected]>2009-12-11 11:21:27 +0100
commit8ca11d98e601dda66cdfb12d526b20fa3beece8e (patch)
tree75895ea37c6f129a7c3f39eb759a6cc6de7cd9df /lib
parent7457122ad3aa8dccb5439d3e430c93fe6ca2654e (diff)
downloadotp-8ca11d98e601dda66cdfb12d526b20fa3beece8e.tar.gz
otp-8ca11d98e601dda66cdfb12d526b20fa3beece8e.tar.bz2
otp-8ca11d98e601dda66cdfb12d526b20fa3beece8e.zip
Add Blowfish ECB, CBC and OFB modes
My previous patch added CFB mode. This patch adds all remaining Blowfish modes. According to the man page http://www.fifi.org/cgi-bin/man2html/usr/share/man/man3/blowfish.3ssl.gz these are available in all versions of OpenSSL. [ Squashed in elimination of signed/unsigned compiler warnings. /bg ]
Diffstat (limited to 'lib')
-rw-r--r--lib/crypto/c_src/crypto_drv.c78
-rw-r--r--lib/crypto/doc/src/crypto.xml64
-rw-r--r--lib/crypto/src/crypto.erl25
3 files changed, 166 insertions, 1 deletions
diff --git a/lib/crypto/c_src/crypto_drv.c b/lib/crypto/c_src/crypto_drv.c
index 241c4ec733..5b6d750dde 100644
--- a/lib/crypto/c_src/crypto_drv.c
+++ b/lib/crypto/c_src/crypto_drv.c
@@ -233,6 +233,11 @@ static ErlDrvEntry crypto_driver_entry = {
#define DRV_BF_CFB64_ENCRYPT 59
#define DRV_BF_CFB64_DECRYPT 60
+#define DRV_BF_ECB_ENCRYPT 61
+#define DRV_BF_ECB_DECRYPT 62
+#define DRV_BF_OFB64_ENCRYPT 63
+#define DRV_BF_CBC_ENCRYPT 64
+#define DRV_BF_CBC_DECRYPT 65
/* #define DRV_CBC_IDEA_ENCRYPT 34 */
/* #define DRV_CBC_IDEA_DECRYPT 35 */
@@ -533,6 +538,79 @@ static int crypto_control(ErlDrvData drv_data, unsigned int command, char *buf,
(command == DRV_CBC_DES_ENCRYPT));
return dlen;
+ case DRV_BF_ECB_ENCRYPT:
+ case DRV_BF_ECB_DECRYPT:
+ {
+ /* buf = klen[4] key data */
+ int bf_direction;
+ const unsigned char *ukey;
+ const unsigned char *bf_dbuf; /* blowfish input data */
+ BF_KEY bf_key; /* blowfish key 8 */
+
+ klen = get_int32(buf);
+ ukey = (unsigned char *) buf + 4;
+ bf_dbuf = ukey + klen;
+ dlen = len - 4 - klen;
+ if (dlen < 0) return -1;
+ BF_set_key(&bf_key, klen, ukey);
+ bin = return_binary(rbuf,rlen,dlen);
+ if (bin==NULL) return -1;
+ bf_direction = command == DRV_BF_ECB_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT;
+ BF_ecb_encrypt(bf_dbuf, bin, &bf_key, bf_direction);
+ return dlen;
+ }
+
+ case DRV_BF_CBC_ENCRYPT:
+ case DRV_BF_CBC_DECRYPT:
+ {
+ /* buf = klen[4] key ivec[8] data */
+ unsigned char *ukey;
+ unsigned char* ivec;
+ unsigned char bf_tkey[8]; /* blowfish ivec */
+ int bf_direction;
+ const unsigned char *bf_dbuf; /* blowfish input data */
+ BF_KEY bf_key; /* blowfish key 8 */
+
+ klen = get_int32(buf);
+ ukey = (unsigned char *)buf + 4;
+ ivec = ukey + klen;
+ bf_dbuf = ivec + 8;
+ dlen = len - 4 - klen - 8;
+ if (dlen < 0) return -1;
+ BF_set_key(&bf_key, klen, ukey);
+ memcpy(bf_tkey, ivec, 8);
+ bin = return_binary(rbuf,rlen,dlen);
+ if (bin==NULL) return -1;
+ bf_direction = command == DRV_BF_CBC_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT;
+ BF_cbc_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, bf_direction);
+ return dlen;
+ }
+
+ case DRV_BF_OFB64_ENCRYPT:
+ {
+ /* buf = klen[4] key ivec[8] data */
+ unsigned char *ukey;
+ unsigned char* ivec;
+ unsigned char bf_tkey[8]; /* blowfish ivec */
+ int bf_n; /* blowfish ivec pos */
+ const unsigned char *bf_dbuf; /* blowfish input data */
+ BF_KEY bf_key; /* blowfish key 8 */
+
+ klen = get_int32(buf);
+ ukey = (unsigned char *)buf + 4;
+ ivec = ukey + klen;
+ bf_dbuf = ivec + 8;
+ dlen = len - 4 - klen - 8;
+ if (dlen < 0) return -1;
+ BF_set_key(&bf_key, klen, ukey);
+ memcpy(bf_tkey, ivec, 8);
+ bin = return_binary(rbuf,rlen,dlen);
+ if (bin==NULL) return -1;
+ bf_n = 0;
+ BF_ofb64_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, &bf_n);
+ return dlen;
+ }
+
case DRV_BF_CFB64_ENCRYPT:
case DRV_BF_CFB64_DECRYPT:
{
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 42ba523c8c..cfc6996332 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -337,6 +337,53 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<c>Key3</c>, and <c>IVec</c> must be 64 bits (8 bytes).</p>
</desc>
</func>
+
+ <func>
+ <name>blowfish_ecb_encrypt(Key, Text) -> Cipher</name>
+ <fsummary>Encrypt the first 64 bits of <c>Text</c> using Blowfish in ECB mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts the first 64 bits of <c>Text</c> using Blowfish in ECB mode. <c>Key</c> is the Blowfish key. The length of <c>Text</c> must be at least 64 bits (8 bytes).</p>
+ </desc>
+ <name>blowfish_ecb_decrypt(Key, Text) -> Cipher</name>
+ <fsummary>Decrypt the first 64 bits of <c>Text</c> using Blowfish in ECB mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Decrypts the first 64 bits of <c>Text</c> using Blowfish in ECB mode. <c>Key</c> is the Blowfish key. The length of <c>Text</c> must be at least 64 bits (8 bytes).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>blowfish_cbc_encrypt(Key, Text) -> Cipher</name>
+ <fsummary>Encrypt <c>Text</c> using Blowfish in CBC mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts <c>Text</c> using Blowfish in CBC mode. <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). The length of <c>Text</c> must be a multiple of 64 bits (8 bytes).</p>
+ </desc>
+ <name>blowfish_cbc_decrypt(Key, Text) -> Cipher</name>
+ <fsummary>Decrypt <c>Text</c> using Blowfish in CBC mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Decrypts <c>Text</c> using Blowfish in CBC mode. <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). The length of <c>Text</c> must be a multiple 64 bits (8 bytes).</p>
+ </desc>
+ </func>
+
<func>
<name>blowfish_cfb64_encrypt(Key, IVec, Text) -> Cipher</name>
<fsummary>Encrypt <c>Text</c>using Blowfish in CFB mode with 64
@@ -367,6 +414,23 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
must be 64 bits (8 bytes).</p>
</desc>
</func>
+
+ <func>
+ <name>blowfish_ofb64_encrypt(Key, IVec, Text) -> Cipher</name>
+ <fsummary>Encrypt <c>Text</c>using Blowfish in OFB 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 OFB 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>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 5189677dd0..fa33bad2e0 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -30,7 +30,10 @@
-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([blowfish_ecb_encrypt/2, blowfish_ecb_decrypt/2]).
+-export([blowfish_cbc_encrypt/3, blowfish_cbc_decrypt/3]).
+-export([blowfish_cfb64_encrypt/3, blowfish_cfb64_decrypt/3]).
+-export([blowfish_ofb64_encrypt/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]).
@@ -115,6 +118,11 @@
-define(BF_CFB64_ENCRYPT, 59).
-define(BF_CFB64_DECRYPT, 60).
+-define(BF_ECB_ENCRYPT, 61).
+-define(BF_ECB_DECRYPT, 62).
+-define(BF_OFB64_ENCRYPT, 63).
+-define(BF_CBC_ENCRYPT, 64).
+-define(BF_CBC_DECRYPT, 65).
%% -define(IDEA_CBC_ENCRYPT, 34).
%% -define(IDEA_CBC_DECRYPT, 35).
@@ -303,12 +311,27 @@ des_ede3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) ->
%%
%% Blowfish
%%
+blowfish_ecb_encrypt(Key, Data) when byte_size(Data) >= 8 ->
+ control_bin(?BF_ECB_ENCRYPT, Key, list_to_binary([Data])).
+
+blowfish_ecb_decrypt(Key, Data) when byte_size(Data) >= 8 ->
+ control_bin(?BF_ECB_DECRYPT, Key, list_to_binary([Data])).
+
+blowfish_cbc_encrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 ->
+ control_bin(?BF_CBC_ENCRYPT, Key, list_to_binary([IVec, Data])).
+
+blowfish_cbc_decrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 ->
+ control_bin(?BF_CBC_DECRYPT, Key, list_to_binary([IVec, Data])).
+
blowfish_cfb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 ->
control_bin(?BF_CFB64_ENCRYPT, Key, list_to_binary([IVec, Data])).
blowfish_cfb64_decrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 ->
control_bin(?BF_CFB64_DECRYPT, Key, list_to_binary([IVec, Data])).
+blowfish_ofb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 ->
+ control_bin(?BF_OFB64_ENCRYPT, Key, list_to_binary([IVec, Data])).
+
%%
%% AES in cipher feedback mode (CFB)
%%