ltc update (serpent,idea)
Karel Miko
6 years ago
0 | 0 | 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 \ | |
40 | 40 | ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/radix_to_bin.o \ |
41 | 41 | ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \ |
42 | 42 | ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/crc32.o \ |
114 | 114 | ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \ |
115 | 115 | ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \ |
116 | 116 | 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 \ | |
118 | 118 | ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o \ |
119 | 119 | ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o \ |
120 | 120 | 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 \ |
0 | 0 | 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 \ | |
8 | 8 | ltc/encauth/chachapoly/chacha20poly1305_decrypt.obj ltc/encauth/chachapoly/chacha20poly1305_done.obj \ |
9 | 9 | ltc/encauth/chachapoly/chacha20poly1305_encrypt.obj ltc/encauth/chachapoly/chacha20poly1305_init.obj \ |
10 | 10 | ltc/encauth/chachapoly/chacha20poly1305_memory.obj ltc/encauth/chachapoly/chacha20poly1305_setiv.obj \ |
122 | 122 | ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \ |
123 | 123 | ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \ |
124 | 124 | 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 \ | |
126 | 126 | ltm/bncore.obj ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj ltm/bn_fast_mp_montgomery_reduce.obj \ |
127 | 127 | ltm/bn_fast_s_mp_mul_digs.obj ltm/bn_fast_s_mp_mul_high_digs.obj ltm/bn_fast_s_mp_sqr.obj \ |
128 | 128 | 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$ */ |
23 | 23 | @param out The ciphertext |
24 | 24 | @param tag [out] The MAC tag |
25 | 25 | @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) | |
27 | 27 | @return CRYPT_OK on success |
28 | 28 | */ |
29 | 29 | int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, |
48 | 48 | if (aad && aadlen > 0) { |
49 | 49 | if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; } |
50 | 50 | } |
51 | if (direction == CHCHA20POLY1305_ENCRYPT) { | |
51 | if (direction == CHACHA20POLY1305_ENCRYPT) { | |
52 | 52 | if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } |
53 | 53 | } |
54 | else if (direction == CHCHA20POLY1305_DECRYPT) { | |
54 | else if (direction == CHACHA20POLY1305_DECRYPT) { | |
55 | 55 | if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } |
56 | 56 | } |
57 | 57 | else { |
276 | 276 | #define LTC_HAVE_BSWAP_BUILTIN |
277 | 277 | #endif |
278 | 278 | |
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 | |
279 | 286 | |
280 | 287 | /* ref: $Format:%D$ */ |
281 | 288 | /* git commit: $Format:%H$ */ |
153 | 153 | }; |
154 | 154 | #endif |
155 | 155 | |
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 | ||
156 | 173 | typedef union Symmetric_key { |
157 | 174 | #ifdef LTC_DES |
158 | 175 | struct des_key des; |
211 | 228 | #endif |
212 | 229 | #ifdef LTC_CAMELLIA |
213 | 230 | 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; | |
214 | 237 | #endif |
215 | 238 | void *data; |
216 | 239 | } symmetric_key; |
815 | 838 | extern const struct ltc_cipher_descriptor camellia_desc; |
816 | 839 | #endif |
817 | 840 | |
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 | ||
818 | 861 | #ifdef LTC_ECB_MODE |
819 | 862 | int ecb_start(int cipher, const unsigned char *key, |
820 | 863 | int keylen, int num_rounds, symmetric_ECB *ecb); |
201 | 201 | #define LTC_KASUMI |
202 | 202 | #define LTC_MULTI2 |
203 | 203 | #define LTC_CAMELLIA |
204 | #define LTC_IDEA | |
205 | #define LTC_SERPENT | |
204 | 206 | |
205 | 207 | /* stream ciphers */ |
206 | 208 | #define LTC_CHACHA |
541 | 541 | int aadflg; |
542 | 542 | } chacha20poly1305_state; |
543 | 543 | |
544 | #define CHCHA20POLY1305_ENCRYPT LTC_ENCRYPT | |
545 | #define CHCHA20POLY1305_DECRYPT LTC_DECRYPT | |
544 | #define CHACHA20POLY1305_ENCRYPT LTC_ENCRYPT | |
545 | #define CHACHA20POLY1305_DECRYPT LTC_DECRYPT | |
546 | 546 | |
547 | 547 | int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen); |
548 | 548 | int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen); |
72 | 72 | int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size); |
73 | 73 | |
74 | 74 | #ifdef LTM_DESC |
75 | void init_LTM(void); | |
75 | LTC_DEPRECATED void init_LTM(void); | |
76 | 76 | #endif |
77 | 77 | #ifdef TFM_DESC |
78 | void init_TFM(void); | |
78 | LTC_DEPRECATED void init_TFM(void); | |
79 | 79 | #endif |
80 | 80 | #ifdef GMP_DESC |
81 | void init_GMP(void); | |
81 | LTC_DEPRECATED void init_GMP(void); | |
82 | 82 | #endif |
83 | int crypt_mp_init(const char* mpi); | |
83 | 84 | |
84 | 85 | #ifdef LTC_ADLER32 |
85 | 86 | typedef struct adler32_state_s |
121 | 121 | #if defined(LTC_CAMELLIA) |
122 | 122 | " Camellia\n" |
123 | 123 | #endif |
124 | #if defined(LTC_IDEA) | |
125 | " IDEA\n" | |
126 | #endif | |
127 | #if defined(LTC_SERPENT) | |
128 | " Serpent\n" | |
129 | #endif | |
124 | 130 | "Stream ciphers built-in:\n" |
125 | 131 | #if defined(LTC_CHACHA) |
126 | 132 | " ChaCha\n" |
36 | 36 | } |
37 | 37 | #endif |
38 | 38 | |
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 | ||
39 | 87 | |
40 | 88 | /* ref: $Format:%D$ */ |
41 | 89 | /* git commit: $Format:%H$ */ |
93 | 93 | #ifdef LTC_CAMELLIA |
94 | 94 | REGISTER_CIPHER(&camellia_desc); |
95 | 95 | #endif |
96 | #ifdef LTC_IDEA | |
97 | REGISTER_CIPHER(&idea_desc); | |
98 | #endif | |
99 | #ifdef LTC_SERPENT | |
100 | REGISTER_CIPHER(&serpent_desc); | |
101 | #endif | |
96 | 102 | return err; |
97 | 103 | } |
98 | 104 |
97 | 97 | _SZ_STRINGIFY_S(des_key), |
98 | 98 | _SZ_STRINGIFY_S(des3_key), |
99 | 99 | #endif |
100 | #ifdef LTC_IDEA | |
101 | _SZ_STRINGIFY_S(idea_key), | |
102 | #endif | |
100 | 103 | #ifdef LTC_KASUMI |
101 | 104 | _SZ_STRINGIFY_S(kasumi_key), |
102 | 105 | #endif |
120 | 123 | #endif |
121 | 124 | #ifdef LTC_RC6 |
122 | 125 | _SZ_STRINGIFY_S(rc6_key), |
126 | #endif | |
127 | #ifdef LTC_SERPENT | |
128 | _SZ_STRINGIFY_S(serpent_key), | |
123 | 129 | #endif |
124 | 130 | #ifdef LTC_SKIPJACK |
125 | 131 | _SZ_STRINGIFY_S(skipjack_key), |
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 | /* 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$ */ |