Commit b14efc2e authored by James Morris's avatar James Morris

[CRYPTO]: Add serpent algorithm.

parent ff7b0319
......@@ -82,6 +82,18 @@ config CRYPTO_TWOFISH
See also:
http://www.counterpane.com/twofish.html
config CRYPTO_SERPENT
tristate "Serpent cipher algorithm"
depends on CRYPTO
help
Serpent cipher algorithm, by Anderson, Biham & Knudsen.
Keys are allowed to be from 0 to 256 bits in length, in steps
of 8 bits.
See also:
http://www.cl.cam.ac.uk/~rja14/serpent.html
config CRYPTO_TEST
tristate "Testing module"
depends on CRYPTO
......
......@@ -17,6 +17,7 @@ obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
obj-$(CONFIG_CRYPTO_DES) += des.o
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
......
This diff is collapsed.
......@@ -48,7 +48,7 @@ static char *tvmem;
static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
"twofish",
"twofish", "serpent",
NULL
};
......@@ -1884,6 +1884,105 @@ test_twofish(void)
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, 1);
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, 1);
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);
}
static void
test_available(void)
{
......@@ -1911,6 +2010,7 @@ do_test(void)
test_sha256();
test_blowfish();
test_twofish();
test_serpent();
#ifdef CONFIG_CRYPTO_HMAC
test_hmac_md5();
test_hmac_sha1();
......@@ -1950,6 +2050,10 @@ do_test(void)
test_twofish();
break;
case 9:
test_serpent();
break;
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac_md5();
......
......@@ -1384,4 +1384,100 @@ struct tf_tv tf_cbc_dec_tv_template[] = {
},
};
/*
* Serpent test vectors. These are backwards because Serpent writes
* octect sequences in right-to-left mode.
*/
#define SERPENT_ENC_TEST_VECTORS 4
#define SERPENT_DEC_TEST_VECTORS 4
struct serpent_tv {
unsigned int keylen, fail;
u8 key[32], plaintext[16], result[16];
};
struct serpent_tv serpent_enc_tv_template[] =
{
{
0, 0,
{ 0 },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }
},
{
16, 0,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }
},
{
32, 0,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }
},
{
16, 0,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}
}
};
struct serpent_tv serpent_dec_tv_template[] =
{
{
0, 0,
{ 0 },
{ 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
},
{
16, 0,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
},
{
32, 0,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
{ 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c },
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
},
{
16, 0,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49},
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
}
};
#endif /* _CRYPTO_TCRYPT_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment