Print this page
4896 Performance improvements for KCF AES modes

Split Close
Expand all
Collapse all
          --- old/usr/src/common/crypto/modes/ctr.c
          +++ new/usr/src/common/crypto/modes/ctr.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
       25 +/*
       26 + * Copyright 2015 by Saso Kiselkov. All rights reserved.
       27 + */
  25   28  
  26   29  #ifndef _KERNEL
  27   30  #include <strings.h>
  28   31  #include <limits.h>
  29   32  #include <assert.h>
  30   33  #include <security/cryptoki.h>
  31   34  #endif
  32   35  
  33   36  #include <sys/types.h>
       37 +#define INLINE_CRYPTO_GET_PTRS
  34   38  #include <modes/modes.h>
  35   39  #include <sys/crypto/common.h>
  36   40  #include <sys/crypto/impl.h>
  37   41  #include <sys/byteorder.h>
       42 +#include <sys/cmn_err.h>
  38   43  
       44 +boolean_t ctr_fastpath_enabled = B_TRUE;
       45 +
  39   46  /*
  40   47   * Encrypt and decrypt multiple blocks of data in counter mode.
  41   48   */
  42   49  int
  43   50  ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length,
  44   51      crypto_data_t *out, size_t block_size,
  45   52      int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct),
  46      -    void (*xor_block)(uint8_t *, uint8_t *))
       53 +    void (*xor_block)(const uint8_t *, uint8_t *),
       54 +    int (*cipher_ctr)(const void *ks, const uint8_t *pt, uint8_t *ct,
       55 +    uint64_t len, uint64_t counter[2]))
  47   56  {
  48   57          size_t remainder = length;
  49   58          size_t need;
  50   59          uint8_t *datap = (uint8_t *)data;
  51   60          uint8_t *blockp;
  52   61          uint8_t *lastp;
  53   62          void *iov_or_mp;
  54   63          offset_t offset;
  55   64          uint8_t *out_data_1;
  56   65          uint8_t *out_data_2;
  57   66          size_t out_data_1_len;
  58   67          uint64_t lower_counter, upper_counter;
  59   68  
       69 +        /*
       70 +         * CTR encryption/decryption fastpath requirements:
       71 +         * - fastpath is enabled
       72 +         * - algorithm-specific acceleration function is available
       73 +         * - input is block-aligned
       74 +         * - the counter value won't overflow the lower counter mask
       75 +         * - output is a single contiguous region and doesn't alias input
       76 +         */
       77 +        if (ctr_fastpath_enabled && cipher_ctr != NULL &&
       78 +            ctx->ctr_remainder_len == 0 && (length & (block_size - 1)) == 0 &&
       79 +            ntohll(ctx->ctr_cb[1]) <= ctx->ctr_lower_mask -
       80 +            length / block_size && CRYPTO_DATA_IS_SINGLE_BLOCK(out)) {
       81 +                cipher_ctr(ctx->ctr_keysched, (uint8_t *)data,
       82 +                    CRYPTO_DATA_FIRST_BLOCK(out), length, ctx->ctr_cb);
       83 +                out->cd_offset += length;
       84 +                return (CRYPTO_SUCCESS);
       85 +        }
       86 +
  60   87          if (length + ctx->ctr_remainder_len < block_size) {
  61   88                  /* accumulate bytes here and return */
  62   89                  bcopy(datap,
  63   90                      (uint8_t *)ctx->ctr_remainder + ctx->ctr_remainder_len,
  64   91                      length);
  65   92                  ctx->ctr_remainder_len += length;
  66   93                  ctx->ctr_copy_to = datap;
  67   94                  return (CRYPTO_SUCCESS);
  68   95          }
  69   96  
↓ open down ↓ 128 lines elided ↑ open up ↑
 198  225                  bcopy((uint8_t *)p + out_data_1_len,
 199  226                      out_data_2, ctx->ctr_remainder_len - out_data_1_len);
 200  227          }
 201  228          out->cd_offset += ctx->ctr_remainder_len;
 202  229          ctx->ctr_remainder_len = 0;
 203  230          return (CRYPTO_SUCCESS);
 204  231  }
 205  232  
 206  233  int
 207  234  ctr_init_ctx(ctr_ctx_t *ctr_ctx, ulong_t count, uint8_t *cb,
 208      -void (*copy_block)(uint8_t *, uint8_t *))
      235 +    void (*copy_block)(const uint8_t *, uint8_t *))
 209  236  {
 210  237          uint64_t upper_mask = 0;
 211  238          uint64_t lower_mask = 0;
 212  239  
 213  240          if (count == 0 || count > 128) {
 214  241                  return (CRYPTO_MECHANISM_PARAM_INVALID);
 215  242          }
 216  243          /* upper 64 bits of the mask */
 217  244          if (count >= 64) {
 218  245                  count -= 64;
↓ open down ↓ 31 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX