Codebase list libcryptx-perl / 79c1bad
ltc update (serpent,idea) Karel Miko 6 years ago
18 changed file(s) with 1619 addition(s) and 513 deletion(s). Raw diff Collapse all Expand all
00 OBJS=ltc/ciphers/anubis.o ltc/ciphers/blowfish.o ltc/ciphers/camellia.o ltc/ciphers/cast5.o \
1 ltc/ciphers/des.o ltc/ciphers/kasumi.o ltc/ciphers/khazad.o ltc/ciphers/kseed.o ltc/ciphers/multi2.o \
2 ltc/ciphers/noekeon.o ltc/ciphers/rc2.o ltc/ciphers/rc5.o ltc/ciphers/rc6.o ltc/ciphers/skipjack.o \
3 ltc/ciphers/xtea.o ltc/ciphers/aes/aes.o ltc/ciphers/safer/safer.o ltc/ciphers/safer/saferp.o \
4 ltc/ciphers/twofish/twofish.o ltc/encauth/ccm/ccm_add_aad.o ltc/encauth/ccm/ccm_add_nonce.o \
5 ltc/encauth/ccm/ccm_done.o ltc/encauth/ccm/ccm_init.o ltc/encauth/ccm/ccm_memory.o \
6 ltc/encauth/ccm/ccm_process.o ltc/encauth/ccm/ccm_reset.o ltc/encauth/chachapoly/chacha20poly1305_add_aad.o \
7 ltc/encauth/chachapoly/chacha20poly1305_decrypt.o ltc/encauth/chachapoly/chacha20poly1305_done.o \
8 ltc/encauth/chachapoly/chacha20poly1305_encrypt.o ltc/encauth/chachapoly/chacha20poly1305_init.o \
9 ltc/encauth/chachapoly/chacha20poly1305_memory.o ltc/encauth/chachapoly/chacha20poly1305_setiv.o \
10 ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o ltc/encauth/eax/eax_addheader.o \
11 ltc/encauth/eax/eax_decrypt.o ltc/encauth/eax/eax_decrypt_verify_memory.o ltc/encauth/eax/eax_done.o \
12 ltc/encauth/eax/eax_encrypt.o ltc/encauth/eax/eax_encrypt_authenticate_memory.o ltc/encauth/eax/eax_init.o \
13 ltc/encauth/gcm/gcm_add_aad.o ltc/encauth/gcm/gcm_add_iv.o ltc/encauth/gcm/gcm_done.o \
14 ltc/encauth/gcm/gcm_gf_mult.o ltc/encauth/gcm/gcm_init.o ltc/encauth/gcm/gcm_memory.o \
15 ltc/encauth/gcm/gcm_mult_h.o ltc/encauth/gcm/gcm_process.o ltc/encauth/gcm/gcm_reset.o \
16 ltc/encauth/ocb3/ocb3_add_aad.o ltc/encauth/ocb3/ocb3_decrypt.o ltc/encauth/ocb3/ocb3_decrypt_last.o \
17 ltc/encauth/ocb3/ocb3_decrypt_verify_memory.o ltc/encauth/ocb3/ocb3_done.o ltc/encauth/ocb3/ocb3_encrypt.o \
18 ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.o ltc/encauth/ocb3/ocb3_encrypt_last.o \
19 ltc/encauth/ocb3/ocb3_init.o ltc/encauth/ocb3/ocb3_int_ntz.o ltc/encauth/ocb3/ocb3_int_xor_blocks.o \
20 ltc/hashes/blake2b.o ltc/hashes/blake2s.o ltc/hashes/md2.o ltc/hashes/md4.o ltc/hashes/md5.o \
21 ltc/hashes/rmd128.o ltc/hashes/rmd160.o ltc/hashes/rmd256.o ltc/hashes/rmd320.o ltc/hashes/sha1.o \
22 ltc/hashes/sha3.o ltc/hashes/sha3_test.o ltc/hashes/tiger.o ltc/hashes/chc/chc.o \
23 ltc/hashes/helper/hash_file.o ltc/hashes/helper/hash_filehandle.o ltc/hashes/helper/hash_memory.o \
24 ltc/hashes/helper/hash_memory_multi.o ltc/hashes/sha2/sha224.o ltc/hashes/sha2/sha256.o \
25 ltc/hashes/sha2/sha384.o ltc/hashes/sha2/sha512.o ltc/hashes/sha2/sha512_224.o ltc/hashes/sha2/sha512_256.o \
26 ltc/hashes/whirl/whirl.o ltc/mac/blake2/blake2bmac.o ltc/mac/blake2/blake2bmac_file.o \
27 ltc/mac/blake2/blake2bmac_memory.o ltc/mac/blake2/blake2bmac_memory_multi.o ltc/mac/blake2/blake2smac.o \
28 ltc/mac/blake2/blake2smac_file.o ltc/mac/blake2/blake2smac_memory.o ltc/mac/blake2/blake2smac_memory_multi.o \
29 ltc/mac/f9/f9_done.o ltc/mac/f9/f9_file.o ltc/mac/f9/f9_init.o ltc/mac/f9/f9_memory.o \
30 ltc/mac/f9/f9_memory_multi.o ltc/mac/f9/f9_process.o ltc/mac/hmac/hmac_done.o ltc/mac/hmac/hmac_file.o \
31 ltc/mac/hmac/hmac_init.o ltc/mac/hmac/hmac_memory.o ltc/mac/hmac/hmac_memory_multi.o \
32 ltc/mac/hmac/hmac_process.o ltc/mac/omac/omac_done.o ltc/mac/omac/omac_file.o ltc/mac/omac/omac_init.o \
33 ltc/mac/omac/omac_memory.o ltc/mac/omac/omac_memory_multi.o ltc/mac/omac/omac_process.o \
34 ltc/mac/pelican/pelican.o ltc/mac/pelican/pelican_memory.o ltc/mac/pmac/pmac_done.o \
35 ltc/mac/pmac/pmac_file.o ltc/mac/pmac/pmac_init.o ltc/mac/pmac/pmac_memory.o ltc/mac/pmac/pmac_memory_multi.o \
36 ltc/mac/pmac/pmac_ntz.o ltc/mac/pmac/pmac_process.o ltc/mac/pmac/pmac_shift_xor.o \
37 ltc/mac/poly1305/poly1305.o ltc/mac/poly1305/poly1305_file.o ltc/mac/poly1305/poly1305_memory.o \
38 ltc/mac/poly1305/poly1305_memory_multi.o ltc/mac/xcbc/xcbc_done.o ltc/mac/xcbc/xcbc_file.o \
39 ltc/mac/xcbc/xcbc_init.o ltc/mac/xcbc/xcbc_memory.o ltc/mac/xcbc/xcbc_memory_multi.o \
1 ltc/ciphers/des.o ltc/ciphers/idea.o ltc/ciphers/kasumi.o ltc/ciphers/khazad.o ltc/ciphers/kseed.o \
2 ltc/ciphers/multi2.o ltc/ciphers/noekeon.o ltc/ciphers/rc2.o ltc/ciphers/rc5.o ltc/ciphers/rc6.o \
3 ltc/ciphers/serpent.o ltc/ciphers/skipjack.o ltc/ciphers/xtea.o ltc/ciphers/aes/aes.o \
4 ltc/ciphers/safer/safer.o ltc/ciphers/safer/saferp.o ltc/ciphers/twofish/twofish.o \
5 ltc/encauth/ccm/ccm_add_aad.o ltc/encauth/ccm/ccm_add_nonce.o ltc/encauth/ccm/ccm_done.o \
6 ltc/encauth/ccm/ccm_init.o ltc/encauth/ccm/ccm_memory.o ltc/encauth/ccm/ccm_process.o \
7 ltc/encauth/ccm/ccm_reset.o ltc/encauth/chachapoly/chacha20poly1305_add_aad.o ltc/encauth/chachapoly/chacha20poly1305_decrypt.o \
8 ltc/encauth/chachapoly/chacha20poly1305_done.o ltc/encauth/chachapoly/chacha20poly1305_encrypt.o \
9 ltc/encauth/chachapoly/chacha20poly1305_init.o ltc/encauth/chachapoly/chacha20poly1305_memory.o \
10 ltc/encauth/chachapoly/chacha20poly1305_setiv.o ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \
11 ltc/encauth/eax/eax_addheader.o ltc/encauth/eax/eax_decrypt.o ltc/encauth/eax/eax_decrypt_verify_memory.o \
12 ltc/encauth/eax/eax_done.o ltc/encauth/eax/eax_encrypt.o ltc/encauth/eax/eax_encrypt_authenticate_memory.o \
13 ltc/encauth/eax/eax_init.o ltc/encauth/gcm/gcm_add_aad.o ltc/encauth/gcm/gcm_add_iv.o \
14 ltc/encauth/gcm/gcm_done.o ltc/encauth/gcm/gcm_gf_mult.o ltc/encauth/gcm/gcm_init.o \
15 ltc/encauth/gcm/gcm_memory.o ltc/encauth/gcm/gcm_mult_h.o ltc/encauth/gcm/gcm_process.o \
16 ltc/encauth/gcm/gcm_reset.o ltc/encauth/ocb3/ocb3_add_aad.o ltc/encauth/ocb3/ocb3_decrypt.o \
17 ltc/encauth/ocb3/ocb3_decrypt_last.o ltc/encauth/ocb3/ocb3_decrypt_verify_memory.o \
18 ltc/encauth/ocb3/ocb3_done.o ltc/encauth/ocb3/ocb3_encrypt.o ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.o \
19 ltc/encauth/ocb3/ocb3_encrypt_last.o ltc/encauth/ocb3/ocb3_init.o ltc/encauth/ocb3/ocb3_int_ntz.o \
20 ltc/encauth/ocb3/ocb3_int_xor_blocks.o ltc/hashes/blake2b.o ltc/hashes/blake2s.o \
21 ltc/hashes/md2.o ltc/hashes/md4.o ltc/hashes/md5.o ltc/hashes/rmd128.o ltc/hashes/rmd160.o \
22 ltc/hashes/rmd256.o ltc/hashes/rmd320.o ltc/hashes/sha1.o ltc/hashes/sha3.o ltc/hashes/sha3_test.o \
23 ltc/hashes/tiger.o ltc/hashes/chc/chc.o ltc/hashes/helper/hash_file.o ltc/hashes/helper/hash_filehandle.o \
24 ltc/hashes/helper/hash_memory.o ltc/hashes/helper/hash_memory_multi.o ltc/hashes/sha2/sha224.o \
25 ltc/hashes/sha2/sha256.o ltc/hashes/sha2/sha384.o ltc/hashes/sha2/sha512.o ltc/hashes/sha2/sha512_224.o \
26 ltc/hashes/sha2/sha512_256.o ltc/hashes/whirl/whirl.o ltc/mac/blake2/blake2bmac.o \
27 ltc/mac/blake2/blake2bmac_file.o ltc/mac/blake2/blake2bmac_memory.o ltc/mac/blake2/blake2bmac_memory_multi.o \
28 ltc/mac/blake2/blake2smac.o ltc/mac/blake2/blake2smac_file.o ltc/mac/blake2/blake2smac_memory.o \
29 ltc/mac/blake2/blake2smac_memory_multi.o ltc/mac/f9/f9_done.o ltc/mac/f9/f9_file.o \
30 ltc/mac/f9/f9_init.o ltc/mac/f9/f9_memory.o ltc/mac/f9/f9_memory_multi.o ltc/mac/f9/f9_process.o \
31 ltc/mac/hmac/hmac_done.o ltc/mac/hmac/hmac_file.o ltc/mac/hmac/hmac_init.o ltc/mac/hmac/hmac_memory.o \
32 ltc/mac/hmac/hmac_memory_multi.o ltc/mac/hmac/hmac_process.o ltc/mac/omac/omac_done.o \
33 ltc/mac/omac/omac_file.o ltc/mac/omac/omac_init.o ltc/mac/omac/omac_memory.o ltc/mac/omac/omac_memory_multi.o \
34 ltc/mac/omac/omac_process.o ltc/mac/pelican/pelican.o ltc/mac/pelican/pelican_memory.o \
35 ltc/mac/pmac/pmac_done.o ltc/mac/pmac/pmac_file.o ltc/mac/pmac/pmac_init.o ltc/mac/pmac/pmac_memory.o \
36 ltc/mac/pmac/pmac_memory_multi.o ltc/mac/pmac/pmac_ntz.o ltc/mac/pmac/pmac_process.o \
37 ltc/mac/pmac/pmac_shift_xor.o ltc/mac/poly1305/poly1305.o ltc/mac/poly1305/poly1305_file.o \
38 ltc/mac/poly1305/poly1305_memory.o ltc/mac/poly1305/poly1305_memory_multi.o ltc/mac/xcbc/xcbc_done.o \
39 ltc/mac/xcbc/xcbc_file.o ltc/mac/xcbc/xcbc_init.o ltc/mac/xcbc/xcbc_memory.o ltc/mac/xcbc/xcbc_memory_multi.o \
4040 ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/radix_to_bin.o \
4141 ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \
4242 ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/crc32.o \
114114 ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \
115115 ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \
116116 ltc/stream/chacha/chacha_ivctr32.o ltc/stream/chacha/chacha_ivctr64.o ltc/stream/chacha/chacha_keystream.o \
117 ltc/stream/chacha/chacha_setup.o ltc/stream/rc4/rc4.o ltc/stream/sober128/sober128.o \
117 ltc/stream/chacha/chacha_setup.o ltc/stream/rc4/rc4_stream.o ltc/stream/sober128/sober128_stream.o \
118118 ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o \
119119 ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o \
120120 ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o ltm/bn_mp_addmod.o ltm/bn_mp_add_d.o \
00 OBJS=ltc/ciphers/anubis.obj ltc/ciphers/blowfish.obj ltc/ciphers/camellia.obj ltc/ciphers/cast5.obj \
1 ltc/ciphers/des.obj ltc/ciphers/kasumi.obj ltc/ciphers/khazad.obj ltc/ciphers/kseed.obj \
2 ltc/ciphers/multi2.obj ltc/ciphers/noekeon.obj ltc/ciphers/rc2.obj ltc/ciphers/rc5.obj \
3 ltc/ciphers/rc6.obj ltc/ciphers/skipjack.obj ltc/ciphers/xtea.obj ltc/ciphers/aes/aes.obj \
4 ltc/ciphers/safer/safer.obj ltc/ciphers/safer/saferp.obj ltc/ciphers/twofish/twofish.obj \
5 ltc/encauth/ccm/ccm_add_aad.obj ltc/encauth/ccm/ccm_add_nonce.obj ltc/encauth/ccm/ccm_done.obj \
6 ltc/encauth/ccm/ccm_init.obj ltc/encauth/ccm/ccm_memory.obj ltc/encauth/ccm/ccm_process.obj \
7 ltc/encauth/ccm/ccm_reset.obj ltc/encauth/chachapoly/chacha20poly1305_add_aad.obj \
1 ltc/ciphers/des.obj ltc/ciphers/idea.obj ltc/ciphers/kasumi.obj ltc/ciphers/khazad.obj \
2 ltc/ciphers/kseed.obj ltc/ciphers/multi2.obj ltc/ciphers/noekeon.obj ltc/ciphers/rc2.obj \
3 ltc/ciphers/rc5.obj ltc/ciphers/rc6.obj ltc/ciphers/serpent.obj ltc/ciphers/skipjack.obj \
4 ltc/ciphers/xtea.obj ltc/ciphers/aes/aes.obj ltc/ciphers/safer/safer.obj ltc/ciphers/safer/saferp.obj \
5 ltc/ciphers/twofish/twofish.obj ltc/encauth/ccm/ccm_add_aad.obj ltc/encauth/ccm/ccm_add_nonce.obj \
6 ltc/encauth/ccm/ccm_done.obj ltc/encauth/ccm/ccm_init.obj ltc/encauth/ccm/ccm_memory.obj \
7 ltc/encauth/ccm/ccm_process.obj ltc/encauth/ccm/ccm_reset.obj ltc/encauth/chachapoly/chacha20poly1305_add_aad.obj \
88 ltc/encauth/chachapoly/chacha20poly1305_decrypt.obj ltc/encauth/chachapoly/chacha20poly1305_done.obj \
99 ltc/encauth/chachapoly/chacha20poly1305_encrypt.obj ltc/encauth/chachapoly/chacha20poly1305_init.obj \
1010 ltc/encauth/chachapoly/chacha20poly1305_memory.obj ltc/encauth/chachapoly/chacha20poly1305_setiv.obj \
122122 ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \
123123 ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \
124124 ltc/stream/chacha/chacha_ivctr32.obj ltc/stream/chacha/chacha_ivctr64.obj ltc/stream/chacha/chacha_keystream.obj \
125 ltc/stream/chacha/chacha_setup.obj ltc/stream/rc4/rc4.obj ltc/stream/sober128/sober128.obj \
125 ltc/stream/chacha/chacha_setup.obj ltc/stream/rc4/rc4_stream.obj ltc/stream/sober128/sober128_stream.obj \
126126 ltm/bncore.obj ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj ltm/bn_fast_mp_montgomery_reduce.obj \
127127 ltm/bn_fast_s_mp_mul_digs.obj ltm/bn_fast_s_mp_mul_high_digs.obj ltm/bn_fast_s_mp_sqr.obj \
128128 ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj ltm/bn_mp_addmod.obj ltm/bn_mp_add_d.obj \
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /* Based on idea.cpp - originally written and placed in the public domain by Wei Dai
10 https://github.com/weidai11/cryptopp/blob/master/idea.cpp
11
12 Patents should be expired. On 2017-10-16 wikipedia says:
13 https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm
14
15 A patent application for IDEA was first filed in Switzerland (CH A 1690/90) on May 18, 1990,
16 then an international patent application was filed under the Patent Cooperation Treaty on
17 May 16, 1991. Patents were eventually granted in Austria, France, Germany, Italy, the Netherlands,
18 Spain, Sweden, Switzerland, the United Kingdom, (European Patent Register entry for European
19 patent no. 0482154, filed May 16, 1991, issued June 22, 1994 and expired May 16, 2011),
20 the United States (U.S. Patent 5,214,703, issued May 25, 1993 and expired January 7, 2012)
21 and Japan (JP 3225440) (expired May 16, 2011).
22 */
23
24 #include "tomcrypt.h"
25
26 #ifdef LTC_IDEA
27
28 const struct ltc_cipher_descriptor idea_desc = {
29 "idea",
30 24, /* cipher_ID */
31 16, 16, 8, 8, /* min_key_len, max_key_len, block_len, default_rounds */
32 &idea_setup,
33 &idea_ecb_encrypt,
34 &idea_ecb_decrypt,
35 &idea_test,
36 &idea_done,
37 &idea_keysize,
38 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
39 };
40
41 typedef unsigned short int ushort16;
42
43 #define _LOW16(x) ((x)&0xffff) /* compiler should be able to optimize this away if x is 16 bits */
44 #define _HIGH16(x) ((x)>>16)
45 #define _MUL(a,b) { \
46 ulong32 p = (ulong32)_LOW16(a) * b; \
47 if (p) { \
48 p = _LOW16(p) - _HIGH16(p); \
49 a = (ushort16)p - (ushort16)_HIGH16(p); \
50 } \
51 else \
52 a = 1 - a - b; \
53 }
54 #define _STORE16(x,y) { (y)[0] = (unsigned char)(((x)>>8)&255); (y)[1] = (unsigned char)((x)&255); }
55 #define _LOAD16(x,y) { x = ((ushort16)((y)[0] & 255)<<8) | ((ushort16)((y)[1] & 255)); }
56
57 static ushort16 _mul_inv(ushort16 x)
58 {
59 ushort16 y = x;
60 unsigned i;
61
62 for (i = 0; i < 15; i++) {
63 _MUL(y, _LOW16(y));
64 _MUL(y, x);
65 }
66 return _LOW16(y);
67 }
68
69 static ushort16 _add_inv(ushort16 x)
70 {
71 return _LOW16(0 - x);
72 }
73
74 static int _setup_key(const unsigned char *key, symmetric_key *skey)
75 {
76 int i, j;
77 ushort16 *e_key = skey->idea.ek;
78 ushort16 *d_key = skey->idea.dk;
79
80 /* prepare enc key */
81 for (i = 0; i < 8; i++) {
82 _LOAD16(e_key[i], key + 2 * i);
83 }
84 for (; i < LTC_IDEA_KEYLEN; i++) {
85 j = (i - i % 8) - 8;
86 e_key[i] = _LOW16((e_key[j+(i+1)%8] << 9) | (e_key[j+(i+2)%8] >> 7));
87 }
88
89 /* prepare dec key */
90 for (i = 0; i < LTC_IDEA_ROUNDS; i++) {
91 d_key[i*6+0] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+0]);
92 d_key[i*6+1] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+1+(i>0 ? 1 : 0)]);
93 d_key[i*6+2] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+2-(i>0 ? 1 : 0)]);
94 d_key[i*6+3] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+3]);
95 d_key[i*6+4] = e_key[(LTC_IDEA_ROUNDS-1-i)*6+4];
96 d_key[i*6+5] = e_key[(LTC_IDEA_ROUNDS-1-i)*6+5];
97 }
98 d_key[i*6+0] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+0]);
99 d_key[i*6+1] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+1]);
100 d_key[i*6+2] = _add_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+2]);
101 d_key[i*6+3] = _mul_inv(e_key[(LTC_IDEA_ROUNDS-i)*6+3]);
102
103 return CRYPT_OK;
104 }
105
106 static int _process_block(const unsigned char *in, unsigned char *out, ushort16 *m_key)
107 {
108 int i;
109 ushort16 x0, x1, x2, x3, t0, t1;
110
111 _LOAD16(x0, in + 0);
112 _LOAD16(x1, in + 2);
113 _LOAD16(x2, in + 4);
114 _LOAD16(x3, in + 6);
115
116 for (i = 0; i < LTC_IDEA_ROUNDS; i++) {
117 _MUL(x0, m_key[i*6+0]);
118 x1 += m_key[i*6+1];
119 x2 += m_key[i*6+2];
120 _MUL(x3, m_key[i*6+3]);
121 t0 = x0^x2;
122 _MUL(t0, m_key[i*6+4]);
123 t1 = t0 + (x1^x3);
124 _MUL(t1, m_key[i*6+5]);
125 t0 += t1;
126 x0 ^= t1;
127 x3 ^= t0;
128 t0 ^= x1;
129 x1 = x2^t1;
130 x2 = t0;
131 }
132
133 _MUL(x0, m_key[LTC_IDEA_ROUNDS*6+0]);
134 x2 += m_key[LTC_IDEA_ROUNDS*6+1];
135 x1 += m_key[LTC_IDEA_ROUNDS*6+2];
136 _MUL(x3, m_key[LTC_IDEA_ROUNDS*6+3]);
137
138 _STORE16(x0, out + 0);
139 _STORE16(x2, out + 2);
140 _STORE16(x1, out + 4);
141 _STORE16(x3, out + 6);
142
143 return CRYPT_OK;
144 }
145
146 int idea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
147 {
148 LTC_ARGCHK(key != NULL);
149 LTC_ARGCHK(skey != NULL);
150
151 if (num_rounds != 0 && num_rounds != 8) return CRYPT_INVALID_ROUNDS;
152 if (keylen != 16) return CRYPT_INVALID_KEYSIZE;
153
154 return _setup_key(key, skey);
155 }
156
157 int idea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
158 {
159 int err = _process_block(pt, ct, skey->idea.ek);
160 #ifdef LTC_CLEAN_STACK
161 burn_stack(sizeof(ushort16) * 6 + sizeof(int));
162 #endif
163 return err;
164 }
165
166 int idea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
167 {
168 int err = _process_block(ct, pt, skey->idea.dk);
169 #ifdef LTC_CLEAN_STACK
170 burn_stack(sizeof(ushort16) * 6 + sizeof(int));
171 #endif
172 return err;
173 }
174
175 void idea_done(symmetric_key *skey)
176 {
177 LTC_UNUSED_PARAM(skey);
178 }
179
180 int idea_keysize(int *keysize)
181 {
182 LTC_ARGCHK(keysize != NULL);
183 if (*keysize < 16) {
184 return CRYPT_INVALID_KEYSIZE;
185 }
186 *keysize = 16;
187 return CRYPT_OK;
188 }
189
190 int idea_test(void)
191 {
192 #ifndef LTC_TEST
193 return CRYPT_NOP;
194 #else
195 static const struct {
196 unsigned char key[16], pt[8], ct[8];
197 } tests[] = {
198 {
199 /* key */ { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
200 /* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
201 /* ct */ { 0xB1, 0xF5, 0xF7, 0xF8, 0x79, 0x01, 0x37, 0x0F }
202 },
203 {
204 /* key */ { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
205 /* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
206 /* ct */ { 0xB3, 0x92, 0x7D, 0xFF, 0xB6, 0x35, 0x86, 0x26 }
207 },
208 {
209 /* key */ { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
210 /* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
211 /* ct */ { 0xE9, 0x87, 0xE0, 0x02, 0x9F, 0xB9, 0x97, 0x85 }
212 },
213 {
214 /* key */ { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
215 /* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
216 /* ct */ { 0x75, 0x4A, 0x03, 0xCE, 0x08, 0xDB, 0x7D, 0xAA }
217 },
218 {
219 /* key */ { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
220 /* pt */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
221 /* ct */ { 0xF0, 0x15, 0xF9, 0xFB, 0x0C, 0xFC, 0x7E, 0x1C }
222 },
223 };
224
225 unsigned char buf[2][8];
226 symmetric_key key;
227 int err, x;
228
229 if (sizeof(ushort16) != 2) {
230 return CRYPT_FAIL_TESTVECTOR;
231 }
232
233 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
234 if ((err = idea_setup(tests[x].key, 16, 8, &key)) != CRYPT_OK) {
235 return err;
236 }
237 if ((err = idea_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
238 return err;
239 }
240 if (compare_testvector(buf[0], 8, tests[x].ct, 8, "IDEA Encrypt", x)) {
241 return CRYPT_FAIL_TESTVECTOR;
242 }
243 if ((err = idea_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
244 return err;
245 }
246 if (compare_testvector(buf[1], 8, tests[x].pt, 8, "IDEA Decrypt", x)) {
247 return CRYPT_FAIL_TESTVECTOR;
248 }
249 }
250
251 return CRYPT_OK;
252 #endif
253 }
254
255 #endif
256
257 /* ref: $Format:%D$ */
258 /* git commit: $Format:%H$ */
259 /* commit time: $Format:%ai$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 /* Based on serpent.cpp - originally written and placed in the public domain by Wei Dai
10 https://github.com/weidai11/cryptopp/blob/master/serpent.cpp
11
12 On 2017-10-16 wikipedia says:
13 "The Serpent cipher algorithm is in the public domain and has not been patented."
14 https://en.wikipedia.org/wiki/Serpent_(cipher)
15 */
16
17 #include "tomcrypt.h"
18
19 #ifdef LTC_SERPENT
20
21 const struct ltc_cipher_descriptor serpent_desc = {
22 "serpent",
23 25, /* cipher_ID */
24 16, 32, 16, 32, /* min_key_len, max_key_len, block_len, default_rounds */
25 &serpent_setup,
26 &serpent_ecb_encrypt,
27 &serpent_ecb_decrypt,
28 &serpent_test,
29 &serpent_done,
30 &serpent_keysize,
31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
32 };
33
34 /* linear transformation */
35 #define _LT(i,a,b,c,d,e) { \
36 a = ROLc(a, 13); \
37 c = ROLc(c, 3); \
38 d = ROLc(d ^ c ^ (a << 3), 7); \
39 b = ROLc(b ^ a ^ c, 1); \
40 a = ROLc(a ^ b ^ d, 5); \
41 c = ROLc(c ^ d ^ (b << 7), 22); \
42 }
43
44 /* inverse linear transformation */
45 #define _ILT(i,a,b,c,d,e) { \
46 c = RORc(c, 22); \
47 a = RORc(a, 5); \
48 c ^= d ^ (b << 7); \
49 a ^= b ^ d; \
50 b = RORc(b, 1); \
51 d = RORc(d, 7) ^ c ^ (a << 3); \
52 b ^= a ^ c; \
53 c = RORc(c, 3); \
54 a = RORc(a, 13); \
55 }
56
57 /* order of output from S-box functions */
58 #define _beforeS0(f) f(0,a,b,c,d,e)
59 #define _afterS0(f) f(1,b,e,c,a,d)
60 #define _afterS1(f) f(2,c,b,a,e,d)
61 #define _afterS2(f) f(3,a,e,b,d,c)
62 #define _afterS3(f) f(4,e,b,d,c,a)
63 #define _afterS4(f) f(5,b,a,e,c,d)
64 #define _afterS5(f) f(6,a,c,b,e,d)
65 #define _afterS6(f) f(7,a,c,d,b,e)
66 #define _afterS7(f) f(8,d,e,b,a,c)
67
68 /* order of output from inverse S-box functions */
69 #define _beforeI7(f) f(8,a,b,c,d,e)
70 #define _afterI7(f) f(7,d,a,b,e,c)
71 #define _afterI6(f) f(6,a,b,c,e,d)
72 #define _afterI5(f) f(5,b,d,e,c,a)
73 #define _afterI4(f) f(4,b,c,e,a,d)
74 #define _afterI3(f) f(3,a,b,e,c,d)
75 #define _afterI2(f) f(2,b,d,e,c,a)
76 #define _afterI1(f) f(1,a,b,c,e,d)
77 #define _afterI0(f) f(0,a,d,b,e,c)
78
79 /* The instruction sequences for the S-box functions
80 * come from Dag Arne Osvik's paper "Speeding up Serpent".
81 */
82
83 #define _S0(i, r0, r1, r2, r3, r4) { \
84 r3 ^= r0; \
85 r4 = r1; \
86 r1 &= r3; \
87 r4 ^= r2; \
88 r1 ^= r0; \
89 r0 |= r3; \
90 r0 ^= r4; \
91 r4 ^= r3; \
92 r3 ^= r2; \
93 r2 |= r1; \
94 r2 ^= r4; \
95 r4 = ~r4; \
96 r4 |= r1; \
97 r1 ^= r3; \
98 r1 ^= r4; \
99 r3 |= r0; \
100 r1 ^= r3; \
101 r4 ^= r3; \
102 }
103
104 #define _I0(i, r0, r1, r2, r3, r4) { \
105 r2 = ~r2; \
106 r4 = r1; \
107 r1 |= r0; \
108 r4 = ~r4; \
109 r1 ^= r2; \
110 r2 |= r4; \
111 r1 ^= r3; \
112 r0 ^= r4; \
113 r2 ^= r0; \
114 r0 &= r3; \
115 r4 ^= r0; \
116 r0 |= r1; \
117 r0 ^= r2; \
118 r3 ^= r4; \
119 r2 ^= r1; \
120 r3 ^= r0; \
121 r3 ^= r1; \
122 r2 &= r3; \
123 r4 ^= r2; \
124 }
125
126 #define _S1(i, r0, r1, r2, r3, r4) { \
127 r0 = ~r0; \
128 r2 = ~r2; \
129 r4 = r0; \
130 r0 &= r1; \
131 r2 ^= r0; \
132 r0 |= r3; \
133 r3 ^= r2; \
134 r1 ^= r0; \
135 r0 ^= r4; \
136 r4 |= r1; \
137 r1 ^= r3; \
138 r2 |= r0; \
139 r2 &= r4; \
140 r0 ^= r1; \
141 r1 &= r2; \
142 r1 ^= r0; \
143 r0 &= r2; \
144 r0 ^= r4; \
145 }
146
147 #define _I1(i, r0, r1, r2, r3, r4) { \
148 r4 = r1; \
149 r1 ^= r3; \
150 r3 &= r1; \
151 r4 ^= r2; \
152 r3 ^= r0; \
153 r0 |= r1; \
154 r2 ^= r3; \
155 r0 ^= r4; \
156 r0 |= r2; \
157 r1 ^= r3; \
158 r0 ^= r1; \
159 r1 |= r3; \
160 r1 ^= r0; \
161 r4 = ~r4; \
162 r4 ^= r1; \
163 r1 |= r0; \
164 r1 ^= r0; \
165 r1 |= r4; \
166 r3 ^= r1; \
167 }
168
169 #define _S2(i, r0, r1, r2, r3, r4) { \
170 r4 = r0; \
171 r0 &= r2; \
172 r0 ^= r3; \
173 r2 ^= r1; \
174 r2 ^= r0; \
175 r3 |= r4; \
176 r3 ^= r1; \
177 r4 ^= r2; \
178 r1 = r3; \
179 r3 |= r4; \
180 r3 ^= r0; \
181 r0 &= r1; \
182 r4 ^= r0; \
183 r1 ^= r3; \
184 r1 ^= r4; \
185 r4 = ~r4; \
186 }
187
188 #define _I2(i, r0, r1, r2, r3, r4) { \
189 r2 ^= r3; \
190 r3 ^= r0; \
191 r4 = r3; \
192 r3 &= r2; \
193 r3 ^= r1; \
194 r1 |= r2; \
195 r1 ^= r4; \
196 r4 &= r3; \
197 r2 ^= r3; \
198 r4 &= r0; \
199 r4 ^= r2; \
200 r2 &= r1; \
201 r2 |= r0; \
202 r3 = ~r3; \
203 r2 ^= r3; \
204 r0 ^= r3; \
205 r0 &= r1; \
206 r3 ^= r4; \
207 r3 ^= r0; \
208 }
209
210 #define _S3(i, r0, r1, r2, r3, r4) { \
211 r4 = r0; \
212 r0 |= r3; \
213 r3 ^= r1; \
214 r1 &= r4; \
215 r4 ^= r2; \
216 r2 ^= r3; \
217 r3 &= r0; \
218 r4 |= r1; \
219 r3 ^= r4; \
220 r0 ^= r1; \
221 r4 &= r0; \
222 r1 ^= r3; \
223 r4 ^= r2; \
224 r1 |= r0; \
225 r1 ^= r2; \
226 r0 ^= r3; \
227 r2 = r1; \
228 r1 |= r3; \
229 r1 ^= r0; \
230 }
231
232 #define _I3(i, r0, r1, r2, r3, r4) { \
233 r4 = r2; \
234 r2 ^= r1; \
235 r1 &= r2; \
236 r1 ^= r0; \
237 r0 &= r4; \
238 r4 ^= r3; \
239 r3 |= r1; \
240 r3 ^= r2; \
241 r0 ^= r4; \
242 r2 ^= r0; \
243 r0 |= r3; \
244 r0 ^= r1; \
245 r4 ^= r2; \
246 r2 &= r3; \
247 r1 |= r3; \
248 r1 ^= r2; \
249 r4 ^= r0; \
250 r2 ^= r4; \
251 }
252
253 #define _S4(i, r0, r1, r2, r3, r4) { \
254 r1 ^= r3; \
255 r3 = ~r3; \
256 r2 ^= r3; \
257 r3 ^= r0; \
258 r4 = r1; \
259 r1 &= r3; \
260 r1 ^= r2; \
261 r4 ^= r3; \
262 r0 ^= r4; \
263 r2 &= r4; \
264 r2 ^= r0; \
265 r0 &= r1; \
266 r3 ^= r0; \
267 r4 |= r1; \
268 r4 ^= r0; \
269 r0 |= r3; \
270 r0 ^= r2; \
271 r2 &= r3; \
272 r0 = ~r0; \
273 r4 ^= r2; \
274 }
275
276 #define _I4(i, r0, r1, r2, r3, r4) { \
277 r4 = r2; \
278 r2 &= r3; \
279 r2 ^= r1; \
280 r1 |= r3; \
281 r1 &= r0; \
282 r4 ^= r2; \
283 r4 ^= r1; \
284 r1 &= r2; \
285 r0 = ~r0; \
286 r3 ^= r4; \
287 r1 ^= r3; \
288 r3 &= r0; \
289 r3 ^= r2; \
290 r0 ^= r1; \
291 r2 &= r0; \
292 r3 ^= r0; \
293 r2 ^= r4; \
294 r2 |= r3; \
295 r3 ^= r0; \
296 r2 ^= r1; \
297 }
298
299 #define _S5(i, r0, r1, r2, r3, r4) { \
300 r0 ^= r1; \
301 r1 ^= r3; \
302 r3 = ~r3; \
303 r4 = r1; \
304 r1 &= r0; \
305 r2 ^= r3; \
306 r1 ^= r2; \
307 r2 |= r4; \
308 r4 ^= r3; \
309 r3 &= r1; \
310 r3 ^= r0; \
311 r4 ^= r1; \
312 r4 ^= r2; \
313 r2 ^= r0; \
314 r0 &= r3; \
315 r2 = ~r2; \
316 r0 ^= r4; \
317 r4 |= r3; \
318 r2 ^= r4; \
319 }
320
321 #define _I5(i, r0, r1, r2, r3, r4) { \
322 r1 = ~r1; \
323 r4 = r3; \
324 r2 ^= r1; \
325 r3 |= r0; \
326 r3 ^= r2; \
327 r2 |= r1; \
328 r2 &= r0; \
329 r4 ^= r3; \
330 r2 ^= r4; \
331 r4 |= r0; \
332 r4 ^= r1; \
333 r1 &= r2; \
334 r1 ^= r3; \
335 r4 ^= r2; \
336 r3 &= r4; \
337 r4 ^= r1; \
338 r3 ^= r0; \
339 r3 ^= r4; \
340 r4 = ~r4; \
341 }
342
343 #define _S6(i, r0, r1, r2, r3, r4) { \
344 r2 = ~r2; \
345 r4 = r3; \
346 r3 &= r0; \
347 r0 ^= r4; \
348 r3 ^= r2; \
349 r2 |= r4; \
350 r1 ^= r3; \
351 r2 ^= r0; \
352 r0 |= r1; \
353 r2 ^= r1; \
354 r4 ^= r0; \
355 r0 |= r3; \
356 r0 ^= r2; \
357 r4 ^= r3; \
358 r4 ^= r0; \
359 r3 = ~r3; \
360 r2 &= r4; \
361 r2 ^= r3; \
362 }
363
364 #define _I6(i, r0, r1, r2, r3, r4) { \
365 r0 ^= r2; \
366 r4 = r2; \
367 r2 &= r0; \
368 r4 ^= r3; \
369 r2 = ~r2; \
370 r3 ^= r1; \
371 r2 ^= r3; \
372 r4 |= r0; \
373 r0 ^= r2; \
374 r3 ^= r4; \
375 r4 ^= r1; \
376 r1 &= r3; \
377 r1 ^= r0; \
378 r0 ^= r3; \
379 r0 |= r2; \
380 r3 ^= r1; \
381 r4 ^= r0; \
382 }
383
384 #define _S7(i, r0, r1, r2, r3, r4) { \
385 r4 = r2; \
386 r2 &= r1; \
387 r2 ^= r3; \
388 r3 &= r1; \
389 r4 ^= r2; \
390 r2 ^= r1; \
391 r1 ^= r0; \
392 r0 |= r4; \
393 r0 ^= r2; \
394 r3 ^= r1; \
395 r2 ^= r3; \
396 r3 &= r0; \
397 r3 ^= r4; \
398 r4 ^= r2; \
399 r2 &= r0; \
400 r4 = ~r4; \
401 r2 ^= r4; \
402 r4 &= r0; \
403 r1 ^= r3; \
404 r4 ^= r1; \
405 }
406
407 #define _I7(i, r0, r1, r2, r3, r4) { \
408 r4 = r2; \
409 r2 ^= r0; \
410 r0 &= r3; \
411 r2 = ~r2; \
412 r4 |= r3; \
413 r3 ^= r1; \
414 r1 |= r0; \
415 r0 ^= r2; \
416 r2 &= r4; \
417 r1 ^= r2; \
418 r2 ^= r0; \
419 r0 |= r2; \
420 r3 &= r4; \
421 r0 ^= r3; \
422 r4 ^= r1; \
423 r3 ^= r4; \
424 r4 |= r0; \
425 r3 ^= r2; \
426 r4 ^= r2; \
427 }
428
429 /* key xor */
430 #define _KX(r, a, b, c, d, e) { \
431 a ^= k[4 * r + 0]; \
432 b ^= k[4 * r + 1]; \
433 c ^= k[4 * r + 2]; \
434 d ^= k[4 * r + 3]; \
435 }
436
437 #define _LK(r, a, b, c, d, e) { \
438 a = k[(8-r)*4 + 0]; \
439 b = k[(8-r)*4 + 1]; \
440 c = k[(8-r)*4 + 2]; \
441 d = k[(8-r)*4 + 3]; \
442 }
443
444 #define _SK(r, a, b, c, d, e) { \
445 k[(8-r)*4 + 4] = a; \
446 k[(8-r)*4 + 5] = b; \
447 k[(8-r)*4 + 6] = c; \
448 k[(8-r)*4 + 7] = d; \
449 }
450
451 static int _setup_key(const unsigned char *key, int keylen, int rounds, ulong32 *k)
452 {
453 int i;
454 ulong32 t;
455 ulong32 k0[8] = { 0 }; /* zero-initialize */
456 ulong32 a, b, c, d, e;
457
458 for (i = 0; i < 8 && i < keylen/4; ++i) {
459 LOAD32L(k0[i], key + i * 4);
460 }
461 if (keylen < 32) {
462 k0[keylen/4] |= (ulong32)1 << ((keylen%4)*8);
463 }
464
465 t = k0[7];
466 for (i = 0; i < 8; ++i) {
467 k[i] = k0[i] = t = ROLc(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11);
468 }
469 for (i = 8; i < 4*(rounds+1); ++i) {
470 k[i] = t = ROLc(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
471 }
472 k -= 20;
473
474 for (i = 0; i < rounds/8; i++) {
475 _afterS2(_LK); _afterS2(_S3); _afterS3(_SK);
476 _afterS1(_LK); _afterS1(_S2); _afterS2(_SK);
477 _afterS0(_LK); _afterS0(_S1); _afterS1(_SK);
478 _beforeS0(_LK); _beforeS0(_S0); _afterS0(_SK);
479 k += 8*4;
480 _afterS6(_LK); _afterS6(_S7); _afterS7(_SK);
481 _afterS5(_LK); _afterS5(_S6); _afterS6(_SK);
482 _afterS4(_LK); _afterS4(_S5); _afterS5(_SK);
483 _afterS3(_LK); _afterS3(_S4); _afterS4(_SK);
484 }
485 _afterS2(_LK); _afterS2(_S3); _afterS3(_SK);
486
487 return CRYPT_OK;
488 }
489
490 static int _enc_block(const unsigned char *in, unsigned char *out, ulong32 *k)
491 {
492 ulong32 a, b, c, d, e;
493 unsigned int i = 1;
494
495 LOAD32L(a, in + 0);
496 LOAD32L(b, in + 4);
497 LOAD32L(c, in + 8);
498 LOAD32L(d, in + 12);
499
500 do {
501 _beforeS0(_KX); _beforeS0(_S0); _afterS0(_LT);
502 _afterS0(_KX); _afterS0(_S1); _afterS1(_LT);
503 _afterS1(_KX); _afterS1(_S2); _afterS2(_LT);
504 _afterS2(_KX); _afterS2(_S3); _afterS3(_LT);
505 _afterS3(_KX); _afterS3(_S4); _afterS4(_LT);
506 _afterS4(_KX); _afterS4(_S5); _afterS5(_LT);
507 _afterS5(_KX); _afterS5(_S6); _afterS6(_LT);
508 _afterS6(_KX); _afterS6(_S7);
509
510 if (i == 4) break;
511
512 ++i;
513 c = b;
514 b = e;
515 e = d;
516 d = a;
517 a = e;
518 k += 32;
519 _beforeS0(_LT);
520 } while (1);
521
522 _afterS7(_KX);
523
524 STORE32L(d, out + 0);
525 STORE32L(e, out + 4);
526 STORE32L(b, out + 8);
527 STORE32L(a, out + 12);
528
529 return CRYPT_OK;
530 }
531
532 static int _dec_block(const unsigned char *in, unsigned char *out, ulong32 *k)
533 {
534 ulong32 a, b, c, d, e;
535 unsigned int i;
536
537 LOAD32L(a, in + 0);
538 LOAD32L(b, in + 4);
539 LOAD32L(c, in + 8);
540 LOAD32L(d, in + 12);
541 e = 0; LTC_UNUSED_PARAM(e); /* avoid scan-build warning */
542 i = 4;
543 k += 96;
544
545 _beforeI7(_KX);
546 goto start;
547
548 do {
549 c = b;
550 b = d;
551 d = e;
552 k -= 32;
553 _beforeI7(_ILT);
554 start:
555 _beforeI7(_I7); _afterI7(_KX);
556 _afterI7(_ILT); _afterI7(_I6); _afterI6(_KX);
557 _afterI6(_ILT); _afterI6(_I5); _afterI5(_KX);
558 _afterI5(_ILT); _afterI5(_I4); _afterI4(_KX);
559 _afterI4(_ILT); _afterI4(_I3); _afterI3(_KX);
560 _afterI3(_ILT); _afterI3(_I2); _afterI2(_KX);
561 _afterI2(_ILT); _afterI2(_I1); _afterI1(_KX);
562 _afterI1(_ILT); _afterI1(_I0); _afterI0(_KX);
563 } while (--i != 0);
564
565 STORE32L(a, out + 0);
566 STORE32L(d, out + 4);
567 STORE32L(b, out + 8);
568 STORE32L(e, out + 12);
569
570 return CRYPT_OK;
571 }
572
573 int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
574 {
575 int err;
576
577 LTC_ARGCHK(key != NULL);
578 LTC_ARGCHK(skey != NULL);
579
580 if (num_rounds != 0 && num_rounds != 32) return CRYPT_INVALID_ROUNDS;
581 if (keylen != 16 && keylen != 24 && keylen != 32) return CRYPT_INVALID_KEYSIZE;
582
583 err = _setup_key(key, keylen, 32, skey->serpent.k);
584 #ifdef LTC_CLEAN_STACK
585 burn_stack(sizeof(ulong32) * 14 + sizeof(int));
586 #endif
587 return err;
588 }
589
590 int serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
591 {
592 int err = _enc_block(pt, ct, skey->serpent.k);
593 #ifdef LTC_CLEAN_STACK
594 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
595 #endif
596 return err;
597 }
598
599 int serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
600 {
601 int err = _dec_block(ct, pt, skey->serpent.k);
602 #ifdef LTC_CLEAN_STACK
603 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
604 #endif
605 return err;
606 }
607
608 void serpent_done(symmetric_key *skey)
609 {
610 LTC_UNUSED_PARAM(skey);
611 }
612
613 int serpent_keysize(int *keysize)
614 {
615 LTC_ARGCHK(keysize != NULL);
616
617 if (*keysize >= 32) { *keysize = 32; }
618 else if (*keysize >= 24) { *keysize = 24; }
619 else if (*keysize >= 16) { *keysize = 16; }
620 else return CRYPT_INVALID_KEYSIZE;
621 return CRYPT_OK;
622 }
623
624 int serpent_test(void)
625 {
626 #ifndef LTC_TEST
627 return CRYPT_NOP;
628 #else
629 static const struct {
630 unsigned char key[32];
631 int keylen;
632 unsigned char pt[16], ct[16];
633 } tests[] = {
634 {
635 /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
636 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
637 /* keylen */ 32,
638 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
639 /* ct */ {0xA2,0x23,0xAA,0x12,0x88,0x46,0x3C,0x0E,0x2B,0xE3,0x8E,0xBD,0x82,0x56,0x16,0xC0}
640 },
641 {
642 /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
643 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
644 /* keylen */ 32,
645 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
646 /* ct */ {0xEA,0xE1,0xD4,0x05,0x57,0x01,0x74,0xDF,0x7D,0xF2,0xF9,0x96,0x6D,0x50,0x91,0x59}
647 },
648 {
649 /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
650 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
651 /* keylen */ 32,
652 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
653 /* ct */ {0x65,0xF3,0x76,0x84,0x47,0x1E,0x92,0x1D,0xC8,0xA3,0x0F,0x45,0xB4,0x3C,0x44,0x99}
654 },
655 {
656 /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
657 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
658 /* keylen */ 24,
659 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
660 /* ct */ {0x9E,0x27,0x4E,0xAD,0x9B,0x73,0x7B,0xB2,0x1E,0xFC,0xFC,0xA5,0x48,0x60,0x26,0x89}
661 },
662 {
663 /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
664 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
665 /* keylen */ 24,
666 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
667 /* ct */ {0x92,0xFC,0x8E,0x51,0x03,0x99,0xE4,0x6A,0x04,0x1B,0xF3,0x65,0xE7,0xB3,0xAE,0x82}
668 },
669 {
670 /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
671 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
672 /* keylen */ 24,
673 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
674 /* ct */ {0x5E,0x0D,0xA3,0x86,0xC4,0x6A,0xD4,0x93,0xDE,0xA2,0x03,0xFD,0xC6,0xF5,0x7D,0x70}
675 },
676 {
677 /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
678 /* keylen */ 16,
679 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
680 /* ct */ {0x26,0x4E,0x54,0x81,0xEF,0xF4,0x2A,0x46,0x06,0xAB,0xDA,0x06,0xC0,0xBF,0xDA,0x3D}
681 },
682 {
683 /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
684 /* keylen */ 16,
685 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
686 /* ct */ {0x4A,0x23,0x1B,0x3B,0xC7,0x27,0x99,0x34,0x07,0xAC,0x6E,0xC8,0x35,0x0E,0x85,0x24}
687 },
688 {
689 /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
690 /* keylen */ 16,
691 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
692 /* ct */ {0xE0,0x32,0x69,0xF9,0xE9,0xFD,0x85,0x3C,0x7D,0x81,0x56,0xDF,0x14,0xB9,0x8D,0x56}
693 }
694 };
695
696 unsigned char buf[2][16];
697 symmetric_key key;
698 int err, x;
699
700 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
701 if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
702 return err;
703 }
704 if ((err = serpent_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
705 return err;
706 }
707 if (compare_testvector(buf[0], 16, tests[x].ct, 16, "SERPENT Encrypt", x)) {
708 return CRYPT_FAIL_TESTVECTOR;
709 }
710 if ((err = serpent_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
711 return err;
712 }
713 if (compare_testvector(buf[1], 16, tests[x].pt, 16, "SERPENT Decrypt", x)) {
714 return CRYPT_FAIL_TESTVECTOR;
715 }
716 }
717
718 return CRYPT_OK;
719 #endif
720 }
721
722 #endif
723
724 /* ref: $Format:%D$ */
725 /* git commit: $Format:%H$ */
726 /* commit time: $Format:%ai$ */
2323 @param out The ciphertext
2424 @param tag [out] The MAC tag
2525 @param taglen [in/out] The MAC tag length
26 @param direction Encrypt or Decrypt mode (CHCHA20POLY1305_ENCRYPT or CHCHA20POLY1305_DECRYPT)
26 @param direction Encrypt or Decrypt mode (CHACHA20POLY1305_ENCRYPT or CHACHA20POLY1305_DECRYPT)
2727 @return CRYPT_OK on success
2828 */
2929 int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
4848 if (aad && aadlen > 0) {
4949 if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; }
5050 }
51 if (direction == CHCHA20POLY1305_ENCRYPT) {
51 if (direction == CHACHA20POLY1305_ENCRYPT) {
5252 if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
5353 }
54 else if (direction == CHCHA20POLY1305_DECRYPT) {
54 else if (direction == CHACHA20POLY1305_DECRYPT) {
5555 if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
5656 }
5757 else {
276276 #define LTC_HAVE_BSWAP_BUILTIN
277277 #endif
278278
279 #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 301)
280 #define LTC_DEPRECATED __attribute__((deprecated))
281 #elif defined(_MSC_VER)
282 #define LTC_DEPRECATED __declspec(deprecated)
283 #else
284 #define LTC_DEPRECATED
285 #endif
279286
280287 /* ref: $Format:%D$ */
281288 /* git commit: $Format:%H$ */
153153 };
154154 #endif
155155
156 #ifdef LTC_IDEA
157 /* rounds */
158 #define LTC_IDEA_ROUNDS 8
159 /* key schedule length in # of unsigned shorts */
160 #define LTC_IDEA_KEYLEN 6*LTC_IDEA_ROUNDS+4
161 struct idea_key {
162 unsigned short int ek[LTC_IDEA_KEYLEN]; /* enc key */
163 unsigned short int dk[LTC_IDEA_KEYLEN]; /* dec key */
164 };
165 #endif
166
167 #ifdef LTC_SERPENT
168 struct serpent_key {
169 ulong32 k[33*4];
170 };
171 #endif
172
156173 typedef union Symmetric_key {
157174 #ifdef LTC_DES
158175 struct des_key des;
211228 #endif
212229 #ifdef LTC_CAMELLIA
213230 struct camellia_key camellia;
231 #endif
232 #ifdef LTC_IDEA
233 struct idea_key idea;
234 #endif
235 #ifdef LTC_SERPENT
236 struct serpent_key serpent;
214237 #endif
215238 void *data;
216239 } symmetric_key;
815838 extern const struct ltc_cipher_descriptor camellia_desc;
816839 #endif
817840
841 #ifdef LTC_IDEA
842 int idea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
843 int idea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
844 int idea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
845 int idea_test(void);
846 void idea_done(symmetric_key *skey);
847 int idea_keysize(int *keysize);
848 extern const struct ltc_cipher_descriptor idea_desc;
849 #endif
850
851 #ifdef LTC_SERPENT
852 int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
853 int serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
854 int serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
855 int serpent_test(void);
856 void serpent_done(symmetric_key *skey);
857 int serpent_keysize(int *keysize);
858 extern const struct ltc_cipher_descriptor serpent_desc;
859 #endif
860
818861 #ifdef LTC_ECB_MODE
819862 int ecb_start(int cipher, const unsigned char *key,
820863 int keylen, int num_rounds, symmetric_ECB *ecb);
201201 #define LTC_KASUMI
202202 #define LTC_MULTI2
203203 #define LTC_CAMELLIA
204 #define LTC_IDEA
205 #define LTC_SERPENT
204206
205207 /* stream ciphers */
206208 #define LTC_CHACHA
541541 int aadflg;
542542 } chacha20poly1305_state;
543543
544 #define CHCHA20POLY1305_ENCRYPT LTC_ENCRYPT
545 #define CHCHA20POLY1305_DECRYPT LTC_DECRYPT
544 #define CHACHA20POLY1305_ENCRYPT LTC_ENCRYPT
545 #define CHACHA20POLY1305_DECRYPT LTC_DECRYPT
546546
547547 int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen);
548548 int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen);
7272 int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size);
7373
7474 #ifdef LTM_DESC
75 void init_LTM(void);
75 LTC_DEPRECATED void init_LTM(void);
7676 #endif
7777 #ifdef TFM_DESC
78 void init_TFM(void);
78 LTC_DEPRECATED void init_TFM(void);
7979 #endif
8080 #ifdef GMP_DESC
81 void init_GMP(void);
81 LTC_DEPRECATED void init_GMP(void);
8282 #endif
83 int crypt_mp_init(const char* mpi);
8384
8485 #ifdef LTC_ADLER32
8586 typedef struct adler32_state_s
121121 #if defined(LTC_CAMELLIA)
122122 " Camellia\n"
123123 #endif
124 #if defined(LTC_IDEA)
125 " IDEA\n"
126 #endif
127 #if defined(LTC_SERPENT)
128 " Serpent\n"
129 #endif
124130 "Stream ciphers built-in:\n"
125131 #if defined(LTC_CHACHA)
126132 " ChaCha\n"
3636 }
3737 #endif
3838
39 int crypt_mp_init(const char* mpi)
40 {
41 if (mpi == NULL) return CRYPT_ERROR;
42 switch (mpi[0]) {
43 #ifdef LTM_DESC
44 case 'l':
45 case 'L':
46 ltc_mp = ltm_desc;
47 return CRYPT_OK;
48 #endif
49 #ifdef TFM_DESC
50 case 't':
51 case 'T':
52 ltc_mp = tfm_desc;
53 return CRYPT_OK;
54 #endif
55 #ifdef GMP_DESC
56 case 'g':
57 case 'G':
58 ltc_mp = gmp_desc;
59 return CRYPT_OK;
60 #endif
61 #ifdef EXT_MATH_LIB
62 case 'e':
63 case 'E':
64 {
65 extern ltc_math_descriptor EXT_MATH_LIB;
66 ltc_mp = EXT_MATH_LIB;
67 }
68
69 #if defined(LTC_TEST_DBG)
70 #define NAME_VALUE(s) #s"="NAME(s)
71 #define NAME(s) #s
72 printf("EXT_MATH_LIB = %s\n", NAME_VALUE(EXT_MATH_LIB));
73 #undef NAME_VALUE
74 #undef NAME
75 #endif
76
77 return CRYPT_OK;
78 #endif
79 default:
80 #if defined(LTC_TEST_DBG)
81 printf("Unknown/Invalid MPI provider: %s\n", mpi);
82 #endif
83 return CRYPT_ERROR;
84 }
85 }
86
3987
4088 /* ref: $Format:%D$ */
4189 /* git commit: $Format:%H$ */
9393 #ifdef LTC_CAMELLIA
9494 REGISTER_CIPHER(&camellia_desc);
9595 #endif
96 #ifdef LTC_IDEA
97 REGISTER_CIPHER(&idea_desc);
98 #endif
99 #ifdef LTC_SERPENT
100 REGISTER_CIPHER(&serpent_desc);
101 #endif
96102 return err;
97103 }
98104
9797 _SZ_STRINGIFY_S(des_key),
9898 _SZ_STRINGIFY_S(des3_key),
9999 #endif
100 #ifdef LTC_IDEA
101 _SZ_STRINGIFY_S(idea_key),
102 #endif
100103 #ifdef LTC_KASUMI
101104 _SZ_STRINGIFY_S(kasumi_key),
102105 #endif
120123 #endif
121124 #ifdef LTC_RC6
122125 _SZ_STRINGIFY_S(rc6_key),
126 #endif
127 #ifdef LTC_SERPENT
128 _SZ_STRINGIFY_S(serpent_key),
123129 #endif
124130 #ifdef LTC_SKIPJACK
125131 _SZ_STRINGIFY_S(skipjack_key),
+0
-111
src/ltc/stream/rc4/rc4.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 #include "tomcrypt.h"
10
11 #ifdef LTC_RC4_STREAM
12
13 /**
14 Initialize an RC4 context (only the key)
15 @param st [out] The destination of the RC4 state
16 @param key The secret key
17 @param keylen The length of the secret key (8 - 256 bytes)
18 @return CRYPT_OK if successful
19 */
20 int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
21 {
22 unsigned char tmp, *s;
23 int x, y;
24 unsigned long j;
25
26 LTC_ARGCHK(st != NULL);
27 LTC_ARGCHK(key != NULL);
28 LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */
29
30 s = st->buf;
31 for (x = 0; x < 256; x++) {
32 s[x] = x;
33 }
34
35 for (j = x = y = 0; x < 256; x++) {
36 y = (y + s[x] + key[j++]) & 255;
37 if (j == keylen) {
38 j = 0;
39 }
40 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
41 }
42 st->x = 0;
43 st->y = 0;
44
45 return CRYPT_OK;
46 }
47
48 /**
49 Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4
50 @param st The RC4 state
51 @param in The plaintext (or ciphertext)
52 @param inlen The length of the input (octets)
53 @param out [out] The ciphertext (or plaintext), length inlen
54 @return CRYPT_OK if successful
55 */
56 int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
57 {
58 unsigned char x, y, *s, tmp;
59
60 LTC_ARGCHK(st != NULL);
61 LTC_ARGCHK(in != NULL);
62 LTC_ARGCHK(out != NULL);
63
64 x = st->x;
65 y = st->y;
66 s = st->buf;
67 while (inlen--) {
68 x = (x + 1) & 255;
69 y = (y + s[x]) & 255;
70 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
71 tmp = (s[x] + s[y]) & 255;
72 *out++ = *in++ ^ s[tmp];
73 }
74 st->x = x;
75 st->y = y;
76 return CRYPT_OK;
77 }
78
79 /**
80 Generate a stream of random bytes via RC4
81 @param st The RC420 state
82 @param out [out] The output buffer
83 @param outlen The output length
84 @return CRYPT_OK on success
85 */
86 int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
87 {
88 if (outlen == 0) return CRYPT_OK; /* nothing to do */
89 LTC_ARGCHK(out != NULL);
90 XMEMSET(out, 0, outlen);
91 return rc4_stream_crypt(st, out, outlen, out);
92 }
93
94 /**
95 Terminate and clear RC4 state
96 @param st The RC4 state
97 @return CRYPT_OK on success
98 */
99 int rc4_stream_done(rc4_state *st)
100 {
101 LTC_ARGCHK(st != NULL);
102 XMEMSET(st, 0, sizeof(rc4_state));
103 return CRYPT_OK;
104 }
105
106 #endif
107
108 /* ref: $Format:%D$ */
109 /* git commit: $Format:%H$ */
110 /* commit time: $Format:%ai$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8
9 #include "tomcrypt.h"
10
11 #ifdef LTC_RC4_STREAM
12
13 /**
14 Initialize an RC4 context (only the key)
15 @param st [out] The destination of the RC4 state
16 @param key The secret key
17 @param keylen The length of the secret key (8 - 256 bytes)
18 @return CRYPT_OK if successful
19 */
20 int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen)
21 {
22 unsigned char tmp, *s;
23 int x, y;
24 unsigned long j;
25
26 LTC_ARGCHK(st != NULL);
27 LTC_ARGCHK(key != NULL);
28 LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */
29
30 s = st->buf;
31 for (x = 0; x < 256; x++) {
32 s[x] = x;
33 }
34
35 for (j = x = y = 0; x < 256; x++) {
36 y = (y + s[x] + key[j++]) & 255;
37 if (j == keylen) {
38 j = 0;
39 }
40 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
41 }
42 st->x = 0;
43 st->y = 0;
44
45 return CRYPT_OK;
46 }
47
48 /**
49 Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4
50 @param st The RC4 state
51 @param in The plaintext (or ciphertext)
52 @param inlen The length of the input (octets)
53 @param out [out] The ciphertext (or plaintext), length inlen
54 @return CRYPT_OK if successful
55 */
56 int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
57 {
58 unsigned char x, y, *s, tmp;
59
60 LTC_ARGCHK(st != NULL);
61 LTC_ARGCHK(in != NULL);
62 LTC_ARGCHK(out != NULL);
63
64 x = st->x;
65 y = st->y;
66 s = st->buf;
67 while (inlen--) {
68 x = (x + 1) & 255;
69 y = (y + s[x]) & 255;
70 tmp = s[x]; s[x] = s[y]; s[y] = tmp;
71 tmp = (s[x] + s[y]) & 255;
72 *out++ = *in++ ^ s[tmp];
73 }
74 st->x = x;
75 st->y = y;
76 return CRYPT_OK;
77 }
78
79 /**
80 Generate a stream of random bytes via RC4
81 @param st The RC420 state
82 @param out [out] The output buffer
83 @param outlen The output length
84 @return CRYPT_OK on success
85 */
86 int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen)
87 {
88 if (outlen == 0) return CRYPT_OK; /* nothing to do */
89 LTC_ARGCHK(out != NULL);
90 XMEMSET(out, 0, outlen);
91 return rc4_stream_crypt(st, out, outlen, out);
92 }
93
94 /**
95 Terminate and clear RC4 state
96 @param st The RC4 state
97 @return CRYPT_OK on success
98 */
99 int rc4_stream_done(rc4_state *st)
100 {
101 LTC_ARGCHK(st != NULL);
102 XMEMSET(st, 0, sizeof(rc4_state));
103 return CRYPT_OK;
104 }
105
106 #endif
107
108 /* ref: $Format:%D$ */
109 /* git commit: $Format:%H$ */
110 /* commit time: $Format:%ai$ */
+0
-346
src/ltc/stream/sober128/sober128.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10 /**
11 @file stream/sober128/sober128.c
12 Implementation of SOBER-128 by Tom St Denis.
13 Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
14 */
15
16 #ifdef LTC_SOBER128
17
18 #define __LTC_SOBER128TAB_C__
19 #include "sober128tab.c"
20
21 /* don't change these... */
22 #define N 17
23 #define FOLD N /* how many iterations of folding to do */
24 #define INITKONST 0x6996c53a /* value of KONST to use during key loading */
25 #define KEYP 15 /* where to insert key words */
26 #define FOLDP 4 /* where to insert non-linear feedback */
27
28 #define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF))
29
30 static ulong32 BYTE2WORD(unsigned char *b)
31 {
32 ulong32 t;
33 LOAD32L(t, b);
34 return t;
35 }
36
37 static void XORWORD(ulong32 w, const unsigned char *in, unsigned char *out)
38 {
39 ulong32 t;
40 LOAD32L(t, in);
41 t ^= w;
42 STORE32L(t, out);
43 }
44
45 /* give correct offset for the current position of the register,
46 * where logically R[0] is at position "zero".
47 */
48 #define OFF(zero, i) (((zero)+(i)) % N)
49
50 /* step the LFSR */
51 /* After stepping, "zero" moves right one place */
52 #define STEP(R,z) \
53 R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
54
55 static void cycle(ulong32 *R)
56 {
57 ulong32 t;
58 int i;
59
60 STEP(R,0);
61 t = R[0];
62 for (i = 1; i < N; ++i) {
63 R[i-1] = R[i];
64 }
65 R[N-1] = t;
66 }
67
68 /* Return a non-linear function of some parts of the register.
69 */
70 #define NLFUNC(c,z) \
71 { \
72 t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \
73 t ^= Sbox[(t >> 24) & 0xFF]; \
74 t = RORc(t, 8); \
75 t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \
76 t ^= Sbox[(t >> 24) & 0xFF]; \
77 t = t + c->R[OFF(z,13)]; \
78 }
79
80 static ulong32 nltap(sober128_state *c)
81 {
82 ulong32 t;
83 NLFUNC(c, 0);
84 return t;
85 }
86
87 /* Save the current register state
88 */
89 static void s128_savestate(sober128_state *c)
90 {
91 int i;
92 for (i = 0; i < N; ++i) {
93 c->initR[i] = c->R[i];
94 }
95 }
96
97 /* initialise to previously saved register state
98 */
99 static void s128_reloadstate(sober128_state *c)
100 {
101 int i;
102
103 for (i = 0; i < N; ++i) {
104 c->R[i] = c->initR[i];
105 }
106 }
107
108 /* Initialise "konst"
109 */
110 static void s128_genkonst(sober128_state *c)
111 {
112 ulong32 newkonst;
113
114 do {
115 cycle(c->R);
116 newkonst = nltap(c);
117 } while ((newkonst & 0xFF000000) == 0);
118 c->konst = newkonst;
119 }
120
121 /* Load key material into the register
122 */
123 #define ADDKEY(k) \
124 c->R[KEYP] += (k);
125
126 #define XORNL(nl) \
127 c->R[FOLDP] ^= (nl);
128
129 /* nonlinear diffusion of register for key */
130 #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t;
131 static void s128_diffuse(sober128_state *c)
132 {
133 ulong32 t;
134 /* relies on FOLD == N == 17! */
135 DROUND(0);
136 DROUND(1);
137 DROUND(2);
138 DROUND(3);
139 DROUND(4);
140 DROUND(5);
141 DROUND(6);
142 DROUND(7);
143 DROUND(8);
144 DROUND(9);
145 DROUND(10);
146 DROUND(11);
147 DROUND(12);
148 DROUND(13);
149 DROUND(14);
150 DROUND(15);
151 DROUND(16);
152 }
153
154 /**
155 Initialize an Sober128 context (only the key)
156 @param c [out] The destination of the Sober128 state
157 @param key The secret key
158 @param keylen The length of the secret key (octets)
159 @return CRYPT_OK if successful
160 */
161 int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned long keylen)
162 {
163 ulong32 i, k;
164
165 LTC_ARGCHK(c != NULL);
166 LTC_ARGCHK(key != NULL);
167 LTC_ARGCHK(keylen > 0);
168
169 /* keylen must be multiple of 4 bytes */
170 if ((keylen & 3) != 0) {
171 return CRYPT_INVALID_KEYSIZE;
172 }
173
174 /* Register initialised to Fibonacci numbers */
175 c->R[0] = 1;
176 c->R[1] = 1;
177 for (i = 2; i < N; ++i) {
178 c->R[i] = c->R[i-1] + c->R[i-2];
179 }
180 c->konst = INITKONST;
181
182 for (i = 0; i < keylen; i += 4) {
183 k = BYTE2WORD((unsigned char *)&key[i]);
184 ADDKEY(k);
185 cycle(c->R);
186 XORNL(nltap(c));
187 }
188
189 /* also fold in the length of the key */
190 ADDKEY(keylen);
191
192 /* now diffuse */
193 s128_diffuse(c);
194 s128_genkonst(c);
195 s128_savestate(c);
196 c->nbuf = 0;
197
198 return CRYPT_OK;
199 }
200
201 /**
202 Set IV to the Sober128 state
203 @param c The Sober12820 state
204 @param iv The IV data to add
205 @param ivlen The length of the IV (must be 12)
206 @return CRYPT_OK on success
207 */
208 int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen)
209 {
210 ulong32 i, k;
211
212 LTC_ARGCHK(c != NULL);
213 LTC_ARGCHK(iv != NULL);
214 LTC_ARGCHK(ivlen > 0);
215
216 /* ok we are adding an IV then... */
217 s128_reloadstate(c);
218
219 /* ivlen must be multiple of 4 bytes */
220 if ((ivlen & 3) != 0) {
221 return CRYPT_INVALID_KEYSIZE;
222 }
223
224 for (i = 0; i < ivlen; i += 4) {
225 k = BYTE2WORD((unsigned char *)&iv[i]);
226 ADDKEY(k);
227 cycle(c->R);
228 XORNL(nltap(c));
229 }
230
231 /* also fold in the length of the key */
232 ADDKEY(ivlen);
233
234 /* now diffuse */
235 s128_diffuse(c);
236 c->nbuf = 0;
237
238 return CRYPT_OK;
239 }
240
241 /* XOR pseudo-random bytes into buffer
242 */
243 #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, in+(z*4), out+(z*4));
244
245 /**
246 Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128
247 @param c The Sober128 state
248 @param in The plaintext (or ciphertext)
249 @param inlen The length of the input (octets)
250 @param out [out] The ciphertext (or plaintext), length inlen
251 @return CRYPT_OK if successful
252 */
253 int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out)
254 {
255 ulong32 t;
256
257 if (inlen == 0) return CRYPT_OK; /* nothing to do */
258 LTC_ARGCHK(out != NULL);
259 LTC_ARGCHK(c != NULL);
260
261 /* handle any previously buffered bytes */
262 while (c->nbuf != 0 && inlen != 0) {
263 *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF);
264 c->sbuf >>= 8;
265 c->nbuf -= 8;
266 --inlen;
267 }
268
269 #ifndef LTC_SMALL_CODE
270 /* do lots at a time, if there's enough to do */
271 while (inlen >= N*4) {
272 SROUND(0);
273 SROUND(1);
274 SROUND(2);
275 SROUND(3);
276 SROUND(4);
277 SROUND(5);
278 SROUND(6);
279 SROUND(7);
280 SROUND(8);
281 SROUND(9);
282 SROUND(10);
283 SROUND(11);
284 SROUND(12);
285 SROUND(13);
286 SROUND(14);
287 SROUND(15);
288 SROUND(16);
289 out += 4*N;
290 in += 4*N;
291 inlen -= 4*N;
292 }
293 #endif
294
295 /* do small or odd size buffers the slow way */
296 while (4 <= inlen) {
297 cycle(c->R);
298 t = nltap(c);
299 XORWORD(t, in, out);
300 out += 4;
301 in += 4;
302 inlen -= 4;
303 }
304
305 /* handle any trailing bytes */
306 if (inlen != 0) {
307 cycle(c->R);
308 c->sbuf = nltap(c);
309 c->nbuf = 32;
310 while (c->nbuf != 0 && inlen != 0) {
311 *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF);
312 c->sbuf >>= 8;
313 c->nbuf -= 8;
314 --inlen;
315 }
316 }
317
318 return CRYPT_OK;
319 }
320
321 int sober128_stream_keystream(sober128_state *c, unsigned char *out, unsigned long outlen)
322 {
323 if (outlen == 0) return CRYPT_OK; /* nothing to do */
324 LTC_ARGCHK(out != NULL);
325 XMEMSET(out, 0, outlen);
326 return sober128_stream_crypt(c, out, outlen, out);
327 }
328
329 /**
330 Terminate and clear Sober128 state
331 @param c The Sober128 state
332 @return CRYPT_OK on success
333 */
334 int sober128_stream_done(sober128_state *c)
335 {
336 LTC_ARGCHK(c != NULL);
337 XMEMSET(c, 0, sizeof(sober128_state));
338 return CRYPT_OK;
339 }
340
341 #endif
342
343 /* ref: $Format:%D$ */
344 /* git commit: $Format:%H$ */
345 /* commit time: $Format:%ai$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10 /**
11 @file sober128_stream.c
12 Implementation of SOBER-128 by Tom St Denis.
13 Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
14 */
15
16 #ifdef LTC_SOBER128
17
18 #define __LTC_SOBER128TAB_C__
19 #include "sober128tab.c"
20
21 /* don't change these... */
22 #define N 17
23 #define FOLD N /* how many iterations of folding to do */
24 #define INITKONST 0x6996c53a /* value of KONST to use during key loading */
25 #define KEYP 15 /* where to insert key words */
26 #define FOLDP 4 /* where to insert non-linear feedback */
27
28 #define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF))
29
30 static ulong32 BYTE2WORD(unsigned char *b)
31 {
32 ulong32 t;
33 LOAD32L(t, b);
34 return t;
35 }
36
37 static void XORWORD(ulong32 w, const unsigned char *in, unsigned char *out)
38 {
39 ulong32 t;
40 LOAD32L(t, in);
41 t ^= w;
42 STORE32L(t, out);
43 }
44
45 /* give correct offset for the current position of the register,
46 * where logically R[0] is at position "zero".
47 */
48 #define OFF(zero, i) (((zero)+(i)) % N)
49
50 /* step the LFSR */
51 /* After stepping, "zero" moves right one place */
52 #define STEP(R,z) \
53 R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
54
55 static void cycle(ulong32 *R)
56 {
57 ulong32 t;
58 int i;
59
60 STEP(R,0);
61 t = R[0];
62 for (i = 1; i < N; ++i) {
63 R[i-1] = R[i];
64 }
65 R[N-1] = t;
66 }
67
68 /* Return a non-linear function of some parts of the register.
69 */
70 #define NLFUNC(c,z) \
71 { \
72 t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \
73 t ^= Sbox[(t >> 24) & 0xFF]; \
74 t = RORc(t, 8); \
75 t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \
76 t ^= Sbox[(t >> 24) & 0xFF]; \
77 t = t + c->R[OFF(z,13)]; \
78 }
79
80 static ulong32 nltap(sober128_state *c)
81 {
82 ulong32 t;
83 NLFUNC(c, 0);
84 return t;
85 }
86
87 /* Save the current register state
88 */
89 static void s128_savestate(sober128_state *c)
90 {
91 int i;
92 for (i = 0; i < N; ++i) {
93 c->initR[i] = c->R[i];
94 }
95 }
96
97 /* initialise to previously saved register state
98 */
99 static void s128_reloadstate(sober128_state *c)
100 {
101 int i;
102
103 for (i = 0; i < N; ++i) {
104 c->R[i] = c->initR[i];
105 }
106 }
107
108 /* Initialise "konst"
109 */
110 static void s128_genkonst(sober128_state *c)
111 {
112 ulong32 newkonst;
113
114 do {
115 cycle(c->R);
116 newkonst = nltap(c);
117 } while ((newkonst & 0xFF000000) == 0);
118 c->konst = newkonst;
119 }
120
121 /* Load key material into the register
122 */
123 #define ADDKEY(k) \
124 c->R[KEYP] += (k);
125
126 #define XORNL(nl) \
127 c->R[FOLDP] ^= (nl);
128
129 /* nonlinear diffusion of register for key */
130 #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t;
131 static void s128_diffuse(sober128_state *c)
132 {
133 ulong32 t;
134 /* relies on FOLD == N == 17! */
135 DROUND(0);
136 DROUND(1);
137 DROUND(2);
138 DROUND(3);
139 DROUND(4);
140 DROUND(5);
141 DROUND(6);
142 DROUND(7);
143 DROUND(8);
144 DROUND(9);
145 DROUND(10);
146 DROUND(11);
147 DROUND(12);
148 DROUND(13);
149 DROUND(14);
150 DROUND(15);
151 DROUND(16);
152 }
153
154 /**
155 Initialize an Sober128 context (only the key)
156 @param c [out] The destination of the Sober128 state
157 @param key The secret key
158 @param keylen The length of the secret key (octets)
159 @return CRYPT_OK if successful
160 */
161 int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned long keylen)
162 {
163 ulong32 i, k;
164
165 LTC_ARGCHK(c != NULL);
166 LTC_ARGCHK(key != NULL);
167 LTC_ARGCHK(keylen > 0);
168
169 /* keylen must be multiple of 4 bytes */
170 if ((keylen & 3) != 0) {
171 return CRYPT_INVALID_KEYSIZE;
172 }
173
174 /* Register initialised to Fibonacci numbers */
175 c->R[0] = 1;
176 c->R[1] = 1;
177 for (i = 2; i < N; ++i) {
178 c->R[i] = c->R[i-1] + c->R[i-2];
179 }
180 c->konst = INITKONST;
181
182 for (i = 0; i < keylen; i += 4) {
183 k = BYTE2WORD((unsigned char *)&key[i]);
184 ADDKEY(k);
185 cycle(c->R);
186 XORNL(nltap(c));
187 }
188
189 /* also fold in the length of the key */
190 ADDKEY(keylen);
191
192 /* now diffuse */
193 s128_diffuse(c);
194 s128_genkonst(c);
195 s128_savestate(c);
196 c->nbuf = 0;
197
198 return CRYPT_OK;
199 }
200
201 /**
202 Set IV to the Sober128 state
203 @param c The Sober12820 state
204 @param iv The IV data to add
205 @param ivlen The length of the IV (must be 12)
206 @return CRYPT_OK on success
207 */
208 int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen)
209 {
210 ulong32 i, k;
211
212 LTC_ARGCHK(c != NULL);
213 LTC_ARGCHK(iv != NULL);
214 LTC_ARGCHK(ivlen > 0);
215
216 /* ok we are adding an IV then... */
217 s128_reloadstate(c);
218
219 /* ivlen must be multiple of 4 bytes */
220 if ((ivlen & 3) != 0) {
221 return CRYPT_INVALID_KEYSIZE;
222 }
223
224 for (i = 0; i < ivlen; i += 4) {
225 k = BYTE2WORD((unsigned char *)&iv[i]);
226 ADDKEY(k);
227 cycle(c->R);
228 XORNL(nltap(c));
229 }
230
231 /* also fold in the length of the key */
232 ADDKEY(ivlen);
233
234 /* now diffuse */
235 s128_diffuse(c);
236 c->nbuf = 0;
237
238 return CRYPT_OK;
239 }
240
241 /* XOR pseudo-random bytes into buffer
242 */
243 #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, in+(z*4), out+(z*4));
244
245 /**
246 Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128
247 @param c The Sober128 state
248 @param in The plaintext (or ciphertext)
249 @param inlen The length of the input (octets)
250 @param out [out] The ciphertext (or plaintext), length inlen
251 @return CRYPT_OK if successful
252 */
253 int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out)
254 {
255 ulong32 t;
256
257 if (inlen == 0) return CRYPT_OK; /* nothing to do */
258 LTC_ARGCHK(out != NULL);
259 LTC_ARGCHK(c != NULL);
260
261 /* handle any previously buffered bytes */
262 while (c->nbuf != 0 && inlen != 0) {
263 *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF);
264 c->sbuf >>= 8;
265 c->nbuf -= 8;
266 --inlen;
267 }
268
269 #ifndef LTC_SMALL_CODE
270 /* do lots at a time, if there's enough to do */
271 while (inlen >= N*4) {
272 SROUND(0);
273 SROUND(1);
274 SROUND(2);
275 SROUND(3);
276 SROUND(4);
277 SROUND(5);
278 SROUND(6);
279 SROUND(7);
280 SROUND(8);
281 SROUND(9);
282 SROUND(10);
283 SROUND(11);
284 SROUND(12);
285 SROUND(13);
286 SROUND(14);
287 SROUND(15);
288 SROUND(16);
289 out += 4*N;
290 in += 4*N;
291 inlen -= 4*N;
292 }
293 #endif
294
295 /* do small or odd size buffers the slow way */
296 while (4 <= inlen) {
297 cycle(c->R);
298 t = nltap(c);
299 XORWORD(t, in, out);
300 out += 4;
301 in += 4;
302 inlen -= 4;
303 }
304
305 /* handle any trailing bytes */
306 if (inlen != 0) {
307 cycle(c->R);
308 c->sbuf = nltap(c);
309 c->nbuf = 32;
310 while (c->nbuf != 0 && inlen != 0) {
311 *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF);
312 c->sbuf >>= 8;
313 c->nbuf -= 8;
314 --inlen;
315 }
316 }
317
318 return CRYPT_OK;
319 }
320
321 int sober128_stream_keystream(sober128_state *c, unsigned char *out, unsigned long outlen)
322 {
323 if (outlen == 0) return CRYPT_OK; /* nothing to do */
324 LTC_ARGCHK(out != NULL);
325 XMEMSET(out, 0, outlen);
326 return sober128_stream_crypt(c, out, outlen, out);
327 }
328
329 /**
330 Terminate and clear Sober128 state
331 @param c The Sober128 state
332 @return CRYPT_OK on success
333 */
334 int sober128_stream_done(sober128_state *c)
335 {
336 LTC_ARGCHK(c != NULL);
337 XMEMSET(c, 0, sizeof(sober128_state));
338 return CRYPT_OK;
339 }
340
341 #endif
342
343 /* ref: $Format:%D$ */
344 /* git commit: $Format:%H$ */
345 /* commit time: $Format:%ai$ */