4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
30 #include <security/cryptoki.h>
33 #include <sys/types.h>
34 #include <modes/modes.h>
35 #include <sys/crypto/common.h>
36 #include <sys/crypto/impl.h>
39 * Algorithm independent ECB functions.
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
))
46 size_t remainder
= length
;
48 uint8_t *datap
= (uint8_t *)data
;
55 size_t out_data_1_len
;
57 if (length
+ ctx
->ecb_remainder_len
< block_size
) {
58 /* accumulate bytes here and return */
60 (uint8_t *)ctx
->ecb_remainder
+ ctx
->ecb_remainder_len
,
62 ctx
->ecb_remainder_len
+= length
;
63 ctx
->ecb_copy_to
= datap
;
64 return (CRYPTO_SUCCESS
);
67 lastp
= (uint8_t *)ctx
->ecb_iv
;
69 crypto_init_ptrs(out
, &iov_or_mp
, &offset
);
72 /* Unprocessed data from last call. */
73 if (ctx
->ecb_remainder_len
> 0) {
74 need
= block_size
- ctx
->ecb_remainder_len
;
77 return (CRYPTO_DATA_LEN_RANGE
);
79 bcopy(datap
, &((uint8_t *)ctx
->ecb_remainder
)
80 [ctx
->ecb_remainder_len
], need
);
82 blockp
= (uint8_t *)ctx
->ecb_remainder
;
88 cipher(ctx
->ecb_keysched
, blockp
, blockp
);
90 ctx
->ecb_lastp
= blockp
;
93 if (ctx
->ecb_remainder_len
> 0) {
94 bcopy(blockp
, ctx
->ecb_copy_to
,
95 ctx
->ecb_remainder_len
);
96 bcopy(blockp
+ ctx
->ecb_remainder_len
, datap
,
100 cipher(ctx
->ecb_keysched
, blockp
, lastp
);
101 crypto_get_ptrs(out
, &iov_or_mp
, &offset
, &out_data_1
,
102 &out_data_1_len
, &out_data_2
, block_size
);
104 /* copy block to where it belongs */
105 bcopy(lastp
, out_data_1
, out_data_1_len
);
106 if (out_data_2
!= NULL
) {
107 bcopy(lastp
+ out_data_1_len
, out_data_2
,
108 block_size
- out_data_1_len
);
111 out
->cd_offset
+= block_size
;
114 /* Update pointer to next block of data to be processed. */
115 if (ctx
->ecb_remainder_len
!= 0) {
117 ctx
->ecb_remainder_len
= 0;
122 remainder
= (size_t)&data
[length
] - (size_t)datap
;
124 /* Incomplete last block. */
125 if (remainder
> 0 && remainder
< block_size
) {
126 bcopy(datap
, ctx
->ecb_remainder
, remainder
);
127 ctx
->ecb_remainder_len
= remainder
;
128 ctx
->ecb_copy_to
= datap
;
131 ctx
->ecb_copy_to
= NULL
;
133 } while (remainder
> 0);
136 return (CRYPTO_SUCCESS
);
141 ecb_alloc_ctx(int kmflag
)
146 if ((ecb_ctx
= kmem_zalloc(sizeof (ecb_ctx_t
), kmflag
)) == NULL
)
148 if ((ecb_ctx
= calloc(1, sizeof (ecb_ctx_t
))) == NULL
)
152 ecb_ctx
->ecb_flags
= ECB_MODE
;