2 * Copyright (c) 2010 Werner Dittmann
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <linux/string.h>
27 #include "skein_api.h"
29 int skein_ctx_prepare(struct skein_ctx
*ctx
, enum skein_size size
)
31 skein_assert_ret(ctx
&& size
, SKEIN_FAIL
);
33 memset(ctx
, 0, sizeof(struct skein_ctx
));
34 ctx
->skein_size
= size
;
39 int skein_init(struct skein_ctx
*ctx
, size_t hash_bit_len
)
44 u64 tree_info
= SKEIN_CFG_TREE_INFO_SEQUENTIAL
;
46 skein_assert_ret(ctx
, SKEIN_FAIL
);
48 * The following two lines rely of the fact that the real Skein
49 * contexts are a union in out context and thus have tha maximum
50 * memory available. The beauty of C :-) .
53 x_len
= ctx
->skein_size
/ 8;
55 * If size is the same and hash bit length is zero then reuse
56 * the save chaining variables.
58 switch (ctx
->skein_size
) {
60 ret
= skein_256_init_ext(&ctx
->m
.s256
, hash_bit_len
,
64 ret
= skein_512_init_ext(&ctx
->m
.s512
, hash_bit_len
,
68 ret
= skein_1024_init_ext(&ctx
->m
.s1024
, hash_bit_len
,
73 if (ret
== SKEIN_SUCCESS
) {
75 * Save chaining variables for this combination of size and
78 memcpy(ctx
->x_save
, x
, x_len
);
83 int skein_mac_init(struct skein_ctx
*ctx
, const u8
*key
, size_t key_len
,
89 u64 tree_info
= SKEIN_CFG_TREE_INFO_SEQUENTIAL
;
91 skein_assert_ret(ctx
, SKEIN_FAIL
);
94 x_len
= ctx
->skein_size
/ 8;
96 skein_assert_ret(hash_bit_len
, SKEIN_BAD_HASHLEN
);
98 switch (ctx
->skein_size
) {
100 ret
= skein_256_init_ext(&ctx
->m
.s256
, hash_bit_len
,
102 (const u8
*)key
, key_len
);
106 ret
= skein_512_init_ext(&ctx
->m
.s512
, hash_bit_len
,
108 (const u8
*)key
, key_len
);
111 ret
= skein_1024_init_ext(&ctx
->m
.s1024
, hash_bit_len
,
113 (const u8
*)key
, key_len
);
117 if (ret
== SKEIN_SUCCESS
) {
119 * Save chaining variables for this combination of key,
120 * key_len, hash_bit_len
122 memcpy(ctx
->x_save
, x
, x_len
);
127 void skein_reset(struct skein_ctx
*ctx
)
133 * The following two lines rely of the fact that the real Skein
134 * contexts are a union in out context and thus have tha maximum
135 * memory available. The beautiy of C :-) .
138 x_len
= ctx
->skein_size
/ 8;
139 /* Restore the chaing variable, reset byte counter */
140 memcpy(x
, ctx
->x_save
, x_len
);
142 /* Setup context to process the message */
143 skein_start_new_type(&ctx
->m
, MSG
);
146 int skein_update(struct skein_ctx
*ctx
, const u8
*msg
,
149 int ret
= SKEIN_FAIL
;
151 skein_assert_ret(ctx
, SKEIN_FAIL
);
153 switch (ctx
->skein_size
) {
155 ret
= skein_256_update(&ctx
->m
.s256
, (const u8
*)msg
,
159 ret
= skein_512_update(&ctx
->m
.s512
, (const u8
*)msg
,
163 ret
= skein_1024_update(&ctx
->m
.s1024
, (const u8
*)msg
,
171 int skein_update_bits(struct skein_ctx
*ctx
, const u8
*msg
,
175 * I've used the bit pad implementation from skein_test.c (see NIST CD)
176 * and modified it to use the convenience functions and added some
177 * pointer arithmetic.
184 * only the final Update() call is allowed do partial bytes, else
187 skein_assert_ret((ctx
->m
.h
.T
[1] & SKEIN_T1_FLAG_BIT_PAD
) == 0 ||
188 msg_bit_cnt
== 0, SKEIN_FAIL
);
190 /* if number of bits is a multiple of bytes - that's easy */
191 if ((msg_bit_cnt
& 0x7) == 0)
192 return skein_update(ctx
, msg
, msg_bit_cnt
>> 3);
194 skein_update(ctx
, msg
, (msg_bit_cnt
>> 3) + 1);
197 * The next line rely on the fact that the real Skein contexts
198 * are a union in our context. After the addition the pointer points to
199 * Skein's real partial block buffer.
200 * If this layout ever changes we have to adapt this as well.
202 up
= (u8
*)ctx
->m
.s256
.x
+ ctx
->skein_size
/ 8;
204 /* set tweak flag for the skein_final call */
205 skein_set_bit_pad_flag(ctx
->m
.h
);
207 /* now "pad" the final partial byte the way NIST likes */
208 /* get the b_cnt value (same location for all block sizes) */
209 length
= ctx
->m
.h
.b_cnt
;
210 /* internal sanity check: there IS a partial byte in the buffer! */
211 skein_assert(length
!= 0);
212 /* partial byte bit mask */
213 mask
= (u8
) (1u << (7 - (msg_bit_cnt
& 7)));
214 /* apply bit padding on final byte (in the buffer) */
215 up
[length
- 1] = (u8
)((up
[length
- 1] & (0 - mask
)) | mask
);
217 return SKEIN_SUCCESS
;
220 int skein_final(struct skein_ctx
*ctx
, u8
*hash
)
222 int ret
= SKEIN_FAIL
;
224 skein_assert_ret(ctx
, SKEIN_FAIL
);
226 switch (ctx
->skein_size
) {
228 ret
= skein_256_final(&ctx
->m
.s256
, (u8
*)hash
);
231 ret
= skein_512_final(&ctx
->m
.s512
, (u8
*)hash
);
234 ret
= skein_1024_final(&ctx
->m
.s1024
, (u8
*)hash
);