xref: /illumos-gate/usr/src/uts/common/crypto/io/aes.c (revision a7e661a2db6ff10cd43a089e7f4dcbd0cfd609f1)
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  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * AES provider for the Kernel Cryptographic Framework (KCF)
28  */
29 
30 #include <sys/types.h>
31 #include <sys/systm.h>
32 #include <sys/modctl.h>
33 #include <sys/cmn_err.h>
34 #include <sys/ddi.h>
35 #include <sys/crypto/common.h>
36 #include <sys/crypto/impl.h>
37 #include <sys/crypto/spi.h>
38 #include <sys/sysmacros.h>
39 #include <sys/strsun.h>
40 #include <modes/modes.h>
41 #include <aes/aes_impl.h>
42 
43 extern struct mod_ops mod_cryptoops;
44 
45 /*
46  * Module linkage information for the kernel.
47  */
48 static struct modlcrypto modlcrypto = {
49 	&mod_cryptoops,
50 	"AES Kernel SW Provider"
51 };
52 
53 static struct modlinkage modlinkage = {
54 	MODREV_1,
55 	(void *)&modlcrypto,
56 	NULL
57 };
58 
59 /*
60  * CSPI information (entry points, provider info, etc.)
61  */
62 typedef enum aes_mech_type {
63 	AES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_AES_ECB */
64 	AES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_AES_CBC */
65 	AES_CBC_PAD_MECH_INFO_TYPE,	/* SUN_CKM_AES_CBC_PAD */
66 	AES_CTR_MECH_INFO_TYPE,		/* SUN_CKM_AES_CTR */
67 	AES_CCM_MECH_INFO_TYPE,		/* SUN_CKM_AES_CCM */
68 	AES_GCM_MECH_INFO_TYPE		/* SUN_CKM_AES_GCM */
69 } aes_mech_type_t;
70 
71 /*
72  * The following definitions are to keep EXPORT_SRC happy.
73  */
74 #ifndef AES_MIN_KEY_BYTES
75 #define	AES_MIN_KEY_BYTES		0
76 #endif
77 
78 #ifndef AES_MAX_KEY_BYTES
79 #define	AES_MAX_KEY_BYTES		0
80 #endif
81 
82 /*
83  * Mechanism info structure passed to KCF during registration.
84  */
85 static crypto_mech_info_t aes_mech_info_tab[] = {
86 	/* AES_ECB */
87 	{SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE,
88 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
89 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
90 	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
91 	/* AES_CBC */
92 	{SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE,
93 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
94 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
95 	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
96 	/* AES_CTR */
97 	{SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE,
98 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
99 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
100 	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
101 	/* AES_CCM */
102 	{SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE,
103 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
104 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
105 	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
106 	/* AES_GCM */
107 	{SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE,
108 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
109 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
110 	    AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
111 };
112 
113 /* operations are in-place if the output buffer is NULL */
114 #define	AES_ARG_INPLACE(input, output)				\
115 	if ((output) == NULL)					\
116 		(output) = (input);
117 
118 static void aes_provider_status(crypto_provider_handle_t, uint_t *);
119 
120 static crypto_control_ops_t aes_control_ops = {
121 	aes_provider_status
122 };
123 
124 static int aes_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
125     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
126 static int aes_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *,
127     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
128 static int aes_common_init(crypto_ctx_t *, crypto_mechanism_t *,
129     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t, boolean_t);
130 static int aes_common_init_ctx(aes_ctx_t *, crypto_spi_ctx_template_t *,
131     crypto_mechanism_t *, crypto_key_t *, int, boolean_t);
132 static int aes_encrypt_final(crypto_ctx_t *, crypto_data_t *,
133     crypto_req_handle_t);
134 static int aes_decrypt_final(crypto_ctx_t *, crypto_data_t *,
135     crypto_req_handle_t);
136 
137 static int aes_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
138     crypto_req_handle_t);
139 static int aes_encrypt_update(crypto_ctx_t *, crypto_data_t *,
140     crypto_data_t *, crypto_req_handle_t);
141 static int aes_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
142     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
143     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
144 
145 static int aes_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
146     crypto_req_handle_t);
147 static int aes_decrypt_update(crypto_ctx_t *, crypto_data_t *,
148     crypto_data_t *, crypto_req_handle_t);
149 static int aes_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
150     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
151     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
152 
153 static crypto_cipher_ops_t aes_cipher_ops = {
154 	aes_encrypt_init,
155 	aes_encrypt,
156 	aes_encrypt_update,
157 	aes_encrypt_final,
158 	aes_encrypt_atomic,
159 	aes_decrypt_init,
160 	aes_decrypt,
161 	aes_decrypt_update,
162 	aes_decrypt_final,
163 	aes_decrypt_atomic
164 };
165 
166 static int aes_create_ctx_template(crypto_provider_handle_t,
167     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
168     size_t *, crypto_req_handle_t);
169 static int aes_free_context(crypto_ctx_t *);
170 
171 static crypto_ctx_ops_t aes_ctx_ops = {
172 	aes_create_ctx_template,
173 	aes_free_context
174 };
175 
176 static crypto_ops_t aes_crypto_ops = {
177 	&aes_control_ops,
178 	NULL,
179 	&aes_cipher_ops,
180 	NULL,
181 	NULL,
182 	NULL,
183 	NULL,
184 	NULL,
185 	NULL,
186 	NULL,
187 	NULL,
188 	NULL,
189 	NULL,
190 	&aes_ctx_ops
191 };
192 
193 static crypto_provider_info_t aes_prov_info = {
194 	CRYPTO_SPI_VERSION_1,
195 	"AES Software Provider",
196 	CRYPTO_SW_PROVIDER,
197 	{&modlinkage},
198 	NULL,
199 	&aes_crypto_ops,
200 	sizeof (aes_mech_info_tab)/sizeof (crypto_mech_info_t),
201 	aes_mech_info_tab
202 };
203 
204 static crypto_kcf_provider_handle_t aes_prov_handle = NULL;
205 
206 int
207 _init(void)
208 {
209 	int ret;
210 
211 	/*
212 	 * Register with KCF. If the registration fails, return error.
213 	 */
214 	if ((ret = crypto_register_provider(&aes_prov_info,
215 	    &aes_prov_handle)) != CRYPTO_SUCCESS) {
216 		cmn_err(CE_WARN, "%s _init: crypto_register_provider()"
217 		    "failed (0x%x)", CRYPTO_PROVIDER_NAME, ret);
218 		return (EACCES);
219 	}
220 
221 	if ((ret = mod_install(&modlinkage)) != 0) {
222 		int rv;
223 
224 		ASSERT(aes_prov_handle != NULL);
225 		/* We should not return if the unregister returns busy. */
226 		while ((rv = crypto_unregister_provider(aes_prov_handle))
227 		    == CRYPTO_BUSY) {
228 			cmn_err(CE_WARN,
229 			    "%s _init: crypto_unregister_provider() "
230 			    "failed (0x%x). Retrying.",
231 			    CRYPTO_PROVIDER_NAME, rv);
232 			/* wait 10 seconds and try again. */
233 			delay(10 * drv_usectohz(1000000));
234 		}
235 	}
236 
237 	return (ret);
238 }
239 
240 int
241 _fini(void)
242 {
243 	int ret;
244 
245 	/*
246 	 * Unregister from KCF if previous registration succeeded.
247 	 */
248 	if (aes_prov_handle != NULL) {
249 		if ((ret = crypto_unregister_provider(aes_prov_handle)) !=
250 		    CRYPTO_SUCCESS) {
251 			cmn_err(CE_WARN,
252 			    "%s _fini: crypto_unregister_provider() "
253 			    "failed (0x%x)", CRYPTO_PROVIDER_NAME, ret);
254 			return (EBUSY);
255 		}
256 		aes_prov_handle = NULL;
257 	}
258 
259 	return (mod_remove(&modlinkage));
260 }
261 
262 int
263 _info(struct modinfo *modinfop)
264 {
265 	return (mod_info(&modlinkage, modinfop));
266 }
267 
268 
269 static int
270 aes_check_mech_param(crypto_mechanism_t *mechanism, aes_ctx_t **ctx, int kmflag)
271 {
272 	void *p = NULL;
273 	int rv = CRYPTO_SUCCESS;
274 
275 	switch (mechanism->cm_type) {
276 	case AES_ECB_MECH_INFO_TYPE:
277 		/* no parameter */
278 		if (ctx != NULL)
279 			p = ecb_alloc_ctx(kmflag);
280 		break;
281 	case AES_CBC_MECH_INFO_TYPE:
282 		if (mechanism->cm_param != NULL &&
283 		    mechanism->cm_param_len != AES_BLOCK_LEN) {
284 			rv = CRYPTO_MECHANISM_PARAM_INVALID;
285 			break;
286 		}
287 		if (ctx != NULL)
288 			p = cbc_alloc_ctx(kmflag);
289 		break;
290 	case AES_CTR_MECH_INFO_TYPE:
291 		if (mechanism->cm_param != NULL &&
292 		    mechanism->cm_param_len != sizeof (CK_AES_CTR_PARAMS)) {
293 			rv = CRYPTO_MECHANISM_PARAM_INVALID;
294 			break;
295 		}
296 		if (ctx != NULL)
297 			p = ctr_alloc_ctx(kmflag);
298 		break;
299 	case AES_CCM_MECH_INFO_TYPE:
300 		if (mechanism->cm_param != NULL &&
301 		    mechanism->cm_param_len != sizeof (CK_AES_CCM_PARAMS)) {
302 			rv = CRYPTO_MECHANISM_PARAM_INVALID;
303 			break;
304 		}
305 		if (ctx != NULL)
306 			p = ccm_alloc_ctx(kmflag);
307 		break;
308 	case AES_GCM_MECH_INFO_TYPE:
309 		if (mechanism->cm_param != NULL &&
310 		    mechanism->cm_param_len != sizeof (CK_AES_GCM_PARAMS)) {
311 			rv = CRYPTO_MECHANISM_PARAM_INVALID;
312 			break;
313 		}
314 		if (ctx != NULL)
315 			p = gcm_alloc_ctx(kmflag);
316 		break;
317 	default:
318 		rv = CRYPTO_MECHANISM_INVALID;
319 	}
320 	if (ctx != NULL)
321 		*ctx = p;
322 
323 	return (rv);
324 }
325 
326 /* EXPORT DELETE START */
327 
328 /*
329  * Initialize key schedules for AES
330  */
331 static int
332 init_keysched(crypto_key_t *key, void *newbie)
333 {
334 	/*
335 	 * Only keys by value are supported by this module.
336 	 */
337 	switch (key->ck_format) {
338 	case CRYPTO_KEY_RAW:
339 		if (key->ck_length < AES_MINBITS ||
340 		    key->ck_length > AES_MAXBITS) {
341 			return (CRYPTO_KEY_SIZE_RANGE);
342 		}
343 
344 		/* key length must be either 128, 192, or 256 */
345 		if ((key->ck_length & 63) != 0)
346 			return (CRYPTO_KEY_SIZE_RANGE);
347 		break;
348 	default:
349 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
350 	}
351 
352 	aes_init_keysched(key->ck_data, key->ck_length, newbie);
353 	return (CRYPTO_SUCCESS);
354 }
355 
356 /* EXPORT DELETE END */
357 
358 /*
359  * KCF software provider control entry points.
360  */
361 /* ARGSUSED */
362 static void
363 aes_provider_status(crypto_provider_handle_t provider, uint_t *status)
364 {
365 	*status = CRYPTO_PROVIDER_READY;
366 }
367 
368 static int
369 aes_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
370     crypto_key_t *key, crypto_spi_ctx_template_t template,
371     crypto_req_handle_t req) {
372 	return (aes_common_init(ctx, mechanism, key, template, req, B_TRUE));
373 }
374 
375 static int
376 aes_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
377     crypto_key_t *key, crypto_spi_ctx_template_t template,
378     crypto_req_handle_t req) {
379 	return (aes_common_init(ctx, mechanism, key, template, req, B_FALSE));
380 }
381 
382 
383 
384 /*
385  * KCF software provider encrypt entry points.
386  */
387 static int
388 aes_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
389     crypto_key_t *key, crypto_spi_ctx_template_t template,
390     crypto_req_handle_t req, boolean_t is_encrypt_init)
391 {
392 
393 /* EXPORT DELETE START */
394 
395 	aes_ctx_t *aes_ctx;
396 	int rv;
397 	int kmflag;
398 
399 	/*
400 	 * Only keys by value are supported by this module.
401 	 */
402 	if (key->ck_format != CRYPTO_KEY_RAW) {
403 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
404 	}
405 
406 	kmflag = crypto_kmflag(req);
407 	if ((rv = aes_check_mech_param(mechanism, &aes_ctx, kmflag))
408 	    != CRYPTO_SUCCESS)
409 		return (rv);
410 
411 	rv = aes_common_init_ctx(aes_ctx, template, mechanism, key, kmflag,
412 	    is_encrypt_init);
413 	if (rv != CRYPTO_SUCCESS) {
414 		crypto_free_mode_ctx(aes_ctx);
415 		return (rv);
416 	}
417 
418 	ctx->cc_provider_private = aes_ctx;
419 
420 /* EXPORT DELETE END */
421 
422 	return (CRYPTO_SUCCESS);
423 }
424 
425 static void
426 aes_copy_block64(uint8_t *in, uint64_t *out)
427 {
428 	if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
429 		/* LINTED: pointer alignment */
430 		out[0] = *(uint64_t *)&in[0];
431 		/* LINTED: pointer alignment */
432 		out[1] = *(uint64_t *)&in[8];
433 	} else {
434 		uint8_t *iv8 = (uint8_t *)&out[0];
435 
436 		AES_COPY_BLOCK(in, iv8);
437 	}
438 }
439 
440 /* ARGSUSED */
441 static int
442 aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
443     crypto_data_t *ciphertext, crypto_req_handle_t req)
444 {
445 	int ret = CRYPTO_FAILED;
446 
447 /* EXPORT DELETE START */
448 
449 	aes_ctx_t *aes_ctx;
450 	size_t saved_length, saved_offset, length_needed;
451 
452 	ASSERT(ctx->cc_provider_private != NULL);
453 	aes_ctx = ctx->cc_provider_private;
454 
455 	/*
456 	 * For block ciphers, plaintext must be a multiple of AES block size.
457 	 * This test is only valid for ciphers whose blocksize is a power of 2.
458 	 * Even though AES CCM mode is a block cipher, it does not
459 	 * require the plaintext to be a multiple of AES block size.
460 	 * The length requirement for AES CCM mode has already been checked
461 	 * at init time
462 	 */
463 	if (((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE)) == 0) &&
464 	    (plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
465 		return (CRYPTO_DATA_LEN_RANGE);
466 
467 	AES_ARG_INPLACE(plaintext, ciphertext);
468 
469 	/*
470 	 * We need to just return the length needed to store the output.
471 	 * We should not destroy the context for the following case.
472 	 */
473 	if (aes_ctx->ac_flags & CCM_MODE) {
474 		length_needed = plaintext->cd_length + aes_ctx->ac_mac_len;
475 	} else if (aes_ctx->ac_flags & GCM_MODE) {
476 		length_needed = plaintext->cd_length + aes_ctx->ac_tag_len;
477 	} else {
478 		length_needed = plaintext->cd_length;
479 	}
480 
481 	if (ciphertext->cd_length < length_needed) {
482 		ciphertext->cd_length = length_needed;
483 		return (CRYPTO_BUFFER_TOO_SMALL);
484 	}
485 
486 	saved_length = ciphertext->cd_length;
487 	saved_offset = ciphertext->cd_offset;
488 
489 	/*
490 	 * Do an update on the specified input data.
491 	 */
492 	ret = aes_encrypt_update(ctx, plaintext, ciphertext, req);
493 	if (ret != CRYPTO_SUCCESS) {
494 		return (ret);
495 	}
496 
497 	/*
498 	 * For CCM mode, aes_ccm_encrypt_final() will take care of any
499 	 * left-over unprocessed data, and compute the MAC
500 	 */
501 	if (aes_ctx->ac_flags & CCM_MODE) {
502 		/*
503 		 * ccm_encrypt_final() will compute the MAC and append
504 		 * it to existing ciphertext. So, need to adjust the left over
505 		 * length value accordingly
506 		 */
507 
508 		/* order of following 2 lines MUST not be reversed */
509 		ciphertext->cd_offset = ciphertext->cd_length;
510 		ciphertext->cd_length = saved_length - ciphertext->cd_length;
511 		ret = ccm_encrypt_final((ccm_ctx_t *)aes_ctx, ciphertext,
512 		    AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
513 		if (ret != CRYPTO_SUCCESS) {
514 			return (ret);
515 		}
516 
517 		if (plaintext != ciphertext) {
518 			ciphertext->cd_length =
519 			    ciphertext->cd_offset - saved_offset;
520 		}
521 		ciphertext->cd_offset = saved_offset;
522 	} else if (aes_ctx->ac_flags & GCM_MODE) {
523 		/*
524 		 * gcm_encrypt_final() will compute the MAC and append
525 		 * it to existing ciphertext. So, need to adjust the left over
526 		 * length value accordingly
527 		 */
528 
529 		/* order of following 2 lines MUST not be reversed */
530 		ciphertext->cd_offset = ciphertext->cd_length;
531 		ciphertext->cd_length = saved_length - ciphertext->cd_length;
532 		ret = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, ciphertext,
533 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
534 		    aes_xor_block);
535 		if (ret != CRYPTO_SUCCESS) {
536 			return (ret);
537 		}
538 
539 		if (plaintext != ciphertext) {
540 			ciphertext->cd_length =
541 			    ciphertext->cd_offset - saved_offset;
542 		}
543 		ciphertext->cd_offset = saved_offset;
544 	}
545 
546 	ASSERT(aes_ctx->ac_remainder_len == 0);
547 	(void) aes_free_context(ctx);
548 
549 /* EXPORT DELETE END */
550 
551 	/* LINTED */
552 	return (ret);
553 }
554 
555 /* ARGSUSED */
556 static int
557 aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
558     crypto_data_t *plaintext, crypto_req_handle_t req)
559 {
560 	int ret = CRYPTO_FAILED;
561 
562 /* EXPORT DELETE START */
563 
564 	aes_ctx_t *aes_ctx;
565 	off_t saved_offset;
566 	size_t saved_length;
567 
568 	ASSERT(ctx->cc_provider_private != NULL);
569 	aes_ctx = ctx->cc_provider_private;
570 
571 	/*
572 	 * For block ciphers, plaintext must be a multiple of AES block size.
573 	 * This test is only valid for ciphers whose blocksize is a power of 2.
574 	 * Even though AES CCM mode is a block cipher, it does not
575 	 * require the plaintext to be a multiple of AES block size.
576 	 * The length requirement for AES CCM mode has already been checked
577 	 * at init time
578 	 */
579 	if (((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE)) == 0) &&
580 	    (ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0) {
581 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
582 	}
583 
584 	AES_ARG_INPLACE(ciphertext, plaintext);
585 
586 	/*
587 	 * We need to just return the length needed to store the output.
588 	 * We should not destroy the context for the following case.
589 	 *
590 	 * For AES CCM mode, size of the plaintext will be MAC_SIZE
591 	 * smaller than size of the cipher text.
592 	 */
593 	if (aes_ctx->ac_flags & CCM_MODE) {
594 		if (plaintext->cd_length < aes_ctx->ac_processed_data_len) {
595 			plaintext->cd_length = aes_ctx->ac_processed_data_len;
596 			return (CRYPTO_BUFFER_TOO_SMALL);
597 		}
598 		saved_offset = plaintext->cd_offset;
599 		saved_length = plaintext->cd_length;
600 	} else if (aes_ctx->ac_flags & GCM_MODE) {
601 		size_t pt_len = ciphertext->cd_length - aes_ctx->ac_tag_len;
602 
603 		if (plaintext->cd_length < pt_len) {
604 			plaintext->cd_length = pt_len;
605 			return (CRYPTO_BUFFER_TOO_SMALL);
606 		}
607 		saved_offset = plaintext->cd_offset;
608 		saved_length = plaintext->cd_length;
609 	} else if (plaintext->cd_length < ciphertext->cd_length) {
610 		plaintext->cd_length = ciphertext->cd_length;
611 		return (CRYPTO_BUFFER_TOO_SMALL);
612 	}
613 
614 	/*
615 	 * Do an update on the specified input data.
616 	 */
617 	ret = aes_decrypt_update(ctx, ciphertext, plaintext, req);
618 	if (ret != CRYPTO_SUCCESS) {
619 		goto cleanup;
620 	}
621 
622 	if (aes_ctx->ac_flags & CCM_MODE) {
623 		ASSERT(aes_ctx->ac_processed_data_len == aes_ctx->ac_data_len);
624 		ASSERT(aes_ctx->ac_processed_mac_len == aes_ctx->ac_mac_len);
625 
626 		/* order of following 2 lines MUST not be reversed */
627 		plaintext->cd_offset = plaintext->cd_length;
628 		plaintext->cd_length = saved_length - plaintext->cd_length;
629 
630 		ret = ccm_decrypt_final((ccm_ctx_t *)aes_ctx, plaintext,
631 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
632 		    aes_xor_block);
633 		if (ret == CRYPTO_SUCCESS) {
634 			if (plaintext != ciphertext) {
635 				plaintext->cd_length =
636 				    plaintext->cd_offset - saved_offset;
637 			}
638 		} else {
639 			plaintext->cd_length = saved_length;
640 		}
641 
642 		plaintext->cd_offset = saved_offset;
643 	} else if (aes_ctx->ac_flags & GCM_MODE) {
644 		/* order of following 2 lines MUST not be reversed */
645 		plaintext->cd_offset = plaintext->cd_length;
646 		plaintext->cd_length = saved_length - plaintext->cd_length;
647 
648 		ret = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, plaintext,
649 		    AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
650 		if (ret == CRYPTO_SUCCESS) {
651 			if (plaintext != ciphertext) {
652 				plaintext->cd_length =
653 				    plaintext->cd_offset - saved_offset;
654 			}
655 		} else {
656 			plaintext->cd_length = saved_length;
657 		}
658 
659 		plaintext->cd_offset = saved_offset;
660 	}
661 
662 	ASSERT(aes_ctx->ac_remainder_len == 0);
663 
664 cleanup:
665 	(void) aes_free_context(ctx);
666 
667 /* EXPORT DELETE END */
668 
669 	/* LINTED */
670 	return (ret);
671 }
672 
673 /* ARGSUSED */
674 static int
675 aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
676     crypto_data_t *ciphertext, crypto_req_handle_t req)
677 {
678 	off_t saved_offset;
679 	size_t saved_length, out_len;
680 	int ret = CRYPTO_SUCCESS;
681 	aes_ctx_t *aes_ctx;
682 
683 	ASSERT(ctx->cc_provider_private != NULL);
684 	aes_ctx = ctx->cc_provider_private;
685 
686 	AES_ARG_INPLACE(plaintext, ciphertext);
687 
688 	/* compute number of bytes that will hold the ciphertext */
689 	out_len = aes_ctx->ac_remainder_len;
690 	out_len += plaintext->cd_length;
691 	out_len &= ~(AES_BLOCK_LEN - 1);
692 
693 	/* return length needed to store the output */
694 	if (ciphertext->cd_length < out_len) {
695 		ciphertext->cd_length = out_len;
696 		return (CRYPTO_BUFFER_TOO_SMALL);
697 	}
698 
699 	saved_offset = ciphertext->cd_offset;
700 	saved_length = ciphertext->cd_length;
701 
702 
703 	/*
704 	 * Do the AES update on the specified input data.
705 	 */
706 	switch (plaintext->cd_format) {
707 	case CRYPTO_DATA_RAW:
708 		ret = crypto_update_iov(ctx->cc_provider_private,
709 		    plaintext, ciphertext, aes_encrypt_contiguous_blocks,
710 		    aes_copy_block64);
711 		break;
712 	case CRYPTO_DATA_UIO:
713 		ret = crypto_update_uio(ctx->cc_provider_private,
714 		    plaintext, ciphertext, aes_encrypt_contiguous_blocks,
715 		    aes_copy_block64);
716 		break;
717 	case CRYPTO_DATA_MBLK:
718 		ret = crypto_update_mp(ctx->cc_provider_private,
719 		    plaintext, ciphertext, aes_encrypt_contiguous_blocks,
720 		    aes_copy_block64);
721 		break;
722 	default:
723 		ret = CRYPTO_ARGUMENTS_BAD;
724 	}
725 
726 	/*
727 	 * Since AES counter mode is a stream cipher, we call
728 	 * ctr_mode_final() to pick up any remaining bytes.
729 	 * It is an internal function that does not destroy
730 	 * the context like *normal* final routines.
731 	 */
732 	if ((aes_ctx->ac_flags & CTR_MODE) && (aes_ctx->ac_remainder_len > 0)) {
733 		ret = ctr_mode_final((ctr_ctx_t *)aes_ctx,
734 		    ciphertext, aes_encrypt_block);
735 	}
736 
737 	if (ret == CRYPTO_SUCCESS) {
738 		if (plaintext != ciphertext)
739 			ciphertext->cd_length =
740 			    ciphertext->cd_offset - saved_offset;
741 	} else {
742 		ciphertext->cd_length = saved_length;
743 	}
744 	ciphertext->cd_offset = saved_offset;
745 
746 	return (ret);
747 }
748 
749 /* ARGSUSED */
750 static int
751 aes_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
752     crypto_data_t *plaintext, crypto_req_handle_t req)
753 {
754 	off_t saved_offset;
755 	size_t saved_length, out_len;
756 	int ret = CRYPTO_SUCCESS;
757 	aes_ctx_t *aes_ctx;
758 
759 	ASSERT(ctx->cc_provider_private != NULL);
760 	aes_ctx = ctx->cc_provider_private;
761 
762 	AES_ARG_INPLACE(ciphertext, plaintext);
763 
764 	/*
765 	 * Compute number of bytes that will hold the plaintext.
766 	 * This is not necessary for CCM and GCM since these mechanisms
767 	 * never return plaintext for update operations.
768 	 */
769 	if ((aes_ctx->ac_flags & (CCM_MODE|GCM_MODE)) == 0) {
770 		out_len = aes_ctx->ac_remainder_len;
771 		out_len += ciphertext->cd_length;
772 		out_len &= ~(AES_BLOCK_LEN - 1);
773 
774 		/* return length needed to store the output */
775 		if (plaintext->cd_length < out_len) {
776 			plaintext->cd_length = out_len;
777 			return (CRYPTO_BUFFER_TOO_SMALL);
778 		}
779 	}
780 
781 	saved_offset = plaintext->cd_offset;
782 	saved_length = plaintext->cd_length;
783 
784 	if (aes_ctx->ac_flags & GCM_MODE)
785 		gcm_set_kmflag((gcm_ctx_t *)aes_ctx, crypto_kmflag(req));
786 
787 	/*
788 	 * Do the AES update on the specified input data.
789 	 */
790 	switch (ciphertext->cd_format) {
791 	case CRYPTO_DATA_RAW:
792 		ret = crypto_update_iov(ctx->cc_provider_private,
793 		    ciphertext, plaintext, aes_decrypt_contiguous_blocks,
794 		    aes_copy_block64);
795 		break;
796 	case CRYPTO_DATA_UIO:
797 		ret = crypto_update_uio(ctx->cc_provider_private,
798 		    ciphertext, plaintext, aes_decrypt_contiguous_blocks,
799 		    aes_copy_block64);
800 		break;
801 	case CRYPTO_DATA_MBLK:
802 		ret = crypto_update_mp(ctx->cc_provider_private,
803 		    ciphertext, plaintext, aes_decrypt_contiguous_blocks,
804 		    aes_copy_block64);
805 		break;
806 	default:
807 		ret = CRYPTO_ARGUMENTS_BAD;
808 	}
809 
810 	/*
811 	 * Since AES counter mode is a stream cipher, we call
812 	 * ctr_mode_final() to pick up any remaining bytes.
813 	 * It is an internal function that does not destroy
814 	 * the context like *normal* final routines.
815 	 */
816 	if ((aes_ctx->ac_flags & CTR_MODE) && (aes_ctx->ac_remainder_len > 0)) {
817 		ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, plaintext,
818 		    aes_encrypt_block);
819 		if (ret == CRYPTO_DATA_LEN_RANGE)
820 			ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
821 	}
822 
823 	if (ret == CRYPTO_SUCCESS) {
824 		if (ciphertext != plaintext)
825 			plaintext->cd_length =
826 			    plaintext->cd_offset - saved_offset;
827 	} else {
828 		plaintext->cd_length = saved_length;
829 	}
830 	plaintext->cd_offset = saved_offset;
831 
832 
833 	return (ret);
834 }
835 
836 /* ARGSUSED */
837 static int
838 aes_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
839     crypto_req_handle_t req)
840 {
841 
842 /* EXPORT DELETE START */
843 
844 	aes_ctx_t *aes_ctx;
845 	int ret;
846 
847 	ASSERT(ctx->cc_provider_private != NULL);
848 	aes_ctx = ctx->cc_provider_private;
849 
850 	if (data->cd_format != CRYPTO_DATA_RAW &&
851 	    data->cd_format != CRYPTO_DATA_UIO &&
852 	    data->cd_format != CRYPTO_DATA_MBLK) {
853 		return (CRYPTO_ARGUMENTS_BAD);
854 	}
855 
856 	if (aes_ctx->ac_flags & CTR_MODE) {
857 		if (aes_ctx->ac_remainder_len > 0) {
858 			ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, data,
859 			    aes_encrypt_block);
860 			if (ret != CRYPTO_SUCCESS)
861 				return (ret);
862 		}
863 	} else if (aes_ctx->ac_flags & CCM_MODE) {
864 		ret = ccm_encrypt_final((ccm_ctx_t *)aes_ctx, data,
865 		    AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
866 		if (ret != CRYPTO_SUCCESS) {
867 			return (ret);
868 		}
869 	} else if (aes_ctx->ac_flags & GCM_MODE) {
870 		size_t saved_offset = data->cd_offset;
871 
872 		ret = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, data,
873 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
874 		    aes_xor_block);
875 		if (ret != CRYPTO_SUCCESS) {
876 			return (ret);
877 		}
878 		data->cd_length = data->cd_offset - saved_offset;
879 		data->cd_offset = saved_offset;
880 	} else {
881 		/*
882 		 * There must be no unprocessed plaintext.
883 		 * This happens if the length of the last data is
884 		 * not a multiple of the AES block length.
885 		 */
886 		if (aes_ctx->ac_remainder_len > 0) {
887 			return (CRYPTO_DATA_LEN_RANGE);
888 		}
889 		data->cd_length = 0;
890 	}
891 
892 	(void) aes_free_context(ctx);
893 
894 /* EXPORT DELETE END */
895 
896 	return (CRYPTO_SUCCESS);
897 }
898 
899 /* ARGSUSED */
900 static int
901 aes_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data,
902     crypto_req_handle_t req)
903 {
904 
905 /* EXPORT DELETE START */
906 
907 	aes_ctx_t *aes_ctx;
908 	int ret;
909 	off_t saved_offset;
910 	size_t saved_length;
911 
912 	ASSERT(ctx->cc_provider_private != NULL);
913 	aes_ctx = ctx->cc_provider_private;
914 
915 	if (data->cd_format != CRYPTO_DATA_RAW &&
916 	    data->cd_format != CRYPTO_DATA_UIO &&
917 	    data->cd_format != CRYPTO_DATA_MBLK) {
918 		return (CRYPTO_ARGUMENTS_BAD);
919 	}
920 
921 	/*
922 	 * There must be no unprocessed ciphertext.
923 	 * This happens if the length of the last ciphertext is
924 	 * not a multiple of the AES block length.
925 	 */
926 	if (aes_ctx->ac_remainder_len > 0) {
927 		if ((aes_ctx->ac_flags & CTR_MODE) == 0)
928 			return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
929 		else {
930 			ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, data,
931 			    aes_encrypt_block);
932 			if (ret == CRYPTO_DATA_LEN_RANGE)
933 				ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
934 			if (ret != CRYPTO_SUCCESS)
935 				return (ret);
936 		}
937 	}
938 
939 	if (aes_ctx->ac_flags & CCM_MODE) {
940 		/*
941 		 * This is where all the plaintext is returned, make sure
942 		 * the plaintext buffer is big enough
943 		 */
944 		size_t pt_len = aes_ctx->ac_data_len;
945 		if (data->cd_length < pt_len) {
946 			data->cd_length = pt_len;
947 			return (CRYPTO_BUFFER_TOO_SMALL);
948 		}
949 
950 		ASSERT(aes_ctx->ac_processed_data_len == pt_len);
951 		ASSERT(aes_ctx->ac_processed_mac_len == aes_ctx->ac_mac_len);
952 		saved_offset = data->cd_offset;
953 		saved_length = data->cd_length;
954 		ret = ccm_decrypt_final((ccm_ctx_t *)aes_ctx, data,
955 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
956 		    aes_xor_block);
957 		if (ret == CRYPTO_SUCCESS) {
958 			data->cd_length = data->cd_offset - saved_offset;
959 		} else {
960 			data->cd_length = saved_length;
961 		}
962 
963 		data->cd_offset = saved_offset;
964 		if (ret != CRYPTO_SUCCESS) {
965 			return (ret);
966 		}
967 	} else if (aes_ctx->ac_flags & GCM_MODE) {
968 		/*
969 		 * This is where all the plaintext is returned, make sure
970 		 * the plaintext buffer is big enough
971 		 */
972 		gcm_ctx_t *ctx = (gcm_ctx_t *)aes_ctx;
973 		size_t pt_len = ctx->gcm_processed_data_len - ctx->gcm_tag_len;
974 
975 		if (data->cd_length < pt_len) {
976 			data->cd_length = pt_len;
977 			return (CRYPTO_BUFFER_TOO_SMALL);
978 		}
979 
980 		saved_offset = data->cd_offset;
981 		saved_length = data->cd_length;
982 		ret = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, data,
983 		    AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
984 		if (ret == CRYPTO_SUCCESS) {
985 			data->cd_length = data->cd_offset - saved_offset;
986 		} else {
987 			data->cd_length = saved_length;
988 		}
989 
990 		data->cd_offset = saved_offset;
991 		if (ret != CRYPTO_SUCCESS) {
992 			return (ret);
993 		}
994 	}
995 
996 
997 	if ((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE)) == 0) {
998 		data->cd_length = 0;
999 	}
1000 
1001 	(void) aes_free_context(ctx);
1002 
1003 /* EXPORT DELETE END */
1004 
1005 	return (CRYPTO_SUCCESS);
1006 }
1007 
1008 /* ARGSUSED */
1009 static int
1010 aes_encrypt_atomic(crypto_provider_handle_t provider,
1011     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1012     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
1013     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1014 {
1015 	aes_ctx_t aes_ctx;	/* on the stack */
1016 	off_t saved_offset;
1017 	size_t saved_length;
1018 	size_t length_needed;
1019 	int ret;
1020 
1021 	AES_ARG_INPLACE(plaintext, ciphertext);
1022 
1023 	/*
1024 	 * CTR, CCM, and GCM modes do not require that ciphertext
1025 	 * be a multiple of AES block size.
1026 	 */
1027 	switch (mechanism->cm_type) {
1028 	case AES_CTR_MECH_INFO_TYPE:
1029 	case AES_CCM_MECH_INFO_TYPE:
1030 	case AES_GCM_MECH_INFO_TYPE:
1031 		break;
1032 	default:
1033 		if ((plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
1034 			return (CRYPTO_DATA_LEN_RANGE);
1035 	}
1036 
1037 	if ((ret = aes_check_mech_param(mechanism, NULL, 0)) != CRYPTO_SUCCESS)
1038 		return (ret);
1039 
1040 	bzero(&aes_ctx, sizeof (aes_ctx_t));
1041 
1042 	ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key,
1043 	    crypto_kmflag(req), B_TRUE);
1044 	if (ret != CRYPTO_SUCCESS)
1045 		return (ret);
1046 
1047 	switch (mechanism->cm_type) {
1048 	case AES_CCM_MECH_INFO_TYPE:
1049 		length_needed = plaintext->cd_length + aes_ctx.ac_mac_len;
1050 		break;
1051 	case AES_GCM_MECH_INFO_TYPE:
1052 		length_needed = plaintext->cd_length + aes_ctx.ac_tag_len;
1053 		break;
1054 	default:
1055 		length_needed = plaintext->cd_length;
1056 	}
1057 
1058 	/* return size of buffer needed to store output */
1059 	if (ciphertext->cd_length < length_needed) {
1060 		ciphertext->cd_length = length_needed;
1061 		ret = CRYPTO_BUFFER_TOO_SMALL;
1062 		goto out;
1063 	}
1064 
1065 	saved_offset = ciphertext->cd_offset;
1066 	saved_length = ciphertext->cd_length;
1067 
1068 	/*
1069 	 * Do an update on the specified input data.
1070 	 */
1071 	switch (plaintext->cd_format) {
1072 	case CRYPTO_DATA_RAW:
1073 		ret = crypto_update_iov(&aes_ctx, plaintext, ciphertext,
1074 		    aes_encrypt_contiguous_blocks, aes_copy_block64);
1075 		break;
1076 	case CRYPTO_DATA_UIO:
1077 		ret = crypto_update_uio(&aes_ctx, plaintext, ciphertext,
1078 		    aes_encrypt_contiguous_blocks, aes_copy_block64);
1079 		break;
1080 	case CRYPTO_DATA_MBLK:
1081 		ret = crypto_update_mp(&aes_ctx, plaintext, ciphertext,
1082 		    aes_encrypt_contiguous_blocks, aes_copy_block64);
1083 		break;
1084 	default:
1085 		ret = CRYPTO_ARGUMENTS_BAD;
1086 	}
1087 
1088 	if (ret == CRYPTO_SUCCESS) {
1089 		if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1090 			ret = ccm_encrypt_final((ccm_ctx_t *)&aes_ctx,
1091 			    ciphertext, AES_BLOCK_LEN, aes_encrypt_block,
1092 			    aes_xor_block);
1093 			if (ret != CRYPTO_SUCCESS)
1094 				goto out;
1095 			ASSERT(aes_ctx.ac_remainder_len == 0);
1096 		} else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE) {
1097 			ret = gcm_encrypt_final((gcm_ctx_t *)&aes_ctx,
1098 			    ciphertext, AES_BLOCK_LEN, aes_encrypt_block,
1099 			    aes_copy_block, aes_xor_block);
1100 			if (ret != CRYPTO_SUCCESS)
1101 				goto out;
1102 			ASSERT(aes_ctx.ac_remainder_len == 0);
1103 		} else if (mechanism->cm_type == AES_CTR_MECH_INFO_TYPE) {
1104 			if (aes_ctx.ac_remainder_len > 0) {
1105 				ret = ctr_mode_final((ctr_ctx_t *)&aes_ctx,
1106 				    ciphertext, aes_encrypt_block);
1107 				if (ret != CRYPTO_SUCCESS)
1108 					goto out;
1109 			}
1110 		} else {
1111 			ASSERT(aes_ctx.ac_remainder_len == 0);
1112 		}
1113 
1114 		if (plaintext != ciphertext) {
1115 			ciphertext->cd_length =
1116 			    ciphertext->cd_offset - saved_offset;
1117 		}
1118 	} else {
1119 		ciphertext->cd_length = saved_length;
1120 	}
1121 	ciphertext->cd_offset = saved_offset;
1122 
1123 out:
1124 	if (aes_ctx.ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1125 		bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1126 		kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1127 	}
1128 
1129 	return (ret);
1130 }
1131 
1132 /* ARGSUSED */
1133 static int
1134 aes_decrypt_atomic(crypto_provider_handle_t provider,
1135     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1136     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
1137     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1138 {
1139 	aes_ctx_t aes_ctx;	/* on the stack */
1140 	off_t saved_offset;
1141 	size_t saved_length;
1142 	size_t length_needed;
1143 	int ret;
1144 
1145 	AES_ARG_INPLACE(ciphertext, plaintext);
1146 
1147 	/*
1148 	 * CCM, GCM, and CTR modes do not require that ciphertext
1149 	 * be a multiple of AES block size.
1150 	 */
1151 	switch (mechanism->cm_type) {
1152 	case AES_CTR_MECH_INFO_TYPE:
1153 	case AES_CCM_MECH_INFO_TYPE:
1154 	case AES_GCM_MECH_INFO_TYPE:
1155 		break;
1156 	default:
1157 		if ((ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0)
1158 			return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
1159 	}
1160 
1161 	if ((ret = aes_check_mech_param(mechanism, NULL, 0)) != CRYPTO_SUCCESS)
1162 		return (ret);
1163 
1164 	bzero(&aes_ctx, sizeof (aes_ctx_t));
1165 
1166 	ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key,
1167 	    crypto_kmflag(req), B_FALSE);
1168 	if (ret != CRYPTO_SUCCESS)
1169 		return (ret);
1170 
1171 	switch (mechanism->cm_type) {
1172 	case AES_CCM_MECH_INFO_TYPE:
1173 		length_needed = aes_ctx.ac_data_len;
1174 		break;
1175 	case AES_GCM_MECH_INFO_TYPE:
1176 		length_needed = ciphertext->cd_length - aes_ctx.ac_tag_len;
1177 		break;
1178 	default:
1179 		length_needed = ciphertext->cd_length;
1180 	}
1181 
1182 	/* return size of buffer needed to store output */
1183 	if (plaintext->cd_length < length_needed) {
1184 		plaintext->cd_length = length_needed;
1185 		ret = CRYPTO_BUFFER_TOO_SMALL;
1186 		goto out;
1187 	}
1188 
1189 	saved_offset = plaintext->cd_offset;
1190 	saved_length = plaintext->cd_length;
1191 
1192 	if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE)
1193 		gcm_set_kmflag((gcm_ctx_t *)&aes_ctx, crypto_kmflag(req));
1194 
1195 	/*
1196 	 * Do an update on the specified input data.
1197 	 */
1198 	switch (ciphertext->cd_format) {
1199 	case CRYPTO_DATA_RAW:
1200 		ret = crypto_update_iov(&aes_ctx, ciphertext, plaintext,
1201 		    aes_decrypt_contiguous_blocks, aes_copy_block64);
1202 		break;
1203 	case CRYPTO_DATA_UIO:
1204 		ret = crypto_update_uio(&aes_ctx, ciphertext, plaintext,
1205 		    aes_decrypt_contiguous_blocks, aes_copy_block64);
1206 		break;
1207 	case CRYPTO_DATA_MBLK:
1208 		ret = crypto_update_mp(&aes_ctx, ciphertext, plaintext,
1209 		    aes_decrypt_contiguous_blocks, aes_copy_block64);
1210 		break;
1211 	default:
1212 		ret = CRYPTO_ARGUMENTS_BAD;
1213 	}
1214 
1215 	if (ret == CRYPTO_SUCCESS) {
1216 		if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) {
1217 			ASSERT(aes_ctx.ac_processed_data_len
1218 			    == aes_ctx.ac_data_len);
1219 			ASSERT(aes_ctx.ac_processed_mac_len
1220 			    == aes_ctx.ac_mac_len);
1221 			ret = ccm_decrypt_final((ccm_ctx_t *)&aes_ctx,
1222 			    plaintext, AES_BLOCK_LEN, aes_encrypt_block,
1223 			    aes_copy_block, aes_xor_block);
1224 			ASSERT(aes_ctx.ac_remainder_len == 0);
1225 			if ((ret == CRYPTO_SUCCESS) &&
1226 			    (ciphertext != plaintext)) {
1227 				plaintext->cd_length =
1228 				    plaintext->cd_offset - saved_offset;
1229 			} else {
1230 				plaintext->cd_length = saved_length;
1231 			}
1232 		} else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE) {
1233 			ret = gcm_decrypt_final((gcm_ctx_t *)&aes_ctx,
1234 			    plaintext, AES_BLOCK_LEN, aes_encrypt_block,
1235 			    aes_xor_block);
1236 			ASSERT(aes_ctx.ac_remainder_len == 0);
1237 			if ((ret == CRYPTO_SUCCESS) &&
1238 			    (ciphertext != plaintext)) {
1239 				plaintext->cd_length =
1240 				    plaintext->cd_offset - saved_offset;
1241 			} else {
1242 				plaintext->cd_length = saved_length;
1243 			}
1244 		} else if (mechanism->cm_type != AES_CTR_MECH_INFO_TYPE) {
1245 			ASSERT(aes_ctx.ac_remainder_len == 0);
1246 			if (ciphertext != plaintext)
1247 				plaintext->cd_length =
1248 				    plaintext->cd_offset - saved_offset;
1249 		} else {
1250 			if (aes_ctx.ac_remainder_len > 0) {
1251 				ret = ctr_mode_final((ctr_ctx_t *)&aes_ctx,
1252 				    plaintext, aes_encrypt_block);
1253 				if (ret == CRYPTO_DATA_LEN_RANGE)
1254 					ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
1255 				if (ret != CRYPTO_SUCCESS)
1256 					goto out;
1257 			}
1258 			if (ciphertext != plaintext)
1259 				plaintext->cd_length =
1260 				    plaintext->cd_offset - saved_offset;
1261 		}
1262 	} else {
1263 		plaintext->cd_length = saved_length;
1264 	}
1265 	plaintext->cd_offset = saved_offset;
1266 
1267 out:
1268 	if (aes_ctx.ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1269 		bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1270 		kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len);
1271 	}
1272 
1273 	if (aes_ctx.ac_flags & CCM_MODE) {
1274 		if (aes_ctx.ac_pt_buf != NULL) {
1275 			kmem_free(aes_ctx.ac_pt_buf, aes_ctx.ac_data_len);
1276 		}
1277 	} else if (aes_ctx.ac_flags & GCM_MODE) {
1278 		if (((gcm_ctx_t *)&aes_ctx)->gcm_pt_buf != NULL) {
1279 			kmem_free(((gcm_ctx_t *)&aes_ctx)->gcm_pt_buf,
1280 			    ((gcm_ctx_t *)&aes_ctx)->gcm_pt_buf_len);
1281 		}
1282 	}
1283 
1284 	return (ret);
1285 }
1286 
1287 /*
1288  * KCF software provider context template entry points.
1289  */
1290 /* ARGSUSED */
1291 static int
1292 aes_create_ctx_template(crypto_provider_handle_t provider,
1293     crypto_mechanism_t *mechanism, crypto_key_t *key,
1294     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1295 {
1296 
1297 /* EXPORT DELETE START */
1298 
1299 	void *keysched;
1300 	size_t size;
1301 	int rv;
1302 
1303 	if (mechanism->cm_type != AES_ECB_MECH_INFO_TYPE &&
1304 	    mechanism->cm_type != AES_CBC_MECH_INFO_TYPE &&
1305 	    mechanism->cm_type != AES_CTR_MECH_INFO_TYPE &&
1306 	    mechanism->cm_type != AES_CCM_MECH_INFO_TYPE)
1307 		return (CRYPTO_MECHANISM_INVALID);
1308 
1309 	if ((keysched = aes_alloc_keysched(&size,
1310 	    crypto_kmflag(req))) == NULL) {
1311 		return (CRYPTO_HOST_MEMORY);
1312 	}
1313 
1314 	/*
1315 	 * Initialize key schedule.  Key length information is stored
1316 	 * in the key.
1317 	 */
1318 	if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
1319 		bzero(keysched, size);
1320 		kmem_free(keysched, size);
1321 		return (rv);
1322 	}
1323 
1324 	*tmpl = keysched;
1325 	*tmpl_size = size;
1326 
1327 /* EXPORT DELETE END */
1328 
1329 	return (CRYPTO_SUCCESS);
1330 }
1331 
1332 /* ARGSUSED */
1333 static int
1334 aes_free_context(crypto_ctx_t *ctx)
1335 {
1336 
1337 /* EXPORT DELETE START */
1338 
1339 	aes_ctx_t *aes_ctx = ctx->cc_provider_private;
1340 
1341 	if (aes_ctx != NULL) {
1342 		if (aes_ctx->ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1343 			ASSERT(aes_ctx->ac_keysched_len != 0);
1344 			bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
1345 			kmem_free(aes_ctx->ac_keysched,
1346 			    aes_ctx->ac_keysched_len);
1347 		}
1348 		crypto_free_mode_ctx(aes_ctx);
1349 		ctx->cc_provider_private = NULL;
1350 	}
1351 
1352 /* EXPORT DELETE END */
1353 
1354 	return (CRYPTO_SUCCESS);
1355 }
1356 
1357 /* ARGSUSED */
1358 static int
1359 aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
1360     crypto_mechanism_t *mechanism, crypto_key_t *key, int kmflag,
1361     boolean_t is_encrypt_init)
1362 {
1363 	int rv = CRYPTO_SUCCESS;
1364 
1365 /* EXPORT DELETE START */
1366 
1367 	void *keysched;
1368 	size_t size;
1369 
1370 	if (template == NULL) {
1371 		if ((keysched = aes_alloc_keysched(&size, kmflag)) == NULL)
1372 			return (CRYPTO_HOST_MEMORY);
1373 		/*
1374 		 * Initialize key schedule.
1375 		 * Key length is stored in the key.
1376 		 */
1377 		if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) {
1378 			kmem_free(keysched, size);
1379 			return (rv);
1380 		}
1381 
1382 		aes_ctx->ac_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
1383 		aes_ctx->ac_keysched_len = size;
1384 	} else {
1385 		keysched = template;
1386 	}
1387 	aes_ctx->ac_keysched = keysched;
1388 
1389 	switch (mechanism->cm_type) {
1390 	case AES_CBC_MECH_INFO_TYPE:
1391 		rv = cbc_init_ctx((cbc_ctx_t *)aes_ctx, mechanism->cm_param,
1392 		    mechanism->cm_param_len, AES_BLOCK_LEN, aes_copy_block64);
1393 		break;
1394 	case AES_CTR_MECH_INFO_TYPE: {
1395 		CK_AES_CTR_PARAMS *pp;
1396 
1397 		if (mechanism->cm_param == NULL ||
1398 		    mechanism->cm_param_len != sizeof (CK_AES_CTR_PARAMS)) {
1399 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1400 		}
1401 		pp = (CK_AES_CTR_PARAMS *)mechanism->cm_param;
1402 		rv = ctr_init_ctx((ctr_ctx_t *)aes_ctx, pp->ulCounterBits,
1403 		    pp->cb, aes_copy_block);
1404 		break;
1405 	}
1406 	case AES_CCM_MECH_INFO_TYPE:
1407 		if (mechanism->cm_param == NULL ||
1408 		    mechanism->cm_param_len != sizeof (CK_AES_CCM_PARAMS)) {
1409 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1410 		}
1411 		rv = ccm_init_ctx((ccm_ctx_t *)aes_ctx, mechanism->cm_param,
1412 		    kmflag, is_encrypt_init, AES_BLOCK_LEN, aes_encrypt_block,
1413 		    aes_xor_block);
1414 		break;
1415 	case AES_GCM_MECH_INFO_TYPE:
1416 		if (mechanism->cm_param == NULL ||
1417 		    mechanism->cm_param_len != sizeof (CK_AES_GCM_PARAMS)) {
1418 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1419 		}
1420 		rv = gcm_init_ctx((gcm_ctx_t *)aes_ctx, mechanism->cm_param,
1421 		    AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
1422 		    aes_xor_block);
1423 		break;
1424 	case AES_ECB_MECH_INFO_TYPE:
1425 		aes_ctx->ac_flags |= ECB_MODE;
1426 	}
1427 
1428 	if (rv != CRYPTO_SUCCESS) {
1429 		if (aes_ctx->ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1430 			bzero(keysched, size);
1431 			kmem_free(keysched, size);
1432 		}
1433 	}
1434 
1435 /* EXPORT DELETE END */
1436 
1437 	return (rv);
1438 }
1439