aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2014-08-17 11:37:34 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-08-25 08:34:07 -0400
commit72f3e00dd67ec449199a8844bc012a4fa1e0340a (patch)
treeb73c93435e7f60dd8064e6e73b83b974ecff0abe /crypto
parent4451d494b1910bf7b7f8381a637d0fe6d2142467 (diff)
crypto: drbg - replace int2byte with cpu_to_be
The DRBG requires the conversion of an integer into a string representation of that integer. The previous implementation converted the given integer byte-wise. However, the kernel offers the cpu_to_be function which already re-arranges the memory representation of an integer such that it applies when interpreting the same memory as character string. The change therefore uses an integer-cast / union of the target character array together with the cpu_to_be function to convert an integer into its string representation. Tests show that the Hash and CTR DRBG implementations (the HMAC DRBG does not require such conversion) is about 10% faster (or requires less computing power, respectively). Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/drbg.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 7894db9ca90b..d86c67792e61 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -302,20 +302,19 @@ static bool drbg_fips_continuous_test(struct drbg_state *drbg,
302 * Convert an integer into a byte representation of this integer. 302 * Convert an integer into a byte representation of this integer.
303 * The byte representation is big-endian 303 * The byte representation is big-endian
304 * 304 *
305 * @buf buffer holding the converted integer
306 * @val value to be converted 305 * @val value to be converted
307 * @buflen length of buffer 306 * @buf buffer holding the converted integer -- caller must ensure that
307 * buffer size is at least 32 bit
308 */ 308 */
309#if (defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_CTR)) 309#if (defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_CTR))
310static inline void drbg_int2byte(unsigned char *buf, uint64_t val, 310static inline void drbg_cpu_to_be32(__u32 val, unsigned char *buf)
311 size_t buflen)
312{ 311{
313 unsigned char *byte; 312 struct s {
314 uint64_t i; 313 __u32 conv;
314 };
315 struct s *conversion = (struct s *) buf;
315 316
316 byte = buf + (buflen - 1); 317 conversion->conv = cpu_to_be32(val);
317 for (i = 0; i < buflen; i++)
318 *(byte--) = val >> (i * 8) & 0xff;
319} 318}
320 319
321/* 320/*
@@ -483,10 +482,10 @@ static int drbg_ctr_df(struct drbg_state *drbg,
483 /* 10.4.2 step 2 -- calculate the entire length of all input data */ 482 /* 10.4.2 step 2 -- calculate the entire length of all input data */
484 list_for_each_entry(seed, seedlist, list) 483 list_for_each_entry(seed, seedlist, list)
485 inputlen += seed->len; 484 inputlen += seed->len;
486 drbg_int2byte(&L_N[0], inputlen, 4); 485 drbg_cpu_to_be32(inputlen, &L_N[0]);
487 486
488 /* 10.4.2 step 3 */ 487 /* 10.4.2 step 3 */
489 drbg_int2byte(&L_N[4], bytes_to_return, 4); 488 drbg_cpu_to_be32(bytes_to_return, &L_N[4]);
490 489
491 /* 10.4.2 step 5: length is L_N, input_string, one byte, padding */ 490 /* 10.4.2 step 5: length is L_N, input_string, one byte, padding */
492 padlen = (inputlen + sizeof(L_N) + 1) % (drbg_blocklen(drbg)); 491 padlen = (inputlen + sizeof(L_N) + 1) % (drbg_blocklen(drbg));
@@ -517,7 +516,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
517 * holds zeros after allocation -- even the increment of i 516 * holds zeros after allocation -- even the increment of i
518 * is irrelevant as the increment remains within length of i 517 * is irrelevant as the increment remains within length of i
519 */ 518 */
520 drbg_int2byte(iv, i, 4); 519 drbg_cpu_to_be32(i, iv);
521 /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ 520 /* 10.4.2 step 9.2 -- BCC and concatenation with temp */
522 ret = drbg_ctr_bcc(drbg, temp + templen, K, &bcc_list); 521 ret = drbg_ctr_bcc(drbg, temp + templen, K, &bcc_list);
523 if (ret) 522 if (ret)
@@ -862,7 +861,7 @@ static int drbg_hash_df(struct drbg_state *drbg,
862 861
863 /* 10.4.1 step 3 */ 862 /* 10.4.1 step 3 */
864 input[0] = 1; 863 input[0] = 1;
865 drbg_int2byte(&input[1], (outlen * 8), 4); 864 drbg_cpu_to_be32((outlen * 8), &input[1]);
866 865
867 /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ 866 /* 10.4.1 step 4.1 -- concatenation of data for input into hash */
868 drbg_string_fill(&data, input, 5); 867 drbg_string_fill(&data, input, 5);
@@ -1023,7 +1022,10 @@ static int drbg_hash_generate(struct drbg_state *drbg,
1023{ 1022{
1024 int len = 0; 1023 int len = 0;
1025 int ret = 0; 1024 int ret = 0;
1026 unsigned char req[8]; 1025 union {
1026 unsigned char req[8];
1027 __u64 req_int;
1028 } u;
1027 unsigned char prefix = DRBG_PREFIX3; 1029 unsigned char prefix = DRBG_PREFIX3;
1028 struct drbg_string data1, data2; 1030 struct drbg_string data1, data2;
1029 LIST_HEAD(datalist); 1031 LIST_HEAD(datalist);
@@ -1053,8 +1055,8 @@ static int drbg_hash_generate(struct drbg_state *drbg,
1053 drbg->scratchpad, drbg_blocklen(drbg)); 1055 drbg->scratchpad, drbg_blocklen(drbg));
1054 drbg_add_buf(drbg->V, drbg_statelen(drbg), 1056 drbg_add_buf(drbg->V, drbg_statelen(drbg),
1055 drbg->C, drbg_statelen(drbg)); 1057 drbg->C, drbg_statelen(drbg));
1056 drbg_int2byte(req, drbg->reseed_ctr, sizeof(req)); 1058 u.req_int = cpu_to_be64(drbg->reseed_ctr);
1057 drbg_add_buf(drbg->V, drbg_statelen(drbg), req, 8); 1059 drbg_add_buf(drbg->V, drbg_statelen(drbg), u.req, 8);
1058 1060
1059out: 1061out:
1060 memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); 1062 memset(drbg->scratchpad, 0, drbg_blocklen(drbg));