/ ltc-sym-ciphers.c
ltc-sym-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  #include <assert.h>
  18  #include <string.h>
  19  #include <tomcrypt.h>
  20  #include <lscrypto/encrypt.h>
  21  #include <lsplugin/mkobject.h>
  22  #include <lsplugin/mkoperator.h>
  23  #include <lsplugin/param.h>
  24  #include "ltc-sym-keys.h"
  25  
  26  /*
  27   * Common structure for all modes.
  28   * This forms the base for the mode specific context structures, and is relied
  29   * upon by the per operation functions.
  30   */
  31  
  32  struct sym_cipher_data_st {
  33    int cipher_idx;
  34    const struct ltc_cipher_descriptor *cipher;
  35  
  36    /*
  37     * Pointer to the associated key, done this way to allow late
  38     * construction of the key (i.e. that LSC_construct_key() can
  39     * be called after LSC_set_encryptor_key()).
  40     * Using the public type allows working with keys from other
  41     * plugins (future extension).
  42     */
  43    LSC_key_t *key;
  44    /*
  45     * libtomcrypt supports |num_rounds| for all cipher modes
  46     */
  47    int num_rounds;
  48    /*
  49     * Many modes have a different unit size than the base algorithm.
  50     */
  51    size_t mode_unit_size;
  52  
  53    /*
  54     * Parametric data
  55     */
  56    /* PKCS#5 / PKCS#7 padding, common for all algorithms.  True / false */
  57    int pad;
  58  
  59    /* IV, common for most algorithms.  Must be of block length size */
  60    unsigned char *iv;
  61    size_t iv_len;                /* Measured in bits */
  62  
  63    /*
  64     * Parameter descriptions.
  65     * They need to be dynamic, because the minimum and maximum size
  66     * depend on the encrypt/decrypt unit size.
  67     */
  68    size_t next_gettable;
  69    LSC_param_desc_t gettable_params[9];
  70    size_t next_settable;
  71    LSC_param_desc_t settable_params[9];
  72  
  73    /*
  74     * Buffer and length for partial blocks
  75     */
  76    /* Oversized: 32 => 256 bits, that's twice AES' block size */
  77    unsigned char partial[32];
  78    size_t partial_len;
  79  
  80    /*
  81     * init, perform and done functions.  |state| is a pointer to the mode
  82     * specific context structure.
  83     */
  84    int (*start)(void *state);
  85    int (*perform)(const unsigned char *from, unsigned char *to,
  86                   unsigned long len, void *state);
  87    int (*stop)(void *state);
  88  
  89    /*
  90     * Pointer to mode specific context structure
  91     */
  92    void *state;
  93  };
  94  
  95  /*
  96   * Common functions
  97   */
  98  static LE_STATUS
  99  setup_common_data(struct sym_cipher_data_st *data,
 100                    const struct ltc_cipher_descriptor *libtomcrypt_desc)
 101  {
 102    int i = register_cipher(libtomcrypt_desc);
 103  
 104    if (i < 0)
 105      return LE_STS_ERROR;
 106  
 107    assert(data != NULL);
 108    data->cipher_idx = i;
 109    data->cipher = libtomcrypt_desc;
 110    data->partial_len = 0;
 111  
 112    /* Padding enabled by default */
 113    data->pad = 1;
 114    /* The unit size set to the base algorithm's block length */
 115    data->mode_unit_size = data->cipher->block_length;
 116  
 117    /* No IV by default */
 118    data->iv = NULL;
 119  
 120    return LE_STS_SUCCESS;
 121  }
 122  
 123  static LE_STATUS setup_common_data_key(struct sym_cipher_data_st *data,
 124                                         LSC_key_t *key)
 125  {
 126    assert(key != NULL && key->lsc_dispatch != NULL);
 127  
 128    /* The ltc plugin currently only supports its own keys */
 129    if (key->lsc_dispatch != LSplugin_key_dispatch)
 130      return LE_STS_ERROR;
 131  
 132    data->key = key;
 133    return LE_STS_SUCCESS;
 134  }
 135  
 136  static LSplugin_param_functions_t pad_fns = {
 137    offsetof(struct sym_cipher_data_st, pad), 0, 0, false,
 138    LSplugin_set_int_param, LSplugin_get_int_param
 139  };
 140  #define I_PAD                   0
 141  #define P_PAD                                                   \
 142    { "pad", I_PAD,                                               \
 143        { LSC_DT_integer, { { sizeof(int), sizeof(int) }, },      \
 144            .d_auxilliary = { 0 }, },                             \
 145        &pad_fns }
 146  
 147  static LE_STATUS
 148  setup_common_gettable_pad_param(struct sym_cipher_data_st *data)
 149  {
 150    assert(data != NULL);
 151  
 152    size_t i = data->next_gettable;
 153    size_t block_bitslen = data->cipher->block_length * 8;
 154    data->gettable_params[i] = (LSC_param_desc_t) P_PAD;
 155    data->next_gettable = ++i;
 156    assert(i < sizeof(data->gettable_params) / sizeof(data->gettable_params[0]));
 157    data->gettable_params[i] = (LSC_param_desc_t) { NULL, };
 158  
 159    return LE_STS_SUCCESS;
 160  }
 161  
 162  static LE_STATUS
 163  setup_common_settable_pad_param(struct sym_cipher_data_st *data)
 164  {
 165    assert(data != NULL);
 166  
 167    size_t i = data->next_settable;
 168    size_t block_bitslen = data->cipher->block_length * 8;
 169    data->settable_params[i] = (LSC_param_desc_t) P_PAD;
 170    data->next_settable = ++i;
 171    assert(i < sizeof(data->settable_params) / sizeof(data->settable_params[0]));
 172    data->settable_params[i] = (LSC_param_desc_t) { NULL, };
 173  
 174    return LE_STS_SUCCESS;
 175  }
 176  
 177  static LSplugin_param_functions_t iv_fns = {
 178    offsetof(struct sym_cipher_data_st, iv),
 179    offsetof(struct sym_cipher_data_st, iv_len),
 180    0, false,
 181    LSplugin_set_bitstring_param, LSplugin_get_bitstring_param
 182  };
 183  #define I_IV                    1
 184  #define P_IV                                                    \
 185    { "iv", I_IV,                                                 \
 186        { LSC_DT_bit_string, { { 0, 0 }, },                       \
 187            .d_auxilliary = { 0 }, },                             \
 188        &iv_fns }
 189  
 190  static LE_STATUS
 191  setup_common_gettable_iv_param(struct sym_cipher_data_st *data)
 192  {
 193    assert(data != NULL);
 194  
 195    size_t i = data->next_gettable;
 196    size_t block_bitslen = data->cipher->block_length * 8;
 197    data->gettable_params[i] = (LSC_param_desc_t) P_IV;
 198    data->gettable_params[i].p_data.d_elems[0].min = block_bitslen;
 199    data->gettable_params[i].p_data.d_elems[0].max = block_bitslen;
 200    data->next_gettable = ++i;
 201    assert(i < sizeof(data->gettable_params) / sizeof(data->gettable_params[0]));
 202    data->gettable_params[i] = (LSC_param_desc_t) { NULL, };
 203  
 204    return LE_STS_SUCCESS;
 205  }
 206  
 207  static LE_STATUS
 208  setup_common_settable_iv_param(struct sym_cipher_data_st *data)
 209  {
 210    assert(data != NULL);
 211  
 212    size_t i = data->next_settable;
 213    size_t block_bitslen = data->cipher->block_length * 8;
 214    data->settable_params[i] = (LSC_param_desc_t) P_IV;
 215    data->settable_params[i].p_data.d_elems[0].min = block_bitslen;
 216    data->settable_params[i].p_data.d_elems[0].max = block_bitslen;
 217    data->next_settable = ++i;
 218    assert(i < sizeof(data->settable_params) / sizeof(data->settable_params[0]));
 219    data->settable_params[i] = (LSC_param_desc_t) { NULL, };
 220  
 221    return LE_STS_SUCCESS;
 222  }
 223  
 224  static LE_STATUS common_start(struct sym_cipher_data_st *data)
 225  {
 226    assert(data->start != NULL && data->state != NULL);
 227    /*
 228     * If some code has padding enabled and the mode unit size == 1
 229     * something's wrong...
 230     */
 231    assert(!data->pad || data->mode_unit_size > 1);
 232  
 233    return (data->start(data->state) == CRYPT_OK) ? LE_STS_SUCCESS : LE_STS_ERROR;
 234  }
 235  
 236  static LE_STATUS
 237  common_perform_encryption(struct sym_cipher_data_st *data,
 238                            const unsigned char *in, size_t inlen,
 239                            unsigned char *out, size_t outsize,
 240                            size_t *outlen)
 241  {
 242    assert(data->perform != NULL && data->state != NULL);
 243  
 244    size_t enclen = inlen;
 245    if (data->mode_unit_size > 1) {
 246      enclen = (((data->partial_len + inlen) / data->mode_unit_size)
 247                * data->mode_unit_size);
 248    }
 249  
 250    if (outlen != NULL)
 251      *outlen = enclen;
 252    if (out == NULL)
 253      return LE_STS_WARNING;
 254    if (outsize < enclen)
 255      return LE_STS_ERROR;
 256  
 257    if (data->mode_unit_size > 1) {
 258      if (data->partial_len > 0
 259          || data->partial_len + inlen < data->mode_unit_size) {
 260        size_t copy_len = data->mode_unit_size - data->partial_len;
 261        if (copy_len > inlen)
 262          copy_len = inlen;
 263        memcpy(data->partial + data->partial_len, in, copy_len);
 264        data->partial_len += copy_len;
 265        in += copy_len;
 266        inlen -= copy_len;
 267      }
 268  
 269      if (data->partial_len == data->mode_unit_size) {
 270        if (data->perform(data->partial, out, data->partial_len, data->state)
 271            != CRYPT_OK)
 272          return LE_STS_ERROR;
 273        out += data->partial_len;
 274        enclen -= data->partial_len;
 275      }
 276    }
 277  
 278    if (enclen > 0) {
 279      if (data->perform(in, out, enclen, data->state) != CRYPT_OK)
 280        return LE_STS_ERROR;
 281      out += enclen;
 282      in += enclen;
 283      inlen -= enclen;
 284      enclen = 0;
 285    }
 286  
 287    /* If there was anything to encrypt, we may have some trailing input */
 288    if (inlen != 0) {
 289      memcpy(data->partial, in, inlen);
 290      data->partial_len = inlen;
 291    }
 292  
 293    return LE_STS_SUCCESS;
 294  }
 295  
 296  static LE_STATUS
 297  common_finalize_encryption(struct sym_cipher_data_st *data,
 298                             unsigned char *out, size_t outsize,
 299                             size_t *outlen)
 300  {
 301    if (outlen != NULL)
 302      *outlen = data->pad ? data->mode_unit_size : 0;
 303    if (out == NULL)
 304      return LE_STS_WARNING;
 305    if (data->pad && outsize < data->mode_unit_size)
 306      return LE_STS_ERROR;
 307  
 308    if (data->pad) {
 309      /* Standard PKCS#5 / PKCS#7 padding */
 310      size_t n = data->mode_unit_size - data->partial_len;
 311      memset(data->partial + data->partial_len, (char)n, n);
 312      if (data->perform(data->partial, out, data->mode_unit_size,
 313                        data->state) != CRYPT_OK)
 314        return LE_STS_ERROR;
 315    } else {
 316      /* No padding means there must be no remaining bytes */
 317      if (data->partial_len > 0)
 318        return LE_STS_ERROR;
 319    }
 320    return LE_STS_SUCCESS;
 321  }
 322  
 323  static LE_STATUS
 324  common_perform_decryption(struct sym_cipher_data_st *data,
 325                            const unsigned char *in, size_t inlen,
 326                            unsigned char *out, size_t outsize,
 327                            size_t *outlen)
 328  {
 329    assert(data->perform != NULL && data->state != NULL);
 330  
 331    size_t declen = inlen;
 332    if (data->mode_unit_size > 1) {
 333      declen = (((data->partial_len + inlen) / data->mode_unit_size)
 334                * data->mode_unit_size);
 335  
 336      /*
 337       * If we're padding, we must save away the last block, to be treated
 338       * by common_finalize_decryption.  To enable that, adjust declen if
 339       * the partial length plus inlen is an exact number of blocks.
 340       */
 341      if (data->pad && declen == data->partial_len + inlen)
 342        declen -= data->mode_unit_size;
 343    }
 344  
 345    if (outlen != NULL)
 346      *outlen = declen;
 347    if (out == NULL)
 348      return LE_STS_WARNING;
 349    if (outsize < declen)
 350      return LE_STS_ERROR;
 351  
 352    if (data->mode_unit_size > 1) {
 353      if (data->partial_len > 0
 354          || data->partial_len + inlen < data->mode_unit_size) {
 355        size_t copy_len = data->mode_unit_size - data->partial_len;
 356        if (copy_len > inlen)
 357          copy_len = inlen;
 358        memcpy(data->partial + data->partial_len, in, copy_len);
 359        data->partial_len += copy_len;
 360        in += copy_len;
 361        inlen -= copy_len;
 362      }
 363  
 364      if (declen > 0) {
 365        if (data->partial_len == data->mode_unit_size) {
 366          if (data->perform(data->partial, out, data->partial_len, data->state)
 367              != CRYPT_OK)
 368            return LE_STS_ERROR;
 369          out += data->partial_len;
 370          declen -= data->partial_len;
 371        }
 372      }
 373    }
 374  
 375    if (declen > 0) {
 376      if (data->perform(in, out, declen, data->state) != CRYPT_OK)
 377        return LE_STS_ERROR;
 378      out += declen;
 379      in += declen;
 380      inlen -= declen;
 381      declen = 0;
 382    }
 383  
 384    /* If there was anything to decrypt, we may have some trailing input */
 385    if (inlen != 0) {
 386      memcpy(data->partial, in, inlen);
 387      data->partial_len = inlen;
 388    }
 389  
 390    return LE_STS_SUCCESS;
 391  }
 392  
 393  static LE_STATUS
 394  common_finalize_decryption(struct sym_cipher_data_st *data,
 395                             unsigned char *out, size_t outsize,
 396                             size_t *outlen)
 397  {
 398    if (outlen != NULL)
 399      *outlen = data->pad ? data->mode_unit_size : 0;
 400    if (out == NULL)
 401      return LE_STS_WARNING;
 402    if (data->pad && outsize < data->mode_unit_size)
 403      return LE_STS_ERROR;
 404  
 405    if (data->pad) {
 406      /*
 407       * Check for standard PKCS#5 / PKCS#7 padding and pass back
 408       * just the right amount of data.
 409       */
 410      if (data->partial_len != data->mode_unit_size)
 411        return LE_STS_ERROR;
 412      unsigned char buf[data->mode_unit_size];
 413      if (data->perform(data->partial, buf, data->mode_unit_size,
 414                        data->state) != CRYPT_OK)
 415        return LE_STS_ERROR;
 416      char c = buf[data->mode_unit_size - 1];
 417      if (c < 1 || c > data->mode_unit_size)
 418        return LE_STS_ERROR;
 419      size_t i;
 420      size_t start = data->mode_unit_size - c;
 421      for (i = start; i < data->mode_unit_size; i++)
 422        if (buf[i] != c)
 423          return LE_STS_ERROR;
 424  
 425      if (outlen != NULL)
 426        *outlen = start;
 427      if (start > 0)
 428        memcpy(out, data->partial, start);
 429    } else {
 430      /* No padding means there must be no remaining bytes */
 431      if (data->partial_len > 0)
 432        return LE_STS_ERROR;
 433    }
 434    return LE_STS_SUCCESS;
 435  }
 436  
 437  static LE_STATUS common_stop(struct sym_cipher_data_st *data)
 438  {
 439    assert(data->stop != NULL && data->state != NULL);
 440  
 441    return (data->stop(data->state) == CRYPT_OK) ? LE_STS_SUCCESS : LE_STS_ERROR;
 442  }
 443  
 444  static LE_STATUS cleanup_common_data(struct sym_cipher_data_st *data)
 445  {
 446    LE_STATUS sts = LE_STS_SUCCESS;
 447  
 448    if (data != NULL) {
 449      if (data->stop != NULL && data->state != NULL)
 450        sts = common_stop(data);
 451      data->key = NULL;
 452      data->partial_len = 0;
 453      data->cipher_idx = -1;
 454      data->cipher = NULL;
 455    }
 456    return sts;
 457  }
 458  
 459  /*********************************************************************
 460   *
 461   *  ECB specific structure and functions
 462   *
 463   *****/
 464  
 465  /* ECB context structure */
 466  struct sym_cipher_ecb_state_st {
 467    struct sym_cipher_data_st base;
 468    symmetric_ECB libtomcrypt_data;
 469  };
 470  
 471  static int ltc_ecb_init(void *state)
 472  {
 473    struct sym_cipher_ecb_state_st *data = state;
 474    struct ltc_symkey_st *k = data->base.key->lsc_data;
 475  
 476    int err = ecb_start(data->base.cipher_idx,
 477                        k->key_bits, k->key_bits_len / 8,
 478                        data->base.num_rounds, &data->libtomcrypt_data);
 479  
 480    return err;
 481  }
 482  
 483  static int ltc_ecb_enc(const unsigned char *from, unsigned char *to,
 484                         unsigned long len, void *state)
 485  {
 486    struct sym_cipher_ecb_state_st *data = state;
 487  
 488    int err = ecb_encrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
 489  
 490    return err;
 491  }
 492  
 493  static int ltc_ecb_dec(const unsigned char *from, unsigned char *to,
 494                         unsigned long len, void *state)
 495  {
 496    struct sym_cipher_ecb_state_st *data = state;
 497  
 498    int err = ecb_decrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
 499  
 500    return err;
 501  }
 502  
 503  static int ltc_ecb_done(void *state)
 504  {
 505    struct sym_cipher_ecb_state_st *data = state;
 506  
 507    int err = ecb_done(&data->libtomcrypt_data);
 508  
 509    return err;
 510  }
 511  
 512  static LE_STATUS
 513  setup_sym_ecb_data(struct sym_cipher_ecb_state_st **state,
 514                     const struct ltc_cipher_descriptor *libtomcrypt_desc,
 515                     int encdec /* 1 = enc, -1 = dec */)
 516  {
 517    assert(state != NULL);
 518    assert(encdec == 1 || encdec == -1);
 519  
 520    if (*state == NULL) {
 521      *state = malloc(sizeof(**state));
 522      memset(*state, 0, sizeof(**state));
 523  
 524      LE_STATUS sts;
 525  
 526      if (!LE_status_is_OK(sts = setup_common_data(&(*state)->base,
 527                                                   libtomcrypt_desc)))
 528        return sts;
 529      if (!LE_status_is_OK(sts = setup_common_gettable_pad_param(&(*state)->base)))
 530        return sts;
 531      if (!LE_status_is_OK(sts = setup_common_settable_pad_param(&(*state)->base)))
 532        return sts;
 533  
 534      (*state)->base.start = ltc_ecb_init;
 535      (*state)->base.perform = encdec > 0 ? ltc_ecb_enc : ltc_ecb_dec ;
 536      (*state)->base.stop = ltc_ecb_done;
 537      (*state)->base.state = *state;
 538    }
 539    if (*state == NULL)
 540      return LE_STS_FATAL_ERROR;
 541  
 542    assert((*state)->base.start == ltc_ecb_init);
 543    assert((*state)->base.perform == (encdec > 0 ? ltc_ecb_enc : ltc_ecb_dec));
 544    assert((*state)->base.stop = ltc_ecb_done);
 545  
 546    return LE_STS_SUCCESS;
 547  }
 548  
 549  static LE_STATUS clean_sym_ecb_data(struct sym_cipher_ecb_state_st **state)
 550  {
 551    assert(state != NULL);
 552  
 553    if (*state != NULL) {
 554      cleanup_common_data(&(*state)->base);
 555      (*state)->base.start = NULL;
 556      (*state)->base.perform = NULL;
 557      (*state)->base.stop = NULL;
 558      (*state)->base.state = NULL;
 559  
 560      free(*state);
 561      *state = NULL;
 562    }
 563  
 564    return LE_STS_SUCCESS;    /* Not yet implemented */
 565  }
 566  
 567  static LE_STATUS setup_sym_ecb_encryptor_data(LSC_encryptor_t *op)
 568  {
 569    struct sym_cipher_ecb_state_st **state
 570      = (struct sym_cipher_ecb_state_st **)&op->lsc_data;
 571    const LSplugin_encryptor_desc_t *desc = op->lsc_dispatch_data;
 572  
 573    return setup_sym_ecb_data(state, desc->lsp_priv_desc, 1);
 574  }
 575  static LE_STATUS clean_sym_ecb_encryptor_data(LSC_encryptor_t *op)
 576  {
 577    struct sym_cipher_ecb_state_st **state
 578      = (struct sym_cipher_ecb_state_st **)&op->lsc_data;
 579  
 580    return clean_sym_ecb_data(state);
 581  }
 582  
 583  static LE_STATUS setup_sym_ecb_decryptor_data(LSC_decryptor_t *op)
 584  {
 585    struct sym_cipher_ecb_state_st **state
 586      = (struct sym_cipher_ecb_state_st **)&op->lsc_data;
 587    const LSplugin_decryptor_desc_t *desc = op->lsc_dispatch_data;
 588  
 589    return setup_sym_ecb_data(state, desc->lsp_priv_desc, -1);
 590  }
 591  static LE_STATUS clean_sym_ecb_decryptor_data(LSC_decryptor_t *op)
 592  {
 593    struct sym_cipher_ecb_state_st **state
 594      = (struct sym_cipher_ecb_state_st **)&op->lsc_data;
 595  
 596    return clean_sym_ecb_data(state);
 597  }
 598  
 599  static LE_STATUS get_sym_ecb_encryptor_unit_size(LSC_encryptor_t *enc,
 600                                                   size_t *size)
 601  {
 602    assert(enc != NULL && enc->lsc_dispatch_data != NULL);
 603    assert(size != NULL);
 604  
 605    const LSplugin_encryptor_desc_t *desc = enc->lsc_dispatch_data;
 606    const struct ltc_cipher_descriptor *ltc_desc = desc->lsp_priv_desc;
 607    assert(ltc_desc != NULL);
 608    *size = (size_t)ltc_desc->block_length;
 609    return LE_STS_SUCCESS;
 610  }
 611  
 612  static LE_STATUS get_sym_ecb_decryptor_unit_size(LSC_decryptor_t *dec,
 613                                                   size_t *size)
 614  {
 615    assert(dec != NULL && dec->lsc_dispatch_data != NULL);
 616    assert(size != NULL);
 617  
 618    const LSplugin_decryptor_desc_t *desc = dec->lsc_dispatch_data;
 619    const struct ltc_cipher_descriptor *ltc_desc = desc->lsp_priv_desc;
 620    assert(ltc_desc != NULL);
 621    *size = (size_t)ltc_desc->block_length;
 622    return LE_STS_SUCCESS;
 623  }
 624  
 625  /*********************************************************************
 626   *
 627   *  CBC specific structure and functions
 628   *
 629   *****/
 630  
 631  /* CBC context structure */
 632  struct sym_cipher_cbc_state_st {
 633    struct sym_cipher_data_st base;
 634    symmetric_CBC libtomcrypt_data;
 635  };
 636  
 637  static int ltc_cbc_init(void *state)
 638  {
 639    struct sym_cipher_cbc_state_st *data = state;
 640    struct ltc_symkey_st *k = data->base.key->lsc_data;
 641    size_t blocksize = data->base.cipher->block_length;
 642    unsigned char default_iv[blocksize];
 643    unsigned char *iv = data->base.iv;
 644    if (iv == NULL) {
 645      memset(default_iv, 0, blocksize);
 646      iv = default_iv;
 647    }
 648  
 649    int err = cbc_start(data->base.cipher_idx, iv,
 650                        k->key_bits, k->key_bits_len / 8,
 651                        data->base.num_rounds, &data->libtomcrypt_data);
 652  
 653    return err;
 654  }
 655  
 656  static int ltc_cbc_enc(const unsigned char *from, unsigned char *to,
 657                         unsigned long len, void *state)
 658  {
 659    struct sym_cipher_cbc_state_st *data = state;
 660  
 661    int err = cbc_encrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
 662  
 663    return err;
 664  }
 665  
 666  static int ltc_cbc_dec(const unsigned char *from, unsigned char *to,
 667                         unsigned long len, void *state)
 668  {
 669    struct sym_cipher_cbc_state_st *data = state;
 670  
 671    int err = cbc_decrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
 672  
 673    return err;
 674  }
 675  
 676  static int ltc_cbc_done(void *state)
 677  {
 678    struct sym_cipher_cbc_state_st *data = state;
 679  
 680    int err = cbc_done(&data->libtomcrypt_data);
 681  
 682    return err;
 683  }
 684  
 685  static LE_STATUS
 686  setup_sym_cbc_data(struct sym_cipher_cbc_state_st **state,
 687                     const struct ltc_cipher_descriptor *libtomcrypt_desc,
 688                     int encdec /* 1 = enc, -1 = dec */)
 689  {
 690    assert(state != NULL);
 691    assert(encdec == 1 || encdec == -1);
 692  
 693    if (*state == NULL) {
 694      *state = malloc(sizeof(**state));
 695      memset(*state, 0, sizeof(**state));
 696  
 697      LE_STATUS sts;
 698  
 699      if (!LE_status_is_OK(sts = setup_common_data(&(*state)->base,
 700                                                   libtomcrypt_desc)))
 701        return sts;
 702      if (!LE_status_is_OK(sts = setup_common_gettable_pad_param(&(*state)->base)))
 703        return sts;
 704      if (!LE_status_is_OK(sts = setup_common_settable_pad_param(&(*state)->base)))
 705        return sts;
 706      if (!LE_status_is_OK(sts = setup_common_gettable_iv_param(&(*state)->base)))
 707        return sts;
 708      if (!LE_status_is_OK(sts = setup_common_settable_iv_param(&(*state)->base)))
 709        return sts;
 710  
 711      (*state)->base.start = ltc_cbc_init;
 712      (*state)->base.perform = encdec > 0 ? ltc_cbc_enc : ltc_cbc_dec ;
 713      (*state)->base.stop = ltc_cbc_done;
 714      (*state)->base.state = *state;
 715    }
 716    if (*state == NULL)
 717      return LE_STS_FATAL_ERROR;
 718  
 719    assert((*state)->base.start == ltc_cbc_init);
 720    assert((*state)->base.perform == (encdec > 0 ? ltc_cbc_enc : ltc_cbc_dec));
 721    assert((*state)->base.stop = ltc_cbc_done);
 722  
 723    return LE_STS_SUCCESS;
 724  }
 725  
 726  static LE_STATUS clean_sym_cbc_data(struct sym_cipher_cbc_state_st **state)
 727  {
 728    assert(state != NULL);
 729  
 730    if (*state != NULL) {
 731      cleanup_common_data(&(*state)->base);
 732      (*state)->base.start = NULL;
 733      (*state)->base.perform = NULL;
 734      (*state)->base.stop = NULL;
 735      (*state)->base.state = NULL;
 736  
 737      free(*state);
 738      *state = NULL;
 739    }
 740  
 741    return LE_STS_SUCCESS;    /* Not yet implemented */
 742  }
 743  
 744  static LE_STATUS setup_sym_cbc_encryptor_data(LSC_encryptor_t *op)
 745  {
 746    struct sym_cipher_cbc_state_st **state
 747      = (struct sym_cipher_cbc_state_st **)&op->lsc_data;
 748    const LSplugin_encryptor_desc_t *desc = op->lsc_dispatch_data;
 749  
 750    return setup_sym_cbc_data(state, desc->lsp_priv_desc, 1);
 751  }
 752  static LE_STATUS clean_sym_cbc_encryptor_data(LSC_encryptor_t *op)
 753  {
 754    struct sym_cipher_cbc_state_st **state
 755      = (struct sym_cipher_cbc_state_st **)&op->lsc_data;
 756  
 757    return clean_sym_cbc_data(state);
 758  }
 759  
 760  static LE_STATUS setup_sym_cbc_decryptor_data(LSC_decryptor_t *op)
 761  {
 762    struct sym_cipher_cbc_state_st **state
 763      = (struct sym_cipher_cbc_state_st **)&op->lsc_data;
 764    const LSplugin_decryptor_desc_t *desc = op->lsc_dispatch_data;
 765  
 766    return setup_sym_cbc_data(state, desc->lsp_priv_desc, -1);
 767  }
 768  static LE_STATUS clean_sym_cbc_decryptor_data(LSC_decryptor_t *op)
 769  {
 770    struct sym_cipher_cbc_state_st **state
 771      = (struct sym_cipher_cbc_state_st **)&op->lsc_data;
 772  
 773    return clean_sym_cbc_data(state);
 774  }
 775  
 776  static LE_STATUS get_sym_cbc_encryptor_unit_size(LSC_encryptor_t *enc,
 777                                                   size_t *size)
 778  {
 779    assert(enc != NULL && enc->lsc_dispatch_data != NULL);
 780    assert(size != NULL);
 781  
 782    const LSplugin_encryptor_desc_t *desc = enc->lsc_dispatch_data;
 783    const struct ltc_cipher_descriptor *ltc_desc = desc->lsp_priv_desc;
 784    assert(ltc_desc != NULL);
 785    *size = (size_t)ltc_desc->block_length;
 786    return LE_STS_SUCCESS;
 787  }
 788  
 789  static LE_STATUS get_sym_cbc_decryptor_unit_size(LSC_decryptor_t *dec,
 790                                                   size_t *size)
 791  {
 792    assert(dec != NULL && dec->lsc_dispatch_data != NULL);
 793    assert(size != NULL);
 794  
 795    const LSplugin_decryptor_desc_t *desc = dec->lsc_dispatch_data;
 796    const struct ltc_cipher_descriptor *ltc_desc = desc->lsp_priv_desc;
 797    assert(ltc_desc != NULL);
 798    *size = (size_t)ltc_desc->block_length;
 799    return LE_STS_SUCCESS;
 800  }
 801  
 802  /*********************************************************************
 803   *
 804   *  CTR specific structure and functions
 805   *
 806   *****/
 807  
 808  /* CTR context structure */
 809  struct sym_cipher_ctr_state_st {
 810    struct sym_cipher_data_st base;
 811    symmetric_CTR libtomcrypt_data;
 812  };
 813  
 814  static int ltc_ctr_init(void *state)
 815  {
 816    struct sym_cipher_ctr_state_st *data = state;
 817    struct ltc_symkey_st *k = data->base.key->lsc_data;
 818    size_t blocksize = data->base.cipher->block_length;
 819    unsigned char default_iv[blocksize];
 820    unsigned char *iv = data->base.iv;
 821    if (iv == NULL) {
 822      memset(default_iv, 0, blocksize);
 823      iv = default_iv;
 824    }
 825  
 826    int err = ctr_start(data->base.cipher_idx, iv,
 827                        k->key_bits, k->key_bits_len / 8,
 828                        data->base.num_rounds, CTR_COUNTER_BIG_ENDIAN,
 829                        &data->libtomcrypt_data);
 830  
 831    return err;
 832  }
 833  
 834  static int ltc_ctr_enc(const unsigned char *from, unsigned char *to,
 835                         unsigned long len, void *state)
 836  {
 837    struct sym_cipher_ctr_state_st *data = state;
 838  
 839    int err = ctr_encrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
 840  
 841    return err;
 842  }
 843  
 844  static int ltc_ctr_dec(const unsigned char *from, unsigned char *to,
 845                         unsigned long len, void *state)
 846  {
 847    struct sym_cipher_ctr_state_st *data = state;
 848  
 849    int err = ctr_decrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
 850  
 851    return err;
 852  }
 853  
 854  static int ltc_ctr_done(void *state)
 855  {
 856    struct sym_cipher_ctr_state_st *data = state;
 857  
 858    int err = ctr_done(&data->libtomcrypt_data);
 859  
 860    return err;
 861  }
 862  
 863  static LE_STATUS
 864  setup_sym_ctr_data(struct sym_cipher_ctr_state_st **state,
 865                     const struct ltc_cipher_descriptor *libtomcrypt_desc,
 866                     int encdec /* 1 = enc, -1 = dec */)
 867  {
 868    assert(state != NULL);
 869    assert(encdec == 1 || encdec == -1);
 870  
 871    if (*state == NULL) {
 872      *state = malloc(sizeof(**state));
 873      memset(*state, 0, sizeof(**state));
 874  
 875      LE_STATUS sts;
 876  
 877      if (!LE_status_is_OK(sts = setup_common_data(&(*state)->base,
 878                                                   libtomcrypt_desc)))
 879        return sts;
 880      if (!LE_status_is_OK(sts = setup_common_gettable_iv_param(&(*state)->base)))
 881        return sts;
 882      if (!LE_status_is_OK(sts = setup_common_settable_iv_param(&(*state)->base)))
 883        return sts;
 884  
 885      (*state)->base.pad = 0;
 886      (*state)->base.mode_unit_size = 1;
 887      (*state)->base.start = ltc_ctr_init;
 888      (*state)->base.perform = encdec > 0 ? ltc_ctr_enc : ltc_ctr_dec ;
 889      (*state)->base.stop = ltc_ctr_done;
 890      (*state)->base.state = *state;
 891    }
 892    if (*state == NULL)
 893      return LE_STS_FATAL_ERROR;
 894  
 895    assert((*state)->base.start == ltc_ctr_init);
 896    assert((*state)->base.perform == (encdec > 0 ? ltc_ctr_enc : ltc_ctr_dec));
 897    assert((*state)->base.stop = ltc_ctr_done);
 898  
 899    return LE_STS_SUCCESS;
 900  }
 901  
 902  static LE_STATUS clean_sym_ctr_data(struct sym_cipher_ctr_state_st **state)
 903  {
 904    assert(state != NULL);
 905  
 906    if (*state != NULL) {
 907      cleanup_common_data(&(*state)->base);
 908      (*state)->base.start = NULL;
 909      (*state)->base.perform = NULL;
 910      (*state)->base.stop = NULL;
 911      (*state)->base.state = NULL;
 912  
 913      free(*state);
 914      *state = NULL;
 915    }
 916  
 917    return LE_STS_SUCCESS;    /* Not yet implemented */
 918  }
 919  
 920  static LE_STATUS setup_sym_ctr_encryptor_data(LSC_encryptor_t *op)
 921  {
 922    struct sym_cipher_ctr_state_st **state
 923      = (struct sym_cipher_ctr_state_st **)&op->lsc_data;
 924    const LSplugin_encryptor_desc_t *desc = op->lsc_dispatch_data;
 925  
 926    return setup_sym_ctr_data(state, desc->lsp_priv_desc, 1);
 927  }
 928  static LE_STATUS clean_sym_ctr_encryptor_data(LSC_encryptor_t *op)
 929  {
 930    struct sym_cipher_ctr_state_st **state
 931      = (struct sym_cipher_ctr_state_st **)&op->lsc_data;
 932  
 933    return clean_sym_ctr_data(state);
 934  }
 935  
 936  static LE_STATUS setup_sym_ctr_decryptor_data(LSC_decryptor_t *op)
 937  {
 938    struct sym_cipher_ctr_state_st **state
 939      = (struct sym_cipher_ctr_state_st **)&op->lsc_data;
 940    const LSplugin_decryptor_desc_t *desc = op->lsc_dispatch_data;
 941  
 942    return setup_sym_ctr_data(state, desc->lsp_priv_desc, -1);
 943  }
 944  static LE_STATUS clean_sym_ctr_decryptor_data(LSC_decryptor_t *op)
 945  {
 946    struct sym_cipher_ctr_state_st **state
 947      = (struct sym_cipher_ctr_state_st **)&op->lsc_data;
 948  
 949    return clean_sym_ctr_data(state);
 950  }
 951  
 952  static LE_STATUS get_sym_ctr_encryptor_unit_size(LSC_encryptor_t *enc,
 953                                                   size_t *size)
 954  {
 955    assert(enc != NULL);
 956    assert(size != NULL);
 957  
 958    *size = 1;
 959    return LE_STS_SUCCESS;
 960  }
 961  
 962  static LE_STATUS get_sym_ctr_decryptor_unit_size(LSC_decryptor_t *dec,
 963                                               size_t *size)
 964  {
 965    assert(dec != NULL);
 966    assert(size != NULL);
 967  
 968    *size = 1;
 969    return LE_STS_SUCCESS;
 970  }
 971  
 972  /*********************************************************************
 973   *
 974   *  CFB specific structure and functions
 975   *
 976   *****/
 977  
 978  /* CFB context structure */
 979  struct sym_cipher_cfb_state_st {
 980    struct sym_cipher_data_st base;
 981    symmetric_CFB libtomcrypt_data;
 982  };
 983  
 984  static int ltc_cfb_init(void *state)
 985  {
 986    struct sym_cipher_cfb_state_st *data = state;
 987    struct ltc_symkey_st *k = data->base.key->lsc_data;
 988    size_t blocksize = data->base.cipher->block_length;
 989    unsigned char default_iv[blocksize];
 990    unsigned char *iv = data->base.iv;
 991    if (iv == NULL) {
 992      memset(default_iv, 0, blocksize);
 993      iv = default_iv;
 994    }
 995  
 996    int err = cfb_start(data->base.cipher_idx, iv,
 997                        k->key_bits, k->key_bits_len / 8,
 998                        data->base.num_rounds, &data->libtomcrypt_data);
 999  
1000    return err;
1001  }
1002  
1003  static int ltc_cfb_enc(const unsigned char *from, unsigned char *to,
1004                         unsigned long len, void *state)
1005  {
1006    struct sym_cipher_cfb_state_st *data = state;
1007  
1008    int err = cfb_encrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
1009  
1010    return err;
1011  }
1012  
1013  static int ltc_cfb_dec(const unsigned char *from, unsigned char *to,
1014                         unsigned long len, void *state)
1015  {
1016    struct sym_cipher_cfb_state_st *data = state;
1017  
1018    int err = cfb_decrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
1019  
1020    return err;
1021  }
1022  
1023  static int ltc_cfb_done(void *state)
1024  {
1025    struct sym_cipher_cfb_state_st *data = state;
1026  
1027    int err = cfb_done(&data->libtomcrypt_data);
1028  
1029    return err;
1030  }
1031  
1032  static LE_STATUS
1033  setup_sym_cfb_data(struct sym_cipher_cfb_state_st **state,
1034                     const struct ltc_cipher_descriptor *libtomcrypt_desc,
1035                     int encdec /* 1 = enc, -1 = dec */)
1036  {
1037    assert(state != NULL);
1038    assert(encdec == 1 || encdec == -1);
1039  
1040    if (*state == NULL) {
1041      *state = malloc(sizeof(**state));
1042      memset(*state, 0, sizeof(**state));
1043  
1044      LE_STATUS sts;
1045  
1046      if (!LE_status_is_OK(sts = setup_common_data(&(*state)->base,
1047                                                   libtomcrypt_desc)))
1048        return sts;
1049      if (!LE_status_is_OK(sts = setup_common_gettable_iv_param(&(*state)->base)))
1050        return sts;
1051      if (!LE_status_is_OK(sts = setup_common_settable_iv_param(&(*state)->base)))
1052        return sts;
1053  
1054      (*state)->base.pad = 0;
1055      (*state)->base.mode_unit_size = 1;
1056      (*state)->base.start = ltc_cfb_init;
1057      (*state)->base.perform = encdec > 0 ? ltc_cfb_enc : ltc_cfb_dec ;
1058      (*state)->base.stop = ltc_cfb_done;
1059      (*state)->base.state = *state;
1060    }
1061    if (*state == NULL)
1062      return LE_STS_FATAL_ERROR;
1063  
1064    assert((*state)->base.start == ltc_cfb_init);
1065    assert((*state)->base.perform == (encdec > 0 ? ltc_cfb_enc : ltc_cfb_dec));
1066    assert((*state)->base.stop = ltc_cfb_done);
1067  
1068    return LE_STS_SUCCESS;
1069  }
1070  
1071  static LE_STATUS clean_sym_cfb_data(struct sym_cipher_cfb_state_st **state)
1072  {
1073    assert(state != NULL);
1074  
1075    if (*state != NULL) {
1076      cleanup_common_data(&(*state)->base);
1077      (*state)->base.start = NULL;
1078      (*state)->base.perform = NULL;
1079      (*state)->base.stop = NULL;
1080      (*state)->base.state = NULL;
1081  
1082      free(*state);
1083      *state = NULL;
1084    }
1085  
1086    return LE_STS_SUCCESS;    /* Not yet implemented */
1087  }
1088  
1089  static LE_STATUS setup_sym_cfb_encryptor_data(LSC_encryptor_t *op)
1090  {
1091    struct sym_cipher_cfb_state_st **state
1092      = (struct sym_cipher_cfb_state_st **)&op->lsc_data;
1093    const LSplugin_encryptor_desc_t *desc = op->lsc_dispatch_data;
1094  
1095    return setup_sym_cfb_data(state, desc->lsp_priv_desc, 1);
1096  }
1097  static LE_STATUS clean_sym_cfb_encryptor_data(LSC_encryptor_t *op)
1098  {
1099    struct sym_cipher_cfb_state_st **state
1100      = (struct sym_cipher_cfb_state_st **)&op->lsc_data;
1101  
1102    return clean_sym_cfb_data(state);
1103  }
1104  
1105  static LE_STATUS setup_sym_cfb_decryptor_data(LSC_decryptor_t *op)
1106  {
1107    struct sym_cipher_cfb_state_st **state
1108      = (struct sym_cipher_cfb_state_st **)&op->lsc_data;
1109    const LSplugin_decryptor_desc_t *desc = op->lsc_dispatch_data;
1110  
1111    return setup_sym_cfb_data(state, desc->lsp_priv_desc, -1);
1112  }
1113  static LE_STATUS clean_sym_cfb_decryptor_data(LSC_decryptor_t *op)
1114  {
1115    struct sym_cipher_cfb_state_st **state
1116      = (struct sym_cipher_cfb_state_st **)&op->lsc_data;
1117  
1118    return clean_sym_cfb_data(state);
1119  }
1120  
1121  static LE_STATUS get_sym_cfb_encryptor_unit_size(LSC_encryptor_t *enc,
1122                                                   size_t *size)
1123  {
1124    assert(enc != NULL);
1125    assert(size != NULL);
1126  
1127    *size = 1;
1128    return LE_STS_SUCCESS;
1129  }
1130  
1131  static LE_STATUS get_sym_cfb_decryptor_unit_size(LSC_decryptor_t *dec,
1132                                               size_t *size)
1133  {
1134    assert(dec != NULL);
1135    assert(size != NULL);
1136  
1137    *size = 1;
1138    return LE_STS_SUCCESS;
1139  }
1140  
1141  /*********************************************************************
1142   *
1143   *  OFB specific structure and functions
1144   *
1145   *****/
1146  
1147  /* OFB context structure */
1148  struct sym_cipher_ofb_state_st {
1149    struct sym_cipher_data_st base;
1150    symmetric_OFB libtomcrypt_data;
1151  };
1152  
1153  static int ltc_ofb_init(void *state)
1154  {
1155    struct sym_cipher_ofb_state_st *data = state;
1156    struct ltc_symkey_st *k = data->base.key->lsc_data;
1157    size_t blocksize = data->base.cipher->block_length;
1158    unsigned char default_iv[blocksize];
1159    unsigned char *iv = data->base.iv;
1160    if (iv == NULL) {
1161      memset(default_iv, 0, blocksize);
1162      iv = default_iv;
1163    }
1164  
1165    int err = ofb_start(data->base.cipher_idx, iv,
1166                        k->key_bits, k->key_bits_len / 8,
1167                        data->base.num_rounds, &data->libtomcrypt_data);
1168  
1169    return err;
1170  }
1171  
1172  static int ltc_ofb_enc(const unsigned char *from, unsigned char *to,
1173                         unsigned long len, void *state)
1174  {
1175    struct sym_cipher_ofb_state_st *data = state;
1176  
1177    int err = ofb_encrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
1178  
1179    return err;
1180  }
1181  
1182  static int ltc_ofb_dec(const unsigned char *from, unsigned char *to,
1183                         unsigned long len, void *state)
1184  {
1185    struct sym_cipher_ofb_state_st *data = state;
1186  
1187    int err = ofb_decrypt((unsigned char *)from, to, len, &data->libtomcrypt_data);
1188  
1189    return err;
1190  }
1191  
1192  static int ltc_ofb_done(void *state)
1193  {
1194    struct sym_cipher_ofb_state_st *data = state;
1195  
1196    int err = ofb_done(&data->libtomcrypt_data);
1197  
1198    return err;
1199  }
1200  
1201  static LE_STATUS
1202  setup_sym_ofb_data(struct sym_cipher_ofb_state_st **state,
1203                     const struct ltc_cipher_descriptor *libtomcrypt_desc,
1204                     int encdec /* 1 = enc, -1 = dec */)
1205  {
1206    assert(state != NULL);
1207    assert(encdec == 1 || encdec == -1);
1208  
1209    if (*state == NULL) {
1210      *state = malloc(sizeof(**state));
1211      memset(*state, 0, sizeof(**state));
1212  
1213      LE_STATUS sts;
1214  
1215      if (!LE_status_is_OK(sts = setup_common_data(&(*state)->base,
1216                                                   libtomcrypt_desc)))
1217        return sts;
1218      if (!LE_status_is_OK(sts = setup_common_gettable_iv_param(&(*state)->base)))
1219        return sts;
1220      if (!LE_status_is_OK(sts = setup_common_settable_iv_param(&(*state)->base)))
1221        return sts;
1222  
1223      (*state)->base.pad = 0;
1224      (*state)->base.mode_unit_size = 1;
1225      (*state)->base.start = ltc_ofb_init;
1226      (*state)->base.perform = encdec > 0 ? ltc_ofb_enc : ltc_ofb_dec ;
1227      (*state)->base.stop = ltc_ofb_done;
1228      (*state)->base.state = *state;
1229    }
1230    if (*state == NULL)
1231      return LE_STS_FATAL_ERROR;
1232  
1233    assert((*state)->base.start == ltc_ofb_init);
1234    assert((*state)->base.perform == (encdec > 0 ? ltc_ofb_enc : ltc_ofb_dec));
1235    assert((*state)->base.stop = ltc_ofb_done);
1236  
1237    return LE_STS_SUCCESS;
1238  }
1239  
1240  static LE_STATUS clean_sym_ofb_data(struct sym_cipher_ofb_state_st **state)
1241  {
1242    assert(state != NULL);
1243  
1244    if (*state != NULL) {
1245      cleanup_common_data(&(*state)->base);
1246      (*state)->base.start = NULL;
1247      (*state)->base.perform = NULL;
1248      (*state)->base.stop = NULL;
1249      (*state)->base.state = NULL;
1250  
1251      free(*state);
1252      *state = NULL;
1253    }
1254  
1255    return LE_STS_SUCCESS;    /* Not yet implemented */
1256  }
1257  
1258  static LE_STATUS setup_sym_ofb_encryptor_data(LSC_encryptor_t *op)
1259  {
1260    struct sym_cipher_ofb_state_st **state
1261      = (struct sym_cipher_ofb_state_st **)&op->lsc_data;
1262    const LSplugin_encryptor_desc_t *desc = op->lsc_dispatch_data;
1263  
1264    return setup_sym_ofb_data(state, desc->lsp_priv_desc, 1);
1265  }
1266  static LE_STATUS clean_sym_ofb_encryptor_data(LSC_encryptor_t *op)
1267  {
1268    struct sym_cipher_ofb_state_st **state
1269      = (struct sym_cipher_ofb_state_st **)&op->lsc_data;
1270  
1271    return clean_sym_ofb_data(state);
1272  }
1273  
1274  static LE_STATUS setup_sym_ofb_decryptor_data(LSC_decryptor_t *op)
1275  {
1276    struct sym_cipher_ofb_state_st **state
1277      = (struct sym_cipher_ofb_state_st **)&op->lsc_data;
1278    const LSplugin_decryptor_desc_t *desc = op->lsc_dispatch_data;
1279  
1280    return setup_sym_ofb_data(state, desc->lsp_priv_desc, -1);
1281  }
1282  static LE_STATUS clean_sym_ofb_decryptor_data(LSC_decryptor_t *op)
1283  {
1284    struct sym_cipher_ofb_state_st **state
1285      = (struct sym_cipher_ofb_state_st **)&op->lsc_data;
1286  
1287    return clean_sym_ofb_data(state);
1288  }
1289  
1290  static LE_STATUS get_sym_ofb_encryptor_unit_size(LSC_encryptor_t *enc,
1291                                                   size_t *size)
1292  {
1293    assert(enc != NULL);
1294    assert(size != NULL);
1295  
1296    *size = 1;
1297    return LE_STS_SUCCESS;
1298  }
1299  
1300  static LE_STATUS get_sym_ofb_decryptor_unit_size(LSC_decryptor_t *dec,
1301                                               size_t *size)
1302  {
1303    assert(dec != NULL);
1304    assert(size != NULL);
1305  
1306    *size = 1;
1307    return LE_STS_SUCCESS;
1308  }
1309  
1310  /*********************************************************************
1311   *
1312   *  Per operation functions
1313   *
1314   *****/
1315  
1316  static LE_STATUS set_sym_encryptor_key(LSC_encryptor_t *enc, LSC_key_t *key)
1317  {
1318    return setup_common_data_key(enc->lsc_data, key);
1319  }
1320  
1321  static LE_STATUS get_sym_encryptor_key(LSC_encryptor_t *enc, LSC_key_t **key)
1322  {
1323    assert(key != NULL && enc != NULL && enc->lsc_data != NULL);
1324    struct sym_cipher_data_st *state = enc->lsc_data;
1325    *key = state->key;
1326    return *key ? LE_STS_SUCCESS : LE_STS_FATAL_ERROR;
1327  }
1328  
1329  static LE_STATUS get_sym_encryptor_param_data(LSC_encryptor_t *enc, void **data)
1330  {
1331    *data = enc->lsc_data;
1332    return LE_STS_SUCCESS;
1333  }
1334  
1335  static LE_STATUS get_sym_encryptor_gettable_param_desc
1336    (LSC_encryptor_t *enc, const LSC_param_desc_t **param_desc)
1337  {
1338    assert(enc != NULL && enc->lsc_data != NULL);
1339    assert(param_desc != NULL);
1340  
1341    struct sym_cipher_data_st *state = enc->lsc_data;
1342    *param_desc = state->gettable_params;
1343  
1344    if (*param_desc == NULL)
1345      return LE_STS_ERROR;
1346    return LE_STS_SUCCESS;
1347  };
1348  LE_STATUS get_sym_encryptor_settable_param_desc
1349    (LSC_encryptor_t *enc, const LSC_param_desc_t **param_desc)
1350  {
1351    assert(enc != NULL && enc->lsc_data != NULL);
1352    assert(param_desc != NULL);
1353  
1354    struct sym_cipher_data_st *state = enc->lsc_data;
1355    *param_desc = state->settable_params;
1356  
1357    if (*param_desc == NULL)
1358      return LE_STS_ERROR;
1359    return LE_STS_SUCCESS;
1360  };
1361  
1362  static LE_STATUS set_sym_decryptor_key(LSC_decryptor_t *dec, LSC_key_t *key)
1363  {
1364    return setup_common_data_key(dec->lsc_data, key);
1365  }
1366  
1367  static LE_STATUS get_sym_decryptor_key(LSC_decryptor_t *dec, LSC_key_t **key)
1368  {
1369    assert(key != NULL && dec != NULL && dec->lsc_data != NULL);
1370    struct sym_cipher_data_st *state = dec->lsc_data;
1371    *key = state->key;
1372    return *key ? LE_STS_SUCCESS : LE_STS_FATAL_ERROR;
1373  }
1374  
1375  static LE_STATUS get_sym_decryptor_param_data(LSC_decryptor_t *dec, void **data)
1376  {
1377    *data = dec->lsc_data;
1378    return LE_STS_SUCCESS;
1379  }
1380  
1381  LE_STATUS get_sym_decryptor_gettable_param_desc
1382    (LSC_decryptor_t *dec, const LSC_param_desc_t **param_desc)
1383  {
1384    assert(dec != NULL && dec->lsc_data != NULL);
1385    assert(param_desc != NULL);
1386  
1387    struct sym_cipher_data_st *state = dec->lsc_data;
1388    *param_desc = state->gettable_params;
1389  
1390    if (*param_desc == NULL)
1391      return LE_STS_ERROR;
1392    return LE_STS_SUCCESS;
1393  };
1394  LE_STATUS get_sym_decryptor_settable_param_desc
1395    (LSC_decryptor_t *dec, const LSC_param_desc_t **param_desc)
1396  {
1397    assert(dec != NULL && dec->lsc_data != NULL);
1398    assert(param_desc != NULL);
1399  
1400    struct sym_cipher_data_st *state = dec->lsc_data;
1401    *param_desc = state->settable_params;
1402  
1403    if (*param_desc == NULL)
1404      return LE_STS_ERROR;
1405    return LE_STS_SUCCESS;
1406  };
1407  
1408  static LE_STATUS get_sym_encryptor_input_size(LSC_encryptor_t *enc, size_t *size)
1409  {
1410    if (size == NULL)
1411      return LE_STS_ERROR;
1412    *size = 0;
1413    return LE_STS_SUCCESS;
1414  }
1415  static LE_STATUS get_sym_decryptor_input_size(LSC_decryptor_t *enc, size_t *size)
1416  {
1417    if (size == NULL)
1418      return LE_STS_ERROR;
1419    *size = 0;
1420    return LE_STS_SUCCESS;
1421  }
1422  
1423  static LE_STATUS get_sym_encryptor_output_size(LSC_encryptor_t *enc, size_t *size)
1424  {
1425    if (size == NULL)
1426      return LE_STS_ERROR;
1427    *size = 0;
1428    return LE_STS_SUCCESS;
1429  }
1430  static LE_STATUS get_sym_decryptor_output_size(LSC_decryptor_t *enc, size_t *size)
1431  {
1432    if (size == NULL)
1433      return LE_STS_ERROR;
1434    *size = 0;
1435    return LE_STS_SUCCESS;
1436  }
1437  
1438  static LE_STATUS start_sym_encryptor(LSC_encryptor_t *enc)
1439  {
1440    assert(enc != NULL && enc->lsc_data != NULL);
1441    return common_start(enc->lsc_data);
1442  }
1443  
1444  static LE_STATUS perform_sym_encryptor(LSC_encryptor_t *enc,
1445                                         const unsigned char *in,
1446                                         size_t inlen,
1447                                         unsigned char *out,
1448                                         size_t outsize,
1449                                         size_t *outlen)
1450  {
1451    assert(enc != NULL && enc->lsc_data != NULL);
1452    return common_perform_encryption(enc->lsc_data, in, inlen,
1453                                     out, outsize, outlen);
1454  }
1455  
1456  static LE_STATUS finalize_sym_encryptor(LSC_encryptor_t *enc,
1457                                          unsigned char *out,
1458                                          size_t outsize,
1459                                          size_t *outlen)
1460  {
1461    assert(enc != NULL && enc->lsc_data != NULL);
1462    return common_finalize_encryption(enc->lsc_data, out, outsize, outlen);
1463  }
1464  
1465  static LE_STATUS stop_sym_encryptor(LSC_encryptor_t *enc)
1466  {
1467    assert(enc != NULL && enc->lsc_data != NULL);
1468    return common_stop(enc->lsc_data);
1469  }
1470  
1471  static LE_STATUS start_sym_decryptor(LSC_decryptor_t *dec)
1472  {
1473    assert(dec != NULL && dec->lsc_data != NULL);
1474    return common_start(dec->lsc_data);
1475  }
1476  
1477  static LE_STATUS perform_sym_decryptor(LSC_decryptor_t *dec,
1478                                         const unsigned char *in,
1479                                         size_t inlen,
1480                                         unsigned char *out,
1481                                         size_t outsize,
1482                                         size_t *outlen)
1483  {
1484    assert(dec != NULL && dec->lsc_data != NULL);
1485    return common_perform_decryption(dec->lsc_data, in, inlen,
1486                                     out, outsize, outlen);
1487  }
1488  
1489  static LE_STATUS finalize_sym_decryptor(LSC_decryptor_t *dec,
1490                                          unsigned char *out,
1491                                          size_t outsize,
1492                                          size_t *outlen)
1493  {
1494    assert(dec != NULL && dec->lsc_data != NULL);
1495    return common_finalize_decryption(dec->lsc_data, out, outsize, outlen);
1496  }
1497  
1498  static LE_STATUS stop_sym_decryptor(LSC_decryptor_t *dec)
1499  {
1500    assert(dec != NULL && dec->lsc_data != NULL);
1501    return common_stop(dec->lsc_data);
1502  }
1503  
1504  #define IMPL_aes_NAME()         "aes"
1505  #define IMPL_des3_NAME()        "3des"
1506  #define IMPL_blowfish_NAME()    "blowfish"
1507  #define IMPL_twofish_NAME()     "twofish"
1508  #define IMPL_cast5_NAME()       "cast5"
1509  #define IMPL_kseed_NAME()       "seed"
1510  #define IMPL_camellia_NAME()    "camellia"
1511  #define IMPL_encryptor_COMMANDS()                                       \
1512    LSC_ENCRYPTOR_TYPE_BASE_COMMANDS(), LSC_ENCRYPTOR_SIZE_COMMANDS(),    \
1513      LSC_NR_start_encryption, LSC_NR_perform_encryption,                 \
1514      LSC_NR_stop_encryption
1515  #define IMPL_decryptor_COMMANDS()                                       \
1516    LSC_DECRYPTOR_TYPE_BASE_COMMANDS(), LSC_DECRYPTOR_SIZE_COMMANDS(),    \
1517      LSC_NR_start_decryption, LSC_NR_perform_decryption,                 \
1518      LSC_NR_stop_decryption
1519  #define IMPL_CIPHER_OP(T,N,M)                                           \
1520    const LSplugin_##T##_desc_t ltc_##N##_##M##_##T##_desc = {            \
1521      NULL, IMPL_##N##_NAME() "-" #M, &N##_desc, IMPL_##N##_NAME(),       \
1522      setup_sym_##M##_##T##_data, clean_sym_##M##_##T##_data,             \
1523      NULL, set_sym_##T##_key, get_sym_##T##_key,                         \
1524      (int[]){ IMPL_##T##_COMMANDS(), 0 },                                \
1525      get_sym_##T##_param_data,                                           \
1526      get_sym_##T##_gettable_param_desc,                                  \
1527      get_sym_##T##_settable_param_desc,                                  \
1528      get_sym_##M##_##T##_unit_size,                                      \
1529      get_sym_##T##_input_size,                                           \
1530      get_sym_##T##_output_size,                                          \
1531      NULL,                /* No perform once */                          \
1532      start_sym_##T, perform_sym_##T, finalize_sym_##T, stop_sym_##T,     \
1533    };
1534  #define IMPL_CIPHER_MODE(N,M)                   \
1535    IMPL_CIPHER_OP(encryptor,N,M);                \
1536    IMPL_CIPHER_OP(decryptor,N,M)
1537  #define IMPL_CIPHER(N)                          \
1538    IMPL_CIPHER_MODE(N,ecb);                      \
1539    IMPL_CIPHER_MODE(N,cbc);                      \
1540    IMPL_CIPHER_MODE(N,ctr);                      \
1541    IMPL_CIPHER_MODE(N,cfb);                      \
1542    IMPL_CIPHER_MODE(N,ofb)
1543  
1544  IMPL_CIPHER(aes);
1545  IMPL_CIPHER(des3);
1546  IMPL_CIPHER(blowfish);
1547  IMPL_CIPHER(twofish);
1548  IMPL_CIPHER(cast5);
1549  IMPL_CIPHER(kseed);
1550  IMPL_CIPHER(camellia);