Print this page
4896 Performance improvements for KCF AES modes
@@ -20,32 +20,41 @@
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright 2015 by Saso Kiselkov. All rights reserved.
+ */
#ifndef _KERNEL
#include <strings.h>
#include <limits.h>
#include <assert.h>
#include <security/cryptoki.h>
#endif
#include <sys/types.h>
+#define INLINE_CRYPTO_GET_PTRS
#include <modes/modes.h>
#include <sys/crypto/common.h>
#include <sys/crypto/impl.h>
#include <sys/byteorder.h>
+#include <sys/cmn_err.h>
+boolean_t ctr_fastpath_enabled = B_TRUE;
+
/*
* Encrypt and decrypt multiple blocks of data in counter mode.
*/
int
ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length,
crypto_data_t *out, size_t block_size,
int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct),
- void (*xor_block)(uint8_t *, uint8_t *))
+ void (*xor_block)(const uint8_t *, uint8_t *),
+ int (*cipher_ctr)(const void *ks, const uint8_t *pt, uint8_t *ct,
+ uint64_t len, uint64_t counter[2]))
{
size_t remainder = length;
size_t need;
uint8_t *datap = (uint8_t *)data;
uint8_t *blockp;
@@ -55,10 +64,28 @@
uint8_t *out_data_1;
uint8_t *out_data_2;
size_t out_data_1_len;
uint64_t lower_counter, upper_counter;
+ /*
+ * CTR encryption/decryption fastpath requirements:
+ * - fastpath is enabled
+ * - algorithm-specific acceleration function is available
+ * - input is block-aligned
+ * - the counter value won't overflow the lower counter mask
+ * - output is a single contiguous region and doesn't alias input
+ */
+ if (ctr_fastpath_enabled && cipher_ctr != NULL &&
+ ctx->ctr_remainder_len == 0 && (length & (block_size - 1)) == 0 &&
+ ntohll(ctx->ctr_cb[1]) <= ctx->ctr_lower_mask -
+ length / block_size && CRYPTO_DATA_IS_SINGLE_BLOCK(out)) {
+ cipher_ctr(ctx->ctr_keysched, (uint8_t *)data,
+ CRYPTO_DATA_FIRST_BLOCK(out), length, ctx->ctr_cb);
+ out->cd_offset += length;
+ return (CRYPTO_SUCCESS);
+ }
+
if (length + ctx->ctr_remainder_len < block_size) {
/* accumulate bytes here and return */
bcopy(datap,
(uint8_t *)ctx->ctr_remainder + ctx->ctr_remainder_len,
length);
@@ -203,11 +230,11 @@
return (CRYPTO_SUCCESS);
}
int
ctr_init_ctx(ctr_ctx_t *ctr_ctx, ulong_t count, uint8_t *cb,
-void (*copy_block)(uint8_t *, uint8_t *))
+ void (*copy_block)(const uint8_t *, uint8_t *))
{
uint64_t upper_mask = 0;
uint64_t lower_mask = 0;
if (count == 0 || count > 128) {