maxtweak added to block
[rofl0r-kripto.git] / lib / block / rc5_64.c
blob3e4ec6bc0895eff9ac0d99dd4f838cceba160dce
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 #include <stdint.h>
15 #include <stdlib.h>
16 #include <limits.h>
18 #include <kripto/cast.h>
19 #include <kripto/loadstore.h>
20 #include <kripto/rotate.h>
21 #include <kripto/memwipe.h>
22 #include <kripto/block.h>
23 #include <kripto/desc/block.h>
24 #include <kripto/object/block.h>
26 #include <kripto/block/rc5_64.h>
28 struct kripto_block
30 struct kripto_block_object obj;
31 unsigned int r;
32 size_t size;
33 uint64_t *k;
36 static void rc5_64_setup
38 kripto_block *s,
39 const uint8_t *key,
40 unsigned int key_len
43 unsigned int i;
44 unsigned int j;
45 unsigned int k;
46 uint64_t a;
47 uint64_t b;
48 uint64_t x[32];
49 const unsigned int ls = (key_len + 7) >> 3;
51 for(i = 0; i < ls; i++) x[i] = 0;
53 for(j = key_len - 1; j != UINT_MAX; j--)
54 x[j >> 3] = (x[j >> 3] << 8) | key[j];
56 *s->k = 0xB7E151628AED2A6B;
57 for(i = 1; i < ((s->r + 1) << 1); i++)
58 s->k[i] = s->k[i - 1] + 0x9E3779B97F4A7C15;
60 a = b = i = j = k = 0;
61 while(k < (s->r + 1) * 6)
63 a = s->k[i] = ROL64_03(s->k[i] + a + b);
64 b = x[j] = ROL64(x[j] + a + b, a + b);
65 if(++i == ((s->r + 1) << 1)) i = 0;
66 if(++j == ls) j = 0;
67 k++;
70 kripto_memwipe(x, ls << 3);
71 kripto_memwipe(&a, sizeof(uint64_t));
72 kripto_memwipe(&b, sizeof(uint64_t));
75 static void rc5_64_encrypt(const kripto_block *s, const void *pt, void *ct)
77 uint64_t a;
78 uint64_t b;
79 unsigned int i = 2;
81 a = LOAD64L(CU8(pt));
82 b = LOAD64L(CU8(pt) + 8);
84 a += s->k[0];
85 b += s->k[1];
87 while(i <= s->r << 1)
89 a ^= b; a = ROL64(a, b) + s->k[i++];
90 b ^= a; b = ROL64(b, a) + s->k[i++];
93 STORE64L(a, U8(ct));
94 STORE64L(b, U8(ct) + 8);
97 static void rc5_64_decrypt(const kripto_block *s, const void *ct, void *pt)
99 uint64_t a;
100 uint64_t b;
101 unsigned int i = (s->r + 1) << 1;
103 a = LOAD64L(CU8(ct));
104 b = LOAD64L(CU8(ct) + 8);
106 while(i > 2)
108 b -= s->k[--i]; b = ROR64(b, a) ^ a;
109 a -= s->k[--i]; a = ROR64(a, b) ^ b;
112 b -= s->k[1];
113 a -= s->k[0];
115 STORE64L(a, U8(pt));
116 STORE64L(b, U8(pt) + 8);
119 static kripto_block *rc5_64_create
121 unsigned int r,
122 const void *key,
123 unsigned int key_len
126 kripto_block *s;
128 if(!r) r = 16;
130 s = malloc(sizeof(kripto_block) + ((r + 1) << 4));
131 if(!s) return 0;
133 s->obj.desc = kripto_block_rc5_64;
134 s->size = sizeof(kripto_block) + ((r + 1) << 4);
135 s->r = r;
136 s->k = (uint64_t *)((uint8_t *)s + sizeof(kripto_block));
138 rc5_64_setup(s, key, key_len);
140 return s;
143 static void rc5_64_destroy(kripto_block *s)
145 kripto_memwipe(s, s->size);
146 free(s);
149 static kripto_block *rc5_64_recreate
151 kripto_block *s,
152 unsigned int r,
153 const void *key,
154 unsigned int key_len
157 if(!r) r = 16;
159 if(sizeof(kripto_block) + ((r + 1) << 4) > s->size)
161 rc5_64_destroy(s);
162 s = rc5_64_create(r, key, key_len);
164 else
166 s->r = r;
167 rc5_64_setup(s, key, key_len);
170 return s;
173 static const kripto_block_desc rc5_64 =
175 &rc5_64_create,
176 &rc5_64_recreate,
177 0, /* tweak */
178 &rc5_64_encrypt,
179 &rc5_64_decrypt,
180 &rc5_64_destroy,
181 16, /* block size */
182 255, /* max key */
183 0 /* max tweak */
186 const kripto_block_desc *const kripto_block_rc5_64 = &rc5_64;