Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/crypto/polyval.h
49070 views
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
*/
26
struct 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
*/
46
struct 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
*/
70
struct 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
88
void polyval_preparekey(struct polyval_key *key,
89
const u8 raw_key[POLYVAL_BLOCK_SIZE]);
90
91
#else
92
static 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
*/
106
static 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
*/
122
static inline void
123
polyval_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
*/
138
static 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
*/
154
void 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
*/
168
void 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
*/
179
static 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 */
191
192