maxtweak added to block
[rofl0r-kripto.git] / lib / block / xtea.c
blob8e3373c8050b52cbea12f4f503f3b7b53b07d29a
1 /*
2 * Written in 2013 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
7 *
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
14 /* this XTEA implementation is big endian */
16 #include <stdint.h>
17 #include <stdlib.h>
18 #include <limits.h>
20 #include <kripto/cast.h>
21 #include <kripto/loadstore.h>
22 #include <kripto/memwipe.h>
23 #include <kripto/block.h>
24 #include <kripto/desc/block.h>
25 #include <kripto/object/block.h>
27 #include <kripto/block/xtea.h>
29 struct kripto_block
31 struct kripto_block_object obj;
32 unsigned int rounds;
33 size_t size;
34 uint32_t *k;
37 static void xtea_setup
39 kripto_block *s,
40 const uint8_t *key,
41 unsigned int key_len
44 uint32_t c = 0;
45 uint32_t k[4] = {0, 0, 0, 0};
46 unsigned int i;
48 /* big endian */
49 for(i = 0; i < key_len; i++)
50 k[i >> 2] |= key[i] << (24 - ((i & 3) << 3));
52 key_len = (key_len + 3) >> 2;
53 i = 0;
54 while(i < s->rounds)
56 s->k[i++] = c + k[c % key_len];
57 if(i == s->rounds) break;
58 c += 0x9E3779B9;
59 s->k[i++] = c + k[(c >> 11) % key_len];
62 kripto_memwipe(k, 16);
65 #define F(X) ((((X) << 4) ^ ((X) >> 5)) + (X))
67 static void xtea_encrypt(const kripto_block *s, const void *pt, void *ct)
69 uint32_t x0 = LOAD32B(CU8(pt));
70 uint32_t x1 = LOAD32B(CU8(pt) + 4);
71 unsigned int i = 0;
73 while(i < s->rounds)
75 x0 += F(x1) ^ s->k[i++];
77 if(i == s->rounds) break;
79 x1 += F(x0) ^ s->k[i++];
82 STORE32B(x0, U8(ct));
83 STORE32B(x1, U8(ct) + 4);
86 static void xtea_decrypt(const kripto_block *s, const void *ct, void *pt)
88 uint32_t x0 = LOAD32B(CU8(ct));
89 uint32_t x1 = LOAD32B(CU8(ct) + 4);
90 unsigned int i = s->rounds - 1;
92 while(i != UINT_MAX)
94 x1 -= F(x0) ^ s->k[i--];
96 if(i == UINT_MAX) break;
98 x0 -= F(x1) ^ s->k[i--];
101 STORE32B(x0, U8(pt));
102 STORE32B(x1, U8(pt) + 4);
105 static kripto_block *xtea_create
107 unsigned int r,
108 const void *key,
109 unsigned int key_len
112 kripto_block *s;
114 if(!r) r = 64;
116 s = malloc(sizeof(kripto_block) + (r << 2));
117 if(!s) return 0;
119 s->obj.desc = kripto_block_xtea;
120 s->size = sizeof(kripto_block) + (r << 2);
121 s->rounds = r;
122 s->k = (uint32_t *)((uint8_t *)s + sizeof(kripto_block));
124 xtea_setup(s, key, key_len);
126 return s;
129 static void xtea_destroy(kripto_block *s)
131 kripto_memwipe(s, s->size);
132 free(s);
135 static kripto_block *xtea_recreate
137 kripto_block *s,
138 unsigned int r,
139 const void *key,
140 unsigned int key_len
143 if(!r) r = 64;
145 if(sizeof(kripto_block) + (r << 2) > s->size)
147 xtea_destroy(s);
148 s = xtea_create(r, key, key_len);
150 else
152 s->rounds = r;
153 xtea_setup(s, key, key_len);
156 return s;
159 static const kripto_block_desc xtea =
161 &xtea_create,
162 &xtea_recreate,
163 0, /* tweak */
164 &xtea_encrypt,
165 &xtea_decrypt,
166 &xtea_destroy,
167 8, /* block size */
168 16, /* max key */
169 0 /* max tweak */
172 const kripto_block_desc *const kripto_block_xtea = &xtea;