[CRYPTO] cipher: Added block ciphers for CBC/ECB
[powerpc.git] / crypto / tcrypt.c
index 49e344f..56d0d8b 100644 (file)
@@ -118,10 +118,7 @@ static void test_hash(char *algo, struct hash_testvec *template,
                sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
 
                crypto_digest_init(tfm);
-               if (tfm->crt_u.digest.dit_setkey) {
-                       crypto_digest_setkey(tfm, hash_tv[i].key,
-                                            hash_tv[i].ksize);
-               }
+               crypto_digest_setkey(tfm, hash_tv[i].key, hash_tv[i].ksize);
                crypto_digest_update(tfm, sg, 1);
                crypto_digest_final(tfm, result);
 
@@ -570,6 +567,122 @@ out:
        crypto_free_tfm(tfm);
 }
 
+static void test_digest_jiffies(struct crypto_tfm *tfm, char *p, int blen,
+                               int plen, char *out, int sec)
+{
+       struct scatterlist sg[1];
+       unsigned long start, end;
+       int bcount, pcount;
+
+       for (start = jiffies, end = start + sec * HZ, bcount = 0;
+            time_before(jiffies, end); bcount++) {
+               crypto_digest_init(tfm);
+               for (pcount = 0; pcount < blen; pcount += plen) {
+                       sg_set_buf(sg, p + pcount, plen);
+                       crypto_digest_update(tfm, sg, 1);
+               }
+               /* we assume there is enough space in 'out' for the result */
+               crypto_digest_final(tfm, out);
+       }
+
+       printk("%6u opers/sec, %9lu bytes/sec\n",
+              bcount / sec, ((long)bcount * blen) / sec);
+
+       return;
+}
+
+static void test_digest_cycles(struct crypto_tfm *tfm, char *p, int blen,
+                              int plen, char *out)
+{
+       struct scatterlist sg[1];
+       unsigned long cycles = 0;
+       int i, pcount;
+
+       local_bh_disable();
+       local_irq_disable();
+
+       /* Warm-up run. */
+       for (i = 0; i < 4; i++) {
+               crypto_digest_init(tfm);
+               for (pcount = 0; pcount < blen; pcount += plen) {
+                       sg_set_buf(sg, p + pcount, plen);
+                       crypto_digest_update(tfm, sg, 1);
+               }
+               crypto_digest_final(tfm, out);
+       }
+
+       /* The real thing. */
+       for (i = 0; i < 8; i++) {
+               cycles_t start, end;
+
+               crypto_digest_init(tfm);
+
+               start = get_cycles();
+
+               for (pcount = 0; pcount < blen; pcount += plen) {
+                       sg_set_buf(sg, p + pcount, plen);
+                       crypto_digest_update(tfm, sg, 1);
+               }
+               crypto_digest_final(tfm, out);
+
+               end = get_cycles();
+
+               cycles += end - start;
+       }
+
+       local_irq_enable();
+       local_bh_enable();
+
+       printk("%6lu cycles/operation, %4lu cycles/byte\n",
+              cycles / 8, cycles / (8 * blen));
+
+       return;
+}
+
+static void test_digest_speed(char *algo, unsigned int sec,
+                             struct digest_speed *speed)
+{
+       struct crypto_tfm *tfm;
+       char output[1024];
+       int i;
+
+       printk("\ntesting speed of %s\n", algo);
+
+       tfm = crypto_alloc_tfm(algo, 0);
+
+       if (tfm == NULL) {
+               printk("failed to load transform for %s\n", algo);
+               return;
+       }
+
+       if (crypto_tfm_alg_digestsize(tfm) > sizeof(output)) {
+               printk("digestsize(%u) > outputbuffer(%zu)\n",
+                      crypto_tfm_alg_digestsize(tfm), sizeof(output));
+               goto out;
+       }
+
+       for (i = 0; speed[i].blen != 0; i++) {
+               if (speed[i].blen > TVMEMSIZE) {
+                       printk("template (%u) too big for tvmem (%u)\n",
+                              speed[i].blen, TVMEMSIZE);
+                       goto out;
+               }
+
+               printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ",
+                      i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
+
+               memset(tvmem, 0xff, speed[i].blen);
+
+               if (sec)
+                       test_digest_jiffies(tfm, tvmem, speed[i].blen, speed[i].plen, output, sec);
+               else
+                       test_digest_cycles(tfm, tvmem, speed[i].blen, speed[i].plen, output);
+       }
+
+out:
+       crypto_free_tfm(tfm);
+}
+
 static void test_deflate(void)
 {
        unsigned int i;
@@ -649,104 +762,6 @@ out:
        crypto_free_tfm(tfm);
 }
 
-static void test_crc32c(void)
-{
-#define NUMVEC 6
-#define VECSIZE 40
-
-       int i, j, pass;
-       u32 crc;
-       u8 b, test_vec[NUMVEC][VECSIZE];
-       static u32 vec_results[NUMVEC] = {
-               0x0e2c157f, 0xe980ebf6, 0xde74bded,
-               0xd579c862, 0xba979ad0, 0x2b29d913
-       };
-       static u32 tot_vec_results = 0x24c5d375;
-
-       struct scatterlist sg[NUMVEC];
-       struct crypto_tfm *tfm;
-       char *fmtdata = "testing crc32c initialized to %08x: %s\n";
-#define SEEDTESTVAL 0xedcba987
-       u32 seed;
-
-       printk("\ntesting crc32c\n");
-
-       tfm = crypto_alloc_tfm("crc32c", 0);
-       if (tfm == NULL) {
-               printk("failed to load transform for crc32c\n");
-               return;
-       }
-
-       crypto_digest_init(tfm);
-       crypto_digest_final(tfm, (u8*)&crc);
-       printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
-
-       /*
-        * stuff test_vec with known values, simple incrementing
-        * byte values.
-        */
-       b = 0;
-       for (i = 0; i < NUMVEC; i++) {
-               for (j = 0; j < VECSIZE; j++)
-                       test_vec[i][j] = ++b;
-               sg_set_buf(&sg[i], test_vec[i], VECSIZE);
-       }
-
-       seed = SEEDTESTVAL;
-       (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
-       crypto_digest_final(tfm, (u8*)&crc);
-       printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ?
-              "pass" : "ERROR");
-
-       printk("testing crc32c using update/final:\n");
-
-       pass = 1;                   /* assume all is well */
-
-       for (i = 0; i < NUMVEC; i++) {
-               seed = ~(u32)0;
-               (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
-               crypto_digest_update(tfm, &sg[i], 1);
-               crypto_digest_final(tfm, (u8*)&crc);
-               if (crc == vec_results[i]) {
-                       printk(" %08x:OK", crc);
-               } else {
-                       printk(" %08x:BAD, wanted %08x\n", crc, vec_results[i]);
-                       pass = 0;
-               }
-       }
-
-       printk("\ntesting crc32c using incremental accumulator:\n");
-       crc = 0;
-       for (i = 0; i < NUMVEC; i++) {
-               seed = (crc ^ ~(u32)0);
-               (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
-               crypto_digest_update(tfm, &sg[i], 1);
-               crypto_digest_final(tfm, (u8*)&crc);
-       }
-       if (crc == tot_vec_results) {
-               printk(" %08x:OK", crc);
-       } else {
-               printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
-               pass = 0;
-       }
-
-       printk("\ntesting crc32c using digest:\n");
-       seed = ~(u32)0;
-       (void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
-       crypto_digest_digest(tfm, sg, NUMVEC, (u8*)&crc);
-       if (crc == tot_vec_results) {
-               printk(" %08x:OK", crc);
-       } else {
-               printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
-               pass = 0;
-       }
-
-       printk("\n%s\n", pass ? "pass" : "ERROR");
-
-       crypto_free_tfm(tfm);
-       printk("crc32c test complete\n");
-}
-
 static void test_available(void)
 {
        char **name = check;
@@ -852,7 +867,7 @@ static void do_test(void)
                test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
                test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
                test_deflate();
-               test_crc32c();
+               test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
 #ifdef CONFIG_CRYPTO_HMAC
                test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
                test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
@@ -948,7 +963,7 @@ static void do_test(void)
                break;
 
        case 18:
-               test_crc32c();
+               test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
                break;
 
        case 19:
@@ -1086,6 +1101,60 @@ static void do_test(void)
                                  des_speed_template);
                break;
 
+       case 300:
+               /* fall through */
+
+       case 301:
+               test_digest_speed("md4", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 302:
+               test_digest_speed("md5", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 303:
+               test_digest_speed("sha1", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 304:
+               test_digest_speed("sha256", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 305:
+               test_digest_speed("sha384", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 306:
+               test_digest_speed("sha512", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 307:
+               test_digest_speed("wp256", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 308:
+               test_digest_speed("wp384", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 309:
+               test_digest_speed("wp512", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 310:
+               test_digest_speed("tgr128", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 311:
+               test_digest_speed("tgr160", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 312:
+               test_digest_speed("tgr192", sec, generic_digest_speed_template);
+               if (mode > 300 && mode < 400) break;
+
+       case 399:
+               break;
+
        case 1000:
                test_available();
                break;
@@ -1113,7 +1182,14 @@ static int __init init(void)
 
        kfree(xbuf);
        kfree(tvmem);
-       return 0;
+
+       /* We intentionaly return -EAGAIN to prevent keeping
+        * the module. It does all its work from init()
+        * and doesn't offer any runtime functionality 
+        * => we don't need it in the memory, do we?
+        *                                        -- mludvig
+        */
+       return -EAGAIN;
 }
 
 /*