tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

pwbox.c (13655B)


      1 /* pwbox.c -- generated by Trunnel v1.5.3.
      2 * https://gitweb.torproject.org/trunnel.git
      3 * You probably shouldn't edit this file.
      4 */
      5 #include <stdlib.h>
      6 #include "trunnel-impl.h"
      7 
      8 #include "pwbox.h"
      9 
     10 #define TRUNNEL_SET_ERROR_CODE(obj) \
     11  do {                              \
     12    (obj)->trunnel_error_code_ = 1; \
     13  } while (0)
     14 
     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__
     20 #else
     21 #define OR_DEADCODE_DUMMY
     22 #endif
     23 
     24 #define CHECK_REMAINING(nbytes, label)                           \
     25  do {                                                           \
     26    if (remaining < (nbytes) OR_DEADCODE_DUMMY) {                \
     27      goto label;                                                \
     28    }                                                            \
     29  } while (0)
     30 
     31 pwbox_encoded_t *
     32 pwbox_encoded_new(void)
     33 {
     34  pwbox_encoded_t *val = trunnel_calloc(1, sizeof(pwbox_encoded_t));
     35  if (NULL == val)
     36    return NULL;
     37  val->fixedbytes0 = PWBOX0_CONST0;
     38  val->fixedbytes1 = PWBOX0_CONST1;
     39  return val;
     40 }
     41 
     42 /** Release all storage held inside 'obj', but do not free 'obj'.
     43 */
     44 static void
     45 pwbox_encoded_clear(pwbox_encoded_t *obj)
     46 {
     47  (void) 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);
     52 }
     53 
     54 void
     55 pwbox_encoded_free(pwbox_encoded_t *obj)
     56 {
     57  if (obj == NULL)
     58    return;
     59  pwbox_encoded_clear(obj);
     60  trunnel_memwipe(obj, sizeof(pwbox_encoded_t));
     61  trunnel_free_(obj);
     62 }
     63 
     64 uint32_t
     65 pwbox_encoded_get_fixedbytes0(const pwbox_encoded_t *inp)
     66 {
     67  return inp->fixedbytes0;
     68 }
     69 int
     70 pwbox_encoded_set_fixedbytes0(pwbox_encoded_t *inp, uint32_t val)
     71 {
     72  if (! ((val == PWBOX0_CONST0))) {
     73     TRUNNEL_SET_ERROR_CODE(inp);
     74     return -1;
     75  }
     76  inp->fixedbytes0 = val;
     77  return 0;
     78 }
     79 uint32_t
     80 pwbox_encoded_get_fixedbytes1(const pwbox_encoded_t *inp)
     81 {
     82  return inp->fixedbytes1;
     83 }
     84 int
     85 pwbox_encoded_set_fixedbytes1(pwbox_encoded_t *inp, uint32_t val)
     86 {
     87  if (! ((val == PWBOX0_CONST1))) {
     88     TRUNNEL_SET_ERROR_CODE(inp);
     89     return -1;
     90  }
     91  inp->fixedbytes1 = val;
     92  return 0;
     93 }
     94 uint8_t
     95 pwbox_encoded_get_header_len(const pwbox_encoded_t *inp)
     96 {
     97  return inp->header_len;
     98 }
     99 int
    100 pwbox_encoded_set_header_len(pwbox_encoded_t *inp, uint8_t val)
    101 {
    102  inp->header_len = val;
    103  return 0;
    104 }
    105 size_t
    106 pwbox_encoded_getlen_skey_header(const pwbox_encoded_t *inp)
    107 {
    108  return TRUNNEL_DYNARRAY_LEN(&inp->skey_header);
    109 }
    110 
    111 uint8_t
    112 pwbox_encoded_get_skey_header(pwbox_encoded_t *inp, size_t idx)
    113 {
    114  return TRUNNEL_DYNARRAY_GET(&inp->skey_header, idx);
    115 }
    116 
    117 uint8_t
    118 pwbox_encoded_getconst_skey_header(const pwbox_encoded_t *inp, size_t idx)
    119 {
    120  return pwbox_encoded_get_skey_header((pwbox_encoded_t*)inp, idx);
    121 }
    122 int
    123 pwbox_encoded_set_skey_header(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
    124 {
    125  TRUNNEL_DYNARRAY_SET(&inp->skey_header, idx, elt);
    126  return 0;
    127 }
    128 int
    129 pwbox_encoded_add_skey_header(pwbox_encoded_t *inp, uint8_t elt)
    130 {
    131 #if SIZE_MAX >= UINT8_MAX
    132  if (inp->skey_header.n_ == UINT8_MAX)
    133    goto trunnel_alloc_failed;
    134 #endif
    135  TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->skey_header, elt, {});
    136  return 0;
    137 trunnel_alloc_failed:
    138  TRUNNEL_SET_ERROR_CODE(inp);
    139  return -1;
    140 }
    141 
    142 uint8_t *
    143 pwbox_encoded_getarray_skey_header(pwbox_encoded_t *inp)
    144 {
    145  return inp->skey_header.elts_;
    146 }
    147 const uint8_t  *
    148 pwbox_encoded_getconstarray_skey_header(const pwbox_encoded_t *inp)
    149 {
    150  return (const uint8_t  *)pwbox_encoded_getarray_skey_header((pwbox_encoded_t*)inp);
    151 }
    152 int
    153 pwbox_encoded_setlen_skey_header(pwbox_encoded_t *inp, size_t newlen)
    154 {
    155  uint8_t *newptr;
    156 #if UINT8_MAX < SIZE_MAX
    157  if (newlen > UINT8_MAX)
    158    goto trunnel_alloc_failed;
    159 #endif
    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;
    167  return 0;
    168 trunnel_alloc_failed:
    169  TRUNNEL_SET_ERROR_CODE(inp);
    170  return -1;
    171 }
    172 size_t
    173 pwbox_encoded_getlen_iv(const pwbox_encoded_t *inp)
    174 {
    175  (void)inp;  return 16;
    176 }
    177 
    178 uint8_t
    179 pwbox_encoded_get_iv(pwbox_encoded_t *inp, size_t idx)
    180 {
    181  trunnel_assert(idx < 16);
    182  return inp->iv[idx];
    183 }
    184 
    185 uint8_t
    186 pwbox_encoded_getconst_iv(const pwbox_encoded_t *inp, size_t idx)
    187 {
    188  return pwbox_encoded_get_iv((pwbox_encoded_t*)inp, idx);
    189 }
    190 int
    191 pwbox_encoded_set_iv(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
    192 {
    193  trunnel_assert(idx < 16);
    194  inp->iv[idx] = elt;
    195  return 0;
    196 }
    197 
    198 uint8_t *
    199 pwbox_encoded_getarray_iv(pwbox_encoded_t *inp)
    200 {
    201  return inp->iv;
    202 }
    203 const uint8_t  *
    204 pwbox_encoded_getconstarray_iv(const pwbox_encoded_t *inp)
    205 {
    206  return (const uint8_t  *)pwbox_encoded_getarray_iv((pwbox_encoded_t*)inp);
    207 }
    208 size_t
    209 pwbox_encoded_getlen_data(const pwbox_encoded_t *inp)
    210 {
    211  return TRUNNEL_DYNARRAY_LEN(&inp->data);
    212 }
    213 
    214 uint8_t
    215 pwbox_encoded_get_data(pwbox_encoded_t *inp, size_t idx)
    216 {
    217  return TRUNNEL_DYNARRAY_GET(&inp->data, idx);
    218 }
    219 
    220 uint8_t
    221 pwbox_encoded_getconst_data(const pwbox_encoded_t *inp, size_t idx)
    222 {
    223  return pwbox_encoded_get_data((pwbox_encoded_t*)inp, idx);
    224 }
    225 int
    226 pwbox_encoded_set_data(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
    227 {
    228  TRUNNEL_DYNARRAY_SET(&inp->data, idx, elt);
    229  return 0;
    230 }
    231 int
    232 pwbox_encoded_add_data(pwbox_encoded_t *inp, uint8_t elt)
    233 {
    234  TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->data, elt, {});
    235  return 0;
    236 trunnel_alloc_failed:
    237  TRUNNEL_SET_ERROR_CODE(inp);
    238  return -1;
    239 }
    240 
    241 uint8_t *
    242 pwbox_encoded_getarray_data(pwbox_encoded_t *inp)
    243 {
    244  return inp->data.elts_;
    245 }
    246 const uint8_t  *
    247 pwbox_encoded_getconstarray_data(const pwbox_encoded_t *inp)
    248 {
    249  return (const uint8_t  *)pwbox_encoded_getarray_data((pwbox_encoded_t*)inp);
    250 }
    251 int
    252 pwbox_encoded_setlen_data(pwbox_encoded_t *inp, size_t newlen)
    253 {
    254  uint8_t *newptr;
    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;
    262  return 0;
    263 trunnel_alloc_failed:
    264  TRUNNEL_SET_ERROR_CODE(inp);
    265  return -1;
    266 }
    267 size_t
    268 pwbox_encoded_getlen_hmac(const pwbox_encoded_t *inp)
    269 {
    270  (void)inp;  return 32;
    271 }
    272 
    273 uint8_t
    274 pwbox_encoded_get_hmac(pwbox_encoded_t *inp, size_t idx)
    275 {
    276  trunnel_assert(idx < 32);
    277  return inp->hmac[idx];
    278 }
    279 
    280 uint8_t
    281 pwbox_encoded_getconst_hmac(const pwbox_encoded_t *inp, size_t idx)
    282 {
    283  return pwbox_encoded_get_hmac((pwbox_encoded_t*)inp, idx);
    284 }
    285 int
    286 pwbox_encoded_set_hmac(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
    287 {
    288  trunnel_assert(idx < 32);
    289  inp->hmac[idx] = elt;
    290  return 0;
    291 }
    292 
    293 uint8_t *
    294 pwbox_encoded_getarray_hmac(pwbox_encoded_t *inp)
    295 {
    296  return inp->hmac;
    297 }
    298 const uint8_t  *
    299 pwbox_encoded_getconstarray_hmac(const pwbox_encoded_t *inp)
    300 {
    301  return (const uint8_t  *)pwbox_encoded_getarray_hmac((pwbox_encoded_t*)inp);
    302 }
    303 const char *
    304 pwbox_encoded_check(const pwbox_encoded_t *obj)
    305 {
    306  if (obj == NULL)
    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";
    316  return NULL;
    317 }
    318 
    319 ssize_t
    320 pwbox_encoded_encoded_len(const pwbox_encoded_t *obj)
    321 {
    322  ssize_t result = 0;
    323 
    324  if (NULL != pwbox_encoded_check(obj))
    325     return -1;
    326 
    327 
    328  /* Length of u32 fixedbytes0 IN [PWBOX0_CONST0] */
    329  result += 4;
    330 
    331  /* Length of u32 fixedbytes1 IN [PWBOX0_CONST1] */
    332  result += 4;
    333 
    334  /* Length of u8 header_len */
    335  result += 1;
    336 
    337  /* Length of u8 skey_header[header_len] */
    338  result += TRUNNEL_DYNARRAY_LEN(&obj->skey_header);
    339 
    340  /* Length of u8 iv[16] */
    341  result += 16;
    342 
    343  /* Length of u8 data[] */
    344  result += TRUNNEL_DYNARRAY_LEN(&obj->data);
    345 
    346  /* Length of u8 hmac[32] */
    347  result += 32;
    348  return result;
    349 }
    350 int
    351 pwbox_encoded_clear_errors(pwbox_encoded_t *obj)
    352 {
    353  int r = obj->trunnel_error_code_;
    354  obj->trunnel_error_code_ = 0;
    355  return r;
    356 }
    357 ssize_t
    358 pwbox_encoded_encode(uint8_t *output, size_t avail, const pwbox_encoded_t *obj)
    359 {
    360  ssize_t result = 0;
    361  size_t written = 0;
    362  uint8_t *ptr = output;
    363  const char *msg;
    364 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    365  const ssize_t encoded_len = pwbox_encoded_encoded_len(obj);
    366 #endif
    367  int enforce_avail = 0;
    368  const size_t avail_orig = avail;
    369 
    370  if (NULL != (msg = pwbox_encoded_check(obj)))
    371    goto check_failed;
    372 
    373 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    374  trunnel_assert(encoded_len >= 0);
    375 #endif
    376 
    377  /* Encode u32 fixedbytes0 IN [PWBOX0_CONST0] */
    378  trunnel_assert(written <= avail);
    379  if (avail - written < 4)
    380    goto truncated;
    381  trunnel_set_uint32(ptr, trunnel_htonl(obj->fixedbytes0));
    382  written += 4; ptr += 4;
    383 
    384  /* Encode u32 fixedbytes1 IN [PWBOX0_CONST1] */
    385  trunnel_assert(written <= avail);
    386  if (avail - written < 4)
    387    goto truncated;
    388  trunnel_set_uint32(ptr, trunnel_htonl(obj->fixedbytes1));
    389  written += 4; ptr += 4;
    390 
    391  /* Encode u8 header_len */
    392  trunnel_assert(written <= avail);
    393  if (avail - written < 1)
    394    goto truncated;
    395  trunnel_set_uint8(ptr, (obj->header_len));
    396  written += 1; ptr += 1;
    397 
    398  /* Encode u8 skey_header[header_len] */
    399  {
    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)
    404      goto truncated;
    405    if (elt_len)
    406      memcpy(ptr, obj->skey_header.elts_, elt_len);
    407    written += elt_len; ptr += elt_len;
    408  }
    409 
    410  /* Encode u8 iv[16] */
    411  trunnel_assert(written <= avail);
    412  if (avail - written < 16)
    413    goto truncated;
    414  memcpy(ptr, obj->iv, 16);
    415  written += 16; ptr += 16;
    416  {
    417 
    418    /* Encode u8 data[] */
    419    {
    420      size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->data);
    421      trunnel_assert(written <= avail);
    422      if (avail - written < elt_len)
    423        goto truncated;
    424      if (elt_len)
    425        memcpy(ptr, obj->data.elts_, elt_len);
    426      written += elt_len; ptr += elt_len;
    427    }
    428    trunnel_assert(written <= avail);
    429    if (avail - written < 32)
    430      goto truncated;
    431    avail = written + 32;
    432    enforce_avail = 1;
    433  }
    434 
    435  /* Encode u8 hmac[32] */
    436  trunnel_assert(written <= avail);
    437  if (avail - written < 32) {
    438    if (avail_orig - written < 32)
    439      goto truncated;
    440    else
    441      goto check_failed;
    442  }
    443  memcpy(ptr, obj->hmac, 32);
    444  written += 32; ptr += 32;
    445 
    446 
    447  trunnel_assert(ptr == output + written);
    448  if (enforce_avail && avail != written)
    449    goto check_failed;
    450 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    451  {
    452    trunnel_assert(encoded_len >= 0);
    453    trunnel_assert((size_t)encoded_len == written);
    454  }
    455 
    456 #endif
    457 
    458  return written;
    459 
    460 truncated:
    461  result = -2;
    462  goto fail;
    463 check_failed:
    464  (void)msg;
    465  result = -1;
    466  goto fail;
    467 fail:
    468  trunnel_assert(result < 0);
    469  return result;
    470 }
    471 
    472 /** As pwbox_encoded_parse(), but do not allocate the output object.
    473 */
    474 static ssize_t
    475 pwbox_encoded_parse_into(pwbox_encoded_t *obj, const uint8_t *input, const size_t len_in)
    476 {
    477  const uint8_t *ptr = input;
    478  size_t remaining = len_in;
    479  ssize_t result = 0;
    480  (void)result;
    481 
    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))
    487    goto fail;
    488 
    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))
    494    goto fail;
    495 
    496  /* Parse u8 header_len */
    497  CHECK_REMAINING(1, truncated);
    498  obj->header_len = (trunnel_get_uint8(ptr));
    499  remaining -= 1; ptr += 1;
    500 
    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;
    505  if (obj->header_len)
    506    memcpy(obj->skey_header.elts_, ptr, obj->header_len);
    507  ptr += obj->header_len; remaining -= obj->header_len;
    508 
    509  /* Parse u8 iv[16] */
    510  CHECK_REMAINING(16, truncated);
    511  memcpy(obj->iv, ptr, 16);
    512  remaining -= 16; ptr += 16;
    513  {
    514    size_t remaining_after;
    515    CHECK_REMAINING(32, truncated);
    516    remaining_after = 32;
    517    remaining = remaining - 32;
    518 
    519    /* Parse u8 data[] */
    520    TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->data, remaining, {});
    521    obj->data.n_ = remaining;
    522    if (remaining)
    523      memcpy(obj->data.elts_, ptr, remaining);
    524    ptr += remaining; remaining -= remaining;
    525    if (remaining != 0)
    526      goto fail;
    527    remaining = remaining_after;
    528  }
    529 
    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;
    536 
    537 truncated:
    538  return -2;
    539 trunnel_alloc_failed:
    540  return -1;
    541 fail:
    542  result = -1;
    543  return result;
    544 }
    545 
    546 ssize_t
    547 pwbox_encoded_parse(pwbox_encoded_t **output, const uint8_t *input, const size_t len_in)
    548 {
    549  ssize_t result;
    550  *output = pwbox_encoded_new();
    551  if (NULL == *output)
    552    return -1;
    553  result = pwbox_encoded_parse_into(*output, input, len_in);
    554  if (result < 0) {
    555    pwbox_encoded_free(*output);
    556    *output = NULL;
    557  }
    558  return result;
    559 }