shash.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Synchronous Cryptographic Hash operations.
  3. *
  4. * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the Free
  8. * Software Foundation; either version 2 of the License, or (at your option)
  9. * any later version.
  10. *
  11. */
  12. #include <crypto/internal/hash.h>
  13. #include <linux/err.h>
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/slab.h>
  17. #include <linux/seq_file.h>
  18. static inline struct crypto_shash *__crypto_shash_cast(struct crypto_tfm *tfm)
  19. {
  20. return container_of(tfm, struct crypto_shash, base);
  21. }
  22. static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
  23. unsigned int keylen)
  24. {
  25. struct shash_alg *shash = crypto_shash_alg(tfm);
  26. unsigned long alignmask = crypto_shash_alignmask(tfm);
  27. unsigned long absize;
  28. u8 *buffer, *alignbuffer;
  29. int err;
  30. absize = keylen + (alignmask & ~(CRYPTO_MINALIGN - 1));
  31. buffer = kmalloc(absize, GFP_KERNEL);
  32. if (!buffer)
  33. return -ENOMEM;
  34. alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
  35. memcpy(alignbuffer, key, keylen);
  36. err = shash->setkey(tfm, alignbuffer, keylen);
  37. memset(alignbuffer, 0, keylen);
  38. kfree(buffer);
  39. return err;
  40. }
  41. int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
  42. unsigned int keylen)
  43. {
  44. struct shash_alg *shash = crypto_shash_alg(tfm);
  45. unsigned long alignmask = crypto_shash_alignmask(tfm);
  46. if ((unsigned long)key & alignmask)
  47. return shash_setkey_unaligned(tfm, key, keylen);
  48. return shash->setkey(tfm, key, keylen);
  49. }
  50. EXPORT_SYMBOL_GPL(crypto_shash_setkey);
  51. static inline unsigned int shash_align_buffer_size(unsigned len,
  52. unsigned long mask)
  53. {
  54. return len + (mask & ~(__alignof__(u8 __attribute__ ((aligned))) - 1));
  55. }
  56. static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
  57. unsigned int len)
  58. {
  59. struct crypto_shash *tfm = desc->tfm;
  60. struct shash_alg *shash = crypto_shash_alg(tfm);
  61. unsigned long alignmask = crypto_shash_alignmask(tfm);
  62. unsigned int unaligned_len = alignmask + 1 -
  63. ((unsigned long)data & alignmask);
  64. u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
  65. __attribute__ ((aligned));
  66. memcpy(buf, data, unaligned_len);
  67. return shash->update(desc, buf, unaligned_len) ?:
  68. shash->update(desc, data + unaligned_len, len - unaligned_len);
  69. }
  70. int crypto_shash_update(struct shash_desc *desc, const u8 *data,
  71. unsigned int len)
  72. {
  73. struct crypto_shash *tfm = desc->tfm;
  74. struct shash_alg *shash = crypto_shash_alg(tfm);
  75. unsigned long alignmask = crypto_shash_alignmask(tfm);
  76. if ((unsigned long)data & alignmask)
  77. return shash_update_unaligned(desc, data, len);
  78. return shash->update(desc, data, len);
  79. }
  80. EXPORT_SYMBOL_GPL(crypto_shash_update);
  81. static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
  82. {
  83. struct crypto_shash *tfm = desc->tfm;
  84. unsigned long alignmask = crypto_shash_alignmask(tfm);
  85. struct shash_alg *shash = crypto_shash_alg(tfm);
  86. unsigned int ds = crypto_shash_digestsize(tfm);
  87. u8 buf[shash_align_buffer_size(ds, alignmask)]
  88. __attribute__ ((aligned));
  89. int err;
  90. err = shash->final(desc, buf);
  91. memcpy(out, buf, ds);
  92. return err;
  93. }
  94. int crypto_shash_final(struct shash_desc *desc, u8 *out)
  95. {
  96. struct crypto_shash *tfm = desc->tfm;
  97. struct shash_alg *shash = crypto_shash_alg(tfm);
  98. unsigned long alignmask = crypto_shash_alignmask(tfm);
  99. if ((unsigned long)out & alignmask)
  100. return shash_final_unaligned(desc, out);
  101. return shash->final(desc, out);
  102. }
  103. EXPORT_SYMBOL_GPL(crypto_shash_final);
  104. static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data,
  105. unsigned int len, u8 *out)
  106. {
  107. return crypto_shash_update(desc, data, len) ?:
  108. crypto_shash_final(desc, out);
  109. }
  110. int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
  111. unsigned int len, u8 *out)
  112. {
  113. struct crypto_shash *tfm = desc->tfm;
  114. struct shash_alg *shash = crypto_shash_alg(tfm);
  115. unsigned long alignmask = crypto_shash_alignmask(tfm);
  116. if (((unsigned long)data | (unsigned long)out) & alignmask ||
  117. !shash->finup)
  118. return shash_finup_unaligned(desc, data, len, out);
  119. return shash->finup(desc, data, len, out);
  120. }
  121. EXPORT_SYMBOL_GPL(crypto_shash_finup);
  122. static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data,
  123. unsigned int len, u8 *out)
  124. {
  125. return crypto_shash_init(desc) ?:
  126. crypto_shash_update(desc, data, len) ?:
  127. crypto_shash_final(desc, out);
  128. }
  129. int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
  130. unsigned int len, u8 *out)
  131. {
  132. struct crypto_shash *tfm = desc->tfm;
  133. struct shash_alg *shash = crypto_shash_alg(tfm);
  134. unsigned long alignmask = crypto_shash_alignmask(tfm);
  135. if (((unsigned long)data | (unsigned long)out) & alignmask ||
  136. !shash->digest)
  137. return shash_digest_unaligned(desc, data, len, out);
  138. return shash->digest(desc, data, len, out);
  139. }
  140. EXPORT_SYMBOL_GPL(crypto_shash_digest);
  141. static int crypto_shash_init_tfm(struct crypto_tfm *tfm,
  142. const struct crypto_type *frontend)
  143. {
  144. if (frontend->type != CRYPTO_ALG_TYPE_SHASH)
  145. return -EINVAL;
  146. return 0;
  147. }
  148. static unsigned int crypto_shash_extsize(struct crypto_alg *alg,
  149. const struct crypto_type *frontend)
  150. {
  151. return alg->cra_ctxsize;
  152. }
  153. static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
  154. __attribute__ ((unused));
  155. static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
  156. {
  157. struct shash_alg *salg = __crypto_shash_alg(alg);
  158. seq_printf(m, "type : shash\n");
  159. seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
  160. seq_printf(m, "digestsize : %u\n", salg->digestsize);
  161. seq_printf(m, "descsize : %u\n", salg->descsize);
  162. }
  163. static const struct crypto_type crypto_shash_type = {
  164. .extsize = crypto_shash_extsize,
  165. .init_tfm = crypto_shash_init_tfm,
  166. #ifdef CONFIG_PROC_FS
  167. .show = crypto_shash_show,
  168. #endif
  169. .maskclear = ~CRYPTO_ALG_TYPE_MASK,
  170. .maskset = CRYPTO_ALG_TYPE_MASK,
  171. .type = CRYPTO_ALG_TYPE_SHASH,
  172. .tfmsize = offsetof(struct crypto_shash, base),
  173. };
  174. struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
  175. u32 mask)
  176. {
  177. return __crypto_shash_cast(
  178. crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask));
  179. }
  180. EXPORT_SYMBOL_GPL(crypto_alloc_shash);
  181. int crypto_register_shash(struct shash_alg *alg)
  182. {
  183. struct crypto_alg *base = &alg->base;
  184. if (alg->digestsize > PAGE_SIZE / 8 ||
  185. alg->descsize > PAGE_SIZE / 8)
  186. return -EINVAL;
  187. base->cra_type = &crypto_shash_type;
  188. base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
  189. base->cra_flags |= CRYPTO_ALG_TYPE_SHASH;
  190. return crypto_register_alg(base);
  191. }
  192. EXPORT_SYMBOL_GPL(crypto_register_shash);
  193. int crypto_unregister_shash(struct shash_alg *alg)
  194. {
  195. return crypto_unregister_alg(&alg->base);
  196. }
  197. EXPORT_SYMBOL_GPL(crypto_unregister_shash);
  198. MODULE_LICENSE("GPL");
  199. MODULE_DESCRIPTION("Synchronous cryptographic hash type");