Unleashed v1.4
[unleashed.git] / usr / src / uts / common / des / des_crypt.c
blob8a0719764573b035f3c6ae76f0c0dc351e0c9ab9
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * Portions of this source code were derived from Berkeley 4.3 BSD
32 * under license from the Regents of the University of California.
36 * des_crypt.c, DES encryption library routines
39 #include <sys/errno.h>
40 #include <sys/modctl.h>
42 #include <sys/systm.h>
43 #include <sys/cmn_err.h>
44 #include <sys/ddi.h>
45 #include <sys/crypto/common.h>
46 #include <sys/crypto/spi.h>
47 #include <sys/sysmacros.h>
48 #include <sys/strsun.h>
49 #include <sys/note.h>
50 #include <modes/modes.h>
51 #define _DES_IMPL
52 #include <des/des_impl.h>
54 #include <sys/types.h>
55 #include <rpc/des_crypt.h>
56 #include <des/des.h>
58 #ifdef sun_hardware
59 #include <sys/ioctl.h>
60 #ifdef _KERNEL
61 #include <sys/conf.h>
62 static int g_desfd = -1;
63 #define getdesfd() (cdevsw[11].d_open(0, 0) ? -1 : 0)
64 #define ioctl(a, b, c) (cdevsw[11].d_ioctl(0, b, c, 0) ? -1 : 0)
65 #else
66 #define getdesfd() (open("/dev/des", O_RDONLY, 0))
67 #endif /* _KERNEL */
68 #endif /* sun */
70 static int common_crypt(char *key, char *buf, size_t len,
71 unsigned int mode, struct desparams *desp);
73 extern int _des_crypt(char *buf, size_t len, struct desparams *desp);
75 extern struct mod_ops mod_cryptoops;
78 * Module linkage information for the kernel.
80 static struct modlmisc modlmisc = {
81 &mod_miscops,
82 "des encryption",
85 static struct modlcrypto modlcrypto = {
86 &mod_cryptoops,
87 "DES Kernel SW Provider"
90 static struct modlinkage modlinkage = {
91 MODREV_1,
92 &modlmisc,
93 &modlcrypto,
94 NULL
97 #define DES_MIN_KEY_LEN DES_MINBYTES
98 #define DES_MAX_KEY_LEN DES_MAXBYTES
99 #define DES3_MIN_KEY_LEN DES3_MAXBYTES /* no CKK_DES2 support */
100 #define DES3_MAX_KEY_LEN DES3_MAXBYTES
102 #ifndef DES_MIN_KEY_LEN
103 #define DES_MIN_KEY_LEN 0
104 #endif
106 #ifndef DES_MAX_KEY_LEN
107 #define DES_MAX_KEY_LEN 0
108 #endif
110 #ifndef DES3_MIN_KEY_LEN
111 #define DES3_MIN_KEY_LEN 0
112 #endif
114 #ifndef DES3_MAX_KEY_LEN
115 #define DES3_MAX_KEY_LEN 0
116 #endif
120 * Mechanism info structure passed to KCF during registration.
122 static crypto_mech_info_t des_mech_info_tab[] = {
123 /* DES_ECB */
124 {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
125 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
126 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
127 DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
128 /* DES_CBC */
129 {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
130 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
131 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
132 DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
133 /* DES3_ECB */
134 {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
135 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
136 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
137 DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
138 /* DES3_CBC */
139 {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
140 CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
141 CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
142 DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
145 /* operations are in-place if the output buffer is NULL */
146 #define DES_ARG_INPLACE(input, output) \
147 if ((output) == NULL) \
148 (output) = (input);
150 static void des_provider_status(crypto_provider_handle_t, uint_t *);
152 static crypto_control_ops_t des_control_ops = {
153 des_provider_status
156 static int
157 des_common_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
158 crypto_spi_ctx_template_t, crypto_req_handle_t);
159 static int des_common_init_ctx(des_ctx_t *, crypto_spi_ctx_template_t *,
160 crypto_mechanism_t *, crypto_key_t *, des_strength_t, int);
161 static int des_encrypt_final(crypto_ctx_t *, crypto_data_t *,
162 crypto_req_handle_t);
163 static int des_decrypt_final(crypto_ctx_t *, crypto_data_t *,
164 crypto_req_handle_t);
166 static int des_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
167 crypto_req_handle_t);
168 static int des_encrypt_update(crypto_ctx_t *, crypto_data_t *,
169 crypto_data_t *, crypto_req_handle_t);
170 static int des_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
171 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
172 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
174 static int des_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
175 crypto_req_handle_t);
176 static int des_decrypt_update(crypto_ctx_t *, crypto_data_t *,
177 crypto_data_t *, crypto_req_handle_t);
178 static int des_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
179 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
180 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
182 static crypto_cipher_ops_t des_cipher_ops = {
183 des_common_init,
184 des_encrypt,
185 des_encrypt_update,
186 des_encrypt_final,
187 des_encrypt_atomic,
188 des_common_init,
189 des_decrypt,
190 des_decrypt_update,
191 des_decrypt_final,
192 des_decrypt_atomic
195 static int des_create_ctx_template(crypto_provider_handle_t,
196 crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
197 size_t *, crypto_req_handle_t);
198 static int des_free_context(crypto_ctx_t *);
200 static crypto_ctx_ops_t des_ctx_ops = {
201 des_create_ctx_template,
202 des_free_context
205 static int des_key_check(crypto_provider_handle_t, crypto_mechanism_t *,
206 crypto_key_t *);
208 static crypto_key_ops_t des_key_ops = {
209 NULL,
210 NULL,
211 NULL,
212 NULL,
213 NULL,
214 des_key_check
217 static crypto_ops_t des_crypto_ops = {
218 &des_control_ops,
219 NULL,
220 &des_cipher_ops,
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 NULL,
226 NULL,
227 NULL,
228 NULL,
229 &des_key_ops,
230 NULL,
231 &des_ctx_ops,
232 NULL,
233 NULL,
234 NULL
237 static crypto_provider_info_t des_prov_info = {
238 CRYPTO_SPI_VERSION_4,
239 "DES Software Provider",
240 CRYPTO_SW_PROVIDER,
241 {&modlinkage},
242 NULL,
243 &des_crypto_ops,
244 sizeof (des_mech_info_tab)/sizeof (crypto_mech_info_t),
245 des_mech_info_tab
248 static crypto_kcf_provider_handle_t des_prov_handle = 0;
251 _init(void)
253 int ret;
255 if ((ret = mod_install(&modlinkage)) != 0)
256 return (ret);
259 * Register with KCF. If the registration fails, kcf will log an
260 * error but do not uninstall the module, since the functionality
261 * provided by misc/des should still be available.
264 (void) crypto_register_provider(&des_prov_info, &des_prov_handle);
266 return (0);
271 _info(struct modinfo *modinfop)
273 return (mod_info(&modlinkage, modinfop));
277 * Copy 8 bytes
279 #define COPY8(src, dst) { \
280 char *a = (char *)dst; \
281 char *b = (char *)src; \
282 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
283 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
287 * Copy multiple of 8 bytes
289 #define DESCOPY(src, dst, len) { \
290 char *a = (char *)dst; \
291 char *b = (char *)src; \
292 int i; \
293 for (i = (size_t)len; i > 0; i -= 8) { \
294 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
295 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
300 * CBC mode encryption
302 /* ARGSUSED */
304 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
306 int err = 0;
307 struct desparams dp;
309 dp.des_mode = CBC;
310 COPY8(ivec, dp.des_ivec);
311 err = common_crypt(key, buf, len, mode, &dp);
312 COPY8(dp.des_ivec, ivec);
313 return (err);
318 * ECB mode encryption
320 /* ARGSUSED */
322 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
324 int err = 0;
325 struct desparams dp;
327 dp.des_mode = ECB;
328 err = common_crypt(key, buf, len, mode, &dp);
329 return (err);
335 * Common code to cbc_crypt() & ecb_crypt()
337 static int
338 common_crypt(char *key, char *buf, size_t len, unsigned int mode,
339 struct desparams *desp)
341 int desdev;
343 if ((len % 8) != 0 || len > DES_MAXDATA)
344 return (DESERR_BADPARAM);
346 desp->des_dir =
347 ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
349 desdev = mode & DES_DEVMASK;
350 COPY8(key, desp->des_key);
352 #ifdef sun_hardware
353 if (desdev == DES_HW) {
354 int res;
356 if (g_desfd < 0 &&
357 (g_desfd == -1 || (g_desfd = getdesfd()) < 0))
358 goto software; /* no hardware device */
361 * hardware
363 desp->des_len = len;
364 if (len <= DES_QUICKLEN) {
365 DESCOPY(buf, desp->des_data, len);
366 res = ioctl(g_desfd, DESIOCQUICK, (char *)desp);
367 DESCOPY(desp->des_data, buf, len);
368 } else {
369 desp->des_buf = (uchar_t *)buf;
370 res = ioctl(g_desfd, DESIOCBLOCK, (char *)desp);
372 return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
374 software:
375 #endif
377 * software
379 if (!_des_crypt(buf, len, desp))
380 return (DESERR_HWERROR);
382 return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
386 * Initialize key schedules for DES and DES3
388 static int
389 init_keysched(crypto_key_t *key, void *newbie, des_strength_t strength)
391 uint8_t corrected_key[DES3_KEYSIZE];
394 * Only keys by value are supported by this module.
396 switch (key->ck_format) {
397 case CRYPTO_KEY_RAW:
398 if (strength == DES && key->ck_length != DES_MAXBITS)
399 return (CRYPTO_KEY_SIZE_RANGE);
400 if (strength == DES3 && key->ck_length != DES3_MAXBITS)
401 return (CRYPTO_KEY_SIZE_RANGE);
402 break;
403 default:
404 return (CRYPTO_KEY_TYPE_INCONSISTENT);
408 * Fix parity bits.
409 * Initialize key schedule even if key is weak.
411 if (key->ck_data == NULL)
412 return (CRYPTO_ARGUMENTS_BAD);
414 des_parity_fix(key->ck_data, strength, corrected_key);
415 des_init_keysched(corrected_key, strength, newbie);
416 return (CRYPTO_SUCCESS);
420 * KCF software provider control entry points.
422 /* ARGSUSED */
423 static void
424 des_provider_status(crypto_provider_handle_t provider, uint_t *status)
426 *status = CRYPTO_PROVIDER_READY;
430 * KCF software provider encrypt entry points.
432 static int
433 des_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
434 crypto_key_t *key, crypto_spi_ctx_template_t template,
435 crypto_req_handle_t req)
438 des_strength_t strength;
439 des_ctx_t *des_ctx = NULL;
440 int rv;
441 int kmflag;
444 * Only keys by value are supported by this module.
446 if (key->ck_format != CRYPTO_KEY_RAW) {
447 return (CRYPTO_KEY_TYPE_INCONSISTENT);
450 kmflag = crypto_kmflag(req);
451 /* Check mechanism type and parameter length */
452 switch (mechanism->cm_type) {
453 case DES_ECB_MECH_INFO_TYPE:
454 des_ctx = ecb_alloc_ctx(kmflag);
455 /* FALLTHRU */
456 case DES_CBC_MECH_INFO_TYPE:
457 if (mechanism->cm_param != NULL &&
458 mechanism->cm_param_len != DES_BLOCK_LEN)
459 return (CRYPTO_MECHANISM_PARAM_INVALID);
460 if (key->ck_length != DES_MAXBITS)
461 return (CRYPTO_KEY_SIZE_RANGE);
462 strength = DES;
463 if (des_ctx == NULL)
464 des_ctx = cbc_alloc_ctx(kmflag);
465 break;
466 case DES3_ECB_MECH_INFO_TYPE:
467 des_ctx = ecb_alloc_ctx(kmflag);
468 /* FALLTHRU */
469 case DES3_CBC_MECH_INFO_TYPE:
470 if (mechanism->cm_param != NULL &&
471 mechanism->cm_param_len != DES_BLOCK_LEN)
472 return (CRYPTO_MECHANISM_PARAM_INVALID);
473 if (key->ck_length != DES3_MAXBITS)
474 return (CRYPTO_KEY_SIZE_RANGE);
475 strength = DES3;
476 if (des_ctx == NULL)
477 des_ctx = cbc_alloc_ctx(kmflag);
478 break;
479 default:
480 return (CRYPTO_MECHANISM_INVALID);
483 if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
484 strength, kmflag)) != CRYPTO_SUCCESS) {
485 crypto_free_mode_ctx(des_ctx);
486 return (rv);
489 ctx->cc_provider_private = des_ctx;
491 return (CRYPTO_SUCCESS);
494 static void
495 des_copy_block64(uint8_t *in, uint64_t *out)
497 if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
498 /* LINTED: pointer alignment */
499 out[0] = *(uint64_t *)&in[0];
500 } else {
501 uint64_t tmp64;
503 #ifdef _BIG_ENDIAN
504 tmp64 = (((uint64_t)in[0] << 56) |
505 ((uint64_t)in[1] << 48) |
506 ((uint64_t)in[2] << 40) |
507 ((uint64_t)in[3] << 32) |
508 ((uint64_t)in[4] << 24) |
509 ((uint64_t)in[5] << 16) |
510 ((uint64_t)in[6] << 8) |
511 (uint64_t)in[7]);
512 #else
513 tmp64 = (((uint64_t)in[7] << 56) |
514 ((uint64_t)in[6] << 48) |
515 ((uint64_t)in[5] << 40) |
516 ((uint64_t)in[4] << 32) |
517 ((uint64_t)in[3] << 24) |
518 ((uint64_t)in[2] << 16) |
519 ((uint64_t)in[1] << 8) |
520 (uint64_t)in[0]);
521 #endif /* _BIG_ENDIAN */
523 out[0] = tmp64;
527 /* ARGSUSED */
528 static int
529 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
530 crypto_data_t *ciphertext, crypto_req_handle_t req)
532 int ret;
534 des_ctx_t *des_ctx;
537 * Plaintext must be a multiple of the block size.
538 * This test only works for non-padded mechanisms
539 * when blocksize is 2^N.
541 if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
542 return (CRYPTO_DATA_LEN_RANGE);
544 ASSERT(ctx->cc_provider_private != NULL);
545 des_ctx = ctx->cc_provider_private;
547 DES_ARG_INPLACE(plaintext, ciphertext);
550 * We need to just return the length needed to store the output.
551 * We should not destroy the context for the following case.
553 if (ciphertext->cd_length < plaintext->cd_length) {
554 ciphertext->cd_length = plaintext->cd_length;
555 return (CRYPTO_BUFFER_TOO_SMALL);
559 * Do an update on the specified input data.
561 ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
562 ASSERT(des_ctx->dc_remainder_len == 0);
563 (void) des_free_context(ctx);
565 /* LINTED */
566 return (ret);
569 /* ARGSUSED */
570 static int
571 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
572 crypto_data_t *plaintext, crypto_req_handle_t req)
574 int ret;
576 des_ctx_t *des_ctx;
579 * Ciphertext must be a multiple of the block size.
580 * This test only works for non-padded mechanisms
581 * when blocksize is 2^N.
583 if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
584 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
586 ASSERT(ctx->cc_provider_private != NULL);
587 des_ctx = ctx->cc_provider_private;
589 DES_ARG_INPLACE(ciphertext, plaintext);
592 * We need to just return the length needed to store the output.
593 * We should not destroy the context for the following case.
595 if (plaintext->cd_length < ciphertext->cd_length) {
596 plaintext->cd_length = ciphertext->cd_length;
597 return (CRYPTO_BUFFER_TOO_SMALL);
601 * Do an update on the specified input data.
603 ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
604 ASSERT(des_ctx->dc_remainder_len == 0);
605 (void) des_free_context(ctx);
607 /* LINTED */
608 return (ret);
611 /* ARGSUSED */
612 static int
613 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
614 crypto_data_t *ciphertext, crypto_req_handle_t req)
616 off_t saved_offset;
617 size_t saved_length, out_len;
618 int ret = CRYPTO_SUCCESS;
620 ASSERT(ctx->cc_provider_private != NULL);
622 DES_ARG_INPLACE(plaintext, ciphertext);
624 /* compute number of bytes that will hold the ciphertext */
625 out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
626 out_len += plaintext->cd_length;
627 out_len &= ~(DES_BLOCK_LEN - 1);
629 /* return length needed to store the output */
630 if (ciphertext->cd_length < out_len) {
631 ciphertext->cd_length = out_len;
632 return (CRYPTO_BUFFER_TOO_SMALL);
635 saved_offset = ciphertext->cd_offset;
636 saved_length = ciphertext->cd_length;
639 * Do the DES update on the specified input data.
641 switch (plaintext->cd_format) {
642 case CRYPTO_DATA_RAW:
643 ret = crypto_update_iov(ctx->cc_provider_private,
644 plaintext, ciphertext, des_encrypt_contiguous_blocks,
645 des_copy_block64);
646 break;
647 case CRYPTO_DATA_UIO:
648 ret = crypto_update_uio(ctx->cc_provider_private,
649 plaintext, ciphertext, des_encrypt_contiguous_blocks,
650 des_copy_block64);
651 break;
652 case CRYPTO_DATA_MBLK:
653 ret = crypto_update_mp(ctx->cc_provider_private,
654 plaintext, ciphertext, des_encrypt_contiguous_blocks,
655 des_copy_block64);
656 break;
657 default:
658 ret = CRYPTO_ARGUMENTS_BAD;
661 if (ret == CRYPTO_SUCCESS) {
662 if (plaintext != ciphertext)
663 ciphertext->cd_length =
664 ciphertext->cd_offset - saved_offset;
665 } else {
666 ciphertext->cd_length = saved_length;
668 ciphertext->cd_offset = saved_offset;
670 return (ret);
673 /* ARGSUSED */
674 static int
675 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
676 crypto_data_t *plaintext, crypto_req_handle_t req)
678 off_t saved_offset;
679 size_t saved_length, out_len;
680 int ret = CRYPTO_SUCCESS;
682 ASSERT(ctx->cc_provider_private != NULL);
684 DES_ARG_INPLACE(ciphertext, plaintext);
686 /* compute number of bytes that will hold the plaintext */
687 out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
688 out_len += ciphertext->cd_length;
689 out_len &= ~(DES_BLOCK_LEN - 1);
691 /* return length needed to store the output */
692 if (plaintext->cd_length < out_len) {
693 plaintext->cd_length = out_len;
694 return (CRYPTO_BUFFER_TOO_SMALL);
697 saved_offset = plaintext->cd_offset;
698 saved_length = plaintext->cd_length;
701 * Do the DES update on the specified input data.
703 switch (ciphertext->cd_format) {
704 case CRYPTO_DATA_RAW:
705 ret = crypto_update_iov(ctx->cc_provider_private,
706 ciphertext, plaintext, des_decrypt_contiguous_blocks,
707 des_copy_block64);
708 break;
709 case CRYPTO_DATA_UIO:
710 ret = crypto_update_uio(ctx->cc_provider_private,
711 ciphertext, plaintext, des_decrypt_contiguous_blocks,
712 des_copy_block64);
713 break;
714 case CRYPTO_DATA_MBLK:
715 ret = crypto_update_mp(ctx->cc_provider_private,
716 ciphertext, plaintext, des_decrypt_contiguous_blocks,
717 des_copy_block64);
718 break;
719 default:
720 ret = CRYPTO_ARGUMENTS_BAD;
723 if (ret == CRYPTO_SUCCESS) {
724 if (ciphertext != plaintext)
725 plaintext->cd_length =
726 plaintext->cd_offset - saved_offset;
727 } else {
728 plaintext->cd_length = saved_length;
730 plaintext->cd_offset = saved_offset;
732 return (ret);
735 /* ARGSUSED */
736 static int
737 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
738 crypto_req_handle_t req)
740 des_ctx_t *des_ctx;
742 ASSERT(ctx->cc_provider_private != NULL);
743 des_ctx = ctx->cc_provider_private;
746 * There must be no unprocessed plaintext.
747 * This happens if the length of the last data is
748 * not a multiple of the DES block length.
750 if (des_ctx->dc_remainder_len > 0)
751 return (CRYPTO_DATA_LEN_RANGE);
753 (void) des_free_context(ctx);
754 ciphertext->cd_length = 0;
756 return (CRYPTO_SUCCESS);
759 /* ARGSUSED */
760 static int
761 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
762 crypto_req_handle_t req)
764 des_ctx_t *des_ctx;
766 ASSERT(ctx->cc_provider_private != NULL);
767 des_ctx = ctx->cc_provider_private;
770 * There must be no unprocessed ciphertext.
771 * This happens if the length of the last ciphertext is
772 * not a multiple of the DES block length.
774 if (des_ctx->dc_remainder_len > 0)
775 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
777 (void) des_free_context(ctx);
778 plaintext->cd_length = 0;
780 return (CRYPTO_SUCCESS);
783 /* ARGSUSED */
784 static int
785 des_encrypt_atomic(crypto_provider_handle_t provider,
786 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
787 crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
788 crypto_spi_ctx_template_t template, crypto_req_handle_t req)
790 int ret;
792 des_ctx_t des_ctx; /* on the stack */
793 des_strength_t strength;
794 off_t saved_offset;
795 size_t saved_length;
797 DES_ARG_INPLACE(plaintext, ciphertext);
800 * Plaintext must be a multiple of the block size.
801 * This test only works for non-padded mechanisms
802 * when blocksize is 2^N.
804 if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
805 return (CRYPTO_DATA_LEN_RANGE);
807 /* return length needed to store the output */
808 if (ciphertext->cd_length < plaintext->cd_length) {
809 ciphertext->cd_length = plaintext->cd_length;
810 return (CRYPTO_BUFFER_TOO_SMALL);
813 /* Check mechanism type and parameter length */
814 switch (mechanism->cm_type) {
815 case DES_ECB_MECH_INFO_TYPE:
816 case DES_CBC_MECH_INFO_TYPE:
817 if (mechanism->cm_param_len > 0 &&
818 mechanism->cm_param_len != DES_BLOCK_LEN)
819 return (CRYPTO_MECHANISM_PARAM_INVALID);
820 if (key->ck_length != DES_MINBITS)
821 return (CRYPTO_KEY_SIZE_RANGE);
822 strength = DES;
823 break;
824 case DES3_ECB_MECH_INFO_TYPE:
825 case DES3_CBC_MECH_INFO_TYPE:
826 if (mechanism->cm_param_len > 0 &&
827 mechanism->cm_param_len != DES_BLOCK_LEN)
828 return (CRYPTO_MECHANISM_PARAM_INVALID);
829 if (key->ck_length != DES3_MAXBITS)
830 return (CRYPTO_KEY_SIZE_RANGE);
831 strength = DES3;
832 break;
833 default:
834 return (CRYPTO_MECHANISM_INVALID);
837 bzero(&des_ctx, sizeof (des_ctx_t));
839 if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
840 strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
841 return (ret);
844 saved_offset = ciphertext->cd_offset;
845 saved_length = ciphertext->cd_length;
848 * Do the update on the specified input data.
850 switch (plaintext->cd_format) {
851 case CRYPTO_DATA_RAW:
852 ret = crypto_update_iov(&des_ctx, plaintext, ciphertext,
853 des_encrypt_contiguous_blocks, des_copy_block64);
854 break;
855 case CRYPTO_DATA_UIO:
856 ret = crypto_update_uio(&des_ctx, plaintext, ciphertext,
857 des_encrypt_contiguous_blocks, des_copy_block64);
858 break;
859 case CRYPTO_DATA_MBLK:
860 ret = crypto_update_mp(&des_ctx, plaintext, ciphertext,
861 des_encrypt_contiguous_blocks, des_copy_block64);
862 break;
863 default:
864 ret = CRYPTO_ARGUMENTS_BAD;
867 if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
868 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
869 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
872 if (ret == CRYPTO_SUCCESS) {
873 ASSERT(des_ctx.dc_remainder_len == 0);
874 if (plaintext != ciphertext)
875 ciphertext->cd_length =
876 ciphertext->cd_offset - saved_offset;
877 } else {
878 ciphertext->cd_length = saved_length;
880 ciphertext->cd_offset = saved_offset;
882 /* LINTED */
883 return (ret);
886 /* ARGSUSED */
887 static int
888 des_decrypt_atomic(crypto_provider_handle_t provider,
889 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
890 crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
891 crypto_spi_ctx_template_t template, crypto_req_handle_t req)
893 int ret;
895 des_ctx_t des_ctx; /* on the stack */
896 des_strength_t strength;
897 off_t saved_offset;
898 size_t saved_length;
900 DES_ARG_INPLACE(ciphertext, plaintext);
903 * Ciphertext must be a multiple of the block size.
904 * This test only works for non-padded mechanisms
905 * when blocksize is 2^N.
907 if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
908 return (CRYPTO_DATA_LEN_RANGE);
910 /* return length needed to store the output */
911 if (plaintext->cd_length < ciphertext->cd_length) {
912 plaintext->cd_length = ciphertext->cd_length;
913 return (CRYPTO_BUFFER_TOO_SMALL);
916 /* Check mechanism type and parameter length */
917 switch (mechanism->cm_type) {
918 case DES_ECB_MECH_INFO_TYPE:
919 case DES_CBC_MECH_INFO_TYPE:
920 if (mechanism->cm_param_len > 0 &&
921 mechanism->cm_param_len != DES_BLOCK_LEN)
922 return (CRYPTO_MECHANISM_PARAM_INVALID);
923 if (key->ck_length != DES_MINBITS)
924 return (CRYPTO_KEY_SIZE_RANGE);
925 strength = DES;
926 break;
927 case DES3_ECB_MECH_INFO_TYPE:
928 case DES3_CBC_MECH_INFO_TYPE:
929 if (mechanism->cm_param_len > 0 &&
930 mechanism->cm_param_len != DES_BLOCK_LEN)
931 return (CRYPTO_MECHANISM_PARAM_INVALID);
932 if (key->ck_length != DES3_MAXBITS)
933 return (CRYPTO_KEY_SIZE_RANGE);
934 strength = DES3;
935 break;
936 default:
937 return (CRYPTO_MECHANISM_INVALID);
940 bzero(&des_ctx, sizeof (des_ctx_t));
942 if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
943 strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
944 return (ret);
947 saved_offset = plaintext->cd_offset;
948 saved_length = plaintext->cd_length;
951 * Do the update on the specified input data.
953 switch (ciphertext->cd_format) {
954 case CRYPTO_DATA_RAW:
955 ret = crypto_update_iov(&des_ctx, ciphertext, plaintext,
956 des_decrypt_contiguous_blocks, des_copy_block64);
957 break;
958 case CRYPTO_DATA_UIO:
959 ret = crypto_update_uio(&des_ctx, ciphertext, plaintext,
960 des_decrypt_contiguous_blocks, des_copy_block64);
961 break;
962 case CRYPTO_DATA_MBLK:
963 ret = crypto_update_mp(&des_ctx, ciphertext, plaintext,
964 des_decrypt_contiguous_blocks, des_copy_block64);
965 break;
966 default:
967 ret = CRYPTO_ARGUMENTS_BAD;
970 if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
971 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
972 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
975 if (ret == CRYPTO_SUCCESS) {
976 ASSERT(des_ctx.dc_remainder_len == 0);
977 if (ciphertext != plaintext)
978 plaintext->cd_length =
979 plaintext->cd_offset - saved_offset;
980 } else {
981 plaintext->cd_length = saved_length;
983 plaintext->cd_offset = saved_offset;
985 /* LINTED */
986 return (ret);
990 * KCF software provider context template entry points.
992 /* ARGSUSED */
993 static int
994 des_create_ctx_template(crypto_provider_handle_t provider,
995 crypto_mechanism_t *mechanism, crypto_key_t *key,
996 crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
999 des_strength_t strength;
1000 void *keysched;
1001 size_t size;
1002 int rv;
1004 switch (mechanism->cm_type) {
1005 case DES_ECB_MECH_INFO_TYPE:
1006 strength = DES;
1007 break;
1008 case DES_CBC_MECH_INFO_TYPE:
1009 strength = DES;
1010 break;
1011 case DES3_ECB_MECH_INFO_TYPE:
1012 strength = DES3;
1013 break;
1014 case DES3_CBC_MECH_INFO_TYPE:
1015 strength = DES3;
1016 break;
1017 default:
1018 return (CRYPTO_MECHANISM_INVALID);
1021 if ((keysched = des_alloc_keysched(&size, strength,
1022 crypto_kmflag(req))) == NULL) {
1023 return (CRYPTO_HOST_MEMORY);
1027 * Initialize key schedule. Key length information is stored
1028 * in the key.
1030 if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1031 bzero(keysched, size);
1032 kmem_free(keysched, size);
1033 return (rv);
1036 *tmpl = keysched;
1037 *tmpl_size = size;
1039 return (CRYPTO_SUCCESS);
1042 /* ARGSUSED */
1043 static int
1044 des_free_context(crypto_ctx_t *ctx)
1046 des_ctx_t *des_ctx = ctx->cc_provider_private;
1048 if (des_ctx != NULL) {
1049 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1050 ASSERT(des_ctx->dc_keysched_len != 0);
1051 bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1052 kmem_free(des_ctx->dc_keysched,
1053 des_ctx->dc_keysched_len);
1055 crypto_free_mode_ctx(des_ctx);
1056 ctx->cc_provider_private = NULL;
1059 return (CRYPTO_SUCCESS);
1063 * Pass it to des_keycheck() which will
1064 * fix it (parity bits), and check if the fixed key is weak.
1066 /* ARGSUSED */
1067 static int
1068 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1069 crypto_key_t *key)
1071 int expectedkeylen;
1072 des_strength_t strength;
1073 uint8_t keydata[DES3_MAX_KEY_LEN];
1075 if ((mech == NULL) || (key == NULL))
1076 return (CRYPTO_ARGUMENTS_BAD);
1078 switch (mech->cm_type) {
1079 case DES_ECB_MECH_INFO_TYPE:
1080 case DES_CBC_MECH_INFO_TYPE:
1081 expectedkeylen = DES_MINBITS;
1082 strength = DES;
1083 break;
1084 case DES3_ECB_MECH_INFO_TYPE:
1085 case DES3_CBC_MECH_INFO_TYPE:
1086 expectedkeylen = DES3_MAXBITS;
1087 strength = DES3;
1088 break;
1089 default:
1090 return (CRYPTO_MECHANISM_INVALID);
1093 if (key->ck_format != CRYPTO_KEY_RAW)
1094 return (CRYPTO_KEY_TYPE_INCONSISTENT);
1096 if (key->ck_length != expectedkeylen)
1097 return (CRYPTO_KEY_SIZE_RANGE);
1099 bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1101 if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1102 return (CRYPTO_WEAK_KEY);
1104 return (CRYPTO_SUCCESS);
1107 /* ARGSUSED */
1108 static int
1109 des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1110 crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1111 int kmflag)
1113 int rv = CRYPTO_SUCCESS;
1115 void *keysched;
1116 size_t size;
1118 if (template == NULL) {
1119 if ((keysched = des_alloc_keysched(&size, strength,
1120 kmflag)) == NULL)
1121 return (CRYPTO_HOST_MEMORY);
1123 * Initialize key schedule.
1124 * Key length is stored in the key.
1126 if ((rv = init_keysched(key, keysched,
1127 strength)) != CRYPTO_SUCCESS)
1128 kmem_free(keysched, size);
1130 des_ctx->dc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
1131 des_ctx->dc_keysched_len = size;
1132 } else {
1133 keysched = template;
1135 des_ctx->dc_keysched = keysched;
1137 if (strength == DES3) {
1138 des_ctx->dc_flags |= DES3_STRENGTH;
1141 switch (mechanism->cm_type) {
1142 case DES_CBC_MECH_INFO_TYPE:
1143 case DES3_CBC_MECH_INFO_TYPE:
1144 rv = cbc_init_ctx((cbc_ctx_t *)des_ctx, mechanism->cm_param,
1145 mechanism->cm_param_len, DES_BLOCK_LEN, des_copy_block64);
1146 break;
1147 case DES_ECB_MECH_INFO_TYPE:
1148 case DES3_ECB_MECH_INFO_TYPE:
1149 des_ctx->dc_flags |= ECB_MODE;
1152 if (rv != CRYPTO_SUCCESS) {
1153 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1154 bzero(keysched, size);
1155 kmem_free(keysched, size);
1159 return (rv);