/ ltc-stream-ciphers.c
ltc-stream-ciphers.c
   1  /*
   2   * Licensed under the Apache License, Version 2.0 (the "License");
   3   * you may not use this file except in compliance with the License.
   4   * See the NOTICE file distributed with this work for additional
   5   * information regarding copyright ownership.
   6   * You may obtain a copy of the License at
   7   *
   8   *     http://www.apache.org/licenses/LICENSE-2.0
   9   *
  10   * Unless required by applicable law or agreed to in writing, software
  11   * distributed under the License is distributed on an "AS IS" BASIS,
  12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13   * See the License for the specific language governing permissions and
  14   * limitations under the License.
  15   */
  16  
  17  /*
  18   * Contrary to symmetric ciphers, which implement keys and modes in two
  19   * different modules (ltc-sym-keys.c and ltc-sym-ciphers.c), stream ciphers
  20   * implement both aspects in this module.  It does lead to a somewhat curious
  21   * situation, where the are offered both as stand-alone en/decrypt operations
  22   * and as key associated operations.  But, that'll do.
  23   */
  24  
  25  #include <stdlib.h>
  26  #include <string.h>
  27  #include <tomcrypt.h>
  28  #include <lscrypto/key.h>
  29  #include <lscrypto/encrypt.h>
  30  #include <lsplugin/mkobject.h>
  31  #include <lsplugin/mkoperator.h>
  32  #include <lsplugin/param.h>
  33  #include "ltc-methods.h"
  34  
  35  #define T(x) LE_status_is_OK(x)
  36  
  37  /*********************************************************************
  38   *
  39   *  Common stream key
  40   *
  41   *  libtomcrypt doesn't have any separate key object for stream ciphers.
  42   *  Instead, there's only a state.  Le'Sec does need a key object, though,
  43   *  and this implementation uses that to simply save away the input key bits.
  44   *
  45   *****/
  46  struct stream_key_st {
  47    /* Cached key bits */
  48    unsigned char *key_bits;
  49    size_t key_bits_len;          /* Measured in bits */
  50  
  51    /* Caches for key data operations */
  52    LSC_key_constructor_t *constructor;
  53    LSC_key_extractor_t *extractor;
  54    /* Caches for associated operations */
  55    LSC_encryptor_t *encryptor;
  56    LSC_decryptor_t *decryptor;
  57  };
  58  
  59  /*
  60   * Start with everything that concerns the key, which includes all
  61   * functions that are strictly for associated operatiion.
  62   */
  63  static LE_STATUS new_key_data(LSC_key_t *key, const void *unused)
  64  {
  65    if (key == NULL)
  66      return LE_STS_ERROR;
  67    struct stream_key_st **k = (struct stream_key_st **)&key->lsc_data;
  68  
  69    if (*k == NULL && (*k = malloc(sizeof(**k))) != NULL)
  70      memset(*k, 0, sizeof(**k));
  71    if (*k == NULL)
  72      return LE_STS_FATAL_ERROR;
  73    return LE_STS_SUCCESS;
  74  }
  75  
  76  static LE_STATUS scrub_key_data(LSC_key_t *key)
  77  {
  78    if (key == NULL || key->lsc_data == NULL)
  79      return LE_STS_SUCCESS;
  80  
  81    struct stream_key_st *k = key->lsc_data;
  82  
  83    free(k->key_bits);
  84    /* DO NOTE that we aren't scrubbing the cached associated operations */
  85    return LE_STS_SUCCESS;
  86  }
  87  
  88  static LE_STATUS clean_key_data(LSC_key_t *key)
  89  {
  90    LE_STATUS sts;
  91  
  92    if (key == NULL || key->lsc_data == NULL)
  93      return LE_STS_SUCCESS;
  94    if (T(sts = scrub_key_data(key))) {
  95      struct stream_key_st *k = key->lsc_data;
  96      /*
  97       * The constructor, encryptor and decryptor are cached, so they don't
  98       * provide a destroy function in the operation object, which means
  99       * that the LSC_free_key_{operation}() calls end up doing nothing.
 100       * Therefore, we must destroy them now, using their destroy functions
 101       * (which do exist) directly.
 102       */
 103      LSplugin_destroy_key_constructor(k->constructor);
 104      LSplugin_destroy_encryptor(k->encryptor);
 105      LSplugin_destroy_decryptor(k->decryptor);
 106      free(k);
 107      key->lsc_data = NULL;
 108    }
 109    return sts;
 110  }
 111  
 112  static LE_STATUS get_key_size(LSC_key_t *key, size_t *keysize)
 113  {
 114    struct stream_key_st *k = key->lsc_data;
 115  
 116    if (k->key_bits == NULL)
 117      return LE_STS_ERROR;
 118    *keysize = k->key_bits_len;
 119    return LE_STS_SUCCESS;
 120  }
 121  
 122  static LE_STATUS set_key_constructor(LSC_key_t *key,
 123                                       LSC_key_constructor_t *con)
 124  {
 125    struct stream_key_st *k = key->lsc_data;
 126  
 127    k->constructor = con;
 128    return LE_STS_SUCCESS;
 129  }
 130  
 131  static LE_STATUS set_key_encryptor(LSC_key_t *key, LSC_encryptor_t *enc)
 132  {
 133    struct stream_key_st *k = key->lsc_data;
 134  
 135    k->encryptor = enc;
 136    return LE_STS_SUCCESS;
 137  }
 138  
 139  static LE_STATUS set_key_decryptor(LSC_key_t *key, LSC_decryptor_t *dec)
 140  {
 141    struct stream_key_st *k = key->lsc_data;
 142  
 143    k->decryptor = dec;
 144    return LE_STS_SUCCESS;
 145  }
 146  
 147  /* Key constructor operation with support functions */
 148  
 149  struct stream_key_constructor_st {
 150    LSC_key_t *key;
 151  
 152    /* Operational parameters */
 153  
 154    /* Key bits */
 155    unsigned char *key_bits;
 156    size_t key_bits_len;          /* Measured in bits */
 157  
 158    /* True when they've been cached in the key itself */
 159    _Bool key_bits_cached;
 160  };
 161  
 162  static LE_STATUS scrub_key_constructor_data(LSC_key_constructor_t *op)
 163  {
 164    if (op == NULL || op->lsc_data == NULL)
 165      return LE_STS_SUCCESS;
 166  
 167    struct stream_key_constructor_st *c = op->lsc_data;
 168  
 169    memset(c, 0, sizeof(*c));
 170    return LE_STS_SUCCESS;
 171  }
 172  
 173  static LE_STATUS new_key_constructor_data(LSC_key_constructor_t *op)
 174  {
 175    LE_STATUS sts;
 176  
 177    if (op == NULL)
 178      return LE_STS_ERROR;
 179  
 180    struct stream_key_constructor_st **c
 181      = (struct stream_key_constructor_st **)&op->lsc_data;
 182  
 183      if (*c == NULL && (*c = malloc(sizeof(**c))) != NULL)
 184        memset(*c, 0, sizeof(**c));
 185    if (*c == NULL)
 186      return LE_STS_FATAL_ERROR;
 187    return LE_STS_SUCCESS;
 188  }
 189  
 190  static LE_STATUS clean_key_constructor_data(LSC_key_constructor_t *op)
 191  {
 192    LE_STATUS sts;
 193  
 194    if (op == NULL || op->lsc_data == NULL)
 195      return LE_STS_SUCCESS;
 196    if (T(sts = scrub_key_constructor_data(op))) {
 197      free(op->lsc_data);
 198      op->lsc_data = NULL;
 199    }
 200    return sts;
 201  }
 202  
 203  static LE_STATUS set_constructor_key(LSC_key_constructor_t *op,
 204                                          LSC_key_t *key)
 205  {
 206    LE_STATUS sts;
 207  
 208    if (LE_status_is_OK(sts = new_key_constructor_data(op))) {
 209      struct stream_key_constructor_st *c = op->lsc_data;
 210  
 211      c->key = key;
 212    }
 213    return sts;
 214  }
 215  
 216  static LE_STATUS get_constructor_key(LSC_key_constructor_t *op,
 217                                          LSC_key_t **key)
 218  {
 219    struct stream_key_constructor_st *c = op->lsc_data;
 220  
 221    *key = c->key;
 222    return LE_STS_SUCCESS;
 223  }
 224  
 225  static LE_STATUS construct_key_data(LSC_key_constructor_t *op)
 226  {
 227    LE_STATUS sts;
 228    struct stream_key_constructor_st *c = op->lsc_data;
 229    LSC_key_t *key = c != NULL ? c->key : NULL;
 230    struct stream_key_st *k = (key != NULL) ? key->lsc_data : NULL;
 231  
 232    if (c->key_bits_cached)
 233      return LE_STS_SUCCESS;
 234    if (T(sts = scrub_key_data(key))) {
 235      /* Cache the key bits in the key itself too, to support extraction */
 236      k->key_bits = c->key_bits;
 237      k->key_bits_len = c->key_bits_len;
 238      c->key_bits_cached = true;
 239    }
 240    return sts;
 241  }
 242  
 243  /*********************************************************************
 244   *
 245   *  ChaCha
 246   *
 247   *****/
 248  
 249  static LSplugin_param_functions_t chacha_key_bits_fns = {
 250    offsetof(struct stream_key_constructor_st, key_bits),
 251    offsetof(struct stream_key_constructor_st, key_bits_len),
 252    0, false,
 253    LSplugin_set_bitstring_param, LSplugin_get_bitstring_param
 254  };
 255  #define CHACHA_I_key_bits               1
 256  #define CHACHA_P_key_bits                                               \
 257    { "key", CHACHA_I_key_bits,                                           \
 258        { LSC_DT_bit_string, { { 128, 128, 0 }, { 256, 256, 0 }, },       \
 259            .d_auxilliary = { 0 }, },                                     \
 260        .p_private = &chacha_key_bits_fns }
 261  static const LSC_param_desc_t gettable_chacha_constructor_params[] = {
 262    CHACHA_P_key_bits,
 263    { NULL, }
 264  };
 265  static const LSC_param_desc_t settable_chacha_constructor_params[] = {
 266    CHACHA_P_key_bits,
 267    { NULL, }
 268  };
 269  
 270  static LE_STATUS
 271  get_chacha_construction_param_data(LSC_key_constructor_t *op, void **data)
 272  {
 273    *data = op->lsc_data;
 274    return LE_STS_SUCCESS;
 275  }
 276  
 277  static LE_STATUS
 278  get_gettable_chacha_construction_param_desc(LSC_key_constructor_t *op,
 279                                              const LSC_param_desc_t **param_desc)
 280  {
 281    assert(op != NULL);
 282    assert(param_desc != NULL);
 283    *param_desc = gettable_chacha_constructor_params;
 284    return LE_STS_SUCCESS;
 285  }
 286  
 287  static LE_STATUS
 288  get_settable_chacha_construction_param_desc(LSC_key_constructor_t *op,
 289                                              const LSC_param_desc_t **param_desc)
 290  {
 291    assert(op != NULL);
 292    assert(param_desc != NULL);
 293    *param_desc = settable_chacha_constructor_params;
 294    return LE_STS_SUCCESS;
 295  }
 296  
 297  /* Encryptor and decryptor */
 298  
 299  struct stream_state_chacha_st {
 300    /*
 301     * Pointer to the associated key, done this way to allow late
 302     * construction of the key (i.e. that LSC_construct_key() can
 303     * be called after LSC_set_encryptor_key()).
 304     * Using the public type allows working with keys from other
 305     * plugins (future extension).
 306     */
 307    LSC_key_t *key;
 308  
 309    unsigned char *nonce_bits;
 310    size_t nonce_bits_len;
 311    size_t initial_counter;
 312    size_t rounds;
 313  
 314    chacha_state libtomcrypt_data;
 315  };
 316  
 317  static LE_STATUS setup_chacha_data(struct stream_state_chacha_st **state)
 318  {
 319    if (*state == NULL) {
 320      *state = malloc(sizeof(**state));
 321      if (*state == NULL)
 322        return LE_STS_FATAL_ERROR;
 323      memset(*state, 0, sizeof(**state));
 324  
 325      /* defaults */
 326      (*state)->rounds = 20;
 327      (*state)->initial_counter = 1;
 328    }
 329    return LE_STS_SUCCESS;
 330  }
 331  static LE_STATUS setup_chacha_encryptor_data(LSC_encryptor_t *op)
 332  {
 333    return setup_chacha_data((struct stream_state_chacha_st **)&op->lsc_data);
 334  }
 335  static LE_STATUS setup_chacha_decryptor_data(LSC_decryptor_t *op)
 336  {
 337    return setup_chacha_data((struct stream_state_chacha_st **)&op->lsc_data);
 338  }
 339  
 340  static LE_STATUS clean_chacha_data(struct stream_state_chacha_st **state)
 341  {
 342    if (*state != NULL) {
 343      free(*state);
 344      *state = NULL;
 345    }
 346    return LE_STS_SUCCESS;
 347  }
 348  static LE_STATUS clean_chacha_encryptor_data(LSC_encryptor_t *op)
 349  {
 350    return clean_chacha_data((struct stream_state_chacha_st **)&op->lsc_data);
 351  }
 352  static LE_STATUS clean_chacha_decryptor_data(LSC_decryptor_t *op)
 353  {
 354    return clean_chacha_data((struct stream_state_chacha_st **)&op->lsc_data);
 355  }
 356  
 357  static LE_STATUS set_chacha_key(struct stream_state_chacha_st *state,
 358                                  LSC_key_t *key)
 359  {
 360    if (state == NULL)
 361      return LE_STS_ERROR;
 362    state->key = key;
 363    return LE_STS_SUCCESS;
 364  }
 365  static LE_STATUS set_chacha_encryptor_key(LSC_encryptor_t *op, LSC_key_t *key)
 366  {
 367    return set_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key);
 368  }
 369  static LE_STATUS set_chacha_decryptor_key(LSC_decryptor_t *op, LSC_key_t *key)
 370  {
 371    return set_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key);
 372  }
 373  
 374  static LE_STATUS get_chacha_key(struct stream_state_chacha_st *state,
 375                                  LSC_key_t **key)
 376  {
 377    if (state == NULL)
 378      return LE_STS_ERROR;
 379    if (key == NULL)
 380      return LE_STS_FATAL_ERROR;
 381    *key = state->key;
 382    return LE_STS_SUCCESS;
 383  }
 384  static LE_STATUS get_chacha_encryptor_key(LSC_encryptor_t *op, LSC_key_t **key)
 385  {
 386    return get_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key);
 387  }
 388  static LE_STATUS get_chacha_decryptor_key(LSC_decryptor_t *op, LSC_key_t **key)
 389  {
 390    return get_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key);
 391  }
 392  
 393  static LSplugin_param_functions_t stream_chacha_nonce_bits_fns = {
 394    offsetof(struct stream_state_chacha_st, nonce_bits),
 395    offsetof(struct stream_state_chacha_st, nonce_bits_len),
 396    0, false,
 397    LSplugin_set_bitstring_param, LSplugin_get_bitstring_param
 398  };
 399  #define CHACHA_I_nonce_bits             1
 400  #define CHACHA_P_nonce_bits                                     \
 401    { "nonce", CHACHA_I_nonce_bits,                               \
 402        { LSC_DT_bit_string, { { 64, 64, 8 }, { 96, 96, 8 }, },   \
 403            .d_auxilliary = { 0 }, },                             \
 404        .p_private = &stream_chacha_nonce_bits_fns }
 405  
 406  static LSplugin_param_functions_t chacha_counter_size_fns = {
 407    offsetof(struct stream_state_chacha_st, initial_counter), 0, 0, false,
 408    LSplugin_set_size_t_param, LSplugin_get_size_t_param
 409  };
 410  #define CHACHA_I_counter                2
 411  #define CHACHA_P_counter                                        \
 412    { "counter", CHACHA_I_counter,                                \
 413        { LSC_DT_integer,                                         \
 414            { { sizeof(size_t), sizeof(size_t) }, }, },           \
 415        .p_private = &chacha_counter_size_fns }
 416  static const LSC_param_desc_t gettable_chacha_params[] = {
 417    CHACHA_P_nonce_bits,
 418    CHACHA_P_counter,
 419    { NULL, }
 420  };
 421  static const LSC_param_desc_t settable_chacha_params[] = {
 422    CHACHA_P_nonce_bits,
 423    CHACHA_P_counter,
 424    { NULL, }
 425  };
 426  
 427  static LE_STATUS
 428  get_encryption_param_data(LSC_encryptor_t *enc, void **data)
 429  {
 430    *data = enc->lsc_data;
 431    return LE_STS_SUCCESS;
 432  }
 433  
 434  static LE_STATUS
 435  get_decryption_param_data(LSC_decryptor_t *enc, void **data)
 436  {
 437    *data = enc->lsc_data;
 438    return LE_STS_SUCCESS;
 439  }
 440  
 441  static LE_STATUS
 442  get_gettable_chacha_param_desc(struct stream_state_chacha_st *state,
 443                                 const LSC_param_desc_t **param_desc)
 444  {
 445    assert(state != NULL);
 446    assert(param_desc != NULL);
 447    *param_desc = gettable_chacha_params;
 448    return LE_STS_SUCCESS;
 449  }
 450  
 451  static LE_STATUS
 452  get_settable_chacha_param_desc(struct stream_state_chacha_st *state,
 453                                 const LSC_param_desc_t **param_desc)
 454  {
 455    assert(state != NULL);
 456    assert(param_desc != NULL);
 457    *param_desc = settable_chacha_params;
 458    return LE_STS_SUCCESS;
 459  }
 460  
 461  #define get_chacha_encryption_param_data        get_encryption_param_data
 462  static LE_STATUS
 463  get_gettable_chacha_encryption_param_desc(LSC_encryptor_t *enc,
 464                                            const LSC_param_desc_t **param_desc)
 465  {
 466    return get_gettable_chacha_param_desc(enc->lsc_data, param_desc);
 467  }
 468  
 469  static LE_STATUS
 470  get_settable_chacha_encryption_param_desc(LSC_encryptor_t *enc,
 471                                            const LSC_param_desc_t **param_desc)
 472  {
 473    return get_gettable_chacha_param_desc(enc->lsc_data, param_desc);
 474  }
 475  
 476  #define get_chacha_decryption_param_data        get_decryption_param_data
 477  static LE_STATUS
 478  get_gettable_chacha_decryption_param_desc(LSC_decryptor_t *dec,
 479                                            const LSC_param_desc_t **param_desc)
 480  {
 481    return get_gettable_chacha_param_desc(dec->lsc_data, param_desc);
 482  }
 483  
 484  static LE_STATUS
 485  get_settable_chacha_decryption_param_desc(LSC_decryptor_t *dec,
 486                                            const LSC_param_desc_t **param_desc)
 487  {
 488    return get_gettable_chacha_param_desc(dec->lsc_data, param_desc);
 489  }
 490  
 491  static LE_STATUS start_chacha(struct stream_state_chacha_st *state)
 492  {
 493    if (state == NULL)
 494      return LE_STS_ERROR;
 495    if (state->key == NULL || state->nonce_bits == NULL)
 496      return LE_STS_ERROR;
 497    struct stream_key_st *k = state->key->lsc_data;
 498    if (k == NULL)
 499      return LE_STS_ERROR;
 500    int err;
 501    err = chacha_setup(&state->libtomcrypt_data,
 502                       k->key_bits, k->key_bits_len / 8, 20);
 503    if (err != CRYPT_OK)
 504      return LE_STS_ERROR;
 505    if (state->nonce_bits_len == 96)
 506      err = chacha_ivctr32(&state->libtomcrypt_data, state->nonce_bits, 12,
 507                           (uint64_t)state->initial_counter);
 508    else
 509      err = chacha_ivctr64(&state->libtomcrypt_data, state->nonce_bits, 8,
 510                           (uint32_t)state->initial_counter);
 511    if (err != CRYPT_OK)
 512      return LE_STS_ERROR;
 513    return LE_STS_SUCCESS;
 514  }
 515  static LE_STATUS start_chacha_encryption(LSC_encryptor_t *enc)
 516  {
 517    return start_chacha((struct stream_state_chacha_st *)enc->lsc_data);
 518  }
 519  static LE_STATUS start_chacha_decryption(LSC_decryptor_t *dec)
 520  {
 521    return start_chacha((struct stream_state_chacha_st *)dec->lsc_data);
 522  }
 523  
 524  static LE_STATUS perform_chacha(struct stream_state_chacha_st *state,
 525                                  const unsigned char *in,
 526                                  size_t inlen,
 527                                  unsigned char *out, size_t outsize,
 528                                  size_t *outlen)
 529  {
 530    if (state == NULL)
 531      return LE_STS_ERROR;
 532    if (outlen != NULL)
 533      *outlen = inlen;
 534    if (out == NULL)
 535      return LE_STS_SUCCESS;
 536    if (in == NULL)
 537      return LE_STS_ERROR;
 538    if (outsize < inlen)
 539      return LE_STS_ERROR;
 540  
 541    int err;
 542    err = chacha_crypt(&state->libtomcrypt_data, in, inlen, out);
 543    if (err != CRYPT_OK)
 544      return LE_STS_ERROR;
 545    return LE_STS_SUCCESS;
 546  }
 547  static LE_STATUS perform_chacha_encryption(LSC_encryptor_t *enc,
 548                                             const unsigned char *in,
 549                                             size_t inlen,
 550                                             unsigned char *out, size_t outsize,
 551                                             size_t *outlen)
 552  {
 553    return perform_chacha((struct stream_state_chacha_st *)enc->lsc_data,
 554                          in, inlen, out, outsize, outlen);
 555  }
 556  static LE_STATUS perform_chacha_decryption(LSC_decryptor_t *dec,
 557                                             const unsigned char *in,
 558                                             size_t inlen,
 559                                             unsigned char *out, size_t outsize,
 560                                             size_t *outlen)
 561  {
 562    return perform_chacha((struct stream_state_chacha_st *)dec->lsc_data,
 563                          in, inlen, out, outsize, outlen);
 564  }
 565  
 566  
 567  static LE_STATUS finalize_chacha(struct stream_state_chacha_st *state,
 568                                   unsigned char *out, size_t outsize,
 569                                   size_t *outlen)
 570  {
 571    if (outlen != NULL)
 572      *outlen = 0;
 573    return LE_STS_SUCCESS;
 574  }
 575  static LE_STATUS finalize_chacha_encryption(LSC_encryptor_t *enc,
 576                                              unsigned char *out, size_t outsize,
 577                                              size_t *outlen)
 578  {
 579    return finalize_chacha((struct stream_state_chacha_st *)enc->lsc_data,
 580                           out, outsize, outlen);
 581  }
 582  static LE_STATUS finalize_chacha_decryption(LSC_decryptor_t *dec,
 583                                              unsigned char *out, size_t outsize,
 584                                              size_t *outlen)
 585  {
 586    return finalize_chacha((struct stream_state_chacha_st *)dec->lsc_data,
 587                           out, outsize, outlen);
 588  }
 589  
 590  static LE_STATUS stop_chacha(struct stream_state_chacha_st *state)
 591  {
 592    if (state == NULL)
 593      return LE_STS_ERROR;
 594    int err;
 595    err = chacha_done(&state->libtomcrypt_data);
 596    if (err != CRYPT_OK)
 597      return LE_STS_ERROR;
 598    return LE_STS_SUCCESS;
 599  }
 600  static LE_STATUS stop_chacha_encryption(LSC_encryptor_t *enc)
 601  {
 602    return stop_chacha((struct stream_state_chacha_st *)enc->lsc_data);
 603  }
 604  static LE_STATUS stop_chacha_decryption(LSC_decryptor_t *dec)
 605  {
 606    return stop_chacha((struct stream_state_chacha_st *)dec->lsc_data);
 607  }
 608  
 609  /*********************************************************************
 610   *
 611   *  RC4
 612   *
 613   *****/
 614  
 615  static LSplugin_param_functions_t rc4_key_bits_fns = {
 616    offsetof(struct stream_key_constructor_st, key_bits),
 617    offsetof(struct stream_key_constructor_st, key_bits_len),
 618    0, false,
 619    LSplugin_set_bitstring_param, LSplugin_get_bitstring_param
 620  };
 621  /* libtomcrypt documents that RC4 takes 5 - 256 byte keys */
 622  #define RC4_I_key_bits                  1
 623  #define RC4_P_key_bits                                                  \
 624    { "key", RC4_I_key_bits,                                              \
 625        { LSC_DT_bit_string, { { 40, 2048, 8 }, },                        \
 626            .d_auxilliary = { 0 }, },                                     \
 627        .p_private = &rc4_key_bits_fns }
 628  static const LSC_param_desc_t gettable_rc4_constructor_params[] = {
 629    RC4_P_key_bits,
 630  
 631    { NULL, }
 632  };
 633  static const LSC_param_desc_t settable_rc4_constructor_params[] = {
 634    RC4_P_key_bits,
 635    { NULL, }
 636  };
 637  
 638  static LE_STATUS
 639  get_rc4_construction_param_data(LSC_key_constructor_t *op, void **data)
 640  {
 641    *data = op->lsc_data;
 642    return LE_STS_SUCCESS;
 643  }
 644  
 645  static LE_STATUS
 646  get_gettable_rc4_construction_param_desc(LSC_key_constructor_t *op,
 647                                           const LSC_param_desc_t **param_desc)
 648  {
 649    assert(op != NULL);
 650    assert(param_desc != NULL);
 651    *param_desc = gettable_rc4_constructor_params;
 652    return LE_STS_SUCCESS;
 653  }
 654  
 655  static LE_STATUS
 656  get_settable_rc4_construction_param_desc(LSC_key_constructor_t *op,
 657                                           const LSC_param_desc_t **param_desc)
 658  {
 659    assert(op != NULL);
 660    assert(param_desc != NULL);
 661    *param_desc = settable_rc4_constructor_params;
 662    return LE_STS_SUCCESS;
 663  }
 664  
 665  /* Encryptor and decryptor */
 666  
 667  struct stream_state_rc4_st {
 668    /*
 669     * Pointer to the associated key, done this way to allow late
 670     * construction of the key (i.e. that LSC_construct_key() can
 671     * be called after LSC_set_encryptor_key()).
 672     * Using the public type allows working with keys from other
 673     * plugins (future extension).
 674     */
 675    LSC_key_t *key;
 676  
 677    rc4_state libtomcrypt_data;
 678  };
 679  
 680  static LE_STATUS setup_rc4_data(struct stream_state_rc4_st **state)
 681  {
 682    if (*state == NULL) {
 683      *state = malloc(sizeof(**state));
 684      if (*state == NULL)
 685        return LE_STS_FATAL_ERROR;
 686      memset(*state, 0, sizeof(**state));
 687    }
 688    return LE_STS_SUCCESS;
 689  }
 690  static LE_STATUS setup_rc4_encryptor_data(LSC_encryptor_t *op)
 691  {
 692    return setup_rc4_data((struct stream_state_rc4_st **)&op->lsc_data);
 693  }
 694  static LE_STATUS setup_rc4_decryptor_data(LSC_decryptor_t *op)
 695  {
 696    return setup_rc4_data((struct stream_state_rc4_st **)&op->lsc_data);
 697  }
 698  
 699  static LE_STATUS clean_rc4_data(struct stream_state_rc4_st **state)
 700  {
 701    if (*state != NULL) {
 702      free(*state);
 703      *state = NULL;
 704    }
 705    return LE_STS_SUCCESS;
 706  }
 707  static LE_STATUS clean_rc4_encryptor_data(LSC_encryptor_t *op)
 708  {
 709    return clean_rc4_data((struct stream_state_rc4_st **)&op->lsc_data);
 710  }
 711  static LE_STATUS clean_rc4_decryptor_data(LSC_decryptor_t *op)
 712  {
 713    return clean_rc4_data((struct stream_state_rc4_st **)&op->lsc_data);
 714  }
 715  
 716  static LE_STATUS set_rc4_key(struct stream_state_rc4_st *state,
 717                                  LSC_key_t *key)
 718  {
 719    if (state == NULL)
 720      return LE_STS_ERROR;
 721    state->key = key;
 722    return LE_STS_SUCCESS;
 723  }
 724  static LE_STATUS set_rc4_encryptor_key(LSC_encryptor_t *op, LSC_key_t *key)
 725  {
 726    return set_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key);
 727  }
 728  static LE_STATUS set_rc4_decryptor_key(LSC_decryptor_t *op, LSC_key_t *key)
 729  {
 730    return set_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key);
 731  }
 732  
 733  static LE_STATUS get_rc4_key(struct stream_state_rc4_st *state,
 734                                  LSC_key_t **key)
 735  {
 736    if (state == NULL)
 737      return LE_STS_ERROR;
 738    if (key == NULL)
 739      return LE_STS_FATAL_ERROR;
 740    *key = state->key;
 741    return LE_STS_SUCCESS;
 742  }
 743  static LE_STATUS get_rc4_encryptor_key(LSC_encryptor_t *op, LSC_key_t **key)
 744  {
 745    return get_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key);
 746  }
 747  static LE_STATUS get_rc4_decryptor_key(LSC_decryptor_t *op, LSC_key_t **key)
 748  {
 749    return get_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key);
 750  }
 751  
 752  #define get_rc4_encryption_param_data           NULL
 753  #define get_rc4_decryption_param_data           NULL
 754  #define get_gettable_rc4_encryption_param_desc  NULL
 755  #define get_settable_rc4_encryption_param_desc  NULL
 756  #define get_gettable_rc4_decryption_param_desc  NULL
 757  #define get_settable_rc4_decryption_param_desc  NULL
 758  
 759  static LE_STATUS start_rc4(struct stream_state_rc4_st *state)
 760  {
 761    if (state == NULL)
 762      return LE_STS_ERROR;
 763    if (state->key == NULL)
 764      return LE_STS_ERROR;
 765    struct stream_key_st *k = state->key->lsc_data;
 766    if (k == NULL)
 767      return LE_STS_ERROR;
 768    int err;
 769    err = rc4_stream_setup(&state->libtomcrypt_data,
 770                           k->key_bits, k->key_bits_len / 8);
 771    if (err != CRYPT_OK)
 772      return LE_STS_ERROR;
 773    return LE_STS_SUCCESS;
 774  }
 775  static LE_STATUS start_rc4_encryption(LSC_encryptor_t *enc)
 776  {
 777    return start_rc4((struct stream_state_rc4_st *)enc->lsc_data);
 778  }
 779  static LE_STATUS start_rc4_decryption(LSC_decryptor_t *dec)
 780  {
 781    return start_rc4((struct stream_state_rc4_st *)dec->lsc_data);
 782  }
 783  
 784  static LE_STATUS perform_rc4(struct stream_state_rc4_st *state,
 785                               const unsigned char *in,
 786                               size_t inlen,
 787                               unsigned char *out, size_t outsize,
 788                               size_t *outlen)
 789  {
 790    if (state == NULL)
 791      return LE_STS_ERROR;
 792    if (outlen != NULL)
 793      *outlen = inlen;
 794    if (out == NULL)
 795      return LE_STS_SUCCESS;
 796    if (in == NULL)
 797      return LE_STS_ERROR;
 798    if (outsize < inlen)
 799      return LE_STS_ERROR;
 800  
 801    int err;
 802    err = rc4_stream_crypt(&state->libtomcrypt_data, in, inlen, out);
 803    if (err != CRYPT_OK)
 804      return LE_STS_ERROR;
 805    return LE_STS_SUCCESS;
 806  }
 807  static LE_STATUS perform_rc4_encryption(LSC_encryptor_t *enc,
 808                                          const unsigned char *in,
 809                                          size_t inlen,
 810                                          unsigned char *out, size_t outsize,
 811                                          size_t *outlen)
 812  {
 813    return perform_rc4((struct stream_state_rc4_st *)enc->lsc_data,
 814                          in, inlen, out, outsize, outlen);
 815  }
 816  static LE_STATUS perform_rc4_decryption(LSC_decryptor_t *dec,
 817                                          const unsigned char *in,
 818                                          size_t inlen,
 819                                          unsigned char *out, size_t outsize,
 820                                          size_t *outlen)
 821  {
 822    return perform_rc4((struct stream_state_rc4_st *)dec->lsc_data,
 823                          in, inlen, out, outsize, outlen);
 824  }
 825  
 826  
 827  static LE_STATUS finalize_rc4(struct stream_state_rc4_st *state,
 828                                unsigned char *out, size_t outsize,
 829                                size_t *outlen)
 830  {
 831    if (outlen != NULL)
 832      *outlen = 0;
 833    return LE_STS_SUCCESS;
 834  }
 835  static LE_STATUS finalize_rc4_encryption(LSC_encryptor_t *enc,
 836                                           unsigned char *out, size_t outsize,
 837                                           size_t *outlen)
 838  {
 839    return finalize_rc4((struct stream_state_rc4_st *)enc->lsc_data,
 840                        out, outsize, outlen);
 841  }
 842  static LE_STATUS finalize_rc4_decryption(LSC_decryptor_t *dec,
 843                                              unsigned char *out, size_t outsize,
 844                                              size_t *outlen)
 845  {
 846    return finalize_rc4((struct stream_state_rc4_st *)dec->lsc_data,
 847                        out, outsize, outlen);
 848  }
 849  
 850  static LE_STATUS stop_rc4(struct stream_state_rc4_st *state)
 851  {
 852    if (state == NULL)
 853      return LE_STS_ERROR;
 854    int err;
 855    err = rc4_stream_done(&state->libtomcrypt_data);
 856    if (err != CRYPT_OK)
 857      return LE_STS_ERROR;
 858    return LE_STS_SUCCESS;
 859  }
 860  static LE_STATUS stop_rc4_encryption(LSC_encryptor_t *enc)
 861  {
 862    return stop_rc4((struct stream_state_rc4_st *)enc->lsc_data);
 863  }
 864  static LE_STATUS stop_rc4_decryption(LSC_decryptor_t *dec)
 865  {
 866    return stop_rc4((struct stream_state_rc4_st *)dec->lsc_data);
 867  }
 868  
 869  /*********************************************************************
 870   *
 871   *  Common operator functions
 872   *
 873   *****/
 874  
 875  /* The unit size of a stream cipher is always 1 */
 876  static LE_STATUS get_stream_encryption_unit_size(LSC_encryptor_t *enc,
 877                                                   size_t *size)
 878  {
 879    if (size == NULL)
 880      return LE_STS_FATAL_ERROR;
 881    *size = 1;
 882    return LE_STS_SUCCESS;
 883  }
 884  static LE_STATUS get_stream_decryption_unit_size(LSC_decryptor_t *enc,
 885                                                   size_t *size)
 886  {
 887    if (size == NULL)
 888      return LE_STS_FATAL_ERROR;
 889    *size = 1;
 890    return LE_STS_SUCCESS;
 891  }
 892  
 893  static LE_STATUS get_stream_encryption_input_size(LSC_encryptor_t *enc,
 894                                                    size_t *size)
 895  {
 896    if (size == NULL)
 897      return LE_STS_FATAL_ERROR;
 898    *size = 0;
 899    return LE_STS_SUCCESS;
 900  }
 901  static LE_STATUS get_stream_decryption_input_size(LSC_decryptor_t *enc,
 902                                                    size_t *size)
 903  {
 904    if (size == NULL)
 905      return LE_STS_FATAL_ERROR;
 906    *size = 0;
 907    return LE_STS_SUCCESS;
 908  }
 909  
 910  static LE_STATUS get_stream_encryption_output_size(LSC_encryptor_t *enc,
 911                                                     size_t *size)
 912  {
 913    if (size == NULL)
 914      return LE_STS_FATAL_ERROR;
 915    *size = 0;
 916    return LE_STS_SUCCESS;
 917  }
 918  static LE_STATUS get_stream_decryption_output_size(LSC_decryptor_t *enc,
 919                                                     size_t *size)
 920  {
 921    if (size == NULL)
 922      return LE_STS_FATAL_ERROR;
 923    *size = 0;
 924    return LE_STS_SUCCESS;
 925  }
 926  
 927  /*********************************************************************
 928   *
 929   *  Implementation tables
 930   *
 931   *****/
 932  
 933  #define IMPL_chacha_NAME()              "chacha"
 934  #define IMPL_rc4_NAME()                 "rc4"
 935  #define IMPL_encryptor_COMMANDS()                                       \
 936    LSC_ENCRYPTOR_TYPE_BASE_COMMANDS(), LSC_ENCRYPTOR_SIZE_COMMANDS(),    \
 937      LSC_NR_start_encryption, LSC_NR_perform_encryption,                 \
 938      LSC_NR_stop_encryption
 939  #define IMPL_decryptor_COMMANDS()                                       \
 940    LSC_DECRYPTOR_TYPE_BASE_COMMANDS(), LSC_DECRYPTOR_SIZE_COMMANDS(),    \
 941      LSC_NR_start_decryption, LSC_NR_perform_decryption,                 \
 942      LSC_NR_stop_decryption
 943  #define IMPL_CIPHER_OP(T1,T2,N)                                         \
 944    const LSplugin_##T1##_desc_t ltc_##N##_##T1##_desc = {                \
 945      NULL, IMPL_##N##_NAME(), NULL, IMPL_##N##_NAME(),                   \
 946      setup_##N##_##T1##_data, clean_##N##_##T1##_data,                   \
 947      NULL, set_##N##_##T1##_key, get_##N##_##T1##_key,                   \
 948      (int[]){ IMPL_##T1##_COMMANDS(), 0 },                               \
 949      get_##N##_##T2##_param_data,                                        \
 950      get_gettable_##N##_##T2##_param_desc,                               \
 951      get_settable_##N##_##T2##_param_desc,                               \
 952      get_stream_##T2##_unit_size,                                        \
 953      get_stream_##T2##_input_size,                                       \
 954      get_stream_##T2##_output_size,                                      \
 955      NULL, /* No perform once */                                         \
 956      start_##N##_##T2,                                                   \
 957      perform_##N##_##T2,                                                 \
 958      finalize_##N##_##T2,                                                \
 959      stop_##N##_##T2,                                                    \
 960    };
 961  #define IMPL_KEY_CONSTRUCTOR_OP(N)                                      \
 962    static const LSplugin_key_constructor_desc_t                          \
 963    ltc_##N##_key_constructor_desc = {                                    \
 964      NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ \
 965      new_key_constructor_data, clean_key_constructor_data,               \
 966      set_key_constructor, set_constructor_key, get_constructor_key,      \
 967      (int[]){ LSC_KEY_TYPE_CONSTRUCTOR_COMMANDS(),                       \
 968               LSC_NR_get_settable_key_construction_param_desc,           \
 969               LSC_NR_set_key_construction_param,                         \
 970               LSC_NR_get_gettable_key_construction_param_desc,           \
 971               LSC_NR_get_key_construction_param,                         \
 972               LSC_NR_construct_key, 0 },                                 \
 973      get_##N##_construction_param_data,                                  \
 974      get_gettable_##N##_construction_param_desc, /* gettable */          \
 975      get_settable_##N##_construction_param_desc, /* settable */          \
 976      construct_key_data                                                  \
 977    }
 978  #define IMPL_KEY_CIPHER_OP(T1,T2,N)                                     \
 979    static const LSplugin_##T1##_desc_t ltc_##N##_key_##T1##_desc = {     \
 980      NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ \
 981      NULL, NULL,                                                         \
 982      set_key_##T1, set_##N##_##T1##_key, get_##N##_##T1##_key,           \
 983      (int[]){ IMPL_##T1##_COMMANDS(), 0 },                               \
 984      NULL, NULL, NULL,                                                   \
 985      get_stream_##T2##_unit_size,                                        \
 986      NULL, /* No get_##N##_##T##_input_size */                           \
 987      NULL, /* No get_##N##_##T##_output_size */                          \
 988      NULL, /* No perform once */                                         \
 989      start_##N##_##T2,                                                   \
 990      perform_##N##_##T2,                                                 \
 991      finalize_##N##_##T2,                                                \
 992      stop_##N##_##T2,                                                    \
 993    }
 994  #define IMPL_CIPHER_KEY(N)                                              \
 995    IMPL_KEY_CONSTRUCTOR_OP(N);                                           \
 996    IMPL_KEY_CIPHER_OP(encryptor,encryption,N);                           \
 997    IMPL_KEY_CIPHER_OP(decryptor,decryption,N);                           \
 998    const LSplugin_key_desc_t ltc_##N##_desc = {                          \
 999      NULL, IMPL_##N##_NAME(), NULL,                                      \
1000      new_key_data, clean_key_data,                                       \
1001      (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),                              \
1002               LSC_NR_get_key_size,                                       \
1003               LSC_NR_get_key_constructor,                                \
1004               LSC_NR_get_associated_encryptor,                           \
1005               LSC_NR_get_associated_decryptor, 0 },                      \
1006      get_key_size,                                                       \
1007      NULL,                    /* No key generator */                     \
1008      &ltc_##N##_key_constructor_desc,                                    \
1009      NULL,                    /* No key extractor */                     \
1010      &ltc_##N##_key_encryptor_desc,                                      \
1011      &ltc_##N##_key_decryptor_desc,                                      \
1012    }
1013  #define IMPL_CIPHER(N)                                                  \
1014    IMPL_CIPHER_OP(encryptor,encryption,N);                               \
1015    IMPL_CIPHER_OP(decryptor,decryption,N);                               \
1016    IMPL_CIPHER_KEY(N)
1017  
1018  IMPL_CIPHER(chacha);
1019  IMPL_CIPHER(rc4);