summaryrefslogtreecommitdiff
path: root/tests/benchmark.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2015-01-16 14:55:03 +0100
committerWerner Koch <wk@gnupg.org>2015-01-16 14:55:03 +0100
commit067d7d8752d4d8a98f8e0e5e9b1a5b13e1b7ff9c (patch)
tree1eab7affe5d24e919a22a5d4a29c8303342cf8db /tests/benchmark.c
parent9d2a22c94ae99f9301321082c4fb8d73f4085fda (diff)
downloadlibgcrypt-067d7d8752d4d8a98f8e0e5e9b1a5b13e1b7ff9c.tar.gz
Add OCB cipher mode
* cipher/cipher-ocb.c: New. * cipher/Makefile.am (libcipher_la_SOURCES): Add cipher-ocb.c * cipher/cipher-internal.h (OCB_BLOCK_LEN, OCB_L_TABLE_SIZE): New. (gcry_cipher_handle): Add fields marks.finalize and u_mode.ocb. * cipher/cipher.c (_gcry_cipher_open_internal): Add OCB mode. (_gcry_cipher_open_internal): Setup default taglen of OCB. (cipher_reset): Clear OCB specific data. (cipher_encrypt, cipher_decrypt, _gcry_cipher_authenticate) (_gcry_cipher_gettag, _gcry_cipher_checktag): Call OCB functions. (_gcry_cipher_setiv): Add OCB specific nonce setting. (_gcry_cipher_ctl): Add GCRYCTL_FINALIZE and GCRYCTL_SET_TAGLEN * src/gcrypt.h.in (GCRYCTL_SET_TAGLEN): New. (gcry_cipher_final): New. * cipher/bufhelp.h (buf_xor_1): New. * tests/basic.c (hex2buffer): New. (check_ocb_cipher): New. (main): Call it here. Add option --cipher-modes. * tests/bench-slope.c (bench_aead_encrypt_do_bench): Call gcry_cipher_final. (bench_aead_decrypt_do_bench): Ditto. (bench_aead_authenticate_do_bench): Ditto. Check error code. (bench_ocb_encrypt_do_bench): New. (bench_ocb_decrypt_do_bench): New. (bench_ocb_authenticate_do_bench): New. (ocb_encrypt_ops): New. (ocb_decrypt_ops): New. (ocb_authenticate_ops): New. (cipher_modes): Add them. (cipher_bench_one): Skip wrong block length for OCB. * tests/benchmark.c (cipher_bench): Add field noncelen to MODES. Add OCB support. -- See the comments on top of cipher/cipher-ocb.c for the patent status of the OCB mode. The implementation has not yet been optimized and as such is not faster that the other AEAD modes. A first candidate for optimization is the double_block function. Large improvements can be expected by writing an AES ECB function to work on multiple blocks. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'tests/benchmark.c')
-rw-r--r--tests/benchmark.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/tests/benchmark.c b/tests/benchmark.c
index 5bf92daa..6be9509b 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -779,6 +779,7 @@ cipher_bench ( const char *algoname )
void (* const aead_init)(gcry_cipher_hd_t hd, size_t buflen, int authlen);
int req_blocksize;
int authlen;
+ int noncelen;
} modes[] = {
{ GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1 },
{ GCRY_CIPHER_MODE_CBC, " CBC", 1 },
@@ -791,6 +792,8 @@ cipher_bench ( const char *algoname )
#endif
{ GCRY_CIPHER_MODE_GCM, " GCM", 0,
NULL, GCRY_GCM_BLOCK_LEN, GCRY_GCM_BLOCK_LEN },
+ { GCRY_CIPHER_MODE_OCB, " OCB", 1,
+ NULL, 16, 16, 15 },
{ GCRY_CIPHER_MODE_STREAM, "", 0 },
{0}
};
@@ -929,9 +932,30 @@ cipher_bench ( const char *algoname )
exit (1);
}
}
+
+ if (modes[modeidx].noncelen)
+ {
+ char nonce[100];
+ size_t noncelen;
+
+ noncelen = modes[modeidx].noncelen;
+ if (noncelen > sizeof nonce)
+ noncelen = sizeof nonce;
+ memset (nonce, 42, noncelen);
+ err = gcry_cipher_setiv (hd, nonce, noncelen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
if (modes[modeidx].aead_init)
{
(*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+ gcry_cipher_final (hd);
err = gcry_cipher_encrypt (hd, outbuf, buflen, buf, buflen);
if (err)
break;
@@ -987,18 +1011,42 @@ cipher_bench ( const char *algoname )
exit (1);
}
}
+
+ if (modes[modeidx].noncelen)
+ {
+ char nonce[100];
+ size_t noncelen;
+
+ noncelen = modes[modeidx].noncelen;
+ if (noncelen > sizeof nonce)
+ noncelen = sizeof nonce;
+ memset (nonce, 42, noncelen);
+ err = gcry_cipher_setiv (hd, nonce, noncelen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
if (modes[modeidx].aead_init)
{
(*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+ gcry_cipher_final (hd);
err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
if (err)
break;
err = gcry_cipher_checktag (hd, outbuf, modes[modeidx].authlen);
if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
- err = gpg_error (GPG_ERR_NO_ERROR);
+ err = 0;
}
else
- err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
+ {
+ gcry_cipher_final (hd);
+ err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
+ }
}
stop_timer ();
printf (" %s", elapsed_time ());