hash.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Cryptographic Hash operations.
  3. *
  4. * Copyright (c) 2006 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. #include <crypto/internal/hash.h>
  12. #include <linux/errno.h>
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/slab.h>
  16. #include <linux/seq_file.h>
  17. #include "internal.h"
  18. static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type,
  19. u32 mask)
  20. {
  21. return alg->cra_ctxsize;
  22. }
  23. static int hash_setkey_unaligned(struct crypto_hash *crt, const u8 *key,
  24. unsigned int keylen)
  25. {
  26. struct crypto_tfm *tfm = crypto_hash_tfm(crt);
  27. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  28. unsigned long alignmask = crypto_hash_alignmask(crt);
  29. int ret;
  30. u8 *buffer, *alignbuffer;
  31. unsigned long absize;
  32. absize = keylen + alignmask;
  33. buffer = kmalloc(absize, GFP_ATOMIC);
  34. if (!buffer)
  35. return -ENOMEM;
  36. alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
  37. memcpy(alignbuffer, key, keylen);
  38. ret = alg->setkey(crt, alignbuffer, keylen);
  39. memset(alignbuffer, 0, keylen);
  40. kfree(buffer);
  41. return ret;
  42. }
  43. static int hash_setkey(struct crypto_hash *crt, const u8 *key,
  44. unsigned int keylen)
  45. {
  46. struct crypto_tfm *tfm = crypto_hash_tfm(crt);
  47. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  48. unsigned long alignmask = crypto_hash_alignmask(crt);
  49. if ((unsigned long)key & alignmask)
  50. return hash_setkey_unaligned(crt, key, keylen);
  51. return alg->setkey(crt, key, keylen);
  52. }
  53. static int hash_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
  54. unsigned int keylen)
  55. {
  56. struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async);
  57. struct crypto_hash *tfm_hash = __crypto_hash_cast(tfm);
  58. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  59. return alg->setkey(tfm_hash, key, keylen);
  60. }
  61. static int hash_async_init(struct ahash_request *req)
  62. {
  63. struct crypto_tfm *tfm = req->base.tfm;
  64. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  65. struct hash_desc desc = {
  66. .tfm = __crypto_hash_cast(tfm),
  67. .flags = req->base.flags,
  68. };
  69. return alg->init(&desc);
  70. }
  71. static int hash_async_update(struct ahash_request *req)
  72. {
  73. struct crypto_tfm *tfm = req->base.tfm;
  74. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  75. struct hash_desc desc = {
  76. .tfm = __crypto_hash_cast(tfm),
  77. .flags = req->base.flags,
  78. };
  79. return alg->update(&desc, req->src, req->nbytes);
  80. }
  81. static int hash_async_final(struct ahash_request *req)
  82. {
  83. struct crypto_tfm *tfm = req->base.tfm;
  84. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  85. struct hash_desc desc = {
  86. .tfm = __crypto_hash_cast(tfm),
  87. .flags = req->base.flags,
  88. };
  89. return alg->final(&desc, req->result);
  90. }
  91. static int hash_async_digest(struct ahash_request *req)
  92. {
  93. struct crypto_tfm *tfm = req->base.tfm;
  94. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  95. struct hash_desc desc = {
  96. .tfm = __crypto_hash_cast(tfm),
  97. .flags = req->base.flags,
  98. };
  99. return alg->digest(&desc, req->src, req->nbytes, req->result);
  100. }
  101. static int crypto_init_hash_ops_async(struct crypto_tfm *tfm)
  102. {
  103. struct ahash_tfm *crt = &tfm->crt_ahash;
  104. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  105. crt->init = hash_async_init;
  106. crt->update = hash_async_update;
  107. crt->final = hash_async_final;
  108. crt->digest = hash_async_digest;
  109. crt->setkey = hash_async_setkey;
  110. crt->digestsize = alg->digestsize;
  111. return 0;
  112. }
  113. static int crypto_init_hash_ops_sync(struct crypto_tfm *tfm)
  114. {
  115. struct hash_tfm *crt = &tfm->crt_hash;
  116. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  117. crt->init = alg->init;
  118. crt->update = alg->update;
  119. crt->final = alg->final;
  120. crt->digest = alg->digest;
  121. crt->setkey = hash_setkey;
  122. crt->digestsize = alg->digestsize;
  123. return 0;
  124. }
  125. static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
  126. {
  127. struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  128. if (alg->digestsize > PAGE_SIZE / 8)
  129. return -EINVAL;
  130. if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK)
  131. return crypto_init_hash_ops_async(tfm);
  132. else
  133. return crypto_init_hash_ops_sync(tfm);
  134. }
  135. static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
  136. __attribute__ ((unused));
  137. static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
  138. {
  139. seq_printf(m, "type : hash\n");
  140. seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
  141. seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize);
  142. }
  143. const struct crypto_type crypto_hash_type = {
  144. .ctxsize = crypto_hash_ctxsize,
  145. .init = crypto_init_hash_ops,
  146. #ifdef CONFIG_PROC_FS
  147. .show = crypto_hash_show,
  148. #endif
  149. };
  150. EXPORT_SYMBOL_GPL(crypto_hash_type);
  151. MODULE_LICENSE("GPL");
  152. MODULE_DESCRIPTION("Generic cryptographic hash type");