adler32.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2012 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <grub/dl.h>
  19. #include <grub/crypto.h>
  20. GRUB_MOD_LICENSE ("GPLv3+");
  21. struct adler32_context
  22. {
  23. grub_uint16_t a, b;
  24. grub_uint32_t c;
  25. };
  26. static void
  27. adler32_init (void *context)
  28. {
  29. struct adler32_context *ctx = context;
  30. ctx->a = 1;
  31. ctx->b = 0;
  32. }
  33. #define MOD 65521
  34. static grub_uint16_t
  35. mod_add (grub_uint16_t a, grub_uint16_t b)
  36. {
  37. if ((grub_uint32_t) a + (grub_uint32_t) b >= MOD)
  38. return a + b - MOD;
  39. return a + b;
  40. }
  41. static void
  42. adler32_write (void *context, const void *inbuf, grub_size_t inlen)
  43. {
  44. struct adler32_context *ctx = context;
  45. const grub_uint8_t *ptr = inbuf;
  46. while (inlen)
  47. {
  48. ctx->a = mod_add (ctx->a, *ptr);
  49. ctx->b = mod_add (ctx->a, ctx->b);
  50. inlen--;
  51. ptr++;
  52. }
  53. }
  54. static void
  55. adler32_final (void *context __attribute__ ((unused)))
  56. {
  57. }
  58. static grub_uint8_t *
  59. adler32_read (void *context)
  60. {
  61. struct adler32_context *ctx = context;
  62. if (ctx->a > MOD)
  63. ctx->a -= MOD;
  64. if (ctx->b > MOD)
  65. ctx->b -= MOD;
  66. ctx->c = grub_cpu_to_be32 (ctx->a | (ctx->b << 16));
  67. return (grub_uint8_t *) &ctx->c;
  68. }
  69. static gcry_md_spec_t spec_adler32 =
  70. {
  71. "ADLER32", 0, 0, 0, 4,
  72. adler32_init, adler32_write, adler32_final, adler32_read,
  73. sizeof (struct adler32_context),
  74. #ifdef GRUB_UTIL
  75. .modname = "adler32",
  76. #endif
  77. .blocksize = 64
  78. };
  79. GRUB_MOD_INIT(adler32)
  80. {
  81. grub_md_register (&spec_adler32);
  82. }
  83. GRUB_MOD_FINI(adler32)
  84. {
  85. grub_md_unregister (&spec_adler32);
  86. }