5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #ifndef _KERNEL
27 #include <strings.h>
28 #include <limits.h>
29 #include <assert.h>
30 #include <security/cryptoki.h>
31 #endif
32
33 #include <sys/types.h>
34 #include <modes/modes.h>
35 #include <sys/crypto/common.h>
36 #include <sys/crypto/impl.h>
37
38 /*
39 * Algorithm independent ECB functions.
40 */
41 int
42 ecb_cipher_contiguous_blocks(ecb_ctx_t *ctx, char *data, size_t length,
43 crypto_data_t *out, size_t block_size,
44 int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct))
45 {
46 size_t remainder = length;
47 size_t need;
48 uint8_t *datap = (uint8_t *)data;
49 uint8_t *blockp;
50 uint8_t *lastp;
51 void *iov_or_mp;
52 offset_t offset;
53 uint8_t *out_data_1;
54 uint8_t *out_data_2;
55 size_t out_data_1_len;
56
57 if (length + ctx->ecb_remainder_len < block_size) {
58 /* accumulate bytes here and return */
59 bcopy(datap,
60 (uint8_t *)ctx->ecb_remainder + ctx->ecb_remainder_len,
61 length);
62 ctx->ecb_remainder_len += length;
63 ctx->ecb_copy_to = datap;
64 return (CRYPTO_SUCCESS);
65 }
66
67 lastp = (uint8_t *)ctx->ecb_iv;
68 if (out != NULL)
69 crypto_init_ptrs(out, &iov_or_mp, &offset);
70
71 do {
72 /* Unprocessed data from last call. */
73 if (ctx->ecb_remainder_len > 0) {
74 need = block_size - ctx->ecb_remainder_len;
75
76 if (need > remainder)
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Copyright 2015 by Saso Kiselkov. All rights reserved.
27 */
28
29 #ifndef _KERNEL
30 #include <strings.h>
31 #include <limits.h>
32 #include <assert.h>
33 #include <security/cryptoki.h>
34 #endif
35
36 #include <sys/types.h>
37 #define INLINE_CRYPTO_GET_PTRS
38 #include <modes/modes.h>
39 #include <sys/crypto/common.h>
40 #include <sys/crypto/impl.h>
41
42 boolean_t ecb_fastpath_enabled = B_TRUE;
43
44 /*
45 * Algorithm independent ECB functions.
46 * `cipher' is a single-block version of the cipher function to be performed
47 * on each input block. `cipher_ecb' is an optional parameter, which if
48 * passed and the input/output conditions allow it, will be invoked for the
49 * entire input buffer once to accelerate the operation.
50 */
51 int
52 ecb_cipher_contiguous_blocks(ecb_ctx_t *ctx, char *data, size_t length,
53 crypto_data_t *out, size_t block_size,
54 int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct),
55 int (*cipher_ecb)(const void *ks, const uint8_t *pt, uint8_t *ct,
56 uint64_t len))
57 {
58 size_t remainder = length;
59 size_t need;
60 uint8_t *datap = (uint8_t *)data;
61 uint8_t *blockp;
62 uint8_t *lastp;
63 void *iov_or_mp;
64 offset_t offset;
65 uint8_t *out_data_1;
66 uint8_t *out_data_2;
67 size_t out_data_1_len;
68
69 /*
70 * ECB encryption/decryption fastpath requirements:
71 * - fastpath is enabled
72 * - caller passed an accelerated ECB version of the cipher function
73 * - input is block-aligned
74 * - output is a single contiguous region or the user requested that
75 * we overwrite their input buffer (input/output aliasing allowed)
76 */
77 if (ecb_fastpath_enabled && cipher_ecb != NULL &&
78 ctx->ecb_remainder_len == 0 && length % block_size == 0 &&
79 (out == NULL || CRYPTO_DATA_IS_SINGLE_BLOCK(out))) {
80 if (out == NULL) {
81 cipher_ecb(ctx->ecb_keysched, (uint8_t *)data,
82 (uint8_t *)data, length);
83 } else {
84 cipher_ecb(ctx->ecb_keysched, (uint8_t *)data,
85 CRYPTO_DATA_FIRST_BLOCK(out), length);
86 out->cd_offset += length;
87 }
88 return (CRYPTO_SUCCESS);
89 }
90
91 if (length + ctx->ecb_remainder_len < block_size) {
92 /* accumulate bytes here and return */
93 bcopy(datap,
94 (uint8_t *)ctx->ecb_remainder + ctx->ecb_remainder_len,
95 length);
96 ctx->ecb_remainder_len += length;
97 ctx->ecb_copy_to = datap;
98 return (CRYPTO_SUCCESS);
99 }
100
101 lastp = (uint8_t *)ctx->ecb_iv;
102 if (out != NULL)
103 crypto_init_ptrs(out, &iov_or_mp, &offset);
104
105 do {
106 /* Unprocessed data from last call. */
107 if (ctx->ecb_remainder_len > 0) {
108 need = block_size - ctx->ecb_remainder_len;
109
110 if (need > remainder)
|