[PATCH 3/3] Faster look-up for spec by algo for digests, ciphers and MAC
Jussi Kivilinna
jussi.kivilinna at iki.fi
Mon Apr 2 11:24:34 CEST 2018
* cipher/cipher.c (cipher_list_algo0, cipher_list_algo301): New cipher
spec lists with same order and spacing as 'gcry_cipher_algos'
enumeration.
(spec_from_algo): Use new spec lists for faster look-up.
* cipher/mac.c (mac_list_algo101, mac_list_algo201, mac_list_algo401)
(mac_list_algo501): New MAC spec lists with same order and spacing as
'gcry_mac_algos' enumeration.
(spec_from_algo): Use new spec lists for faster look-up.
* cipher/md.c (digest_list_algo0, digest_list_algo301): New digest
spec lists with same order and spacing as 'gcry_md_algos'
enumeration.
(spec_from_algo): Use new spec lists for faster look-up.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
cipher/cipher.c | 124 ++++++++++++++++++++++++++-
cipher/mac.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
cipher/md.c | 155 +++++++++++++++++++++++++++++++++-
3 files changed, 510 insertions(+), 19 deletions(-)
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 1bef766cb..d6cd0b42e 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -90,6 +90,114 @@ static gcry_cipher_spec_t * const cipher_list[] =
NULL
};
+/* Cipher implementations starting with index 0 (enum gcry_cipher_algos) */
+static gcry_cipher_spec_t * const cipher_list_algo0[] =
+ {
+ NULL, /* GCRY_CIPHER_NONE */
+#ifdef USE_IDEA
+ &_gcry_cipher_spec_idea,
+#else
+ NULL,
+#endif
+#if USE_DES
+ &_gcry_cipher_spec_tripledes,
+#else
+ NULL,
+#endif
+#if USE_CAST5
+ &_gcry_cipher_spec_cast5,
+#else
+ NULL,
+#endif
+#if USE_BLOWFISH
+ &_gcry_cipher_spec_blowfish,
+#else
+ NULL,
+#endif
+ NULL, /* GCRY_CIPHER_SAFER_SK128 */
+ NULL, /* GCRY_CIPHER_DES_SK */
+#if USE_AES
+ &_gcry_cipher_spec_aes,
+ &_gcry_cipher_spec_aes192,
+ &_gcry_cipher_spec_aes256,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_cipher_spec_twofish
+#else
+ NULL
+#endif
+ };
+
+/* Cipher implementations starting with index 301 (enum gcry_cipher_algos) */
+static gcry_cipher_spec_t * const cipher_list_algo301[] =
+ {
+#if USE_ARCFOUR
+ &_gcry_cipher_spec_arcfour,
+#else
+ NULL,
+#endif
+#if USE_DES
+ &_gcry_cipher_spec_des,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_cipher_spec_twofish128,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_cipher_spec_serpent128,
+ &_gcry_cipher_spec_serpent192,
+ &_gcry_cipher_spec_serpent256,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_RFC2268
+ &_gcry_cipher_spec_rfc2268_40,
+ &_gcry_cipher_spec_rfc2268_128,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_cipher_spec_seed,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_cipher_spec_camellia128,
+ &_gcry_cipher_spec_camellia192,
+ &_gcry_cipher_spec_camellia256,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_SALSA20
+ &_gcry_cipher_spec_salsa20,
+ &_gcry_cipher_spec_salsa20r12,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_GOST28147
+ &_gcry_cipher_spec_gost28147,
+#else
+ NULL,
+#endif
+#if USE_CHACHA20
+ &_gcry_cipher_spec_chacha20
+#else
+ NULL,
+#endif
+ };
@@ -105,15 +213,19 @@ map_algo (int algo)
static gcry_cipher_spec_t *
spec_from_algo (int algo)
{
- int idx;
- gcry_cipher_spec_t *spec;
+ gcry_cipher_spec_t *spec = NULL;
algo = map_algo (algo);
- for (idx = 0; (spec = cipher_list[idx]); idx++)
- if (algo == spec->algo)
- return spec;
- return NULL;
+ if (algo >= 0 && algo < DIM(cipher_list_algo0))
+ spec = cipher_list_algo0[algo];
+ else if (algo >= 301 && algo < 301 + DIM(cipher_list_algo301))
+ spec = cipher_list_algo301[algo - 301];
+
+ if (spec)
+ gcry_assert (spec->algo == algo);
+
+ return spec;
}
diff --git a/cipher/mac.c b/cipher/mac.c
index e8e7cebdb..1b79bf315 100644
--- a/cipher/mac.c
+++ b/cipher/mac.c
@@ -130,6 +130,236 @@ static gcry_mac_spec_t * const mac_list[] = {
NULL,
};
+/* HMAC implementations start with index 101 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo101[] =
+ {
+#if USE_SHA256
+ &_gcry_mac_type_spec_hmac_sha256,
+ &_gcry_mac_type_spec_hmac_sha224,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SHA512
+ &_gcry_mac_type_spec_hmac_sha512,
+ &_gcry_mac_type_spec_hmac_sha384,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SHA1
+ &_gcry_mac_type_spec_hmac_sha1,
+#else
+ NULL,
+#endif
+#if USE_MD5
+ &_gcry_mac_type_spec_hmac_md5,
+#else
+ NULL,
+#endif
+#if USE_MD4
+ &_gcry_mac_type_spec_hmac_md4,
+#else
+ NULL,
+#endif
+#if USE_RMD160
+ &_gcry_mac_type_spec_hmac_rmd160,
+#else
+ NULL,
+#endif
+#if USE_TIGER
+ &_gcry_mac_type_spec_hmac_tiger1,
+#else
+ NULL,
+#endif
+#if USE_WHIRLPOOL
+ &_gcry_mac_type_spec_hmac_whirlpool,
+#else
+ NULL,
+#endif
+#ifdef USE_GOST_R_3411_94
+ &_gcry_mac_type_spec_hmac_gost3411_94,
+#else
+ NULL,
+#endif
+#ifdef USE_GOST_R_3411_12
+ &_gcry_mac_type_spec_hmac_stribog256,
+ &_gcry_mac_type_spec_hmac_stribog512,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_MD2
+ &_gcry_mac_type_spec_hmac_md2,
+#else
+ NULL,
+#endif
+#if USE_SHA3
+ &_gcry_mac_type_spec_hmac_sha3_224,
+ &_gcry_mac_type_spec_hmac_sha3_256,
+ &_gcry_mac_type_spec_hmac_sha3_384,
+ &_gcry_mac_type_spec_hmac_sha3_512,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#ifdef USE_GOST_R_3411_94
+ &_gcry_mac_type_spec_hmac_gost3411_cp,
+#else
+ NULL,
+#endif
+#if USE_BLAKE2
+ &_gcry_mac_type_spec_hmac_blake2b_512,
+ &_gcry_mac_type_spec_hmac_blake2b_384,
+ &_gcry_mac_type_spec_hmac_blake2b_256,
+ &_gcry_mac_type_spec_hmac_blake2b_160,
+ &_gcry_mac_type_spec_hmac_blake2s_256,
+ &_gcry_mac_type_spec_hmac_blake2s_224,
+ &_gcry_mac_type_spec_hmac_blake2s_160,
+ &_gcry_mac_type_spec_hmac_blake2s_128,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_SM3
+ &_gcry_mac_type_spec_hmac_sm3
+#else
+ NULL
+#endif
+ };
+
+/* CMAC implementations start with index 201 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo201[] =
+ {
+#if USE_AES
+ &_gcry_mac_type_spec_cmac_aes,
+#else
+ NULL,
+#endif
+#if USE_DES
+ &_gcry_mac_type_spec_cmac_tripledes,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_mac_type_spec_cmac_camellia,
+#else
+ NULL,
+#endif
+#if USE_CAST5
+ &_gcry_mac_type_spec_cmac_cast5,
+#else
+ NULL,
+#endif
+#if USE_BLOWFISH
+ &_gcry_mac_type_spec_cmac_blowfish,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_mac_type_spec_cmac_twofish,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_mac_type_spec_cmac_serpent,
+#else
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_mac_type_spec_cmac_seed,
+#else
+ NULL,
+#endif
+#if USE_RFC2268
+ &_gcry_mac_type_spec_cmac_rfc2268,
+#else
+ NULL,
+#endif
+#ifdef USE_IDEA
+ &_gcry_mac_type_spec_cmac_idea,
+#else
+ NULL,
+#endif
+#if USE_GOST28147
+ &_gcry_mac_type_spec_cmac_gost28147
+#else
+ NULL
+#endif
+ };
+
+/* GMAC implementations start with index 401 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo401[] =
+ {
+#if USE_AES
+ &_gcry_mac_type_spec_gmac_aes,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_mac_type_spec_gmac_camellia,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_mac_type_spec_gmac_twofish,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_mac_type_spec_gmac_serpent,
+#else
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_mac_type_spec_gmac_seed
+#else
+ NULL
+#endif
+ };
+
+/* Poly1305-MAC implementations start with index 501 (enum gcry_mac_algos) */
+static gcry_mac_spec_t * const mac_list_algo501[] =
+ {
+ &_gcry_mac_type_spec_poly1305mac,
+#if USE_AES
+ &_gcry_mac_type_spec_poly1305mac_aes,
+#else
+ NULL,
+#endif
+#if USE_CAMELLIA
+ &_gcry_mac_type_spec_poly1305mac_camellia,
+#else
+ NULL,
+#endif
+#if USE_TWOFISH
+ &_gcry_mac_type_spec_poly1305mac_twofish,
+#else
+ NULL,
+#endif
+#if USE_SERPENT
+ &_gcry_mac_type_spec_poly1305mac_serpent,
+#else
+ NULL,
+#endif
+#if USE_SEED
+ &_gcry_mac_type_spec_poly1305mac_seed
+#else
+ NULL
+#endif
+ };
+
+
+
+
/* Explicitly initialize this module. */
gcry_err_code_t
_gcry_mac_init (void)
@@ -154,13 +384,21 @@ _gcry_mac_init (void)
static gcry_mac_spec_t *
spec_from_algo (int algo)
{
- gcry_mac_spec_t *spec;
- int idx;
+ gcry_mac_spec_t *spec = NULL;
- for (idx = 0; (spec = mac_list[idx]); idx++)
- if (algo == spec->algo)
- return spec;
- return NULL;
+ if (algo >= 101 && algo < 101 + DIM(mac_list_algo101))
+ spec = mac_list_algo101[algo - 101];
+ else if (algo >= 201 && algo < 201 + DIM(mac_list_algo201))
+ spec = mac_list_algo201[algo - 201];
+ else if (algo >= 401 && algo < 401 + DIM(mac_list_algo401))
+ spec = mac_list_algo401[algo - 401];
+ else if (algo >= 501 && algo < 501 + DIM(mac_list_algo501))
+ spec = mac_list_algo501[algo - 501];
+
+ if (spec)
+ gcry_assert (spec->algo == algo);
+
+ return spec;
}
diff --git a/cipher/md.c b/cipher/md.c
index f6c1954c7..47c8cecdd 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -101,6 +101,143 @@ static gcry_md_spec_t * const digest_list[] =
NULL
};
+/* Digest implementations starting with index 0 (enum gcry_md_algos) */
+static gcry_md_spec_t * const digest_list_algo0[] =
+ {
+ NULL, /* GCRY_MD_NONE */
+#if USE_MD5
+ &_gcry_digest_spec_md5,
+#else
+ NULL,
+#endif
+#if USE_SHA1
+ &_gcry_digest_spec_sha1,
+#else
+ NULL,
+#endif
+#if USE_RMD160
+ &_gcry_digest_spec_rmd160,
+#else
+ NULL,
+#endif
+ NULL, /* Unused index 4 */
+#if USE_MD2
+ &_gcry_digest_spec_md2,
+#else
+ NULL,
+#endif
+#if USE_TIGER
+ &_gcry_digest_spec_tiger,
+#else
+ NULL,
+#endif
+ NULL, /* GCRY_MD_HAVAL */
+#if USE_SHA256
+ &_gcry_digest_spec_sha256,
+#else
+ NULL,
+#endif
+#if USE_SHA512
+ &_gcry_digest_spec_sha384,
+ &_gcry_digest_spec_sha512,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_SHA256
+ &_gcry_digest_spec_sha224
+#else
+ NULL
+#endif
+ };
+
+/* Digest implementations starting with index 301 (enum gcry_md_algos) */
+static gcry_md_spec_t * const digest_list_algo301[] =
+ {
+#if USE_MD4
+ &_gcry_digest_spec_md4,
+#else
+ NULL,
+#endif
+#if USE_CRC
+ &_gcry_digest_spec_crc32,
+ &_gcry_digest_spec_crc32_rfc1510,
+ &_gcry_digest_spec_crc24_rfc2440,
+#else
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_WHIRLPOOL
+ &_gcry_digest_spec_whirlpool,
+#else
+ NULL,
+#endif
+#if USE_TIGER
+ &_gcry_digest_spec_tiger1,
+ &_gcry_digest_spec_tiger2,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_GOST_R_3411_94
+ &_gcry_digest_spec_gost3411_94,
+#else
+ NULL,
+#endif
+#if USE_GOST_R_3411_12
+ &_gcry_digest_spec_stribog_256,
+ &_gcry_digest_spec_stribog_512,
+#else
+ NULL,
+ NULL,
+#endif
+#if USE_GOST_R_3411_94
+ &_gcry_digest_spec_gost3411_cp,
+#else
+ NULL,
+#endif
+#if USE_SHA3
+ &_gcry_digest_spec_sha3_224,
+ &_gcry_digest_spec_sha3_256,
+ &_gcry_digest_spec_sha3_384,
+ &_gcry_digest_spec_sha3_512,
+ &_gcry_digest_spec_shake128,
+ &_gcry_digest_spec_shake256,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_BLAKE2
+ &_gcry_digest_spec_blake2b_512,
+ &_gcry_digest_spec_blake2b_384,
+ &_gcry_digest_spec_blake2b_256,
+ &_gcry_digest_spec_blake2b_160,
+ &_gcry_digest_spec_blake2s_256,
+ &_gcry_digest_spec_blake2s_224,
+ &_gcry_digest_spec_blake2s_160,
+ &_gcry_digest_spec_blake2s_128,
+#else
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+#endif
+#if USE_SM3
+ &_gcry_digest_spec_sm3
+#else
+ NULL
+#endif
+ };
+
typedef struct gcry_md_list
{
@@ -118,7 +255,7 @@ struct gcry_md_context
size_t actual_handle_size; /* Allocated size of this handle. */
FILE *debug;
struct {
- unsigned int secure: 1;
+ unsigned int secure:1;
unsigned int finalized:1;
unsigned int bugemu1:1;
unsigned int hmac:1;
@@ -153,15 +290,19 @@ map_algo (int algo)
static gcry_md_spec_t *
spec_from_algo (int algo)
{
- int idx;
- gcry_md_spec_t *spec;
+ gcry_md_spec_t *spec = NULL;
algo = map_algo (algo);
- for (idx = 0; (spec = digest_list[idx]); idx++)
- if (algo == spec->algo)
- return spec;
- return NULL;
+ if (algo >= 0 && algo < DIM(digest_list_algo0))
+ spec = digest_list_algo0[algo];
+ else if (algo >= 301 && algo < 301 + DIM(digest_list_algo301))
+ spec = digest_list_algo301[algo - 301];
+
+ if (spec)
+ gcry_assert (spec->algo == algo);
+
+ return spec;
}
More information about the Gcrypt-devel
mailing list