]> err.no Git - linux-2.6/blobdiff - crypto/tcrypt.c
[CRYPTO] chainiv: Add chain IV generator
[linux-2.6] / crypto / tcrypt.c
index 1e12b86bc951c6e8b4fb90807b19c4374e77cec4..1142b4998c8443a4b48647c3a91bc69dcbf04256 100644 (file)
@@ -84,15 +84,14 @@ static char *check[] = {
        "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
        "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
        "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta",  "fcrypt",
-       "camellia", "seed", "salsa20", NULL
+       "camellia", "seed", "salsa20", "lzo", NULL
 };
 
 static void hexdump(unsigned char *buf, unsigned int len)
 {
-       while (len--)
-               printk("%02x", *buf++);
-
-       printk("\n");
+       print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
+                       16, 1,
+                       buf, len, false);
 }
 
 static void tcrypt_complete(struct crypto_async_request *req, int err)
@@ -236,6 +235,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
        struct scatterlist asg[8];
        const char *e;
        struct tcrypt_result result;
+       unsigned int authsize;
 
        if (enc == ENCRYPT)
                e = "encryption";
@@ -266,6 +266,8 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
                return;
        }
 
+       authsize = crypto_aead_authsize(tfm);
+
        req = aead_request_alloc(tfm, GFP_KERNEL);
        if (!req) {
                printk(KERN_INFO "failed to allocate request for %s\n", algo);
@@ -297,7 +299,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
                        }
 
                        sg_init_one(&sg[0], aead_tv[i].input,
-                                   aead_tv[i].ilen);
+                                   aead_tv[i].ilen + (enc ? authsize : 0));
 
                        sg_init_one(&asg[0], aead_tv[i].assoc,
                                    aead_tv[i].alen);
@@ -308,13 +310,9 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
 
                        aead_request_set_assoc(req, asg, aead_tv[i].alen);
 
-                       if (enc) {
-                               ret = crypto_aead_encrypt(req);
-                       } else {
-                               memcpy(req->__ctx, aead_tv[i].tag,
-                                      aead_tv[i].tlen);
-                               ret = crypto_aead_decrypt(req);
-                       }
+                       ret = enc ?
+                               crypto_aead_encrypt(req) :
+                               crypto_aead_decrypt(req);
 
                        switch (ret) {
                        case 0:
@@ -336,16 +334,10 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
 
                        q = kmap(sg_page(&sg[0])) + sg[0].offset;
                        hexdump(q, aead_tv[i].rlen);
-                       printk(KERN_INFO "auth tag: ");
-                       hexdump((unsigned char *)req->__ctx, aead_tv[i].tlen);
 
                        printk(KERN_INFO "enc/dec: %s\n",
                               memcmp(q, aead_tv[i].result,
                                      aead_tv[i].rlen) ? "fail" : "pass");
-
-                       printk(KERN_INFO "auth tag: %s\n",
-                              memcmp(req->__ctx, aead_tv[i].tag,
-                                     aead_tv[i].tlen) ? "fail" : "pass");
                }
        }
 
@@ -382,6 +374,9 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
                                           aead_tv[i].tap[k]);
                        }
 
+                       if (enc)
+                               sg[k - 1].length += authsize;
+
                        sg_init_table(asg, aead_tv[i].anp);
                        for (k = 0, temp = 0; k < aead_tv[i].anp; k++) {
                                memcpy(&axbuf[IDX[k]],
@@ -398,13 +393,9 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
 
                        aead_request_set_assoc(req, asg, aead_tv[i].alen);
 
-                       if (enc) {
-                               ret = crypto_aead_encrypt(req);
-                       } else {
-                               memcpy(req->__ctx, aead_tv[i].tag,
-                                      aead_tv[i].tlen);
-                               ret = crypto_aead_decrypt(req);
-                       }
+                       ret = enc ?
+                               crypto_aead_encrypt(req) :
+                               crypto_aead_decrypt(req);
 
                        switch (ret) {
                        case 0:
@@ -430,17 +421,13 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
                                hexdump(q, aead_tv[i].tap[k]);
                                printk(KERN_INFO "%s\n",
                                       memcmp(q, aead_tv[i].result + temp,
-                                             aead_tv[i].tap[k]) ?
+                                             aead_tv[i].tap[k] -
+                                             (k < aead_tv[i].np - 1 || enc ?
+                                              0 : authsize)) ?
                                       "fail" : "pass");
 
                                temp += aead_tv[i].tap[k];
                        }
-                       printk(KERN_INFO "auth tag: ");
-                       hexdump((unsigned char *)req->__ctx, aead_tv[i].tlen);
-
-                       printk(KERN_INFO "auth tag: %s\n",
-                              memcmp(req->__ctx, aead_tv[i].tag,
-                                     aead_tv[i].tlen) ? "fail" : "pass");
                }
        }
 
@@ -471,15 +458,11 @@ static void test_cipher(char *algo, int enc,
        printk("\ntesting %s %s\n", algo, e);
 
        tsize = sizeof (struct cipher_testvec);
-       tsize *= tcount;
-
        if (tsize > TVMEMSIZE) {
                printk("template (%u) too big for tvmem (%u)\n", tsize,
                       TVMEMSIZE);
                return;
        }
-
-       memcpy(tvmem, template, tsize);
        cipher_tv = (void *)tvmem;
 
        init_completion(&result.completion);
@@ -503,33 +486,34 @@ static void test_cipher(char *algo, int enc,
 
        j = 0;
        for (i = 0; i < tcount; i++) {
-               if (!(cipher_tv[i].np)) {
+               memcpy(cipher_tv, &template[i], tsize);
+               if (!(cipher_tv->np)) {
                        j++;
                        printk("test %u (%d bit key):\n",
-                       j, cipher_tv[i].klen * 8);
+                       j, cipher_tv->klen * 8);
 
                        crypto_ablkcipher_clear_flags(tfm, ~0);
-                       if (cipher_tv[i].wk)
+                       if (cipher_tv->wk)
                                crypto_ablkcipher_set_flags(
                                        tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-                       key = cipher_tv[i].key;
+                       key = cipher_tv->key;
 
                        ret = crypto_ablkcipher_setkey(tfm, key,
-                                                      cipher_tv[i].klen);
+                                                      cipher_tv->klen);
                        if (ret) {
                                printk("setkey() failed flags=%x\n",
                                       crypto_ablkcipher_get_flags(tfm));
 
-                               if (!cipher_tv[i].fail)
+                               if (!cipher_tv->fail)
                                        goto out;
                        }
 
-                       sg_init_one(&sg[0], cipher_tv[i].input,
-                                   cipher_tv[i].ilen);
+                       sg_init_one(&sg[0], cipher_tv->input,
+                                   cipher_tv->ilen);
 
                        ablkcipher_request_set_crypt(req, sg, sg,
-                                                    cipher_tv[i].ilen,
-                                                    cipher_tv[i].iv);
+                                                    cipher_tv->ilen,
+                                                    cipher_tv->iv);
 
                        ret = enc ?
                                crypto_ablkcipher_encrypt(req) :
@@ -553,11 +537,11 @@ static void test_cipher(char *algo, int enc,
                        }
 
                        q = kmap(sg_page(&sg[0])) + sg[0].offset;
-                       hexdump(q, cipher_tv[i].rlen);
+                       hexdump(q, cipher_tv->rlen);
 
                        printk("%s\n",
-                              memcmp(q, cipher_tv[i].result,
-                                     cipher_tv[i].rlen) ? "fail" : "pass");
+                              memcmp(q, cipher_tv->result,
+                                     cipher_tv->rlen) ? "fail" : "pass");
                }
        }
 
@@ -566,41 +550,42 @@ static void test_cipher(char *algo, int enc,
 
        j = 0;
        for (i = 0; i < tcount; i++) {
-               if (cipher_tv[i].np) {
+               memcpy(cipher_tv, &template[i], tsize);
+               if (cipher_tv->np) {
                        j++;
                        printk("test %u (%d bit key):\n",
-                       j, cipher_tv[i].klen * 8);
+                       j, cipher_tv->klen * 8);
 
                        crypto_ablkcipher_clear_flags(tfm, ~0);
-                       if (cipher_tv[i].wk)
+                       if (cipher_tv->wk)
                                crypto_ablkcipher_set_flags(
                                        tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-                       key = cipher_tv[i].key;
+                       key = cipher_tv->key;
 
                        ret = crypto_ablkcipher_setkey(tfm, key,
-                                                      cipher_tv[i].klen);
+                                                      cipher_tv->klen);
                        if (ret) {
                                printk("setkey() failed flags=%x\n",
                                       crypto_ablkcipher_get_flags(tfm));
 
-                               if (!cipher_tv[i].fail)
+                               if (!cipher_tv->fail)
                                        goto out;
                        }
 
                        temp = 0;
-                       sg_init_table(sg, cipher_tv[i].np);
-                       for (k = 0; k < cipher_tv[i].np; k++) {
+                       sg_init_table(sg, cipher_tv->np);
+                       for (k = 0; k < cipher_tv->np; k++) {
                                memcpy(&xbuf[IDX[k]],
-                                      cipher_tv[i].input + temp,
-                                      cipher_tv[i].tap[k]);
-                               temp += cipher_tv[i].tap[k];
+                                      cipher_tv->input + temp,
+                                      cipher_tv->tap[k]);
+                               temp += cipher_tv->tap[k];
                                sg_set_buf(&sg[k], &xbuf[IDX[k]],
-                                          cipher_tv[i].tap[k]);
+                                          cipher_tv->tap[k]);
                        }
 
                        ablkcipher_request_set_crypt(req, sg, sg,
-                                                    cipher_tv[i].ilen,
-                                                    cipher_tv[i].iv);
+                                                    cipher_tv->ilen,
+                                                    cipher_tv->iv);
 
                        ret = enc ?
                                crypto_ablkcipher_encrypt(req) :
@@ -624,15 +609,15 @@ static void test_cipher(char *algo, int enc,
                        }
 
                        temp = 0;
-                       for (k = 0; k < cipher_tv[i].np; k++) {
+                       for (k = 0; k < cipher_tv->np; k++) {
                                printk("page %u\n", k);
                                q = kmap(sg_page(&sg[k])) + sg[k].offset;
-                               hexdump(q, cipher_tv[i].tap[k]);
+                               hexdump(q, cipher_tv->tap[k]);
                                printk("%s\n",
-                                       memcmp(q, cipher_tv[i].result + temp,
-                                               cipher_tv[i].tap[k]) ? "fail" :
+                                       memcmp(q, cipher_tv->result + temp,
+                                               cipher_tv->tap[k]) ? "fail" :
                                        "pass");
-                               temp += cipher_tv[i].tap[k];
+                               temp += cipher_tv->tap[k];
                        }
                }
        }
@@ -1034,7 +1019,8 @@ out:
        crypto_free_hash(tfm);
 }
 
-static void test_deflate(void)
+static void test_comp(char *algo, struct comp_testvec *ctemplate,
+                      struct comp_testvec *dtemplate, int ctcount, int dtcount)
 {
        unsigned int i;
        char result[COMP_BUF_SIZE];
@@ -1042,25 +1028,26 @@ static void test_deflate(void)
        struct comp_testvec *tv;
        unsigned int tsize;
 
-       printk("\ntesting deflate compression\n");
+       printk("\ntesting %s compression\n", algo);
 
-       tsize = sizeof (deflate_comp_tv_template);
+       tsize = sizeof(struct comp_testvec);
+       tsize *= ctcount;
        if (tsize > TVMEMSIZE) {
                printk("template (%u) too big for tvmem (%u)\n", tsize,
                       TVMEMSIZE);
                return;
        }
 
-       memcpy(tvmem, deflate_comp_tv_template, tsize);
+       memcpy(tvmem, ctemplate, tsize);
        tv = (void *)tvmem;
 
-       tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC);
+       tfm = crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(tfm)) {
-               printk("failed to load transform for deflate\n");
+               printk("failed to load transform for %s\n", algo);
                return;
        }
 
-       for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) {
+       for (i = 0; i < ctcount; i++) {
                int ilen, ret, dlen = COMP_BUF_SIZE;
 
                printk("test %u:\n", i + 1);
@@ -1079,19 +1066,20 @@ static void test_deflate(void)
                       ilen, dlen);
        }
 
-       printk("\ntesting deflate decompression\n");
+       printk("\ntesting %s decompression\n", algo);
 
-       tsize = sizeof (deflate_decomp_tv_template);
+       tsize = sizeof(struct comp_testvec);
+       tsize *= dtcount;
        if (tsize > TVMEMSIZE) {
                printk("template (%u) too big for tvmem (%u)\n", tsize,
                       TVMEMSIZE);
                goto out;
        }
 
-       memcpy(tvmem, deflate_decomp_tv_template, tsize);
+       memcpy(tvmem, dtemplate, tsize);
        tv = (void *)tvmem;
 
-       for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
+       for (i = 0; i < dtcount; i++) {
                int ilen, ret, dlen = COMP_BUF_SIZE;
 
                printk("test %u:\n", i + 1);
@@ -1205,9 +1193,9 @@ static void do_test(void)
                            AES_XTS_ENC_TEST_VECTORS);
                test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
                            AES_XTS_DEC_TEST_VECTORS);
-               test_cipher("ctr(aes,4,8,4)", ENCRYPT, aes_ctr_enc_tv_template,
+               test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template,
                            AES_CTR_ENC_TEST_VECTORS);
-               test_cipher("ctr(aes,4,8,4)", DECRYPT, aes_ctr_dec_tv_template,
+               test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template,
                            AES_CTR_DEC_TEST_VECTORS);
                test_aead("gcm(aes)", ENCRYPT, aes_gcm_enc_tv_template,
                          AES_GCM_ENC_TEST_VECTORS);
@@ -1301,7 +1289,11 @@ static void do_test(void)
                test_hash("tgr192", tgr192_tv_template, TGR192_TEST_VECTORS);
                test_hash("tgr160", tgr160_tv_template, TGR160_TEST_VECTORS);
                test_hash("tgr128", tgr128_tv_template, TGR128_TEST_VECTORS);
-               test_deflate();
+               test_comp("deflate", deflate_comp_tv_template,
+                         deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS,
+                         DEFLATE_DECOMP_TEST_VECTORS);
+               test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template,
+                         LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS);
                test_hash("crc32c", crc32c_tv_template, CRC32C_TEST_VECTORS);
                test_hash("hmac(md5)", hmac_md5_tv_template,
                          HMAC_MD5_TEST_VECTORS);
@@ -1402,9 +1394,9 @@ static void do_test(void)
                            AES_XTS_ENC_TEST_VECTORS);
                test_cipher("xts(aes)", DECRYPT, aes_xts_dec_tv_template,
                            AES_XTS_DEC_TEST_VECTORS);
-               test_cipher("ctr(aes,4,8,4)", ENCRYPT, aes_ctr_enc_tv_template,
+               test_cipher("rfc3686(ctr(aes))", ENCRYPT, aes_ctr_enc_tv_template,
                            AES_CTR_ENC_TEST_VECTORS);
-               test_cipher("ctr(aes,4,8,4)", DECRYPT, aes_ctr_dec_tv_template,
+               test_cipher("rfc3686(ctr(aes))", DECRYPT, aes_ctr_dec_tv_template,
                            AES_CTR_DEC_TEST_VECTORS);
                break;
 
@@ -1417,7 +1409,9 @@ static void do_test(void)
                break;
 
        case 13:
-               test_deflate();
+               test_comp("deflate", deflate_comp_tv_template,
+                         deflate_decomp_tv_template, DEFLATE_COMP_TEST_VECTORS,
+                         DEFLATE_DECOMP_TEST_VECTORS);
                break;
 
        case 14:
@@ -1551,6 +1545,18 @@ static void do_test(void)
                            SALSA20_STREAM_ENC_TEST_VECTORS);
                break;
 
+       case 35:
+               test_aead("gcm(aes)", ENCRYPT, aes_gcm_enc_tv_template,
+                         AES_GCM_ENC_TEST_VECTORS);
+               test_aead("gcm(aes)", DECRYPT, aes_gcm_dec_tv_template,
+                         AES_GCM_DEC_TEST_VECTORS);
+               break;
+
+       case 36:
+               test_comp("lzo", lzo_comp_tv_template, lzo_decomp_tv_template,
+                         LZO_COMP_TEST_VECTORS, LZO_DECOMP_TEST_VECTORS);
+               break;
+
        case 100:
                test_hash("hmac(md5)", hmac_md5_tv_template,
                          HMAC_MD5_TEST_VECTORS);
@@ -1662,6 +1668,11 @@ static void do_test(void)
                                camellia_speed_template);
                break;
 
+       case 206:
+               test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0,
+                                 salsa20_speed_template);
+               break;
+
        case 300:
                /* fall through */