Extracting encrypted rar files is noticeably slower than unencrypted
ones. Rar uses the standard AES-128-CBC algorithm for encryption,
so I had the idea of using OpenSSL's optimized implementation instead
of the generic one included with unrar.
Running "unrar t" on a 1.5 GB test archive, I see a substantial
speedup on my amd64:
included AES: 1m43.74s real 1m28.22s user 0m2.35s system
OpenSSL AES: 0m35.30s real 0m19.54s user 0m2.00s system
Do we want his? If so, it could stand additional testing.
Index: Makefile
===================================================================
RCS file: /cvs/ports/archivers/unrar/Makefile,v
retrieving revision 1.53
diff -u -p -r1.53 Makefile
--- Makefile 8 Sep 2011 11:13:30 -0000 1.53
+++ Makefile 5 Apr 2012 23:50:18 -0000
@@ -11,6 +11,7 @@ COMMENT= extract, list, and test RAR arc
PKGNAME= unrar-4.00
EPOCH= 1
+REVISION= 0
DISTNAME= unrarsrc-4.0.7
CATEGORIES= archivers
@@ -24,7 +25,7 @@ PERMIT_PACKAGE_FTP= Yes
PERMIT_DISTFILES_CDROM= Yes
PERMIT_DISTFILES_FTP= Yes
-WANTLIB= c m stdc++
+WANTLIB= c crypto m stdc++
MASTER_SITES= ${HOMEPAGE}rar/
Index: patches/patch-makefile_unix
===================================================================
RCS file: /cvs/ports/archivers/unrar/patches/patch-makefile_unix,v
retrieving revision 1.13
diff -u -p -r1.13 patch-makefile_unix
--- patches/patch-makefile_unix 18 Mar 2011 20:14:58 -0000 1.13
+++ patches/patch-makefile_unix 5 Apr 2012 23:50:18 -0000
@@ -1,12 +1,24 @@
$OpenBSD: patch-makefile_unix,v 1.13 2011/03/18 20:14:58 naddy Exp $
---- makefile.unix.orig Wed Mar 9 17:40:47 2011
-+++ makefile.unix Wed Mar 9 17:41:01 2011
-@@ -107,6 +107,8 @@ OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o sma
+--- makefile.unix.orig Tue Mar 30 17:26:26 2010
++++ makefile.unix Fri Apr 6 00:30:46 2012
+@@ -8,9 +8,10 @@
+ # Linux using GCC
+ #CXX=g++
+ #CXXFLAGS=-O2
+-DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
++DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DOPENSSL
+ STRIP=strip
+ DESTDIR=/usr
++LIBS=-lcrypto
+
+ # Linux using LCC
+ #CXX=lcc
+@@ -106,6 +107,8 @@ OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o sma
+ archive.o arcread.o unicode.o system.o isnt.o crypt.o crc.o rawread.o
encname.o \
resource.o match.o timefn.o rdwrfn.o consio.o options.o ulinks.o
errhnd.o rarvm.o \
rijndael.o getbits.o sha1.o extinfo.o extract.o volume.o list.o find.o
unpack.o cmddata.o
-
-+.SUFFIXES: .cpp
+
++.SUFFIXES: .cpp
+
.cpp.o:
$(COMPILE) -D$(WHAT) -c $<
-
Index: patches/patch-os_hpp
===================================================================
RCS file: /cvs/ports/archivers/unrar/patches/patch-os_hpp,v
retrieving revision 1.6
diff -u -p -r1.6 patch-os_hpp
--- patches/patch-os_hpp 30 Dec 2010 07:51:31 -0000 1.6
+++ patches/patch-os_hpp 5 Apr 2012 23:50:18 -0000
@@ -1,7 +1,18 @@
$OpenBSD: patch-os_hpp,v 1.6 2010/12/30 07:51:31 benoit Exp $
---- os.hpp.orig Fri Nov 26 08:20:01 2010
-+++ os.hpp Mon Dec 6 07:49:22 2010
-@@ -262,12 +262,12 @@
+--- os.hpp.orig Wed Mar 2 08:43:12 2011
++++ os.hpp Fri Apr 6 00:30:19 2012
+@@ -192,6 +192,10 @@
+ #include <utime.h>
+ #include <locale.h>
+
++#ifdef OPENSSL
++#include <openssl/evp.h>
++#endif
++
+ #ifdef S_IFLNK
+ #define SAVE_LINKS
+ #endif
+@@ -262,12 +266,12 @@
#endif
#endif
Index: patches/patch-rijndael_cpp
===================================================================
RCS file: patches/patch-rijndael_cpp
diff -N patches/patch-rijndael_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-rijndael_cpp 5 Apr 2012 23:50:18 -0000
@@ -0,0 +1,80 @@
+$OpenBSD$
+--- rijndael.cpp.orig Wed Mar 2 08:43:12 2011
++++ rijndael.cpp Fri Apr 6 00:32:04 2012
+@@ -7,6 +7,8 @@
+ **************************************************************************/
+ #include "rar.hpp"
+
++#ifndef OPENSSL
++
+ const int uKeyLenInBytes=16, m_uRounds=10;
+
+ static byte S[256],S5[256],rcon[30];
+@@ -54,6 +56,7 @@ inline void Copy128(byte *dest,const byte *src)
+ #endif
+ }
+
++#endif // OPENSSL
+
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // API
+@@ -61,13 +64,21 @@ inline void Copy128(byte *dest,const byte *src)
+
+ Rijndael::Rijndael()
+ {
++#ifndef OPENSSL
+ if (S[0]==0)
+ GenerateTables();
++#endif
+ }
+
+
+ void Rijndael::init(Direction dir,const byte * key,byte * initVector)
+ {
++#ifdef OPENSSL
++ EVP_CIPHER_CTX_init(&ctx);
++ EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, initVector,
++ dir == Decrypt ? 0 : 1);
++ EVP_CIPHER_CTX_set_padding(&ctx, 0);
++#else
+ m_direction = dir;
+
+ byte keyMatrix[_MAX_KEY_COLUMNS][4];
+@@ -82,6 +93,7 @@ void Rijndael::init(Direction dir,const byte * key,byt
+
+ if(m_direction == Decrypt)
+ keyEncToDec();
++#endif // OPENSSL
+ }
+
+
+@@ -91,6 +103,11 @@ size_t Rijndael::blockDecrypt(const byte *input, size_
+ if (input == 0 || inputLen <= 0)
+ return 0;
+
++#ifdef OPENSSL
++ int outLen;
++ EVP_CipherUpdate(&ctx, outBuffer, &outLen, input, inputLen);
++ return outLen;
++#else
+ byte block[16], iv[4][4];
+ memcpy(iv,m_initVector,16);
+
+@@ -113,9 +130,11 @@ size_t Rijndael::blockDecrypt(const byte *input, size_
+ memcpy(m_initVector,iv,16);
+
+ return 16*numBlocks;
++#endif // OPENSSL
+ }
+
+
++#ifndef OPENSSL
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ALGORITHM
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+@@ -296,3 +315,5 @@ void Rijndael::GenerateTables()
+
U1[b][0]=U2[b][1]=U3[b][2]=U4[b][3]=T5[i][0]=T6[i][1]=T7[i][2]=T8[i][3]=FFmul0e(b);
+ }
+ }
++
++#endif // OPENSSL
Index: patches/patch-rijndael_hpp
===================================================================
RCS file: patches/patch-rijndael_hpp
diff -N patches/patch-rijndael_hpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-rijndael_hpp 5 Apr 2012 23:50:18 -0000
@@ -0,0 +1,25 @@
+$OpenBSD$
+--- rijndael.hpp.orig Wed Mar 2 08:43:13 2011
++++ rijndael.hpp Fri Apr 6 00:32:04 2012
+@@ -18,15 +18,21 @@ class Rijndael
+ public:
+ enum Direction { Encrypt , Decrypt };
+ private:
++#ifndef OPENSSL
+ void keySched(byte key[_MAX_KEY_COLUMNS][4]);
+ void keyEncToDec();
+ void encrypt(const byte a[16], byte b[16]);
+ void decrypt(const byte a[16], byte b[16]);
+ void GenerateTables();
++#endif
+
++#ifdef OPENSSL
++ EVP_CIPHER_CTX ctx;
++#else
+ Direction m_direction;
+ byte m_initVector[MAX_IV_SIZE];
+ byte m_expandedKey[_MAX_ROUNDS+1][4][4];
++#endif
+ public:
+ Rijndael();
+ void init(Direction dir,const byte *key,byte *initVector);
--
Christian "naddy" Weisgerber [email protected]