2 * Copyright (C) 2011, 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.
19 #include <kripto/cast.h>
20 #include <kripto/loadstore.h>
21 #include <kripto/rotate.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/rc5.h>
31 struct kripto_block_object obj
;
37 #define RC5_K_LEN(r) (((r) << 1) + 2)
49 const unsigned int ls
= (key_len
+ 3) >> 2;
54 for(i
= 0; i
< ls
; i
++) x
[i
] = 0;
56 for(j
= key_len
- 1; j
!= UINT_MAX
; j
--)
57 x
[j
>> 2] = (x
[j
>> 2] << 8) | key
[j
];
60 for(i
= 1; i
< RC5_K_LEN(s
->rounds
); i
++)
61 s
->k
[i
] = s
->k
[i
-1] + 0x9E3779B9;
63 a
= b
= i
= j
= k
= 0;
64 while(k
< RC5_K_LEN(s
->rounds
) * 3)
66 a
= s
->k
[i
] = ROL32(s
->k
[i
] + a
+ b
, 3);
67 b
= x
[j
] = ROL32(x
[j
] + a
+ b
, a
+ b
);
68 if(++i
== RC5_K_LEN(s
->rounds
)) i
= 0;
74 kripto_memwipe(x
, ls
<< 2);
75 kripto_memwipe(&a
, sizeof(uint32_t));
76 kripto_memwipe(&b
, sizeof(uint32_t));
79 static void rc5_encrypt(const kripto_block
*s
, const void *pt
, void *ct
)
86 b
= LOAD32L(CU8(pt
) + 4);
91 while(i
< s
->rounds
<< 1)
93 a
= ROL32(a
^ b
, b
& 31) + s
->k
[i
++];
94 b
= ROL32(b
^ a
, a
& 31) + s
->k
[i
++];
98 STORE32L(b
, U8(ct
) + 4);
101 static void rc5_decrypt(const kripto_block
*s
, const void *ct
, void *pt
)
105 unsigned int i
= s
->rounds
<< 1;
107 a
= LOAD32L(CU8(ct
));
108 b
= LOAD32L(CU8(ct
) + 4);
112 b
= ROR32(b
- s
->k
[i
], a
& 31) ^ a
;
114 a
= ROR32(a
- s
->k
[i
], b
& 31) ^ b
;
121 STORE32L(b
, U8(pt
) + 4);
124 static kripto_block
*rc5_create
135 s
= malloc(sizeof(kripto_block
) + (RC5_K_LEN(r
) << 2));
138 s
->obj
.desc
= kripto_block_rc5
;
139 s
->size
= sizeof(kripto_block
) + (RC5_K_LEN(r
) << 2);
141 s
->k
= (uint32_t *)((uint8_t *)s
+ sizeof(kripto_block
));
143 rc5_setup(s
, key
, key_len
);
148 static void rc5_destroy(kripto_block
*s
)
150 kripto_memwipe(s
, s
->size
);
154 static kripto_block
*rc5_recreate
164 if(sizeof(kripto_block
) + (RC5_K_LEN(r
) << 2) > s
->size
)
167 s
= rc5_create(r
, key
, key_len
);
172 rc5_setup(s
, key
, key_len
);
178 static const kripto_block_desc rc5
=
190 const kripto_block_desc
*const kripto_block_rc5
= &rc5
;