1 | Proposal for OSSL_PARAM futures
|
---|
2 | ===============================
|
---|
3 |
|
---|
4 | Format:
|
---|
5 |
|
---|
6 | ```perl
|
---|
7 | {-
|
---|
8 | use OpenSSL::paramnames qw(produce_param_handlers);
|
---|
9 | -}
|
---|
10 |
|
---|
11 | /*
|
---|
12 | * Machine generated parameter handling
|
---|
13 | * generated by util/perl/OpenSSL/paramnames.pm
|
---|
14 | */
|
---|
15 | {-
|
---|
16 | produce_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 |
|
---|
99 | THe 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 |
|
---|
111 | Within the "params" the fields specify each parameter by label.
|
---|
112 |
|
---|
113 | Each 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 |
|
---|
142 | The idea is that the gettable and get functions will be simultaneously
|
---|
143 | generated along with fast decoder to look up parameter names quickly.
|
---|
144 |
|
---|
145 | The 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 |
|
---|
153 | A worked example for scrypt:
|
---|
154 |
|
---|
155 | Would generate something along the lines of:
|
---|
156 |
|
---|
157 | ```c
|
---|
158 | enum 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 |
|
---|
171 | static 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 |
|
---|
176 | static 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 |
|
---|
256 | static 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 |
|
---|
272 | static 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 |
|
---|
336 | static 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 | ```
|
---|