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.
21 #include <kripto/cast.h>
22 #include <kripto/loadstore.h>
23 #include <kripto/memwipe.h>
24 #include <kripto/block.h>
25 #include <kripto/block/threefish1024.h>
26 #include <kripto/mac.h>
27 #include <kripto/desc/mac.h>
28 #include <kripto/object/mac.h>
30 #include <kripto/mac/skein1024.h>
34 struct kripto_mac_object obj
;
44 #define POS_ADD(TWEAK, ADD) \
64 static void skein1024_process(kripto_mac
*s
)
68 (void)kripto_block_recreate(s
->block
, s
->r
, s
->h
, 128);
69 kripto_block_tweak(s
->block
, s
->tweak
, 16);
70 kripto_block_encrypt(s
->block
, s
->buf
, s
->h
);
72 for(i
= 0; i
< 128; i
++) s
->h
[i
] ^= s
->buf
[i
];
75 static kripto_mac
*skein1024_recreate
91 memset(s
->tweak
, 0, 16);
96 s
->tweak
[15] = 0x40; /* type KEY, first */
100 if(key_len
> 128) block
= 128;
101 else block
= key_len
;
103 memcpy(s
->buf
, key
, block
);
104 memset(s
->buf
, 0, 128 - block
);
106 POS_ADD(s
->tweak
, block
);
110 if(!key_len
) s
->tweak
[15] |= 0x80; /* add final */
112 skein1024_process(s
);
114 s
->tweak
[15] &= 0xBF; /* remove first */
126 STORE64L(t
, s
->buf
+ 8);
127 memset(s
->buf
+ 16, 0, 112);
129 s
->tweak
[15] = 0xC4; /* type CFG, first, final */
130 skein1024_process(s
);
134 s
->tweak
[15] = 0x70; /* type MSG, first */
139 static void skein1024_input
148 for(i
= 0; i
< len
; i
++)
150 s
->buf
[s
->i
++] = CU8(in
)[i
];
154 POS_ADD(s
->tweak
, 128);
156 skein1024_process(s
);
157 s
->tweak
[15] = 0x30; /* type MSG */
163 static void skein1024_finish(kripto_mac
*s
)
165 POS_ADD(s
->tweak
, s
->i
);
167 memset(s
->buf
+ s
->i
, 0, 128 - s
->i
);
168 s
->tweak
[15] |= 0x80; /* add final */
169 skein1024_process(s
);
171 memset(s
->buf
, 0, 128);
172 memset(s
->tweak
, 0, 12);
173 s
->tweak
[0] = 8; /* 8 byte counter */
174 s
->tweak
[15] = 0xFF; /* type OUT, first, final */
175 skein1024_process(s
);
181 static void skein1024_tag(kripto_mac
*s
, void *tag
, unsigned int len
)
183 assert(s
->i
+ len
<= 128);
185 if(!s
->f
) skein1024_finish(s
);
187 memcpy(tag
, s
->h
+ s
->i
, len
);
191 static kripto_mac
*skein1024_create
193 const kripto_mac_desc
*desc
,
196 unsigned int key_len
,
204 s
= malloc(sizeof(kripto_mac
));
207 s
->obj
.desc
= kripto_mac_skein1024
;
209 s
->block
= kripto_block_create(kripto_block_threefish1024
, r
, "", 1);
216 (void)skein1024_recreate(s
, r
, key
, key_len
, tag_len
);
221 static void skein1024_destroy(kripto_mac
*s
)
223 kripto_block_destroy(s
->block
);
224 kripto_memwipe(s
, sizeof(kripto_mac
));
228 static const kripto_mac_desc skein1024
=
238 const kripto_mac_desc
*const kripto_mac_skein1024
= &skein1024
;