Print this page
6717509 Need to use bswap/bswapq for byte swap of 64-bit integer on x32/x64 (fix lint)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/common/crypto/modes/ctr.c
+++ new/usr/src/common/crypto/modes/ctr.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 25
26 26 #ifndef _KERNEL
27 27 #include <strings.h>
28 28 #include <limits.h>
29 29 #include <assert.h>
30 30 #include <security/cryptoki.h>
31 31 #endif
32 32
33 33 #include <sys/types.h>
34 34 #include <modes/modes.h>
35 35 #include <sys/crypto/common.h>
36 36 #include <sys/crypto/impl.h>
37 37
38 38 #ifdef _LITTLE_ENDIAN
39 39 #include <sys/byteorder.h>
40 40 #endif
41 41
42 42 /*
43 43 * Encrypt and decrypt multiple blocks of data in counter mode.
44 44 */
45 45 int
46 46 ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length,
47 47 crypto_data_t *out, size_t block_size,
48 48 int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct),
49 49 void (*xor_block)(uint8_t *, uint8_t *))
50 50 {
51 51 size_t remainder = length;
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
52 52 size_t need;
53 53 uint8_t *datap = (uint8_t *)data;
54 54 uint8_t *blockp;
55 55 uint8_t *lastp;
56 56 void *iov_or_mp;
57 57 offset_t offset;
58 58 uint8_t *out_data_1;
59 59 uint8_t *out_data_2;
60 60 size_t out_data_1_len;
61 61 uint64_t counter;
62 -#ifdef _LITTLE_ENDIAN
63 - uint8_t *p;
64 -#endif
65 62
66 63 if (length + ctx->ctr_remainder_len < block_size) {
67 64 /* accumulate bytes here and return */
68 65 bcopy(datap,
69 66 (uint8_t *)ctx->ctr_remainder + ctx->ctr_remainder_len,
70 67 length);
71 68 ctx->ctr_remainder_len += length;
72 69 ctx->ctr_copy_to = datap;
73 70 return (CRYPTO_SUCCESS);
74 71 }
75 72
76 73 lastp = (uint8_t *)ctx->ctr_cb;
77 74 if (out != NULL)
78 75 crypto_init_ptrs(out, &iov_or_mp, &offset);
79 76
80 77 do {
81 78 /* Unprocessed data from last call. */
82 79 if (ctx->ctr_remainder_len > 0) {
83 80 need = block_size - ctx->ctr_remainder_len;
84 81
85 82 if (need > remainder)
86 83 return (CRYPTO_DATA_LEN_RANGE);
87 84
88 85 bcopy(datap, &((uint8_t *)ctx->ctr_remainder)
89 86 [ctx->ctr_remainder_len], need);
90 87
91 88 blockp = (uint8_t *)ctx->ctr_remainder;
92 89 } else {
93 90 blockp = datap;
94 91 }
95 92
96 93 /* ctr_cb is the counter block */
97 94 cipher(ctx->ctr_keysched, (uint8_t *)ctx->ctr_cb,
98 95 (uint8_t *)ctx->ctr_tmp);
99 96
100 97 lastp = (uint8_t *)ctx->ctr_tmp;
101 98
102 99 /*
103 100 * Increment counter. Counter bits are confined
104 101 * to the bottom 64 bits of the counter block.
105 102 */
106 103 #ifdef _LITTLE_ENDIAN
107 104 counter = ntohll(ctx->ctr_cb[1] & ctx->ctr_counter_mask);
108 105 counter = htonll(counter + 1);
109 106 #else
110 107 counter = ctx->ctr_cb[1] & ctx->ctr_counter_mask;
111 108 counter++;
112 109 #endif /* _LITTLE_ENDIAN */
113 110 counter &= ctx->ctr_counter_mask;
114 111 ctx->ctr_cb[1] =
115 112 (ctx->ctr_cb[1] & ~(ctx->ctr_counter_mask)) | counter;
116 113
117 114 /*
118 115 * XOR the previous cipher block or IV with the
119 116 * current clear block.
120 117 */
121 118 xor_block(blockp, lastp);
122 119
123 120 if (out == NULL) {
124 121 if (ctx->ctr_remainder_len > 0) {
125 122 bcopy(lastp, ctx->ctr_copy_to,
126 123 ctx->ctr_remainder_len);
127 124 bcopy(lastp + ctx->ctr_remainder_len, datap,
128 125 need);
129 126 }
130 127 } else {
131 128 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
132 129 &out_data_1_len, &out_data_2, block_size);
133 130
134 131 /* copy block to where it belongs */
135 132 bcopy(lastp, out_data_1, out_data_1_len);
136 133 if (out_data_2 != NULL) {
137 134 bcopy(lastp + out_data_1_len, out_data_2,
138 135 block_size - out_data_1_len);
139 136 }
140 137 /* update offset */
141 138 out->cd_offset += block_size;
142 139 }
143 140
144 141 /* Update pointer to next block of data to be processed. */
145 142 if (ctx->ctr_remainder_len != 0) {
146 143 datap += need;
147 144 ctx->ctr_remainder_len = 0;
148 145 } else {
149 146 datap += block_size;
150 147 }
151 148
152 149 remainder = (size_t)&data[length] - (size_t)datap;
153 150
154 151 /* Incomplete last block. */
155 152 if (remainder > 0 && remainder < block_size) {
156 153 bcopy(datap, ctx->ctr_remainder, remainder);
157 154 ctx->ctr_remainder_len = remainder;
158 155 ctx->ctr_copy_to = datap;
159 156 goto out;
160 157 }
161 158 ctx->ctr_copy_to = NULL;
162 159
163 160 } while (remainder > 0);
164 161
165 162 out:
166 163 return (CRYPTO_SUCCESS);
167 164 }
168 165
169 166 int
170 167 ctr_mode_final(ctr_ctx_t *ctx, crypto_data_t *out,
171 168 int (*encrypt_block)(const void *, const uint8_t *, uint8_t *))
172 169 {
173 170 uint8_t *lastp;
174 171 void *iov_or_mp;
175 172 offset_t offset;
176 173 uint8_t *out_data_1;
177 174 uint8_t *out_data_2;
178 175 size_t out_data_1_len;
179 176 uint8_t *p;
180 177 int i;
181 178
182 179 if (out->cd_length < ctx->ctr_remainder_len)
183 180 return (CRYPTO_DATA_LEN_RANGE);
184 181
185 182 encrypt_block(ctx->ctr_keysched, (uint8_t *)ctx->ctr_cb,
186 183 (uint8_t *)ctx->ctr_tmp);
187 184
188 185 lastp = (uint8_t *)ctx->ctr_tmp;
189 186 p = (uint8_t *)ctx->ctr_remainder;
190 187 for (i = 0; i < ctx->ctr_remainder_len; i++) {
191 188 p[i] ^= lastp[i];
192 189 }
193 190
194 191 crypto_init_ptrs(out, &iov_or_mp, &offset);
195 192 crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
196 193 &out_data_1_len, &out_data_2, ctx->ctr_remainder_len);
197 194
198 195 bcopy(p, out_data_1, out_data_1_len);
199 196 if (out_data_2 != NULL) {
200 197 bcopy((uint8_t *)p + out_data_1_len,
201 198 out_data_2, ctx->ctr_remainder_len - out_data_1_len);
202 199 }
203 200 out->cd_offset += ctx->ctr_remainder_len;
204 201 ctx->ctr_remainder_len = 0;
205 202 return (CRYPTO_SUCCESS);
206 203 }
207 204
208 205 int
209 206 ctr_init_ctx(ctr_ctx_t *ctr_ctx, ulong_t count, uint8_t *cb,
210 207 void (*copy_block)(uint8_t *, uint8_t *))
211 208 {
212 209 uint64_t mask = 0;
213 210
214 211 if (count == 0 || count > 64) {
215 212 return (CRYPTO_MECHANISM_PARAM_INVALID);
216 213 }
217 214 while (count-- > 0)
218 215 mask |= (1ULL << count);
219 216
220 217 #ifdef _LITTLE_ENDIAN
221 218 mask = htonll(mask);
222 219 #endif
223 220 ctr_ctx->ctr_counter_mask = mask;
224 221 copy_block(cb, (uchar_t *)ctr_ctx->ctr_cb);
225 222 ctr_ctx->ctr_lastp = (uint8_t *)&ctr_ctx->ctr_cb[0];
226 223 ctr_ctx->ctr_flags |= CTR_MODE;
227 224 return (CRYPTO_SUCCESS);
228 225 }
229 226
230 227 /* ARGSUSED */
231 228 void *
232 229 ctr_alloc_ctx(int kmflag)
233 230 {
234 231 ctr_ctx_t *ctr_ctx;
235 232
236 233 #ifdef _KERNEL
237 234 if ((ctr_ctx = kmem_zalloc(sizeof (ctr_ctx_t), kmflag)) == NULL)
238 235 #else
239 236 if ((ctr_ctx = calloc(1, sizeof (ctr_ctx_t))) == NULL)
240 237 #endif
241 238 return (NULL);
242 239
243 240 ctr_ctx->ctr_flags = CTR_MODE;
244 241 return (ctr_ctx);
245 242 }
↓ open down ↓ |
171 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX