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