xref: /linux/include/crypto/gf128hash.h (revision 6fa6b5cb60490db2591bb93872b95f72315e5f53)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * GF(2^128) polynomial hashing: GHASH and POLYVAL
4  *
5  * Copyright 2025 Google LLC
6  */
7 
8 #ifndef _CRYPTO_GF128HASH_H
9 #define _CRYPTO_GF128HASH_H
10 
11 #include <crypto/ghash.h>
12 #include <linux/string.h>
13 #include <linux/types.h>
14 
15 #define POLYVAL_BLOCK_SIZE	16
16 #define POLYVAL_DIGEST_SIZE	16
17 
18 /**
19  * struct polyval_elem - An element of the POLYVAL finite field
20  * @bytes: View of the element as a byte array (unioned with @lo and @hi)
21  * @lo: The low 64 terms of the element's polynomial
22  * @hi: The high 64 terms of the element's polynomial
23  *
24  * This represents an element of the finite field GF(2^128), using the POLYVAL
25  * convention: little-endian byte order and natural bit order.
26  */
27 struct polyval_elem {
28 	union {
29 		u8 bytes[POLYVAL_BLOCK_SIZE];
30 		struct {
31 			__le64 lo;
32 			__le64 hi;
33 		};
34 	};
35 };
36 
37 /**
38  * struct ghash_key - Prepared key for GHASH
39  *
40  * Use ghash_preparekey() to initialize this.
41  */
42 struct ghash_key {
43 #if defined(CONFIG_CRYPTO_LIB_GF128HASH_ARCH) && defined(CONFIG_PPC64)
44 	/** @htable: GHASH key format used by the POWER8 assembly code */
45 	u64 htable[4][2];
46 #elif defined(CONFIG_CRYPTO_LIB_GF128HASH_ARCH) && \
47 	(defined(CONFIG_RISCV) || defined(CONFIG_S390))
48 	/** @h_raw: The hash key H, in GHASH format */
49 	u8 h_raw[GHASH_BLOCK_SIZE];
50 #endif
51 	/** @h: The hash key H, in POLYVAL format */
52 	struct polyval_elem h;
53 };
54 
55 /**
56  * struct polyval_key - Prepared key for POLYVAL
57  *
58  * This may contain just the raw key H, or it may contain precomputed key
59  * powers, depending on the platform's POLYVAL implementation.  Use
60  * polyval_preparekey() to initialize this.
61  *
62  * By H^i we mean H^(i-1) * H * x^-128, with base case H^1 = H.  I.e. the
63  * exponentiation repeats the POLYVAL dot operation, with its "extra" x^-128.
64  */
65 struct polyval_key {
66 #if defined(CONFIG_CRYPTO_LIB_GF128HASH_ARCH) && \
67 	(defined(CONFIG_ARM64) || defined(CONFIG_X86))
68 	/** @h_powers: Powers of the hash key H^8 through H^1 */
69 	struct polyval_elem h_powers[8];
70 #else
71 	/** @h: The hash key H */
72 	struct polyval_elem h;
73 #endif
74 };
75 
76 /**
77  * struct ghash_ctx - Context for computing a GHASH value
78  * @key: Pointer to the prepared GHASH key.  The user of the API is
79  *	 responsible for ensuring that the key lives as long as the context.
80  * @acc: The accumulator.  It is stored in POLYVAL format rather than GHASH
81  *	 format, since most implementations want it in POLYVAL format.
82  * @partial: Number of data bytes processed so far modulo GHASH_BLOCK_SIZE
83  */
84 struct ghash_ctx {
85 	const struct ghash_key *key;
86 	struct polyval_elem acc;
87 	size_t partial;
88 };
89 
90 /**
91  * struct polyval_ctx - Context for computing a POLYVAL value
92  * @key: Pointer to the prepared POLYVAL key.  The user of the API is
93  *	 responsible for ensuring that the key lives as long as the context.
94  * @acc: The accumulator
95  * @partial: Number of data bytes processed so far modulo POLYVAL_BLOCK_SIZE
96  */
97 struct polyval_ctx {
98 	const struct polyval_key *key;
99 	struct polyval_elem acc;
100 	size_t partial;
101 };
102 
103 /**
104  * ghash_preparekey() - Prepare a GHASH key
105  * @key: (output) The key structure to initialize
106  * @raw_key: The raw hash key
107  *
108  * Initialize a GHASH key structure from a raw key.
109  *
110  * Context: Any context.
111  */
112 void ghash_preparekey(struct ghash_key *key,
113 		      const u8 raw_key[GHASH_BLOCK_SIZE]);
114 
115 /**
116  * polyval_preparekey() - Prepare a POLYVAL key
117  * @key: (output) The key structure to initialize
118  * @raw_key: The raw hash key
119  *
120  * Initialize a POLYVAL key structure from a raw key.  This may be a simple
121  * copy, or it may involve precomputing powers of the key, depending on the
122  * platform's POLYVAL implementation.
123  *
124  * Context: Any context.
125  */
126 void polyval_preparekey(struct polyval_key *key,
127 			const u8 raw_key[POLYVAL_BLOCK_SIZE]);
128 
129 /**
130  * ghash_init() - Initialize a GHASH context for a new message
131  * @ctx: The context to initialize
132  * @key: The key to use.  Note that a pointer to the key is saved in the
133  *	 context, so the key must live at least as long as the context.
134  */
135 static inline void ghash_init(struct ghash_ctx *ctx,
136 			      const struct ghash_key *key)
137 {
138 	*ctx = (struct ghash_ctx){ .key = key };
139 }
140 
141 /**
142  * polyval_init() - Initialize a POLYVAL context for a new message
143  * @ctx: The context to initialize
144  * @key: The key to use.  Note that a pointer to the key is saved in the
145  *	 context, so the key must live at least as long as the context.
146  */
147 static inline void polyval_init(struct polyval_ctx *ctx,
148 				const struct polyval_key *key)
149 {
150 	*ctx = (struct polyval_ctx){ .key = key };
151 }
152 
153 /**
154  * polyval_import_blkaligned() - Import a POLYVAL accumulator value
155  * @ctx: The context to initialize
156  * @key: The key to import.  Note that a pointer to the key is saved in the
157  *	 context, so the key must live at least as long as the context.
158  * @acc: The accumulator value to import.
159  *
160  * This imports an accumulator that was saved by polyval_export_blkaligned().
161  * The same key must be used.
162  */
163 static inline void
164 polyval_import_blkaligned(struct polyval_ctx *ctx,
165 			  const struct polyval_key *key,
166 			  const struct polyval_elem *acc)
167 {
168 	*ctx = (struct polyval_ctx){ .key = key, .acc = *acc };
169 }
170 
171 /**
172  * polyval_export_blkaligned() - Export a POLYVAL accumulator value
173  * @ctx: The context to export the accumulator value from
174  * @acc: (output) The exported accumulator value
175  *
176  * This exports the accumulator from a POLYVAL context.  The number of data
177  * bytes processed so far must be a multiple of POLYVAL_BLOCK_SIZE.
178  */
179 static inline void polyval_export_blkaligned(const struct polyval_ctx *ctx,
180 					     struct polyval_elem *acc)
181 {
182 	*acc = ctx->acc;
183 }
184 
185 /**
186  * ghash_update() - Update a GHASH context with message data
187  * @ctx: The context to update; must have been initialized
188  * @data: The message data
189  * @len: The data length in bytes.  Doesn't need to be block-aligned.
190  *
191  * This can be called any number of times.
192  *
193  * Context: Any context.
194  */
195 void ghash_update(struct ghash_ctx *ctx, const u8 *data, size_t len);
196 
197 /**
198  * polyval_update() - Update a POLYVAL context with message data
199  * @ctx: The context to update; must have been initialized
200  * @data: The message data
201  * @len: The data length in bytes.  Doesn't need to be block-aligned.
202  *
203  * This can be called any number of times.
204  *
205  * Context: Any context.
206  */
207 void polyval_update(struct polyval_ctx *ctx, const u8 *data, size_t len);
208 
209 /**
210  * ghash_final() - Finish computing a GHASH value
211  * @ctx: The context to finalize
212  * @out: The output value
213  *
214  * If the total data length isn't a multiple of GHASH_BLOCK_SIZE, then the
215  * final block is automatically zero-padded.
216  *
217  * After finishing, this zeroizes @ctx.  So the caller does not need to do it.
218  *
219  * Context: Any context.
220  */
221 void ghash_final(struct ghash_ctx *ctx, u8 out[GHASH_BLOCK_SIZE]);
222 
223 /**
224  * polyval_final() - Finish computing a POLYVAL value
225  * @ctx: The context to finalize
226  * @out: The output value
227  *
228  * If the total data length isn't a multiple of POLYVAL_BLOCK_SIZE, then the
229  * final block is automatically zero-padded.
230  *
231  * After finishing, this zeroizes @ctx.  So the caller does not need to do it.
232  *
233  * Context: Any context.
234  */
235 void polyval_final(struct polyval_ctx *ctx, u8 out[POLYVAL_BLOCK_SIZE]);
236 
237 /**
238  * ghash() - Compute a GHASH value
239  * @key: The prepared key
240  * @data: The message data
241  * @len: The data length in bytes.  Doesn't need to be block-aligned.
242  * @out: The output value
243  *
244  * Context: Any context.
245  */
246 static inline void ghash(const struct ghash_key *key, const u8 *data,
247 			 size_t len, u8 out[GHASH_BLOCK_SIZE])
248 {
249 	struct ghash_ctx ctx;
250 
251 	ghash_init(&ctx, key);
252 	ghash_update(&ctx, data, len);
253 	ghash_final(&ctx, out);
254 }
255 
256 /**
257  * polyval() - Compute a POLYVAL value
258  * @key: The prepared key
259  * @data: The message data
260  * @len: The data length in bytes.  Doesn't need to be block-aligned.
261  * @out: The output value
262  *
263  * Context: Any context.
264  */
265 static inline void polyval(const struct polyval_key *key,
266 			   const u8 *data, size_t len,
267 			   u8 out[POLYVAL_BLOCK_SIZE])
268 {
269 	struct polyval_ctx ctx;
270 
271 	polyval_init(&ctx, key);
272 	polyval_update(&ctx, data, len);
273 	polyval_final(&ctx, out);
274 }
275 
276 #endif /* _CRYPTO_GF128HASH_H */
277