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