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