Canonical Voices

What Ryan Finnie talks about

Ryan Finnie

One of the nice things about the Raspberry Pi 2 is it has a Cortex-A7-based ARMv7 CPU, as opposed to the original Pi's ARMv6 CPU. This not only allows many more distributions to run on it (as most armhf distributions are compiled to ARMv7 minimum), but also brings with it the performance benefits associated with userland ARMv7 code. After releasing an Ubuntu 14.04 (trusty) image for the Raspberry Pi 2, I decided to pit Raspbian (which uses an ARMv6 userland for compatibility between the original Pi and the Pi 2) against Ubuntu (which is only compiled to ARMv7). I also benchmarked a Utilite Pro, an ARM system with a faster CPU and built-in SSD, and a modern Intel server.

  • Raspberry Pi B, 700 MHz 1-core BCM2708 CPU, 512 MiB memory, 16 GB SanDisk SDHC Class 4
  • Raspberry Pi 2 B, 900 MHz 4-core BCM2709 CPU, 1 GiB memory, 32 GB SanDisk Ultra Plus microSDHC Class 10 UHS-1
  • Utilite Pro, 1 GHz 4-core i.MX6 CPU, 2 GiB memory, 32 GB SanDisk U110 SSD
  • ASRock Z97 Pro3, 3.5 GHz 4-core Intel Core i5-4690K, 32 GiB memory, 4x 2TB Seagate ST2000DL003 5900 RPM in MD RAID 10

Raspbian wheezy was tested on both Raspberry Pi models, while Ubuntu trusty was also tested on the Raspberry Pi 2, along with the rest of the systems. All installations were current as of today. The systems were tested with nbench (BYTEmark), OpenSSL and Bonnie++.


This is a hand-picked assortment of test results; for the full raw results, see below.

Test RPi B
RPi 2
RPi 2
Numeric sort 217.2 450.72 421.55 334.63 2,385.1
FP emulation 41.334 70.276 55.108 52.454 795.9
IDEA 694.72 1,308.5 1,573.3 1,315 15,059
md5 1024 37,008.46 62,628.86 69,563.39 80,632.53 670,637.40
aes-256 cbc 1024 11,969.50 18,445.31 17,295.36 20,986.47 124,509.53
sha512 1024 8,491.32 11,838.81 20,718.25 25,803.70 431,647.74
whirlpool 1024 1,584.61 2,949.80 2,747.05 2,687.46 135,009.28
rsa 1024 verify 1,540.3 2,649.6 2,630.5 2,890.8 114,074.5
ecdsa 256 verify 73.2 126.3 138.0 161.1 4,329.6
Block output 7,520 11,028 11,299 48,214 62,762
Block input 13,233 23,015 22,997 125,954 284,914
Random seeks 524.7 1,054 874.6 3,218 444.5


  • Interestingly, many of the BYTEmark tests on the Pi 2 were faster on Raspbian than on Ubuntu. But keep in mind that these are tests from the 1990s, and are not taking advantage of modern optimizations (like the floating point emulation test). Many OpenSSL tests performed better on Ubuntu, but not all.
  • Edit: The slower nbench results in Ubuntu appear to be due to a running LSM (Linux Security Module). When Ubuntu is running with AppArmor (default) or SELinux enabled, it's marginally slower than Raspbian, but with LSMs disabled, it's marginally faster than Raspbian. (The Raspbian kernel has no LSM modules compiled in.) I'm keeping these test results as they are because AppArmor is enabled by default, but keep that in mind.
  • Raspbian/Ubuntu aside, virtually all of the tests were faster on the Pi 2 than the original Pi.
  • Bonnie++ tests were roughly the same between Raspbian and Ubuntu on Pi 2, and were decently faster than the original Pi (though in this test an older SDHC card was used for the original Pi, so it's not apples to apples). The SSD on the Utilite blows them away though.
  • All of the CPU tests are single-threaded, and do not take multi-core performance into consideration.
  • This was not a controlled scientific test. I did not run multiple tests on each system and average them together, and in the Intel system's case, it was an active (but low volume) server.
  • All Bonnie++ tests were run with swap disabled and on the boot drive, except for the Intel system where the boot drive (an SSD) did not have enough space for a full test. (Bonnie++ requires twice the amount of RAM as disk to run. On 512 MiB / 1 GiB / 2 GiB systems that's fine, but I didn't have 64 GiB free on the the Intel system's boot drive.

Raw results


BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
NUMERIC SORT        :           217.2  :       5.57  :       1.83
STRING SORT         :          30.638  :      13.69  :       2.12
BITFIELD            :      8.3354e+07  :      14.30  :       2.99
FP EMULATION        :          41.334  :      19.83  :       4.58
FOURIER             :          2359.7  :       2.68  :       1.51
ASSIGNMENT          :          2.5804  :       9.82  :       2.55
IDEA                :          694.72  :      10.63  :       3.15
HUFFMAN             :          428.85  :      11.89  :       3.80
NEURAL NET          :          3.1952  :       5.13  :       2.16
LU DECOMPOSITION    :           75.29  :       3.90  :       2.82
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 11.514
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : ARMv6-compatible processor rev 7 (v6l)
L2 Cache            : 
OS                  : Linux 3.18.7+
C compiler          : gcc version 4.6.3 (Debian 4.6.3-14+rpi1) 
libc                :
MEMORY INDEX        : 2.526
INTEGER INDEX       : 3.165
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc, libc-5.4.38
* Trademarks are property of their respective holder.

Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
raspberrypi      1G    42  99  7520  14  4514   8   443  99 13233  11 524.7  51
Latency               276ms    9344ms    5262ms   26123us   16149us   34751us
Version  1.96       ------Sequential Create------ --------Random Create--------
raspberrypi         -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  2586  57 +++++ +++  3886  55  3200  70 +++++ +++  3696  53
Latency              2726us    5095us    4832us    2743us     307us    2468us

OpenSSL 1.0.1e 11 Feb 2013
built on: Fri Jun  6 15:02:47 UTC 2014
options:bn(64,32) rc4(ptr,char) des(idx,cisc,16,long) aes(partial) blowfish(ptr) 
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md2                  0.00         0.00         0.00         0.00         0.00 
mdc2                 0.00         0.00         0.00         0.00         0.00 
md4               2111.92k     7710.99k    23471.96k    48774.36k    70500.68k
md5               1575.49k     5735.79k    17700.13k    37008.46k    53661.71k
hmac(md5)         2724.28k     9222.25k    25068.61k    43978.74k    56001.50k
sha1              1834.41k     6005.60k    15216.97k    24641.76k    30080.26k
rmd160            1391.15k     4389.22k    10595.31k    16489.15k    19804.23k
rc4              34807.13k    40177.89k    41639.59k    42066.47k    42146.33k
des cbc           6241.84k     6592.86k     6662.08k     6715.25k     6682.37k
des ede3          2281.85k     2351.88k     2374.12k     2370.95k     2385.89k
idea cbc             0.00         0.00         0.00         0.00         0.00 
seed cbc          7857.93k     9024.04k     9347.69k     9446.83k     9482.45k
rc2 cbc           6075.61k     6397.57k     6474.49k     6491.95k     6534.29k
rc5-32/12 cbc        0.00         0.00         0.00         0.00         0.00 
blowfish cbc     11636.94k    12964.88k    13267.65k    13459.91k    13439.83k
cast cbc          9786.53k    11425.48k    11879.08k    11967.79k    11967.44k
aes-128 cbc      13080.39k    14961.80k    15568.42k    15649.73k    15723.71k
aes-192 cbc      11587.16k    12963.16k    13444.83k    13519.88k    13551.05k
aes-256 cbc      10360.83k    11460.35k    11866.72k    11969.50k    12059.83k
camellia-128 cbc     8748.67k    10194.79k    10655.76k    10786.59k    10792.07k
camellia-192 cbc     7147.44k     8142.29k     8373.08k     8462.90k     8517.47k
camellia-256 cbc     7123.43k     8075.43k     8361.70k     8479.96k     8507.08k
sha256            3658.39k     8428.37k    14875.23k    18311.67k    19586.83k
sha512            1085.66k     4327.83k     6221.40k     8491.32k     9533.51k
whirlpool          387.65k      786.62k     1299.52k     1584.61k     1685.13k
aes-128 ige      11574.51k    13695.36k    14529.56k    14645.61k    14345.65k
aes-192 ige      10408.42k    12080.82k    12692.24k    12720.55k    12468.83k
aes-256 ige       9362.89k    10807.50k    11218.30k    11325.65k    11100.43k
ghash            15969.05k    17589.81k    18060.24k    18286.30k    18123.77k
                  sign    verify    sign/s verify/s
rsa  512 bits 0.002215s 0.000229s    451.6   4364.5
rsa 1024 bits 0.011254s 0.000649s     88.9   1540.3
rsa 2048 bits 0.073529s 0.002276s     13.6    439.5
rsa 4096 bits 0.535789s 0.008645s      1.9    115.7
                  sign    verify    sign/s verify/s
dsa  512 bits 0.002236s 0.002353s    447.2    424.9
dsa 1024 bits 0.006300s 0.007022s    158.7    142.4
dsa 2048 bits 0.022053s 0.025711s     45.3     38.9
                              sign    verify    sign/s verify/s
 160 bit ecdsa (secp160r1)   0.0018s   0.0059s    569.9    169.5
 192 bit ecdsa (nistp192)   0.0022s   0.0084s    462.0    119.7
 224 bit ecdsa (nistp224)   0.0027s   0.0106s    364.8     94.1
 256 bit ecdsa (nistp256)   0.0032s   0.0137s    307.7     73.2
 384 bit ecdsa (nistp384)   0.0065s   0.0314s    153.8     31.9
 521 bit ecdsa (nistp521)   0.0130s   0.0686s     77.1     14.6
 163 bit ecdsa (nistk163)   0.0047s   0.0170s    212.2     58.7
 233 bit ecdsa (nistk233)   0.0095s   0.0306s    105.4     32.6
 283 bit ecdsa (nistk283)   0.0141s   0.0560s     71.0     17.9
 409 bit ecdsa (nistk409)   0.0350s   0.1238s     28.5      8.1
 571 bit ecdsa (nistk571)   0.0845s   0.2883s     11.8      3.5
 163 bit ecdsa (nistb163)   0.0046s   0.0182s    217.0     55.0
 233 bit ecdsa (nistb233)   0.0093s   0.0333s    107.9     30.0
 283 bit ecdsa (nistb283)   0.0141s   0.0623s     71.0     16.1
 409 bit ecdsa (nistb409)   0.0350s   0.1401s     28.5      7.1
 571 bit ecdsa (nistb571)   0.0844s   0.3290s     11.9      3.0
                              op      op/s
 160 bit ecdh (secp160r1)   0.0050s    200.8
 192 bit ecdh (nistp192)   0.0066s    151.5
 224 bit ecdh (nistp224)   0.0084s    118.8
 256 bit ecdh (nistp256)   0.0110s     91.0
 384 bit ecdh (nistp384)   0.0261s     38.3
 521 bit ecdh (nistp521)   0.0567s     17.6
 163 bit ecdh (nistk163)   0.0082s    121.7
 233 bit ecdh (nistk233)   0.0149s     67.1
 283 bit ecdh (nistk283)   0.0274s     36.4
 409 bit ecdh (nistk409)   0.0611s     16.4
 571 bit ecdh (nistk571)   0.1427s      7.0
 163 bit ecdh (nistb163)   0.0088s    113.1
 233 bit ecdh (nistb233)   0.0164s     60.9
 283 bit ecdh (nistb283)   0.0306s     32.6
 409 bit ecdh (nistb409)   0.0697s     14.4
 571 bit ecdh (nistb571)   0.1634s      6.1

RPi 2 Raspbian

BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
NUMERIC SORT        :          450.72  :      11.56  :       3.80
STRING SORT         :          36.422  :      16.27  :       2.52
BITFIELD            :      1.2923e+08  :      22.17  :       4.63
FP EMULATION        :          70.276  :      33.72  :       7.78
FOURIER             :          4762.7  :       5.42  :       3.04
ASSIGNMENT          :          6.8898  :      26.22  :       6.80
IDEA                :          1308.5  :      20.01  :       5.94
HUFFMAN             :          657.63  :      18.24  :       5.82
NEURAL NET          :          6.2476  :      10.04  :       4.22
LU DECOMPOSITION    :          229.36  :      11.88  :       8.58
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 20.143
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : 4 CPU ARMv7 Processor rev 5 (v7l)
L2 Cache            : 
OS                  : Linux 3.18.7-v7+
C compiler          : gcc version 4.6.3 (Debian 4.6.3-14+rpi1) 
libc                :
MEMORY INDEX        : 4.296
INTEGER INDEX       : 5.654
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc, libc-5.4.38
* Trademarks are property of their respective holder.

Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
raspberrypi      2G    75  98 11028   9  7172   7   507  99 23015   9  1054  47
Latency               613ms    9537ms    6887ms   37024us   29880us   89690us
Version  1.96       ------Sequential Create------ --------Random Create--------
raspberrypi         -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  3861  39 +++++ +++  5097  41  7133  71 +++++ +++  4915  40
Latency               761us    3017us    3273us     694us      82us     619us

OpenSSL 1.0.1e 11 Feb 2013
built on: Thu Jan 15 21:10:17 UTC 2015
options:bn(64,32) rc4(ptr,char) des(idx,cisc,16,long) aes(partial) blowfish(ptr) 
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md2                  0.00         0.00         0.00         0.00         0.00 
mdc2                 0.00         0.00         0.00         0.00         0.00 
md4               5729.39k    19130.11k    49388.12k    81406.29k   100783.45k
md5               4438.31k    14612.82k    37866.07k    62628.86k    77651.97k
hmac(md5)         4319.19k    14172.82k    37175.64k    62360.92k    77799.42k
sha1              4468.70k    12776.64k    27218.26k    38258.35k    43382.10k
rmd160            3564.22k     9565.55k    19012.52k    25239.55k    27931.99k
rc4              51118.50k    57082.26k    58688.00k    59210.75k    59361.96k
des cbc          10716.11k    11323.88k    11482.62k    11527.51k    11539.80k
des ede3          4014.53k     4126.68k     4157.87k     4165.97k     4169.73k
idea cbc             0.00         0.00         0.00         0.00         0.00 
seed cbc         12535.65k    13878.08k    14283.09k    14388.91k    14420.65k
rc2 cbc           9081.97k     9540.69k     9663.23k     9694.55k     9704.79k
rc5-32/12 cbc        0.00         0.00         0.00         0.00         0.00 
blowfish cbc     17411.52k    19035.82k    19490.73k    19605.50k    19641.69k
cast cbc         16156.60k    18213.35k    18851.75k    19018.41k    19068.25k
aes-128 cbc      18509.82k    20745.75k    21447.68k    21703.32k    21684.22k
aes-192 cbc      16306.52k    17849.22k    18322.35k    18445.31k    18481.15k
aes-256 cbc      14645.75k    15878.23k    16251.90k    16348.50k    16375.81k
camellia-128 cbc    14842.11k    16692.03k    17303.64k    17463.98k    17511.77k
camellia-192 cbc    12000.46k    13217.69k    13603.50k    13703.17k    13732.52k
camellia-256 cbc    12016.46k    13221.08k    13603.84k    13703.17k    13732.52k
sha256            5168.70k    11715.06k    20019.97k    24473.94k    26167.98k
sha512            1550.01k     6186.62k     8711.34k    11838.81k    13221.89k
whirlpool          758.03k     1546.97k     2503.68k     2949.80k     3116.23k
aes-128 ige      16969.61k    19336.21k    20102.06k    20303.19k    20357.12k
aes-192 ige      14989.08k    16979.78k    17632.68k    17828.18k    17877.67k
aes-256 ige      13574.30k    15186.30k    15722.07k    15861.76k    15900.67k
ghash            24090.86k    26185.30k    27120.21k    27364.69k    27437.74k
                  sign    verify    sign/s verify/s
rsa  512 bits 0.001275s 0.000122s    784.1   8222.0
rsa 1024 bits 0.006798s 0.000377s    147.1   2649.6
rsa 2048 bits 0.045090s 0.001387s     22.2    720.8
rsa 4096 bits 0.332903s 0.005339s      3.0    187.3
                  sign    verify    sign/s verify/s
dsa  512 bits 0.001277s 0.001359s    782.9    735.9
dsa 1024 bits 0.003777s 0.004367s    264.7    229.0
dsa 2048 bits 0.013699s 0.016051s     73.0     62.3
                              sign    verify    sign/s verify/s
 160 bit ecdsa (secp160r1)   0.0009s   0.0034s   1158.6    293.8
 192 bit ecdsa (nistp192)   0.0011s   0.0046s    907.0    217.5
 224 bit ecdsa (nistp224)   0.0014s   0.0061s    724.8    163.6
 256 bit ecdsa (nistp256)   0.0017s   0.0079s    582.0    126.3
 384 bit ecdsa (nistp384)   0.0036s   0.0185s    276.3     53.9
 521 bit ecdsa (nistp521)   0.0074s   0.0408s    135.0     24.5
 163 bit ecdsa (nistk163)   0.0026s   0.0109s    382.4     91.7
 233 bit ecdsa (nistk233)   0.0056s   0.0207s    178.1     48.2
 283 bit ecdsa (nistk283)   0.0087s   0.0382s    114.5     26.2
 409 bit ecdsa (nistk409)   0.0224s   0.0870s     44.6     11.5
 571 bit ecdsa (nistk571)   0.0545s   0.2000s     18.4      5.0
 163 bit ecdsa (nistb163)   0.0026s   0.0116s    384.0     86.1
 233 bit ecdsa (nistb233)   0.0056s   0.0234s    179.7     42.7
 283 bit ecdsa (nistb283)   0.0088s   0.0428s    113.9     23.4
 409 bit ecdsa (nistb409)   0.0225s   0.0999s     44.5     10.0
 571 bit ecdsa (nistb571)   0.0543s   0.2311s     18.4      4.3
                              op      op/s
 160 bit ecdh (secp160r1)   0.0028s    353.3
 192 bit ecdh (nistp192)   0.0039s    258.4
 224 bit ecdh (nistp224)   0.0051s    195.8
 256 bit ecdh (nistp256)   0.0066s    152.4
 384 bit ecdh (nistp384)   0.0155s     64.4
 521 bit ecdh (nistp521)   0.0340s     29.4
 163 bit ecdh (nistk163)   0.0054s    184.8
 233 bit ecdh (nistk233)   0.0105s     95.5
 283 bit ecdh (nistk283)   0.0189s     53.0
 409 bit ecdh (nistk409)   0.0432s     23.2
 571 bit ecdh (nistk571)   0.1002s     10.0
 163 bit ecdh (nistb163)   0.0057s    173.9
 233 bit ecdh (nistb233)   0.0116s     86.5
 283 bit ecdh (nistb283)   0.0211s     47.3
 409 bit ecdh (nistb409)   0.0496s     20.2
 571 bit ecdh (nistb571)   0.1144s      8.7

RPi 2 Ubuntu

BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
NUMERIC SORT        :          421.55  :      10.81  :       3.55
STRING SORT         :          44.564  :      19.91  :       3.08
BITFIELD            :      1.2551e+08  :      21.53  :       4.50
FP EMULATION        :          55.108  :      26.44  :       6.10
FOURIER             :          3900.8  :       4.44  :       2.49
ASSIGNMENT          :          7.4676  :      28.42  :       7.37
IDEA                :          1573.3  :      24.06  :       7.14
HUFFMAN             :          697.19  :      19.33  :       6.17
NEURAL NET          :          5.6795  :       9.12  :       3.84
LU DECOMPOSITION    :          229.17  :      11.87  :       8.57
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 20.685
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : 4 CPU ARMv7 Processor rev 5 (v7l)
L2 Cache            : 
OS                  : Linux 3.18.0-14-rpi2
C compiler          : gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-19ubuntu1) 
libc                :
MEMORY INDEX        : 4.675
INTEGER INDEX       : 5.560
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc, libc-5.4.38
* Trademarks are property of their respective holder.

Version  1.97       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
ubuntu           2G    81  99 11299  12  6663   7   458  99 22997   9 874.6  47
Latency               146ms    1964ms    1969ms   28234us   17446us    4996ms
Version  1.97       ------Sequential Create------ --------Random Create--------
ubuntu              -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  5377  53 +++++ +++  9181  73  5538  53 +++++ +++  8974  73
Latency               495us    3662us    3825us     579us     151us     453us

OpenSSL 1.0.1f 6 Jan 2014
built on: Fri Jan  9 18:00:48 UTC 2015
options:bn(64,32) rc4(ptr,char) des(idx,cisc,16,long) aes(partial) blowfish(ptr) 
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md2                  0.00         0.00         0.00         0.00         0.00 
mdc2                 0.00         0.00         0.00         0.00         0.00 
md4               5583.18k    19339.84k    50591.15k    84928.17k   105990.83k
md5               4933.80k    16334.36k    42260.72k    69563.39k    86103.38k
hmac(md5)         5168.09k    16575.19k    42759.08k    70127.27k    86078.81k
sha1              4753.71k    13573.10k    28955.91k    40685.57k    46178.30k
rmd160            4114.97k    11203.16k    22984.95k    30934.70k    34390.07k
rc4              51762.27k    60471.42k    63043.07k    63848.45k    64042.33k
des cbc          11655.27k    12331.43k    12531.33k    12557.65k    12569.26k
des ede3          4439.70k     4544.32k     4571.82k     4578.99k     4573.87k
idea cbc             0.00         0.00         0.00         0.00         0.00 
seed cbc         15028.15k    15992.85k    16226.46k    16152.58k    16134.68k
rc2 cbc           8283.84k     8735.81k     8842.87k     8890.31k     8896.51k
rc5-32/12 cbc        0.00         0.00         0.00         0.00         0.00 
blowfish cbc     17713.68k    19325.95k    19862.27k    19652.61k    19942.06k
cast cbc         17440.01k    18823.55k    19480.49k    19606.87k    19685.38k
aes-128 cbc      20525.47k    22075.99k    22760.96k    22951.94k    23003.14k
aes-192 cbc      17829.68k    19140.84k    19556.78k    19664.21k    19685.38k
aes-256 cbc      15833.37k    16889.54k    17187.84k    17295.36k    17317.89k
camellia-128 cbc    16605.77k    17759.25k    18107.56k    18184.19k    18071.88k
camellia-192 cbc    13084.38k    13919.70k    14156.46k    14218.58k    14196.74k
camellia-256 cbc    13120.85k    13918.42k    14240.68k    14304.60k    14305.96k
sha256            5257.09k    11834.20k    20598.02k    25311.57k    27197.99k
sha512            2573.96k    10302.66k    14994.94k    20718.25k    23317.16k
whirlpool          699.24k     1430.44k     2318.76k     2747.05k     2899.97k
aes-128 ige      19613.12k    21159.32k    21582.68k    21689.69k    21575.92k
aes-192 ige      16952.97k    18264.38k    18650.71k    18749.10k    18746.03k
aes-256 ige      15216.35k    16191.06k    16493.65k    16570.71k    16545.11k
ghash            24319.88k    26480.96k    27397.46k    27801.26k    27863.72k
                  sign    verify    sign/s verify/s
rsa  512 bits 0.001258s 0.000120s    795.1   8336.1
rsa 1024 bits 0.006826s 0.000380s    146.5   2630.5
rsa 2048 bits 0.045500s 0.001403s     22.0    712.9
rsa 4096 bits 0.336000s 0.005411s      3.0    184.8
                  sign    verify    sign/s verify/s
dsa  512 bits 0.001238s 0.001323s    807.7    755.9
dsa 1024 bits 0.003753s 0.004369s    266.5    228.9
dsa 2048 bits 0.013788s 0.016303s     72.5     61.3
                              sign    verify    sign/s verify/s
 160 bit ecdsa (secp160r1)   0.0008s   0.0030s   1315.6    333.1
 192 bit ecdsa (nistp192)   0.0010s   0.0042s   1008.8    240.5
 224 bit ecdsa (nistp224)   0.0013s   0.0056s    793.9    180.0
 256 bit ecdsa (nistp256)   0.0016s   0.0072s    634.6    138.0
 384 bit ecdsa (nistp384)   0.0034s   0.0178s    289.9     56.2
 521 bit ecdsa (nistp521)   0.0072s   0.0400s    138.9     25.0
 163 bit ecdsa (nistk163)   0.0025s   0.0092s    399.7    108.5
 233 bit ecdsa (nistk233)   0.0054s   0.0171s    186.3     58.6
 283 bit ecdsa (nistk283)   0.0084s   0.0313s    119.2     32.0
 409 bit ecdsa (nistk409)   0.0214s   0.0677s     46.7     14.8
 571 bit ecdsa (nistk571)   0.0518s   0.1578s     19.3      6.3
 163 bit ecdsa (nistb163)   0.0025s   0.0100s    402.6     99.8
 233 bit ecdsa (nistb233)   0.0053s   0.0186s    188.4     53.7
 283 bit ecdsa (nistb283)   0.0084s   0.0347s    118.8     28.8
 409 bit ecdsa (nistb409)   0.0215s   0.0764s     46.5     13.1
 571 bit ecdsa (nistb571)   0.0518s   0.1793s     19.3      5.6
                              op      op/s
 160 bit ecdh (secp160r1)   0.0025s    397.3
 192 bit ecdh (nistp192)   0.0035s    287.1
 224 bit ecdh (nistp224)   0.0047s    213.4
 256 bit ecdh (nistp256)   0.0061s    164.8
 384 bit ecdh (nistp384)   0.0148s     67.7
 521 bit ecdh (nistp521)   0.0333s     30.1
 163 bit ecdh (nistk163)   0.0045s    219.8
 233 bit ecdh (nistk233)   0.0084s    119.3
 283 bit ecdh (nistk283)   0.0154s     65.0
 409 bit ecdh (nistk409)   0.0332s     30.1
 571 bit ecdh (nistk571)   0.0778s     12.8
 163 bit ecdh (nistb163)   0.0049s    205.4
 233 bit ecdh (nistb233)   0.0092s    108.9
 283 bit ecdh (nistb283)   0.0171s     58.5
 409 bit ecdh (nistb409)   0.0379s     26.4
 571 bit ecdh (nistb571)   0.0895s     11.2


BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
NUMERIC SORT        :          334.63  :       8.58  :       2.82
STRING SORT         :          51.165  :      22.86  :       3.54
BITFIELD            :      1.2678e+08  :      21.75  :       4.54
FP EMULATION        :          52.454  :      25.17  :       5.81
FOURIER             :          4589.4  :       5.22  :       2.93
ASSIGNMENT          :          5.7939  :      22.05  :       5.72
IDEA                :            1315  :      20.11  :       5.97
HUFFMAN             :          668.33  :      18.53  :       5.92
NEURAL NET          :          6.2869  :      10.10  :       4.25
LU DECOMPOSITION    :          209.07  :      10.83  :       7.82
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 18.965
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : 4 CPU ARMv7 Processor rev 10 (v7l)
L2 Cache            : 
OS                  : Linux 3.13.0-45-generic
C compiler          : gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-19ubuntu1) 
libc                :
MEMORY INDEX        : 4.513
INTEGER INDEX       : 4.904
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc, libc-5.4.38
* Trademarks are property of their respective holder.

Version  1.97       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
clamps           4G    96  99 48214  41 38833  57   484  99 125954  97  3218 304
Latency             93438us    2073ms     831ms   38317us    5599us   11133us
Version  1.97       ------Sequential Create------ --------Random Create--------
clamps              -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  8359  91 +++++ +++ 12668  89  9318  92 +++++ +++ 11547  92
Latency              7211us    2315us    3450us    2208us      42us    2775us

OpenSSL 1.0.1f 6 Jan 2014
built on: Fri Jan  9 18:00:48 UTC 2015
options:bn(64,32) rc4(ptr,char) des(idx,cisc,16,long) aes(partial) blowfish(ptr) 
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security
 -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md2                  0.00         0.00         0.00         0.00         0.00 
mdc2                 0.00         0.00         0.00         0.00         0.00 
md4               8241.83k    26442.64k    68072.19k   110937.69k   137616.85k
md5               6614.97k    20734.38k    50776.42k    80632.53k    96689.61k
hmac(md5)         6211.28k    19780.36k    50121.04k    80594.27k    97447.04k
sha1              6224.03k    17443.40k    36604.73k    51314.10k    57698.09k
rmd160            5281.47k    14105.00k    28500.52k    38167.31k    42205.18k
rc4              47155.17k    53723.78k    56523.76k    57421.26k    57431.15k
des cbc          12163.80k    12749.62k    13012.00k    13033.06k    12996.98k
des ede3          4672.83k     4775.56k     4796.24k     4800.45k     4824.83k
idea cbc             0.00         0.00         0.00         0.00         0.00 
seed cbc         15433.24k    16347.68k    16366.75k    16512.74k    16525.96k
rc2 cbc           9267.11k     9746.40k     9817.27k     9917.86k     9891.40k
rc5-32/12 cbc        0.00         0.00         0.00         0.00         0.00 
blowfish cbc     20327.67k    22173.27k    22814.70k    22972.48k    22843.30k
cast cbc         18834.93k    20428.78k    20931.76k    21110.43k    21150.52k
aes-128 cbc      25165.48k    26673.46k    27322.31k    27435.49k    27447.67k
aes-192 cbc      21798.22k    23635.20k    24230.21k    24392.99k    24442.37k
aes-256 cbc      19373.50k    20436.75k    20813.25k    20986.47k    20941.73k
camellia-128 cbc    18807.92k    20145.04k    20569.41k    20652.12k    20675.33k
camellia-192 cbc    15084.09k    15862.17k    16229.40k    16244.03k    16280.12k
camellia-256 cbc    15055.23k    15930.37k    16118.34k    16298.73k    16319.86k
sha256            6813.70k    15169.79k    26092.42k    31481.10k    33762.12k
sha512            3204.16k    12776.06k    18733.28k    25803.70k    28988.92k
whirlpool          692.55k     1408.34k     2275.29k     2687.46k     2845.34k
aes-128 ige      24451.80k    26496.75k    27079.17k    27450.12k    27408.34k
aes-192 ige      21368.84k    22686.98k    23424.82k    23525.57k    23473.80k
aes-256 ige      18886.16k    20038.38k    20458.26k    20566.79k    20646.17k
ghash            32450.51k    35398.26k    36421.72k    36791.07k    36908.85k
                  sign    verify    sign/s verify/s
rsa  512 bits 0.001124s 0.000105s    890.0   9550.8
rsa 1024 bits 0.006208s 0.000346s    161.1   2890.8
rsa 2048 bits 0.041946s 0.001267s     23.8    789.1
rsa 4096 bits 0.302581s 0.004887s      3.3    204.6
                  sign    verify    sign/s verify/s
dsa  512 bits 0.001130s 0.001199s    885.3    833.9
dsa 1024 bits 0.003470s 0.004028s    288.2    248.3
dsa 2048 bits 0.012430s 0.014396s     80.4     69.5
                              sign    verify    sign/s verify/s
 160 bit ecdsa (secp160r1)   0.0007s   0.0026s   1426.5    392.1
 192 bit ecdsa (nistp192)   0.0009s   0.0036s   1103.3    280.3
 224 bit ecdsa (nistp224)   0.0012s   0.0053s    815.7    188.5
 256 bit ecdsa (nistp256)   0.0014s   0.0062s    699.6    161.1
 384 bit ecdsa (nistp384)   0.0033s   0.0163s    304.3     61.4
 521 bit ecdsa (nistp521)   0.0067s   0.0362s    150.0     27.6
 163 bit ecdsa (nistk163)   0.0024s   0.0075s    412.9    132.7
 233 bit ecdsa (nistk233)   0.0050s   0.0137s    201.9     73.2
 283 bit ecdsa (nistk283)   0.0076s   0.0257s    131.1     39.0
 409 bit ecdsa (nistk409)   0.0196s   0.0559s     50.9     17.9
 571 bit ecdsa (nistk571)   0.0511s   0.1296s     19.6      7.7
 163 bit ecdsa (nistb163)   0.0024s   0.0081s    418.2    122.8
 233 bit ecdsa (nistb233)   0.0049s   0.0149s    205.1     67.0
 283 bit ecdsa (nistb283)   0.0076s   0.0286s    131.2     35.0
 409 bit ecdsa (nistb409)   0.0196s   0.0628s     51.1     15.9
 571 bit ecdsa (nistb571)   0.0511s   0.1464s     19.6      6.8
                              op      op/s
 160 bit ecdh (secp160r1)   0.0021s    468.1
 192 bit ecdh (nistp192)   0.0030s    335.2
 224 bit ecdh (nistp224)   0.0044s    226.0
 256 bit ecdh (nistp256)   0.0051s    195.0
 384 bit ecdh (nistp384)   0.0138s     72.7
 521 bit ecdh (nistp521)   0.0301s     33.2
 163 bit ecdh (nistk163)   0.0037s    270.9
 233 bit ecdh (nistk233)   0.0067s    150.1
 283 bit ecdh (nistk283)   0.0127s     78.9
 409 bit ecdh (nistk409)   0.0275s     36.4
 571 bit ecdh (nistk571)   0.0638s     15.7
 163 bit ecdh (nistb163)   0.0040s    250.7
 233 bit ecdh (nistb233)   0.0073s    136.3
 283 bit ecdh (nistb283)   0.0139s     71.9
 409 bit ecdh (nistb409)   0.0311s     32.1
 571 bit ecdh (nistb571)   0.0719s     13.9


BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
NUMERIC SORT        :          2385.1  :      61.17  :      20.09
STRING SORT         :          1345.8  :     601.32  :      93.07
BITFIELD            :      7.4081e+08  :     127.07  :      26.54
FP EMULATION        :           795.9  :     381.91  :      88.13
FOURIER             :           58268  :      66.27  :      37.22
ASSIGNMENT          :          78.017  :     296.87  :      77.00
IDEA                :           15059  :     230.33  :      68.39
HUFFMAN             :          6721.5  :     186.39  :      59.52
NEURAL NET          :          136.68  :     219.57  :      92.36
LU DECOMPOSITION    :          3702.2  :     191.79  :     138.49
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 217.125
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : 4 CPU GenuineIntel Intel(R) Core(TM) i5-4690K CPU @ 3.50GHz 3501MHz
L2 Cache            : 6144 KB
OS                  : Linux 3.13.0-45-generic
C compiler          : gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 
libc                :
MEMORY INDEX        : 57.512
INTEGER INDEX       : 51.811
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc, libc-5.4.38
* Trademarks are property of their respective holder.

Version  1.97       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
nibbler      63744M  2717  88 62762   5 96251   3 +++++ +++ 284914   5 444.5   6
Latency             52062us    2482ms   14652ms   36641us   99483us     370ms
Version  1.97       ------Sequential Create------ --------Random Create--------
nibbler             -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  7648   5 +++++ +++  3568   3  2250   5 +++++ +++   628   0
Latency               186ms      81us     386ms     228ms      11us    2314ms

OpenSSL 1.0.1f 6 Jan 2014
built on: Fri Jan  9 17:52:48 UTC 2015
options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx) 
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md2                  0.00         0.00         0.00         0.00         0.00 
mdc2                 0.00         0.00         0.00         0.00         0.00 
md4             106719.16k   322994.60k   737961.39k  1105796.37k  1289319.77k
md5              74058.79k   213987.90k   470995.74k   670637.40k   767888.04k
hmac(md5)        63472.70k   190996.20k   442288.12k   656018.77k   766369.79k
sha1             86987.60k   239977.86k   509936.55k   741900.97k   902851.55k
rmd160           50582.59k   120868.69k   218979.15k   273907.03k   295291.56k
rc4             439214.15k   793583.10k   931643.08k   959178.75k   965929.64k
des cbc          82232.33k    85451.92k    85785.86k    85917.01k    86350.26k
des ede3         31638.78k    32192.49k    32414.31k    32370.01k    32385.71k
idea cbc             0.00         0.00         0.00         0.00         0.00 
seed cbc         85378.73k    86113.46k    85957.63k    85827.58k    86218.75k
rc2 cbc          52713.13k    53636.61k    53993.22k    54268.92k    54160.04k
rc5-32/12 cbc        0.00         0.00         0.00         0.00         0.00 
blowfish cbc    132890.61k   140962.25k   142400.85k   143064.75k   143606.58k
cast cbc        123477.80k   131612.07k   133600.00k   134423.46k   134250.50k
aes-128 cbc     155945.39k   170214.83k   173895.42k   175899.91k   175699.29k
aes-192 cbc     131270.06k   142201.22k   144801.02k   146176.86k   146210.82k
aes-256 cbc     113957.72k   122551.72k   124043.69k   124509.53k   124903.42k
camellia-128 cbc   116319.99k   179128.77k   204550.83k   211808.60k   214896.16k
camellia-192 cbc   100422.48k   140049.42k   154080.68k   158968.15k   161086.50k
camellia-256 cbc    97688.27k   138615.62k   153032.19k   159233.03k   160516.78k
sha256           61247.67k   136223.06k   235369.64k   291570.01k   307383.57k
sha512           49566.23k   198618.43k   307382.45k   431647.74k   475592.02k
whirlpool        32330.11k    68737.35k   113109.50k   135009.28k   143833.99k
aes-128 ige     157819.94k   164321.30k   165555.97k   166157.53k   166488.75k
aes-192 ige     134085.14k   138452.57k   139268.27k   139497.57k   139569.83k
aes-256 ige     115722.84k   119265.58k   120394.66k   119833.26k   120444.25k
ghash          1555713.02k  3315741.80k  3619220.55k  3641529.34k  3646270.12k
                  sign    verify    sign/s verify/s
rsa  512 bits 0.000038s 0.000003s  26399.4 303787.7
rsa 1024 bits 0.000126s 0.000009s   7913.9 114074.5
rsa 2048 bits 0.000956s 0.000029s   1046.3  34247.7
rsa 4096 bits 0.006810s 0.000108s    146.8   9296.6
                  sign    verify    sign/s verify/s
dsa  512 bits 0.000040s 0.000037s  25145.5  27289.8
dsa 1024 bits 0.000092s 0.000101s  10874.2   9864.7
dsa 2048 bits 0.000286s 0.000335s   3491.0   2984.4
                              sign    verify    sign/s verify/s
 160 bit ecdsa (secp160r1)   0.0000s   0.0002s  20603.9   5858.8
 192 bit ecdsa (nistp192)   0.0001s   0.0002s  17141.2   4853.3
 224 bit ecdsa (nistp224)   0.0001s   0.0001s  16441.4   7415.1
 256 bit ecdsa (nistp256)   0.0001s   0.0002s  10583.9   4329.6
 384 bit ecdsa (nistp384)   0.0002s   0.0007s   6151.7   1471.3
 521 bit ecdsa (nistp521)   0.0004s   0.0009s   2664.9   1151.5
 163 bit ecdsa (nistk163)   0.0001s   0.0003s   7021.2   2944.9
 233 bit ecdsa (nistk233)   0.0003s   0.0004s   3571.8   2255.8
 283 bit ecdsa (nistk283)   0.0004s   0.0008s   2352.1   1230.7
 409 bit ecdsa (nistk409)   0.0010s   0.0013s   1029.0    759.2
 571 bit ecdsa (nistk571)   0.0021s   0.0031s    477.4    318.9
 163 bit ecdsa (nistb163)   0.0001s   0.0004s   7056.1   2785.4
 233 bit ecdsa (nistb233)   0.0003s   0.0005s   3609.1   2114.1
 283 bit ecdsa (nistb283)   0.0004s   0.0009s   2340.8   1156.8
 409 bit ecdsa (nistb409)   0.0010s   0.0014s   1024.7    716.2
 571 bit ecdsa (nistb571)   0.0021s   0.0034s    477.6    294.6
                              op      op/s
 160 bit ecdh (secp160r1)   0.0001s   7288.2
 192 bit ecdh (nistp192)   0.0002s   6045.6
 224 bit ecdh (nistp224)   0.0001s  10659.0
 256 bit ecdh (nistp256)   0.0002s   5927.2
 384 bit ecdh (nistp384)   0.0006s   1779.3
 521 bit ecdh (nistp521)   0.0006s   1610.1
 163 bit ecdh (nistk163)   0.0002s   6214.0
 233 bit ecdh (nistk233)   0.0002s   4779.5
 283 bit ecdh (nistk283)   0.0004s   2560.5
 409 bit ecdh (nistk409)   0.0006s   1597.7
 571 bit ecdh (nistk571)   0.0015s    657.1
 163 bit ecdh (nistb163)   0.0002s   5777.9
 233 bit ecdh (nistb233)   0.0002s   4529.4
 283 bit ecdh (nistb283)   0.0004s   2395.6
 409 bit ecdh (nistb409)   0.0007s   1479.1
 571 bit ecdh (nistb571)   0.0017s    599.0

Read more
Ryan Finnie

Download the lastest Ubuntu 14.04 Raspberry Pi 2 image

If you downloaded an older image than the current one, you shouldn't need to reinstall, but be sure to review the changelog in the link above.

Note that this blog post originally contained a bunch more information, which has been moved to a dedicated page on

I've closed comments on this blog post. If you are looking for help, please see this post on the forums. If you post there, you'll be reaching a wider audience of people (including myself) who can help you. Thanks for all of your comments!

After my last post, I went and ported Sjoerd's Raspberry Pi 2 Debian kernel patchset to Ubuntu's kernel package base (specifically 3.18.0-14.15). The result is an RPi2-compatible 3.18.7-based kernel which not only installs in Ubuntu, but has all the Ubuntu bells and whistles. I also re-ported flash-kernel based on Ubuntu's package, recompiled raspberrypi-firmware-nokernel, created a linux-meta-rpi2 package, and put it all in a PPA.

With that all done, I decided to go ahead and produce a base Ubuntu trusty image. It's 1.75GB uncompressed so you can put it on a 2GB or larger MicroSD card, and includes a full ubuntu-standard setup. Also included in the zip is a .bmap file; if you are writing the image in Linux you can use bmap-tools package to write only the non-zero bytes, saving some time. Otherwise it's the same procedure as other Raspberry Pi images.

(PS: If this image becomes popular, I should point out ahead of time: This is an unofficial image and is in no way endorsed by my employer, who happens to be the company who produces Ubuntu. This is a purely personal undertaking.)

Read more
Ryan Finnie

UPDATE: I've created a proper Ubuntu 14.04 image for the Raspberry Pi 2.

My Raspberry Pi 2 arrived yesterday, and I started playing with it today. Unlike the original Raspberry Pi which had an ARMv6 CPU, the Raspberry Pi 2 uses a Broadcom BCM2836 (ARMv7) CPU, which allows for binary compatibility with many distributions' armhf ports. However, it's still early early in the game, and since ARM systems have little standardization, there isn't much available yet. Raspbian works, but its userland still uses ARMv6-optimized binaries. Ubuntu has an early beta of Ubuntu Snappy, but Snappy is a much different environment than "regular" Ubuntu.

I found this post by Sjoerd Simons detailing getting Debian testing (jessie) on the Pi 2, and he did a good job of putting together the needed software, which I used to get a clean working install of Ubuntu trusty on my Pi 2. This is meant as a rough guide, mostly from memory -- I'll let better people eventually take care of producing a user-friendly system image. This procedure should work for trusty, utopic, and vivid, and might work for earlier distributions.

1) Install and boot Raspbian on one MicroSD card, and get the system access to a second MicroSD card, e.g. via a USB adapter.

2) Partition and format the card. #1 must be a vfat partition (64MB should be fine), and for the rest of this post I'm going to assume #2 is a swap partition and #3 is the rest of the card as ext4 for the root partition. Mount the root partition at e.g. /mnt/ubuntu and the vfat partition at e.g. /mnt/ubuntu-boot

3) Bootstrap a trusty system.

# apt-get install debootstrap
# ln -sf gutsy /usr/share/debootstrap/scripts/trusty
# debootstrap trusty /mnt/ubuntu

4) Chroot into the bootstrapped system.

# mount -t proc none /mnt/ubuntu/proc
# mount -t sysfs none /mnt/ubuntu/sys
# mount --bind /dev /mnt/ubuntu/dev
# chroot /mnt/ubuntu

5) Configure the base system. At the very least you should add a user, set passwords, and edit /etc/fstab as so:

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p3  /               ext4    defaults,noatime  0       1
/dev/mmcblk0p2  none            swap    sw                0       0

6) Install all the necessary packages in Sjoerd's repository. You can either add the apt repository, or just do as I did and download/dpkg install them manually. However, there's a problem. These are built for jessie, and the linux-image package requires initramfs-tools 0.110 or greater, which is not yet available in Ubuntu. But since the kernel we're using doesn't actually need an initramfs, I've put together an "initramfs-tools 0.110~fake1" package which fakes it. Simply install that package ahead of time.

7) Outside the chroot, copy /boot/config.txt from the Raspbian installation to /mnt/ubuntu/boot/firmware/config.txt. Then create /mnt/ubuntu/boot/firmware/cmdline.txt with the following:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p3 rootwait

8) Copy the firmware files to the actual boot device:

# cp -a /mnt/ubuntu/boot/firmware/* /mnt/ubuntu-boot/

9) Umount everything, shut down the system, swap the new card into place, and boot. Once you are successfully booted into the Ubuntu system, I'd recommend installing the ubuntu-standard metapackage to get everything not pulled in by the base debootstrap.

ryan@raspberrypi:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.1 LTS
Release:        14.04
Codename:       trusty

ryan@raspberrypi:~$ uname -a
Linux raspberrypi 3.18.0-trunk-rpi2 #1 SMP PREEMPT Debian 3.18.5-1~exp1.co1 (2015-02-02) armv7l armv7l armv7l GNU/Linux

ryan@raspberrypi:~$ cat /proc/cpuinfo 
processor       : [0,1,2,3]
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 38.40
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

Hardware        : BCM2709
Revision        : 0000
Serial          : 0000000000000000

ryan@raspberrypi:~$ gcc -v
Using built-in specs.
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-19ubuntu1)

Read more
Ryan Finnie

A year ago, I launched M29, a URL shortener with a twist. Apparently I forgot to announce it here. Whoops.

Normal URL shorteners are fairly simple. You submit a long URL. The service generates a short URL. The long and short URL are placed in a backend database. If you go to the short URL, it redirects to the long URL.

This means that the URL shortener service has a large database of URLs available to it. While 99% of the contents of this database may be mundane, it's still a large, centralized source of information. Very relevant to the recent NSA news, for example.

M29's twist is, except when serving the redirect, it does not know anything about the contents of the long URLs. This is accomplished by generating an AES-128 key, using it to encrypt the long URL, and then splitting the key in two. One half of the key is stored in the backend service, and the other half is encoded as part of the short URL itself. This means the only time the two parts of the key come together is when the short URL is requested for the redirect.

Getting from a long URL to a short URL can be done one of several ways. If you go to and have Javascript enabled, the client side actually loads an AES libary, builds the key, encrypts the URL, and sends the encrypted URL and half of the key to the server, all processed on the client side. If you don't have Javascript enabled, this task is farmed out to the server side, which generates a random key, encrypts, makes the database insert, returns the short URL, then throws away half of the key. M29 also has a featureful API which lets you do these tasks yourself. (It is also compatible with the API, which is easy to work with and has several tools available.)

The net effect is, while I currently have a database of about 10,000 entries, I cannot read them. Source IP and URI logging are not done on the server, so the only way I can find a long URL is if I load a full short URL, which is not possible given just the backend database.

Anyway, this weekend I did some work on M29, including adding a preview option (append a "+" to the short URL to get its info), among other small feature additions and fixes. It was then I realized, by going to that above short URL (the first URL generated and used in documentation) that the one-year anniversary of the service is today.

Read more
Ryan Finnie

The original Half-Life and Counter-Strike games were quietly released for Linux and Mac OS X last week, and as the maintainer of SteamLink, a repackaging of Half-Life: Uplink for Steam, I went out to see if the mod's files could be installed on these platforms.

Turns out there is a bug in Steam for these platforms, where it tries to launch the Windows version of Half-Life for GoldSrc mods from within Steam. However, Half-Life can be manually launched and pointed at the mod.

I have released a new version of SteamLink as a zip file. If you would like to run Half-Life: Uplink on Linux or OS X, simply download and extract the zip, and run the installer shell script. It will determine the Half-Life installation directory, install the mod, and give you a symlink to a script to launch it.

Read more
Ryan Finnie

I'm working on re-doing my home router / VM server to provide better IO. The goal is to have an SSD as the boot drive, and 4 2TB disks in RAID 10 (4TB usable total) for the VMs. I'll be using md RAID for building it, however I want to be particular about where the drives are physically, for a few reasons:

  • The RAID drives are all SATA 6Gbps drives, but the server's motherboard only has 2 SATA 6Gbps ports. I've got a 2-port PCIe SATA 6Gbps controller on the way[0].
  • I want to place the two drives in each base RAID 1 set on different controllers: one on the motherboard controller, one on the PCIe card controller. This may provide extra performance, but more importantly, having each disk on a different controller protects the array as a whole in case of a controller failure.

Linux md RAID 10 is a relatively new mode. In the past, you would manually create multiple RAID 1 arrays, then combine them in RAID 0, thereby knowing where the disks were placed, since you were doing it yourself. The mdadm RAID 10 method is easier, but I found there is literally no documentation on what drives it uses for the underlying RAID 1 arrays. Using loopback devices and some trial and error, I figured out how the arrays are assembled.

In a nutshell, the underlying RAID 1 arrays are paired two at a time, in order given during creation. If you were to do this:

# mdadm --create --verbose /dev/md0 --level=10 --raid-devices=4 /dev/sd{a,b,c,d}1

sda1 and sdb1 form one RAID 1 array, and sdc1 and sdd1 form another:

|           RAID0           |
|    RAID1    |    RAID1    |
| sda1 | sdb1 | sdc1 | sdd1 |

One other thing to mention is what happens when multiple drives are lost. Say in this case, both sda1 and sdd1 are lost, resulting in a degraded but functional array:

# mdadm --fail /dev/md0 /dev/sda1
# mdadm --remove /dev/md0 /dev/sda1
# mdadm --fail /dev/md0 /dev/sdd1
# mdadm --remove /dev/md0 /dev/sdd1
|           RAID0           |
|  RAID1 (D)  |  RAID1 (D)  |
|      | sdb1 | sdc1 |      |

If you were to replace sdd and add it back first, you might think it would go in the second RAID 1 array. But no, it takes the first available degraded slot:

# mdadm --add /dev/md0 /dev/sdd1
|           RAID0           |
|    RAID1    |  RAID1 (D)  |
| sdd1 | sdb1 | sdc1 |      |

So be careful in this situation, if you care about where the devices are physically laid out.

[0] Half of the order actually arrived Friday, including the SSD and a 4-port PCIe 4x SATA 6Gbps controller. The idea was to place two of the RAID drives on the motherboard SATA 6Gbps controller, and two on the new controller, plus the boot SSD (which is also SATA 6Gbps). My system has 3 PCIe 1x ports and a PCIe 16x port. The 4x card was supposed to go in the 16x port, but I learned after failure that many motherboards do not like non-video cards in the primary 16x port. Oh well. The boot SSD will now go on one of the motherboard SATA 3Gbps ports, and I've got an order in for a 2-port PCIe 1x SATA 6Gbps controller.

Read more
Ryan Finnie

I'm not a programmer, honest, but lately I've had this annoying habit of releasing code. But instead of my normal rambling posts about new announcements, I'll try to keep it brief.

apache-vsl has been one of my "90/90" projects (90% done, just need to finish the remaining 90%) for many years; I believe I started it around 2006, and I finally got the urge to finish and release it to the public. It's an Apache logging daemon (managed by Apache itself), capable of intelligently handling multiple VirtualHosts while being as efficient and extensible as possible. It's specifically built for two use cases -- servers which have a large number of VirtualHosts (hundreds or more), and VirtualHosts which receive a lot of traffic -- but it's easy enough to manage that it's useful with any Apache installation.

You can define time-based log files (monthly, daily, hourly... it's all just strftime), and apache-vsl handles when to log to a new file according to your definition. It manages symlinks to both the current and previous logfiles (for example, access_log.2012-08 -> access_log and access_log.2012-07 -> access_log.old), and has support for program triggers when a rotation happens (say, for running Webalizer against the old logfile, or compressing it).

apache-vsl manages its open files efficiently, so for a server with many VirtualHosts (not all of which may be accessed very often), all of the VirtualHosts' log files won't be open at once, but for VirtualHosts which are accessed frequently, the log filehandle will not constantly be opening and closing.

apache-vsl shares many features with cronolog, but while cronolog is designed more for splitting logfiles after the fact (if you were to use it directly from Apache, you'd need to have Apache open a dedicated pipe for every VirtualHost), apache-vsl is designed to communicate with Apache with a single pipe for multiple VirtualHosts.

A lot of good documentation is available in the manpage, so if you're interested, I suggest you start there.

Read more
Ryan Finnie

Raspberry Pi

Raspberry Pi

My Raspberry Pi, the $35 barebones computer, arrived last week. I bought it for three primary reasons:

  1. It was cheap.
  2. It was interesting.
  3. It was cheap.

I ordered early on a Thursday morning, expecting 3-4 weeks before it shipped per Element14's estimates. So I was quite surprised when I got a shipment notification later in the day. I'm guessing Element14 had a batch in, and was processing the backorders from the last few weeks, and somehow my order got mixed into that. So hey, yay instant gratification!

Shortly after that, Adafruit's clear acrylic case became available again, so I ordered that as well. I was expecting a tighter fit, but instead it bounces around a bit within the case. It's still sturdy enough to do its job, and looks nice, though the top panel no longer has the etched Raspberry Pi logo like I've seen on previous photos.

Raspberry Pi

I also ordered some cables and a powered USB hub from Monoprice (gotta love $5 next day shipping to California/Nevada), and a high power iPad USB charger from OWC, but that turned out to be unnecessary. The 7-port Monoprice USB hub seems to provide enough power to power the Raspberry Pi itself, along with some accessories.

In the above setup, I've got it powering the Raspberry Pi (with HDMI output, plus 16GB SDHC card), a keyboard and mouse, a 4GB USB thumb drive, and my Defcon 20 badge. Not only does the Raspberry Pi boot, but I gave it a stress test for a few hours: Running a Quake 3 Arena 1920x1080 demo on loop (GPU), while simultaneously running Bonnie++ on the USB thumb drive (CPU and IO). It successfully did that for the entire test, so I'm confident in the power performance of the USB hub.

Now, I have no real plans for it; it'll probably sit, powered on in the corner of my office, for if I need to test something on an ARM system. But I do like the concept of its primary purpose. My first computer was a Vic 20 (predecessor to the Commodore 64), and then a Commodore 128 (backwards-compatible successor to the Commodore 64). I have fond memories of those computers, and they helped shape the course of the rest of my life. I like how the Raspberry Pi has both HDMI and Composite output, meaning it supports any TV or monitor made in the last 5 years or so, plus at least the previous 50 years of TVs. (Remember RF adapters?) This really lowers the barrier of computer use for your average child.

However, there is one problem with the Raspberry Pi I really disagree with. Namely, it requires an operating system. A 440MB operating system, as well as the means to get it onto an SD card. An operating system that could easily be destroyed by curious fingers. This could be a huge barrier.

One of the things about my Vic 20 and Commodore 128 was I didn't have any cartridges or pre-bought software. Just the computer, a tape drive, and some CR-90 tapes. All value I got out of them was either by typing in BASIC programs from BYTE or Commodore magazines, or creating programs myself.

The Raspberry Pi really needs an onboard ROM with some sort of simple language on it, such as BBC BASIC, and the ability to save directly to SD cards. Upon boot, if the SD card contains a bootloader pointing to a full operating system, boot that, but if not, load the BASIC ROM.

Read more
Ryan Finnie

You may remember about a year ago when I released twuewand, a TrueRand implementation. TrueRand is a hardware entropy generation technique, implemented in software. In a nutshell, it works by setting an alarm for a few milliseconds in the future, and flipping a bit until the alarm is reached. It works due to the fact that time (your computer's RTC) and work (your computer's CPU) are not linked, so the result when the alarm comes due is unpredictable.

TrueRand was invented in 1995, and had mostly been forgotten for the last decade, until I started doing research on it last year. So it was quite a surprise when I was at Dan Kaminsky's talk at DEFCON a few weeks ago, and one of the topics he brought up was TrueRand. (Go check out his presentation slides; I just want to point out that while I'll be focusing on entropy and debiasing here, he goes into a lot of other interesting topics.)

Dan came to roughly the same conclusion as I did, that entropy sources have gotten worse over time, not better, and systems like VMs are almost completely devoid of entropy. Even more worrying, a paper published this year came to the conclusion that approximately 1 out of every 200 public keys on the Internet are easily breakable, not due to weaknesses in the encryption, but by bad entropy being used when generating the keypair. TrueRand may have been forgotten, but it's needed today more than ever. Dan and I talked for awhile after his talk, and went over a few things by email in the week following. twuewand 2.0's new features are influenced by those discussions.

Dan proposed a number of enhancements for TrueRand, mostly centered around other ideas for measuring variances given only a CPU and RTC, but what caught my eye was his idea of enhancing debiasing.

Many forms of random data are random in the technical sense, but are prone to bias. As an theoretical example, take a gun placed in a sturdy mount and pointed at a target not too far away. Most of the time, shots from it will hit the same spot every time (0), but occasionally they won't (1). So you're left something like 00000001000001001100000010000010; mostly hits, but with random misses. So it's random in a technical sense, but the distribution is heavily weighted toward one side.

The simplest method of debiasing is known as Von Neumann debiasing. Bits are processed as pairs, and any pair that is both 0 or both 1 is simply thrown out. Out of the pairs that are left, {0,1} becomes 0 and {1,0} becomes 1. So in the example above, the Von Neumann debiased output would be 00101. The data is now distributed better, but as you can tell, a lot was lost in the process. This is an extreme example since the data was heavily biased to begin with, but in data without a lot of bias, you still lose at least 50% of the bits (I've found 70-75% in real-world twuewand usage).

Dan thought, "Hmm, that's an awful lot of data simply being thrown out. We can't use the discarded data in the direct output, but perhaps we can use it to better (de-)influence the final output." He came up with a method he called modified Von Neumann, which I refer to in twuewand as Kaminsky debiasing.

The incoming bit stream is still run through Von Neumann, and put into an output buffer. However, all bits (whether they pass Von Neumann or not) are fed to a SHA256 stream. Occasionally (after the input stream is finished, or a sufficient number of bytes are put into the output buffer), the SHA256 hash is computed[1], and used as a 256-bit key for AES-256-CBC encrypting the output buffer. This way, only the bits which pass Von Neumann influence the output directly, but all bits help indirectly influence the output as well.

So twuewand now supports Kaminsky debiasing, and will use it by default if Digest::SHA and Crypt::Rijndael are installed.

Now, I want to clear up a mistake I made in my last post. I said that feeding twuewand output to /dev/urandom on Linux systems influences the primary pool, increasing entropy. First, you can actually write to either /dev/random or /dev/urandom, the effect is the same. But more importantly, entropy is NOT increased by writing to /dev/[u]random. It's merely "stirring the pot". If your system is out of entropy and you are blocking on /dev/random, no amount of writing to /dev/[u]random will unblock. (Directly, that is. If you're banging on your local keyboard to do this, you're slowly increasing entropy, but you could be doing the same thing in a text editor, or to /dev/null.)

Unfortunately, there is no way to increase entropy in the primary pool via standard system command line tools or character devices. However, there is a Linux ioctl, RNDADDENTROPY, which does this. So I wrote a small C wrapper, which takes STDIN and feeds it to the ioctl. This requires root of course. The utility is called, boringly enough, rndaddentropy, and is distributed with the twuewand tarball. It will be built by `make` on Linux systems.

I must point out that this utility gives you a very excellent method to shoot yourself in the foot. The lack of command line tools to directly access the primary buffer is most likely by design, since this bypasses most of the in-kernel filters for random input. Injecting, say, the contents of /bin/ls to the primary pool would be a great way to become one of those 1 in 200 statistics. Only use this utility to feed high quality entropy (such as by twuewand, or something like an entropy key).

Dan Kaminsky will be publishing software in the future called DakaRand, which does much of what twuewand currently does, but incorporates some of his other ideas. He provided me a work-in-progress copy, which looks very interesting, but it is not available to the public yet for a number of reasons. Be on the lookout for that when it is released.

Update (2012-08-15): Dan released DakaRand 1.0 a few hours after I made this post. Go check it out.

[1] In Dan's proposal, after the SHA256 hash is computed, it would then be run through Scrypt's hashing algorithm. This is not done in twuewand for two reasons. First, Crypt::Scrypt does not currently provide a low-level method to just do hashing; instead it wants to create a full digest which is unsuitable for this purpose. Second, Dan has been debating whether this step is necessary or desirable at all, and Scrypt has "undefined effects on embedded hardware".

Read more
Ryan Finnie

[ This was written at 2AM, and I tended to ramble. Hopefully I'll come back tomorrow and clean it up, add links to RFCs and Wikipedia entries where relevant, etc. ]

I've been explaining this a number of times in the last few days, so I figured I'd get this down in blog form to avoid repeating myself (even more). IPv6 is much like IPv4 in most respects, but its autoconfiguration can seem rather alien to people already familiar with IPv4 (that is, DHCP).

On an IPv6 network, the default router runs a service called the Router Advertisement daemon. Its primary purpose is to send out packets saying "hey, I'm the default router for the 2001:db8:1234:abcd::/64 network".

It actually doesn't matter what the router's IPv6 address actually is on 2001:db8:1234:abcd::/64; indeed, it (usually) doesn't even tell your what it is. Instead, it sends out RAs using its "link-local" fe80:: address. Link-local addresses are specific to the LAN segment you're on, and every device is required to have one (derived from the MAC address). It's sort of a middleware layer of doing things, between Layer 2 and Layer 3. But the important thing is you can talk to other devices if you know their link-local fe80:: address (and you're both on the same segment), and you can route to them.

So it really doesn't matter if the router's address is 2001:db8:1234:abcd::1/64 or 2001:db8:1234:abcd::dead:beef/64 or if it doesn't even have an address; if you're doing autoconfiguration, your OS will most likely be routing to it based on its link-local address. For example, my home router's link-local address on the LAN side is fe80::6a05:caff:fe02:4e4d/64, which it uses to send RAs.

By default the router sends an RA every minute or so, so the client device could theoretically set up autoconfiguration without ever talking to the router. But it will also respond to Router Solicitation requests being broadcast to the network. These requests are responded to (via broadcast) with the exact same RA packet it would have sent on a timer, except this time it happened on-demand.

Now, the RA lets the client device know what the LAN's IPv6 network space is. It also sends a series of flags which can make autoconfiguration possible.

The most relevant is the Autonomous address-configuration ("A") flag. This flag provides stateless autoconfiguration, and essentially says "you are permitted to construct your own IP address in the network I mentioned". The client will then use the MAC address of the interface as a basis for constructing an IP address. In the above example, 2001:db8:1234:abcd::/64 was the network. Say my interface's MAC address is 00:19:d2:43:c0:c4. Using the recommended MAC-munging method, this becomes 2001:db8:1234:abcd:219:d2ff:fe43:c0c4/64.

The client then uses Duplicate Address Detection (DAD) to make sure nobody on the network is already using this address. (DAD is also used to make sure the link-local address mentioned above is also unique to the network segment.)

So that's it! The client now has enough information to construct IP information, and in theory it never even had to send a packet. (I say "in theory" because DAD requires sending out a multicast packet. Plus, most OSes send out a Router Solicitation to trigger the Router Advertisement.) In this example, the router, fe80::6a05:caff:fe02:4e4d, sent out an RA stating the network is 2001:db8:1234:abcd::/64, and the "A" flag was set. The client used this information to construct the IP 2001:db8:1234:abcd:219:d2ff:fe43:c0c4/64, which it gave to itself, with the default route being fe80::6a05:caff:fe02:4e4d.

Now what about DNS? In a dual-stack environment, the client probably already has an IPv4 DNS address by now, and can certainly use that to look up IPv6 (AAAA) records. But for pure IPv6, there are two methods for getting DNS servers to the client.

First up is RDNSS, a relatively recent extension to the RA standard. It's simply an extension which gives one or more DNS servers in the RA packet. Simple, but not often used today.

The RA also has a "Managed address configuration" ("M") flag. This simply means, "there is a DHCPv6 server on this network. You may go look for it for more granular control." Also known as stateful autoconfiguration.

DHCPv6 is similar to DHCPv4, but has a number of differences. I'm not going to go into it in detail, but you can do pretty much everything you can do with DHCPv4: pooled address allocations, individual address allocation, DNS servers, domain search lists, etc. It's worth noting that if you have both the "A" and "M" flags in the RA set (and you're running a DHCPv6 server), the client will use both of these methods. That is to say, it'll construct an IP address using stateless means, then request an IP address from the DHCPv6 server, and will bind both of these addresses to the interface.

Side note: IPv6 has no concept of network or broadcast addresses. In this post's example, 2001:db8:1234:abcd::/64 was the network, but 2001:db8:1234:abcd:: can also be a device. However, most networks I've seen continue the old tradition of giving the .1 (or in IPv6's case, :1) address to the default router.

Read more
Ryan Finnie

I solved my problem from a few months ago with my iPhone and iPad not being able to get IPv6 info. It was actually a combination of two problems.

Last year I bought a Netgear N750DB router as an access point to replace my Linksys WRT54GL. Turns out the N750DB will send multicast traffic from a wireless device back to itself. This breaks IPv6 Duplicate Address Detection (DAD), and I was also seeing problems on my Ubuntu laptop. So I went back to the WRT54GL, and while stateless autconfiguration started working on the laptop again, it was still not working on the iPhone and iPad.

The second part was the iOS devices needed to be rebooted. No idea why, but after a hard reboot, they started pulling RA (and DHCPv6, which I had configured in the meantime). I've since bought a Linksys E4200 v1 to replace the N750DB, and everything is now working great.

Note that it's actually hard to tell when iOS has an IPv6 address. There are literally no IPv6 options in iOS, and the IPv6 address itself is not displayed anywhere. The only hint is in the network config page. If you have a DHCPv6 server or giving out RDNSS via RAs, the IPv6 nameserver and/or domain will show up in "DNS" and "Search Domains", though will likely be cut off. The only OS-level way to get meaningful IPv6 address/route information is a utility app called IPv6 Toolkit ($2 but worth it in this case). You can also go to a web site like (which of course I wrote) to see what your IP address is.

Note that even after fixing my AP and rebooting my devices, when I went to in Safari, it was still preferring v4 over v6. I was able to solve that by clearing all cached info in Safari.

Read more
Ryan Finnie

This weekend, I upgraded the OS on my main colo box, from 32-bit Debian lenny to 64-bit Ubuntu 12.04 precise LTS. This was an installation which I've had for over 8 years. It was originally installed in early 2004, when Debian sarge was in its long beta freeze. It had been dist-upgraded over the years, from sarge to etch to lenny, and was quite well maintained. And over the years, the hardware has been upgraded, from a Pentium 4 with 512MB memory and 80GB usable disk, to a Pentium D with 2GB memory and 160GB disk, to a Core i7 with 9GB memory[1] and 320GB disk.

However, it was still an 8-year-old installation, and I wanted to get to a 64-bit OS. Debian lenny's support was dropped in February, and Ubuntu precise seemed like a good target, so I made the decision late last year to replace the OS.

I bought two 1.5TB WD Black SATA drives and installed precise on them a few weeks ago, in a RAID1 set. My colo box in San Jose has a 3ware 9650SE 2-port SATA 2 card, and I had an identical card available at home. Thankfully 3ware cards store RAID configuration on the disks themselves, so it was just a matter of installing the OS on the surrogate server at home and shipping the disks to San Jose to be physically installed. I also bumped the memory up to its maximum of 24GB, as long as the case was open (memory is insanely cheap right now).

The precise install was a minimal install, with just networking and SSH configured. I then took a backup of the lenny install and put it in /srv/oldos. The idea was once the datacenter swapped out the disks and powered it on, I'd go in and, for example, "chroot /srv/oldos /etc/init.d/apache2 start" for all the essential services. I could then migrate the services into the new install one at a time.

With a few small bumps[2], that strategy worked well. However, a LOT of stuff is on this box, and it took me a most of the weekend to get everything right. Here's a sample of what this server is responsible for:

  • HTTP/HTTPS (Apache, a dozen or so web sites, plus MySQL/PostgreSQL)
  • SMTP (Postfix, plus Mailman, Dovecot IMAPS)
  • DNS (BIND9)
  • XMPP (ejabberd)
  • BitTorrent (bittornado tracker, torrent clients for Finnix)
  • Minecraft
  • Mumble/Murmur
  • rsyncd (Finnix mirrors)
  • 2ping listener
  • The all-important TCPMUX server
  • Various AI, TTS, text manipulation and audio utilities for X11R5 and the Cybersauce Broadcasting Corporation

As of Monday, everything is now running off the new precise install. I installed this server over LVM, and have only allocated about 500GB of the 1.5TB usable space. There is a relatively small 120GB root partition, a 160GB /home partition, and a 250GB /srv partition. The idea is not much more than the OS should be on root (and should never need more than 120GB), /home is self explanatory, and all projects (web sites, etc) go in /srv. If /home or /srv need to be expanded, it can be done remotely relatively easily by umounting them, expanding the partitions using LVM, and running resize2fs. I've also left most of the space unallocated in case I want to run KVM guests some day, though I don't have an immediate need.

[1] Yes, 9GB memory. Triple channel, so it was 3x2GB + 3x1GB modules.
[2] I had two significant problems with the migrations:

  1. The problem with picking a custom third-party Festival voice for the voice of the Cybersauce Broadcasting Corporation is that it looks like it has not been updated in years, and is specific to only a handful of Festival versions. So now I have a minimal, yet 300MB chroot running (64-bit) Debian lenny for the sole purpose of providing Festival's text2wave utility with the custom voice.
  2. I'm using two packages[3] not available in Debian/Ubuntu: a Perl module (AI::MegaHAL) and a PHP module (crack), both of which are published at my PPA. Both are sufficiently ancient and have not been updated upstream for years. Both compiled fine in 64-bit precise and at first appeared to run fine, but would then crash. Turns out both were not 64-bit safe, and required patching. Thankfully this is easy to roll out with PPAs.

[3] Okay, three, technically. I've packaged the tw_cli utility for the 3ware RAID card, but cannot distribute the package through my PPA because it's a non-free binary.

Read more
Ryan Finnie

2ping 2.0 has been released today. User-visible changes are minor, but behind the scenes, a major update to the protocol specification has been implemented, justifying the major version bump:

  • Updated to support 2ping protocol 2.0
    • Protocol 1.0 and 2.0 are backwards and forwards compatible with each other
    • Added support for extended segments
    • Added extended segment support for program version and notice text
    • Changed default minimum packet size from 64 to 128 bytes
  • Added peer reply packet size matching support, turned on by default
  • Added extra error output for socket errors (such as hostname not found)
  • Added extra version support for downstream distributions
  • Removed generation of 2ping6 symlinks at "make all" time (symlinks are still generated during "make install" in the destination tree)

2ping is a bi-directional ping utility. It uses 3-way pings (akin to TCP SYN, SYN/ACK, ACK) and after-the-fact state comparison between a 2ping listener and a 2ping client to determine which direction packet loss occurs.

Read more
Ryan Finnie

One night last week, my cable internet service went down. OK, it rarely happens, and when it does, I have an iPhone with tethering. No big deal normally, I would just have my laptop connect to the tether. However, that night I was in the middle of a few things on my home LAN, and wanted my whole network to have internet access, not just my laptop. Getting wireless access on my home router/server seemed the most preferable. So I dug through the junk crates and found:

  • Two Orinoco Gold 802.11b PCMCIA cards
  • Four Orinoco Silver 802.11b PCMCIA cards
  • A Linksys 802.11b USB dongle which required a USB A to A cable
  • A Linksys 802.11g PCI card
  • About a dozen WRT54G (or similar) router/APs

I immediately threw away the USB dongle due to its odd requirement. I should throw away the Orinoco cards as well, but dammit, they had real value (ten years ago). The PCI card would have worked, except my new router/server actually has no "legacy" PCI slots, just PCI Express slots. I could have cobbled together some sort of bridge with a WRT54G, but it would have been too much work. In the end I toughed it out and waited for the cable internet to return.

The next day I ordered a $17 PCI express 802.11n adapter, and it arrived today. Ubuntu 12.04 "precise" (currently in beta, set to be released next week) saw it immediately, and with a little reading I was able to get it working with my phone. I'm leaving the configs here in case they are useful to someone else:


#auto wlan0
iface wlan0 inet dhcp
    wpa-conf /etc/wpa_supplicant.conf

"auto wlan0" is commented out because I obviously don't want it running on boot, since this is a backup solution. That line could simply be omitted, but I like it there to point out to myself it is not brought up on boot.


    ssid="Ryan’s iPhone"

iPhone-specific note: that "’" is actually a unicode character, U+2019. "iwlist wlan0 scan" was returning this, which wpa_supplicant was not accepting:

ESSID:"Ryan\xE2\x80\x99s iPhone"

In the end, I hopped on my laptop, associated with the phone and grabbed the SSID from the logs and pasted it in on the server, to preserve the unicode character.

With that in place, "ifup wlan0" worked fine. In the future, during an outage I should just be able to log into the server, run "ifdown eth1", then "ifup wlan0", and everything at home should be run through my phone.

Read more
Ryan Finnie

A copy of this announcement is available at, in case the text is mangled here and the signature cannot be verified.

Hash: SHA256,SHA1

Wed, 11 Apr 2012 10:30:08 -0700

For a number of reasons, I've recently set up a new OpenPGP key, and 
will be transitioning away from my old one.  My old key was created 
over 10 years ago, as a 1024 bit DSA key with a SHA-1 signatures, both 
of which are considered inadequate today.  My new key is a 4096 bit RSA 
key with SHA-256 signatures.

The old key will continue to be valid for at least 90 days.  It will be 
revoked on or around 2012-07-15, or after the release of Finnix 105, 
whichever is later.  (My old key was used to manage signatures for the 
Finnix project.  This will be split out into a Finnix-specific signing 
key, and will be announced in a separate message.)

However, I would prefer all future correspondence to come to the new 
one, as of today.  I would also like this new key to be re-integrated 
into the web of trust.  This message is signed by both keys to certify 
the transition.

The old key was:

pub   1024D/203ECA25 2001-05-09
      Key fingerprint = B023 7C63 DF28 70AA C3AB  C54A 2996 10A9 203E CA25

And the new key is:

pub   4096R/86AE8D98 2012-04-11
      Key fingerprint = 42E2 C8DE 8C17 3AB1 02F5  2C6E 7E60 A3A6 86AE 8D98

To fetch the full key (including a photo UID, which is commonly
stripped by public keyservers), you can get it with:

  wget -q -O- | gpg --import -

Or, to fetch my new key from a public key server, you can simply do:

  gpg --keyserver --recv-key 86AE8D98

If you already know my old key, you can now verify that the new key is
signed by the old one:

  gpg --check-sigs 86AE8D98

The new and old keys' primary UIDs are both "Ryan Finnie 
".  This was by design, to ensure you must verify the 
key signatures rather than seeing something like "Ryan Finnie (2012) 

If you don't already know my old key, or you just want to be double
extra paranoid, you can check the fingerprint against the one above:

  gpg --fingerprint 86AE8D98

If you are satisfied that you've got the right key, and the UIDs match
what you expect, I'd appreciate it if you would sign my key:

  gpg --sign-key 86AE8D98

Lastly, if you could upload these signatures, I would appreciate it.
You can either send me an e-mail with the new signatures (if you have
a functional MTA on your system):

  gpg --armor --export 86AE8D98 | mail -s 'OpenPGP Signatures'

Or you can just upload the signatures to a public keyserver directly:

  gpg --keyserver --send-key 86AE8D98

Please let me know if there is any trouble, and sorry for the

Thank you,
Ryan Finnie

[Much of this text was adapted from dkg ,
thank you!]
Version: GnuPG v1.4.11 (GNU/Linux)


Read more
Ryan Finnie

While debugging my IPv6 problem (which I still don't have a resolution for), I registered a domain and made yet another "what is my IP?" site: It looks pretty. You should visit it.

Read more
Ryan Finnie

Dear Lazyweb,

I'm at a loss here. I've got an IPv6 setup at home, with radvd giving out network information. And it basically just works. My laptop associates with the wireless network, sends out a Router Solicitation packet, the router responds with a Router Advertisement (RA), and the laptop gives itself an IP. And for good measure, the router sends out unsolicited RAs every 10 seconds or so.

But my iPhone and iPad are no longer getting IPv6 addresses. They associate with the AP, get a DHCPv4 address, then nothing. I've even tried using the Ip6config app to scan for RAs, but according to it, no RAs arrive. But I can see them from my laptop, capture them with Wireshark, and they look proper. And of course there's no way to get around this in iOS, since there are literally no user-configurable IPv6 options.

I know this worked at one point, because whenever I try searching the web, I keep coming up with my own post from 2010 on getting this working. That being "hey, it's not working... oh, now it is".

Update (2012-06-08): I've figured out what caused this.

Read more
Ryan Finnie

New home server (nibbler)It's been a long time since I've built a computer from scratch, and even longer since I've been excited about it. For the last few years, my home office network has been mostly kitbashed together from other computers, and when I've needed to buy new parts, it's usually been begrudgingly.

However, a few weeks ago, the stars all aligned. I was preparing to upgrade the RAM and drives on my colo box in San Jose after Ubuntu 12.04 is released, and went shopping. Hard drive prices are very high due to the flooding in Thailand last year, but RAM is dirt cheap. I was able to max out my colo server's RAM to 24GB (6x4GB) for $100. That got me thinking about my home office. At any given moment, 7 desktop computers were on: my main Ubuntu workstation, a Windows gaming machine, two G4 Mini Finnix dev machines (PPC), an C2D E7200 Finnix dev machine (x86), an Athlon64 3200+ Debian sid dev machine and an Athlon64 X2 4600+ router / miscellaneous server.

The desktops are used frequently, the G4s are insignificant (they consume 9w each), but the last three servers were all relatively old, very power hungry (and hot), and all perform tasks that need somewhat significant computing power, though usually never at the same time. And at idle, the three of them draw a combined 240w. So I decided now would be a good time to build a virtualization server and combine them. I considered upgrading one of them for the task, but decided it wouldn't work: The E7200, despite being relatively new, doesn't support VT. The 3200+ is nearing 10 years old (it was the first 64-bit consumer processor released) and definitely doesn't support VT. The 4600+ does, but it's pretty old, and the worst power offender.

No, it would be best to start from scratch. I decided to focus on an Intel Sandy Bridge processor, as much RAM as I could get, and a mid-range 6Gbps SATA drive for serving the VMs, with a focus on energy savings primarily and computing power secondarily. Here's what I ended up with:

The parts arrived on Wednesday the 29th, I assembled it last weekend, and installed Ubuntu precise Beta 1 (AMD64 server). I was worried about building a Sandy Bridge system, the platform being relatively new, but nearly everything has worked perfectly so far. The CPU is well supported, the integrated graphics work, and all integrated components on the motherboard work fine. The only issue I've found so far is the system will not reliably power off after shutdown, but I can live with that. Heck, this is even the first machine I've owned where SATA hotplug works correctly.

The 6Gbps Seagate is a LUKS-crypted LVM disk holding the OS installations. The main install contains the routing / VPN / DHCP / etc services, as well as a QEMU/KVM host managed by libvirt. The Finnix dev and Debian sid dev machines have been transferred to this as VM guests. And Finnix build times have been reduced by nearly 2/3rds in the process.

Additionally, the host contains an existing 1.5TB WD Green SATA 3Gbps drive for shared media (ISOs, iTunes collection, movies, etc), and an existing 1.0TB WD Green SATA 3Gbps drive for backups of the other hosts. This drive is mounted in one of the front hotswap SATA sled trays for easy removal. (I learned this lesson late last year when I evacuated my home due to a nearby wildfire, and found that even quick-release case screws and toolless hard drive mounts were difficult to remove when you are short on time.) The other sled tray is simply for miscellaneous uses when needed.

So I replaced three servers, consuming 240w combined idle, with a beefy new server: powerful new CPU, 32GB RAM, and 3 hard drives totaling 4.5TB. I was expecting the idle power draw to be about 120w. But when I plugged it into my Kill-a-Watt, I found the power draw was really... 58w. Wow. And the CPU and case temperatures always hover around 28C. My first feeling was anger with myself; I should have spent the extra few dollars on the i5-2500 or i7-2600, but I was worried about power draw and heat dissipation. Oh well, the i5-2400 is still much faster than anything I've owned before.

I got all the functionality transferred over to the new server last weekend, but haven't done much with it for the last week. (I was pretty sick this week, missing four days of work.) This weekend I hope to make sure everything is in working order, and decommission the other servers.

Read more
Ryan Finnie

A month ago, I started working at Canonical, the makers of Ubuntu. Normally I'd write a long-winded post about my experiences from the last month, how/why I started and so on, but I'll just summarize: it rocks.

I work in the IS Operations group as a system administrator, and while my Launchpad profile has the little "Member of Canonical" badge on it now, I am not an Ubuntu developer (though of course Canonical employs quite a number of Ubuntu developers). That's not to say I don't contribute to Ubuntu; I file bugs, and manage packages as trickle-down from my Debian maintainer status, but these are all contributions that any member of the public community can do. Working in Canonical IS Operations is much like being a sysadmin in any large Ubuntu server shop.

I've gone back through last year's posts and tagged relevant posts with planet:canonical, which are aggregated at Canonical Voices, a feed aggregator for Canonical employees. ("Planet" has become a generic term for feed aggregation sites, though Canonical Voices is not actually running Planet software.) These tagged posts don't necessarily have to do with Canonical or Ubuntu topics, but are a filter for posts I want to appear there; technology topics, mostly.

Last month I made a post to the Finnix blog, explaining how my employment will affect Finnix development (it won't). Since then, Finnix 104 has been released, and I even found out some of the coworkers in my group are Finnix users. Good times!

Read more
Ryan Finnie

I occasionally plug this into Wolfram Alpha:

a^2+b^2=c^2, a/b=16/9, c=27

Click the "approximate forms" solution to get the width and height (a and b) for a rectangle where you know the diagonal (c) and the ratio (16/9). a or b can be specified at the end instead of c if you know the width or height.

I most often use this when I need to get the physical width and height of a monitor panel that I know the diagonal size of (since nearly all monitors are advertised by their diagonal panel size). With that information and the resolution, you can figure out the physical DPI of the monitor. (Not to be confused with the effective DPI of the operating system, which is used for things like converting font points and ems to pixels, and is usually independent of the monitor's size and resolution: 96 DPI for Windows, 72 DPI for Mac OS, and 75 or 100 DPI for X11 historically, though many Linux distros are preset to 96 DPI today.)

Read more