status update, probably last commit
[rofl0r-kripto.git] / lib / block / speck32.c
blobe4b0bca4378b9dff86a92cd720328b3b786dbabd
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/speck32.h>
28 struct kripto_block
30 struct kripto_block_object obj;
31 unsigned int rounds;
32 size_t size;
33 uint16_t *k;
36 #define R(A, B, K) \
37 { \
38 A = (ROR16_07(A) + B) ^ (K); \
39 B = ROL16_02(B) ^ A; \
42 #define IR(A, B, K) \
43 { \
44 B = ROR16_02(B ^ A); \
45 A = ROL16_07((A ^ (K)) - B); \
48 static void speck32_encrypt
50 const kripto_block *s,
51 const void *pt,
52 void *ct
55 uint16_t a;
56 uint16_t b;
57 unsigned int i;
59 a = LOAD16B(CU8(pt));
60 b = LOAD16B(CU8(pt) + 2);
62 for(i = 0; i < s->rounds; i++)
63 R(a, b, s->k[i]);
65 STORE16B(a, U8(ct));
66 STORE16B(b, U8(ct) + 2);
69 static void speck32_decrypt
71 const kripto_block *s,
72 const void *ct,
73 void *pt
76 uint16_t a;
77 uint16_t b;
78 unsigned int i;
80 a = LOAD16B(CU8(ct));
81 b = LOAD16B(CU8(ct) + 2);
83 for(i = s->rounds; i--;)
84 IR(a, b, s->k[i]);
86 STORE16B(a, U8(pt));
87 STORE16B(b, U8(pt) + 2);
90 static void speck32_setup
92 kripto_block *s,
93 const uint8_t *key,
94 unsigned int len
97 unsigned int i;
98 uint16_t k[4] = {0, 0, 0, 0};
100 for(i = 0; i < len; i++)
101 k[3 - (i >> 1)] |= (uint16_t)key[i] << (8 - ((i & 1) << 3));
103 s->k[0] = k[0];
105 for(i = 0; i < s->rounds - 1;)
107 R(k[(i % 3) + 1], k[0], i);
108 s->k[++i] = k[0];
111 kripto_memwipe(k, 8);
114 static kripto_block *speck32_create
116 unsigned int r,
117 const void *key,
118 unsigned int key_len
121 kripto_block *s;
123 if(!r) r = 22;
125 s = malloc(sizeof(kripto_block) + (r << 1));
126 if(!s) return 0;
128 s->obj.desc = kripto_block_speck32;
129 s->size = sizeof(kripto_block) + (r << 1);
130 s->k = (uint16_t *)(((uint8_t *)s) + sizeof(kripto_block));
131 s->rounds = r;
133 speck32_setup(s, key, key_len);
135 return s;
138 static void speck32_destroy(kripto_block *s)
140 kripto_memwipe(s, s->size);
141 free(s);
144 static kripto_block *speck32_recreate
146 kripto_block *s,
147 unsigned int r,
148 const void *key,
149 unsigned int key_len
152 if(!r) r = 22;
154 if(sizeof(kripto_block) + (r << 1) > s->size)
156 speck32_destroy(s);
157 s = speck32_create(r, key, key_len);
159 else
161 s->rounds = r;
162 speck32_setup(s, key, key_len);
165 return s;
168 static const kripto_block_desc speck32 =
170 &speck32_create,
171 &speck32_recreate,
172 0, /* tweak */
173 &speck32_encrypt,
174 &speck32_decrypt,
175 &speck32_destroy,
176 4, /* block size */
177 8, /* max key */
178 0 /* max tweak */
181 const kripto_block_desc *const kripto_block_speck32 = &speck32;