Print this page
first pass
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/crypto/io/blowfish.c
+++ new/usr/src/uts/common/crypto/io/blowfish.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 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * Blowfish provider for the Kernel Cryptographic Framework (KCF)
28 28 */
29 29
30 30 #include <sys/types.h>
31 31 #include <sys/systm.h>
32 32 #include <sys/modctl.h>
33 33 #include <sys/cmn_err.h>
34 34 #include <sys/ddi.h>
35 35 #include <sys/crypto/common.h>
36 36 #include <sys/crypto/spi.h>
37 37 #include <sys/sysmacros.h>
38 38 #include <sys/strsun.h>
39 39 #include <sys/note.h>
40 40 #include <modes/modes.h>
41 41 #include <blowfish/blowfish_impl.h>
42 42
43 43 extern struct mod_ops mod_cryptoops;
44 44
45 45 /*
46 46 * Module linkage information for the kernel.
47 47 */
48 48 static struct modlcrypto modlcrypto = {
49 49 &mod_cryptoops,
50 50 "Blowfish Kernel SW Provider"
51 51 };
52 52
53 53 static struct modlinkage modlinkage = {
54 54 MODREV_1,
55 55 (void *)&modlcrypto,
56 56 NULL
57 57 };
58 58
59 59 /*
60 60 * CSPI information (entry points, provider info, etc.)
61 61 */
62 62 typedef enum blowfish_mech_type {
63 63 BLOWFISH_ECB_MECH_INFO_TYPE, /* SUN_CKM_BLOWFISH_ECB */
64 64 BLOWFISH_CBC_MECH_INFO_TYPE /* SUN_CKM_BLOWFISH_CBC */
65 65 } blowfish_mech_type_t;
66 66
67 67
68 68 #define BLOWFISH_COPY_BLOCK(src, dst) \
69 69 (dst)[0] = (src)[0]; \
70 70 (dst)[1] = (src)[1]; \
71 71 (dst)[2] = (src)[2]; \
72 72 (dst)[3] = (src)[3]; \
73 73 (dst)[4] = (src)[4]; \
74 74 (dst)[5] = (src)[5]; \
75 75 (dst)[6] = (src)[6]; \
76 76 (dst)[7] = (src)[7]
77 77
78 78 #define BLOWFISH_XOR_BLOCK(src, dst) \
79 79 (dst)[0] ^= (src)[0]; \
80 80 (dst)[1] ^= (src)[1]; \
81 81 (dst)[2] ^= (src)[2]; \
82 82 (dst)[3] ^= (src)[3]; \
83 83 (dst)[4] ^= (src)[4]; \
84 84 (dst)[5] ^= (src)[5]; \
85 85 (dst)[6] ^= (src)[6]; \
86 86 (dst)[7] ^= (src)[7]
87 87
88 88 /*
89 89 * Mechanism info structure passed to KCF during registration.
90 90 */
91 91
92 92 static crypto_mech_info_t blowfish_mech_info_tab[] = {
93 93 /* BLOWFISH_ECB */
94 94 {SUN_CKM_BLOWFISH_ECB, BLOWFISH_ECB_MECH_INFO_TYPE,
95 95 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
96 96 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
97 97 BLOWFISH_MINBITS, BLOWFISH_MAXBITS, CRYPTO_KEYSIZE_UNIT_IN_BITS},
98 98 /* BLOWFISH_CBC */
99 99 {SUN_CKM_BLOWFISH_CBC, BLOWFISH_CBC_MECH_INFO_TYPE,
100 100 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
101 101 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
102 102 BLOWFISH_MINBITS, BLOWFISH_MAXBITS, CRYPTO_KEYSIZE_UNIT_IN_BITS}
103 103 };
104 104
105 105 #define BLOWFISH_VALID_MECH(mech) \
106 106 (((mech)->cm_type == BLOWFISH_ECB_MECH_INFO_TYPE || \
107 107 (mech)->cm_type == BLOWFISH_CBC_MECH_INFO_TYPE) ? 1 : 0)
108 108
109 109 /* operations are in-place if the output buffer is NULL */
110 110 #define BLOWFISH_ARG_INPLACE(input, output) \
111 111 if ((output) == NULL) \
112 112 (output) = (input);
113 113
114 114 static void blowfish_provider_status(crypto_provider_handle_t, uint_t *);
115 115
116 116 static crypto_control_ops_t blowfish_control_ops = {
117 117 blowfish_provider_status
118 118 };
119 119
120 120 static int blowfish_common_init(crypto_ctx_t *, crypto_mechanism_t *,
121 121 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
122 122 static int blowfish_common_init_ctx(blowfish_ctx_t *,
123 123 crypto_spi_ctx_template_t *, crypto_mechanism_t *, crypto_key_t *, int);
124 124 static int blowfish_encrypt_final(crypto_ctx_t *, crypto_data_t *,
125 125 crypto_req_handle_t);
126 126 static int blowfish_decrypt_final(crypto_ctx_t *, crypto_data_t *,
127 127 crypto_req_handle_t);
128 128
129 129 static int blowfish_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
130 130 crypto_req_handle_t);
131 131 static int blowfish_encrypt_update(crypto_ctx_t *, crypto_data_t *,
132 132 crypto_data_t *, crypto_req_handle_t);
133 133 static int blowfish_encrypt_atomic(crypto_provider_handle_t,
134 134 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
135 135 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
136 136
137 137 static int blowfish_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
138 138 crypto_req_handle_t);
139 139 static int blowfish_decrypt_update(crypto_ctx_t *, crypto_data_t *,
140 140 crypto_data_t *, crypto_req_handle_t);
141 141 static int blowfish_decrypt_atomic(crypto_provider_handle_t,
142 142 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
143 143 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
144 144
145 145 static crypto_cipher_ops_t blowfish_cipher_ops = {
146 146 blowfish_common_init,
147 147 blowfish_encrypt,
148 148 blowfish_encrypt_update,
149 149 blowfish_encrypt_final,
150 150 blowfish_encrypt_atomic,
151 151 blowfish_common_init,
152 152 blowfish_decrypt,
153 153 blowfish_decrypt_update,
154 154 blowfish_decrypt_final,
155 155 blowfish_decrypt_atomic
156 156 };
157 157
158 158 static int blowfish_create_ctx_template(crypto_provider_handle_t,
159 159 crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
160 160 size_t *, crypto_req_handle_t);
161 161 static int blowfish_free_context(crypto_ctx_t *);
162 162
163 163 static crypto_ctx_ops_t blowfish_ctx_ops = {
164 164 blowfish_create_ctx_template,
165 165 blowfish_free_context
166 166 };
167 167
168 168 static crypto_ops_t blowfish_crypto_ops = {
169 169 &blowfish_control_ops,
170 170 NULL,
171 171 &blowfish_cipher_ops,
172 172 NULL,
173 173 NULL,
174 174 NULL,
175 175 NULL,
176 176 NULL,
177 177 NULL,
178 178 NULL,
179 179 NULL,
180 180 NULL,
181 181 NULL,
182 182 &blowfish_ctx_ops
183 183 };
184 184
185 185 static crypto_provider_info_t blowfish_prov_info = {
186 186 CRYPTO_SPI_VERSION_1,
187 187 "Blowfish Software Provider",
188 188 CRYPTO_SW_PROVIDER,
189 189 {&modlinkage},
190 190 NULL,
191 191 &blowfish_crypto_ops,
192 192 sizeof (blowfish_mech_info_tab)/sizeof (crypto_mech_info_t),
193 193 blowfish_mech_info_tab
194 194 };
195 195
196 196
197 197 static crypto_kcf_provider_handle_t blowfish_prov_handle = NULL;
198 198
199 199 int
200 200 _init(void)
201 201 {
202 202 int ret;
203 203
204 204 if ((ret = mod_install(&modlinkage)) != 0)
205 205 return (ret);
206 206
207 207 /* Register with KCF. If the registration fails, remove the module. */
208 208 if (crypto_register_provider(&blowfish_prov_info,
209 209 &blowfish_prov_handle)) {
210 210 (void) mod_remove(&modlinkage);
211 211 return (EACCES);
212 212 }
213 213
214 214 return (0);
215 215 }
216 216
217 217 int
218 218 _fini(void)
219 219 {
220 220 /* Unregister from KCF if module is registered */
221 221 if (blowfish_prov_handle != NULL) {
222 222 if (crypto_unregister_provider(blowfish_prov_handle))
223 223 return (EBUSY);
224 224
225 225 blowfish_prov_handle = NULL;
226 226 }
227 227
228 228 return (mod_remove(&modlinkage));
229 229 }
230 230
231 231 int
232 232 _info(struct modinfo *modinfop)
↓ open down ↓ |
232 lines elided |
↑ open up ↑ |
233 233 {
234 234 return (mod_info(&modlinkage, modinfop));
235 235 }
236 236
237 237 /*
238 238 * Initialize key schedules for blowfish
239 239 */
240 240 static int
241 241 init_keysched(crypto_key_t *key, void *keysched)
242 242 {
243 -/* EXPORT DELETE START */
244 243 /*
245 244 * Only keys by value are supported by this module.
246 245 */
247 246 switch (key->ck_format) {
248 247 case CRYPTO_KEY_RAW:
249 248 if (key->ck_length < BLOWFISH_MINBITS ||
250 249 key->ck_length > BLOWFISH_MAXBITS) {
251 250 return (CRYPTO_KEY_SIZE_RANGE);
252 251 }
253 252 break;
254 253 default:
255 254 return (CRYPTO_KEY_TYPE_INCONSISTENT);
256 255 }
257 256
258 257 blowfish_init_keysched(key->ck_data, key->ck_length, keysched);
259 -/* EXPORT DELETE END */
260 258 return (CRYPTO_SUCCESS);
261 259 }
262 260
263 261 /*
264 262 * KCF software provider control entry points.
265 263 */
266 264 /* ARGSUSED */
267 265 static void
268 266 blowfish_provider_status(crypto_provider_handle_t provider, uint_t *status)
269 267 {
270 268 *status = CRYPTO_PROVIDER_READY;
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
271 269 }
272 270
273 271 /*
274 272 * KCF software provider encrypt entry points.
275 273 */
276 274 static int
277 275 blowfish_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
278 276 crypto_key_t *key, crypto_spi_ctx_template_t template,
279 277 crypto_req_handle_t req)
280 278 {
281 -
282 -/* EXPORT DELETE START */
283 -
284 279 blowfish_ctx_t *blowfish_ctx;
285 280 int rv;
286 281 int kmflag;
287 282
288 283 /*
289 284 * Only keys by value are supported by this module.
290 285 */
291 286 if (key->ck_format != CRYPTO_KEY_RAW) {
292 287 return (CRYPTO_KEY_TYPE_INCONSISTENT);
293 288 }
294 289
295 290 if (!BLOWFISH_VALID_MECH(mechanism))
296 291 return (CRYPTO_MECHANISM_INVALID);
297 292
298 293 if (mechanism->cm_param != NULL &&
299 294 mechanism->cm_param_len != BLOWFISH_BLOCK_LEN)
300 295 return (CRYPTO_MECHANISM_PARAM_INVALID);
301 296
302 297 kmflag = crypto_kmflag(req);
303 298 switch (mechanism->cm_type) {
304 299 case BLOWFISH_ECB_MECH_INFO_TYPE:
305 300 blowfish_ctx = ecb_alloc_ctx(kmflag);
306 301 break;
307 302 case BLOWFISH_CBC_MECH_INFO_TYPE:
308 303 blowfish_ctx = cbc_alloc_ctx(kmflag);
309 304 break;
310 305 }
311 306 if (blowfish_ctx == NULL)
312 307 return (CRYPTO_HOST_MEMORY);
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
313 308
314 309 rv = blowfish_common_init_ctx(blowfish_ctx, template, mechanism,
315 310 key, kmflag);
316 311 if (rv != CRYPTO_SUCCESS) {
317 312 crypto_free_mode_ctx(blowfish_ctx);
318 313 return (rv);
319 314 }
320 315
321 316 ctx->cc_provider_private = blowfish_ctx;
322 317
323 -/* EXPORT DELETE END */
324 -
325 318 return (CRYPTO_SUCCESS);
326 319 }
327 320
328 321 static void
329 322 blowfish_copy_block64(uint8_t *in, uint64_t *out)
330 323 {
331 324 if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
332 325 /* LINTED: pointer alignment */
333 326 out[0] = *(uint64_t *)&in[0];
334 327 } else {
335 328 uint8_t *iv8 = (uint8_t *)&out[0];
336 329
337 330 BLOWFISH_COPY_BLOCK(in, iv8);
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
338 331 }
339 332 }
340 333
341 334 /* ARGSUSED */
342 335 static int
343 336 blowfish_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
344 337 crypto_data_t *ciphertext, crypto_req_handle_t req)
345 338 {
346 339 int ret;
347 340
348 -/* EXPORT DELETE START */
349 -
350 341 blowfish_ctx_t *blowfish_ctx;
351 342
352 343 /*
353 344 * Plaintext must be a multiple of blowfish block size.
354 345 * This test only works for non-padded mechanisms
355 346 * when blocksize is 2^N.
356 347 */
357 348 if ((plaintext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
358 349 return (CRYPTO_DATA_LEN_RANGE);
359 350
360 351 ASSERT(ctx->cc_provider_private != NULL);
361 352 blowfish_ctx = ctx->cc_provider_private;
362 353
363 354 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
364 355
365 356 /*
366 357 * We need to just return the length needed to store the output.
367 358 * We should not destroy the context for the following case.
368 359 */
369 360 if (ciphertext->cd_length < plaintext->cd_length) {
370 361 ciphertext->cd_length = plaintext->cd_length;
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
371 362 return (CRYPTO_BUFFER_TOO_SMALL);
372 363 }
373 364
374 365 /*
375 366 * Do an update on the specified input data.
376 367 */
377 368 ret = blowfish_encrypt_update(ctx, plaintext, ciphertext, req);
378 369 ASSERT(blowfish_ctx->bc_remainder_len == 0);
379 370 (void) blowfish_free_context(ctx);
380 371
381 -/* EXPORT DELETE END */
382 -
383 372 /* LINTED */
384 373 return (ret);
385 374 }
386 375
387 376 /* ARGSUSED */
388 377 static int
389 378 blowfish_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
390 379 crypto_data_t *plaintext, crypto_req_handle_t req)
391 380 {
392 381 int ret;
393 382
394 -/* EXPORT DELETE START */
395 -
396 383 blowfish_ctx_t *blowfish_ctx;
397 384
398 385 /*
399 386 * Ciphertext must be a multiple of blowfish block size.
400 387 * This test only works for non-padded mechanisms
401 388 * when blocksize is 2^N.
402 389 */
403 390 if ((ciphertext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
404 391 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
405 392
406 393 ASSERT(ctx->cc_provider_private != NULL);
407 394 blowfish_ctx = ctx->cc_provider_private;
408 395
409 396 BLOWFISH_ARG_INPLACE(ciphertext, plaintext);
410 397
411 398 /*
412 399 * We need to just return the length needed to store the output.
413 400 * We should not destroy the context for the following case.
414 401 */
415 402 if (plaintext->cd_length < ciphertext->cd_length) {
416 403 plaintext->cd_length = ciphertext->cd_length;
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
417 404 return (CRYPTO_BUFFER_TOO_SMALL);
418 405 }
419 406
420 407 /*
421 408 * Do an update on the specified input data.
422 409 */
423 410 ret = blowfish_decrypt_update(ctx, ciphertext, plaintext, req);
424 411 ASSERT(blowfish_ctx->bc_remainder_len == 0);
425 412 (void) blowfish_free_context(ctx);
426 413
427 -/* EXPORT DELETE END */
428 -
429 414 /* LINTED */
430 415 return (ret);
431 416 }
432 417
433 418 /* ARGSUSED */
434 419 static int
435 420 blowfish_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
436 421 crypto_data_t *ciphertext, crypto_req_handle_t req)
437 422 {
438 423 off_t saved_offset;
439 424 size_t saved_length, out_len;
440 425 int ret = CRYPTO_SUCCESS;
441 426
442 427 ASSERT(ctx->cc_provider_private != NULL);
443 428
444 429 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
445 430
446 431 /* compute number of bytes that will hold the ciphertext */
447 432 out_len =
448 433 ((blowfish_ctx_t *)ctx->cc_provider_private)->bc_remainder_len;
449 434 out_len += plaintext->cd_length;
450 435 out_len &= ~(BLOWFISH_BLOCK_LEN - 1);
451 436
452 437 /* return length needed to store the output */
453 438 if (ciphertext->cd_length < out_len) {
454 439 ciphertext->cd_length = out_len;
455 440 return (CRYPTO_BUFFER_TOO_SMALL);
456 441 }
457 442
458 443 saved_offset = ciphertext->cd_offset;
459 444 saved_length = ciphertext->cd_length;
460 445
461 446 /*
462 447 * Do the blowfish update on the specified input data.
463 448 */
464 449 switch (plaintext->cd_format) {
465 450 case CRYPTO_DATA_RAW:
466 451 ret = crypto_update_iov(ctx->cc_provider_private,
467 452 plaintext, ciphertext, blowfish_encrypt_contiguous_blocks,
468 453 blowfish_copy_block64);
469 454 break;
470 455 case CRYPTO_DATA_UIO:
471 456 ret = crypto_update_uio(ctx->cc_provider_private,
472 457 plaintext, ciphertext, blowfish_encrypt_contiguous_blocks,
473 458 blowfish_copy_block64);
474 459 break;
475 460 case CRYPTO_DATA_MBLK:
476 461 ret = crypto_update_mp(ctx->cc_provider_private,
477 462 plaintext, ciphertext, blowfish_encrypt_contiguous_blocks,
478 463 blowfish_copy_block64);
479 464 break;
480 465 default:
481 466 ret = CRYPTO_ARGUMENTS_BAD;
482 467 }
483 468
484 469 if (ret == CRYPTO_SUCCESS) {
485 470 if (plaintext != ciphertext)
486 471 ciphertext->cd_length =
487 472 ciphertext->cd_offset - saved_offset;
488 473 } else {
489 474 ciphertext->cd_length = saved_length;
490 475 }
491 476 ciphertext->cd_offset = saved_offset;
492 477
493 478 return (ret);
494 479 }
495 480
496 481 /* ARGSUSED */
497 482 static int
498 483 blowfish_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
499 484 crypto_data_t *plaintext, crypto_req_handle_t req)
500 485 {
501 486 off_t saved_offset;
502 487 size_t saved_length, out_len;
503 488 int ret = CRYPTO_SUCCESS;
504 489
505 490 ASSERT(ctx->cc_provider_private != NULL);
506 491
507 492 BLOWFISH_ARG_INPLACE(ciphertext, plaintext);
508 493
509 494 /* compute number of bytes that will hold the plaintext */
510 495 out_len =
511 496 ((blowfish_ctx_t *)ctx->cc_provider_private)->bc_remainder_len;
512 497 out_len += ciphertext->cd_length;
513 498 out_len &= ~(BLOWFISH_BLOCK_LEN - 1);
514 499
515 500 /* return length needed to store the output */
516 501 if (plaintext->cd_length < out_len) {
517 502 plaintext->cd_length = out_len;
518 503 return (CRYPTO_BUFFER_TOO_SMALL);
519 504 }
520 505
521 506 saved_offset = plaintext->cd_offset;
522 507 saved_length = plaintext->cd_length;
523 508
524 509 /*
525 510 * Do the blowfish update on the specified input data.
526 511 */
527 512 switch (ciphertext->cd_format) {
528 513 case CRYPTO_DATA_RAW:
529 514 ret = crypto_update_iov(ctx->cc_provider_private,
530 515 ciphertext, plaintext, blowfish_decrypt_contiguous_blocks,
531 516 blowfish_copy_block64);
532 517 break;
533 518 case CRYPTO_DATA_UIO:
534 519 ret = crypto_update_uio(ctx->cc_provider_private,
535 520 ciphertext, plaintext, blowfish_decrypt_contiguous_blocks,
536 521 blowfish_copy_block64);
537 522 break;
538 523 case CRYPTO_DATA_MBLK:
539 524 ret = crypto_update_mp(ctx->cc_provider_private,
540 525 ciphertext, plaintext, blowfish_decrypt_contiguous_blocks,
541 526 blowfish_copy_block64);
542 527 break;
543 528 default:
544 529 ret = CRYPTO_ARGUMENTS_BAD;
545 530 }
546 531
547 532 if (ret == CRYPTO_SUCCESS) {
548 533 if (ciphertext != plaintext)
549 534 plaintext->cd_length =
550 535 plaintext->cd_offset - saved_offset;
551 536 } else {
552 537 plaintext->cd_length = saved_length;
553 538 }
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
554 539 plaintext->cd_offset = saved_offset;
555 540
556 541 return (ret);
557 542 }
558 543
559 544 /* ARGSUSED */
560 545 static int
561 546 blowfish_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
562 547 crypto_req_handle_t req)
563 548 {
564 -
565 -/* EXPORT DELETE START */
566 -
567 549 blowfish_ctx_t *blowfish_ctx;
568 550
569 551 ASSERT(ctx->cc_provider_private != NULL);
570 552 blowfish_ctx = ctx->cc_provider_private;
571 553
572 554 /*
573 555 * There must be no unprocessed data.
574 556 * This happens if the length of the last data is
575 557 * not a multiple of the BLOWFISH block length.
576 558 */
577 559 if (blowfish_ctx->bc_remainder_len > 0)
578 560 return (CRYPTO_DATA_LEN_RANGE);
579 561
580 562 (void) blowfish_free_context(ctx);
581 563 data->cd_length = 0;
582 564
583 -/* EXPORT DELETE END */
584 -
585 565 return (CRYPTO_SUCCESS);
586 566 }
587 567
588 568 /* ARGSUSED */
589 569 static int
590 570 blowfish_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
591 571 crypto_req_handle_t req)
592 572 {
593 -
594 -/* EXPORT DELETE START */
595 -
596 573 blowfish_ctx_t *blowfish_ctx;
597 574
598 575 ASSERT(ctx->cc_provider_private != NULL);
599 576 blowfish_ctx = ctx->cc_provider_private;
600 577
601 578 /*
602 579 * There must be no unprocessed ciphertext.
603 580 * This happens if the length of the last ciphertext is
604 581 * not a multiple of the BLOWFISH block length.
605 582 */
606 583 if (blowfish_ctx->bc_remainder_len > 0)
607 584 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
608 585
609 586 (void) blowfish_free_context(ctx);
610 587 data->cd_length = 0;
611 588
612 -/* EXPORT DELETE END */
613 -
614 589 return (CRYPTO_SUCCESS);
615 590 }
616 591
617 592 /* ARGSUSED */
618 593 static int
619 594 blowfish_encrypt_atomic(crypto_provider_handle_t provider,
620 595 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
621 596 crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
622 597 crypto_spi_ctx_template_t template, crypto_req_handle_t req)
623 598 {
624 599 blowfish_ctx_t blowfish_ctx; /* on the stack */
625 600 off_t saved_offset;
626 601 size_t saved_length;
627 602 int ret;
628 603
629 604 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
630 605
631 606 /*
632 607 * Plaintext must be a multiple of blowfish block size.
633 608 * This test only works for non-padded mechanisms
634 609 * when blocksize is 2^N.
635 610 */
636 611 if ((plaintext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
637 612 return (CRYPTO_DATA_LEN_RANGE);
638 613
639 614 /* return length needed to store the output */
640 615 if (ciphertext->cd_length < plaintext->cd_length) {
641 616 ciphertext->cd_length = plaintext->cd_length;
642 617 return (CRYPTO_BUFFER_TOO_SMALL);
643 618 }
644 619
645 620 if (!BLOWFISH_VALID_MECH(mechanism))
646 621 return (CRYPTO_MECHANISM_INVALID);
647 622
648 623 if (mechanism->cm_param_len != 0 &&
649 624 mechanism->cm_param_len != BLOWFISH_BLOCK_LEN)
650 625 return (CRYPTO_MECHANISM_PARAM_INVALID);
651 626
652 627 bzero(&blowfish_ctx, sizeof (blowfish_ctx_t));
653 628
654 629 ret = blowfish_common_init_ctx(&blowfish_ctx, template, mechanism,
655 630 key, crypto_kmflag(req));
656 631 if (ret != CRYPTO_SUCCESS)
657 632 return (ret);
658 633
659 634 saved_offset = ciphertext->cd_offset;
660 635 saved_length = ciphertext->cd_length;
661 636
662 637 /*
663 638 * Do an update on the specified input data.
664 639 */
665 640 switch (plaintext->cd_format) {
666 641 case CRYPTO_DATA_RAW:
667 642 ret = crypto_update_iov(&blowfish_ctx,
668 643 plaintext, ciphertext, blowfish_encrypt_contiguous_blocks,
669 644 blowfish_copy_block64);
670 645 break;
671 646 case CRYPTO_DATA_UIO:
672 647 ret = crypto_update_uio(&blowfish_ctx,
673 648 plaintext, ciphertext, blowfish_encrypt_contiguous_blocks,
674 649 blowfish_copy_block64);
675 650 break;
676 651 case CRYPTO_DATA_MBLK:
677 652 ret = crypto_update_mp((void *)&blowfish_ctx,
678 653 plaintext, ciphertext, blowfish_encrypt_contiguous_blocks,
679 654 blowfish_copy_block64);
680 655 break;
681 656 default:
682 657 ret = CRYPTO_ARGUMENTS_BAD;
683 658 }
684 659
685 660 if (blowfish_ctx.bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
686 661 bzero(blowfish_ctx.bc_keysched, blowfish_ctx.bc_keysched_len);
687 662 kmem_free(blowfish_ctx.bc_keysched,
688 663 blowfish_ctx.bc_keysched_len);
689 664 }
690 665
691 666 if (ret == CRYPTO_SUCCESS) {
692 667 ASSERT(blowfish_ctx.bc_remainder_len == 0);
693 668 if (plaintext != ciphertext)
694 669 ciphertext->cd_length =
695 670 ciphertext->cd_offset - saved_offset;
696 671 } else {
697 672 ciphertext->cd_length = saved_length;
698 673 }
699 674 ciphertext->cd_offset = saved_offset;
700 675
701 676 return (ret);
702 677 }
703 678
704 679 /* ARGSUSED */
705 680 static int
706 681 blowfish_decrypt_atomic(crypto_provider_handle_t provider,
707 682 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
708 683 crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
709 684 crypto_spi_ctx_template_t template, crypto_req_handle_t req)
710 685 {
711 686 blowfish_ctx_t blowfish_ctx; /* on the stack */
712 687 off_t saved_offset;
713 688 size_t saved_length;
714 689 int ret;
715 690
716 691 BLOWFISH_ARG_INPLACE(ciphertext, plaintext);
717 692
718 693 /*
719 694 * Ciphertext must be a multiple of blowfish block size.
720 695 * This test only works for non-padded mechanisms
721 696 * when blocksize is 2^N.
722 697 */
723 698 if ((ciphertext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
724 699 return (CRYPTO_DATA_LEN_RANGE);
725 700
726 701 /* return length needed to store the output */
727 702 if (plaintext->cd_length < ciphertext->cd_length) {
728 703 plaintext->cd_length = ciphertext->cd_length;
729 704 return (CRYPTO_BUFFER_TOO_SMALL);
730 705 }
731 706
732 707 if (!BLOWFISH_VALID_MECH(mechanism))
733 708 return (CRYPTO_MECHANISM_INVALID);
734 709
735 710 if (mechanism->cm_param_len != 0 &&
736 711 mechanism->cm_param_len != BLOWFISH_BLOCK_LEN)
737 712 return (CRYPTO_MECHANISM_PARAM_INVALID);
738 713
739 714 bzero(&blowfish_ctx, sizeof (blowfish_ctx_t));
740 715
741 716 ret = blowfish_common_init_ctx(&blowfish_ctx, template, mechanism,
742 717 key, crypto_kmflag(req));
743 718 if (ret != CRYPTO_SUCCESS)
744 719 return (ret);
745 720
746 721 saved_offset = plaintext->cd_offset;
747 722 saved_length = plaintext->cd_length;
748 723
749 724 /*
750 725 * Do an update on the specified input data.
751 726 */
752 727 switch (ciphertext->cd_format) {
753 728 case CRYPTO_DATA_RAW:
754 729 ret = crypto_update_iov(&blowfish_ctx,
755 730 ciphertext, plaintext, blowfish_decrypt_contiguous_blocks,
756 731 blowfish_copy_block64);
757 732 break;
758 733 case CRYPTO_DATA_UIO:
759 734 ret = crypto_update_uio(&blowfish_ctx,
760 735 ciphertext, plaintext, blowfish_decrypt_contiguous_blocks,
761 736 blowfish_copy_block64);
762 737 break;
763 738 case CRYPTO_DATA_MBLK:
764 739 ret = crypto_update_mp(&blowfish_ctx,
765 740 ciphertext, plaintext, blowfish_decrypt_contiguous_blocks,
766 741 blowfish_copy_block64);
767 742 break;
768 743 default:
769 744 ret = CRYPTO_ARGUMENTS_BAD;
770 745 }
771 746
772 747 if (blowfish_ctx.bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
773 748 bzero(blowfish_ctx.bc_keysched, blowfish_ctx.bc_keysched_len);
774 749 kmem_free(blowfish_ctx.bc_keysched,
775 750 blowfish_ctx.bc_keysched_len);
776 751 }
777 752
778 753 if (ret == CRYPTO_SUCCESS) {
779 754 ASSERT(blowfish_ctx.bc_remainder_len == 0);
780 755 if (ciphertext != plaintext)
781 756 plaintext->cd_length =
782 757 plaintext->cd_offset - saved_offset;
783 758 } else {
784 759 plaintext->cd_length = saved_length;
785 760 }
786 761 plaintext->cd_offset = saved_offset;
787 762
788 763 return (ret);
789 764 }
↓ open down ↓ |
166 lines elided |
↑ open up ↑ |
790 765
791 766 /*
792 767 * KCF software provider context template entry points.
793 768 */
794 769 /* ARGSUSED */
795 770 static int
796 771 blowfish_create_ctx_template(crypto_provider_handle_t provider,
797 772 crypto_mechanism_t *mechanism, crypto_key_t *key,
798 773 crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
799 774 {
800 -
801 -/* EXPORT DELETE START */
802 -
803 775 void *keysched;
804 776 size_t size;
805 777 int rv;
806 778
807 779 if (!BLOWFISH_VALID_MECH(mechanism))
808 780 return (CRYPTO_MECHANISM_INVALID);
809 781
810 782 if ((keysched = blowfish_alloc_keysched(&size,
811 783 crypto_kmflag(req))) == NULL) {
812 784 return (CRYPTO_HOST_MEMORY);
813 785 }
814 786
815 787 /*
816 788 * Initialize key schedule. Key length information is stored
817 789 * in the key.
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
818 790 */
819 791 if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
820 792 bzero(keysched, size);
821 793 kmem_free(keysched, size);
822 794 return (rv);
823 795 }
824 796
825 797 *tmpl = keysched;
826 798 *tmpl_size = size;
827 799
828 -/* EXPORT DELETE END */
829 -
830 800 return (CRYPTO_SUCCESS);
831 801 }
832 802
833 803 /* ARGSUSED */
834 804 static int
835 805 blowfish_free_context(crypto_ctx_t *ctx)
836 806 {
837 807 blowfish_ctx_t *blowfish_ctx = ctx->cc_provider_private;
838 808
839 809 if (blowfish_ctx != NULL) {
840 810 if (blowfish_ctx->bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
841 811 ASSERT(blowfish_ctx->bc_keysched_len != 0);
842 812 bzero(blowfish_ctx->bc_keysched,
843 813 blowfish_ctx->bc_keysched_len);
844 814 kmem_free(blowfish_ctx->bc_keysched,
845 815 blowfish_ctx->bc_keysched_len);
846 816 }
847 817 crypto_free_mode_ctx(blowfish_ctx);
848 818 ctx->cc_provider_private = NULL;
849 819 }
850 820
851 821 return (CRYPTO_SUCCESS);
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
852 822 }
853 823
854 824 /* ARGSUSED */
855 825 static int
856 826 blowfish_common_init_ctx(blowfish_ctx_t *blowfish_ctx,
857 827 crypto_spi_ctx_template_t *template, crypto_mechanism_t *mechanism,
858 828 crypto_key_t *key, int kmflag)
859 829 {
860 830 int rv = CRYPTO_SUCCESS;
861 831
862 -/* EXPORT DELETE START */
863 -
864 832 void *keysched;
865 833 size_t size;
866 834
867 835 if (template == NULL) {
868 836 if ((keysched = blowfish_alloc_keysched(&size, kmflag)) == NULL)
869 837 return (CRYPTO_HOST_MEMORY);
870 838 /*
871 839 * Initialize key schedule.
872 840 * Key length is stored in the key.
873 841 */
874 842 if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS)
875 843 kmem_free(keysched, size);
876 844
877 845 blowfish_ctx->bc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
878 846 blowfish_ctx->bc_keysched_len = size;
879 847 } else {
880 848 keysched = template;
881 849 }
882 850 blowfish_ctx->bc_keysched = keysched;
883 851
884 852 switch (mechanism->cm_type) {
885 853 case BLOWFISH_CBC_MECH_INFO_TYPE:
886 854 rv = cbc_init_ctx((cbc_ctx_t *)blowfish_ctx,
887 855 mechanism->cm_param, mechanism->cm_param_len,
888 856 BLOWFISH_BLOCK_LEN, blowfish_copy_block64);
889 857 break;
890 858 case BLOWFISH_ECB_MECH_INFO_TYPE:
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
891 859 blowfish_ctx->bc_flags |= ECB_MODE;
892 860 }
893 861
894 862 if (rv != CRYPTO_SUCCESS) {
895 863 if (blowfish_ctx->bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
896 864 bzero(keysched, size);
897 865 kmem_free(keysched, size);
898 866 }
899 867 }
900 868
901 -/* EXPORT DELETE END */
902 -
903 869 return (rv);
904 870 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX