random: Add performance improvements for the DRBG.
authorStephan Mueller <smueller@chronox.de>
Thu, 1 Dec 2016 16:15:10 +0000 (17:15 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 8 Dec 2016 07:58:25 +0000 (08:58 +0100)
commit20886fdcb841b0bf89bb1d44303d42f1804e38cb
tree3aa93c2f9a9313370ad2579911f4211da5a8b56a
parent227099f179df9dcf083d0ef6be9883c775df0874
random: Add performance improvements for the DRBG.

* random/random-drbg.c (struct drbg_state_ops_s): New function
pointers 'crypto_init' and 'crypto-fini'.
(struct drbg_state_s): New fields 'priv_data', 'ctr_handle', and
'ctr_null'.
(drbg_hash_init, drbg_hash_fini): New.
(drbg_hmac_init, drbg_hmac_setkey): New.
(drbg_sym_fini, drbg_sym_init, drbg_sym_setkey): New.
(drbg_sym_ctr): New.
(drbg_ctr_bcc): Set the key.
(drbg_ctr_df): Ditto.
(drbg_hmac_update): Ditto.
(drbg_hmac_generate): Replace drgb_hmac by drbg_hash.
(drbg_hash_df): Ditto.
(drbg_hash_process_addtl): Ditto.
(drbg_hash_hashgen): Ditto.
(drbg_ctr_update): Rework.
(drbg_ctr_generate): Rework.
(drbg_ctr_ops): Init new functions pointers.
(drbg_uninstantiate): Call fini function.
(drbg_instantiate): Call init function.

--
The performance improvements can be categorized as follows:

* Initialize the cipher handle of the backend ciphers once and re-use
  them for subsequent cipher invocations.

* Limit the invocation of setkey to the cases when the key is newly
  created.

* Use the AES CTR mode and rip out the counter maintenance in the DRBG
  code. This allows the use of accelerated CTR AES implementations. To
  use the CTR AES mode, a NULL buffer is created that is used as the
  "plaintext" to the CTR mode, because the DRBG CTR AES operation is the
  result of the encryption of the CTR (i.e. the NULL buffer makes the
  final XOR of the CTR AES mode a noop).

The following timing measurements are made. The measurement do not use a
precise timing operation and should rather serve as a general hint to
the performance improvements.

 On a Broadwell i7 CPU:

block size 4096 1024 128 32 16
 aes256 old 28MB/s 27MB/s 19MB/s 11MB/s 6MB/s
 aes128 old 29MB/s 32MB/s 23MB/s 15MB/s 9MB/s
 sha256 old 48MB/s 48MB/s 33MB/s 16MB/s 8MB/s
 hmac sha256 old 15MB/s 15MB/s 10MB/s 5MB/s 2MB/s

 aes256 new 180MB/s 169MB/s 93MB/s 37MB/s 20MB/s
 aes128 new 240MB/s 221MB/s 125MB/s 51MB/s 27MB/s
 sha256 new 75MB/s 69MB/s 48MB/s 23MB/s 11MB/s
 hmac sha256 new 37MB/s 34MB/s 21MB/s 8MB/s 4MB/s

Signed-off-by: Stephan Mueller <smueller@chronox.de>
ChnageLog entries above written by -wk
random/random-drbg.c