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.
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 */
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>
31 struct kripto_block_object obj
;
37 static void xtea_setup
45 uint32_t k
[4] = {0, 0, 0, 0};
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;
56 s
->k
[i
++] = c
+ k
[c
% key_len
];
57 if(i
== s
->rounds
) break;
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);
75 x0
+= F(x1
) ^ s
->k
[i
++];
77 if(i
== s
->rounds
) break;
79 x1
+= F(x0
) ^ s
->k
[i
++];
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;
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
116 s
= malloc(sizeof(kripto_block
) + (r
<< 2));
119 s
->obj
.desc
= kripto_block_xtea
;
120 s
->size
= sizeof(kripto_block
) + (r
<< 2);
122 s
->k
= (uint32_t *)((uint8_t *)s
+ sizeof(kripto_block
));
124 xtea_setup(s
, key
, key_len
);
129 static void xtea_destroy(kripto_block
*s
)
131 kripto_memwipe(s
, s
->size
);
135 static kripto_block
*xtea_recreate
145 if(sizeof(kripto_block
) + (r
<< 2) > s
->size
)
148 s
= xtea_create(r
, key
, key_len
);
153 xtea_setup(s
, key
, key_len
);
159 static const kripto_block_desc xtea
=
172 const kripto_block_desc
*const kripto_block_xtea
= &xtea
;