polyval.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * POLYVAL library API
  4. *
  5. * Copyright 2025 Google LLC
  6. */
  7. #ifndef _CRYPTO_POLYVAL_H
  8. #define _CRYPTO_POLYVAL_H
  9. #include <linux/string.h>
  10. #include <linux/types.h>
  11. #define POLYVAL_BLOCK_SIZE 16
  12. #define POLYVAL_DIGEST_SIZE 16
  13. /**
  14. * struct polyval_elem - An element of the POLYVAL finite field
  15. * @bytes: View of the element as a byte array (unioned with @lo and @hi)
  16. * @lo: The low 64 terms of the element's polynomial
  17. * @hi: The high 64 terms of the element's polynomial
  18. *
  19. * This represents an element of the finite field GF(2^128), using the POLYVAL
  20. * convention: little-endian byte order and natural bit order.
  21. */
  22. struct polyval_elem {
  23. union {
  24. u8 bytes[POLYVAL_BLOCK_SIZE];
  25. struct {
  26. __le64 lo;
  27. __le64 hi;
  28. };
  29. };
  30. };
  31. /**
  32. * struct polyval_key - Prepared key for POLYVAL
  33. *
  34. * This may contain just the raw key H, or it may contain precomputed key
  35. * powers, depending on the platform's POLYVAL implementation. Use
  36. * polyval_preparekey() to initialize this.
  37. *
  38. * By H^i we mean H^(i-1) * H * x^-128, with base case H^1 = H. I.e. the
  39. * exponentiation repeats the POLYVAL dot operation, with its "extra" x^-128.
  40. */
  41. struct polyval_key {
  42. #ifdef CONFIG_CRYPTO_LIB_POLYVAL_ARCH
  43. #ifdef CONFIG_ARM64
  44. /** @h_powers: Powers of the hash key H^8 through H^1 */
  45. struct polyval_elem h_powers[8];
  46. #elif defined(CONFIG_X86)
  47. /** @h_powers: Powers of the hash key H^8 through H^1 */
  48. struct polyval_elem h_powers[8];
  49. #else
  50. #error "Unhandled arch"
  51. #endif
  52. #else /* CONFIG_CRYPTO_LIB_POLYVAL_ARCH */
  53. /** @h: The hash key H */
  54. struct polyval_elem h;
  55. #endif /* !CONFIG_CRYPTO_LIB_POLYVAL_ARCH */
  56. };
  57. /**
  58. * struct polyval_ctx - Context for computing a POLYVAL value
  59. * @key: Pointer to the prepared POLYVAL key. The user of the API is
  60. * responsible for ensuring that the key lives as long as the context.
  61. * @acc: The accumulator
  62. * @partial: Number of data bytes processed so far modulo POLYVAL_BLOCK_SIZE
  63. */
  64. struct polyval_ctx {
  65. const struct polyval_key *key;
  66. struct polyval_elem acc;
  67. size_t partial;
  68. };
  69. /**
  70. * polyval_preparekey() - Prepare a POLYVAL key
  71. * @key: (output) The key structure to initialize
  72. * @raw_key: The raw hash key
  73. *
  74. * Initialize a POLYVAL key structure from a raw key. This may be a simple
  75. * copy, or it may involve precomputing powers of the key, depending on the
  76. * platform's POLYVAL implementation.
  77. *
  78. * Context: Any context.
  79. */
  80. #ifdef CONFIG_CRYPTO_LIB_POLYVAL_ARCH
  81. void polyval_preparekey(struct polyval_key *key,
  82. const u8 raw_key[POLYVAL_BLOCK_SIZE]);
  83. #else
  84. static inline void polyval_preparekey(struct polyval_key *key,
  85. const u8 raw_key[POLYVAL_BLOCK_SIZE])
  86. {
  87. /* Just a simple copy, so inline it. */
  88. memcpy(key->h.bytes, raw_key, POLYVAL_BLOCK_SIZE);
  89. }
  90. #endif
  91. /**
  92. * polyval_init() - Initialize a POLYVAL context for a new message
  93. * @ctx: The context to initialize
  94. * @key: The key to use. Note that a pointer to the key is saved in the
  95. * context, so the key must live at least as long as the context.
  96. */
  97. static inline void polyval_init(struct polyval_ctx *ctx,
  98. const struct polyval_key *key)
  99. {
  100. *ctx = (struct polyval_ctx){ .key = key };
  101. }
  102. /**
  103. * polyval_import_blkaligned() - Import a POLYVAL accumulator value
  104. * @ctx: The context to initialize
  105. * @key: The key to import. Note that a pointer to the key is saved in the
  106. * context, so the key must live at least as long as the context.
  107. * @acc: The accumulator value to import.
  108. *
  109. * This imports an accumulator that was saved by polyval_export_blkaligned().
  110. * The same key must be used.
  111. */
  112. static inline void
  113. polyval_import_blkaligned(struct polyval_ctx *ctx,
  114. const struct polyval_key *key,
  115. const struct polyval_elem *acc)
  116. {
  117. *ctx = (struct polyval_ctx){ .key = key, .acc = *acc };
  118. }
  119. /**
  120. * polyval_export_blkaligned() - Export a POLYVAL accumulator value
  121. * @ctx: The context to export the accumulator value from
  122. * @acc: (output) The exported accumulator value
  123. *
  124. * This exports the accumulator from a POLYVAL context. The number of data
  125. * bytes processed so far must be a multiple of POLYVAL_BLOCK_SIZE.
  126. */
  127. static inline void polyval_export_blkaligned(const struct polyval_ctx *ctx,
  128. struct polyval_elem *acc)
  129. {
  130. *acc = ctx->acc;
  131. }
  132. /**
  133. * polyval_update() - Update a POLYVAL context with message data
  134. * @ctx: The context to update; must have been initialized
  135. * @data: The message data
  136. * @len: The data length in bytes. Doesn't need to be block-aligned.
  137. *
  138. * This can be called any number of times.
  139. *
  140. * Context: Any context.
  141. */
  142. void polyval_update(struct polyval_ctx *ctx, const u8 *data, size_t len);
  143. /**
  144. * polyval_final() - Finish computing a POLYVAL value
  145. * @ctx: The context to finalize
  146. * @out: The output value
  147. *
  148. * If the total data length isn't a multiple of POLYVAL_BLOCK_SIZE, then the
  149. * final block is automatically zero-padded.
  150. *
  151. * After finishing, this zeroizes @ctx. So the caller does not need to do it.
  152. *
  153. * Context: Any context.
  154. */
  155. void polyval_final(struct polyval_ctx *ctx, u8 out[POLYVAL_BLOCK_SIZE]);
  156. /**
  157. * polyval() - Compute a POLYVAL value
  158. * @key: The prepared key
  159. * @data: The message data
  160. * @len: The data length in bytes. Doesn't need to be block-aligned.
  161. * @out: The output value
  162. *
  163. * Context: Any context.
  164. */
  165. static inline void polyval(const struct polyval_key *key,
  166. const u8 *data, size_t len,
  167. u8 out[POLYVAL_BLOCK_SIZE])
  168. {
  169. struct polyval_ctx ctx;
  170. polyval_init(&ctx, key);
  171. polyval_update(&ctx, data, len);
  172. polyval_final(&ctx, out);
  173. }
  174. #endif /* _CRYPTO_POLYVAL_H */