VirtualBox

source: vbox/trunk/src/libs/openssl-3.3.2/doc/designs/fast-param-find.md

Last change on this file was 108206, checked in by vboxsync, 3 months ago

openssl-3.3.2: Exported all files to OSE and removed .scm-settings ​bugref:10757

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.7 KB
Line 
1Proposal for OSSL_PARAM futures
2===============================
3
4Format:
5
6```perl
7{-
8use OpenSSL::paramnames qw(produce_param_handlers);
9-}
10
11/*
12 * Machine generated parameter handling
13 * generated by util/perl/OpenSSL/paramnames.pm
14 */
15{-
16produce_param_handlers(
17 'name' => 'kdf_scrypt',
18 'functions' => 'both', # getter or setter being the other options
19 'prologue' => "KDF_SCRYPT *ctx = vctx;",
20 "static" => "yes", # "yes" to generate static functions (default) or
21 # "no" to not
22 'params' => (
23 'KDF_PARAM_PASSWORD' => (
24 'type' => 'octet string',
25 'access' => 'writeonly',
26 'setaction' => qq(
27 if (!scrypt_set_membuf(&ctx->pass, &ctx->pass_len, p))
28 return 0;
29 ),
30 ),
31
32 'KDF_PARAM_SALT' => (
33 'type' => 'octet string',
34 'access' => 'readwrite',
35 'setaction' => qq(
36 if (!scrypt_set_membuf(&ctx->salt, &ctx->salt_len, p))
37 return 0;
38 ),
39 'getaction' => qq(
40 p->return_size = ctx->salt_len;
41 if (p->data_size >= ctx->salt_len)
42 memcpy(p->data, ctx->salt, p->data_size >= ctx->salt_len);
43 ),
44 ),
45
46 'KDF_PARAM_SCRYPT_N' => (
47 'type' => 'integer',
48 'ctype' => 'uint64_t',
49 'access' => 'readwrite',
50 'field' => "ctx->N",
51 'sanitycheck' => "value > 1 && is_power_of_two(value)"
52 ),
53
54 'KDF_PARAM_SCRYPT_R' => (
55 'type' => 'integer',
56 'ctype' => 'uint64_t',
57 'access' => 'readwrite',
58 'field' => "ctx->r",
59 'sanitycheck' => "value >= 1",
60 ),
61
62 'KDF_PARAM_SCRYPT_P' => (
63 'type' => 'integer',
64 'ctype' => 'uint64_t',
65 'access' => 'readwrite',
66 'field' => "ctx->p",
67 'sanitycheck' => "value >= 1",
68 ),
69
70 'KDF_PARAM_SCRYPT_MAXMEM' => (
71 'type' => 'integer',
72 'ctype' => 'uint64_t',
73 'access' => 'readwrite',
74 'field' => "ctx->maxmem_bytes",
75 'sanitycheck' => "value >= 1",
76 ),
77
78 'KDF_PARAM_PROPERTIES' => (
79 'type' => 'utf8_string',
80 'access' => 'readwrite',
81 'setaction' => qq(
82 if (!set_property_query(ctx, p->data) || !set_digest(ctx))
83 return 0;
84 ),
85 ),
86
87 'KDF_PARAM_SIZE' => (
88 'type' => 'integer',
89 'ctype' => 'size_t',
90 'access' => 'readonly',
91 'field' => "SIZE_MAX",
92 ),
93 );
94);
95-}
96/* End of generated code */
97```
98
99THe top level attributes are:
100
101- "name" is the name the functions will derive from e.g. "kdf_scrypt" to this
102 will be appended _[gs]et[_ctx]_params
103- "functions" is the functions to generate. By default both setters and
104 getters but either can be omitted.
105- "prologue" defines some introductory code emitted in the generated functions.
106 Function arguments are: `void *vctx, OSSL_PARAM params[]` and this
107 can be used to specialise the void pointer or declare locals.
108- "epilogue" defines some post decode code emitted in the generated function
109- "params" defines the parameters both gettable and settable
110
111Within the "params" the fields specify each parameter by label.
112
113Each parameter is then specialised with attributes:
114
115- "type" is the OSSL_PARAM type
116- "ctype" is the underlying C type (e.g. for an integer parameter size_t
117 could be the C type)
118- "access" is readwrite, readonly or writeonly. This determines if the
119 parameter is a settable, gettable or both
120- "field" is an accessor to the field itself
121- "sanitycheck" is a validation check for the parameter. If present, code
122 will be generated `if (!(sanitycheck)) return 0;`
123 The local variable `var` will contain the C value if specified.
124- "setaction" is C code to execute when the parameter is being set. It will
125 define an OSSL_PARAM pointer p to set.
126- "code" set to "no" skips code generation for this parameter, it defaults
127 to "yes" which generates handlers. This is useful when a parameter
128 is duplicated with differenting types (e.g. utf8 string and integer).
129- "published" set to "yes" includes the parameter in the gettable/settable
130 lists. Set to "no" and it isn't included (but will still be processed).
131 It defaults to "yes".
132
133- Flags include:
134 - nostatic: do not make the function static
135 - nocode: do not generate code for this parameter
136 - This allows, e.g., two different types for a parameter (int & string)
137 - unpublished: do not generate this parameter in the gettable/settable list
138 - "engine" is the only one like this
139 - readonly: create a getter but not a setter
140 - writeonly: create a setting but not a getter
141
142The idea is that the gettable and get functions will be simultaneously
143generated along with fast decoder to look up parameter names quickly.
144
145The getter and setter functions will be pre-populated with some local variable:
146
147```c
148 OSSL_PARAM *p; /* The matching parameter */
149 type val; /* The value of the parameter after a get/set call */
150 /* (for C types) */
151```
152
153A worked example for scrypt:
154
155Would generate something along the lines of:
156
157```c
158enum kdf_scrypt_ctx_param_e {
159 kdf_scrypt_ctx_param_INVALID,
160 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_PASSWORD,
161 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_PROPERTIES,
162 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SALT,
163 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_MAXMEM,
164 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_N,
165 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_P,
166 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_R,
167 kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SIZE
168};
169
170
171static enum kdf_scrypt_ctx_param_e kdf_scrypt_ctx_lookup(const OSSL_PARAM *p) {
172 /* magic decoder */
173 return kdf_scrypt_ctx_param_INVALID;
174}
175
176static int kdf_scrypt_set_ctx_params(void *vctx, const OSSL_PARAM params[])
177{
178 const OSSL_PARAM *p;
179 KDF_SCRYPT *ctx = vctx;
180
181 if (params == NULL)
182 return 1;
183
184 for (p = params; p->key != NULL; p++) {
185 switch (kdf_scrypt_ctx_lookup(p)) {
186 default:
187 break;
188
189 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_PASSWORD:
190 if (!scrypt_set_membuf(&ctx->pass, &ctx->pass_len, p))
191 return 0;
192 break;
193
194 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SALT:
195 if (!scrypt_set_membuf(&ctx->salt, &ctx->salt_len, p))
196 return 0;
197 break;
198
199 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_N: {
200 uint64_t value;
201
202 if (!OSSL_PARAM_get_uint64(p, &value) {
203 if (!(value > 1 && is_power_of_two(u64_value)))
204 return 0;
205 ctx->N = value;
206 }
207 break;
208 }
209
210 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_R: {
211 uint64_t value;
212
213 if (!OSSL_PARAM_get_uint64(p, &value) {
214 if (!(value >= 1))
215 return 0;
216 ctx->r = value;
217 }
218 break;
219 }
220
221 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_P: {
222 uint64_t value;
223
224 if (!OSSL_PARAM_get_uint64(p, &value) {
225 if (!(value >= 1))
226 return 0;
227 ctx->p = value;
228 }
229 break;
230 }
231
232 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_MAXMEM: {
233 uint64_t value;
234
235 if (!OSSL_PARAM_get_uint64(p, &value) {
236 if (!(value >= 1))
237 return 0;
238 ctx->p = value;
239 }
240 break;
241 }
242
243 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_PROPERTIES:
244 if (p != NULL) {
245 if (p->data_type != OSSL_PARAM_UTF8_STRING) {
246 if (!set_property_query(ctx, p->data) || !set_digest(ctx))
247 return 0;
248 }
249 }
250 }
251 }
252
253 return 1;
254}
255
256static const OSSL_PARAM *kdf_scrypt_settable_ctx_params(ossl_unused void *ctx,
257 ossl_unused void *p_ctx)
258{
259 static const OSSL_PARAM known_settable_ctx_params[] = {
260 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0),
261 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
262 OSSL_PARAM_uint64(OSSL_KDF_PARAM_SCRYPT_N, NULL),
263 OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_R, NULL),
264 OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_P, NULL),
265 OSSL_PARAM_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, NULL),
266 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
267 OSSL_PARAM_END
268 };
269 return known_settable_ctx_params;
270}
271
272static int kdf_scrypt_get_ctx_params(void *vctx, OSSL_PARAM params[])
273{
274 const OSSL_PARAM *p;
275 KDF_SCRYPT *ctx = vctx;
276
277 if (params == NULL)
278 return 1;
279
280 for (p = params; p->key != NULL; p++) {
281 switch (kdf_scrypt_ctx_lookup(p)) {
282 default:
283 break;
284
285 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_PASSWORD:
286 if (!scrypt_set_membuf(&ctx->pass, &ctx->pass_len, p))
287 return 0;
288 break;
289
290 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SALT:
291 p->return_size = ctx->salt_len;
292 if (p->data_size >= ctx->salt_len)
293 memcpy(p->data, ctx->salt, ctx->salt_len);
294 break;
295
296 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_N: {
297 if (!OSSL_PARAM_set_uint64(p, &ctx->N)
298 return 0;
299 break;
300 }
301
302 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_R: {
303 if (!OSSL_PARAM_set_uint64(p, &ctx->r)
304 return 0;
305 break;
306 }
307
308 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_P: {
309 if (!OSSL_PARAM_set_uint64(p, &ctx->p)
310 return 0;
311 break;
312 }
313
314 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_SCRYPT_MAXMEM: {
315 if (!OSSL_PARAM_set_uint64(p, &ctx->maxmem)
316 return 0;
317 break;
318 }
319
320 case kdf_scrypt_ctx_param_OSSL_KDF_PARAM_PROPERTIES:
321 if (p->data_type != OSSL_PARAM_UTF8_STRING) {
322 if (!set_property_query(ctx, p->data) || !set_digest(ctx))
323 return 0;
324 }
325 break;
326
327 case kdf_scrypt_ctx_param_KDF_PARAM_SIZE:
328 if (!OSSL_PARAM_set_size_t(p, SIZE_MAX))
329 return 0;
330 break;
331 }
332 }
333 return 1;
334}
335
336static const OSSL_PARAM *kdf_scrypt_gettable_ctx_params(ossl_unused void *ctx,
337 ossl_unused void *p_ctx)
338{
339 static const OSSL_PARAM known_gettable_ctx_params[] = {
340 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
341 OSSL_PARAM_END
342 };
343 return known_gettable_ctx_params;
344}
345```
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette