1 /* pwbox.c -- generated by Trunnel v1.5.3.
2 * https://gitweb.torproject.org/trunnel.git
3 * You probably shouldn't edit this file.
6 #include "trunnel-impl.h"
10 #define TRUNNEL_SET_ERROR_CODE(obj) \
12 (obj)->trunnel_error_code_ = 1; \
15 #if defined(__COVERITY__) || defined(__clang_analyzer__)
16 /* If we're running a static analysis tool, we don't want it to complain
17 * that some of our remaining-bytes checks are dead-code. */
18 int pwbox_deadcode_dummy__
= 0;
19 #define OR_DEADCODE_DUMMY || pwbox_deadcode_dummy__
21 #define OR_DEADCODE_DUMMY
24 #define CHECK_REMAINING(nbytes, label) \
26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
32 pwbox_encoded_new(void)
34 pwbox_encoded_t
*val
= trunnel_calloc(1, sizeof(pwbox_encoded_t
));
37 val
->fixedbytes0
= PWBOX0_CONST0
;
38 val
->fixedbytes1
= PWBOX0_CONST1
;
42 /** Release all storage held inside 'obj', but do not free 'obj'.
45 pwbox_encoded_clear(pwbox_encoded_t
*obj
)
48 TRUNNEL_DYNARRAY_WIPE(&obj
->skey_header
);
49 TRUNNEL_DYNARRAY_CLEAR(&obj
->skey_header
);
50 TRUNNEL_DYNARRAY_WIPE(&obj
->data
);
51 TRUNNEL_DYNARRAY_CLEAR(&obj
->data
);
55 pwbox_encoded_free(pwbox_encoded_t
*obj
)
59 pwbox_encoded_clear(obj
);
60 trunnel_memwipe(obj
, sizeof(pwbox_encoded_t
));
65 pwbox_encoded_get_fixedbytes0(const pwbox_encoded_t
*inp
)
67 return inp
->fixedbytes0
;
70 pwbox_encoded_set_fixedbytes0(pwbox_encoded_t
*inp
, uint32_t val
)
72 if (! ((val
== PWBOX0_CONST0
))) {
73 TRUNNEL_SET_ERROR_CODE(inp
);
76 inp
->fixedbytes0
= val
;
80 pwbox_encoded_get_fixedbytes1(const pwbox_encoded_t
*inp
)
82 return inp
->fixedbytes1
;
85 pwbox_encoded_set_fixedbytes1(pwbox_encoded_t
*inp
, uint32_t val
)
87 if (! ((val
== PWBOX0_CONST1
))) {
88 TRUNNEL_SET_ERROR_CODE(inp
);
91 inp
->fixedbytes1
= val
;
95 pwbox_encoded_get_header_len(const pwbox_encoded_t
*inp
)
97 return inp
->header_len
;
100 pwbox_encoded_set_header_len(pwbox_encoded_t
*inp
, uint8_t val
)
102 inp
->header_len
= val
;
106 pwbox_encoded_getlen_skey_header(const pwbox_encoded_t
*inp
)
108 return TRUNNEL_DYNARRAY_LEN(&inp
->skey_header
);
112 pwbox_encoded_get_skey_header(pwbox_encoded_t
*inp
, size_t idx
)
114 return TRUNNEL_DYNARRAY_GET(&inp
->skey_header
, idx
);
118 pwbox_encoded_getconst_skey_header(const pwbox_encoded_t
*inp
, size_t idx
)
120 return pwbox_encoded_get_skey_header((pwbox_encoded_t
*)inp
, idx
);
123 pwbox_encoded_set_skey_header(pwbox_encoded_t
*inp
, size_t idx
, uint8_t elt
)
125 TRUNNEL_DYNARRAY_SET(&inp
->skey_header
, idx
, elt
);
129 pwbox_encoded_add_skey_header(pwbox_encoded_t
*inp
, uint8_t elt
)
131 #if SIZE_MAX >= UINT8_MAX
132 if (inp
->skey_header
.n_
== UINT8_MAX
)
133 goto trunnel_alloc_failed
;
135 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp
->skey_header
, elt
, {});
137 trunnel_alloc_failed
:
138 TRUNNEL_SET_ERROR_CODE(inp
);
143 pwbox_encoded_getarray_skey_header(pwbox_encoded_t
*inp
)
145 return inp
->skey_header
.elts_
;
148 pwbox_encoded_getconstarray_skey_header(const pwbox_encoded_t
*inp
)
150 return (const uint8_t *)pwbox_encoded_getarray_skey_header((pwbox_encoded_t
*)inp
);
153 pwbox_encoded_setlen_skey_header(pwbox_encoded_t
*inp
, size_t newlen
)
156 #if UINT8_MAX < SIZE_MAX
157 if (newlen
> UINT8_MAX
)
158 goto trunnel_alloc_failed
;
160 newptr
= trunnel_dynarray_setlen(&inp
->skey_header
.allocated_
,
161 &inp
->skey_header
.n_
, inp
->skey_header
.elts_
, newlen
,
162 sizeof(inp
->skey_header
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
163 &inp
->trunnel_error_code_
);
164 if (newlen
!= 0 && newptr
== NULL
)
165 goto trunnel_alloc_failed
;
166 inp
->skey_header
.elts_
= newptr
;
168 trunnel_alloc_failed
:
169 TRUNNEL_SET_ERROR_CODE(inp
);
173 pwbox_encoded_getlen_iv(const pwbox_encoded_t
*inp
)
175 (void)inp
; return 16;
179 pwbox_encoded_get_iv(pwbox_encoded_t
*inp
, size_t idx
)
181 trunnel_assert(idx
< 16);
186 pwbox_encoded_getconst_iv(const pwbox_encoded_t
*inp
, size_t idx
)
188 return pwbox_encoded_get_iv((pwbox_encoded_t
*)inp
, idx
);
191 pwbox_encoded_set_iv(pwbox_encoded_t
*inp
, size_t idx
, uint8_t elt
)
193 trunnel_assert(idx
< 16);
199 pwbox_encoded_getarray_iv(pwbox_encoded_t
*inp
)
204 pwbox_encoded_getconstarray_iv(const pwbox_encoded_t
*inp
)
206 return (const uint8_t *)pwbox_encoded_getarray_iv((pwbox_encoded_t
*)inp
);
209 pwbox_encoded_getlen_data(const pwbox_encoded_t
*inp
)
211 return TRUNNEL_DYNARRAY_LEN(&inp
->data
);
215 pwbox_encoded_get_data(pwbox_encoded_t
*inp
, size_t idx
)
217 return TRUNNEL_DYNARRAY_GET(&inp
->data
, idx
);
221 pwbox_encoded_getconst_data(const pwbox_encoded_t
*inp
, size_t idx
)
223 return pwbox_encoded_get_data((pwbox_encoded_t
*)inp
, idx
);
226 pwbox_encoded_set_data(pwbox_encoded_t
*inp
, size_t idx
, uint8_t elt
)
228 TRUNNEL_DYNARRAY_SET(&inp
->data
, idx
, elt
);
232 pwbox_encoded_add_data(pwbox_encoded_t
*inp
, uint8_t elt
)
234 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp
->data
, elt
, {});
236 trunnel_alloc_failed
:
237 TRUNNEL_SET_ERROR_CODE(inp
);
242 pwbox_encoded_getarray_data(pwbox_encoded_t
*inp
)
244 return inp
->data
.elts_
;
247 pwbox_encoded_getconstarray_data(const pwbox_encoded_t
*inp
)
249 return (const uint8_t *)pwbox_encoded_getarray_data((pwbox_encoded_t
*)inp
);
252 pwbox_encoded_setlen_data(pwbox_encoded_t
*inp
, size_t newlen
)
255 newptr
= trunnel_dynarray_setlen(&inp
->data
.allocated_
,
256 &inp
->data
.n_
, inp
->data
.elts_
, newlen
,
257 sizeof(inp
->data
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
258 &inp
->trunnel_error_code_
);
259 if (newlen
!= 0 && newptr
== NULL
)
260 goto trunnel_alloc_failed
;
261 inp
->data
.elts_
= newptr
;
263 trunnel_alloc_failed
:
264 TRUNNEL_SET_ERROR_CODE(inp
);
268 pwbox_encoded_getlen_hmac(const pwbox_encoded_t
*inp
)
270 (void)inp
; return 32;
274 pwbox_encoded_get_hmac(pwbox_encoded_t
*inp
, size_t idx
)
276 trunnel_assert(idx
< 32);
277 return inp
->hmac
[idx
];
281 pwbox_encoded_getconst_hmac(const pwbox_encoded_t
*inp
, size_t idx
)
283 return pwbox_encoded_get_hmac((pwbox_encoded_t
*)inp
, idx
);
286 pwbox_encoded_set_hmac(pwbox_encoded_t
*inp
, size_t idx
, uint8_t elt
)
288 trunnel_assert(idx
< 32);
289 inp
->hmac
[idx
] = elt
;
294 pwbox_encoded_getarray_hmac(pwbox_encoded_t
*inp
)
299 pwbox_encoded_getconstarray_hmac(const pwbox_encoded_t
*inp
)
301 return (const uint8_t *)pwbox_encoded_getarray_hmac((pwbox_encoded_t
*)inp
);
304 pwbox_encoded_check(const pwbox_encoded_t
*obj
)
307 return "Object was NULL";
308 if (obj
->trunnel_error_code_
)
309 return "A set function failed on this object";
310 if (! (obj
->fixedbytes0
== PWBOX0_CONST0
))
311 return "Integer out of bounds";
312 if (! (obj
->fixedbytes1
== PWBOX0_CONST1
))
313 return "Integer out of bounds";
314 if (TRUNNEL_DYNARRAY_LEN(&obj
->skey_header
) != obj
->header_len
)
315 return "Length mismatch for skey_header";
320 pwbox_encoded_encoded_len(const pwbox_encoded_t
*obj
)
324 if (NULL
!= pwbox_encoded_check(obj
))
328 /* Length of u32 fixedbytes0 IN [PWBOX0_CONST0] */
331 /* Length of u32 fixedbytes1 IN [PWBOX0_CONST1] */
334 /* Length of u8 header_len */
337 /* Length of u8 skey_header[header_len] */
338 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->skey_header
);
340 /* Length of u8 iv[16] */
343 /* Length of u8 data[] */
344 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->data
);
346 /* Length of u8 hmac[32] */
351 pwbox_encoded_clear_errors(pwbox_encoded_t
*obj
)
353 int r
= obj
->trunnel_error_code_
;
354 obj
->trunnel_error_code_
= 0;
358 pwbox_encoded_encode(uint8_t *output
, size_t avail
, const pwbox_encoded_t
*obj
)
362 uint8_t *ptr
= output
;
364 #ifdef TRUNNEL_CHECK_ENCODED_LEN
365 const ssize_t encoded_len
= pwbox_encoded_encoded_len(obj
);
367 int enforce_avail
= 0;
368 const size_t avail_orig
= avail
;
370 if (NULL
!= (msg
= pwbox_encoded_check(obj
)))
373 #ifdef TRUNNEL_CHECK_ENCODED_LEN
374 trunnel_assert(encoded_len
>= 0);
377 /* Encode u32 fixedbytes0 IN [PWBOX0_CONST0] */
378 trunnel_assert(written
<= avail
);
379 if (avail
- written
< 4)
381 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->fixedbytes0
));
382 written
+= 4; ptr
+= 4;
384 /* Encode u32 fixedbytes1 IN [PWBOX0_CONST1] */
385 trunnel_assert(written
<= avail
);
386 if (avail
- written
< 4)
388 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->fixedbytes1
));
389 written
+= 4; ptr
+= 4;
391 /* Encode u8 header_len */
392 trunnel_assert(written
<= avail
);
393 if (avail
- written
< 1)
395 trunnel_set_uint8(ptr
, (obj
->header_len
));
396 written
+= 1; ptr
+= 1;
398 /* Encode u8 skey_header[header_len] */
400 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->skey_header
);
401 trunnel_assert(obj
->header_len
== elt_len
);
402 trunnel_assert(written
<= avail
);
403 if (avail
- written
< elt_len
)
406 memcpy(ptr
, obj
->skey_header
.elts_
, elt_len
);
407 written
+= elt_len
; ptr
+= elt_len
;
410 /* Encode u8 iv[16] */
411 trunnel_assert(written
<= avail
);
412 if (avail
- written
< 16)
414 memcpy(ptr
, obj
->iv
, 16);
415 written
+= 16; ptr
+= 16;
418 /* Encode u8 data[] */
420 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->data
);
421 trunnel_assert(written
<= avail
);
422 if (avail
- written
< elt_len
)
425 memcpy(ptr
, obj
->data
.elts_
, elt_len
);
426 written
+= elt_len
; ptr
+= elt_len
;
428 trunnel_assert(written
<= avail
);
429 if (avail
- written
< 32)
431 avail
= written
+ 32;
435 /* Encode u8 hmac[32] */
436 trunnel_assert(written
<= avail
);
437 if (avail
- written
< 32) {
438 if (avail_orig
- written
< 32)
443 memcpy(ptr
, obj
->hmac
, 32);
444 written
+= 32; ptr
+= 32;
447 trunnel_assert(ptr
== output
+ written
);
448 if (enforce_avail
&& avail
!= written
)
450 #ifdef TRUNNEL_CHECK_ENCODED_LEN
452 trunnel_assert(encoded_len
>= 0);
453 trunnel_assert((size_t)encoded_len
== written
);
468 trunnel_assert(result
< 0);
472 /** As pwbox_encoded_parse(), but do not allocate the output object.
475 pwbox_encoded_parse_into(pwbox_encoded_t
*obj
, const uint8_t *input
, const size_t len_in
)
477 const uint8_t *ptr
= input
;
478 size_t remaining
= len_in
;
482 /* Parse u32 fixedbytes0 IN [PWBOX0_CONST0] */
483 CHECK_REMAINING(4, truncated
);
484 obj
->fixedbytes0
= trunnel_ntohl(trunnel_get_uint32(ptr
));
485 remaining
-= 4; ptr
+= 4;
486 if (! (obj
->fixedbytes0
== PWBOX0_CONST0
))
489 /* Parse u32 fixedbytes1 IN [PWBOX0_CONST1] */
490 CHECK_REMAINING(4, truncated
);
491 obj
->fixedbytes1
= trunnel_ntohl(trunnel_get_uint32(ptr
));
492 remaining
-= 4; ptr
+= 4;
493 if (! (obj
->fixedbytes1
== PWBOX0_CONST1
))
496 /* Parse u8 header_len */
497 CHECK_REMAINING(1, truncated
);
498 obj
->header_len
= (trunnel_get_uint8(ptr
));
499 remaining
-= 1; ptr
+= 1;
501 /* Parse u8 skey_header[header_len] */
502 CHECK_REMAINING(obj
->header_len
, truncated
);
503 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj
->skey_header
, obj
->header_len
, {});
504 obj
->skey_header
.n_
= obj
->header_len
;
506 memcpy(obj
->skey_header
.elts_
, ptr
, obj
->header_len
);
507 ptr
+= obj
->header_len
; remaining
-= obj
->header_len
;
509 /* Parse u8 iv[16] */
510 CHECK_REMAINING(16, truncated
);
511 memcpy(obj
->iv
, ptr
, 16);
512 remaining
-= 16; ptr
+= 16;
514 size_t remaining_after
;
515 CHECK_REMAINING(32, truncated
);
516 remaining_after
= 32;
517 remaining
= remaining
- 32;
519 /* Parse u8 data[] */
520 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj
->data
, remaining
, {});
521 obj
->data
.n_
= remaining
;
523 memcpy(obj
->data
.elts_
, ptr
, remaining
);
524 ptr
+= remaining
; remaining
-= remaining
;
527 remaining
= remaining_after
;
530 /* Parse u8 hmac[32] */
531 CHECK_REMAINING(32, truncated
);
532 memcpy(obj
->hmac
, ptr
, 32);
533 remaining
-= 32; ptr
+= 32;
534 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
535 return len_in
- remaining
;
539 trunnel_alloc_failed
:
547 pwbox_encoded_parse(pwbox_encoded_t
**output
, const uint8_t *input
, const size_t len_in
)
550 *output
= pwbox_encoded_new();
553 result
= pwbox_encoded_parse_into(*output
, input
, len_in
);
555 pwbox_encoded_free(*output
);