2 * Copyright (C) 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
15 /* this XTEA implementation is big endian */
21 #include <kripto/cast.h>
22 #include <kripto/loadstore.h>
23 #include <kripto/rotate.h>
24 #include <kripto/memwipe.h>
25 #include <kripto/block.h>
26 #include <kripto/desc/block.h>
27 #include <kripto/object/block.h>
29 #include <kripto/block/xtea.h>
33 struct kripto_block_object obj
;
39 static void xtea_setup
47 uint32_t k
[4] = {0, 0, 0, 0};
51 for(i
= 0; i
< key_len
; i
++)
52 k
[i
>> 2] |= key
[i
] << (24 - ((i
& 3) << 3));
54 key_len
= (key_len
+ 3) >> 2;
58 s
->k
[i
++] = c
+ k
[c
% key_len
];
59 if(i
== s
->rounds
) break;
61 s
->k
[i
++] = c
+ k
[(c
>> 11) % key_len
];
64 kripto_memwipe(k
, 16);
67 #define F(X) ((((X) << 4) ^ ((X) >> 5)) + (X))
69 static void xtea_encrypt(const kripto_block
*s
, const void *pt
, void *ct
)
71 uint32_t x0
= LOAD32B(CU8(pt
));
72 uint32_t x1
= LOAD32B(CU8(pt
) + 4);
77 x0
+= F(x1
) ^ s
->k
[i
++];
79 if(i
== s
->rounds
) break;
81 x1
+= F(x0
) ^ s
->k
[i
++];
85 STORE32B(x1
, U8(ct
) + 4);
88 static void xtea_decrypt(const kripto_block
*s
, const void *ct
, void *pt
)
90 uint32_t x0
= LOAD32B(CU8(ct
));
91 uint32_t x1
= LOAD32B(CU8(ct
) + 4);
92 unsigned int i
= s
->rounds
- 1;
96 x1
-= F(x0
) ^ s
->k
[i
--];
98 if(i
== UINT_MAX
) break;
100 x0
-= F(x1
) ^ s
->k
[i
--];
103 STORE32B(x0
, U8(pt
));
104 STORE32B(x1
, U8(pt
) + 4);
107 static kripto_block
*xtea_create
118 s
= malloc(sizeof(kripto_block
) + (r
<< 2));
121 s
->obj
.desc
= kripto_block_xtea
;
122 s
->size
= sizeof(kripto_block
) + (r
<< 2);
124 s
->k
= (uint32_t *)((uint8_t *)s
+ sizeof(kripto_block
));
126 xtea_setup(s
, key
, key_len
);
131 static void xtea_destroy(kripto_block
*s
)
133 kripto_memwipe(s
, s
->size
);
137 static kripto_block
*xtea_recreate
147 if(sizeof(kripto_block
) + (r
<< 2) > s
->size
)
150 s
= xtea_create(r
, key
, key_len
);
155 xtea_setup(s
, key
, key_len
);
161 static const kripto_block_desc xtea
=
173 const kripto_block_desc
*const kripto_block_xtea
= &xtea
;