Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2013 Nicolas George
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public License
  8.  * as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public License
  17.  * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  18.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. /* Optional external libraries; can be enabled using:
  22.  * make VERSUS=crypto+gcrypt+tomcrypt tools/crypto_bench */
  23. #define USE_crypto           0x01    /* OpenSSL's libcrypto */
  24. #define USE_gcrypt           0x02    /* GnuTLS's libgcrypt */
  25. #define USE_tomcrypt         0x04    /* LibTomCrypt */
  26.  
  27. #include <stdlib.h>
  28. #include <math.h>
  29.  
  30. #include "libavutil/avutil.h"
  31. #include "libavutil/avstring.h"
  32. #include "libavutil/crc.h"
  33. #include "libavutil/intreadwrite.h"
  34. #include "libavutil/timer.h"
  35.  
  36. #ifndef AV_READ_TIME
  37. #define AV_READ_TIME(x) 0
  38. #endif
  39.  
  40. #if HAVE_UNISTD_H
  41. #include <unistd.h> /* for getopt */
  42. #endif
  43. #if !HAVE_GETOPT
  44. #include "compat/getopt.c"
  45. #endif
  46.  
  47. #define MAX_INPUT_SIZE 1048576
  48. #define MAX_OUTPUT_SIZE 128
  49.  
  50. static const char *enabled_libs;
  51. static const char *enabled_algos;
  52. static unsigned specified_runs;
  53.  
  54. static const uint8_t *hardcoded_key = "FFmpeg is the best program ever.";
  55.  
  56. static void fatal_error(const char *tag)
  57. {
  58.     av_log(NULL, AV_LOG_ERROR, "Fatal error: %s\n", tag);
  59.     exit(1);
  60. }
  61.  
  62. struct hash_impl {
  63.     const char *lib;
  64.     const char *name;
  65.     void (*run)(uint8_t *output, const uint8_t *input, unsigned size);
  66.     const char *output;
  67. };
  68.  
  69. /***************************************************************************
  70.  * lavu: libavutil
  71.  ***************************************************************************/
  72.  
  73. #include "libavutil/md5.h"
  74. #include "libavutil/sha.h"
  75. #include "libavutil/sha512.h"
  76. #include "libavutil/ripemd.h"
  77. #include "libavutil/aes.h"
  78. #include "libavutil/blowfish.h"
  79. #include "libavutil/camellia.h"
  80. #include "libavutil/cast5.h"
  81. #include "libavutil/twofish.h"
  82. #include "libavutil/rc4.h"
  83. #include "libavutil/xtea.h"
  84.  
  85. #define IMPL_USE_lavu IMPL_USE
  86.  
  87. static void run_lavu_md5(uint8_t *output,
  88.                          const uint8_t *input, unsigned size)
  89. {
  90.     av_md5_sum(output, input, size);
  91. }
  92.  
  93. #define DEFINE_LAVU_MD(suffix, type, namespace, hsize)                       \
  94. static void run_lavu_ ## suffix(uint8_t *output,                             \
  95.                                 const uint8_t *input, unsigned size)         \
  96. {                                                                            \
  97.     static struct type *h;                                                   \
  98.     if (!h && !(h = av_ ## namespace ## _alloc()))                           \
  99.         fatal_error("out of memory");                                        \
  100.     av_ ## namespace ## _init(h, hsize);                                     \
  101.     av_ ## namespace ## _update(h, input, size);                             \
  102.     av_ ## namespace ## _final(h, output);                                   \
  103. }
  104.  
  105. DEFINE_LAVU_MD(sha1,      AVSHA,    sha, 160);
  106. DEFINE_LAVU_MD(sha256,    AVSHA,    sha, 256);
  107. DEFINE_LAVU_MD(sha512,    AVSHA512, sha512, 512);
  108. DEFINE_LAVU_MD(ripemd128, AVRIPEMD, ripemd, 128);
  109. DEFINE_LAVU_MD(ripemd160, AVRIPEMD, ripemd, 160);
  110.  
  111. static void run_lavu_aes128(uint8_t *output,
  112.                             const uint8_t *input, unsigned size)
  113. {
  114.     static struct AVAES *aes;
  115.     if (!aes && !(aes = av_aes_alloc()))
  116.         fatal_error("out of memory");
  117.     av_aes_init(aes, hardcoded_key, 128, 0);
  118.     av_aes_crypt(aes, output, input, size >> 4, NULL, 0);
  119. }
  120.  
  121. static void run_lavu_blowfish(uint8_t *output,
  122.                               const uint8_t *input, unsigned size)
  123. {
  124.     static struct AVBlowfish *blowfish;
  125.     if (!blowfish && !(blowfish = av_blowfish_alloc()))
  126.         fatal_error("out of memory");
  127.     av_blowfish_init(blowfish, hardcoded_key, 16);
  128.     av_blowfish_crypt(blowfish, output, input, size >> 3, NULL, 0);
  129. }
  130.  
  131. static void run_lavu_camellia(uint8_t *output,
  132.                               const uint8_t *input, unsigned size)
  133. {
  134.     static struct AVCAMELLIA *camellia;
  135.     if (!camellia && !(camellia = av_camellia_alloc()))
  136.         fatal_error("out of memory");
  137.     av_camellia_init(camellia, hardcoded_key, 128);
  138.     av_camellia_crypt(camellia, output, input, size >> 4, NULL, 0);
  139. }
  140.  
  141. static void run_lavu_cast128(uint8_t *output,
  142.                              const uint8_t *input, unsigned size)
  143. {
  144.     static struct AVCAST5 *cast;
  145.     if (!cast && !(cast = av_cast5_alloc()))
  146.         fatal_error("out of memory");
  147.     av_cast5_init(cast, hardcoded_key, 128);
  148.     av_cast5_crypt(cast, output, input, size >> 3, 0);
  149. }
  150.  
  151. static void run_lavu_twofish(uint8_t *output,
  152.                               const uint8_t *input, unsigned size)
  153. {
  154.     static struct AVTWOFISH *twofish;
  155.     if (!twofish && !(twofish = av_twofish_alloc()))
  156.         fatal_error("out of memory");
  157.     av_twofish_init(twofish, hardcoded_key, 128);
  158.     av_twofish_crypt(twofish, output, input, size >> 4, NULL, 0);
  159. }
  160.  
  161. static void run_lavu_rc4(uint8_t *output,
  162.                               const uint8_t *input, unsigned size)
  163. {
  164.     static struct AVRC4 *rc4;
  165.     if (!rc4 && !(rc4 = av_rc4_alloc()))
  166.         fatal_error("out of memory");
  167.     av_rc4_init(rc4, hardcoded_key, 128, 0);
  168.     av_rc4_crypt(rc4, output, input, size, NULL, 0);
  169. }
  170.  
  171. static void run_lavu_xtea(uint8_t *output,
  172.                               const uint8_t *input, unsigned size)
  173. {
  174.     static struct AVXTEA *xtea;
  175.     if (!xtea && !(xtea = av_xtea_alloc()))
  176.         fatal_error("out of memory");
  177.     av_xtea_init(xtea, hardcoded_key);
  178.     av_xtea_crypt(xtea, output, input, size >> 3, NULL, 0);
  179. }
  180.  
  181. /***************************************************************************
  182.  * crypto: OpenSSL's libcrypto
  183.  ***************************************************************************/
  184.  
  185. #if (USE_EXT_LIBS) & USE_crypto
  186.  
  187. #include <openssl/md5.h>
  188. #include <openssl/sha.h>
  189. #include <openssl/ripemd.h>
  190. #include <openssl/aes.h>
  191. #include <openssl/blowfish.h>
  192. #include <openssl/camellia.h>
  193. #include <openssl/cast.h>
  194. #include <openssl/rc4.h>
  195.  
  196. #define DEFINE_CRYPTO_WRAPPER(suffix, function)                              \
  197. static void run_crypto_ ## suffix(uint8_t *output,                           \
  198.                                   const uint8_t *input, unsigned size)       \
  199. {                                                                            \
  200.     function(input, size, output);                                           \
  201. }
  202.  
  203. DEFINE_CRYPTO_WRAPPER(md5,       MD5)
  204. DEFINE_CRYPTO_WRAPPER(sha1,      SHA1)
  205. DEFINE_CRYPTO_WRAPPER(sha256,    SHA256)
  206. DEFINE_CRYPTO_WRAPPER(sha512,    SHA512)
  207. DEFINE_CRYPTO_WRAPPER(ripemd160, RIPEMD160)
  208.  
  209. static void run_crypto_aes128(uint8_t *output,
  210.                               const uint8_t *input, unsigned size)
  211. {
  212.     AES_KEY aes;
  213.     unsigned i;
  214.  
  215.     AES_set_encrypt_key(hardcoded_key, 128, &aes);
  216.     size -= 15;
  217.     for (i = 0; i < size; i += 16)
  218.         AES_encrypt(input + i, output + i, &aes);
  219. }
  220.  
  221. static void run_crypto_blowfish(uint8_t *output,
  222.                                 const uint8_t *input, unsigned size)
  223. {
  224.     BF_KEY blowfish;
  225.     unsigned i;
  226.  
  227.     BF_set_key(&blowfish, 16, hardcoded_key);
  228.     for (i = 0; i < size; i += 8)
  229.         BF_ecb_encrypt(input + i, output + i, &blowfish, 1);
  230. }
  231.  
  232. static void run_crypto_camellia(uint8_t *output,
  233.                                 const uint8_t *input, unsigned size)
  234. {
  235.     CAMELLIA_KEY camellia;
  236.     unsigned i;
  237.  
  238.     Camellia_set_key(hardcoded_key, 128, &camellia);
  239.     size -= 15;
  240.     for (i = 0; i < size; i += 16)
  241.         Camellia_ecb_encrypt(input + i, output + i, &camellia, 1);
  242. }
  243.  
  244. static void run_crypto_cast128(uint8_t *output,
  245.                                const uint8_t *input, unsigned size)
  246. {
  247.     CAST_KEY cast;
  248.     unsigned i;
  249.  
  250.     CAST_set_key(&cast, 16, hardcoded_key);
  251.     for (i = 0; i < size; i += 8)
  252.         CAST_ecb_encrypt(input + i, output + i, &cast, 1);
  253. }
  254.  
  255. static void run_crypto_rc4(uint8_t *output,
  256.                                 const uint8_t *input, unsigned size)
  257. {
  258.     RC4_KEY rc4;
  259.  
  260.     RC4_set_key(&rc4, 16, hardcoded_key);
  261.     RC4(&rc4, size, input, output);
  262. }
  263.  
  264. #define IMPL_USE_crypto(...) IMPL_USE(__VA_ARGS__)
  265. #else
  266. #define IMPL_USE_crypto(...) /* ignore */
  267. #endif
  268.  
  269. /***************************************************************************
  270.  * gcrypt: GnuTLS's libgcrypt
  271.  ***************************************************************************/
  272.  
  273. #if (USE_EXT_LIBS) & USE_gcrypt
  274.  
  275. #include <gcrypt.h>
  276.  
  277. #define DEFINE_GCRYPT_WRAPPER(suffix, algo)                                  \
  278. static void run_gcrypt_ ## suffix(uint8_t *output,                           \
  279.                                   const uint8_t *input, unsigned size)       \
  280. {                                                                            \
  281.     gcry_md_hash_buffer(GCRY_MD_ ## algo, output, input, size);              \
  282. }
  283.  
  284. DEFINE_GCRYPT_WRAPPER(md5,       MD5)
  285. DEFINE_GCRYPT_WRAPPER(sha1,      SHA1)
  286. DEFINE_GCRYPT_WRAPPER(sha256,    SHA256)
  287. DEFINE_GCRYPT_WRAPPER(sha512,    SHA512)
  288. DEFINE_GCRYPT_WRAPPER(ripemd160, RMD160)
  289.  
  290. static void run_gcrypt_aes128(uint8_t *output,
  291.                               const uint8_t *input, unsigned size)
  292. {
  293.     static gcry_cipher_hd_t aes;
  294.     if (!aes)
  295.         gcry_cipher_open(&aes, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0);
  296.     gcry_cipher_setkey(aes, hardcoded_key, 16);
  297.     gcry_cipher_encrypt(aes, output, size, input, size);
  298. }
  299.  
  300. static void run_gcrypt_blowfish(uint8_t *output,
  301.                                 const uint8_t *input, unsigned size)
  302. {
  303.     static gcry_cipher_hd_t blowfish;
  304.     if (!blowfish)
  305.         gcry_cipher_open(&blowfish, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0);
  306.     gcry_cipher_setkey(blowfish, hardcoded_key, 16);
  307.     gcry_cipher_encrypt(blowfish, output, size, input, size);
  308. }
  309.  
  310. static void run_gcrypt_camellia(uint8_t *output,
  311.                                 const uint8_t *input, unsigned size)
  312. {
  313.     static gcry_cipher_hd_t camellia;
  314.     if (!camellia)
  315.         gcry_cipher_open(&camellia, GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_ECB, 0);
  316.     gcry_cipher_setkey(camellia, hardcoded_key, 16);
  317.     gcry_cipher_encrypt(camellia, output, size, input, size);
  318. }
  319.  
  320. static void run_gcrypt_cast128(uint8_t *output,
  321.                               const uint8_t *input, unsigned size)
  322. {
  323.     static gcry_cipher_hd_t cast;
  324.     if (!cast)
  325.         gcry_cipher_open(&cast, GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB, 0);
  326.     gcry_cipher_setkey(cast, hardcoded_key, 16);
  327.     gcry_cipher_encrypt(cast, output, size, input, size);
  328. }
  329.  
  330. static void run_gcrypt_twofish(uint8_t *output,
  331.                                 const uint8_t *input, unsigned size)
  332. {
  333.     static gcry_cipher_hd_t twofish;
  334.     if (!twofish)
  335.         gcry_cipher_open(&twofish, GCRY_CIPHER_TWOFISH128, GCRY_CIPHER_MODE_ECB, 0);
  336.     gcry_cipher_setkey(twofish, hardcoded_key, 16);
  337.     gcry_cipher_encrypt(twofish, output, size, input, size);
  338. }
  339.  
  340. #define IMPL_USE_gcrypt(...) IMPL_USE(__VA_ARGS__)
  341. #else
  342. #define IMPL_USE_gcrypt(...) /* ignore */
  343. #endif
  344.  
  345. /***************************************************************************
  346.  * tomcrypt: LibTomCrypt
  347.  ***************************************************************************/
  348.  
  349. #if (USE_EXT_LIBS) & USE_tomcrypt
  350.  
  351. #include <tomcrypt.h>
  352.  
  353. #define DEFINE_TOMCRYPT_WRAPPER(suffix, namespace, algo)                     \
  354. static void run_tomcrypt_ ## suffix(uint8_t *output,                         \
  355.                                     const uint8_t *input, unsigned size)     \
  356. {                                                                            \
  357.     hash_state md;                                                           \
  358.     namespace ## _init(&md);                                                 \
  359.     namespace ## _process(&md, input, size);                                 \
  360.     namespace ## _done(&md, output);                                         \
  361. }
  362.  
  363. DEFINE_TOMCRYPT_WRAPPER(md5,       md5,    MD5)
  364. DEFINE_TOMCRYPT_WRAPPER(sha1,      sha1,   SHA1)
  365. DEFINE_TOMCRYPT_WRAPPER(sha256,    sha256, SHA256)
  366. DEFINE_TOMCRYPT_WRAPPER(sha512,    sha512, SHA512)
  367. DEFINE_TOMCRYPT_WRAPPER(ripemd128, rmd128, RIPEMD128)
  368. DEFINE_TOMCRYPT_WRAPPER(ripemd160, rmd160, RIPEMD160)
  369.  
  370. static void run_tomcrypt_aes128(uint8_t *output,
  371.                                 const uint8_t *input, unsigned size)
  372. {
  373.     symmetric_key aes;
  374.     unsigned i;
  375.  
  376.     aes_setup(hardcoded_key, 16, 0, &aes);
  377.     size -= 15;
  378.     for (i = 0; i < size; i += 16)
  379.         aes_ecb_encrypt(input + i, output + i, &aes);
  380. }
  381.  
  382. static void run_tomcrypt_blowfish(uint8_t *output,
  383.                                   const uint8_t *input, unsigned size)
  384. {
  385.     symmetric_key blowfish;
  386.     unsigned i;
  387.  
  388.     blowfish_setup(hardcoded_key, 16, 0, &blowfish);
  389.     for (i = 0; i < size; i += 8)
  390.         blowfish_ecb_encrypt(input + i, output + i, &blowfish);
  391. }
  392.  
  393. static void run_tomcrypt_camellia(uint8_t *output,
  394.                                   const uint8_t *input, unsigned size)
  395. {
  396.     symmetric_key camellia;
  397.     unsigned i;
  398.  
  399.     camellia_setup(hardcoded_key, 16, 0, &camellia);
  400.     size -= 15;
  401.     for (i = 0; i < size; i += 16)
  402.         camellia_ecb_encrypt(input + i, output + i, &camellia);
  403. }
  404.  
  405. static void run_tomcrypt_cast128(uint8_t *output,
  406.                                 const uint8_t *input, unsigned size)
  407. {
  408.     symmetric_key cast;
  409.     unsigned i;
  410.  
  411.     cast5_setup(hardcoded_key, 16, 0, &cast);
  412.     for (i = 0; i < size; i += 8)
  413.         cast5_ecb_encrypt(input + i, output + i, &cast);
  414. }
  415.  
  416. static void run_tomcrypt_twofish(uint8_t *output,
  417.                                 const uint8_t *input, unsigned size)
  418. {
  419.     symmetric_key twofish;
  420.     unsigned i;
  421.  
  422.     twofish_setup(hardcoded_key, 16, 0, &twofish);
  423.     size -= 15;
  424.     for (i = 0; i < size; i += 16)
  425.         twofish_ecb_encrypt(input + i, output + i, &twofish);
  426. }
  427.  
  428. static void run_tomcrypt_xtea(uint8_t *output,
  429.                               const uint8_t *input, unsigned size)
  430. {
  431.     symmetric_key xtea;
  432.     unsigned i;
  433.  
  434.     xtea_setup(hardcoded_key, 16, 0, &xtea);
  435.     for (i = 0; i < size; i += 8)
  436.         xtea_ecb_encrypt(input + i, output + i, &xtea);
  437. }
  438.  
  439.  
  440. #define IMPL_USE_tomcrypt(...) IMPL_USE(__VA_ARGS__)
  441. #else
  442. #define IMPL_USE_tomcrypt(...) /* ignore */
  443. #endif
  444.  
  445. /***************************************************************************
  446.  * Driver code
  447.  ***************************************************************************/
  448.  
  449. static unsigned crc32(const uint8_t *data, unsigned size)
  450. {
  451.     return av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, data, size);
  452. }
  453.  
  454. static void run_implementation(const uint8_t *input, uint8_t *output,
  455.                                struct hash_impl *impl, unsigned size)
  456. {
  457.     uint64_t t0, t1;
  458.     unsigned nruns = specified_runs ? specified_runs : (1 << 30) / size;
  459.     unsigned outlen = 0, outcrc = 0;
  460.     unsigned i, j, val;
  461.     double mtime, ttime = 0, ttime2 = 0, stime;
  462.     uint8_t outref[MAX_OUTPUT_SIZE];
  463.  
  464.     if (enabled_libs  && !av_stristr(enabled_libs,  impl->lib) ||
  465.         enabled_algos && !av_stristr(enabled_algos, impl->name))
  466.         return;
  467.     if (!sscanf(impl->output, "crc:%x", &outcrc)) {
  468.         outlen = strlen(impl->output) / 2;
  469.         for (i = 0; i < outlen; i++) {
  470.             sscanf(impl->output + i * 2, "%02x", &val);
  471.             outref[i] = val;
  472.         }
  473.     }
  474.     for (i = 0; i < 8; i++) /* heat caches */
  475.         impl->run(output, input, size);
  476.     for (i = 0; i < nruns; i++) {
  477.         memset(output, 0, size); /* avoid leftovers from previous runs */
  478.         t0 = AV_READ_TIME();
  479.         impl->run(output, input, size);
  480.         t1 = AV_READ_TIME();
  481.         if (outlen ? memcmp(output, outref, outlen) :
  482.                      crc32(output, size) != outcrc) {
  483.             fprintf(stderr, "Expected: ");
  484.             if (outlen)
  485.                 for (j = 0; j < outlen; j++)
  486.                     fprintf(stderr, "%02x", output[j]);
  487.             else
  488.                 fprintf(stderr, "%08x", crc32(output, size));
  489.             fprintf(stderr, "\n");
  490.             fatal_error("output mismatch");
  491.         }
  492.         mtime = (double)(t1 - t0) / size;
  493.         ttime  += mtime;
  494.         ttime2 += mtime * mtime;
  495.     }
  496.  
  497.     ttime  /= nruns;
  498.     ttime2 /= nruns;
  499.     stime = sqrt(ttime2 - ttime * ttime);
  500.     printf("%-10s %-12s size: %7d  runs: %6d  time: %8.3f +- %.3f\n",
  501.            impl->lib, impl->name, size, nruns, ttime, stime);
  502.     fflush(stdout);
  503. }
  504.  
  505. #define IMPL_USE(lib, name, symbol, output) \
  506.     { #lib, name, run_ ## lib ## _ ## symbol, output },
  507. #define IMPL(lib, ...) IMPL_USE_ ## lib(lib, __VA_ARGS__)
  508. #define IMPL_ALL(...) \
  509.     IMPL(lavu,       __VA_ARGS__) \
  510.     IMPL(crypto,     __VA_ARGS__) \
  511.     IMPL(gcrypt,     __VA_ARGS__) \
  512.     IMPL(tomcrypt,   __VA_ARGS__)
  513.  
  514. struct hash_impl implementations[] = {
  515.     IMPL_ALL("MD5",        md5,       "aa26ff5b895356bcffd9292ba9f89e66")
  516.     IMPL_ALL("SHA-1",      sha1,      "1fd8bd1fa02f5b0fe916b0d71750726b096c5744")
  517.     IMPL_ALL("SHA-256",    sha256,    "14028ac673b3087e51a1d407fbf0df4deeec8f217119e13b07bf2138f93db8c5")
  518.     IMPL_ALL("SHA-512",    sha512,    "3afdd44a80d99af15c87bd724cb717243193767835ce866dd5d58c02d674bb57"
  519.                                       "7c25b9e118c200a189fcd5a01ef106a4e200061f3e97dbf50ba065745fd46bef")
  520.     IMPL(lavu,     "RIPEMD-128", ripemd128, "9ab8bfba2ddccc5d99c9d4cdfb844a5f")
  521.     IMPL(tomcrypt, "RIPEMD-128", ripemd128, "9ab8bfba2ddccc5d99c9d4cdfb844a5f")
  522.     IMPL_ALL("RIPEMD-160", ripemd160, "62a5321e4fc8784903bb43ab7752c75f8b25af00")
  523.     IMPL_ALL("AES-128",    aes128,    "crc:ff6bc888")
  524.     IMPL_ALL("CAMELLIA",   camellia,  "crc:7abb59a7")
  525.     IMPL_ALL("CAST-128",   cast128,   "crc:456aa584")
  526.     IMPL_ALL("BLOWFISH",   blowfish,  "crc:33e8aa74")
  527.     IMPL(lavu,     "TWOFISH", twofish, "crc:9edbd5c1")
  528.     IMPL(gcrypt,   "TWOFISH", twofish, "crc:9edbd5c1")
  529.     IMPL(tomcrypt, "TWOFISH", twofish, "crc:9edbd5c1")
  530.     IMPL(lavu,     "RC4",     rc4,     "crc:538d37b2")
  531.     IMPL(crypto,   "RC4",     rc4,     "crc:538d37b2")
  532.     IMPL(lavu,     "XTEA",    xtea,    "crc:931fc270")
  533.     IMPL(tomcrypt, "XTEA",    xtea,    "crc:931fc270")
  534. };
  535.  
  536. int main(int argc, char **argv)
  537. {
  538.     uint8_t *input = av_malloc(MAX_INPUT_SIZE * 2);
  539.     uint8_t *output = input + MAX_INPUT_SIZE;
  540.     unsigned i, impl, size;
  541.     int opt;
  542.  
  543.     while ((opt = getopt(argc, argv, "hl:a:r:")) != -1) {
  544.         switch (opt) {
  545.         case 'l':
  546.             enabled_libs = optarg;
  547.             break;
  548.         case 'a':
  549.             enabled_algos = optarg;
  550.             break;
  551.         case 'r':
  552.             specified_runs = strtol(optarg, NULL, 0);
  553.             break;
  554.         case 'h':
  555.         default:
  556.             fprintf(stderr, "Usage: %s [-l libs] [-a algos] [-r runs]\n",
  557.                     argv[0]);
  558.             if ((USE_EXT_LIBS)) {
  559.                 char buf[1024];
  560.                 snprintf(buf, sizeof(buf), "%s%s%s",
  561.                          ((USE_EXT_LIBS) & USE_crypto)   ? "+crypto"   : "",
  562.                          ((USE_EXT_LIBS) & USE_gcrypt)   ? "+gcrypt"   : "",
  563.                          ((USE_EXT_LIBS) & USE_tomcrypt) ? "+tomcrypt" : "");
  564.                 fprintf(stderr, "Built with the following external libraries:\n"
  565.                         "make VERSUS=%s\n", buf + 1);
  566.             } else {
  567.                 fprintf(stderr, "Built without external libraries; use\n"
  568.                         "make VERSUS=crypto+gcrypt+tomcrypt tools/crypto_bench\n"
  569.                         "to enable them.\n");
  570.             }
  571.             exit(opt != 'h');
  572.         }
  573.     }
  574.  
  575.     if (!input)
  576.         fatal_error("out of memory");
  577.     for (i = 0; i < MAX_INPUT_SIZE; i += 4)
  578.         AV_WB32(input + i, i);
  579.  
  580.     size = MAX_INPUT_SIZE;
  581.     for (impl = 0; impl < FF_ARRAY_ELEMS(implementations); impl++)
  582.         run_implementation(input, output, &implementations[impl], size);
  583.  
  584.     av_free(input);
  585.  
  586.     return 0;
  587. }
  588.