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/>.
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.h>
30 struct kripto_block_object obj
;
49 const unsigned int ls
= (key_len
+ 3) >> 2;
51 for(i
= 0; i
< ls
; i
++) x
[i
] = 0;
53 for(j
= key_len
- 1; j
!= UINT_MAX
; j
--)
54 x
[j
>> 2] = (x
[j
>> 2] << 8) | key
[j
];
57 for(i
= 1; i
< ((s
->r
+ 1) << 1); i
++)
58 s
->k
[i
] = s
->k
[i
- 1] + 0x9E3779B9;
60 a
= b
= i
= j
= k
= 0;
61 while(k
< (s
->r
+ 1) * 6)
63 a
= s
->k
[i
] = ROL32_03(s
->k
[i
] + a
+ b
);
64 b
= x
[j
] = ROL32(x
[j
] + a
+ b
, a
+ b
);
65 if(++i
== ((s
->r
+ 1) << 1)) i
= 0;
70 kripto_memwipe(x
, ls
<< 2);
71 kripto_memwipe(&a
, sizeof(uint32_t));
72 kripto_memwipe(&b
, sizeof(uint32_t));
75 static void rc5_encrypt(const kripto_block
*s
, const void *pt
, void *ct
)
82 b
= LOAD32L(CU8(pt
) + 4);
89 a
^= b
; a
= ROL32(a
, b
) + s
->k
[i
++];
90 b
^= a
; b
= ROL32(b
, a
) + s
->k
[i
++];
94 STORE32L(b
, U8(ct
) + 4);
97 static void rc5_decrypt(const kripto_block
*s
, const void *ct
, void *pt
)
101 unsigned int i
= (s
->r
+ 1) << 1;
103 a
= LOAD32L(CU8(ct
));
104 b
= LOAD32L(CU8(ct
) + 4);
108 b
-= s
->k
[--i
]; b
= ROR32(b
, a
) ^ a
;
109 a
-= s
->k
[--i
]; a
= ROR32(a
, b
) ^ b
;
116 STORE32L(b
, U8(pt
) + 4);
119 static kripto_block
*rc5_create
130 s
= malloc(sizeof(kripto_block
) + ((r
+ 1) << 3));
133 s
->obj
.desc
= kripto_block_rc5
;
134 s
->size
= sizeof(kripto_block
) + ((r
+ 1) << 3);
136 s
->k
= (uint32_t *)((uint8_t *)s
+ sizeof(kripto_block
));
138 rc5_setup(s
, key
, key_len
);
143 static void rc5_destroy(kripto_block
*s
)
145 kripto_memwipe(s
, s
->size
);
149 static kripto_block
*rc5_recreate
159 if(sizeof(kripto_block
) + ((r
+ 1) << 3) > s
->size
)
162 s
= rc5_create(r
, key
, key_len
);
167 rc5_setup(s
, key
, key_len
);
173 static const kripto_block_desc rc5
=
186 const kripto_block_desc
*const kripto_block_rc5
= &rc5
;