xref: /titanic_50/usr/src/uts/common/des/des_crypt.c (revision 7c2fbfb345896881c631598ee3852ce9ce33fb07)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  *
21  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
22  * Use is subject to license terms.
23  */
24 
25 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
26 /*	  All Rights Reserved  	*/
27 
28 /*
29  * Portions of this source code were derived from Berkeley 4.3 BSD
30  * under license from the Regents of the University of California.
31  */
32 
33 #pragma ident	"%Z%%M%	%I%	%E% SMI"
34 
35 /*
36  * des_crypt.c, DES encryption library routines
37  */
38 
39 #include <sys/errno.h>
40 #include <sys/modctl.h>
41 
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 #include <des/des_impl.h>
52 
53 /* EXPORT DELETE START */
54 #include <sys/types.h>
55 #include <rpc/des_crypt.h>
56 #include <des/des.h>
57 
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", 0, 0))
67 #endif	/* _KERNEL */
68 #endif	/* sun */
69 
70 static int common_crypt(char *key, char *buf, size_t len,
71     unsigned int mode, struct desparams *desp);
72 
73 extern int _des_crypt(char *buf, size_t len, struct desparams *desp);
74 
75 /* EXPORT DELETE END */
76 
77 extern struct mod_ops mod_cryptoops;
78 
79 /*
80  * Module linkage information for the kernel.
81  */
82 static struct modlmisc modlmisc = {
83 	&mod_miscops,
84 	"des encryption",
85 };
86 
87 static struct modlcrypto modlcrypto = {
88 	&mod_cryptoops,
89 	"DES Kernel SW Provider"
90 };
91 
92 static struct modlinkage modlinkage = {
93 	MODREV_1,
94 	&modlmisc,
95 	&modlcrypto,
96 	NULL
97 };
98 
99 /*
100  * CSPI information (entry points, provider info, etc.)
101  */
102 typedef enum des_mech_type {
103 	DES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_DES_ECB */
104 	DES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_DES_CBC */
105 	DES_CFB_MECH_INFO_TYPE,		/* SUN_CKM_DES_CFB */
106 	DES3_ECB_MECH_INFO_TYPE,	/* SUN_CKM_DES3_ECB */
107 	DES3_CBC_MECH_INFO_TYPE,	/* SUN_CKM_DES3_CBC */
108 	DES3_CFB_MECH_INFO_TYPE		/* SUN_CKM_DES3_CFB */
109 } des_mech_type_t;
110 
111 /* EXPORT DELETE START */
112 
113 #define	DES_MIN_KEY_LEN		DES_MINBYTES
114 #define	DES_MAX_KEY_LEN		DES_MAXBYTES
115 #define	DES3_MIN_KEY_LEN	DES3_MINBYTES
116 #define	DES3_MAX_KEY_LEN	DES3_MAXBYTES
117 
118 /* EXPORT DELETE END */
119 
120 #ifndef DES_MIN_KEY_LEN
121 #define	DES_MIN_KEY_LEN		0
122 #endif
123 
124 #ifndef DES_MAX_KEY_LEN
125 #define	DES_MAX_KEY_LEN		0
126 #endif
127 
128 #ifndef DES3_MIN_KEY_LEN
129 #define	DES3_MIN_KEY_LEN	0
130 #endif
131 
132 #ifndef DES3_MAX_KEY_LEN
133 #define	DES3_MAX_KEY_LEN	0
134 #endif
135 
136 /*
137  * Mechanism info structure passed to KCF during registration.
138  */
139 static crypto_mech_info_t des_mech_info_tab[] = {
140 	/* DES_ECB */
141 	{SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
142 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
143 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
144 	    DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
145 	/* DES_CBC */
146 	{SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
147 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
148 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
149 	    DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
150 	/* DES3_ECB */
151 	{SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
152 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
153 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
154 	    DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
155 	/* DES3_CBC */
156 	{SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
157 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
158 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
159 	    DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
160 };
161 
162 /* operations are in-place if the output buffer is NULL */
163 #define	DES_ARG_INPLACE(input, output)				\
164 	if ((output) == NULL)					\
165 		(output) = (input);
166 
167 static void des_provider_status(crypto_provider_handle_t, uint_t *);
168 
169 static crypto_control_ops_t des_control_ops = {
170 	des_provider_status
171 };
172 
173 static int
174 des_common_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
175     crypto_spi_ctx_template_t, crypto_req_handle_t);
176 static int des_common_init_ctx(des_ctx_t *, crypto_spi_ctx_template_t *,
177     crypto_mechanism_t *, crypto_key_t *, des_strength_t, int);
178 static int des_encrypt_final(crypto_ctx_t *, crypto_data_t *,
179     crypto_req_handle_t);
180 static int des_decrypt_final(crypto_ctx_t *, crypto_data_t *,
181     crypto_req_handle_t);
182 
183 static int des_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
184     crypto_req_handle_t);
185 static int des_encrypt_update(crypto_ctx_t *, crypto_data_t *,
186     crypto_data_t *, crypto_req_handle_t);
187 static int des_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
188     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
189     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
190 
191 static int des_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
192     crypto_req_handle_t);
193 static int des_decrypt_update(crypto_ctx_t *, crypto_data_t *,
194     crypto_data_t *, crypto_req_handle_t);
195 static int des_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
196     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
197     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
198 
199 static crypto_cipher_ops_t des_cipher_ops = {
200 	des_common_init,
201 	des_encrypt,
202 	des_encrypt_update,
203 	des_encrypt_final,
204 	des_encrypt_atomic,
205 	des_common_init,
206 	des_decrypt,
207 	des_decrypt_update,
208 	des_decrypt_final,
209 	des_decrypt_atomic
210 };
211 
212 static int des_create_ctx_template(crypto_provider_handle_t,
213     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
214     size_t *, crypto_req_handle_t);
215 static int des_free_context(crypto_ctx_t *);
216 
217 static crypto_ctx_ops_t des_ctx_ops = {
218 	des_create_ctx_template,
219 	des_free_context
220 };
221 
222 static int des_key_check(crypto_provider_handle_t, crypto_mechanism_t *,
223     crypto_key_t *);
224 
225 static crypto_key_ops_t des_key_ops = {
226 	NULL,
227 	NULL,
228 	NULL,
229 	NULL,
230 	NULL,
231 	des_key_check
232 };
233 
234 static crypto_ops_t des_crypto_ops = {
235 	&des_control_ops,
236 	NULL,
237 	&des_cipher_ops,
238 	NULL,
239 	NULL,
240 	NULL,
241 	NULL,
242 	NULL,
243 	NULL,
244 	NULL,
245 	NULL,
246 	&des_key_ops,
247 	NULL,
248 	&des_ctx_ops
249 };
250 
251 static crypto_provider_info_t des_prov_info = {
252 	CRYPTO_SPI_VERSION_1,
253 	"DES Software Provider",
254 	CRYPTO_SW_PROVIDER,
255 	{&modlinkage},
256 	NULL,
257 	&des_crypto_ops,
258 	sizeof (des_mech_info_tab)/sizeof (crypto_mech_info_t),
259 	des_mech_info_tab
260 };
261 
262 static crypto_kcf_provider_handle_t des_prov_handle = NULL;
263 
264 int
265 _init(void)
266 {
267 	int ret;
268 
269 	if ((ret = mod_install(&modlinkage)) != 0)
270 		return (ret);
271 
272 	/*
273 	 * Register with KCF. If the registration fails, log an
274 	 * error but do not uninstall the module, since the functionality
275 	 * provided by misc/des should still be available.
276 	 */
277 	if ((ret = crypto_register_provider(&des_prov_info,
278 	    &des_prov_handle)) != CRYPTO_SUCCESS) {
279 		cmn_err(CE_WARN, "des _init: crypto_register_provider() "
280 		    "failed (0x%x)", ret);
281 	}
282 
283 	return (0);
284 }
285 
286 
287 int
288 _info(struct modinfo *modinfop)
289 {
290 	return (mod_info(&modlinkage, modinfop));
291 }
292 
293 /*
294  * Copy 8 bytes
295  */
296 #define	COPY8(src, dst) { \
297 	char *a = (char *)dst; \
298 	char *b = (char *)src; \
299 	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
300 	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
301 }
302 
303 /*
304  * Copy multiple of 8 bytes
305  */
306 #define	DESCOPY(src, dst, len) { \
307 	char *a = (char *)dst; \
308 	char *b = (char *)src; \
309 	int i; \
310 	for (i = (size_t)len; i > 0; i -= 8) { \
311 		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
312 		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
313 	} \
314 }
315 
316 /*
317  * CBC mode encryption
318  */
319 /* ARGSUSED */
320 int
321 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
322 {
323 	int err = 0;
324 /* EXPORT DELETE START */
325 	struct desparams dp;
326 
327 	dp.des_mode = CBC;
328 	COPY8(ivec, dp.des_ivec);
329 	err = common_crypt(key, buf, len, mode, &dp);
330 	COPY8(dp.des_ivec, ivec);
331 /* EXPORT DELETE END */
332 	return (err);
333 }
334 
335 
336 /*
337  * ECB mode encryption
338  */
339 /* ARGSUSED */
340 int
341 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
342 {
343 	int err = 0;
344 /* EXPORT DELETE START */
345 	struct desparams dp;
346 
347 	dp.des_mode = ECB;
348 	err = common_crypt(key, buf, len, mode, &dp);
349 /* EXPORT DELETE END */
350 	return (err);
351 }
352 
353 
354 
355 /* EXPORT DELETE START */
356 /*
357  * Common code to cbc_crypt() & ecb_crypt()
358  */
359 static int
360 common_crypt(char *key, char *buf, size_t len, unsigned int mode,
361     struct desparams *desp)
362 {
363 	int desdev;
364 
365 	if ((len % 8) != 0 || len > DES_MAXDATA)
366 		return (DESERR_BADPARAM);
367 
368 	desp->des_dir =
369 	    ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
370 
371 	desdev = mode & DES_DEVMASK;
372 	COPY8(key, desp->des_key);
373 
374 #ifdef sun_hardware
375 	if (desdev == DES_HW) {
376 		int res;
377 
378 		if (g_desfd < 0 &&
379 		    (g_desfd == -1 || (g_desfd = getdesfd()) < 0))
380 				goto software;	/* no hardware device */
381 
382 		/*
383 		 * hardware
384 		 */
385 		desp->des_len = len;
386 		if (len <= DES_QUICKLEN) {
387 			DESCOPY(buf, desp->des_data, len);
388 			res = ioctl(g_desfd, DESIOCQUICK, (char *)desp);
389 			DESCOPY(desp->des_data, buf, len);
390 		} else {
391 			desp->des_buf = (uchar_t *)buf;
392 			res = ioctl(g_desfd, DESIOCBLOCK, (char *)desp);
393 		}
394 		return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
395 	}
396 software:
397 #endif
398 	/*
399 	 * software
400 	 */
401 	if (!_des_crypt(buf, len, desp))
402 		return (DESERR_HWERROR);
403 
404 	return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
405 }
406 
407 /*
408  * Initialize key schedules for DES and DES3
409  */
410 static int
411 init_keysched(crypto_key_t *key, void *newbie, des_strength_t strength)
412 {
413 	uint8_t corrected_key[DES3_KEYSIZE];
414 
415 	/*
416 	 * Only keys by value are supported by this module.
417 	 */
418 	switch (key->ck_format) {
419 	case CRYPTO_KEY_RAW:
420 		if (strength == DES && key->ck_length != DES_MINBITS)
421 			return (CRYPTO_KEY_SIZE_RANGE);
422 		if (strength == DES3 && key->ck_length != DES3_MINBITS)
423 			return (CRYPTO_KEY_SIZE_RANGE);
424 		break;
425 	default:
426 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
427 	}
428 
429 	/*
430 	 * Fix parity bits.
431 	 * Initialize key schedule even if key is weak.
432 	 */
433 	if (key->ck_data == NULL)
434 		return (CRYPTO_ARGUMENTS_BAD);
435 
436 	des_parity_fix(key->ck_data, strength, corrected_key);
437 	des_init_keysched(corrected_key, strength, newbie);
438 	return (CRYPTO_SUCCESS);
439 }
440 
441 /* EXPORT DELETE END */
442 
443 /*
444  * KCF software provider control entry points.
445  */
446 /* ARGSUSED */
447 static void
448 des_provider_status(crypto_provider_handle_t provider, uint_t *status)
449 {
450 	*status = CRYPTO_PROVIDER_READY;
451 }
452 
453 /*
454  * KCF software provider encrypt entry points.
455  */
456 static int
457 des_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
458     crypto_key_t *key, crypto_spi_ctx_template_t template,
459     crypto_req_handle_t req)
460 {
461 
462 /* EXPORT DELETE START */
463 
464 	des_strength_t strength;
465 	des_ctx_t *des_ctx = NULL;
466 	int rv;
467 	int kmflag;
468 
469 	/*
470 	 * Only keys by value are supported by this module.
471 	 */
472 	if (key->ck_format != CRYPTO_KEY_RAW) {
473 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
474 	}
475 
476 	kmflag = crypto_kmflag(req);
477 	/* Check mechanism type and parameter length */
478 	switch (mechanism->cm_type) {
479 	case DES_ECB_MECH_INFO_TYPE:
480 		des_ctx = ecb_alloc_ctx(kmflag);
481 		/* FALLTHRU */
482 	case DES_CBC_MECH_INFO_TYPE:
483 		if (mechanism->cm_param != NULL &&
484 		    mechanism->cm_param_len != DES_BLOCK_LEN)
485 			return (CRYPTO_MECHANISM_PARAM_INVALID);
486 		if (key->ck_length != DES_MINBITS)
487 			return (CRYPTO_KEY_SIZE_RANGE);
488 		strength = DES;
489 		if (des_ctx == NULL)
490 			des_ctx = cbc_alloc_ctx(kmflag);
491 		break;
492 	case DES3_ECB_MECH_INFO_TYPE:
493 		des_ctx = ecb_alloc_ctx(kmflag);
494 		/* FALLTHRU */
495 	case DES3_CBC_MECH_INFO_TYPE:
496 		if (mechanism->cm_param != NULL &&
497 		    mechanism->cm_param_len != DES_BLOCK_LEN)
498 			return (CRYPTO_MECHANISM_PARAM_INVALID);
499 		if (key->ck_length != DES3_MINBITS)
500 			return (CRYPTO_KEY_SIZE_RANGE);
501 		strength = DES3;
502 		if (des_ctx == NULL)
503 			des_ctx = cbc_alloc_ctx(kmflag);
504 		break;
505 	default:
506 		return (CRYPTO_MECHANISM_INVALID);
507 	}
508 
509 	if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
510 	    strength, kmflag)) != CRYPTO_SUCCESS) {
511 		crypto_free_mode_ctx(des_ctx);
512 		return (rv);
513 	}
514 
515 	ctx->cc_provider_private = des_ctx;
516 
517 /* EXPORT DELETE END */
518 
519 	return (CRYPTO_SUCCESS);
520 }
521 
522 static void
523 des_copy_block64(uint8_t *in, uint64_t *out)
524 {
525 	if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
526 		/* LINTED: pointer alignment */
527 		out[0] = *(uint64_t *)&in[0];
528 	} else {
529 		uint64_t tmp64;
530 
531 #ifdef _BIG_ENDIAN
532 		tmp64 = (((uint64_t)in[0] << 56) |
533 		    ((uint64_t)in[1] << 48) |
534 		    ((uint64_t)in[2] << 40) |
535 		    ((uint64_t)in[3] << 32) |
536 		    ((uint64_t)in[4] << 24) |
537 		    ((uint64_t)in[5] << 16) |
538 		    ((uint64_t)in[6] << 8) |
539 		    (uint64_t)in[7]);
540 #else
541 		tmp64 = (((uint64_t)in[7] << 56) |
542 		    ((uint64_t)in[6] << 48) |
543 		    ((uint64_t)in[5] << 40) |
544 		    ((uint64_t)in[4] << 32) |
545 		    ((uint64_t)in[3] << 24) |
546 		    ((uint64_t)in[2] << 16) |
547 		    ((uint64_t)in[1] << 8) |
548 		    (uint64_t)in[0]);
549 #endif /* _BIG_ENDIAN */
550 
551 		out[0] = tmp64;
552 	}
553 }
554 
555 /* ARGSUSED */
556 static int
557 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
558     crypto_data_t *ciphertext, crypto_req_handle_t req)
559 {
560 	int ret;
561 
562 /* EXPORT DELETE START */
563 	des_ctx_t *des_ctx;
564 
565 	/*
566 	 * Plaintext must be a multiple of the block size.
567 	 * This test only works for non-padded mechanisms
568 	 * when blocksize is 2^N.
569 	 */
570 	if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
571 		return (CRYPTO_DATA_LEN_RANGE);
572 
573 	ASSERT(ctx->cc_provider_private != NULL);
574 	des_ctx = ctx->cc_provider_private;
575 
576 	DES_ARG_INPLACE(plaintext, ciphertext);
577 
578 	/*
579 	 * We need to just return the length needed to store the output.
580 	 * We should not destroy the context for the following case.
581 	 */
582 	if (ciphertext->cd_length < plaintext->cd_length) {
583 		ciphertext->cd_length = plaintext->cd_length;
584 		return (CRYPTO_BUFFER_TOO_SMALL);
585 	}
586 
587 	/*
588 	 * Do an update on the specified input data.
589 	 */
590 	ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
591 	ASSERT(des_ctx->dc_remainder_len == 0);
592 	(void) des_free_context(ctx);
593 
594 /* EXPORT DELETE END */
595 
596 	/* LINTED */
597 	return (ret);
598 }
599 
600 /* ARGSUSED */
601 static int
602 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
603     crypto_data_t *plaintext, crypto_req_handle_t req)
604 {
605 	int ret;
606 
607 /* EXPORT DELETE START */
608 	des_ctx_t *des_ctx;
609 
610 	/*
611 	 * Ciphertext must be a multiple of the block size.
612 	 * This test only works for non-padded mechanisms
613 	 * when blocksize is 2^N.
614 	 */
615 	if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
616 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
617 
618 	ASSERT(ctx->cc_provider_private != NULL);
619 	des_ctx = ctx->cc_provider_private;
620 
621 	DES_ARG_INPLACE(ciphertext, plaintext);
622 
623 	/*
624 	 * We need to just return the length needed to store the output.
625 	 * We should not destroy the context for the following case.
626 	 */
627 	if (plaintext->cd_length < ciphertext->cd_length) {
628 		plaintext->cd_length = ciphertext->cd_length;
629 		return (CRYPTO_BUFFER_TOO_SMALL);
630 	}
631 
632 	/*
633 	 * Do an update on the specified input data.
634 	 */
635 	ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
636 	ASSERT(des_ctx->dc_remainder_len == 0);
637 	(void) des_free_context(ctx);
638 
639 /* EXPORT DELETE END */
640 
641 	/* LINTED */
642 	return (ret);
643 }
644 
645 /* ARGSUSED */
646 static int
647 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
648     crypto_data_t *ciphertext, crypto_req_handle_t req)
649 {
650 	off_t saved_offset;
651 	size_t saved_length, out_len;
652 	int ret = CRYPTO_SUCCESS;
653 
654 /* EXPORT DELETE START */
655 
656 	ASSERT(ctx->cc_provider_private != NULL);
657 
658 	DES_ARG_INPLACE(plaintext, ciphertext);
659 
660 	/* compute number of bytes that will hold the ciphertext */
661 	out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
662 	out_len += plaintext->cd_length;
663 	out_len &= ~(DES_BLOCK_LEN - 1);
664 
665 	/* return length needed to store the output */
666 	if (ciphertext->cd_length < out_len) {
667 		ciphertext->cd_length = out_len;
668 		return (CRYPTO_BUFFER_TOO_SMALL);
669 	}
670 
671 	saved_offset = ciphertext->cd_offset;
672 	saved_length = ciphertext->cd_length;
673 
674 	/*
675 	 * Do the DES update on the specified input data.
676 	 */
677 	switch (plaintext->cd_format) {
678 	case CRYPTO_DATA_RAW:
679 		ret = crypto_update_iov(ctx->cc_provider_private,
680 		    plaintext, ciphertext, des_encrypt_contiguous_blocks,
681 		    des_copy_block64);
682 		break;
683 	case CRYPTO_DATA_UIO:
684 		ret = crypto_update_uio(ctx->cc_provider_private,
685 		    plaintext, ciphertext, des_encrypt_contiguous_blocks,
686 		    des_copy_block64);
687 		break;
688 	case CRYPTO_DATA_MBLK:
689 		ret = crypto_update_mp(ctx->cc_provider_private,
690 		    plaintext, ciphertext, des_encrypt_contiguous_blocks,
691 		    des_copy_block64);
692 		break;
693 	default:
694 		ret = CRYPTO_ARGUMENTS_BAD;
695 	}
696 
697 	if (ret == CRYPTO_SUCCESS) {
698 		if (plaintext != ciphertext)
699 			ciphertext->cd_length =
700 			    ciphertext->cd_offset - saved_offset;
701 	} else {
702 		ciphertext->cd_length = saved_length;
703 	}
704 	ciphertext->cd_offset = saved_offset;
705 
706 /* EXPORT DELETE END */
707 
708 	return (ret);
709 }
710 
711 /* ARGSUSED */
712 static int
713 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
714     crypto_data_t *plaintext, crypto_req_handle_t req)
715 {
716 	off_t saved_offset;
717 	size_t saved_length, out_len;
718 	int ret = CRYPTO_SUCCESS;
719 
720 /* EXPORT DELETE START */
721 
722 	ASSERT(ctx->cc_provider_private != NULL);
723 
724 	DES_ARG_INPLACE(ciphertext, plaintext);
725 
726 	/* compute number of bytes that will hold the plaintext */
727 	out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
728 	out_len += ciphertext->cd_length;
729 	out_len &= ~(DES_BLOCK_LEN - 1);
730 
731 	/* return length needed to store the output */
732 	if (plaintext->cd_length < out_len) {
733 		plaintext->cd_length = out_len;
734 		return (CRYPTO_BUFFER_TOO_SMALL);
735 	}
736 
737 	saved_offset = plaintext->cd_offset;
738 	saved_length = plaintext->cd_length;
739 
740 	/*
741 	 * Do the DES update on the specified input data.
742 	 */
743 	switch (ciphertext->cd_format) {
744 	case CRYPTO_DATA_RAW:
745 		ret = crypto_update_iov(ctx->cc_provider_private,
746 		    ciphertext, plaintext, des_decrypt_contiguous_blocks,
747 		    des_copy_block64);
748 		break;
749 	case CRYPTO_DATA_UIO:
750 		ret = crypto_update_uio(ctx->cc_provider_private,
751 		    ciphertext, plaintext, des_decrypt_contiguous_blocks,
752 		    des_copy_block64);
753 		break;
754 	case CRYPTO_DATA_MBLK:
755 		ret = crypto_update_mp(ctx->cc_provider_private,
756 		    ciphertext, plaintext, des_decrypt_contiguous_blocks,
757 		    des_copy_block64);
758 		break;
759 	default:
760 		ret = CRYPTO_ARGUMENTS_BAD;
761 	}
762 
763 	if (ret == CRYPTO_SUCCESS) {
764 		if (ciphertext != plaintext)
765 			plaintext->cd_length =
766 			    plaintext->cd_offset - saved_offset;
767 	} else {
768 		plaintext->cd_length = saved_length;
769 	}
770 	plaintext->cd_offset = saved_offset;
771 
772 /* EXPORT DELETE END */
773 
774 	return (ret);
775 }
776 
777 /* ARGSUSED */
778 static int
779 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
780     crypto_req_handle_t req)
781 {
782 
783 /* EXPORT DELETE START */
784 
785 	des_ctx_t *des_ctx;
786 
787 	ASSERT(ctx->cc_provider_private != NULL);
788 	des_ctx = ctx->cc_provider_private;
789 
790 	/*
791 	 * There must be no unprocessed plaintext.
792 	 * This happens if the length of the last data is
793 	 * not a multiple of the DES block length.
794 	 */
795 	if (des_ctx->dc_remainder_len > 0)
796 		return (CRYPTO_DATA_LEN_RANGE);
797 
798 	(void) des_free_context(ctx);
799 	ciphertext->cd_length = 0;
800 
801 /* EXPORT DELETE END */
802 
803 	return (CRYPTO_SUCCESS);
804 }
805 
806 /* ARGSUSED */
807 static int
808 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
809     crypto_req_handle_t req)
810 {
811 
812 /* EXPORT DELETE START */
813 
814 	des_ctx_t *des_ctx;
815 
816 	ASSERT(ctx->cc_provider_private != NULL);
817 	des_ctx = ctx->cc_provider_private;
818 
819 	/*
820 	 * There must be no unprocessed ciphertext.
821 	 * This happens if the length of the last ciphertext is
822 	 * not a multiple of the DES block length.
823 	 */
824 	if (des_ctx->dc_remainder_len > 0)
825 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
826 
827 	(void) des_free_context(ctx);
828 	plaintext->cd_length = 0;
829 
830 /* EXPORT DELETE END */
831 
832 	return (CRYPTO_SUCCESS);
833 }
834 
835 /* ARGSUSED */
836 static int
837 des_encrypt_atomic(crypto_provider_handle_t provider,
838     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
839     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
840     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
841 {
842 	int ret;
843 
844 /* EXPORT DELETE START */
845 
846 	des_ctx_t des_ctx;		/* on the stack */
847 	des_strength_t strength;
848 	off_t saved_offset;
849 	size_t saved_length;
850 
851 	DES_ARG_INPLACE(plaintext, ciphertext);
852 
853 	/*
854 	 * Plaintext must be a multiple of the block size.
855 	 * This test only works for non-padded mechanisms
856 	 * when blocksize is 2^N.
857 	 */
858 	if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
859 		return (CRYPTO_DATA_LEN_RANGE);
860 
861 	/* return length needed to store the output */
862 	if (ciphertext->cd_length < plaintext->cd_length) {
863 		ciphertext->cd_length = plaintext->cd_length;
864 		return (CRYPTO_BUFFER_TOO_SMALL);
865 	}
866 
867 	/* Check mechanism type and parameter length */
868 	switch (mechanism->cm_type) {
869 	case DES_ECB_MECH_INFO_TYPE:
870 	case DES_CBC_MECH_INFO_TYPE:
871 		if (mechanism->cm_param_len > 0 &&
872 		    mechanism->cm_param_len != DES_BLOCK_LEN)
873 			return (CRYPTO_MECHANISM_PARAM_INVALID);
874 		if (key->ck_length != DES_MINBITS)
875 			return (CRYPTO_KEY_SIZE_RANGE);
876 		strength = DES;
877 		break;
878 	case DES3_ECB_MECH_INFO_TYPE:
879 	case DES3_CBC_MECH_INFO_TYPE:
880 		if (mechanism->cm_param_len > 0 &&
881 		    mechanism->cm_param_len != DES_BLOCK_LEN)
882 			return (CRYPTO_MECHANISM_PARAM_INVALID);
883 		if (key->ck_length != DES3_MINBITS)
884 			return (CRYPTO_KEY_SIZE_RANGE);
885 		strength = DES3;
886 		break;
887 	default:
888 		return (CRYPTO_MECHANISM_INVALID);
889 	}
890 
891 	bzero(&des_ctx, sizeof (des_ctx_t));
892 
893 	if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
894 	    strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
895 		return (ret);
896 	}
897 
898 	saved_offset = ciphertext->cd_offset;
899 	saved_length = ciphertext->cd_length;
900 
901 	/*
902 	 * Do the update on the specified input data.
903 	 */
904 	switch (plaintext->cd_format) {
905 	case CRYPTO_DATA_RAW:
906 		ret = crypto_update_iov(&des_ctx, plaintext, ciphertext,
907 		    des_encrypt_contiguous_blocks, des_copy_block64);
908 		break;
909 	case CRYPTO_DATA_UIO:
910 		ret = crypto_update_uio(&des_ctx, plaintext, ciphertext,
911 		    des_encrypt_contiguous_blocks, des_copy_block64);
912 		break;
913 	case CRYPTO_DATA_MBLK:
914 		ret = crypto_update_mp(&des_ctx, plaintext, ciphertext,
915 		    des_encrypt_contiguous_blocks, des_copy_block64);
916 		break;
917 	default:
918 		ret = CRYPTO_ARGUMENTS_BAD;
919 	}
920 
921 	if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
922 		bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
923 		kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
924 	}
925 
926 	if (ret == CRYPTO_SUCCESS) {
927 		ASSERT(des_ctx.dc_remainder_len == 0);
928 		if (plaintext != ciphertext)
929 			ciphertext->cd_length =
930 			    ciphertext->cd_offset - saved_offset;
931 	} else {
932 		ciphertext->cd_length = saved_length;
933 	}
934 	ciphertext->cd_offset = saved_offset;
935 
936 /* EXPORT DELETE END */
937 
938 	/* LINTED */
939 	return (ret);
940 }
941 
942 /* ARGSUSED */
943 static int
944 des_decrypt_atomic(crypto_provider_handle_t provider,
945     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
946     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
947     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
948 {
949 	int ret;
950 
951 /* EXPORT DELETE START */
952 
953 	des_ctx_t des_ctx;	/* on the stack */
954 	des_strength_t strength;
955 	off_t saved_offset;
956 	size_t saved_length;
957 
958 	DES_ARG_INPLACE(ciphertext, plaintext);
959 
960 	/*
961 	 * Ciphertext must be a multiple of the block size.
962 	 * This test only works for non-padded mechanisms
963 	 * when blocksize is 2^N.
964 	 */
965 	if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
966 		return (CRYPTO_DATA_LEN_RANGE);
967 
968 	/* return length needed to store the output */
969 	if (plaintext->cd_length < ciphertext->cd_length) {
970 		plaintext->cd_length = ciphertext->cd_length;
971 		return (CRYPTO_BUFFER_TOO_SMALL);
972 	}
973 
974 	/* Check mechanism type and parameter length */
975 	switch (mechanism->cm_type) {
976 	case DES_ECB_MECH_INFO_TYPE:
977 	case DES_CBC_MECH_INFO_TYPE:
978 		if (mechanism->cm_param_len > 0 &&
979 		    mechanism->cm_param_len != DES_BLOCK_LEN)
980 			return (CRYPTO_MECHANISM_PARAM_INVALID);
981 		if (key->ck_length != DES_MINBITS)
982 			return (CRYPTO_KEY_SIZE_RANGE);
983 		strength = DES;
984 		break;
985 	case DES3_ECB_MECH_INFO_TYPE:
986 	case DES3_CBC_MECH_INFO_TYPE:
987 		if (mechanism->cm_param_len > 0 &&
988 		    mechanism->cm_param_len != DES_BLOCK_LEN)
989 			return (CRYPTO_MECHANISM_PARAM_INVALID);
990 		if (key->ck_length != DES3_MINBITS)
991 			return (CRYPTO_KEY_SIZE_RANGE);
992 		strength = DES3;
993 		break;
994 	default:
995 		return (CRYPTO_MECHANISM_INVALID);
996 	}
997 
998 	bzero(&des_ctx, sizeof (des_ctx_t));
999 
1000 	if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
1001 	    strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
1002 		return (ret);
1003 	}
1004 
1005 	saved_offset = plaintext->cd_offset;
1006 	saved_length = plaintext->cd_length;
1007 
1008 	/*
1009 	 * Do the update on the specified input data.
1010 	 */
1011 	switch (ciphertext->cd_format) {
1012 	case CRYPTO_DATA_RAW:
1013 		ret = crypto_update_iov(&des_ctx, ciphertext, plaintext,
1014 		    des_decrypt_contiguous_blocks, des_copy_block64);
1015 		break;
1016 	case CRYPTO_DATA_UIO:
1017 		ret = crypto_update_uio(&des_ctx, ciphertext, plaintext,
1018 		    des_decrypt_contiguous_blocks, des_copy_block64);
1019 		break;
1020 	case CRYPTO_DATA_MBLK:
1021 		ret = crypto_update_mp(&des_ctx, ciphertext, plaintext,
1022 		    des_decrypt_contiguous_blocks, des_copy_block64);
1023 		break;
1024 	default:
1025 		ret = CRYPTO_ARGUMENTS_BAD;
1026 	}
1027 
1028 	if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1029 		bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1030 		kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1031 	}
1032 
1033 	if (ret == CRYPTO_SUCCESS) {
1034 		ASSERT(des_ctx.dc_remainder_len == 0);
1035 		if (ciphertext != plaintext)
1036 			plaintext->cd_length =
1037 			    plaintext->cd_offset - saved_offset;
1038 	} else {
1039 		plaintext->cd_length = saved_length;
1040 	}
1041 	plaintext->cd_offset = saved_offset;
1042 
1043 /* EXPORT DELETE END */
1044 
1045 	/* LINTED */
1046 	return (ret);
1047 }
1048 
1049 /*
1050  * KCF software provider context template entry points.
1051  */
1052 /* ARGSUSED */
1053 static int
1054 des_create_ctx_template(crypto_provider_handle_t provider,
1055     crypto_mechanism_t *mechanism, crypto_key_t *key,
1056     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1057 {
1058 
1059 /* EXPORT DELETE START */
1060 
1061 	des_strength_t strength;
1062 	void *keysched;
1063 	size_t size;
1064 	int rv;
1065 
1066 	switch (mechanism->cm_type) {
1067 	case DES_ECB_MECH_INFO_TYPE:
1068 		strength = DES;
1069 		break;
1070 	case DES_CBC_MECH_INFO_TYPE:
1071 		strength = DES;
1072 		break;
1073 	case DES3_ECB_MECH_INFO_TYPE:
1074 		strength = DES3;
1075 		break;
1076 	case DES3_CBC_MECH_INFO_TYPE:
1077 		strength = DES3;
1078 		break;
1079 	default:
1080 		return (CRYPTO_MECHANISM_INVALID);
1081 	}
1082 
1083 	if ((keysched = des_alloc_keysched(&size, strength,
1084 	    crypto_kmflag(req))) == NULL) {
1085 		return (CRYPTO_HOST_MEMORY);
1086 	}
1087 
1088 	/*
1089 	 * Initialize key schedule.  Key length information is stored
1090 	 * in the key.
1091 	 */
1092 	if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1093 		bzero(keysched, size);
1094 		kmem_free(keysched, size);
1095 		return (rv);
1096 	}
1097 
1098 	*tmpl = keysched;
1099 	*tmpl_size = size;
1100 
1101 /* EXPORT DELETE END */
1102 
1103 	return (CRYPTO_SUCCESS);
1104 }
1105 
1106 /* ARGSUSED */
1107 static int
1108 des_free_context(crypto_ctx_t *ctx)
1109 {
1110 
1111 /* EXPORT DELETE START */
1112 
1113 	des_ctx_t *des_ctx = ctx->cc_provider_private;
1114 
1115 	if (des_ctx != NULL) {
1116 		if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1117 			ASSERT(des_ctx->dc_keysched_len != 0);
1118 			bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1119 			kmem_free(des_ctx->dc_keysched,
1120 			    des_ctx->dc_keysched_len);
1121 		}
1122 		crypto_free_mode_ctx(des_ctx);
1123 		ctx->cc_provider_private = NULL;
1124 	}
1125 
1126 /* EXPORT DELETE END */
1127 
1128 	return (CRYPTO_SUCCESS);
1129 }
1130 
1131 /*
1132  * Pass it to des_keycheck() which will
1133  * fix it (parity bits), and check if the fixed key is weak.
1134  */
1135 /* ARGSUSED */
1136 static int
1137 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1138     crypto_key_t *key)
1139 {
1140 
1141 /* EXPORT DELETE START */
1142 
1143 	int expectedkeylen;
1144 	des_strength_t strength;
1145 	uint8_t keydata[DES3_MAX_KEY_LEN];
1146 
1147 	if ((mech == NULL) || (key == NULL))
1148 		return (CRYPTO_ARGUMENTS_BAD);
1149 
1150 	switch (mech->cm_type) {
1151 	case DES_ECB_MECH_INFO_TYPE:
1152 	case DES_CBC_MECH_INFO_TYPE:
1153 		expectedkeylen = DES_MINBITS;
1154 		strength = DES;
1155 		break;
1156 	case DES3_ECB_MECH_INFO_TYPE:
1157 	case DES3_CBC_MECH_INFO_TYPE:
1158 		expectedkeylen = DES3_MINBITS;
1159 		strength = DES3;
1160 		break;
1161 	default:
1162 		return (CRYPTO_MECHANISM_INVALID);
1163 	}
1164 
1165 	if (key->ck_format != CRYPTO_KEY_RAW)
1166 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
1167 
1168 	if (key->ck_length != expectedkeylen)
1169 		return (CRYPTO_KEY_SIZE_RANGE);
1170 
1171 	bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1172 
1173 	if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1174 		return (CRYPTO_WEAK_KEY);
1175 
1176 /* EXPORT DELETE END */
1177 
1178 	return (CRYPTO_SUCCESS);
1179 }
1180 
1181 /* ARGSUSED */
1182 static int
1183 des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1184     crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1185     int kmflag)
1186 {
1187 	int rv = CRYPTO_SUCCESS;
1188 
1189 /* EXPORT DELETE START */
1190 
1191 	void *keysched;
1192 	size_t size;
1193 
1194 	if (template == NULL) {
1195 		if ((keysched = des_alloc_keysched(&size, strength,
1196 		    kmflag)) == NULL)
1197 			return (CRYPTO_HOST_MEMORY);
1198 		/*
1199 		 * Initialize key schedule.
1200 		 * Key length is stored in the key.
1201 		 */
1202 		if ((rv = init_keysched(key, keysched,
1203 		    strength)) != CRYPTO_SUCCESS)
1204 			kmem_free(keysched, size);
1205 
1206 		des_ctx->dc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
1207 		des_ctx->dc_keysched_len = size;
1208 	} else {
1209 		keysched = template;
1210 	}
1211 	des_ctx->dc_keysched = keysched;
1212 
1213 	if (strength == DES3) {
1214 		des_ctx->dc_flags |= DES3_STRENGTH;
1215 	}
1216 
1217 	switch (mechanism->cm_type) {
1218 	case DES_CBC_MECH_INFO_TYPE:
1219 	case DES3_CBC_MECH_INFO_TYPE:
1220 		rv = cbc_init_ctx((cbc_ctx_t *)des_ctx, mechanism->cm_param,
1221 		    mechanism->cm_param_len, DES_BLOCK_LEN, des_copy_block64);
1222 		break;
1223 	case DES_ECB_MECH_INFO_TYPE:
1224 	case DES3_ECB_MECH_INFO_TYPE:
1225 		des_ctx->dc_flags |= ECB_MODE;
1226 	}
1227 
1228 	if (rv != CRYPTO_SUCCESS) {
1229 		if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1230 			bzero(keysched, size);
1231 			kmem_free(keysched, size);
1232 		}
1233 	}
1234 
1235 /* EXPORT DELETE END */
1236 
1237 	return (rv);
1238 }
1239