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