/* * Quick & dirty crypto testing module. * * This will only exist until we have a better testing mechanism * (e.g. a char device). * * Copyright (c) 2002 James Morris * Copyright (c) 2002 Jean-Francois Dive * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * */ #include #include #include #include #include #include #include #include #include #include "tcrypt.h" /* * Need to kmalloc() memory for testing kmap(). */ #define TVMEMSIZE 4096 #define XBUFSIZE 32768 /* * Indexes into the xbuf to simulate cross-page access. */ #define IDX1 37 #define IDX2 32400 #define IDX3 1 #define IDX4 8193 #define IDX5 22222 #define IDX6 17101 #define IDX7 27333 #define IDX8 3000 static int mode = 0; static char *xbuf; static char *tvmem; static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "deflate", NULL }; static void hexdump(unsigned char *buf, unsigned int len) { while (len--) printk("%02x", *buf++); printk("\n"); } static void test_md5(void) { char *p; unsigned int i; struct scatterlist sg[2]; char result[128]; struct crypto_tfm *tfm; struct md5_testvec *md5_tv; unsigned int tsize; printk("\ntesting md5\n"); tsize = sizeof (md5_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, md5_tv_template, tsize); md5_tv = (void *) tvmem; tfm = crypto_alloc_tfm("md5", 0); if (tfm == NULL) { printk("failed to load transform for md5\n"); return; } for (i = 0; i < MD5_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = md5_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(md5_tv[i].plaintext); crypto_digest_init(tfm); crypto_digest_update(tfm, sg, 1); crypto_digest_final(tfm, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, md5_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } printk("\ntesting md5 across pages\n"); /* setup the dummy buffer first */ memset(xbuf, 0, XBUFSIZE); memcpy(&xbuf[IDX1], "abcdefghijklm", 13); memcpy(&xbuf[IDX2], "nopqrstuvwxyz", 13); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 13; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 13; memset(result, 0, sizeof (result)); crypto_digest_digest(tfm, sg, 2, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, md5_tv[4].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); crypto_free_tfm(tfm); } #ifdef CONFIG_CRYPTO_HMAC static void test_hmac_md5(void) { char *p; unsigned int i, klen; struct scatterlist sg[2]; char result[128]; struct crypto_tfm *tfm; struct hmac_md5_testvec *hmac_md5_tv; unsigned int tsize; tfm = crypto_alloc_tfm("md5", 0); if (tfm == NULL) { printk("failed to load transform for md5\n"); return; } printk("\ntesting hmac_md5\n"); tsize = sizeof (hmac_md5_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, hmac_md5_tv_template, tsize); hmac_md5_tv = (void *) tvmem; for (i = 0; i < HMAC_MD5_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = hmac_md5_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(hmac_md5_tv[i].plaintext); klen = strlen(hmac_md5_tv[i].key); crypto_hmac(tfm, hmac_md5_tv[i].key, &klen, sg, 1, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, hmac_md5_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } printk("\ntesting hmac_md5 across pages\n"); memset(xbuf, 0, XBUFSIZE); memcpy(&xbuf[IDX1], "what do ya want ", 16); memcpy(&xbuf[IDX2], "for nothing?", 12); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 16; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 12; memset(result, 0, sizeof (result)); klen = strlen(hmac_md5_tv[7].key); crypto_hmac(tfm, hmac_md5_tv[7].key, &klen, sg, 2, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, hmac_md5_tv[7].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); out: crypto_free_tfm(tfm); } static void test_hmac_sha1(void) { char *p; unsigned int i, klen; struct crypto_tfm *tfm; struct hmac_sha1_testvec *hmac_sha1_tv; struct scatterlist sg[2]; unsigned int tsize; char result[SHA1_DIGEST_SIZE]; tfm = crypto_alloc_tfm("sha1", 0); if (tfm == NULL) { printk("failed to load transform for sha1\n"); return; } printk("\ntesting hmac_sha1\n"); tsize = sizeof (hmac_sha1_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, hmac_sha1_tv_template, tsize); hmac_sha1_tv = (void *) tvmem; for (i = 0; i < HMAC_SHA1_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = hmac_sha1_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(hmac_sha1_tv[i].plaintext); klen = strlen(hmac_sha1_tv[i].key); crypto_hmac(tfm, hmac_sha1_tv[i].key, &klen, sg, 1, result); hexdump(result, sizeof (result)); printk("%s\n", memcmp(result, hmac_sha1_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } printk("\ntesting hmac_sha1 across pages\n"); /* setup the dummy buffer first */ memset(xbuf, 0, XBUFSIZE); memcpy(&xbuf[IDX1], "what do ya want ", 16); memcpy(&xbuf[IDX2], "for nothing?", 12); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 16; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 12; memset(result, 0, sizeof (result)); klen = strlen(hmac_sha1_tv[7].key); crypto_hmac(tfm, hmac_sha1_tv[7].key, &klen, sg, 2, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, hmac_sha1_tv[7].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); out: crypto_free_tfm(tfm); } static void test_hmac_sha256(void) { char *p; unsigned int i, klen; struct crypto_tfm *tfm; struct hmac_sha256_testvec *hmac_sha256_tv; struct scatterlist sg[2]; unsigned int tsize; char result[SHA256_DIGEST_SIZE]; tfm = crypto_alloc_tfm("sha256", 0); if (tfm == NULL) { printk("failed to load transform for sha256\n"); return; } printk("\ntesting hmac_sha256\n"); tsize = sizeof (hmac_sha256_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, hmac_sha256_tv_template, tsize); hmac_sha256_tv = (void *) tvmem; for (i = 0; i < HMAC_SHA256_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = hmac_sha256_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(hmac_sha256_tv[i].plaintext); klen = strlen(hmac_sha256_tv[i].key); hexdump(hmac_sha256_tv[i].key, strlen(hmac_sha256_tv[i].key)); crypto_hmac(tfm, hmac_sha256_tv[i].key, &klen, sg, 1, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, hmac_sha256_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } out: crypto_free_tfm(tfm); } #endif /* CONFIG_CRYPTO_HMAC */ static void test_md4(void) { char *p; unsigned int i; struct scatterlist sg[1]; char result[128]; struct crypto_tfm *tfm; struct md4_testvec *md4_tv; unsigned int tsize; printk("\ntesting md4\n"); tsize = sizeof (md4_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, md4_tv_template, tsize); md4_tv = (void *) tvmem; tfm = crypto_alloc_tfm("md4", 0); if (tfm == NULL) { printk("failed to load transform for md4\n"); return; } for (i = 0; i < MD4_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = md4_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(md4_tv[i].plaintext); crypto_digest_digest(tfm, sg, 1, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, md4_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } crypto_free_tfm(tfm); } static void test_sha1(void) { char *p; unsigned int i; struct crypto_tfm *tfm; struct sha1_testvec *sha1_tv; struct scatterlist sg[2]; unsigned int tsize; char result[SHA1_DIGEST_SIZE]; printk("\ntesting sha1\n"); tsize = sizeof (sha1_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, sha1_tv_template, tsize); sha1_tv = (void *) tvmem; tfm = crypto_alloc_tfm("sha1", 0); if (tfm == NULL) { printk("failed to load transform for sha1\n"); return; } for (i = 0; i < SHA1_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = sha1_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(sha1_tv[i].plaintext); crypto_digest_init(tfm); crypto_digest_update(tfm, sg, 1); crypto_digest_final(tfm, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, sha1_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } printk("\ntesting sha1 across pages\n"); /* setup the dummy buffer first */ memset(xbuf, 0, XBUFSIZE); memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 28; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 28; memset(result, 0, sizeof (result)); crypto_digest_digest(tfm, sg, 2, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, sha1_tv[1].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); crypto_free_tfm(tfm); } static void test_sha256(void) { char *p; unsigned int i; struct crypto_tfm *tfm; struct sha256_testvec *sha256_tv; struct scatterlist sg[2]; unsigned int tsize; char result[SHA256_DIGEST_SIZE]; printk("\ntesting sha256\n"); tsize = sizeof (sha256_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, sha256_tv_template, tsize); sha256_tv = (void *) tvmem; tfm = crypto_alloc_tfm("sha256", 0); if (tfm == NULL) { printk("failed to load transform for sha256\n"); return; } for (i = 0; i < SHA256_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = sha256_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(sha256_tv[i].plaintext); crypto_digest_init(tfm); crypto_digest_update(tfm, sg, 1); crypto_digest_final(tfm, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, sha256_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } printk("\ntesting sha256 across pages\n"); /* setup the dummy buffer first */ memset(xbuf, 0, XBUFSIZE); memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 28; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 28; memset(result, 0, sizeof (result)); crypto_digest_digest(tfm, sg, 2, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, sha256_tv[1].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); crypto_free_tfm(tfm); } static void test_sha384(void) { char *p; unsigned int i; struct crypto_tfm *tfm; struct sha384_testvec *sha384_tv; struct scatterlist sg[2]; unsigned int tsize; char result[SHA384_DIGEST_SIZE]; printk("\ntesting sha384\n"); tsize = sizeof (sha384_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, sha384_tv_template, tsize); sha384_tv = (void *) tvmem; tfm = crypto_alloc_tfm("sha384", 0); if (tfm == NULL) { printk("failed to load transform for sha384\n"); return; } for (i = 0; i < SHA384_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = sha384_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(sha384_tv[i].plaintext); crypto_digest_init(tfm); crypto_digest_update(tfm, sg, 1); crypto_digest_final(tfm, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, sha384_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } crypto_free_tfm(tfm); } static void test_sha512(void) { char *p; unsigned int i; struct crypto_tfm *tfm; struct sha512_testvec *sha512_tv; struct scatterlist sg[2]; unsigned int tsize; char result[SHA512_DIGEST_SIZE]; printk("\ntesting sha512\n"); tsize = sizeof (sha512_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, sha512_tv_template, tsize); sha512_tv = (void *) tvmem; tfm = crypto_alloc_tfm("sha512", 0); if (tfm == NULL) { printk("failed to load transform for sha512\n"); return; } for (i = 0; i < SHA512_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); p = sha512_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = strlen(sha512_tv[i].plaintext); crypto_digest_init(tfm); crypto_digest_update(tfm, sg, 1); crypto_digest_final(tfm, result); hexdump(result, crypto_tfm_alg_digestsize(tfm)); printk("%s\n", memcmp(result, sha512_tv[i].digest, crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass"); } crypto_free_tfm(tfm); } void test_des(void) { unsigned int ret, i, len; unsigned int tsize; char *p, *q; struct crypto_tfm *tfm; char *key; char res[8]; struct des_tv *des_tv; struct scatterlist sg[8]; printk("\ntesting des encryption\n"); tsize = sizeof (des_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, des_enc_tv_template, tsize); des_tv = (void *) tvmem; tfm = crypto_alloc_tfm("des", 0); if (tfm == NULL) { printk("failed to load transform for des (default ecb)\n"); return; } for (i = 0; i < DES_ENC_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); key = des_tv[i].key; tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!des_tv[i].fail) goto out; } len = des_tv[i].len; p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, len); printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); } printk("\ntesting des ecb encryption across pages\n"); i = 5; key = des_tv[i].key; tfm->crt_flags = 0; hexdump(key, 8); ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8); memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 8; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 8; ret = crypto_cipher_encrypt(tfm, sg, sg, 16); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 8); printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 8); printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); printk("\ntesting des ecb encryption chunking scenario A\n"); /* * Scenario A: * * F1 F2 F3 * [8 + 6] [2 + 8] [8] * ^^^^^^ ^ * a b c * * Chunking should begin at a, then end with b, and * continue encrypting at an offset of 2 until c. * */ i = 7; key = des_tv[i].key; tfm->crt_flags = 0; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); /* Frag 1: 8 + 6 */ memcpy(&xbuf[IDX3], des_tv[i].plaintext, 14); /* Frag 2: 2 + 8 */ memcpy(&xbuf[IDX4], des_tv[i].plaintext + 14, 10); /* Frag 3: 8 */ memcpy(&xbuf[IDX5], des_tv[i].plaintext + 24, 8); p = &xbuf[IDX3]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 14; p = &xbuf[IDX4]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 10; p = &xbuf[IDX5]; sg[2].page = virt_to_page(p); sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 8; ret = crypto_cipher_encrypt(tfm, sg, sg, 32); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 14); printk("%s\n", memcmp(q, des_tv[i].result, 14) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 10); printk("%s\n", memcmp(q, des_tv[i].result + 14, 10) ? "fail" : "pass"); printk("page 3\n"); q = kmap(sg[2].page) + sg[2].offset; hexdump(q, 8); printk("%s\n", memcmp(q, des_tv[i].result + 24, 8) ? "fail" : "pass"); printk("\ntesting des ecb encryption chunking scenario B\n"); /* * Scenario B: * * F1 F2 F3 F4 * [2] [1] [3] [2 + 8 + 8] */ i = 7; key = des_tv[i].key; tfm->crt_flags = 0; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); /* Frag 1: 2 */ memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2); /* Frag 2: 1 */ memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 1); /* Frag 3: 3 */ memcpy(&xbuf[IDX5], des_tv[i].plaintext + 3, 3); /* Frag 4: 2 + 8 + 8 */ memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 18); p = &xbuf[IDX3]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 2; p = &xbuf[IDX4]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 1; p = &xbuf[IDX5]; sg[2].page = virt_to_page(p); sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 3; p = &xbuf[IDX6]; sg[3].page = virt_to_page(p); sg[3].offset = ((long) p & ~PAGE_MASK); sg[3].length = 18; ret = crypto_cipher_encrypt(tfm, sg, sg, 24); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 2); printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 1); printk("%s\n", memcmp(q, des_tv[i].result + 2, 1) ? "fail" : "pass"); printk("page 3\n"); q = kmap(sg[2].page) + sg[2].offset; hexdump(q, 3); printk("%s\n", memcmp(q, des_tv[i].result + 3, 3) ? "fail" : "pass"); printk("page 4\n"); q = kmap(sg[3].page) + sg[3].offset; hexdump(q, 18); printk("%s\n", memcmp(q, des_tv[i].result + 6, 18) ? "fail" : "pass"); printk("\ntesting des ecb encryption chunking scenario C\n"); /* * Scenario B: * * F1 F2 F3 F4 F5 * [2] [2] [2] [2] [8] */ i = 7; key = des_tv[i].key; tfm->crt_flags = 0; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); /* Frag 1: 2 */ memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2); /* Frag 2: 2 */ memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 2); /* Frag 3: 2 */ memcpy(&xbuf[IDX5], des_tv[i].plaintext + 4, 2); /* Frag 4: 2 */ memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 2); /* Frag 5: 8 */ memcpy(&xbuf[IDX7], des_tv[i].plaintext + 8, 8); p = &xbuf[IDX3]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 2; p = &xbuf[IDX4]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 2; p = &xbuf[IDX5]; sg[2].page = virt_to_page(p); sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 2; p = &xbuf[IDX6]; sg[3].page = virt_to_page(p); sg[3].offset = ((long) p & ~PAGE_MASK); sg[3].length = 2; p = &xbuf[IDX7]; sg[4].page = virt_to_page(p); sg[4].offset = ((long) p & ~PAGE_MASK); sg[4].length = 8; ret = crypto_cipher_encrypt(tfm, sg, sg, 16); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 2); printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 2); printk("%s\n", memcmp(q, des_tv[i].result + 2, 2) ? "fail" : "pass"); printk("page 3\n"); q = kmap(sg[2].page) + sg[2].offset; hexdump(q, 2); printk("%s\n", memcmp(q, des_tv[i].result + 4, 2) ? "fail" : "pass"); printk("page 4\n"); q = kmap(sg[3].page) + sg[3].offset; hexdump(q, 2); printk("%s\n", memcmp(q, des_tv[i].result + 6, 2) ? "fail" : "pass"); printk("page 5\n"); q = kmap(sg[4].page) + sg[4].offset; hexdump(q, 8); printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); printk("\ntesting des ecb encryption chunking scenario D\n"); /* * Scenario D, torture test, one byte per frag. */ i = 7; key = des_tv[i].key; tfm->crt_flags = 0; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, XBUFSIZE); xbuf[IDX1] = des_tv[i].plaintext[0]; xbuf[IDX2] = des_tv[i].plaintext[1]; xbuf[IDX3] = des_tv[i].plaintext[2]; xbuf[IDX4] = des_tv[i].plaintext[3]; xbuf[IDX5] = des_tv[i].plaintext[4]; xbuf[IDX6] = des_tv[i].plaintext[5]; xbuf[IDX7] = des_tv[i].plaintext[6]; xbuf[IDX8] = des_tv[i].plaintext[7]; p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 1; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 1; p = &xbuf[IDX3]; sg[2].page = virt_to_page(p); sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 1; p = &xbuf[IDX4]; sg[3].page = virt_to_page(p); sg[3].offset = ((long) p & ~PAGE_MASK); sg[3].length = 1; p = &xbuf[IDX5]; sg[4].page = virt_to_page(p); sg[4].offset = ((long) p & ~PAGE_MASK); sg[4].length = 1; p = &xbuf[IDX6]; sg[5].page = virt_to_page(p); sg[5].offset = ((long) p & ~PAGE_MASK); sg[5].length = 1; p = &xbuf[IDX7]; sg[6].page = virt_to_page(p); sg[6].offset = ((long) p & ~PAGE_MASK); sg[6].length = 1; p = &xbuf[IDX8]; sg[7].page = virt_to_page(p); sg[7].offset = ((long) p & ~PAGE_MASK); sg[7].length = 1; ret = crypto_cipher_encrypt(tfm, sg, sg, 8); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } for (i = 0; i < 8; i++) res[i] = *(char *) (kmap(sg[i].page) + sg[i].offset); hexdump(res, 8); printk("%s\n", memcmp(res, des_tv[7].result, 8) ? "fail" : "pass"); printk("\ntesting des decryption\n"); tsize = sizeof (des_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, des_dec_tv_template, tsize); des_tv = (void *) tvmem; for (i = 0; i < DES_DEC_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); key = des_tv[i].key; tfm->crt_flags = 0; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } len = des_tv[i].len; p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("des_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, len); printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); } printk("\ntesting des ecb decryption across pages\n"); i = 6; key = des_tv[i].key; tfm->crt_flags = 0; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8); memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 8; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 8; ret = crypto_cipher_decrypt(tfm, sg, sg, 16); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 8); printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 8); printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass"); /* * Scenario E: * * F1 F2 F3 * [3] [5 + 7] [1] * */ printk("\ntesting des ecb decryption chunking scenario E\n"); i = 2; key = des_tv[i].key; tfm->crt_flags = 0; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); memcpy(&xbuf[IDX1], des_tv[i].plaintext, 3); memcpy(&xbuf[IDX2], des_tv[i].plaintext + 3, 12); memcpy(&xbuf[IDX3], des_tv[i].plaintext + 15, 1); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 3; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 12; p = &xbuf[IDX3]; sg[2].page = virt_to_page(p); sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 1; ret = crypto_cipher_decrypt(tfm, sg, sg, 16); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 3); printk("%s\n", memcmp(q, des_tv[i].result, 3) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 12); printk("%s\n", memcmp(q, des_tv[i].result + 3, 12) ? "fail" : "pass"); printk("page 3\n"); q = kmap(sg[2].page) + sg[2].offset; hexdump(q, 1); printk("%s\n", memcmp(q, des_tv[i].result + 15, 1) ? "fail" : "pass"); crypto_free_tfm(tfm); tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC); if (tfm == NULL) { printk("failed to load transform for des cbc\n"); return; } printk("\ntesting des cbc encryption\n"); tsize = sizeof (des_cbc_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, des_cbc_enc_tv_template, tsize); des_tv = (void *) tvmem; crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); crypto_cipher_get_iv(tfm, res, crypto_tfm_alg_ivsize(tfm)); if (memcmp(res, des_tv[i].iv, sizeof(res))) { printk("crypto_cipher_[set|get]_iv() failed\n"); goto out; } for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); key = des_tv[i].key; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } len = des_tv[i].len; p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("des_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, len); printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); } crypto_free_tfm(tfm); /* * Scenario F: * * F1 F2 * [8 + 5] [3 + 8] * */ printk("\ntesting des cbc encryption chunking scenario F\n"); i = 4; tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC); if (tfm == NULL) { printk("failed to load transform for CRYPTO_ALG_DES_CCB\n"); return; } tfm->crt_flags = 0; key = des_tv[i].key; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); memcpy(&xbuf[IDX1], des_tv[i].plaintext, 13); memcpy(&xbuf[IDX2], des_tv[i].plaintext + 13, 11); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 13; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 11; crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); ret = crypto_cipher_encrypt(tfm, sg, sg, 24); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 13); printk("%s\n", memcmp(q, des_tv[i].result, 13) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 11); printk("%s\n", memcmp(q, des_tv[i].result + 13, 11) ? "fail" : "pass"); tsize = sizeof (des_cbc_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, des_cbc_dec_tv_template, tsize); des_tv = (void *) tvmem; printk("\ntesting des cbc decryption\n"); for (i = 0; i < DES_CBC_DEC_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); tfm->crt_flags = 0; key = des_tv[i].key; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } len = des_tv[i].len; p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_blocksize(tfm)); ret = crypto_cipher_decrypt(tfm, sg, sg, len); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } hexdump(tfm->crt_cipher.cit_iv, 8); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, len); printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); } /* * Scenario G: * * F1 F2 * [4] [4] * */ printk("\ntesting des cbc decryption chunking scenario G\n"); i = 3; tfm->crt_flags = 0; key = des_tv[i].key; ret = crypto_cipher_setkey(tfm, key, 8); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } /* setup the dummy buffer first */ memset(xbuf, 0, sizeof (xbuf)); memcpy(&xbuf[IDX1], des_tv[i].plaintext, 4); memcpy(&xbuf[IDX2], des_tv[i].plaintext + 4, 4); p = &xbuf[IDX1]; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = 4; p = &xbuf[IDX2]; sg[1].page = virt_to_page(p); sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 4; crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); ret = crypto_cipher_decrypt(tfm, sg, sg, 8); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } printk("page 1\n"); q = kmap(sg[0].page) + sg[0].offset; hexdump(q, 4); printk("%s\n", memcmp(q, des_tv[i].result, 4) ? "fail" : "pass"); printk("page 2\n"); q = kmap(sg[1].page) + sg[1].offset; hexdump(q, 4); printk("%s\n", memcmp(q, des_tv[i].result + 4, 4) ? "fail" : "pass"); out: crypto_free_tfm(tfm); } void test_des3_ede(void) { unsigned int ret, i, len; unsigned int tsize; char *p, *q; struct crypto_tfm *tfm; char *key; /*char res[8]; */ struct des_tv *des_tv; struct scatterlist sg[8]; printk("\ntesting des3 ede encryption\n"); tsize = sizeof (des3_ede_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, des3_ede_enc_tv_template, tsize); des_tv = (void *) tvmem; tfm = crypto_alloc_tfm("des3_ede", CRYPTO_TFM_MODE_ECB); if (tfm == NULL) { printk("failed to load transform for 3des ecb\n"); return; } for (i = 0; i < DES3_EDE_ENC_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); key = des_tv[i].key; ret = crypto_cipher_setkey(tfm, key, 24); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!des_tv[i].fail) goto out; } len = des_tv[i].len; p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, len); printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); } printk("\ntesting des3 ede decryption\n"); tsize = sizeof (des3_ede_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, des3_ede_dec_tv_template, tsize); des_tv = (void *) tvmem; for (i = 0; i < DES3_EDE_DEC_TEST_VECTORS; i++) { printk("test %u:\n", i + 1); key = des_tv[i].key; ret = crypto_cipher_setkey(tfm, key, 24); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!des_tv[i].fail) goto out; } len = des_tv[i].len; p = des_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; ret = crypto_cipher_decrypt(tfm, sg, sg, len); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, len); printk("%s\n", memcmp(q, des_tv[i].result, len) ? "fail" : "pass"); } out: crypto_free_tfm(tfm); } void test_blowfish(void) { unsigned int ret, i; unsigned int tsize; char *p, *q; struct crypto_tfm *tfm; char *key; struct bf_tv *bf_tv; struct scatterlist sg[1]; printk("\ntesting blowfish encryption\n"); tsize = sizeof (bf_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, bf_enc_tv_template, tsize); bf_tv = (void *) tvmem; tfm = crypto_alloc_tfm("blowfish", 0); if (tfm == NULL) { printk("failed to load transform for blowfish (default ecb)\n"); return; } for (i = 0; i < BF_ENC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, bf_tv[i].keylen * 8); key = bf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!bf_tv[i].fail) goto out; } p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, bf_tv[i].rlen); printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? "fail" : "pass"); } printk("\ntesting blowfish decryption\n"); tsize = sizeof (bf_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, bf_dec_tv_template, tsize); bf_tv = (void *) tvmem; for (i = 0; i < BF_DEC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, bf_tv[i].keylen * 8); key = bf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!bf_tv[i].fail) goto out; } p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, bf_tv[i].rlen); printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? "fail" : "pass"); } crypto_free_tfm(tfm); tfm = crypto_alloc_tfm("blowfish", CRYPTO_TFM_MODE_CBC); if (tfm == NULL) { printk("failed to load transform for blowfish cbc\n"); return; } printk("\ntesting blowfish cbc encryption\n"); tsize = sizeof (bf_cbc_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, bf_cbc_enc_tv_template, tsize); bf_tv = (void *) tvmem; for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, bf_tv[i].keylen * 8); key = bf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; crypto_cipher_set_iv(tfm, bf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, bf_tv[i].rlen); printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? "fail" : "pass"); } printk("\ntesting blowfish cbc decryption\n"); tsize = sizeof (bf_cbc_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, bf_cbc_dec_tv_template, tsize); bf_tv = (void *) tvmem; for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, bf_tv[i].keylen * 8); key = bf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } p = bf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; crypto_cipher_set_iv(tfm, bf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, bf_tv[i].rlen); printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ? "fail" : "pass"); } out: crypto_free_tfm(tfm); } void test_twofish(void) { unsigned int ret, i; unsigned int tsize; char *p, *q; struct crypto_tfm *tfm; char *key; struct tf_tv *tf_tv; struct scatterlist sg[1]; printk("\ntesting twofish encryption\n"); tsize = sizeof (tf_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, tf_enc_tv_template, tsize); tf_tv = (void *) tvmem; tfm = crypto_alloc_tfm("twofish", 0); if (tfm == NULL) { printk("failed to load transform for blowfish (default ecb)\n"); return; } for (i = 0; i < TF_ENC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, tf_tv[i].keylen * 8); key = tf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!tf_tv[i].fail) goto out; } p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, tf_tv[i].rlen); printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? "fail" : "pass"); } printk("\ntesting twofish decryption\n"); tsize = sizeof (tf_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, tf_dec_tv_template, tsize); tf_tv = (void *) tvmem; for (i = 0; i < TF_DEC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, tf_tv[i].keylen * 8); key = tf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!tf_tv[i].fail) goto out; } p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, tf_tv[i].rlen); printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? "fail" : "pass"); } crypto_free_tfm(tfm); tfm = crypto_alloc_tfm("twofish", CRYPTO_TFM_MODE_CBC); if (tfm == NULL) { printk("failed to load transform for twofish cbc\n"); return; } printk("\ntesting twofish cbc encryption\n"); tsize = sizeof (tf_cbc_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, tf_cbc_enc_tv_template, tsize); tf_tv = (void *) tvmem; for (i = 0; i < TF_CBC_ENC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, tf_tv[i].keylen * 8); key = tf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; crypto_cipher_set_iv(tfm, tf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, tf_tv[i].rlen); printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? "fail" : "pass"); } printk("\ntesting twofish cbc decryption\n"); tsize = sizeof (tf_cbc_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, tf_cbc_dec_tv_template, tsize); tf_tv = (void *) tvmem; for (i = 0; i < TF_CBC_DEC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, tf_tv[i].keylen * 8); key = tf_tv[i].key; ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out; } p = tf_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; crypto_cipher_set_iv(tfm, tf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, tf_tv[i].rlen); printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ? "fail" : "pass"); } out: crypto_free_tfm(tfm); } void test_serpent(void) { unsigned int ret, i, tsize; u8 *p, *q, *key; struct crypto_tfm *tfm; struct serpent_tv *serp_tv; struct scatterlist sg[1]; printk("\ntesting serpent encryption\n"); tfm = crypto_alloc_tfm("serpent", 0); if (tfm == NULL) { printk("failed to load transform for serpent (default ecb)\n"); return; } tsize = sizeof (serpent_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, serpent_enc_tv_template, tsize); serp_tv = (void *) tvmem; for (i = 0; i < SERPENT_ENC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8); key = serp_tv[i].key; ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!serp_tv[i].fail) goto out; } p = serp_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = sizeof(serp_tv[i].plaintext); ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, sizeof(serp_tv[i].result)); printk("%s\n", memcmp(q, serp_tv[i].result, sizeof(serp_tv[i].result)) ? "fail" : "pass"); } printk("\ntesting serpent decryption\n"); tsize = sizeof (serpent_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, serpent_dec_tv_template, tsize); serp_tv = (void *) tvmem; for (i = 0; i < SERPENT_DEC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8); key = serp_tv[i].key; ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!serp_tv[i].fail) goto out; } p = serp_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = sizeof(serp_tv[i].plaintext); ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, sizeof(serp_tv[i].result)); printk("%s\n", memcmp(q, serp_tv[i].result, sizeof(serp_tv[i].result)) ? "fail" : "pass"); } out: crypto_free_tfm(tfm); } void test_aes(void) { unsigned int ret, i; unsigned int tsize; char *p, *q; struct crypto_tfm *tfm; char *key; struct aes_tv *aes_tv; struct scatterlist sg[1]; printk("\ntesting aes encryption\n"); tsize = sizeof (aes_enc_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, aes_enc_tv_template, tsize); aes_tv = (void *) tvmem; tfm = crypto_alloc_tfm("aes", 0); if (tfm == NULL) { printk("failed to load transform for aes (default ecb)\n"); return; } for (i = 0; i < AES_ENC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, aes_tv[i].keylen * 8); key = aes_tv[i].key; ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!aes_tv[i].fail) goto out; } p = aes_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = aes_tv[i].plen; ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, aes_tv[i].rlen); printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ? "fail" : "pass"); } printk("\ntesting aes decryption\n"); tsize = sizeof (aes_dec_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, aes_dec_tv_template, tsize); aes_tv = (void *) tvmem; for (i = 0; i < AES_DEC_TEST_VECTORS; i++) { printk("test %u (%d bit key):\n", i + 1, aes_tv[i].keylen * 8); key = aes_tv[i].key; ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen); if (ret) { printk("setkey() failed flags=%x\n", tfm->crt_flags); if (!aes_tv[i].fail) goto out; } p = aes_tv[i].plaintext; sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = aes_tv[i].plen; ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; } q = kmap(sg[0].page) + sg[0].offset; hexdump(q, aes_tv[i].rlen); printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ? "fail" : "pass"); } out: crypto_free_tfm(tfm); } static void test_deflate(void) { unsigned int i; char result[COMP_BUF_SIZE]; struct crypto_tfm *tfm; struct comp_testvec *tv; unsigned int tsize; printk("\ntesting deflate compression\n"); tsize = sizeof (deflate_comp_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); return; } memcpy(tvmem, deflate_comp_tv_template, tsize); tv = (void *) tvmem; tfm = crypto_alloc_tfm("deflate", 0); if (tfm == NULL) { printk("failed to load transform for deflate\n"); return; } for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) { int ilen, ret, dlen = COMP_BUF_SIZE; printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); ilen = tv[i].inlen; ret = crypto_comp_compress(tfm, tv[i].input, ilen, result, &dlen); if (ret) { printk("fail: ret=%d\n", ret); continue; } hexdump(result, dlen); printk("%s (ratio %d:%d)\n", memcmp(result, tv[i].output, dlen) ? "fail" : "pass", ilen, dlen); } printk("\ntesting deflate decompression\n"); tsize = sizeof (deflate_decomp_tv_template); if (tsize > TVMEMSIZE) { printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE); goto out; } memcpy(tvmem, deflate_decomp_tv_template, tsize); tv = (void *) tvmem; for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) { int ilen, ret, dlen = COMP_BUF_SIZE; printk("test %u:\n", i + 1); memset(result, 0, sizeof (result)); ilen = tv[i].inlen; ret = crypto_comp_decompress(tfm, tv[i].input, ilen, result, &dlen); if (ret) { printk("fail: ret=%d\n", ret); continue; } hexdump(result, dlen); printk("%s (ratio %d:%d)\n", memcmp(result, tv[i].output, dlen) ? "fail" : "pass", ilen, dlen); } out: crypto_free_tfm(tfm); } static void test_available(void) { char **name = check; while (*name) { printk("alg %s ", *name); printk((crypto_alg_available(*name, 0)) ? "found\n" : "not found\n"); name++; } } static void do_test(void) { switch (mode) { case 0: test_md5(); test_sha1(); test_des(); test_des3_ede(); test_md4(); test_sha256(); test_blowfish(); test_twofish(); test_serpent(); test_aes(); test_sha384(); test_sha512(); test_deflate(); #ifdef CONFIG_CRYPTO_HMAC test_hmac_md5(); test_hmac_sha1(); test_hmac_sha256(); #endif break; case 1: test_md5(); break; case 2: test_sha1(); break; case 3: test_des(); break; case 4: test_des3_ede(); break; case 5: test_md4(); break; case 6: test_sha256(); break; case 7: test_blowfish(); break; case 8: test_twofish(); break; case 9: test_serpent(); break; case 10: test_aes(); break; case 11: test_sha384(); break; case 12: test_sha512(); break; case 13: test_deflate(); break; #ifdef CONFIG_CRYPTO_HMAC case 100: test_hmac_md5(); break; case 101: test_hmac_sha1(); break; case 102: test_hmac_sha256(); break; #endif case 1000: test_available(); break; default: /* useful for debugging */ printk("not testing anything\n"); break; } } static int __init init(void) { tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL); if (tvmem == NULL) return -ENOMEM; xbuf = kmalloc(XBUFSIZE, GFP_KERNEL); if (xbuf == NULL) { kfree(tvmem); return -ENOMEM; } do_test(); kfree(xbuf); kfree(tvmem); return 0; } module_init(init); MODULE_PARM(mode, "i"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Quick & dirty crypto testing module"); MODULE_AUTHOR("James Morris ");