sha_common.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Cryptographic API.
  4. *
  5. * s390 generic implementation of the SHA Secure Hash Algorithms.
  6. *
  7. * Copyright IBM Corp. 2007
  8. * Author(s): Jan Glauber (jang@de.ibm.com)
  9. */
  10. #include <crypto/internal/hash.h>
  11. #include <linux/module.h>
  12. #include <asm/cpacf.h>
  13. #include "sha.h"
  14. int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
  15. {
  16. struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
  17. unsigned int bsize = crypto_shash_blocksize(desc->tfm);
  18. unsigned int index, n;
  19. int fc;
  20. /* how much is already in the buffer? */
  21. index = ctx->count % bsize;
  22. ctx->count += len;
  23. if ((index + len) < bsize)
  24. goto store;
  25. fc = ctx->func;
  26. if (ctx->first_message_part)
  27. fc |= test_facility(86) ? CPACF_KIMD_NIP : 0;
  28. /* process one stored block */
  29. if (index) {
  30. memcpy(ctx->buf + index, data, bsize - index);
  31. cpacf_kimd(fc, ctx->state, ctx->buf, bsize);
  32. ctx->first_message_part = 0;
  33. fc &= ~CPACF_KIMD_NIP;
  34. data += bsize - index;
  35. len -= bsize - index;
  36. index = 0;
  37. }
  38. /* process as many blocks as possible */
  39. if (len >= bsize) {
  40. n = (len / bsize) * bsize;
  41. cpacf_kimd(fc, ctx->state, data, n);
  42. ctx->first_message_part = 0;
  43. data += n;
  44. len -= n;
  45. }
  46. store:
  47. if (len)
  48. memcpy(ctx->buf + index , data, len);
  49. return 0;
  50. }
  51. EXPORT_SYMBOL_GPL(s390_sha_update);
  52. static int s390_crypto_shash_parmsize(int func)
  53. {
  54. switch (func) {
  55. case CPACF_KLMD_SHA_1:
  56. return 20;
  57. case CPACF_KLMD_SHA_256:
  58. return 32;
  59. case CPACF_KLMD_SHA_512:
  60. return 64;
  61. case CPACF_KLMD_SHA3_224:
  62. case CPACF_KLMD_SHA3_256:
  63. case CPACF_KLMD_SHA3_384:
  64. case CPACF_KLMD_SHA3_512:
  65. return 200;
  66. default:
  67. return -EINVAL;
  68. }
  69. }
  70. int s390_sha_final(struct shash_desc *desc, u8 *out)
  71. {
  72. struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
  73. unsigned int bsize = crypto_shash_blocksize(desc->tfm);
  74. u64 bits;
  75. unsigned int n;
  76. int mbl_offset, fc;
  77. n = ctx->count % bsize;
  78. bits = ctx->count * 8;
  79. mbl_offset = s390_crypto_shash_parmsize(ctx->func);
  80. if (mbl_offset < 0)
  81. return -EINVAL;
  82. mbl_offset = mbl_offset / sizeof(u32);
  83. /* set total msg bit length (mbl) in CPACF parmblock */
  84. switch (ctx->func) {
  85. case CPACF_KLMD_SHA_1:
  86. case CPACF_KLMD_SHA_256:
  87. memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
  88. break;
  89. case CPACF_KLMD_SHA_512:
  90. /*
  91. * the SHA512 parmblock has a 128-bit mbl field, clear
  92. * high-order u64 field, copy bits to low-order u64 field
  93. */
  94. memset(ctx->state + mbl_offset, 0x00, sizeof(bits));
  95. mbl_offset += sizeof(u64) / sizeof(u32);
  96. memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
  97. break;
  98. case CPACF_KLMD_SHA3_224:
  99. case CPACF_KLMD_SHA3_256:
  100. case CPACF_KLMD_SHA3_384:
  101. case CPACF_KLMD_SHA3_512:
  102. break;
  103. default:
  104. return -EINVAL;
  105. }
  106. fc = ctx->func;
  107. fc |= test_facility(86) ? CPACF_KLMD_DUFOP : 0;
  108. if (ctx->first_message_part)
  109. fc |= CPACF_KLMD_NIP;
  110. cpacf_klmd(fc, ctx->state, ctx->buf, n);
  111. /* copy digest to out */
  112. memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
  113. /* wipe context */
  114. memset(ctx, 0, sizeof *ctx);
  115. return 0;
  116. }
  117. EXPORT_SYMBOL_GPL(s390_sha_final);
  118. MODULE_LICENSE("GPL");
  119. MODULE_DESCRIPTION("s390 SHA cipher common functions");