skein_api.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * Copyright (c) 2010 Werner Dittmann
  3. *
  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
  11. * conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  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.
  24. */
  25. #include <linux/string.h>
  26. #include "skein_api.h"
  27. int skein_ctx_prepare(struct skein_ctx *ctx, enum skein_size size)
  28. {
  29. skein_assert_ret(ctx && size, SKEIN_FAIL);
  30. memset(ctx, 0, sizeof(struct skein_ctx));
  31. ctx->skein_size = size;
  32. return SKEIN_SUCCESS;
  33. }
  34. int skein_init(struct skein_ctx *ctx, size_t hash_bit_len)
  35. {
  36. int ret = SKEIN_FAIL;
  37. size_t x_len = 0;
  38. u64 *x = NULL;
  39. u64 tree_info = SKEIN_CFG_TREE_INFO_SEQUENTIAL;
  40. skein_assert_ret(ctx, SKEIN_FAIL);
  41. /*
  42. * The following two lines rely of the fact that the real Skein
  43. * contexts are a union in out context and thus have tha maximum
  44. * memory available. The beauty of C :-) .
  45. */
  46. x = ctx->m.s256.x;
  47. x_len = ctx->skein_size / 8;
  48. /*
  49. * If size is the same and hash bit length is zero then reuse
  50. * the save chaining variables.
  51. */
  52. switch (ctx->skein_size) {
  53. case SKEIN_256:
  54. ret = skein_256_init_ext(&ctx->m.s256, hash_bit_len,
  55. tree_info, NULL, 0);
  56. break;
  57. case SKEIN_512:
  58. ret = skein_512_init_ext(&ctx->m.s512, hash_bit_len,
  59. tree_info, NULL, 0);
  60. break;
  61. case SKEIN_1024:
  62. ret = skein_1024_init_ext(&ctx->m.s1024, hash_bit_len,
  63. tree_info, NULL, 0);
  64. break;
  65. }
  66. if (ret == SKEIN_SUCCESS) {
  67. /*
  68. * Save chaining variables for this combination of size and
  69. * hash_bit_len
  70. */
  71. memcpy(ctx->x_save, x, x_len);
  72. }
  73. return ret;
  74. }
  75. int skein_mac_init(struct skein_ctx *ctx, const u8 *key, size_t key_len,
  76. size_t hash_bit_len)
  77. {
  78. int ret = SKEIN_FAIL;
  79. u64 *x = NULL;
  80. size_t x_len = 0;
  81. u64 tree_info = SKEIN_CFG_TREE_INFO_SEQUENTIAL;
  82. skein_assert_ret(ctx, SKEIN_FAIL);
  83. x = ctx->m.s256.x;
  84. x_len = ctx->skein_size / 8;
  85. skein_assert_ret(hash_bit_len, SKEIN_BAD_HASHLEN);
  86. switch (ctx->skein_size) {
  87. case SKEIN_256:
  88. ret = skein_256_init_ext(&ctx->m.s256, hash_bit_len,
  89. tree_info,
  90. (const u8 *)key, key_len);
  91. break;
  92. case SKEIN_512:
  93. ret = skein_512_init_ext(&ctx->m.s512, hash_bit_len,
  94. tree_info,
  95. (const u8 *)key, key_len);
  96. break;
  97. case SKEIN_1024:
  98. ret = skein_1024_init_ext(&ctx->m.s1024, hash_bit_len,
  99. tree_info,
  100. (const u8 *)key, key_len);
  101. break;
  102. }
  103. if (ret == SKEIN_SUCCESS) {
  104. /*
  105. * Save chaining variables for this combination of key,
  106. * key_len, hash_bit_len
  107. */
  108. memcpy(ctx->x_save, x, x_len);
  109. }
  110. return ret;
  111. }
  112. void skein_reset(struct skein_ctx *ctx)
  113. {
  114. size_t x_len = 0;
  115. u64 *x;
  116. /*
  117. * The following two lines rely of the fact that the real Skein
  118. * contexts are a union in out context and thus have tha maximum
  119. * memory available. The beautiy of C :-) .
  120. */
  121. x = ctx->m.s256.x;
  122. x_len = ctx->skein_size / 8;
  123. /* Restore the chaing variable, reset byte counter */
  124. memcpy(x, ctx->x_save, x_len);
  125. /* Setup context to process the message */
  126. skein_start_new_type(&ctx->m, MSG);
  127. }
  128. int skein_update(struct skein_ctx *ctx, const u8 *msg,
  129. size_t msg_byte_cnt)
  130. {
  131. int ret = SKEIN_FAIL;
  132. skein_assert_ret(ctx, SKEIN_FAIL);
  133. switch (ctx->skein_size) {
  134. case SKEIN_256:
  135. ret = skein_256_update(&ctx->m.s256, (const u8 *)msg,
  136. msg_byte_cnt);
  137. break;
  138. case SKEIN_512:
  139. ret = skein_512_update(&ctx->m.s512, (const u8 *)msg,
  140. msg_byte_cnt);
  141. break;
  142. case SKEIN_1024:
  143. ret = skein_1024_update(&ctx->m.s1024, (const u8 *)msg,
  144. msg_byte_cnt);
  145. break;
  146. }
  147. return ret;
  148. }
  149. int skein_update_bits(struct skein_ctx *ctx, const u8 *msg,
  150. size_t msg_bit_cnt)
  151. {
  152. /*
  153. * I've used the bit pad implementation from skein_test.c (see NIST CD)
  154. * and modified it to use the convenience functions and added some
  155. * pointer arithmetic.
  156. */
  157. size_t length;
  158. u8 mask;
  159. u8 *up;
  160. /*
  161. * only the final Update() call is allowed do partial bytes, else
  162. * assert an error
  163. */
  164. skein_assert_ret((ctx->m.h.T[1] & SKEIN_T1_FLAG_BIT_PAD) == 0 ||
  165. msg_bit_cnt == 0, SKEIN_FAIL);
  166. /* if number of bits is a multiple of bytes - that's easy */
  167. if ((msg_bit_cnt & 0x7) == 0)
  168. return skein_update(ctx, msg, msg_bit_cnt >> 3);
  169. skein_update(ctx, msg, (msg_bit_cnt >> 3) + 1);
  170. /*
  171. * The next line rely on the fact that the real Skein contexts
  172. * are a union in our context. After the addition the pointer points to
  173. * Skein's real partial block buffer.
  174. * If this layout ever changes we have to adapt this as well.
  175. */
  176. up = (u8 *)ctx->m.s256.x + ctx->skein_size / 8;
  177. /* set tweak flag for the skein_final call */
  178. skein_set_bit_pad_flag(ctx->m.h);
  179. /* now "pad" the final partial byte the way NIST likes */
  180. /* get the b_cnt value (same location for all block sizes) */
  181. length = ctx->m.h.b_cnt;
  182. /* internal sanity check: there IS a partial byte in the buffer! */
  183. skein_assert(length != 0);
  184. /* partial byte bit mask */
  185. mask = (u8) (1u << (7 - (msg_bit_cnt & 7)));
  186. /* apply bit padding on final byte (in the buffer) */
  187. up[length - 1] = (u8)((up[length - 1] & (0 - mask)) | mask);
  188. return SKEIN_SUCCESS;
  189. }
  190. int skein_final(struct skein_ctx *ctx, u8 *hash)
  191. {
  192. int ret = SKEIN_FAIL;
  193. skein_assert_ret(ctx, SKEIN_FAIL);
  194. switch (ctx->skein_size) {
  195. case SKEIN_256:
  196. ret = skein_256_final(&ctx->m.s256, (u8 *)hash);
  197. break;
  198. case SKEIN_512:
  199. ret = skein_512_final(&ctx->m.s512, (u8 *)hash);
  200. break;
  201. case SKEIN_1024:
  202. ret = skein_1024_final(&ctx->m.s1024, (u8 *)hash);
  203. break;
  204. }
  205. return ret;
  206. }