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 */
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * Portions of this source code were derived from Berkeley 4.3 BSD
32 * under license from the Regents of the University of California.
33 */
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 #define _DES_IMPL
52 #include <des/des_impl.h>
53
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 extern struct mod_ops mod_cryptoops;
76
77 /*
78 * Module linkage information for the kernel.
79 */
80 static struct modlmisc modlmisc = {
81 &mod_miscops,
82 "des encryption",
83 };
84
85 static struct modlcrypto modlcrypto = {
86 &mod_cryptoops,
87 "DES Kernel SW Provider"
88 };
89
90 static struct modlinkage modlinkage = {
91 MODREV_1,
92 &modlmisc,
93 &modlcrypto,
94 NULL
95 };
96
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
101
102 #ifndef DES_MIN_KEY_LEN
103 #define DES_MIN_KEY_LEN 0
104 #endif
105
106 #ifndef DES_MAX_KEY_LEN
107 #define DES_MAX_KEY_LEN 0
108 #endif
109
110 #ifndef DES3_MIN_KEY_LEN
111 #define DES3_MIN_KEY_LEN 0
112 #endif
113
114 #ifndef DES3_MAX_KEY_LEN
115 #define DES3_MAX_KEY_LEN 0
116 #endif
117
118
119 /*
120 * Mechanism info structure passed to KCF during registration.
121 */
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}
143 };
144
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);
149
150 static void des_provider_status(crypto_provider_handle_t, uint_t *);
151
152 static crypto_control_ops_t des_control_ops = {
153 des_provider_status
154 };
155
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);
165
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);
173
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);
181
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
193 };
194
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 *);
199
200 static crypto_ctx_ops_t des_ctx_ops = {
201 des_create_ctx_template,
202 des_free_context
203 };
204
205 static int des_key_check(crypto_provider_handle_t, crypto_mechanism_t *,
206 crypto_key_t *);
207
208 static crypto_key_ops_t des_key_ops = {
209 NULL,
210 NULL,
211 NULL,
212 NULL,
213 NULL,
214 des_key_check
215 };
216
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
235 };
236
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
246 };
247
248 static crypto_kcf_provider_handle_t des_prov_handle = NULL;
249
250 int
_init(void)251 _init(void)
252 {
253 int ret;
254
255 if ((ret = mod_install(&modlinkage)) != 0)
256 return (ret);
257
258 /*
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.
262 *
263 */
264 (void) crypto_register_provider(&des_prov_info, &des_prov_handle);
265
266 return (0);
267 }
268
269
270 int
_info(struct modinfo * modinfop)271 _info(struct modinfo *modinfop)
272 {
273 return (mod_info(&modlinkage, modinfop));
274 }
275
276 /*
277 * Copy 8 bytes
278 */
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++; \
284 }
285
286 /*
287 * Copy multiple of 8 bytes
288 */
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++; \
296 } \
297 }
298
299 /*
300 * CBC mode encryption
301 */
302 /* ARGSUSED */
303 int
cbc_crypt(char * key,char * buf,size_t len,unsigned int mode,char * ivec)304 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
305 {
306 int err = 0;
307 struct desparams dp;
308
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);
314 }
315
316
317 /*
318 * ECB mode encryption
319 */
320 /* ARGSUSED */
321 int
ecb_crypt(char * key,char * buf,size_t len,unsigned int mode)322 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
323 {
324 int err = 0;
325 struct desparams dp;
326
327 dp.des_mode = ECB;
328 err = common_crypt(key, buf, len, mode, &dp);
329 return (err);
330 }
331
332
333
334 /*
335 * Common code to cbc_crypt() & ecb_crypt()
336 */
337 static int
common_crypt(char * key,char * buf,size_t len,unsigned int mode,struct desparams * desp)338 common_crypt(char *key, char *buf, size_t len, unsigned int mode,
339 struct desparams *desp)
340 {
341 int desdev;
342
343 if ((len % 8) != 0 || len > DES_MAXDATA)
344 return (DESERR_BADPARAM);
345
346 desp->des_dir =
347 ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
348
349 desdev = mode & DES_DEVMASK;
350 COPY8(key, desp->des_key);
351
352 #ifdef sun_hardware
353 if (desdev == DES_HW) {
354 int res;
355
356 if (g_desfd < 0 &&
357 (g_desfd == -1 || (g_desfd = getdesfd()) < 0))
358 goto software; /* no hardware device */
359
360 /*
361 * hardware
362 */
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);
371 }
372 return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
373 }
374 software:
375 #endif
376 /*
377 * software
378 */
379 if (!_des_crypt(buf, len, desp))
380 return (DESERR_HWERROR);
381
382 return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
383 }
384
385 /*
386 * Initialize key schedules for DES and DES3
387 */
388 static int
init_keysched(crypto_key_t * key,void * newbie,des_strength_t strength)389 init_keysched(crypto_key_t *key, void *newbie, des_strength_t strength)
390 {
391 uint8_t corrected_key[DES3_KEYSIZE];
392
393 /*
394 * Only keys by value are supported by this module.
395 */
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);
405 }
406
407 /*
408 * Fix parity bits.
409 * Initialize key schedule even if key is weak.
410 */
411 if (key->ck_data == NULL)
412 return (CRYPTO_ARGUMENTS_BAD);
413
414 des_parity_fix(key->ck_data, strength, corrected_key);
415 des_init_keysched(corrected_key, strength, newbie);
416 return (CRYPTO_SUCCESS);
417 }
418
419 /*
420 * KCF software provider control entry points.
421 */
422 /* ARGSUSED */
423 static void
des_provider_status(crypto_provider_handle_t provider,uint_t * status)424 des_provider_status(crypto_provider_handle_t provider, uint_t *status)
425 {
426 *status = CRYPTO_PROVIDER_READY;
427 }
428
429 /*
430 * KCF software provider encrypt entry points.
431 */
432 static int
des_common_init(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t template,crypto_req_handle_t req)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)
436 {
437
438 des_strength_t strength;
439 des_ctx_t *des_ctx = NULL;
440 int rv;
441 int kmflag;
442
443 /*
444 * Only keys by value are supported by this module.
445 */
446 if (key->ck_format != CRYPTO_KEY_RAW) {
447 return (CRYPTO_KEY_TYPE_INCONSISTENT);
448 }
449
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);
481 }
482
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);
487 }
488
489 ctx->cc_provider_private = des_ctx;
490
491 return (CRYPTO_SUCCESS);
492 }
493
494 static void
des_copy_block64(uint8_t * in,uint64_t * out)495 des_copy_block64(uint8_t *in, uint64_t *out)
496 {
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;
502
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 */
522
523 out[0] = tmp64;
524 }
525 }
526
527 /* ARGSUSED */
528 static int
des_encrypt(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)529 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
530 crypto_data_t *ciphertext, crypto_req_handle_t req)
531 {
532 int ret;
533
534 des_ctx_t *des_ctx;
535
536 /*
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.
540 */
541 if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
542 return (CRYPTO_DATA_LEN_RANGE);
543
544 ASSERT(ctx->cc_provider_private != NULL);
545 des_ctx = ctx->cc_provider_private;
546
547 DES_ARG_INPLACE(plaintext, ciphertext);
548
549 /*
550 * We need to just return the length needed to store the output.
551 * We should not destroy the context for the following case.
552 */
553 if (ciphertext->cd_length < plaintext->cd_length) {
554 ciphertext->cd_length = plaintext->cd_length;
555 return (CRYPTO_BUFFER_TOO_SMALL);
556 }
557
558 /*
559 * Do an update on the specified input data.
560 */
561 ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
562 ASSERT(des_ctx->dc_remainder_len == 0);
563 (void) des_free_context(ctx);
564
565 /* LINTED */
566 return (ret);
567 }
568
569 /* ARGSUSED */
570 static int
des_decrypt(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)571 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
572 crypto_data_t *plaintext, crypto_req_handle_t req)
573 {
574 int ret;
575
576 des_ctx_t *des_ctx;
577
578 /*
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.
582 */
583 if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
584 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
585
586 ASSERT(ctx->cc_provider_private != NULL);
587 des_ctx = ctx->cc_provider_private;
588
589 DES_ARG_INPLACE(ciphertext, plaintext);
590
591 /*
592 * We need to just return the length needed to store the output.
593 * We should not destroy the context for the following case.
594 */
595 if (plaintext->cd_length < ciphertext->cd_length) {
596 plaintext->cd_length = ciphertext->cd_length;
597 return (CRYPTO_BUFFER_TOO_SMALL);
598 }
599
600 /*
601 * Do an update on the specified input data.
602 */
603 ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
604 ASSERT(des_ctx->dc_remainder_len == 0);
605 (void) des_free_context(ctx);
606
607 /* LINTED */
608 return (ret);
609 }
610
611 /* ARGSUSED */
612 static int
des_encrypt_update(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_req_handle_t req)613 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
614 crypto_data_t *ciphertext, crypto_req_handle_t req)
615 {
616 off_t saved_offset;
617 size_t saved_length, out_len;
618 int ret = CRYPTO_SUCCESS;
619
620 ASSERT(ctx->cc_provider_private != NULL);
621
622 DES_ARG_INPLACE(plaintext, ciphertext);
623
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);
628
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);
633 }
634
635 saved_offset = ciphertext->cd_offset;
636 saved_length = ciphertext->cd_length;
637
638 /*
639 * Do the DES update on the specified input data.
640 */
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;
659 }
660
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;
667 }
668 ciphertext->cd_offset = saved_offset;
669
670 return (ret);
671 }
672
673 /* ARGSUSED */
674 static int
des_decrypt_update(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_req_handle_t req)675 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
676 crypto_data_t *plaintext, crypto_req_handle_t req)
677 {
678 off_t saved_offset;
679 size_t saved_length, out_len;
680 int ret = CRYPTO_SUCCESS;
681
682 ASSERT(ctx->cc_provider_private != NULL);
683
684 DES_ARG_INPLACE(ciphertext, plaintext);
685
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);
690
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);
695 }
696
697 saved_offset = plaintext->cd_offset;
698 saved_length = plaintext->cd_length;
699
700 /*
701 * Do the DES update on the specified input data.
702 */
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;
721 }
722
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;
729 }
730 plaintext->cd_offset = saved_offset;
731
732 return (ret);
733 }
734
735 /* ARGSUSED */
736 static int
des_encrypt_final(crypto_ctx_t * ctx,crypto_data_t * ciphertext,crypto_req_handle_t req)737 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
738 crypto_req_handle_t req)
739 {
740 des_ctx_t *des_ctx;
741
742 ASSERT(ctx->cc_provider_private != NULL);
743 des_ctx = ctx->cc_provider_private;
744
745 /*
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.
749 */
750 if (des_ctx->dc_remainder_len > 0)
751 return (CRYPTO_DATA_LEN_RANGE);
752
753 (void) des_free_context(ctx);
754 ciphertext->cd_length = 0;
755
756 return (CRYPTO_SUCCESS);
757 }
758
759 /* ARGSUSED */
760 static int
des_decrypt_final(crypto_ctx_t * ctx,crypto_data_t * plaintext,crypto_req_handle_t req)761 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
762 crypto_req_handle_t req)
763 {
764 des_ctx_t *des_ctx;
765
766 ASSERT(ctx->cc_provider_private != NULL);
767 des_ctx = ctx->cc_provider_private;
768
769 /*
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.
773 */
774 if (des_ctx->dc_remainder_len > 0)
775 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
776
777 (void) des_free_context(ctx);
778 plaintext->cd_length = 0;
779
780 return (CRYPTO_SUCCESS);
781 }
782
783 /* ARGSUSED */
784 static int
des_encrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * plaintext,crypto_data_t * ciphertext,crypto_spi_ctx_template_t template,crypto_req_handle_t req)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)
789 {
790 int ret;
791
792 des_ctx_t des_ctx; /* on the stack */
793 des_strength_t strength;
794 off_t saved_offset;
795 size_t saved_length;
796
797 DES_ARG_INPLACE(plaintext, ciphertext);
798
799 /*
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.
803 */
804 if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
805 return (CRYPTO_DATA_LEN_RANGE);
806
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);
811 }
812
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);
835 }
836
837 bzero(&des_ctx, sizeof (des_ctx_t));
838
839 if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
840 strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
841 return (ret);
842 }
843
844 saved_offset = ciphertext->cd_offset;
845 saved_length = ciphertext->cd_length;
846
847 /*
848 * Do the update on the specified input data.
849 */
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;
865 }
866
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);
870 }
871
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;
879 }
880 ciphertext->cd_offset = saved_offset;
881
882 /* LINTED */
883 return (ret);
884 }
885
886 /* ARGSUSED */
887 static int
des_decrypt_atomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * ciphertext,crypto_data_t * plaintext,crypto_spi_ctx_template_t template,crypto_req_handle_t req)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)
892 {
893 int ret;
894
895 des_ctx_t des_ctx; /* on the stack */
896 des_strength_t strength;
897 off_t saved_offset;
898 size_t saved_length;
899
900 DES_ARG_INPLACE(ciphertext, plaintext);
901
902 /*
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.
906 */
907 if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
908 return (CRYPTO_DATA_LEN_RANGE);
909
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);
914 }
915
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);
938 }
939
940 bzero(&des_ctx, sizeof (des_ctx_t));
941
942 if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
943 strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
944 return (ret);
945 }
946
947 saved_offset = plaintext->cd_offset;
948 saved_length = plaintext->cd_length;
949
950 /*
951 * Do the update on the specified input data.
952 */
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;
968 }
969
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);
973 }
974
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;
982 }
983 plaintext->cd_offset = saved_offset;
984
985 /* LINTED */
986 return (ret);
987 }
988
989 /*
990 * KCF software provider context template entry points.
991 */
992 /* ARGSUSED */
993 static int
des_create_ctx_template(crypto_provider_handle_t provider,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_spi_ctx_template_t * tmpl,size_t * tmpl_size,crypto_req_handle_t req)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)
997 {
998
999 des_strength_t strength;
1000 void *keysched;
1001 size_t size;
1002 int rv;
1003
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);
1019 }
1020
1021 if ((keysched = des_alloc_keysched(&size, strength,
1022 crypto_kmflag(req))) == NULL) {
1023 return (CRYPTO_HOST_MEMORY);
1024 }
1025
1026 /*
1027 * Initialize key schedule. Key length information is stored
1028 * in the key.
1029 */
1030 if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1031 bzero(keysched, size);
1032 kmem_free(keysched, size);
1033 return (rv);
1034 }
1035
1036 *tmpl = keysched;
1037 *tmpl_size = size;
1038
1039 return (CRYPTO_SUCCESS);
1040 }
1041
1042 /* ARGSUSED */
1043 static int
des_free_context(crypto_ctx_t * ctx)1044 des_free_context(crypto_ctx_t *ctx)
1045 {
1046 des_ctx_t *des_ctx = ctx->cc_provider_private;
1047
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);
1054 }
1055 crypto_free_mode_ctx(des_ctx);
1056 ctx->cc_provider_private = NULL;
1057 }
1058
1059 return (CRYPTO_SUCCESS);
1060 }
1061
1062 /*
1063 * Pass it to des_keycheck() which will
1064 * fix it (parity bits), and check if the fixed key is weak.
1065 */
1066 /* ARGSUSED */
1067 static int
des_key_check(crypto_provider_handle_t pd,crypto_mechanism_t * mech,crypto_key_t * key)1068 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1069 crypto_key_t *key)
1070 {
1071 int expectedkeylen;
1072 des_strength_t strength;
1073 uint8_t keydata[DES3_MAX_KEY_LEN];
1074
1075 if ((mech == NULL) || (key == NULL))
1076 return (CRYPTO_ARGUMENTS_BAD);
1077
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);
1091 }
1092
1093 if (key->ck_format != CRYPTO_KEY_RAW)
1094 return (CRYPTO_KEY_TYPE_INCONSISTENT);
1095
1096 if (key->ck_length != expectedkeylen)
1097 return (CRYPTO_KEY_SIZE_RANGE);
1098
1099 bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1100
1101 if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1102 return (CRYPTO_WEAK_KEY);
1103
1104 return (CRYPTO_SUCCESS);
1105 }
1106
1107 /* ARGSUSED */
1108 static int
des_common_init_ctx(des_ctx_t * des_ctx,crypto_spi_ctx_template_t * template,crypto_mechanism_t * mechanism,crypto_key_t * key,des_strength_t strength,int kmflag)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)
1112 {
1113 int rv = CRYPTO_SUCCESS;
1114
1115 void *keysched;
1116 size_t size;
1117
1118 if (template == NULL) {
1119 if ((keysched = des_alloc_keysched(&size, strength,
1120 kmflag)) == NULL)
1121 return (CRYPTO_HOST_MEMORY);
1122 /*
1123 * Initialize key schedule.
1124 * Key length is stored in the key.
1125 */
1126 if ((rv = init_keysched(key, keysched,
1127 strength)) != CRYPTO_SUCCESS)
1128 kmem_free(keysched, size);
1129
1130 des_ctx->dc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
1131 des_ctx->dc_keysched_len = size;
1132 } else {
1133 keysched = template;
1134 }
1135 des_ctx->dc_keysched = keysched;
1136
1137 if (strength == DES3) {
1138 des_ctx->dc_flags |= DES3_STRENGTH;
1139 }
1140
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;
1150 }
1151
1152 if (rv != CRYPTO_SUCCESS) {
1153 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1154 bzero(keysched, size);
1155 kmem_free(keysched, size);
1156 }
1157 }
1158
1159 return (rv);
1160 }
1161