File Index
Files and directories
Sign in
FILE

polyval.h

File preview with syntax highlighting.

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