223 return (EBUSY);
224
225 blowfish_prov_handle = NULL;
226 }
227
228 return (mod_remove(&modlinkage));
229 }
230
231 int
232 _info(struct modinfo *modinfop)
233 {
234 return (mod_info(&modlinkage, modinfop));
235 }
236
237 /*
238 * Initialize key schedules for blowfish
239 */
240 static int
241 init_keysched(crypto_key_t *key, void *keysched)
242 {
243 /* EXPORT DELETE START */
244 /*
245 * Only keys by value are supported by this module.
246 */
247 switch (key->ck_format) {
248 case CRYPTO_KEY_RAW:
249 if (key->ck_length < BLOWFISH_MINBITS ||
250 key->ck_length > BLOWFISH_MAXBITS) {
251 return (CRYPTO_KEY_SIZE_RANGE);
252 }
253 break;
254 default:
255 return (CRYPTO_KEY_TYPE_INCONSISTENT);
256 }
257
258 blowfish_init_keysched(key->ck_data, key->ck_length, keysched);
259 /* EXPORT DELETE END */
260 return (CRYPTO_SUCCESS);
261 }
262
263 /*
264 * KCF software provider control entry points.
265 */
266 /* ARGSUSED */
267 static void
268 blowfish_provider_status(crypto_provider_handle_t provider, uint_t *status)
269 {
270 *status = CRYPTO_PROVIDER_READY;
271 }
272
273 /*
274 * KCF software provider encrypt entry points.
275 */
276 static int
277 blowfish_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
278 crypto_key_t *key, crypto_spi_ctx_template_t template,
279 crypto_req_handle_t req)
280 {
281
282 /* EXPORT DELETE START */
283
284 blowfish_ctx_t *blowfish_ctx;
285 int rv;
286 int kmflag;
287
288 /*
289 * Only keys by value are supported by this module.
290 */
291 if (key->ck_format != CRYPTO_KEY_RAW) {
292 return (CRYPTO_KEY_TYPE_INCONSISTENT);
293 }
294
295 if (!BLOWFISH_VALID_MECH(mechanism))
296 return (CRYPTO_MECHANISM_INVALID);
297
298 if (mechanism->cm_param != NULL &&
299 mechanism->cm_param_len != BLOWFISH_BLOCK_LEN)
300 return (CRYPTO_MECHANISM_PARAM_INVALID);
301
302 kmflag = crypto_kmflag(req);
303 switch (mechanism->cm_type) {
304 case BLOWFISH_ECB_MECH_INFO_TYPE:
305 blowfish_ctx = ecb_alloc_ctx(kmflag);
306 break;
307 case BLOWFISH_CBC_MECH_INFO_TYPE:
308 blowfish_ctx = cbc_alloc_ctx(kmflag);
309 break;
310 }
311 if (blowfish_ctx == NULL)
312 return (CRYPTO_HOST_MEMORY);
313
314 rv = blowfish_common_init_ctx(blowfish_ctx, template, mechanism,
315 key, kmflag);
316 if (rv != CRYPTO_SUCCESS) {
317 crypto_free_mode_ctx(blowfish_ctx);
318 return (rv);
319 }
320
321 ctx->cc_provider_private = blowfish_ctx;
322
323 /* EXPORT DELETE END */
324
325 return (CRYPTO_SUCCESS);
326 }
327
328 static void
329 blowfish_copy_block64(uint8_t *in, uint64_t *out)
330 {
331 if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
332 /* LINTED: pointer alignment */
333 out[0] = *(uint64_t *)&in[0];
334 } else {
335 uint8_t *iv8 = (uint8_t *)&out[0];
336
337 BLOWFISH_COPY_BLOCK(in, iv8);
338 }
339 }
340
341 /* ARGSUSED */
342 static int
343 blowfish_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
344 crypto_data_t *ciphertext, crypto_req_handle_t req)
345 {
346 int ret;
347
348 /* EXPORT DELETE START */
349
350 blowfish_ctx_t *blowfish_ctx;
351
352 /*
353 * Plaintext must be a multiple of blowfish block size.
354 * This test only works for non-padded mechanisms
355 * when blocksize is 2^N.
356 */
357 if ((plaintext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
358 return (CRYPTO_DATA_LEN_RANGE);
359
360 ASSERT(ctx->cc_provider_private != NULL);
361 blowfish_ctx = ctx->cc_provider_private;
362
363 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
364
365 /*
366 * We need to just return the length needed to store the output.
367 * We should not destroy the context for the following case.
368 */
369 if (ciphertext->cd_length < plaintext->cd_length) {
370 ciphertext->cd_length = plaintext->cd_length;
371 return (CRYPTO_BUFFER_TOO_SMALL);
372 }
373
374 /*
375 * Do an update on the specified input data.
376 */
377 ret = blowfish_encrypt_update(ctx, plaintext, ciphertext, req);
378 ASSERT(blowfish_ctx->bc_remainder_len == 0);
379 (void) blowfish_free_context(ctx);
380
381 /* EXPORT DELETE END */
382
383 /* LINTED */
384 return (ret);
385 }
386
387 /* ARGSUSED */
388 static int
389 blowfish_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
390 crypto_data_t *plaintext, crypto_req_handle_t req)
391 {
392 int ret;
393
394 /* EXPORT DELETE START */
395
396 blowfish_ctx_t *blowfish_ctx;
397
398 /*
399 * Ciphertext must be a multiple of blowfish block size.
400 * This test only works for non-padded mechanisms
401 * when blocksize is 2^N.
402 */
403 if ((ciphertext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
404 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
405
406 ASSERT(ctx->cc_provider_private != NULL);
407 blowfish_ctx = ctx->cc_provider_private;
408
409 BLOWFISH_ARG_INPLACE(ciphertext, plaintext);
410
411 /*
412 * We need to just return the length needed to store the output.
413 * We should not destroy the context for the following case.
414 */
415 if (plaintext->cd_length < ciphertext->cd_length) {
416 plaintext->cd_length = ciphertext->cd_length;
417 return (CRYPTO_BUFFER_TOO_SMALL);
418 }
419
420 /*
421 * Do an update on the specified input data.
422 */
423 ret = blowfish_decrypt_update(ctx, ciphertext, plaintext, req);
424 ASSERT(blowfish_ctx->bc_remainder_len == 0);
425 (void) blowfish_free_context(ctx);
426
427 /* EXPORT DELETE END */
428
429 /* LINTED */
430 return (ret);
431 }
432
433 /* ARGSUSED */
434 static int
435 blowfish_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
436 crypto_data_t *ciphertext, crypto_req_handle_t req)
437 {
438 off_t saved_offset;
439 size_t saved_length, out_len;
440 int ret = CRYPTO_SUCCESS;
441
442 ASSERT(ctx->cc_provider_private != NULL);
443
444 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
445
446 /* compute number of bytes that will hold the ciphertext */
447 out_len =
448 ((blowfish_ctx_t *)ctx->cc_provider_private)->bc_remainder_len;
544 ret = CRYPTO_ARGUMENTS_BAD;
545 }
546
547 if (ret == CRYPTO_SUCCESS) {
548 if (ciphertext != plaintext)
549 plaintext->cd_length =
550 plaintext->cd_offset - saved_offset;
551 } else {
552 plaintext->cd_length = saved_length;
553 }
554 plaintext->cd_offset = saved_offset;
555
556 return (ret);
557 }
558
559 /* ARGSUSED */
560 static int
561 blowfish_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
562 crypto_req_handle_t req)
563 {
564
565 /* EXPORT DELETE START */
566
567 blowfish_ctx_t *blowfish_ctx;
568
569 ASSERT(ctx->cc_provider_private != NULL);
570 blowfish_ctx = ctx->cc_provider_private;
571
572 /*
573 * There must be no unprocessed data.
574 * This happens if the length of the last data is
575 * not a multiple of the BLOWFISH block length.
576 */
577 if (blowfish_ctx->bc_remainder_len > 0)
578 return (CRYPTO_DATA_LEN_RANGE);
579
580 (void) blowfish_free_context(ctx);
581 data->cd_length = 0;
582
583 /* EXPORT DELETE END */
584
585 return (CRYPTO_SUCCESS);
586 }
587
588 /* ARGSUSED */
589 static int
590 blowfish_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
591 crypto_req_handle_t req)
592 {
593
594 /* EXPORT DELETE START */
595
596 blowfish_ctx_t *blowfish_ctx;
597
598 ASSERT(ctx->cc_provider_private != NULL);
599 blowfish_ctx = ctx->cc_provider_private;
600
601 /*
602 * There must be no unprocessed ciphertext.
603 * This happens if the length of the last ciphertext is
604 * not a multiple of the BLOWFISH block length.
605 */
606 if (blowfish_ctx->bc_remainder_len > 0)
607 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
608
609 (void) blowfish_free_context(ctx);
610 data->cd_length = 0;
611
612 /* EXPORT DELETE END */
613
614 return (CRYPTO_SUCCESS);
615 }
616
617 /* ARGSUSED */
618 static int
619 blowfish_encrypt_atomic(crypto_provider_handle_t provider,
620 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
621 crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
622 crypto_spi_ctx_template_t template, crypto_req_handle_t req)
623 {
624 blowfish_ctx_t blowfish_ctx; /* on the stack */
625 off_t saved_offset;
626 size_t saved_length;
627 int ret;
628
629 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
630
631 /*
632 * Plaintext must be a multiple of blowfish block size.
633 * This test only works for non-padded mechanisms
780 if (ciphertext != plaintext)
781 plaintext->cd_length =
782 plaintext->cd_offset - saved_offset;
783 } else {
784 plaintext->cd_length = saved_length;
785 }
786 plaintext->cd_offset = saved_offset;
787
788 return (ret);
789 }
790
791 /*
792 * KCF software provider context template entry points.
793 */
794 /* ARGSUSED */
795 static int
796 blowfish_create_ctx_template(crypto_provider_handle_t provider,
797 crypto_mechanism_t *mechanism, crypto_key_t *key,
798 crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
799 {
800
801 /* EXPORT DELETE START */
802
803 void *keysched;
804 size_t size;
805 int rv;
806
807 if (!BLOWFISH_VALID_MECH(mechanism))
808 return (CRYPTO_MECHANISM_INVALID);
809
810 if ((keysched = blowfish_alloc_keysched(&size,
811 crypto_kmflag(req))) == NULL) {
812 return (CRYPTO_HOST_MEMORY);
813 }
814
815 /*
816 * Initialize key schedule. Key length information is stored
817 * in the key.
818 */
819 if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
820 bzero(keysched, size);
821 kmem_free(keysched, size);
822 return (rv);
823 }
824
825 *tmpl = keysched;
826 *tmpl_size = size;
827
828 /* EXPORT DELETE END */
829
830 return (CRYPTO_SUCCESS);
831 }
832
833 /* ARGSUSED */
834 static int
835 blowfish_free_context(crypto_ctx_t *ctx)
836 {
837 blowfish_ctx_t *blowfish_ctx = ctx->cc_provider_private;
838
839 if (blowfish_ctx != NULL) {
840 if (blowfish_ctx->bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
841 ASSERT(blowfish_ctx->bc_keysched_len != 0);
842 bzero(blowfish_ctx->bc_keysched,
843 blowfish_ctx->bc_keysched_len);
844 kmem_free(blowfish_ctx->bc_keysched,
845 blowfish_ctx->bc_keysched_len);
846 }
847 crypto_free_mode_ctx(blowfish_ctx);
848 ctx->cc_provider_private = NULL;
849 }
850
851 return (CRYPTO_SUCCESS);
852 }
853
854 /* ARGSUSED */
855 static int
856 blowfish_common_init_ctx(blowfish_ctx_t *blowfish_ctx,
857 crypto_spi_ctx_template_t *template, crypto_mechanism_t *mechanism,
858 crypto_key_t *key, int kmflag)
859 {
860 int rv = CRYPTO_SUCCESS;
861
862 /* EXPORT DELETE START */
863
864 void *keysched;
865 size_t size;
866
867 if (template == NULL) {
868 if ((keysched = blowfish_alloc_keysched(&size, kmflag)) == NULL)
869 return (CRYPTO_HOST_MEMORY);
870 /*
871 * Initialize key schedule.
872 * Key length is stored in the key.
873 */
874 if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS)
875 kmem_free(keysched, size);
876
877 blowfish_ctx->bc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
878 blowfish_ctx->bc_keysched_len = size;
879 } else {
880 keysched = template;
881 }
882 blowfish_ctx->bc_keysched = keysched;
883
884 switch (mechanism->cm_type) {
885 case BLOWFISH_CBC_MECH_INFO_TYPE:
886 rv = cbc_init_ctx((cbc_ctx_t *)blowfish_ctx,
887 mechanism->cm_param, mechanism->cm_param_len,
888 BLOWFISH_BLOCK_LEN, blowfish_copy_block64);
889 break;
890 case BLOWFISH_ECB_MECH_INFO_TYPE:
891 blowfish_ctx->bc_flags |= ECB_MODE;
892 }
893
894 if (rv != CRYPTO_SUCCESS) {
895 if (blowfish_ctx->bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
896 bzero(keysched, size);
897 kmem_free(keysched, size);
898 }
899 }
900
901 /* EXPORT DELETE END */
902
903 return (rv);
904 }
|
223 return (EBUSY);
224
225 blowfish_prov_handle = NULL;
226 }
227
228 return (mod_remove(&modlinkage));
229 }
230
231 int
232 _info(struct modinfo *modinfop)
233 {
234 return (mod_info(&modlinkage, modinfop));
235 }
236
237 /*
238 * Initialize key schedules for blowfish
239 */
240 static int
241 init_keysched(crypto_key_t *key, void *keysched)
242 {
243 /*
244 * Only keys by value are supported by this module.
245 */
246 switch (key->ck_format) {
247 case CRYPTO_KEY_RAW:
248 if (key->ck_length < BLOWFISH_MINBITS ||
249 key->ck_length > BLOWFISH_MAXBITS) {
250 return (CRYPTO_KEY_SIZE_RANGE);
251 }
252 break;
253 default:
254 return (CRYPTO_KEY_TYPE_INCONSISTENT);
255 }
256
257 blowfish_init_keysched(key->ck_data, key->ck_length, keysched);
258 return (CRYPTO_SUCCESS);
259 }
260
261 /*
262 * KCF software provider control entry points.
263 */
264 /* ARGSUSED */
265 static void
266 blowfish_provider_status(crypto_provider_handle_t provider, uint_t *status)
267 {
268 *status = CRYPTO_PROVIDER_READY;
269 }
270
271 /*
272 * KCF software provider encrypt entry points.
273 */
274 static int
275 blowfish_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
276 crypto_key_t *key, crypto_spi_ctx_template_t template,
277 crypto_req_handle_t req)
278 {
279 blowfish_ctx_t *blowfish_ctx;
280 int rv;
281 int kmflag;
282
283 /*
284 * Only keys by value are supported by this module.
285 */
286 if (key->ck_format != CRYPTO_KEY_RAW) {
287 return (CRYPTO_KEY_TYPE_INCONSISTENT);
288 }
289
290 if (!BLOWFISH_VALID_MECH(mechanism))
291 return (CRYPTO_MECHANISM_INVALID);
292
293 if (mechanism->cm_param != NULL &&
294 mechanism->cm_param_len != BLOWFISH_BLOCK_LEN)
295 return (CRYPTO_MECHANISM_PARAM_INVALID);
296
297 kmflag = crypto_kmflag(req);
298 switch (mechanism->cm_type) {
299 case BLOWFISH_ECB_MECH_INFO_TYPE:
300 blowfish_ctx = ecb_alloc_ctx(kmflag);
301 break;
302 case BLOWFISH_CBC_MECH_INFO_TYPE:
303 blowfish_ctx = cbc_alloc_ctx(kmflag);
304 break;
305 }
306 if (blowfish_ctx == NULL)
307 return (CRYPTO_HOST_MEMORY);
308
309 rv = blowfish_common_init_ctx(blowfish_ctx, template, mechanism,
310 key, kmflag);
311 if (rv != CRYPTO_SUCCESS) {
312 crypto_free_mode_ctx(blowfish_ctx);
313 return (rv);
314 }
315
316 ctx->cc_provider_private = blowfish_ctx;
317
318 return (CRYPTO_SUCCESS);
319 }
320
321 static void
322 blowfish_copy_block64(uint8_t *in, uint64_t *out)
323 {
324 if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
325 /* LINTED: pointer alignment */
326 out[0] = *(uint64_t *)&in[0];
327 } else {
328 uint8_t *iv8 = (uint8_t *)&out[0];
329
330 BLOWFISH_COPY_BLOCK(in, iv8);
331 }
332 }
333
334 /* ARGSUSED */
335 static int
336 blowfish_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
337 crypto_data_t *ciphertext, crypto_req_handle_t req)
338 {
339 int ret;
340
341 blowfish_ctx_t *blowfish_ctx;
342
343 /*
344 * Plaintext must be a multiple of blowfish block size.
345 * This test only works for non-padded mechanisms
346 * when blocksize is 2^N.
347 */
348 if ((plaintext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
349 return (CRYPTO_DATA_LEN_RANGE);
350
351 ASSERT(ctx->cc_provider_private != NULL);
352 blowfish_ctx = ctx->cc_provider_private;
353
354 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
355
356 /*
357 * We need to just return the length needed to store the output.
358 * We should not destroy the context for the following case.
359 */
360 if (ciphertext->cd_length < plaintext->cd_length) {
361 ciphertext->cd_length = plaintext->cd_length;
362 return (CRYPTO_BUFFER_TOO_SMALL);
363 }
364
365 /*
366 * Do an update on the specified input data.
367 */
368 ret = blowfish_encrypt_update(ctx, plaintext, ciphertext, req);
369 ASSERT(blowfish_ctx->bc_remainder_len == 0);
370 (void) blowfish_free_context(ctx);
371
372 /* LINTED */
373 return (ret);
374 }
375
376 /* ARGSUSED */
377 static int
378 blowfish_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
379 crypto_data_t *plaintext, crypto_req_handle_t req)
380 {
381 int ret;
382
383 blowfish_ctx_t *blowfish_ctx;
384
385 /*
386 * Ciphertext must be a multiple of blowfish block size.
387 * This test only works for non-padded mechanisms
388 * when blocksize is 2^N.
389 */
390 if ((ciphertext->cd_length & (BLOWFISH_BLOCK_LEN - 1)) != 0)
391 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
392
393 ASSERT(ctx->cc_provider_private != NULL);
394 blowfish_ctx = ctx->cc_provider_private;
395
396 BLOWFISH_ARG_INPLACE(ciphertext, plaintext);
397
398 /*
399 * We need to just return the length needed to store the output.
400 * We should not destroy the context for the following case.
401 */
402 if (plaintext->cd_length < ciphertext->cd_length) {
403 plaintext->cd_length = ciphertext->cd_length;
404 return (CRYPTO_BUFFER_TOO_SMALL);
405 }
406
407 /*
408 * Do an update on the specified input data.
409 */
410 ret = blowfish_decrypt_update(ctx, ciphertext, plaintext, req);
411 ASSERT(blowfish_ctx->bc_remainder_len == 0);
412 (void) blowfish_free_context(ctx);
413
414 /* LINTED */
415 return (ret);
416 }
417
418 /* ARGSUSED */
419 static int
420 blowfish_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
421 crypto_data_t *ciphertext, crypto_req_handle_t req)
422 {
423 off_t saved_offset;
424 size_t saved_length, out_len;
425 int ret = CRYPTO_SUCCESS;
426
427 ASSERT(ctx->cc_provider_private != NULL);
428
429 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
430
431 /* compute number of bytes that will hold the ciphertext */
432 out_len =
433 ((blowfish_ctx_t *)ctx->cc_provider_private)->bc_remainder_len;
529 ret = CRYPTO_ARGUMENTS_BAD;
530 }
531
532 if (ret == CRYPTO_SUCCESS) {
533 if (ciphertext != plaintext)
534 plaintext->cd_length =
535 plaintext->cd_offset - saved_offset;
536 } else {
537 plaintext->cd_length = saved_length;
538 }
539 plaintext->cd_offset = saved_offset;
540
541 return (ret);
542 }
543
544 /* ARGSUSED */
545 static int
546 blowfish_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
547 crypto_req_handle_t req)
548 {
549 blowfish_ctx_t *blowfish_ctx;
550
551 ASSERT(ctx->cc_provider_private != NULL);
552 blowfish_ctx = ctx->cc_provider_private;
553
554 /*
555 * There must be no unprocessed data.
556 * This happens if the length of the last data is
557 * not a multiple of the BLOWFISH block length.
558 */
559 if (blowfish_ctx->bc_remainder_len > 0)
560 return (CRYPTO_DATA_LEN_RANGE);
561
562 (void) blowfish_free_context(ctx);
563 data->cd_length = 0;
564
565 return (CRYPTO_SUCCESS);
566 }
567
568 /* ARGSUSED */
569 static int
570 blowfish_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
571 crypto_req_handle_t req)
572 {
573 blowfish_ctx_t *blowfish_ctx;
574
575 ASSERT(ctx->cc_provider_private != NULL);
576 blowfish_ctx = ctx->cc_provider_private;
577
578 /*
579 * There must be no unprocessed ciphertext.
580 * This happens if the length of the last ciphertext is
581 * not a multiple of the BLOWFISH block length.
582 */
583 if (blowfish_ctx->bc_remainder_len > 0)
584 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
585
586 (void) blowfish_free_context(ctx);
587 data->cd_length = 0;
588
589 return (CRYPTO_SUCCESS);
590 }
591
592 /* ARGSUSED */
593 static int
594 blowfish_encrypt_atomic(crypto_provider_handle_t provider,
595 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
596 crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
597 crypto_spi_ctx_template_t template, crypto_req_handle_t req)
598 {
599 blowfish_ctx_t blowfish_ctx; /* on the stack */
600 off_t saved_offset;
601 size_t saved_length;
602 int ret;
603
604 BLOWFISH_ARG_INPLACE(plaintext, ciphertext);
605
606 /*
607 * Plaintext must be a multiple of blowfish block size.
608 * This test only works for non-padded mechanisms
755 if (ciphertext != plaintext)
756 plaintext->cd_length =
757 plaintext->cd_offset - saved_offset;
758 } else {
759 plaintext->cd_length = saved_length;
760 }
761 plaintext->cd_offset = saved_offset;
762
763 return (ret);
764 }
765
766 /*
767 * KCF software provider context template entry points.
768 */
769 /* ARGSUSED */
770 static int
771 blowfish_create_ctx_template(crypto_provider_handle_t provider,
772 crypto_mechanism_t *mechanism, crypto_key_t *key,
773 crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
774 {
775 void *keysched;
776 size_t size;
777 int rv;
778
779 if (!BLOWFISH_VALID_MECH(mechanism))
780 return (CRYPTO_MECHANISM_INVALID);
781
782 if ((keysched = blowfish_alloc_keysched(&size,
783 crypto_kmflag(req))) == NULL) {
784 return (CRYPTO_HOST_MEMORY);
785 }
786
787 /*
788 * Initialize key schedule. Key length information is stored
789 * in the key.
790 */
791 if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
792 bzero(keysched, size);
793 kmem_free(keysched, size);
794 return (rv);
795 }
796
797 *tmpl = keysched;
798 *tmpl_size = size;
799
800 return (CRYPTO_SUCCESS);
801 }
802
803 /* ARGSUSED */
804 static int
805 blowfish_free_context(crypto_ctx_t *ctx)
806 {
807 blowfish_ctx_t *blowfish_ctx = ctx->cc_provider_private;
808
809 if (blowfish_ctx != NULL) {
810 if (blowfish_ctx->bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
811 ASSERT(blowfish_ctx->bc_keysched_len != 0);
812 bzero(blowfish_ctx->bc_keysched,
813 blowfish_ctx->bc_keysched_len);
814 kmem_free(blowfish_ctx->bc_keysched,
815 blowfish_ctx->bc_keysched_len);
816 }
817 crypto_free_mode_ctx(blowfish_ctx);
818 ctx->cc_provider_private = NULL;
819 }
820
821 return (CRYPTO_SUCCESS);
822 }
823
824 /* ARGSUSED */
825 static int
826 blowfish_common_init_ctx(blowfish_ctx_t *blowfish_ctx,
827 crypto_spi_ctx_template_t *template, crypto_mechanism_t *mechanism,
828 crypto_key_t *key, int kmflag)
829 {
830 int rv = CRYPTO_SUCCESS;
831
832 void *keysched;
833 size_t size;
834
835 if (template == NULL) {
836 if ((keysched = blowfish_alloc_keysched(&size, kmflag)) == NULL)
837 return (CRYPTO_HOST_MEMORY);
838 /*
839 * Initialize key schedule.
840 * Key length is stored in the key.
841 */
842 if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS)
843 kmem_free(keysched, size);
844
845 blowfish_ctx->bc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
846 blowfish_ctx->bc_keysched_len = size;
847 } else {
848 keysched = template;
849 }
850 blowfish_ctx->bc_keysched = keysched;
851
852 switch (mechanism->cm_type) {
853 case BLOWFISH_CBC_MECH_INFO_TYPE:
854 rv = cbc_init_ctx((cbc_ctx_t *)blowfish_ctx,
855 mechanism->cm_param, mechanism->cm_param_len,
856 BLOWFISH_BLOCK_LEN, blowfish_copy_block64);
857 break;
858 case BLOWFISH_ECB_MECH_INFO_TYPE:
859 blowfish_ctx->bc_flags |= ECB_MODE;
860 }
861
862 if (rv != CRYPTO_SUCCESS) {
863 if (blowfish_ctx->bc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
864 bzero(keysched, size);
865 kmem_free(keysched, size);
866 }
867 }
868
869 return (rv);
870 }
|