Bring stuff up2date and added own stuff

This commit is contained in:
WolverinDEV
2019-07-02 21:31:51 +02:00
parent 7e7eb695d5
commit 0274d6c822
75 changed files with 4618 additions and 330 deletions
+260
View File
@@ -0,0 +1,260 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* Based on idea.cpp - originally written and placed in the public domain by Wei Dai
https://github.com/weidai11/cryptopp/blob/master/idea.cpp
Patents should be expired. On 2017-10-16 wikipedia says:
https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm
A patent application for IDEA was first filed in Switzerland (CH A 1690/90) on May 18, 1990,
then an international patent application was filed under the Patent Cooperation Treaty on
May 16, 1991. Patents were eventually granted in Austria, France, Germany, Italy, the Netherlands,
Spain, Sweden, Switzerland, the United Kingdom, (European Patent Register entry for European
patent no. 0482154, filed May 16, 1991, issued June 22, 1994 and expired May 16, 2011),
the United States (U.S. Patent 5,214,703, issued May 25, 1993 and expired January 7, 2012)
and Japan (JP 3225440) (expired May 16, 2011).
*/
#include "tomcrypt.h"
#ifdef LTC_IDEA
const struct ltc_cipher_descriptor idea_desc = {
"idea",
24, /* cipher_ID */
16, 16, 8, 8, /* min_key_len, max_key_len, block_len, default_rounds */
&idea_setup,
&idea_ecb_encrypt,
&idea_ecb_decrypt,
&idea_test,
&idea_done,
&idea_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
typedef unsigned short int ushort16;
#define _LOW16(x) ((x)&0xffff) /* compiler should be able to optimize this away if x is 16 bits */
#define _HIGH16(x) ((x)>>16)
#define _MUL(a,b) { \
ulong32 p = (ulong32)_LOW16(a) * b; \
if (p) { \
p = _LOW16(p) - _HIGH16(p); \
a = (ushort16)p - (ushort16)_HIGH16(p); \
} \
else \
a = 1 - a - b; \
}
#define _STORE16(x,y) { (y)[0] = (unsigned char)(((x)>>8)&255); (y)[1] = (unsigned char)((x)&255); }
#define _LOAD16(x,y) { x = ((ushort16)((y)[0] & 255)<<8) | ((ushort16)((y)[1] & 255)); }
static ushort16 _mul_inv(ushort16 x)
{
ushort16 y = x;
unsigned i;
for (i = 0; i < 15; i++) {
_MUL(y, _LOW16(y));
_MUL(y, x);
}
return _LOW16(y);
}
static ushort16 _add_inv(ushort16 x)
{
return _LOW16(0 - x);
}
static int _setup_key(const unsigned char *key, symmetric_key *skey)
{
int i, j;
ushort16 *e_key = skey->idea.ek;
ushort16 *d_key = skey->idea.dk;
/* prepare enc key */
for (i = 0; i < 8; i++) {
_LOAD16(e_key[i], key + 2 * i);
}
for (; i < LTC_IDEA_KEYLEN; i++) {
j = (i - i % 8) - 8;
e_key[i] = _LOW16((e_key[j+(i+1)%8] << 9) | (e_key[j+(i+2)%8] >> 7));
}
/* prepare dec key */
for (i = 0; i < LTC_IDEA_ROUNDS; i++) {
d_key[i*6+0] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+0]);
d_key[i*6+1] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+1+(i>0 ? 1 : 0)]);
d_key[i*6+2] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+2-(i>0 ? 1 : 0)]);
d_key[i*6+3] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+3]);
d_key[i*6+4] = e_key[(LTC_IDEA_ROUNDS-1-i)*6+4];
d_key[i*6+5] = e_key[(LTC_IDEA_ROUNDS-1-i)*6+5];
}
d_key[i*6+0] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+0]);
d_key[i*6+1] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+1]);
d_key[i*6+2] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+2]);
d_key[i*6+3] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+3]);
return CRYPT_OK;
}
static int _process_block(const unsigned char *in, unsigned char *out, ushort16 *m_key)
{
int i;
ushort16 x0, x1, x2, x3, t0, t1;
_LOAD16(x0, in + 0);
_LOAD16(x1, in + 2);
_LOAD16(x2, in + 4);
_LOAD16(x3, in + 6);
for (i = 0; i < LTC_IDEA_ROUNDS; i++) {
_MUL(x0, m_key[i*6+0]);
x1 += m_key[i*6+1];
x2 += m_key[i*6+2];
_MUL(x3, m_key[i*6+3]);
t0 = x0^x2;
_MUL(t0, m_key[i*6+4]);
t1 = t0 + (x1^x3);
_MUL(t1, m_key[i*6+5]);
t0 += t1;
x0 ^= t1;
x3 ^= t0;
t0 ^= x1;
x1 = x2^t1;
x2 = t0;
}
_MUL(x0, m_key[LTC_IDEA_ROUNDS*6+0]);
x2 += m_key[LTC_IDEA_ROUNDS*6+1];
x1 += m_key[LTC_IDEA_ROUNDS*6+2];
_MUL(x3, m_key[LTC_IDEA_ROUNDS*6+3]);
_STORE16(x0, out + 0);
_STORE16(x2, out + 2);
_STORE16(x1, out + 4);
_STORE16(x3, out + 6);
return CRYPT_OK;
}
int idea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (num_rounds != 0 && num_rounds != 8) return CRYPT_INVALID_ROUNDS;
if (keylen != 16) return CRYPT_INVALID_KEYSIZE;
return _setup_key(key, skey);
}
int idea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _process_block(pt, ct, skey->idea.ek);
#ifdef LTC_CLEAN_STACK
burn_stack(sizeof(ushort16) * 6 + sizeof(int));
#endif
return err;
}
int idea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _process_block(ct, pt, skey->idea.dk);
#ifdef LTC_CLEAN_STACK
burn_stack(sizeof(ushort16) * 6 + sizeof(int));
#endif
return err;
}
void idea_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
int idea_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
}
*keysize = 16;
return CRYPT_OK;
}
int idea_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[16], pt[8], ct[8];
} tests[] = {
{
/* key */ { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* ct */ { 0xB1, 0xF5, 0xF7, 0xF8, 0x79, 0x01, 0x37, 0x0F }
},
{
/* key */ { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* ct */ { 0xB3, 0x92, 0x7D, 0xFF, 0xB6, 0x35, 0x86, 0x26 }
},
{
/* key */ { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* ct */ { 0xE9, 0x87, 0xE0, 0x02, 0x9F, 0xB9, 0x97, 0x85 }
},
{
/* key */ { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* ct */ { 0x75, 0x4A, 0x03, 0xCE, 0x08, 0xDB, 0x7D, 0xAA }
},
{
/* key */ { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* ct */ { 0xF0, 0x15, 0xF9, 0xFB, 0x0C, 0xFC, 0x7E, 0x1C }
},
};
unsigned char buf[2][8];
symmetric_key key;
int err, x;
if (sizeof(ushort16) != 2) {
return CRYPT_FAIL_TESTVECTOR;
}
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
if ((err = idea_setup(tests[x].key, 16, 8, &key)) != CRYPT_OK) {
return err;
}
if ((err = idea_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf[0], 8, tests[x].ct, 8, "IDEA Encrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = idea_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf[1], 8, tests[x].pt, 8, "IDEA Decrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
+727
View File
@@ -0,0 +1,727 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* Based on serpent.cpp - originally written and placed in the public domain by Wei Dai
https://github.com/weidai11/cryptopp/blob/master/serpent.cpp
On 2017-10-16 wikipedia says:
"The Serpent cipher algorithm is in the public domain and has not been patented."
https://en.wikipedia.org/wiki/Serpent_(cipher)
*/
#include "tomcrypt.h"
#ifdef LTC_SERPENT
const struct ltc_cipher_descriptor serpent_desc = {
"serpent",
25, /* cipher_ID */
16, 32, 16, 32, /* min_key_len, max_key_len, block_len, default_rounds */
&serpent_setup,
&serpent_ecb_encrypt,
&serpent_ecb_decrypt,
&serpent_test,
&serpent_done,
&serpent_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
/* linear transformation */
#define _LT(i,a,b,c,d,e) { \
a = ROLc(a, 13); \
c = ROLc(c, 3); \
d = ROLc(d ^ c ^ (a << 3), 7); \
b = ROLc(b ^ a ^ c, 1); \
a = ROLc(a ^ b ^ d, 5); \
c = ROLc(c ^ d ^ (b << 7), 22); \
}
/* inverse linear transformation */
#define _ILT(i,a,b,c,d,e) { \
c = RORc(c, 22); \
a = RORc(a, 5); \
c ^= d ^ (b << 7); \
a ^= b ^ d; \
b = RORc(b, 1); \
d = RORc(d, 7) ^ c ^ (a << 3); \
b ^= a ^ c; \
c = RORc(c, 3); \
a = RORc(a, 13); \
}
/* order of output from S-box functions */
#define _beforeS0(f) f(0,a,b,c,d,e)
#define _afterS0(f) f(1,b,e,c,a,d)
#define _afterS1(f) f(2,c,b,a,e,d)
#define _afterS2(f) f(3,a,e,b,d,c)
#define _afterS3(f) f(4,e,b,d,c,a)
#define _afterS4(f) f(5,b,a,e,c,d)
#define _afterS5(f) f(6,a,c,b,e,d)
#define _afterS6(f) f(7,a,c,d,b,e)
#define _afterS7(f) f(8,d,e,b,a,c)
/* order of output from inverse S-box functions */
#define _beforeI7(f) f(8,a,b,c,d,e)
#define _afterI7(f) f(7,d,a,b,e,c)
#define _afterI6(f) f(6,a,b,c,e,d)
#define _afterI5(f) f(5,b,d,e,c,a)
#define _afterI4(f) f(4,b,c,e,a,d)
#define _afterI3(f) f(3,a,b,e,c,d)
#define _afterI2(f) f(2,b,d,e,c,a)
#define _afterI1(f) f(1,a,b,c,e,d)
#define _afterI0(f) f(0,a,d,b,e,c)
/* The instruction sequences for the S-box functions
* come from Dag Arne Osvik's paper "Speeding up Serpent".
*/
#define _S0(i, r0, r1, r2, r3, r4) { \
r3 ^= r0; \
r4 = r1; \
r1 &= r3; \
r4 ^= r2; \
r1 ^= r0; \
r0 |= r3; \
r0 ^= r4; \
r4 ^= r3; \
r3 ^= r2; \
r2 |= r1; \
r2 ^= r4; \
r4 = ~r4; \
r4 |= r1; \
r1 ^= r3; \
r1 ^= r4; \
r3 |= r0; \
r1 ^= r3; \
r4 ^= r3; \
}
#define _I0(i, r0, r1, r2, r3, r4) { \
r2 = ~r2; \
r4 = r1; \
r1 |= r0; \
r4 = ~r4; \
r1 ^= r2; \
r2 |= r4; \
r1 ^= r3; \
r0 ^= r4; \
r2 ^= r0; \
r0 &= r3; \
r4 ^= r0; \
r0 |= r1; \
r0 ^= r2; \
r3 ^= r4; \
r2 ^= r1; \
r3 ^= r0; \
r3 ^= r1; \
r2 &= r3; \
r4 ^= r2; \
}
#define _S1(i, r0, r1, r2, r3, r4) { \
r0 = ~r0; \
r2 = ~r2; \
r4 = r0; \
r0 &= r1; \
r2 ^= r0; \
r0 |= r3; \
r3 ^= r2; \
r1 ^= r0; \
r0 ^= r4; \
r4 |= r1; \
r1 ^= r3; \
r2 |= r0; \
r2 &= r4; \
r0 ^= r1; \
r1 &= r2; \
r1 ^= r0; \
r0 &= r2; \
r0 ^= r4; \
}
#define _I1(i, r0, r1, r2, r3, r4) { \
r4 = r1; \
r1 ^= r3; \
r3 &= r1; \
r4 ^= r2; \
r3 ^= r0; \
r0 |= r1; \
r2 ^= r3; \
r0 ^= r4; \
r0 |= r2; \
r1 ^= r3; \
r0 ^= r1; \
r1 |= r3; \
r1 ^= r0; \
r4 = ~r4; \
r4 ^= r1; \
r1 |= r0; \
r1 ^= r0; \
r1 |= r4; \
r3 ^= r1; \
}
#define _S2(i, r0, r1, r2, r3, r4) { \
r4 = r0; \
r0 &= r2; \
r0 ^= r3; \
r2 ^= r1; \
r2 ^= r0; \
r3 |= r4; \
r3 ^= r1; \
r4 ^= r2; \
r1 = r3; \
r3 |= r4; \
r3 ^= r0; \
r0 &= r1; \
r4 ^= r0; \
r1 ^= r3; \
r1 ^= r4; \
r4 = ~r4; \
}
#define _I2(i, r0, r1, r2, r3, r4) { \
r2 ^= r3; \
r3 ^= r0; \
r4 = r3; \
r3 &= r2; \
r3 ^= r1; \
r1 |= r2; \
r1 ^= r4; \
r4 &= r3; \
r2 ^= r3; \
r4 &= r0; \
r4 ^= r2; \
r2 &= r1; \
r2 |= r0; \
r3 = ~r3; \
r2 ^= r3; \
r0 ^= r3; \
r0 &= r1; \
r3 ^= r4; \
r3 ^= r0; \
}
#define _S3(i, r0, r1, r2, r3, r4) { \
r4 = r0; \
r0 |= r3; \
r3 ^= r1; \
r1 &= r4; \
r4 ^= r2; \
r2 ^= r3; \
r3 &= r0; \
r4 |= r1; \
r3 ^= r4; \
r0 ^= r1; \
r4 &= r0; \
r1 ^= r3; \
r4 ^= r2; \
r1 |= r0; \
r1 ^= r2; \
r0 ^= r3; \
r2 = r1; \
r1 |= r3; \
r1 ^= r0; \
}
#define _I3(i, r0, r1, r2, r3, r4) { \
r4 = r2; \
r2 ^= r1; \
r1 &= r2; \
r1 ^= r0; \
r0 &= r4; \
r4 ^= r3; \
r3 |= r1; \
r3 ^= r2; \
r0 ^= r4; \
r2 ^= r0; \
r0 |= r3; \
r0 ^= r1; \
r4 ^= r2; \
r2 &= r3; \
r1 |= r3; \
r1 ^= r2; \
r4 ^= r0; \
r2 ^= r4; \
}
#define _S4(i, r0, r1, r2, r3, r4) { \
r1 ^= r3; \
r3 = ~r3; \
r2 ^= r3; \
r3 ^= r0; \
r4 = r1; \
r1 &= r3; \
r1 ^= r2; \
r4 ^= r3; \
r0 ^= r4; \
r2 &= r4; \
r2 ^= r0; \
r0 &= r1; \
r3 ^= r0; \
r4 |= r1; \
r4 ^= r0; \
r0 |= r3; \
r0 ^= r2; \
r2 &= r3; \
r0 = ~r0; \
r4 ^= r2; \
}
#define _I4(i, r0, r1, r2, r3, r4) { \
r4 = r2; \
r2 &= r3; \
r2 ^= r1; \
r1 |= r3; \
r1 &= r0; \
r4 ^= r2; \
r4 ^= r1; \
r1 &= r2; \
r0 = ~r0; \
r3 ^= r4; \
r1 ^= r3; \
r3 &= r0; \
r3 ^= r2; \
r0 ^= r1; \
r2 &= r0; \
r3 ^= r0; \
r2 ^= r4; \
r2 |= r3; \
r3 ^= r0; \
r2 ^= r1; \
}
#define _S5(i, r0, r1, r2, r3, r4) { \
r0 ^= r1; \
r1 ^= r3; \
r3 = ~r3; \
r4 = r1; \
r1 &= r0; \
r2 ^= r3; \
r1 ^= r2; \
r2 |= r4; \
r4 ^= r3; \
r3 &= r1; \
r3 ^= r0; \
r4 ^= r1; \
r4 ^= r2; \
r2 ^= r0; \
r0 &= r3; \
r2 = ~r2; \
r0 ^= r4; \
r4 |= r3; \
r2 ^= r4; \
}
#define _I5(i, r0, r1, r2, r3, r4) { \
r1 = ~r1; \
r4 = r3; \
r2 ^= r1; \
r3 |= r0; \
r3 ^= r2; \
r2 |= r1; \
r2 &= r0; \
r4 ^= r3; \
r2 ^= r4; \
r4 |= r0; \
r4 ^= r1; \
r1 &= r2; \
r1 ^= r3; \
r4 ^= r2; \
r3 &= r4; \
r4 ^= r1; \
r3 ^= r0; \
r3 ^= r4; \
r4 = ~r4; \
}
#define _S6(i, r0, r1, r2, r3, r4) { \
r2 = ~r2; \
r4 = r3; \
r3 &= r0; \
r0 ^= r4; \
r3 ^= r2; \
r2 |= r4; \
r1 ^= r3; \
r2 ^= r0; \
r0 |= r1; \
r2 ^= r1; \
r4 ^= r0; \
r0 |= r3; \
r0 ^= r2; \
r4 ^= r3; \
r4 ^= r0; \
r3 = ~r3; \
r2 &= r4; \
r2 ^= r3; \
}
#define _I6(i, r0, r1, r2, r3, r4) { \
r0 ^= r2; \
r4 = r2; \
r2 &= r0; \
r4 ^= r3; \
r2 = ~r2; \
r3 ^= r1; \
r2 ^= r3; \
r4 |= r0; \
r0 ^= r2; \
r3 ^= r4; \
r4 ^= r1; \
r1 &= r3; \
r1 ^= r0; \
r0 ^= r3; \
r0 |= r2; \
r3 ^= r1; \
r4 ^= r0; \
}
#define _S7(i, r0, r1, r2, r3, r4) { \
r4 = r2; \
r2 &= r1; \
r2 ^= r3; \
r3 &= r1; \
r4 ^= r2; \
r2 ^= r1; \
r1 ^= r0; \
r0 |= r4; \
r0 ^= r2; \
r3 ^= r1; \
r2 ^= r3; \
r3 &= r0; \
r3 ^= r4; \
r4 ^= r2; \
r2 &= r0; \
r4 = ~r4; \
r2 ^= r4; \
r4 &= r0; \
r1 ^= r3; \
r4 ^= r1; \
}
#define _I7(i, r0, r1, r2, r3, r4) { \
r4 = r2; \
r2 ^= r0; \
r0 &= r3; \
r2 = ~r2; \
r4 |= r3; \
r3 ^= r1; \
r1 |= r0; \
r0 ^= r2; \
r2 &= r4; \
r1 ^= r2; \
r2 ^= r0; \
r0 |= r2; \
r3 &= r4; \
r0 ^= r3; \
r4 ^= r1; \
r3 ^= r4; \
r4 |= r0; \
r3 ^= r2; \
r4 ^= r2; \
}
/* key xor */
#define _KX(r, a, b, c, d, e) { \
a ^= k[4 * r + 0]; \
b ^= k[4 * r + 1]; \
c ^= k[4 * r + 2]; \
d ^= k[4 * r + 3]; \
}
#define _LK(r, a, b, c, d, e) { \
a = k[(8-r)*4 + 0]; \
b = k[(8-r)*4 + 1]; \
c = k[(8-r)*4 + 2]; \
d = k[(8-r)*4 + 3]; \
}
#define _SK(r, a, b, c, d, e) { \
k[(8-r)*4 + 4] = a; \
k[(8-r)*4 + 5] = b; \
k[(8-r)*4 + 6] = c; \
k[(8-r)*4 + 7] = d; \
}
static int _setup_key(const unsigned char *key, int keylen, int rounds, ulong32 *k)
{
int i;
ulong32 t;
ulong32 k0[8] = { 0 }; /* zero-initialize */
ulong32 a, b, c, d, e;
for (i = 0; i < 8 && i < keylen/4; ++i) {
LOAD32L(k0[i], key + i * 4);
}
if (keylen < 32) {
k0[keylen/4] |= (ulong32)1 << ((keylen%4)*8);
}
t = k0[7];
for (i = 0; i < 8; ++i) {
k[i] = k0[i] = t = ROLc(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11);
}
for (i = 8; i < 4*(rounds+1); ++i) {
k[i] = t = ROLc(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
}
k -= 20;
for (i = 0; i < rounds/8; i++) {
_afterS2(_LK); _afterS2(_S3); _afterS3(_SK);
_afterS1(_LK); _afterS1(_S2); _afterS2(_SK);
_afterS0(_LK); _afterS0(_S1); _afterS1(_SK);
_beforeS0(_LK); _beforeS0(_S0); _afterS0(_SK);
k += 8*4;
_afterS6(_LK); _afterS6(_S7); _afterS7(_SK);
_afterS5(_LK); _afterS5(_S6); _afterS6(_SK);
_afterS4(_LK); _afterS4(_S5); _afterS5(_SK);
_afterS3(_LK); _afterS3(_S4); _afterS4(_SK);
}
_afterS2(_LK); _afterS2(_S3); _afterS3(_SK);
return CRYPT_OK;
}
static int _enc_block(const unsigned char *in, unsigned char *out, ulong32 *k)
{
ulong32 a, b, c, d, e;
unsigned int i = 1;
LOAD32L(a, in + 0);
LOAD32L(b, in + 4);
LOAD32L(c, in + 8);
LOAD32L(d, in + 12);
do {
_beforeS0(_KX); _beforeS0(_S0); _afterS0(_LT);
_afterS0(_KX); _afterS0(_S1); _afterS1(_LT);
_afterS1(_KX); _afterS1(_S2); _afterS2(_LT);
_afterS2(_KX); _afterS2(_S3); _afterS3(_LT);
_afterS3(_KX); _afterS3(_S4); _afterS4(_LT);
_afterS4(_KX); _afterS4(_S5); _afterS5(_LT);
_afterS5(_KX); _afterS5(_S6); _afterS6(_LT);
_afterS6(_KX); _afterS6(_S7);
if (i == 4) break;
++i;
c = b;
b = e;
e = d;
d = a;
a = e;
k += 32;
_beforeS0(_LT);
} while (1);
_afterS7(_KX);
STORE32L(d, out + 0);
STORE32L(e, out + 4);
STORE32L(b, out + 8);
STORE32L(a, out + 12);
return CRYPT_OK;
}
static int _dec_block(const unsigned char *in, unsigned char *out, ulong32 *k)
{
ulong32 a, b, c, d, e;
unsigned int i;
LOAD32L(a, in + 0);
LOAD32L(b, in + 4);
LOAD32L(c, in + 8);
LOAD32L(d, in + 12);
e = 0; LTC_UNUSED_PARAM(e); /* avoid scan-build warning */
i = 4;
k += 96;
_beforeI7(_KX);
goto start;
do {
c = b;
b = d;
d = e;
k -= 32;
_beforeI7(_ILT);
start:
_beforeI7(_I7); _afterI7(_KX);
_afterI7(_ILT); _afterI7(_I6); _afterI6(_KX);
_afterI6(_ILT); _afterI6(_I5); _afterI5(_KX);
_afterI5(_ILT); _afterI5(_I4); _afterI4(_KX);
_afterI4(_ILT); _afterI4(_I3); _afterI3(_KX);
_afterI3(_ILT); _afterI3(_I2); _afterI2(_KX);
_afterI2(_ILT); _afterI2(_I1); _afterI1(_KX);
_afterI1(_ILT); _afterI1(_I0); _afterI0(_KX);
} while (--i != 0);
STORE32L(a, out + 0);
STORE32L(d, out + 4);
STORE32L(b, out + 8);
STORE32L(e, out + 12);
return CRYPT_OK;
}
int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int err;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (num_rounds != 0 && num_rounds != 32) return CRYPT_INVALID_ROUNDS;
if (keylen != 16 && keylen != 24 && keylen != 32) return CRYPT_INVALID_KEYSIZE;
err = _setup_key(key, keylen, 32, skey->serpent.k);
#ifdef LTC_CLEAN_STACK
burn_stack(sizeof(ulong32) * 14 + sizeof(int));
#endif
return err;
}
int serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _enc_block(pt, ct, skey->serpent.k);
#ifdef LTC_CLEAN_STACK
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
#endif
return err;
}
int serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _dec_block(ct, pt, skey->serpent.k);
#ifdef LTC_CLEAN_STACK
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
#endif
return err;
}
void serpent_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
int serpent_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize >= 32) { *keysize = 32; }
else if (*keysize >= 24) { *keysize = 24; }
else if (*keysize >= 16) { *keysize = 16; }
else return CRYPT_INVALID_KEYSIZE;
return CRYPT_OK;
}
int serpent_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[32];
int keylen;
unsigned char pt[16], ct[16];
} tests[] = {
{
/* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 32,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0xA2,0x23,0xAA,0x12,0x88,0x46,0x3C,0x0E,0x2B,0xE3,0x8E,0xBD,0x82,0x56,0x16,0xC0}
},
{
/* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 32,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0xEA,0xE1,0xD4,0x05,0x57,0x01,0x74,0xDF,0x7D,0xF2,0xF9,0x96,0x6D,0x50,0x91,0x59}
},
{
/* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 32,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0x65,0xF3,0x76,0x84,0x47,0x1E,0x92,0x1D,0xC8,0xA3,0x0F,0x45,0xB4,0x3C,0x44,0x99}
},
{
/* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 24,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0x9E,0x27,0x4E,0xAD,0x9B,0x73,0x7B,0xB2,0x1E,0xFC,0xFC,0xA5,0x48,0x60,0x26,0x89}
},
{
/* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 24,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0x92,0xFC,0x8E,0x51,0x03,0x99,0xE4,0x6A,0x04,0x1B,0xF3,0x65,0xE7,0xB3,0xAE,0x82}
},
{
/* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 24,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0x5E,0x0D,0xA3,0x86,0xC4,0x6A,0xD4,0x93,0xDE,0xA2,0x03,0xFD,0xC6,0xF5,0x7D,0x70}
},
{
/* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 16,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0x26,0x4E,0x54,0x81,0xEF,0xF4,0x2A,0x46,0x06,0xAB,0xDA,0x06,0xC0,0xBF,0xDA,0x3D}
},
{
/* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 16,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0x4A,0x23,0x1B,0x3B,0xC7,0x27,0x99,0x34,0x07,0xAC,0x6E,0xC8,0x35,0x0E,0x85,0x24}
},
{
/* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* keylen */ 16,
/* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/* ct */ {0xE0,0x32,0x69,0xF9,0xE9,0xFD,0x85,0x3C,0x7D,0x81,0x56,0xDF,0x14,0xB9,0x8D,0x56}
}
};
unsigned char buf[2][16];
symmetric_key key;
int err, x;
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
if ((err = serpent_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf[0], 16, tests[x].ct, 16, "SERPENT Encrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = serpent_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf[1], 16, tests[x].pt, 16, "SERPENT Decrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */