xref: /titanic_44/usr/src/uts/common/crypto/io/aes.c (revision 1a7c1b724419d3cb5fa6eea75123c6b2060ba31b)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * AES provider for the Kernel Cryptographic Framework (KCF)
31  */
32 
33 #include <sys/types.h>
34 #include <sys/systm.h>
35 #include <sys/modctl.h>
36 #include <sys/cmn_err.h>
37 #include <sys/ddi.h>
38 #include <sys/crypto/common.h>
39 #include <sys/crypto/spi.h>
40 #include <sys/sysmacros.h>
41 #include <sys/strsun.h>
42 #include <aes_impl.h>
43 #include <aes_cbc_crypt.h>
44 
45 extern struct mod_ops mod_cryptoops;
46 
47 /*
48  * Module linkage information for the kernel.
49  */
50 static struct modlcrypto modlcrypto = {
51 	&mod_cryptoops,
52 	"AES Kernel SW Provider %I%"
53 };
54 
55 static struct modlinkage modlinkage = {
56 	MODREV_1,
57 	(void *)&modlcrypto,
58 	NULL
59 };
60 
61 /*
62  * CSPI information (entry points, provider info, etc.)
63  */
64 typedef enum aes_mech_type {
65 	AES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_AES_ECB */
66 	AES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_AES_CBC */
67 	AES_CBC_PAD_MECH_INFO_TYPE	/* SUN_CKM_AES_CBC_PAD */
68 } aes_mech_type_t;
69 
70 /*
71  * The following definitions are to keep EXPORT_SRC happy.
72  */
73 #ifndef AES_MIN_KEY_LEN
74 #define	AES_MIN_KEY_LEN		0
75 #endif
76 
77 #ifndef AES_MAX_KEY_LEN
78 #define	AES_MAX_KEY_LEN		0
79 #endif
80 
81 /*
82  * Mechanism info structure passed to KCF during registration.
83  */
84 static crypto_mech_info_t aes_mech_info_tab[] = {
85 	/* AES_ECB */
86 	{SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
87 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
88 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
89 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
90 	/* AES_CBC */
91 	{SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
92 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
93 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
94 	    AES_MIN_KEY_LEN, AES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
95 };
96 
97 #define	AES_VALID_MECH(mech)					\
98 	(((mech)->cm_type == AES_ECB_MECH_INFO_TYPE ||		\
99 	(mech)->cm_type == AES_CBC_MECH_INFO_TYPE) ? 1 : 0)
100 
101 /* operations are in-place if the output buffer is NULL */
102 #define	AES_ARG_INPLACE(input, output)				\
103 	if ((output) == NULL)					\
104 		(output) = (input);
105 
106 static void aes_provider_status(crypto_provider_handle_t, uint_t *);
107 
108 static crypto_control_ops_t aes_control_ops = {
109 	aes_provider_status
110 };
111 
112 static int aes_common_init(crypto_ctx_t *, crypto_mechanism_t *,
113     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
114 static int aes_common_init_ctx(aes_ctx_t *, crypto_spi_ctx_template_t *,
115     crypto_mechanism_t *, crypto_key_t *, int);
116 static int aes_encrypt_final(crypto_ctx_t *, crypto_data_t *,
117     crypto_req_handle_t);
118 static int aes_decrypt_final(crypto_ctx_t *, crypto_data_t *,
119     crypto_req_handle_t);
120 
121 static int aes_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
122     crypto_req_handle_t);
123 static int aes_encrypt_update(crypto_ctx_t *, crypto_data_t *,
124     crypto_data_t *, crypto_req_handle_t);
125 static int aes_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
126     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
127     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
128 
129 static int aes_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
130     crypto_req_handle_t);
131 static int aes_decrypt_update(crypto_ctx_t *, crypto_data_t *,
132     crypto_data_t *, crypto_req_handle_t);
133 static int aes_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
134     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
135     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
136 
137 static crypto_cipher_ops_t aes_cipher_ops = {
138 	aes_common_init,
139 	aes_encrypt,
140 	aes_encrypt_update,
141 	aes_encrypt_final,
142 	aes_encrypt_atomic,
143 	aes_common_init,
144 	aes_decrypt,
145 	aes_decrypt_update,
146 	aes_decrypt_final,
147 	aes_decrypt_atomic
148 };
149 
150 static int aes_create_ctx_template(crypto_provider_handle_t,
151     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
152     size_t *, crypto_req_handle_t);
153 static int aes_free_context(crypto_ctx_t *);
154 
155 static crypto_ctx_ops_t aes_ctx_ops = {
156 	aes_create_ctx_template,
157 	aes_free_context
158 };
159 
160 static crypto_ops_t aes_crypto_ops = {
161 	&aes_control_ops,
162 	NULL,
163 	&aes_cipher_ops,
164 	NULL,
165 	NULL,
166 	NULL,
167 	NULL,
168 	NULL,
169 	NULL,
170 	NULL,
171 	NULL,
172 	NULL,
173 	NULL,
174 	&aes_ctx_ops
175 };
176 
177 static crypto_provider_info_t aes_prov_info = {
178 	CRYPTO_SPI_VERSION_1,
179 	"AES Software Provider",
180 	CRYPTO_SW_PROVIDER,
181 	{&modlinkage},
182 	NULL,
183 	&aes_crypto_ops,
184 	sizeof (aes_mech_info_tab)/sizeof (crypto_mech_info_t),
185 	aes_mech_info_tab
186 };
187 
188 static crypto_kcf_provider_handle_t aes_prov_handle = NULL;
189 
190 int
191 _init(void)
192 {
193 	int ret;
194 
195 	/*
196 	 * Register with KCF. If the registration fails, return error.
197 	 */
198 	if ((ret = crypto_register_provider(&aes_prov_info,
199 	    &aes_prov_handle)) != CRYPTO_SUCCESS) {
200 		cmn_err(CE_WARN, "%s _init: crypto_register_provider()"
201 		    "failed (0x%x)", CRYPTO_PROVIDER_NAME, ret);
202 		return (EACCES);
203 	}
204 
205 	if ((ret = mod_install(&modlinkage)) != 0) {
206 		int rv;
207 
208 		ASSERT(aes_prov_handle != NULL);
209 		/* We should not return if the unregister returns busy. */
210 		while ((rv = crypto_unregister_provider(aes_prov_handle))
211 		    == CRYPTO_BUSY) {
212 			cmn_err(CE_WARN,
213 			    "%s _init: crypto_unregister_provider() "
214 			    "failed (0x%x). Retrying.",
215 			    CRYPTO_PROVIDER_NAME, rv);
216 			/* wait 10 seconds and try again. */
217 			delay(10 * drv_usectohz(1000000));
218 		}
219 	}
220 
221 	return (ret);
222 }
223 
224 int
225 _fini(void)
226 {
227 	int ret;
228 
229 	/*
230 	 * Unregister from KCF if previous registration succeeded.
231 	 */
232 	if (aes_prov_handle != NULL) {
233 		if ((ret = crypto_unregister_provider(aes_prov_handle)) !=
234 		    CRYPTO_SUCCESS) {
235 			cmn_err(CE_WARN,
236 			    "%s _fini: crypto_unregister_provider() "
237 			    "failed (0x%x)", CRYPTO_PROVIDER_NAME, ret);
238 			return (EBUSY);
239 		}
240 		aes_prov_handle = NULL;
241 	}
242 
243 	return (mod_remove(&modlinkage));
244 }
245 
246 int
247 _info(struct modinfo *modinfop)
248 {
249 	return (mod_info(&modlinkage, modinfop));
250 }
251 
252 
253 /* EXPORT DELETE START */
254 
255 /*
256  * Initialize key schedules for AES
257  */
258 static int
259 init_keysched(crypto_key_t *key, void *newbie)
260 {
261 	/*
262 	 * Only keys by value are supported by this module.
263 	 */
264 	switch (key->ck_format) {
265 	case CRYPTO_KEY_RAW:
266 		if (key->ck_length < AES_MINBITS ||
267 		    key->ck_length > AES_MAXBITS) {
268 			return (CRYPTO_KEY_SIZE_RANGE);
269 		}
270 
271 		/* key length must be either 128, 192, or 256 */
272 		if ((key->ck_length & 63) != 0)
273 			return (CRYPTO_KEY_SIZE_RANGE);
274 		break;
275 	default:
276 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
277 	}
278 
279 	aes_init_keysched(key->ck_data, key->ck_length, newbie);
280 	return (CRYPTO_SUCCESS);
281 }
282 
283 /* EXPORT DELETE END */
284 
285 /*
286  * KCF software provider control entry points.
287  */
288 /* ARGSUSED */
289 static void
290 aes_provider_status(crypto_provider_handle_t provider, uint_t *status)
291 {
292 	*status = CRYPTO_PROVIDER_READY;
293 }
294 
295 /*
296  * KCF software provider encrypt entry points.
297  */
298 static int
299 aes_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
300     crypto_key_t *key, crypto_spi_ctx_template_t template,
301     crypto_req_handle_t req)
302 {
303 
304 /* EXPORT DELETE START */
305 
306 	aes_ctx_t *aes_ctx;
307 	int rv;
308 	int kmflag;
309 
310 	/*
311 	 * Only keys by value are supported by this module.
312 	 */
313 	if (key->ck_format != CRYPTO_KEY_RAW) {
314 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
315 	}
316 
317 	if (!AES_VALID_MECH(mechanism))
318 		return (CRYPTO_MECHANISM_INVALID);
319 
320 	if (mechanism->cm_param != NULL &&
321 	    mechanism->cm_param_len != AES_BLOCK_LEN)
322 		return (CRYPTO_MECHANISM_PARAM_INVALID);
323 
324 	/*
325 	 * Allocate an AES context.
326 	 */
327 	kmflag = crypto_kmflag(req);
328 	if ((aes_ctx = kmem_zalloc(sizeof (aes_ctx_t), kmflag)) == NULL)
329 		return (CRYPTO_HOST_MEMORY);
330 
331 	rv = aes_common_init_ctx(aes_ctx, template, mechanism, key, kmflag);
332 	if (rv != CRYPTO_SUCCESS) {
333 		kmem_free(aes_ctx, sizeof (aes_ctx_t));
334 		return (rv);
335 	}
336 
337 	ctx->cc_provider_private = aes_ctx;
338 
339 /* EXPORT DELETE END */
340 
341 	return (CRYPTO_SUCCESS);
342 }
343 
344 /*
345  * Helper AES encrypt update function for iov input data.
346  */
347 static int
348 aes_cipher_update_iov(aes_ctx_t *aes_ctx, crypto_data_t *input,
349     crypto_data_t *output, int (*cipher)(aes_ctx_t *, caddr_t, size_t,
350     crypto_data_t *))
351 {
352 	int rv;
353 /* EXPORT DELETE START */
354 
355 	if (input->cd_miscdata != NULL) {
356 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
357 			/* LINTED: pointer alignment */
358 			aes_ctx->ac_iv[0] = *(uint64_t *)input->cd_miscdata;
359 			/* LINTED: pointer alignment */
360 			aes_ctx->ac_iv[1] = *(uint64_t *)&input->cd_miscdata[8];
361 		} else {
362 			uint8_t *miscdata8 = (uint8_t *)&input->cd_miscdata[0];
363 			uint8_t *iv8 = (uint8_t *)&aes_ctx->ac_iv[0];
364 
365 			AES_COPY_BLOCK(miscdata8, iv8);
366 		}
367 	}
368 
369 	if (input->cd_raw.iov_len < input->cd_length)
370 		return (CRYPTO_ARGUMENTS_BAD);
371 
372 	rv = (cipher)(aes_ctx, input->cd_raw.iov_base + input->cd_offset,
373 	    input->cd_length, (input == output) ? NULL : output);
374 
375 /* EXPORT DELETE END */
376 
377 	return (rv);
378 }
379 
380 /*
381  * Helper AES encrypt update function for uio input data.
382  */
383 static int
384 aes_cipher_update_uio(aes_ctx_t *aes_ctx, crypto_data_t *input,
385     crypto_data_t *output, int (*cipher)(aes_ctx_t *, caddr_t, size_t,
386     crypto_data_t *))
387 {
388 /* EXPORT DELETE START */
389 	uio_t *uiop = input->cd_uio;
390 	off_t offset = input->cd_offset;
391 	size_t length = input->cd_length;
392 	uint_t vec_idx;
393 	size_t cur_len;
394 
395 	if (input->cd_miscdata != NULL) {
396 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
397 			/* LINTED: pointer alignment */
398 			aes_ctx->ac_iv[0] = *(uint64_t *)input->cd_miscdata;
399 			/* LINTED: pointer alignment */
400 			aes_ctx->ac_iv[1] = *(uint64_t *)&input->cd_miscdata[8];
401 		} else {
402 			uint8_t *miscdata8 = (uint8_t *)&input->cd_miscdata[0];
403 			uint8_t *iv8 = (uint8_t *)&aes_ctx->ac_iv[0];
404 
405 			AES_COPY_BLOCK(miscdata8, iv8);
406 		}
407 	}
408 
409 	if (input->cd_uio->uio_segflg != UIO_SYSSPACE) {
410 		return (CRYPTO_ARGUMENTS_BAD);
411 	}
412 
413 	/*
414 	 * Jump to the first iovec containing data to be
415 	 * processed.
416 	 */
417 	for (vec_idx = 0; vec_idx < uiop->uio_iovcnt &&
418 	    offset >= uiop->uio_iov[vec_idx].iov_len;
419 	    offset -= uiop->uio_iov[vec_idx++].iov_len);
420 	if (vec_idx == uiop->uio_iovcnt) {
421 		/*
422 		 * The caller specified an offset that is larger than the
423 		 * total size of the buffers it provided.
424 		 */
425 		return (CRYPTO_DATA_LEN_RANGE);
426 	}
427 
428 	/*
429 	 * Now process the iovecs.
430 	 */
431 	while (vec_idx < uiop->uio_iovcnt && length > 0) {
432 		cur_len = MIN(uiop->uio_iov[vec_idx].iov_len -
433 		    offset, length);
434 
435 		(cipher)(aes_ctx, uiop->uio_iov[vec_idx].iov_base + offset,
436 		    cur_len, (input == output) ? NULL : output);
437 
438 		length -= cur_len;
439 		vec_idx++;
440 		offset = 0;
441 	}
442 
443 	if (vec_idx == uiop->uio_iovcnt && length > 0) {
444 		/*
445 		 * The end of the specified iovec's was reached but
446 		 * the length requested could not be processed, i.e.
447 		 * The caller requested to digest more data than it provided.
448 		 */
449 
450 		return (CRYPTO_DATA_LEN_RANGE);
451 	}
452 
453 /* EXPORT DELETE END */
454 
455 	return (CRYPTO_SUCCESS);
456 }
457 
458 /*
459  * Helper AES encrypt update function for mblk input data.
460  */
461 static int
462 aes_cipher_update_mp(aes_ctx_t *aes_ctx, crypto_data_t *input,
463     crypto_data_t *output, int (*cipher)(aes_ctx_t *, caddr_t, size_t,
464     crypto_data_t *))
465 {
466 /* EXPORT DELETE START */
467 	off_t offset = input->cd_offset;
468 	size_t length = input->cd_length;
469 	mblk_t *mp;
470 	size_t cur_len;
471 
472 	if (input->cd_miscdata != NULL) {
473 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
474 			/* LINTED: pointer alignment */
475 			aes_ctx->ac_iv[0] = *(uint64_t *)input->cd_miscdata;
476 			/* LINTED: pointer alignment */
477 			aes_ctx->ac_iv[1] = *(uint64_t *)&input->cd_miscdata[8];
478 		} else {
479 			uint8_t *miscdata8 = (uint8_t *)&input->cd_miscdata[0];
480 			uint8_t *iv8 = (uint8_t *)&aes_ctx->ac_iv[0];
481 
482 			AES_COPY_BLOCK(miscdata8, iv8);
483 		}
484 	}
485 
486 	/*
487 	 * Jump to the first mblk_t containing data to be processed.
488 	 */
489 	for (mp = input->cd_mp; mp != NULL && offset >= MBLKL(mp);
490 	    offset -= MBLKL(mp), mp = mp->b_cont);
491 	if (mp == NULL) {
492 		/*
493 		 * The caller specified an offset that is larger than the
494 		 * total size of the buffers it provided.
495 		 */
496 		return (CRYPTO_DATA_LEN_RANGE);
497 	}
498 
499 	/*
500 	 * Now do the processing on the mblk chain.
501 	 */
502 	while (mp != NULL && length > 0) {
503 		cur_len = MIN(MBLKL(mp) - offset, length);
504 		(cipher)(aes_ctx, (char *)(mp->b_rptr + offset), cur_len,
505 		    (input == output) ? NULL : output);
506 
507 		length -= cur_len;
508 		offset = 0;
509 		mp = mp->b_cont;
510 	}
511 
512 	if (mp == NULL && length > 0) {
513 		/*
514 		 * The end of the mblk was reached but the length requested
515 		 * could not be processed, i.e. The caller requested
516 		 * to digest more data than it provided.
517 		 */
518 		return (CRYPTO_DATA_LEN_RANGE);
519 	}
520 
521 /* EXPORT DELETE END */
522 
523 	return (CRYPTO_SUCCESS);
524 }
525 
526 /* ARGSUSED */
527 static int
528 aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
529     crypto_data_t *ciphertext, crypto_req_handle_t req)
530 {
531 	int ret = CRYPTO_FAILED;
532 
533 /* EXPORT DELETE START */
534 
535 	aes_ctx_t *aes_ctx;
536 
537 	/*
538 	 * Plaintext must be a multiple of AES block size.
539 	 * This test only works for non-padded mechanisms
540 	 * when blocksize is 2^N.
541 	 */
542 	if ((plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
543 		return (CRYPTO_DATA_LEN_RANGE);
544 
545 	ASSERT(ctx->cc_provider_private != NULL);
546 	aes_ctx = ctx->cc_provider_private;
547 
548 	AES_ARG_INPLACE(plaintext, ciphertext);
549 
550 	/*
551 	 * We need to just return the length needed to store the output.
552 	 * We should not destroy the context for the following case.
553 	 */
554 	if (ciphertext->cd_length < plaintext->cd_length) {
555 		ciphertext->cd_length = plaintext->cd_length;
556 		return (CRYPTO_BUFFER_TOO_SMALL);
557 	}
558 
559 	/*
560 	 * Do an update on the specified input data.
561 	 */
562 	ret = aes_encrypt_update(ctx, plaintext, ciphertext, req);
563 	ASSERT(aes_ctx->ac_remainder_len == 0);
564 	(void) aes_free_context(ctx);
565 
566 /* EXPORT DELETE END */
567 
568 	/* LINTED */
569 	return (ret);
570 }
571 
572 /* ARGSUSED */
573 static int
574 aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
575     crypto_data_t *plaintext, crypto_req_handle_t req)
576 {
577 	int ret = CRYPTO_FAILED;
578 
579 /* EXPORT DELETE START */
580 
581 	aes_ctx_t *aes_ctx;
582 
583 	/*
584 	 * Ciphertext must be a multiple of AES block size.
585 	 * This test only works for non-padded mechanisms
586 	 * when blocksize is 2^N.
587 	 */
588 	if ((ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
589 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
590 
591 	ASSERT(ctx->cc_provider_private != NULL);
592 	aes_ctx = ctx->cc_provider_private;
593 
594 	AES_ARG_INPLACE(ciphertext, plaintext);
595 
596 	/*
597 	 * We need to just return the length needed to store the output.
598 	 * We should not destroy the context for the following case.
599 	 */
600 	if (plaintext->cd_length < ciphertext->cd_length) {
601 		plaintext->cd_length = ciphertext->cd_length;
602 		return (CRYPTO_BUFFER_TOO_SMALL);
603 	}
604 
605 	/*
606 	 * Do an update on the specified input data.
607 	 */
608 	ret = aes_decrypt_update(ctx, ciphertext, plaintext, req);
609 	ASSERT(aes_ctx->ac_remainder_len == 0);
610 	(void) aes_free_context(ctx);
611 
612 /* EXPORT DELETE END */
613 
614 	/* LINTED */
615 	return (ret);
616 }
617 
618 /* ARGSUSED */
619 static int
620 aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
621     crypto_data_t *ciphertext, crypto_req_handle_t req)
622 {
623 	off_t saved_offset;
624 	size_t saved_length, out_len;
625 	int ret = CRYPTO_SUCCESS;
626 
627 	ASSERT(ctx->cc_provider_private != NULL);
628 
629 	AES_ARG_INPLACE(plaintext, ciphertext);
630 
631 	/* compute number of bytes that will hold the ciphertext */
632 	out_len = ((aes_ctx_t *)ctx->cc_provider_private)->ac_remainder_len;
633 	out_len += plaintext->cd_length;
634 	out_len &= ~(AES_BLOCK_LEN - 1);
635 
636 	/* return length needed to store the output */
637 	if (ciphertext->cd_length < out_len) {
638 		ciphertext->cd_length = out_len;
639 		return (CRYPTO_BUFFER_TOO_SMALL);
640 	}
641 
642 	saved_offset = ciphertext->cd_offset;
643 	saved_length = ciphertext->cd_length;
644 
645 	/*
646 	 * Do the AES update on the specified input data.
647 	 */
648 	switch (plaintext->cd_format) {
649 	case CRYPTO_DATA_RAW:
650 		ret = aes_cipher_update_iov(ctx->cc_provider_private,
651 		    plaintext, ciphertext, aes_encrypt_contiguous_blocks);
652 		break;
653 	case CRYPTO_DATA_UIO:
654 		ret = aes_cipher_update_uio(ctx->cc_provider_private,
655 		    plaintext, ciphertext, aes_encrypt_contiguous_blocks);
656 		break;
657 	case CRYPTO_DATA_MBLK:
658 		ret = aes_cipher_update_mp(ctx->cc_provider_private,
659 		    plaintext, ciphertext, aes_encrypt_contiguous_blocks);
660 		break;
661 	default:
662 		ret = CRYPTO_ARGUMENTS_BAD;
663 	}
664 
665 	if (ret == CRYPTO_SUCCESS) {
666 		if (plaintext != ciphertext)
667 			ciphertext->cd_length =
668 			    ciphertext->cd_offset - saved_offset;
669 	} else {
670 		ciphertext->cd_length = saved_length;
671 	}
672 	ciphertext->cd_offset = saved_offset;
673 
674 	return (ret);
675 }
676 
677 /* ARGSUSED */
678 static int
679 aes_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
680     crypto_data_t *plaintext, crypto_req_handle_t req)
681 {
682 	off_t saved_offset;
683 	size_t saved_length, out_len;
684 	int ret = CRYPTO_SUCCESS;
685 
686 	ASSERT(ctx->cc_provider_private != NULL);
687 
688 	AES_ARG_INPLACE(ciphertext, plaintext);
689 
690 	/* compute number of bytes that will hold the plaintext */
691 	out_len = ((aes_ctx_t *)ctx->cc_provider_private)->ac_remainder_len;
692 	out_len += ciphertext->cd_length;
693 	out_len &= ~(AES_BLOCK_LEN - 1);
694 
695 	/* return length needed to store the output */
696 	if (plaintext->cd_length < out_len) {
697 		plaintext->cd_length = out_len;
698 		return (CRYPTO_BUFFER_TOO_SMALL);
699 	}
700 
701 	saved_offset = plaintext->cd_offset;
702 	saved_length = plaintext->cd_length;
703 
704 	/*
705 	 * Do the AES update on the specified input data.
706 	 */
707 	switch (ciphertext->cd_format) {
708 	case CRYPTO_DATA_RAW:
709 		ret = aes_cipher_update_iov(ctx->cc_provider_private,
710 		    ciphertext, plaintext, aes_decrypt_contiguous_blocks);
711 		break;
712 	case CRYPTO_DATA_UIO:
713 		ret = aes_cipher_update_uio(ctx->cc_provider_private,
714 		    ciphertext, plaintext, aes_decrypt_contiguous_blocks);
715 		break;
716 	case CRYPTO_DATA_MBLK:
717 		ret = aes_cipher_update_mp(ctx->cc_provider_private,
718 		    ciphertext, plaintext, aes_decrypt_contiguous_blocks);
719 		break;
720 	default:
721 		ret = CRYPTO_ARGUMENTS_BAD;
722 	}
723 
724 	if (ret == CRYPTO_SUCCESS) {
725 		if (ciphertext != plaintext)
726 			plaintext->cd_length =
727 			    plaintext->cd_offset - saved_offset;
728 	} else {
729 		plaintext->cd_length = saved_length;
730 	}
731 	plaintext->cd_offset = saved_offset;
732 
733 	return (ret);
734 }
735 
736 /* ARGSUSED */
737 static int
738 aes_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
739     crypto_req_handle_t req)
740 {
741 
742 /* EXPORT DELETE START */
743 
744 	aes_ctx_t *aes_ctx;
745 
746 	ASSERT(ctx->cc_provider_private != NULL);
747 	aes_ctx = ctx->cc_provider_private;
748 
749 	/*
750 	 * There must be no unprocessed plaintext.
751 	 * This happens if the length of the last data is
752 	 * not a multiple of the AES block length.
753 	 */
754 	if (aes_ctx->ac_remainder_len > 0)
755 		return (CRYPTO_DATA_LEN_RANGE);
756 
757 	(void) aes_free_context(ctx);
758 	data->cd_length = 0;
759 
760 /* EXPORT DELETE END */
761 
762 	return (CRYPTO_SUCCESS);
763 }
764 
765 /* ARGSUSED */
766 static int
767 aes_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
768     crypto_req_handle_t req)
769 {
770 
771 /* EXPORT DELETE START */
772 
773 	aes_ctx_t *aes_ctx;
774 
775 	ASSERT(ctx->cc_provider_private != NULL);
776 	aes_ctx = ctx->cc_provider_private;
777 
778 	/*
779 	 * There must be no unprocessed ciphertext.
780 	 * This happens if the length of the last ciphertext is
781 	 * not a multiple of the AES block length.
782 	 */
783 	if (aes_ctx->ac_remainder_len > 0)
784 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
785 
786 	(void) aes_free_context(ctx);
787 	data->cd_length = 0;
788 
789 /* EXPORT DELETE END */
790 
791 	return (CRYPTO_SUCCESS);
792 }
793 
794 /* ARGSUSED */
795 static int
796 aes_encrypt_atomic(crypto_provider_handle_t provider,
797     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
798     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
799     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
800 {
801 	aes_ctx_t aes_ctx;	/* on the stack */
802 	off_t saved_offset;
803 	size_t saved_length;
804 	int ret;
805 
806 	AES_ARG_INPLACE(plaintext, ciphertext);
807 
808 	/*
809 	 * Plaintext must be a multiple of AES block size.
810 	 * This test only works for non-padded mechanisms
811 	 * when blocksize is 2^N.
812 	 */
813 	if ((plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
814 		return (CRYPTO_DATA_LEN_RANGE);
815 
816 	/* return length needed to store the output */
817 	if (ciphertext->cd_length < plaintext->cd_length) {
818 		ciphertext->cd_length = plaintext->cd_length;
819 		return (CRYPTO_BUFFER_TOO_SMALL);
820 	}
821 
822 	if (!AES_VALID_MECH(mechanism))
823 		return (CRYPTO_MECHANISM_INVALID);
824 
825 	if (mechanism->cm_param_len != 0 &&
826 	    mechanism->cm_param_len != AES_BLOCK_LEN)
827 		return (CRYPTO_MECHANISM_PARAM_INVALID);
828 
829 	bzero(&aes_ctx, sizeof (aes_ctx_t));
830 
831 	ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key,
832 	    crypto_kmflag(req));
833 	if (ret != CRYPTO_SUCCESS)
834 		return (ret);
835 
836 	saved_offset = ciphertext->cd_offset;
837 	saved_length = ciphertext->cd_length;
838 
839 	/*
840 	 * Do an update on the specified input data.
841 	 */
842 	switch (plaintext->cd_format) {
843 	case CRYPTO_DATA_RAW:
844 		ret = aes_cipher_update_iov(&aes_ctx, plaintext, ciphertext,
845 		    aes_encrypt_contiguous_blocks);
846 		break;
847 	case CRYPTO_DATA_UIO:
848 		ret = aes_cipher_update_uio(&aes_ctx, plaintext, ciphertext,
849 		    aes_encrypt_contiguous_blocks);
850 		break;
851 	case CRYPTO_DATA_MBLK:
852 		ret = aes_cipher_update_mp(&aes_ctx, plaintext, ciphertext,
853 		    aes_encrypt_contiguous_blocks);
854 		break;
855 	default:
856 		ret = CRYPTO_ARGUMENTS_BAD;
857 	}
858 
859 	if (aes_ctx.ac_flags & AES_PROVIDER_OWNS_KEY_SCHEDULE) {
860 		bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
861 		kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
862 	}
863 
864 	if (ret == CRYPTO_SUCCESS) {
865 		ASSERT(aes_ctx.ac_remainder_len == 0);
866 		if (plaintext != ciphertext)
867 			ciphertext->cd_length =
868 			    ciphertext->cd_offset - saved_offset;
869 	} else {
870 		ciphertext->cd_length = saved_length;
871 	}
872 	ciphertext->cd_offset = saved_offset;
873 
874 	return (ret);
875 }
876 
877 /* ARGSUSED */
878 static int
879 aes_decrypt_atomic(crypto_provider_handle_t provider,
880     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
881     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
882     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
883 {
884 	aes_ctx_t aes_ctx;	/* on the stack */
885 	off_t saved_offset;
886 	size_t saved_length;
887 	int ret;
888 
889 	AES_ARG_INPLACE(ciphertext, plaintext);
890 
891 	/*
892 	 * Ciphertext must be a multiple of AES block size.
893 	 * This test only works for non-padded mechanisms
894 	 * when blocksize is 2^N.
895 	 */
896 	if ((ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
897 		return (CRYPTO_DATA_LEN_RANGE);
898 
899 	/* return length needed to store the output */
900 	if (plaintext->cd_length < ciphertext->cd_length) {
901 		plaintext->cd_length = ciphertext->cd_length;
902 		return (CRYPTO_BUFFER_TOO_SMALL);
903 	}
904 
905 	if (!AES_VALID_MECH(mechanism))
906 		return (CRYPTO_MECHANISM_INVALID);
907 
908 	if (mechanism->cm_param_len != 0 &&
909 	    mechanism->cm_param_len != AES_BLOCK_LEN)
910 		return (CRYPTO_MECHANISM_PARAM_INVALID);
911 
912 	bzero(&aes_ctx, sizeof (aes_ctx_t));
913 
914 	ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key,
915 	    crypto_kmflag(req));
916 	if (ret != CRYPTO_SUCCESS)
917 		return (ret);
918 
919 	saved_offset = plaintext->cd_offset;
920 	saved_length = plaintext->cd_length;
921 
922 	/*
923 	 * Do an update on the specified input data.
924 	 */
925 	switch (ciphertext->cd_format) {
926 	case CRYPTO_DATA_RAW:
927 		ret = aes_cipher_update_iov(&aes_ctx, ciphertext, plaintext,
928 		    aes_decrypt_contiguous_blocks);
929 		break;
930 	case CRYPTO_DATA_UIO:
931 		ret = aes_cipher_update_uio(&aes_ctx, ciphertext, plaintext,
932 		    aes_decrypt_contiguous_blocks);
933 		break;
934 	case CRYPTO_DATA_MBLK:
935 		ret = aes_cipher_update_mp(&aes_ctx, ciphertext, plaintext,
936 		    aes_decrypt_contiguous_blocks);
937 		break;
938 	default:
939 		ret = CRYPTO_ARGUMENTS_BAD;
940 	}
941 
942 	if (aes_ctx.ac_flags & AES_PROVIDER_OWNS_KEY_SCHEDULE) {
943 		bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
944 		kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
945 	}
946 
947 	if (ret == CRYPTO_SUCCESS) {
948 		ASSERT(aes_ctx.ac_remainder_len == 0);
949 		if (ciphertext != plaintext)
950 			plaintext->cd_length =
951 			    plaintext->cd_offset - saved_offset;
952 	} else {
953 		plaintext->cd_length = saved_length;
954 	}
955 	plaintext->cd_offset = saved_offset;
956 
957 	return (ret);
958 }
959 
960 /*
961  * KCF software provider context template entry points.
962  */
963 /* ARGSUSED */
964 static int
965 aes_create_ctx_template(crypto_provider_handle_t provider,
966     crypto_mechanism_t *mechanism, crypto_key_t *key,
967     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
968 {
969 
970 /* EXPORT DELETE START */
971 
972 	void *keysched;
973 	size_t size;
974 	int rv;
975 
976 	if (!AES_VALID_MECH(mechanism))
977 		return (CRYPTO_MECHANISM_INVALID);
978 
979 	if ((keysched = aes_alloc_keysched(&size,
980 	    crypto_kmflag(req))) == NULL) {
981 		return (CRYPTO_HOST_MEMORY);
982 	}
983 
984 	/*
985 	 * Initialize key schedule.  Key length information is stored
986 	 * in the key.
987 	 */
988 	if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
989 		bzero(keysched, size);
990 		kmem_free(keysched, size);
991 		return (rv);
992 	}
993 
994 	*tmpl = keysched;
995 	*tmpl_size = size;
996 
997 /* EXPORT DELETE END */
998 
999 	return (CRYPTO_SUCCESS);
1000 }
1001 
1002 /* ARGSUSED */
1003 static int
1004 aes_free_context(crypto_ctx_t *ctx)
1005 {
1006 
1007 /* EXPORT DELETE START */
1008 
1009 	aes_ctx_t *aes_ctx = ctx->cc_provider_private;
1010 
1011 	if (aes_ctx != NULL) {
1012 		if (aes_ctx->ac_flags & AES_PROVIDER_OWNS_KEY_SCHEDULE) {
1013 			ASSERT(aes_ctx->ac_keysched_len != 0);
1014 			bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
1015 			kmem_free(aes_ctx->ac_keysched,
1016 			    aes_ctx->ac_keysched_len);
1017 		}
1018 		kmem_free(aes_ctx, sizeof (aes_ctx_t));
1019 		ctx->cc_provider_private = NULL;
1020 	}
1021 
1022 /* EXPORT DELETE END */
1023 
1024 	return (CRYPTO_SUCCESS);
1025 }
1026 
1027 /* ARGSUSED */
1028 static int
1029 aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
1030     crypto_mechanism_t *mechanism, crypto_key_t *key, int kmflag)
1031 {
1032 	int rv = CRYPTO_SUCCESS;
1033 
1034 /* EXPORT DELETE START */
1035 
1036 	void *keysched;
1037 	size_t size;
1038 
1039 	if (template == NULL) {
1040 		if ((keysched = aes_alloc_keysched(&size, kmflag)) == NULL)
1041 			return (CRYPTO_HOST_MEMORY);
1042 		/*
1043 		 * Initialize key schedule.
1044 		 * Key length is stored in the key.
1045 		 */
1046 		if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS)
1047 			kmem_free(keysched, size);
1048 
1049 		aes_ctx->ac_flags = AES_PROVIDER_OWNS_KEY_SCHEDULE;
1050 		aes_ctx->ac_keysched_len = size;
1051 	} else {
1052 		keysched = template;
1053 	}
1054 
1055 	if (mechanism->cm_type == AES_CBC_MECH_INFO_TYPE) {
1056 		/*
1057 		 * Copy IV into AES context.
1058 		 *
1059 		 * If cm_param == NULL then the IV comes from the
1060 		 * cd_miscdata field in the crypto_data structure.
1061 		 */
1062 		if (mechanism->cm_param != NULL) {
1063 			ASSERT(mechanism->cm_param_len == AES_BLOCK_LEN);
1064 			if (IS_P2ALIGNED(mechanism->cm_param,
1065 			    sizeof (uint64_t))) {
1066 				uint64_t *param64;
1067 				param64 = (uint64_t *)mechanism->cm_param;
1068 
1069 				aes_ctx->ac_iv[0] = *param64++;
1070 				aes_ctx->ac_iv[1] = *param64;
1071 			} else {
1072 				uint8_t *iv8;
1073 				uint8_t *p8;
1074 				iv8 = (uint8_t *)&aes_ctx->ac_iv;
1075 				p8 = (uint8_t *)&mechanism->cm_param[0];
1076 
1077 				iv8[0] = p8[0];
1078 				iv8[1] = p8[1];
1079 				iv8[2] = p8[2];
1080 				iv8[3] = p8[3];
1081 				iv8[4] = p8[4];
1082 				iv8[5] = p8[5];
1083 				iv8[6] = p8[6];
1084 				iv8[7] = p8[7];
1085 				iv8[8] = p8[8];
1086 				iv8[9] = p8[9];
1087 				iv8[10] = p8[10];
1088 				iv8[11] = p8[11];
1089 				iv8[12] = p8[12];
1090 				iv8[13] = p8[13];
1091 				iv8[14] = p8[14];
1092 				iv8[15] = p8[15];
1093 			}
1094 		}
1095 
1096 		aes_ctx->ac_lastp = (uint8_t *)&aes_ctx->ac_iv[0];
1097 		aes_ctx->ac_flags |= AES_CBC_MODE;
1098 	}
1099 	aes_ctx->ac_keysched = keysched;
1100 
1101 /* EXPORT DELETE END */
1102 
1103 	return (rv);
1104 }
1105