xref: /illumos-gate/usr/src/common/crypto/md5/md5.c (revision a0b85df4)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Cleaned-up and optimized version of MD5, based on the reference
8  * implementation provided in RFC 1321.  See RSA Copyright information
9  * below.
10  *
11  * NOTE:  All compiler data was gathered with SC4.2, and verified with SC5.x,
12  *	  as used to build Solaris 2.7.  Hopefully the compiler behavior won't
13  *	  change for the worse in subsequent Solaris builds.
14  */
15 
16 #pragma ident	"%Z%%M%	%I%	%E% SMI"
17 
18 /*
19  * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
20  */
21 
22 /*
23  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
24  * rights reserved.
25  *
26  * License to copy and use this software is granted provided that it
27  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
28  * Algorithm" in all material mentioning or referencing this software
29  * or this function.
30  *
31  * License is also granted to make and use derivative works provided
32  * that such works are identified as "derived from the RSA Data
33  * Security, Inc. MD5 Message-Digest Algorithm" in all material
34  * mentioning or referencing the derived work.
35  *
36  * RSA Data Security, Inc. makes no representations concerning either
37  * the merchantability of this software or the suitability of this
38  * software for any particular purpose. It is provided "as is"
39  * without express or implied warranty of any kind.
40  *
41  * These notices must be retained in any copies of any part of this
42  * documentation and/or software.
43  */
44 
45 #include <sys/types.h>
46 #include <sys/md5.h>
47 #include <sys/md5_consts.h>	/* MD5_CONST() optimization */
48 #if	!defined(_KERNEL) || defined(_BOOT)
49 #include <strings.h>
50 #endif /* !_KERNEL || _BOOT */
51 
52 #if	defined(_KERNEL) && !defined(_BOOT)
53 
54 /*
55  * In kernel module, the md5 module is created with two modlinkages:
56  * - a modlmisc that allows consumers to directly call the entry points
57  *   MD5Init, MD5Update, and MD5Final.
58  * - a modlcrypto that allows the module to register with the Kernel
59  *   Cryptographic Framework (KCF) as a software provider for the MD5
60  *   mechanisms.
61  */
62 
63 #include <sys/systm.h>
64 #include <sys/modctl.h>
65 #include <sys/cmn_err.h>
66 #include <sys/ddi.h>
67 #include <sys/crypto/common.h>
68 #include <sys/crypto/spi.h>
69 #include <sys/sysmacros.h>
70 #include <sys/strsun.h>
71 #include <sys/note.h>
72 
73 extern struct mod_ops mod_miscops;
74 extern struct mod_ops mod_cryptoops;
75 
76 /*
77  * Module linkage information for the kernel.
78  */
79 
80 static struct modlmisc modlmisc = {
81 	&mod_miscops,
82 	"MD5 Message-Digest Algorithm"
83 };
84 
85 static struct modlcrypto modlcrypto = {
86 	&mod_cryptoops,
87 	"MD5 Kernel SW Provider %I%"
88 };
89 
90 static struct modlinkage modlinkage = {
91 	MODREV_1,
92 	(void *)&modlmisc,
93 	(void *)&modlcrypto,
94 	NULL
95 };
96 
97 /*
98  * CSPI information (entry points, provider info, etc.)
99  */
100 
101 typedef enum md5_mech_type {
102 	MD5_MECH_INFO_TYPE,		/* SUN_CKM_MD5 */
103 	MD5_HMAC_MECH_INFO_TYPE,	/* SUN_CKM_MD5_HMAC */
104 	MD5_HMAC_GEN_MECH_INFO_TYPE	/* SUN_CKM_MD5_HMAC_GENERAL */
105 } md5_mech_type_t;
106 
107 #define	MD5_DIGEST_LENGTH	16	/* MD5 digest length in bytes */
108 #define	MD5_HMAC_BLOCK_SIZE	64	/* MD5 block size */
109 #define	MD5_HMAC_MIN_KEY_LEN	8	/* MD5-HMAC min key length in bits */
110 #define	MD5_HMAC_MAX_KEY_LEN	INT_MAX	/* MD5-HMAC max key length in bits */
111 #define	MD5_HMAC_INTS_PER_BLOCK	(MD5_HMAC_BLOCK_SIZE/sizeof (uint32_t))
112 
113 /*
114  * Context for MD5 mechanism.
115  */
116 typedef struct md5_ctx {
117 	md5_mech_type_t		mc_mech_type;	/* type of context */
118 	MD5_CTX			mc_md5_ctx;	/* MD5 context */
119 } md5_ctx_t;
120 
121 /*
122  * Context for MD5-HMAC and MD5-HMAC-GENERAL mechanisms.
123  */
124 typedef struct md5_hmac_ctx {
125 	md5_mech_type_t		hc_mech_type;	/* type of context */
126 	uint32_t		hc_digest_len;	/* digest len in bytes */
127 	MD5_CTX			hc_icontext;	/* inner MD5 context */
128 	MD5_CTX			hc_ocontext;	/* outer MD5 context */
129 } md5_hmac_ctx_t;
130 
131 /*
132  * Macros to access the MD5 or MD5-HMAC contexts from a context passed
133  * by KCF to one of the entry points.
134  */
135 
136 #define	PROV_MD5_CTX(ctx)	((md5_ctx_t *)(ctx)->cc_provider_private)
137 #define	PROV_MD5_HMAC_CTX(ctx)	((md5_hmac_ctx_t *)(ctx)->cc_provider_private)
138 /* to extract the digest length passed as mechanism parameter */
139 
140 #define	PROV_MD5_GET_DIGEST_LEN(m, len) {				\
141 	if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t)))		\
142 		(len) = (uint32_t)*((ulong_t *)mechanism->cm_param);	\
143 	else {								\
144 		ulong_t tmp_ulong;					\
145 		bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t));	\
146 		(len) = (uint32_t)tmp_ulong;				\
147 	}								\
148 }
149 
150 #define	PROV_MD5_DIGEST_KEY(ctx, key, len, digest) {	\
151 	MD5Init(ctx);					\
152 	MD5Update(ctx, key, len);			\
153 	MD5Final(digest, ctx);				\
154 }
155 
156 /*
157  * Mechanism info structure passed to KCF during registration.
158  */
159 static crypto_mech_info_t md5_mech_info_tab[] = {
160 	/* MD5 */
161 	{SUN_CKM_MD5, MD5_MECH_INFO_TYPE,
162 	    CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC,
163 	    0, 0, CRYPTO_KEYSIZE_UNIT_IN_BITS},
164 	/* MD5-HMAC */
165 	{SUN_CKM_MD5_HMAC, MD5_HMAC_MECH_INFO_TYPE,
166 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
167 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
168 	    CRYPTO_KEYSIZE_UNIT_IN_BITS},
169 	/* MD5-HMAC GENERAL */
170 	{SUN_CKM_MD5_HMAC_GENERAL, MD5_HMAC_GEN_MECH_INFO_TYPE,
171 	    CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC,
172 	    MD5_HMAC_MIN_KEY_LEN, MD5_HMAC_MAX_KEY_LEN,
173 	    CRYPTO_KEYSIZE_UNIT_IN_BITS}
174 };
175 
176 static void md5_provider_status(crypto_provider_handle_t, uint_t *);
177 
178 static crypto_control_ops_t md5_control_ops = {
179 	md5_provider_status
180 };
181 
182 static int md5_digest_init(crypto_ctx_t *, crypto_mechanism_t *,
183     crypto_req_handle_t);
184 static int md5_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
185     crypto_req_handle_t);
186 static int md5_digest_update(crypto_ctx_t *, crypto_data_t *,
187     crypto_req_handle_t);
188 static int md5_digest_final(crypto_ctx_t *, crypto_data_t *,
189     crypto_req_handle_t);
190 static int md5_digest_atomic(crypto_provider_handle_t, crypto_session_id_t,
191     crypto_mechanism_t *, crypto_data_t *, crypto_data_t *,
192     crypto_req_handle_t);
193 
194 static crypto_digest_ops_t md5_digest_ops = {
195 	md5_digest_init,
196 	md5_digest,
197 	md5_digest_update,
198 	NULL,
199 	md5_digest_final,
200 	md5_digest_atomic
201 };
202 
203 static int md5_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
204     crypto_spi_ctx_template_t, crypto_req_handle_t);
205 static int md5_mac_update(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
206 static int md5_mac_final(crypto_ctx_t *, crypto_data_t *, crypto_req_handle_t);
207 static int md5_mac_atomic(crypto_provider_handle_t, crypto_session_id_t,
208     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
209     crypto_spi_ctx_template_t, crypto_req_handle_t);
210 static int md5_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
211     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
212     crypto_spi_ctx_template_t, crypto_req_handle_t);
213 
214 static crypto_mac_ops_t md5_mac_ops = {
215 	md5_mac_init,
216 	NULL,
217 	md5_mac_update,
218 	md5_mac_final,
219 	md5_mac_atomic,
220 	md5_mac_verify_atomic
221 };
222 
223 static int md5_create_ctx_template(crypto_provider_handle_t,
224     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
225     size_t *, crypto_req_handle_t);
226 static int md5_free_context(crypto_ctx_t *);
227 
228 static crypto_ctx_ops_t md5_ctx_ops = {
229 	md5_create_ctx_template,
230 	md5_free_context
231 };
232 
233 static crypto_ops_t md5_crypto_ops = {
234 	&md5_control_ops,
235 	&md5_digest_ops,
236 	NULL,
237 	&md5_mac_ops,
238 	NULL,
239 	NULL,
240 	NULL,
241 	NULL,
242 	NULL,
243 	NULL,
244 	NULL,
245 	NULL,
246 	NULL,
247 	&md5_ctx_ops
248 };
249 
250 static crypto_provider_info_t md5_prov_info = {
251 	CRYPTO_SPI_VERSION_1,
252 	"MD5 Software Provider",
253 	CRYPTO_SW_PROVIDER,
254 	{&modlinkage},
255 	NULL,
256 	&md5_crypto_ops,
257 	sizeof (md5_mech_info_tab)/sizeof (crypto_mech_info_t),
258 	md5_mech_info_tab
259 };
260 
261 static crypto_kcf_provider_handle_t md5_prov_handle = NULL;
262 
263 int
264 _init(void)
265 {
266 	int ret;
267 
268 	if ((ret = mod_install(&modlinkage)) != 0)
269 		return (ret);
270 
271 	/*
272 	 * Register with KCF. If the registration fails, log an
273 	 * error but do not uninstall the module, since the functionality
274 	 * provided by misc/md5 should still be available.
275 	 */
276 	if ((ret = crypto_register_provider(&md5_prov_info,
277 	    &md5_prov_handle)) != CRYPTO_SUCCESS)
278 		cmn_err(CE_WARN, "md5 _init: "
279 		    "crypto_register_provider() failed (0x%x)", ret);
280 
281 	return (0);
282 }
283 
284 int
285 _fini(void)
286 {
287 	int ret;
288 
289 	/*
290 	 * Unregister from KCF if previous registration succeeded.
291 	 */
292 	if (md5_prov_handle != NULL) {
293 		if ((ret = crypto_unregister_provider(md5_prov_handle)) !=
294 		    CRYPTO_SUCCESS) {
295 			cmn_err(CE_WARN, "md5 _fini: "
296 			    "crypto_unregister_provider() failed (0x%x)", ret);
297 			return (EBUSY);
298 		}
299 		md5_prov_handle = NULL;
300 	}
301 
302 	return (mod_remove(&modlinkage));
303 }
304 
305 int
306 _info(struct modinfo *modinfop)
307 {
308 	return (mod_info(&modlinkage, modinfop));
309 }
310 #endif	/* _KERNEL && !_BOOT */
311 
312 static void Encode(uint8_t *, uint32_t *, size_t);
313 static void MD5Transform(uint32_t, uint32_t, uint32_t, uint32_t, MD5_CTX *,
314     const uint8_t [64]);
315 
316 static uint8_t PADDING[64] = { 0x80, /* all zeros */ };
317 
318 /*
319  * F, G, H and I are the basic MD5 functions.
320  */
321 #define	F(b, c, d)	(((b) & (c)) | ((~b) & (d)))
322 #define	G(b, c, d)	(((b) & (d)) | ((c) & (~d)))
323 #define	H(b, c, d)	((b) ^ (c) ^ (d))
324 #define	I(b, c, d)	((c) ^ ((b) | (~d)))
325 
326 /*
327  * ROTATE_LEFT rotates x left n bits.
328  */
329 #define	ROTATE_LEFT(x, n)	\
330 	(((x) << (n)) | ((x) >> ((sizeof (x) << 3) - (n))))
331 
332 /*
333  * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
334  * Rotation is separate from addition to prevent recomputation.
335  */
336 
337 #define	FF(a, b, c, d, x, s, ac) { \
338 	(a) += F((b), (c), (d)) + (x) + ((unsigned long long)(ac)); \
339 	(a) = ROTATE_LEFT((a), (s)); \
340 	(a) += (b); \
341 	}
342 
343 #define	GG(a, b, c, d, x, s, ac) { \
344 	(a) += G((b), (c), (d)) + (x) + ((unsigned long long)(ac)); \
345 	(a) = ROTATE_LEFT((a), (s)); \
346 	(a) += (b); \
347 	}
348 
349 #define	HH(a, b, c, d, x, s, ac) { \
350 	(a) += H((b), (c), (d)) + (x) + ((unsigned long long)(ac)); \
351 	(a) = ROTATE_LEFT((a), (s)); \
352 	(a) += (b); \
353 	}
354 
355 #define	II(a, b, c, d, x, s, ac) { \
356 	(a) += I((b), (c), (d)) + (x) + ((unsigned long long)(ac)); \
357 	(a) = ROTATE_LEFT((a), (s)); \
358 	(a) += (b); \
359 	}
360 
361 /*
362  * Loading 32-bit constants on a RISC is expensive since it involves both a
363  * `sethi' and an `or'.  thus, we instead have the compiler generate `ld's to
364  * load the constants from an array called `md5_consts'.  however, on intel
365  * (and other CISC processors), it is cheaper to load the constant
366  * directly.  thus, the c code in MD5Transform() uses the macro MD5_CONST()
367  * which either expands to a constant or an array reference, depending on the
368  * architecture the code is being compiled for.
369  *
370  * Right now, i386 and amd64 are the CISC exceptions.
371  * If we get another CISC ISA, we'll have to change the ifdef.
372  */
373 
374 /*
375  * Using the %asi register to achieve little endian loads - register
376  * is set using a inline template.
377  *
378  * Saves a few arithmetic ops as can now use an immediate offset with the
379  * lduwa instructions.
380  */
381 
382 extern void set_little(uint32_t);
383 extern uint32_t get_little();
384 
385 #if defined(__i386) || defined(__amd64)
386 
387 #define	MD5_CONST(x)		(MD5_CONST_ ## x)
388 #define	MD5_CONST_e(x)		MD5_CONST(x)
389 #define	MD5_CONST_o(x)		MD5_CONST(x)
390 
391 #else
392 /*
393  * sparc/RISC optimization:
394  *
395  * while it is somewhat counter-intuitive, on sparc (and presumably other RISC
396  * machines), it is more efficient to place all the constants used in this
397  * function in an array and load the values out of the array than to manually
398  * load the constants.  this is because setting a register to a 32-bit value
399  * takes two ops in most cases: a `sethi' and an `or', but loading a 32-bit
400  * value from memory only takes one `ld' (or `lduw' on v9).  while this
401  * increases memory usage, the compiler can find enough other things to do
402  * while waiting to keep the pipeline does not stall.  additionally, it is
403  * likely that many of these constants are cached so that later accesses do
404  * not even go out to the bus.
405  *
406  * this array is declared `static' to keep the compiler from having to
407  * bcopy() this array onto the stack frame of MD5Transform() each time it is
408  * called -- which is unacceptably expensive.
409  *
410  * the `const' is to ensure that callers are good citizens and do not try to
411  * munge the array.  since these routines are going to be called from inside
412  * multithreaded kernelland, this is a good safety check. -- `constants' will
413  * end up in .rodata.
414  *
415  * unfortunately, loading from an array in this manner hurts performance under
416  * intel (and presumably other CISC machines).  so, there is a macro,
417  * MD5_CONST(), used in MD5Transform(), that either expands to a reference to
418  * this array, or to the actual constant, depending on what platform this code
419  * is compiled for.
420  */
421 
422 #ifdef sun4v
423 
424 /*
425  * Going to load these consts in 8B chunks, so need to enforce 8B alignment
426  */
427 
428 /* CSTYLED */
429 #pragma align 64 (md5_consts)
430 
431 #endif /* sun4v */
432 
433 static const uint32_t md5_consts[] = {
434 	MD5_CONST_0,	MD5_CONST_1,	MD5_CONST_2,	MD5_CONST_3,
435 	MD5_CONST_4,	MD5_CONST_5,	MD5_CONST_6,	MD5_CONST_7,
436 	MD5_CONST_8,	MD5_CONST_9,	MD5_CONST_10,	MD5_CONST_11,
437 	MD5_CONST_12,	MD5_CONST_13,	MD5_CONST_14,	MD5_CONST_15,
438 	MD5_CONST_16,	MD5_CONST_17,	MD5_CONST_18,	MD5_CONST_19,
439 	MD5_CONST_20,	MD5_CONST_21,	MD5_CONST_22,	MD5_CONST_23,
440 	MD5_CONST_24,	MD5_CONST_25,	MD5_CONST_26,	MD5_CONST_27,
441 	MD5_CONST_28,	MD5_CONST_29,	MD5_CONST_30,	MD5_CONST_31,
442 	MD5_CONST_32,	MD5_CONST_33,	MD5_CONST_34,	MD5_CONST_35,
443 	MD5_CONST_36,	MD5_CONST_37,	MD5_CONST_38,	MD5_CONST_39,
444 	MD5_CONST_40,	MD5_CONST_41,	MD5_CONST_42,	MD5_CONST_43,
445 	MD5_CONST_44,	MD5_CONST_45,	MD5_CONST_46,	MD5_CONST_47,
446 	MD5_CONST_48,	MD5_CONST_49,	MD5_CONST_50,	MD5_CONST_51,
447 	MD5_CONST_52,	MD5_CONST_53,	MD5_CONST_54,	MD5_CONST_55,
448 	MD5_CONST_56,	MD5_CONST_57,	MD5_CONST_58,	MD5_CONST_59,
449 	MD5_CONST_60,	MD5_CONST_61,	MD5_CONST_62,	MD5_CONST_63
450 };
451 
452 
453 #ifdef sun4v
454 /*
455  * To reduce the number of loads, load consts in 64-bit
456  * chunks and then split.
457  *
458  * No need to mask upper 32-bits, as just interested in
459  * low 32-bits (saves an & operation and means that this
460  * optimization doesn't increases the icount.
461  */
462 #define	MD5_CONST_e(x)		(md5_consts64[x/2] >> 32)
463 #define	MD5_CONST_o(x)		(md5_consts64[x/2])
464 
465 #else
466 
467 #define	MD5_CONST_e(x)		(md5_consts[x])
468 #define	MD5_CONST_o(x)		(md5_consts[x])
469 
470 #endif /* sun4v */
471 
472 #endif
473 
474 /*
475  * MD5Init()
476  *
477  * purpose: initializes the md5 context and begins and md5 digest operation
478  *   input: MD5_CTX *	: the context to initialize.
479  *  output: void
480  */
481 
482 void
483 MD5Init(MD5_CTX *ctx)
484 {
485 	ctx->count[0] = ctx->count[1] = 0;
486 
487 	/* load magic initialization constants */
488 	ctx->state[0] = MD5_INIT_CONST_1;
489 	ctx->state[1] = MD5_INIT_CONST_2;
490 	ctx->state[2] = MD5_INIT_CONST_3;
491 	ctx->state[3] = MD5_INIT_CONST_4;
492 }
493 
494 /*
495  * MD5Update()
496  *
497  * purpose: continues an md5 digest operation, using the message block
498  *          to update the context.
499  *   input: MD5_CTX *	: the context to update
500  *          uint8_t *	: the message block
501  *          uint32_t    : the length of the message block in bytes
502  *  output: void
503  *
504  * MD5 crunches in 64-byte blocks.  All numeric constants here are related to
505  * that property of MD5.
506  */
507 
508 void
509 MD5Update(MD5_CTX *ctx, const void *inpp, unsigned int input_len)
510 {
511 	uint32_t		i, buf_index, buf_len;
512 #ifdef	sun4v
513 	uint32_t		old_asi;
514 #endif	/* sun4v */
515 	const unsigned char 	*input = (const unsigned char *)inpp;
516 
517 	/* compute (number of bytes computed so far) mod 64 */
518 	buf_index = (ctx->count[0] >> 3) & 0x3F;
519 
520 	/* update number of bits hashed into this MD5 computation so far */
521 	if ((ctx->count[0] += (input_len << 3)) < (input_len << 3))
522 	    ctx->count[1]++;
523 	ctx->count[1] += (input_len >> 29);
524 
525 	buf_len = 64 - buf_index;
526 
527 	/* transform as many times as possible */
528 	i = 0;
529 	if (input_len >= buf_len) {
530 
531 		/*
532 		 * general optimization:
533 		 *
534 		 * only do initial bcopy() and MD5Transform() if
535 		 * buf_index != 0.  if buf_index == 0, we're just
536 		 * wasting our time doing the bcopy() since there
537 		 * wasn't any data left over from a previous call to
538 		 * MD5Update().
539 		 */
540 
541 #ifdef sun4v
542 		/*
543 		 * For N1 use %asi register. However, costly to repeatedly set
544 		 * in MD5Transform. Therefore, set once here.
545 		 * Should probably restore the old value afterwards...
546 		 */
547 		old_asi = get_little();
548 		set_little(0x88);
549 #endif /* sun4v */
550 
551 		if (buf_index) {
552 			bcopy(input, &ctx->buf_un.buf8[buf_index], buf_len);
553 
554 			MD5Transform(ctx->state[0], ctx->state[1],
555 			    ctx->state[2], ctx->state[3], ctx,
556 			    ctx->buf_un.buf8);
557 
558 			i = buf_len;
559 		}
560 
561 		for (; i + 63 < input_len; i += 64)
562 			MD5Transform(ctx->state[0], ctx->state[1],
563 			    ctx->state[2], ctx->state[3], ctx, &input[i]);
564 
565 
566 #ifdef sun4v
567 		/*
568 		 * Restore old %ASI value
569 		 */
570 		set_little(old_asi);
571 #endif /* sun4v */
572 
573 		/*
574 		 * general optimization:
575 		 *
576 		 * if i and input_len are the same, return now instead
577 		 * of calling bcopy(), since the bcopy() in this
578 		 * case will be an expensive nop.
579 		 */
580 
581 		if (input_len == i)
582 			return;
583 
584 		buf_index = 0;
585 	}
586 
587 	/* buffer remaining input */
588 	bcopy(&input[i], &ctx->buf_un.buf8[buf_index], input_len - i);
589 }
590 
591 /*
592  * MD5Final()
593  *
594  * purpose: ends an md5 digest operation, finalizing the message digest and
595  *          zeroing the context.
596  *   input: uint8_t *	: a buffer to store the digest in
597  *          MD5_CTX *   : the context to finalize, save, and zero
598  *  output: void
599  */
600 
601 void
602 MD5Final(unsigned char *digest, MD5_CTX *ctx)
603 {
604 	uint8_t		bitcount_le[sizeof (ctx->count)];
605 	uint32_t	index = (ctx->count[0] >> 3) & 0x3f;
606 
607 	/* store bit count, little endian */
608 	Encode(bitcount_le, ctx->count, sizeof (bitcount_le));
609 
610 	/* pad out to 56 mod 64 */
611 	MD5Update(ctx, PADDING, ((index < 56) ? 56 : 120) - index);
612 
613 	/* append length (before padding) */
614 	MD5Update(ctx, bitcount_le, sizeof (bitcount_le));
615 
616 	/* store state in digest */
617 	Encode(digest, ctx->state, sizeof (ctx->state));
618 }
619 
620 #ifndef	_KERNEL
621 
622 void
623 md5_calc(unsigned char *output, unsigned char *input, unsigned int inlen)
624 {
625 	MD5_CTX context;
626 
627 	MD5Init(&context);
628 	MD5Update(&context, input, inlen);
629 	MD5Final(output, &context);
630 }
631 
632 #endif	/* !_KERNEL */
633 
634 /*
635  * Little-endian optimization:  I don't need to do any weirdness.   On
636  * some little-endian boxen, I'll have to do alignment checks, but I can do
637  * that below.
638  */
639 
640 #ifdef _LITTLE_ENDIAN
641 
642 #if !defined(__i386) && !defined(__amd64)
643 /*
644  * i386 and amd64 don't require aligned 4-byte loads.  The symbol
645  * _MD5_CHECK_ALIGNMENT indicates below whether the MD5Transform function
646  * requires alignment checking.
647  */
648 #define	_MD5_CHECK_ALIGNMENT
649 #endif /* !__i386 && !__amd64 */
650 
651 #define	LOAD_LITTLE_32(addr)	(*(uint32_t *)(addr))
652 
653 /*
654  * sparc v9/v8plus optimization:
655  *
656  * on the sparc v9/v8plus, we can load data little endian.  however, since
657  * the compiler doesn't have direct support for little endian, we
658  * link to an assembly-language routine `load_little_32' to do
659  * the magic.  note that special care must be taken to ensure the
660  * address is 32-bit aligned -- in the interest of speed, we don't
661  * check to make sure, since careful programming can guarantee this
662  * for us.
663  */
664 
665 #elif	defined(sun4u)
666 
667 /* Define alignment check because we can 4-byte load as little endian. */
668 #define	_MD5_CHECK_ALIGNMENT
669 
670 extern  uint32_t load_little_32(uint32_t *);
671 #define	LOAD_LITTLE_32(addr)    load_little_32((uint32_t *)(addr))
672 
673 #ifdef sun4v
674 
675 /*
676  * For N1 want to minimize number of arithmetic operations. This is best
677  * achieved by using the %asi register to specify ASI for the lduwa operations.
678  * Also, have a separate inline template for each word, so can utilize the
679  * immediate offset in lduwa, without relying on the compiler to do the right
680  * thing.
681  *
682  * Moving to 64-bit loads might also be beneficial.
683  */
684 
685 extern	uint32_t load_little_32_0(uint32_t *);
686 extern	uint32_t load_little_32_1(uint32_t *);
687 extern	uint32_t load_little_32_2(uint32_t *);
688 extern	uint32_t load_little_32_3(uint32_t *);
689 extern	uint32_t load_little_32_4(uint32_t *);
690 extern	uint32_t load_little_32_5(uint32_t *);
691 extern	uint32_t load_little_32_6(uint32_t *);
692 extern	uint32_t load_little_32_7(uint32_t *);
693 extern	uint32_t load_little_32_8(uint32_t *);
694 extern	uint32_t load_little_32_9(uint32_t *);
695 extern	uint32_t load_little_32_a(uint32_t *);
696 extern	uint32_t load_little_32_b(uint32_t *);
697 extern	uint32_t load_little_32_c(uint32_t *);
698 extern	uint32_t load_little_32_d(uint32_t *);
699 extern	uint32_t load_little_32_e(uint32_t *);
700 extern	uint32_t load_little_32_f(uint32_t *);
701 #define	LOAD_LITTLE_32_0(addr)	load_little_32_0((uint32_t *)(addr))
702 #define	LOAD_LITTLE_32_1(addr)	load_little_32_1((uint32_t *)(addr))
703 #define	LOAD_LITTLE_32_2(addr)	load_little_32_2((uint32_t *)(addr))
704 #define	LOAD_LITTLE_32_3(addr)	load_little_32_3((uint32_t *)(addr))
705 #define	LOAD_LITTLE_32_4(addr)	load_little_32_4((uint32_t *)(addr))
706 #define	LOAD_LITTLE_32_5(addr)	load_little_32_5((uint32_t *)(addr))
707 #define	LOAD_LITTLE_32_6(addr)	load_little_32_6((uint32_t *)(addr))
708 #define	LOAD_LITTLE_32_7(addr)	load_little_32_7((uint32_t *)(addr))
709 #define	LOAD_LITTLE_32_8(addr)	load_little_32_8((uint32_t *)(addr))
710 #define	LOAD_LITTLE_32_9(addr)	load_little_32_9((uint32_t *)(addr))
711 #define	LOAD_LITTLE_32_a(addr)	load_little_32_a((uint32_t *)(addr))
712 #define	LOAD_LITTLE_32_b(addr)	load_little_32_b((uint32_t *)(addr))
713 #define	LOAD_LITTLE_32_c(addr)	load_little_32_c((uint32_t *)(addr))
714 #define	LOAD_LITTLE_32_d(addr)	load_little_32_d((uint32_t *)(addr))
715 #define	LOAD_LITTLE_32_e(addr)	load_little_32_e((uint32_t *)(addr))
716 #define	LOAD_LITTLE_32_f(addr)	load_little_32_f((uint32_t *)(addr))
717 #endif /* sun4v */
718 
719 /* Placate lint */
720 #if	defined(__lint)
721 uint32_t
722 load_little_32(uint32_t *addr)
723 {
724 	return (*addr);
725 }
726 #endif
727 
728 #else	/* big endian -- will work on little endian, but slowly */
729 
730 /* Since we do byte operations, we don't have to check for alignment. */
731 #define	LOAD_LITTLE_32(addr)	\
732 	((addr)[0] | ((addr)[1] << 8) | ((addr)[2] << 16) | ((addr)[3] << 24))
733 #endif
734 
735 /*
736  * sparc register window optimization:
737  *
738  * `a', `b', `c', and `d' are passed into MD5Transform explicitly
739  * since it increases the number of registers available to the
740  * compiler.  under this scheme, these variables can be held in
741  * %i0 - %i3, which leaves more local and out registers available.
742  */
743 
744 /*
745  * MD5Transform()
746  *
747  * purpose: md5 transformation -- updates the digest based on `block'
748  *   input: uint32_t	: bytes  1 -  4 of the digest
749  *          uint32_t	: bytes  5 -  8 of the digest
750  *          uint32_t	: bytes  9 - 12 of the digest
751  *          uint32_t	: bytes 12 - 16 of the digest
752  *          MD5_CTX *   : the context to update
753  *          uint8_t [64]: the block to use to update the digest
754  *  output: void
755  */
756 
757 static void
758 MD5Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d,
759     MD5_CTX *ctx, const uint8_t block[64])
760 {
761 	/*
762 	 * general optimization:
763 	 *
764 	 * use individual integers instead of using an array.  this is a
765 	 * win, although the amount it wins by seems to vary quite a bit.
766 	 */
767 
768 	register uint32_t	x_0, x_1, x_2,  x_3,  x_4,  x_5,  x_6,  x_7;
769 	register uint32_t	x_8, x_9, x_10, x_11, x_12, x_13, x_14, x_15;
770 #ifdef sun4v
771 	unsigned long long 	*md5_consts64;
772 
773 	md5_consts64 = (unsigned long long *) md5_consts;
774 #endif	/* sun4v */
775 
776 	/*
777 	 * general optimization:
778 	 *
779 	 * the compiler (at least SC4.2/5.x) generates better code if
780 	 * variable use is localized.  in this case, swapping the integers in
781 	 * this order allows `x_0 'to be swapped nearest to its first use in
782 	 * FF(), and likewise for `x_1' and up.  note that the compiler
783 	 * prefers this to doing each swap right before the FF() that
784 	 * uses it.
785 	 */
786 
787 	/*
788 	 * sparc v9/v8plus optimization:
789 	 *
790 	 * if `block' is already aligned on a 4-byte boundary, use the
791 	 * optimized load_little_32() directly.  otherwise, bcopy()
792 	 * into a buffer that *is* aligned on a 4-byte boundary and
793 	 * then do the load_little_32() on that buffer.  benchmarks
794 	 * have shown that using the bcopy() is better than loading
795 	 * the bytes individually and doing the endian-swap by hand.
796 	 *
797 	 * even though it's quite tempting to assign to do:
798 	 *
799 	 * blk = bcopy(blk, ctx->buf_un.buf32, sizeof (ctx->buf_un.buf32));
800 	 *
801 	 * and only have one set of LOAD_LITTLE_32()'s, the compiler (at least
802 	 * SC4.2/5.x) *does not* like that, so please resist the urge.
803 	 */
804 
805 #ifdef _MD5_CHECK_ALIGNMENT
806 	if ((uintptr_t)block & 0x3) {		/* not 4-byte aligned? */
807 		bcopy(block, ctx->buf_un.buf32, sizeof (ctx->buf_un.buf32));
808 
809 #ifdef sun4v
810 		x_15 = LOAD_LITTLE_32_f(ctx->buf_un.buf32);
811 		x_14 = LOAD_LITTLE_32_e(ctx->buf_un.buf32);
812 		x_13 = LOAD_LITTLE_32_d(ctx->buf_un.buf32);
813 		x_12 = LOAD_LITTLE_32_c(ctx->buf_un.buf32);
814 		x_11 = LOAD_LITTLE_32_b(ctx->buf_un.buf32);
815 		x_10 = LOAD_LITTLE_32_a(ctx->buf_un.buf32);
816 		x_9  = LOAD_LITTLE_32_9(ctx->buf_un.buf32);
817 		x_8  = LOAD_LITTLE_32_8(ctx->buf_un.buf32);
818 		x_7  = LOAD_LITTLE_32_7(ctx->buf_un.buf32);
819 		x_6  = LOAD_LITTLE_32_6(ctx->buf_un.buf32);
820 		x_5  = LOAD_LITTLE_32_5(ctx->buf_un.buf32);
821 		x_4  = LOAD_LITTLE_32_4(ctx->buf_un.buf32);
822 		x_3  = LOAD_LITTLE_32_3(ctx->buf_un.buf32);
823 		x_2  = LOAD_LITTLE_32_2(ctx->buf_un.buf32);
824 		x_1  = LOAD_LITTLE_32_1(ctx->buf_un.buf32);
825 		x_0  = LOAD_LITTLE_32_0(ctx->buf_un.buf32);
826 #else
827 		x_15 = LOAD_LITTLE_32(ctx->buf_un.buf32 + 15);
828 		x_14 = LOAD_LITTLE_32(ctx->buf_un.buf32 + 14);
829 		x_13 = LOAD_LITTLE_32(ctx->buf_un.buf32 + 13);
830 		x_12 = LOAD_LITTLE_32(ctx->buf_un.buf32 + 12);
831 		x_11 = LOAD_LITTLE_32(ctx->buf_un.buf32 + 11);
832 		x_10 = LOAD_LITTLE_32(ctx->buf_un.buf32 + 10);
833 		x_9  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  9);
834 		x_8  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  8);
835 		x_7  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  7);
836 		x_6  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  6);
837 		x_5  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  5);
838 		x_4  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  4);
839 		x_3  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  3);
840 		x_2  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  2);
841 		x_1  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  1);
842 		x_0  = LOAD_LITTLE_32(ctx->buf_un.buf32 +  0);
843 #endif /* sun4v */
844 	} else
845 #endif
846 	{
847 
848 #ifdef sun4v
849 		x_15 = LOAD_LITTLE_32_f(block);
850 		x_14 = LOAD_LITTLE_32_e(block);
851 		x_13 = LOAD_LITTLE_32_d(block);
852 		x_12 = LOAD_LITTLE_32_c(block);
853 		x_11 = LOAD_LITTLE_32_b(block);
854 		x_10 = LOAD_LITTLE_32_a(block);
855 		x_9  = LOAD_LITTLE_32_9(block);
856 		x_8  = LOAD_LITTLE_32_8(block);
857 		x_7  = LOAD_LITTLE_32_7(block);
858 		x_6  = LOAD_LITTLE_32_6(block);
859 		x_5  = LOAD_LITTLE_32_5(block);
860 		x_4  = LOAD_LITTLE_32_4(block);
861 		x_3  = LOAD_LITTLE_32_3(block);
862 		x_2  = LOAD_LITTLE_32_2(block);
863 		x_1  = LOAD_LITTLE_32_1(block);
864 		x_0  = LOAD_LITTLE_32_0(block);
865 #else
866 		x_15 = LOAD_LITTLE_32(block + 60);
867 		x_14 = LOAD_LITTLE_32(block + 56);
868 		x_13 = LOAD_LITTLE_32(block + 52);
869 		x_12 = LOAD_LITTLE_32(block + 48);
870 		x_11 = LOAD_LITTLE_32(block + 44);
871 		x_10 = LOAD_LITTLE_32(block + 40);
872 		x_9  = LOAD_LITTLE_32(block + 36);
873 		x_8  = LOAD_LITTLE_32(block + 32);
874 		x_7  = LOAD_LITTLE_32(block + 28);
875 		x_6  = LOAD_LITTLE_32(block + 24);
876 		x_5  = LOAD_LITTLE_32(block + 20);
877 		x_4  = LOAD_LITTLE_32(block + 16);
878 		x_3  = LOAD_LITTLE_32(block + 12);
879 		x_2  = LOAD_LITTLE_32(block +  8);
880 		x_1  = LOAD_LITTLE_32(block +  4);
881 		x_0  = LOAD_LITTLE_32(block +  0);
882 #endif /* sun4v */
883 	}
884 
885 	/* round 1 */
886 	FF(a, b, c, d, 	x_0, MD5_SHIFT_11, MD5_CONST_e(0));  /* 1 */
887 	FF(d, a, b, c, 	x_1, MD5_SHIFT_12, MD5_CONST_o(1));  /* 2 */
888 	FF(c, d, a, b, 	x_2, MD5_SHIFT_13, MD5_CONST_e(2));  /* 3 */
889 	FF(b, c, d, a, 	x_3, MD5_SHIFT_14, MD5_CONST_o(3));  /* 4 */
890 	FF(a, b, c, d, 	x_4, MD5_SHIFT_11, MD5_CONST_e(4));  /* 5 */
891 	FF(d, a, b, c, 	x_5, MD5_SHIFT_12, MD5_CONST_o(5));  /* 6 */
892 	FF(c, d, a, b, 	x_6, MD5_SHIFT_13, MD5_CONST_e(6));  /* 7 */
893 	FF(b, c, d, a, 	x_7, MD5_SHIFT_14, MD5_CONST_o(7));  /* 8 */
894 	FF(a, b, c, d, 	x_8, MD5_SHIFT_11, MD5_CONST_e(8));  /* 9 */
895 	FF(d, a, b, c, 	x_9, MD5_SHIFT_12, MD5_CONST_o(9));  /* 10 */
896 	FF(c, d, a, b, x_10, MD5_SHIFT_13, MD5_CONST_e(10)); /* 11 */
897 	FF(b, c, d, a, x_11, MD5_SHIFT_14, MD5_CONST_o(11)); /* 12 */
898 	FF(a, b, c, d, x_12, MD5_SHIFT_11, MD5_CONST_e(12)); /* 13 */
899 	FF(d, a, b, c, x_13, MD5_SHIFT_12, MD5_CONST_o(13)); /* 14 */
900 	FF(c, d, a, b, x_14, MD5_SHIFT_13, MD5_CONST_e(14)); /* 15 */
901 	FF(b, c, d, a, x_15, MD5_SHIFT_14, MD5_CONST_o(15)); /* 16 */
902 
903 	/* round 2 */
904 	GG(a, b, c, d,  x_1, MD5_SHIFT_21, MD5_CONST_e(16)); /* 17 */
905 	GG(d, a, b, c,  x_6, MD5_SHIFT_22, MD5_CONST_o(17)); /* 18 */
906 	GG(c, d, a, b, x_11, MD5_SHIFT_23, MD5_CONST_e(18)); /* 19 */
907 	GG(b, c, d, a,  x_0, MD5_SHIFT_24, MD5_CONST_o(19)); /* 20 */
908 	GG(a, b, c, d,  x_5, MD5_SHIFT_21, MD5_CONST_e(20)); /* 21 */
909 	GG(d, a, b, c, x_10, MD5_SHIFT_22, MD5_CONST_o(21)); /* 22 */
910 	GG(c, d, a, b, x_15, MD5_SHIFT_23, MD5_CONST_e(22)); /* 23 */
911 	GG(b, c, d, a,  x_4, MD5_SHIFT_24, MD5_CONST_o(23)); /* 24 */
912 	GG(a, b, c, d,  x_9, MD5_SHIFT_21, MD5_CONST_e(24)); /* 25 */
913 	GG(d, a, b, c, x_14, MD5_SHIFT_22, MD5_CONST_o(25)); /* 26 */
914 	GG(c, d, a, b,  x_3, MD5_SHIFT_23, MD5_CONST_e(26)); /* 27 */
915 	GG(b, c, d, a,  x_8, MD5_SHIFT_24, MD5_CONST_o(27)); /* 28 */
916 	GG(a, b, c, d, x_13, MD5_SHIFT_21, MD5_CONST_e(28)); /* 29 */
917 	GG(d, a, b, c,  x_2, MD5_SHIFT_22, MD5_CONST_o(29)); /* 30 */
918 	GG(c, d, a, b,  x_7, MD5_SHIFT_23, MD5_CONST_e(30)); /* 31 */
919 	GG(b, c, d, a, x_12, MD5_SHIFT_24, MD5_CONST_o(31)); /* 32 */
920 
921 	/* round 3 */
922 	HH(a, b, c, d,  x_5, MD5_SHIFT_31, MD5_CONST_e(32)); /* 33 */
923 	HH(d, a, b, c,  x_8, MD5_SHIFT_32, MD5_CONST_o(33)); /* 34 */
924 	HH(c, d, a, b, x_11, MD5_SHIFT_33, MD5_CONST_e(34)); /* 35 */
925 	HH(b, c, d, a, x_14, MD5_SHIFT_34, MD5_CONST_o(35)); /* 36 */
926 	HH(a, b, c, d,  x_1, MD5_SHIFT_31, MD5_CONST_e(36)); /* 37 */
927 	HH(d, a, b, c,  x_4, MD5_SHIFT_32, MD5_CONST_o(37)); /* 38 */
928 	HH(c, d, a, b,  x_7, MD5_SHIFT_33, MD5_CONST_e(38)); /* 39 */
929 	HH(b, c, d, a, x_10, MD5_SHIFT_34, MD5_CONST_o(39)); /* 40 */
930 	HH(a, b, c, d, x_13, MD5_SHIFT_31, MD5_CONST_e(40)); /* 41 */
931 	HH(d, a, b, c,  x_0, MD5_SHIFT_32, MD5_CONST_o(41)); /* 42 */
932 	HH(c, d, a, b,  x_3, MD5_SHIFT_33, MD5_CONST_e(42)); /* 43 */
933 	HH(b, c, d, a,  x_6, MD5_SHIFT_34, MD5_CONST_o(43)); /* 44 */
934 	HH(a, b, c, d,  x_9, MD5_SHIFT_31, MD5_CONST_e(44)); /* 45 */
935 	HH(d, a, b, c, x_12, MD5_SHIFT_32, MD5_CONST_o(45)); /* 46 */
936 	HH(c, d, a, b, x_15, MD5_SHIFT_33, MD5_CONST_e(46)); /* 47 */
937 	HH(b, c, d, a,  x_2, MD5_SHIFT_34, MD5_CONST_o(47)); /* 48 */
938 
939 	/* round 4 */
940 	II(a, b, c, d,  x_0, MD5_SHIFT_41, MD5_CONST_e(48)); /* 49 */
941 	II(d, a, b, c,  x_7, MD5_SHIFT_42, MD5_CONST_o(49)); /* 50 */
942 	II(c, d, a, b, x_14, MD5_SHIFT_43, MD5_CONST_e(50)); /* 51 */
943 	II(b, c, d, a,  x_5, MD5_SHIFT_44, MD5_CONST_o(51)); /* 52 */
944 	II(a, b, c, d, x_12, MD5_SHIFT_41, MD5_CONST_e(52)); /* 53 */
945 	II(d, a, b, c,  x_3, MD5_SHIFT_42, MD5_CONST_o(53)); /* 54 */
946 	II(c, d, a, b, x_10, MD5_SHIFT_43, MD5_CONST_e(54)); /* 55 */
947 	II(b, c, d, a,  x_1, MD5_SHIFT_44, MD5_CONST_o(55)); /* 56 */
948 	II(a, b, c, d,  x_8, MD5_SHIFT_41, MD5_CONST_e(56)); /* 57 */
949 	II(d, a, b, c, x_15, MD5_SHIFT_42, MD5_CONST_o(57)); /* 58 */
950 	II(c, d, a, b,  x_6, MD5_SHIFT_43, MD5_CONST_e(58)); /* 59 */
951 	II(b, c, d, a, x_13, MD5_SHIFT_44, MD5_CONST_o(59)); /* 60 */
952 	II(a, b, c, d,  x_4, MD5_SHIFT_41, MD5_CONST_e(60)); /* 61 */
953 	II(d, a, b, c, x_11, MD5_SHIFT_42, MD5_CONST_o(61)); /* 62 */
954 	II(c, d, a, b,  x_2, MD5_SHIFT_43, MD5_CONST_e(62)); /* 63 */
955 	II(b, c, d, a,  x_9, MD5_SHIFT_44, MD5_CONST_o(63)); /* 64 */
956 
957 	ctx->state[0] += a;
958 	ctx->state[1] += b;
959 	ctx->state[2] += c;
960 	ctx->state[3] += d;
961 
962 	/*
963 	 * zeroize sensitive information -- compiler will optimize
964 	 * this out if everything is kept in registers
965 	 */
966 
967 	x_0 = x_1  = x_2  = x_3  = x_4  = x_5  = x_6  = x_7 = x_8 = 0;
968 	x_9 = x_10 = x_11 = x_12 = x_13 = x_14 = x_15 = 0;
969 }
970 
971 /*
972  * devpro compiler optimization:
973  *
974  * the compiler can generate better code if it knows that `input' and
975  * `output' do not point to the same source.  there is no portable
976  * way to tell the compiler this, but the devpro compiler recognizes the
977  * `_Restrict' keyword to indicate this condition.  use it if possible.
978  */
979 
980 #if defined(__RESTRICT) && !defined(__GNUC__)
981 #define	restrict	_Restrict
982 #else
983 #define	restrict	/* nothing */
984 #endif
985 
986 /*
987  * Encode()
988  *
989  * purpose: to convert a list of numbers from big endian to little endian
990  *   input: uint8_t *	: place to store the converted little endian numbers
991  *	    uint32_t *	: place to get numbers to convert from
992  *          size_t	: the length of the input in bytes
993  *  output: void
994  */
995 
996 static void
997 Encode(uint8_t *restrict output, uint32_t *restrict input, size_t input_len)
998 {
999 	size_t		i, j;
1000 
1001 	for (i = 0, j = 0; j < input_len; i++, j += sizeof (uint32_t)) {
1002 
1003 #ifdef _LITTLE_ENDIAN
1004 
1005 #ifdef _MD5_CHECK_ALIGNMENT
1006 		if ((uintptr_t)output & 0x3)	/* Not 4-byte aligned */
1007 			bcopy(input + i, output + j, 4);
1008 		else *(uint32_t *)(output + j) = input[i];
1009 #else
1010 		*(uint32_t *)(output + j) = input[i];
1011 #endif /* _MD5_CHECK_ALIGNMENT */
1012 
1013 #else	/* big endian -- will work on little endian, but slowly */
1014 
1015 		output[j] = input[i] & 0xff;
1016 		output[j + 1] = (input[i] >> 8)  & 0xff;
1017 		output[j + 2] = (input[i] >> 16) & 0xff;
1018 		output[j + 3] = (input[i] >> 24) & 0xff;
1019 #endif
1020 	}
1021 }
1022 
1023 #if	defined(_KERNEL) && !defined(_BOOT)
1024 
1025 /*
1026  * KCF software provider control entry points.
1027  */
1028 /* ARGSUSED */
1029 static void
1030 md5_provider_status(crypto_provider_handle_t provider, uint_t *status)
1031 {
1032 	*status = CRYPTO_PROVIDER_READY;
1033 }
1034 
1035 /*
1036  * KCF software provider digest entry points.
1037  */
1038 
1039 static int
1040 md5_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
1041     crypto_req_handle_t req)
1042 {
1043 	if (mechanism->cm_type != MD5_MECH_INFO_TYPE)
1044 		return (CRYPTO_MECHANISM_INVALID);
1045 
1046 	/*
1047 	 * Allocate and initialize MD5 context.
1048 	 */
1049 	ctx->cc_provider_private = kmem_alloc(sizeof (md5_ctx_t),
1050 	    crypto_kmflag(req));
1051 	if (ctx->cc_provider_private == NULL)
1052 		return (CRYPTO_HOST_MEMORY);
1053 
1054 	PROV_MD5_CTX(ctx)->mc_mech_type = MD5_MECH_INFO_TYPE;
1055 	MD5Init(&PROV_MD5_CTX(ctx)->mc_md5_ctx);
1056 
1057 	return (CRYPTO_SUCCESS);
1058 }
1059 
1060 /*
1061  * Helper MD5 digest update function for uio data.
1062  */
1063 static int
1064 md5_digest_update_uio(MD5_CTX *md5_ctx, crypto_data_t *data)
1065 {
1066 	off_t offset = data->cd_offset;
1067 	size_t length = data->cd_length;
1068 	uint_t vec_idx;
1069 	size_t cur_len;
1070 
1071 	/* we support only kernel buffer */
1072 	if (data->cd_uio->uio_segflg != UIO_SYSSPACE)
1073 		return (CRYPTO_ARGUMENTS_BAD);
1074 
1075 	/*
1076 	 * Jump to the first iovec containing data to be
1077 	 * digested.
1078 	 */
1079 	for (vec_idx = 0; vec_idx < data->cd_uio->uio_iovcnt &&
1080 	    offset >= data->cd_uio->uio_iov[vec_idx].iov_len;
1081 	    offset -= data->cd_uio->uio_iov[vec_idx++].iov_len);
1082 	if (vec_idx == data->cd_uio->uio_iovcnt) {
1083 		/*
1084 		 * The caller specified an offset that is larger than the
1085 		 * total size of the buffers it provided.
1086 		 */
1087 		return (CRYPTO_DATA_LEN_RANGE);
1088 	}
1089 
1090 	/*
1091 	 * Now do the digesting on the iovecs.
1092 	 */
1093 	while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) {
1094 		cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len -
1095 		    offset, length);
1096 
1097 		MD5Update(md5_ctx, data->cd_uio->uio_iov[vec_idx].iov_base +
1098 		    offset, cur_len);
1099 
1100 		length -= cur_len;
1101 		vec_idx++;
1102 		offset = 0;
1103 	}
1104 
1105 	if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) {
1106 		/*
1107 		 * The end of the specified iovec's was reached but
1108 		 * the length requested could not be processed, i.e.
1109 		 * The caller requested to digest more data than it provided.
1110 		 */
1111 		return (CRYPTO_DATA_LEN_RANGE);
1112 	}
1113 
1114 	return (CRYPTO_SUCCESS);
1115 }
1116 
1117 /*
1118  * Helper MD5 digest final function for uio data.
1119  * digest_len is the length of the desired digest. If digest_len
1120  * is smaller than the default MD5 digest length, the caller
1121  * must pass a scratch buffer, digest_scratch, which must
1122  * be at least MD5_DIGEST_LENGTH bytes.
1123  */
1124 static int
1125 md5_digest_final_uio(MD5_CTX *md5_ctx, crypto_data_t *digest,
1126     ulong_t digest_len, uchar_t *digest_scratch)
1127 {
1128 	off_t offset = digest->cd_offset;
1129 	uint_t vec_idx;
1130 
1131 	/* we support only kernel buffer */
1132 	if (digest->cd_uio->uio_segflg != UIO_SYSSPACE)
1133 		return (CRYPTO_ARGUMENTS_BAD);
1134 
1135 	/*
1136 	 * Jump to the first iovec containing ptr to the digest to
1137 	 * be returned.
1138 	 */
1139 	for (vec_idx = 0; offset >= digest->cd_uio->uio_iov[vec_idx].iov_len &&
1140 	    vec_idx < digest->cd_uio->uio_iovcnt;
1141 	    offset -= digest->cd_uio->uio_iov[vec_idx++].iov_len);
1142 	if (vec_idx == digest->cd_uio->uio_iovcnt) {
1143 		/*
1144 		 * The caller specified an offset that is
1145 		 * larger than the total size of the buffers
1146 		 * it provided.
1147 		 */
1148 		return (CRYPTO_DATA_LEN_RANGE);
1149 	}
1150 
1151 	if (offset + digest_len <=
1152 	    digest->cd_uio->uio_iov[vec_idx].iov_len) {
1153 		/*
1154 		 * The computed MD5 digest will fit in the current
1155 		 * iovec.
1156 		 */
1157 		if (digest_len != MD5_DIGEST_LENGTH) {
1158 			/*
1159 			 * The caller requested a short digest. Digest
1160 			 * into a scratch buffer and return to
1161 			 * the user only what was requested.
1162 			 */
1163 			MD5Final(digest_scratch, md5_ctx);
1164 			bcopy(digest_scratch, (uchar_t *)digest->
1165 			    cd_uio->uio_iov[vec_idx].iov_base + offset,
1166 			    digest_len);
1167 		} else {
1168 			MD5Final((uchar_t *)digest->
1169 			    cd_uio->uio_iov[vec_idx].iov_base + offset,
1170 			    md5_ctx);
1171 		}
1172 	} else {
1173 		/*
1174 		 * The computed digest will be crossing one or more iovec's.
1175 		 * This is bad performance-wise but we need to support it.
1176 		 * Allocate a small scratch buffer on the stack and
1177 		 * copy it piece meal to the specified digest iovec's.
1178 		 */
1179 		uchar_t digest_tmp[MD5_DIGEST_LENGTH];
1180 		off_t scratch_offset = 0;
1181 		size_t length = digest_len;
1182 		size_t cur_len;
1183 
1184 		MD5Final(digest_tmp, md5_ctx);
1185 
1186 		while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) {
1187 			cur_len = MIN(digest->cd_uio->uio_iov[vec_idx].iov_len -
1188 			    offset, length);
1189 			bcopy(digest_tmp + scratch_offset,
1190 			    digest->cd_uio->uio_iov[vec_idx].iov_base + offset,
1191 			    cur_len);
1192 
1193 			length -= cur_len;
1194 			vec_idx++;
1195 			scratch_offset += cur_len;
1196 			offset = 0;
1197 		}
1198 
1199 		if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) {
1200 			/*
1201 			 * The end of the specified iovec's was reached but
1202 			 * the length requested could not be processed, i.e.
1203 			 * The caller requested to digest more data than it
1204 			 * provided.
1205 			 */
1206 			return (CRYPTO_DATA_LEN_RANGE);
1207 		}
1208 	}
1209 
1210 	return (CRYPTO_SUCCESS);
1211 }
1212 
1213 /*
1214  * Helper MD5 digest update for mblk's.
1215  */
1216 static int
1217 md5_digest_update_mblk(MD5_CTX *md5_ctx, crypto_data_t *data)
1218 {
1219 	off_t offset = data->cd_offset;
1220 	size_t length = data->cd_length;
1221 	mblk_t *mp;
1222 	size_t cur_len;
1223 
1224 	/*
1225 	 * Jump to the first mblk_t containing data to be digested.
1226 	 */
1227 	for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp);
1228 	    offset -= MBLKL(mp), mp = mp->b_cont);
1229 	if (mp == NULL) {
1230 		/*
1231 		 * The caller specified an offset that is larger than the
1232 		 * total size of the buffers it provided.
1233 		 */
1234 		return (CRYPTO_DATA_LEN_RANGE);
1235 	}
1236 
1237 	/*
1238 	 * Now do the digesting on the mblk chain.
1239 	 */
1240 	while (mp != NULL && length > 0) {
1241 		cur_len = MIN(MBLKL(mp) - offset, length);
1242 		MD5Update(md5_ctx, mp->b_rptr + offset, cur_len);
1243 		length -= cur_len;
1244 		offset = 0;
1245 		mp = mp->b_cont;
1246 	}
1247 
1248 	if (mp == NULL && length > 0) {
1249 		/*
1250 		 * The end of the mblk was reached but the length requested
1251 		 * could not be processed, i.e. The caller requested
1252 		 * to digest more data than it provided.
1253 		 */
1254 		return (CRYPTO_DATA_LEN_RANGE);
1255 	}
1256 
1257 	return (CRYPTO_SUCCESS);
1258 }
1259 
1260 /*
1261  * Helper MD5 digest final for mblk's.
1262  * digest_len is the length of the desired digest. If digest_len
1263  * is smaller than the default MD5 digest length, the caller
1264  * must pass a scratch buffer, digest_scratch, which must
1265  * be at least MD5_DIGEST_LENGTH bytes.
1266  */
1267 static int
1268 md5_digest_final_mblk(MD5_CTX *md5_ctx, crypto_data_t *digest,
1269     ulong_t digest_len, uchar_t *digest_scratch)
1270 {
1271 	off_t offset = digest->cd_offset;
1272 	mblk_t *mp;
1273 
1274 	/*
1275 	 * Jump to the first mblk_t that will be used to store the digest.
1276 	 */
1277 	for (mp = digest->cd_mp; mp != NULL && offset >= MBLKL(mp);
1278 	    offset -= MBLKL(mp), mp = mp->b_cont);
1279 	if (mp == NULL) {
1280 		/*
1281 		 * The caller specified an offset that is larger than the
1282 		 * total size of the buffers it provided.
1283 		 */
1284 		return (CRYPTO_DATA_LEN_RANGE);
1285 	}
1286 
1287 	if (offset + digest_len <= MBLKL(mp)) {
1288 		/*
1289 		 * The computed MD5 digest will fit in the current mblk.
1290 		 * Do the MD5Final() in-place.
1291 		 */
1292 		if (digest_len != MD5_DIGEST_LENGTH) {
1293 			/*
1294 			 * The caller requested a short digest. Digest
1295 			 * into a scratch buffer and return to
1296 			 * the user only what was requested.
1297 			 */
1298 			MD5Final(digest_scratch, md5_ctx);
1299 			bcopy(digest_scratch, mp->b_rptr + offset, digest_len);
1300 		} else {
1301 			MD5Final(mp->b_rptr + offset, md5_ctx);
1302 		}
1303 	} else {
1304 		/*
1305 		 * The computed digest will be crossing one or more mblk's.
1306 		 * This is bad performance-wise but we need to support it.
1307 		 * Allocate a small scratch buffer on the stack and
1308 		 * copy it piece meal to the specified digest iovec's.
1309 		 */
1310 		uchar_t digest_tmp[MD5_DIGEST_LENGTH];
1311 		off_t scratch_offset = 0;
1312 		size_t length = digest_len;
1313 		size_t cur_len;
1314 
1315 		MD5Final(digest_tmp, md5_ctx);
1316 
1317 		while (mp != NULL && length > 0) {
1318 			cur_len = MIN(MBLKL(mp) - offset, length);
1319 			bcopy(digest_tmp + scratch_offset,
1320 			    mp->b_rptr + offset, cur_len);
1321 
1322 			length -= cur_len;
1323 			mp = mp->b_cont;
1324 			scratch_offset += cur_len;
1325 			offset = 0;
1326 		}
1327 
1328 		if (mp == NULL && length > 0) {
1329 			/*
1330 			 * The end of the specified mblk was reached but
1331 			 * the length requested could not be processed, i.e.
1332 			 * The caller requested to digest more data than it
1333 			 * provided.
1334 			 */
1335 			return (CRYPTO_DATA_LEN_RANGE);
1336 		}
1337 	}
1338 
1339 	return (CRYPTO_SUCCESS);
1340 }
1341 
1342 /* ARGSUSED */
1343 static int
1344 md5_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest,
1345     crypto_req_handle_t req)
1346 {
1347 	int ret = CRYPTO_SUCCESS;
1348 
1349 	ASSERT(ctx->cc_provider_private != NULL);
1350 
1351 	/*
1352 	 * We need to just return the length needed to store the output.
1353 	 * We should not destroy the context for the following cases.
1354 	 */
1355 	if ((digest->cd_length == 0) ||
1356 	    (digest->cd_length < MD5_DIGEST_LENGTH)) {
1357 		digest->cd_length = MD5_DIGEST_LENGTH;
1358 		return (CRYPTO_BUFFER_TOO_SMALL);
1359 	}
1360 
1361 	/*
1362 	 * Do the MD5 update on the specified input data.
1363 	 */
1364 	switch (data->cd_format) {
1365 	case CRYPTO_DATA_RAW:
1366 		MD5Update(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1367 		    data->cd_raw.iov_base + data->cd_offset,
1368 		    data->cd_length);
1369 		break;
1370 	case CRYPTO_DATA_UIO:
1371 		ret = md5_digest_update_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1372 		    data);
1373 		break;
1374 	case CRYPTO_DATA_MBLK:
1375 		ret = md5_digest_update_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1376 		    data);
1377 		break;
1378 	default:
1379 		ret = CRYPTO_ARGUMENTS_BAD;
1380 	}
1381 
1382 	if (ret != CRYPTO_SUCCESS) {
1383 		/* the update failed, free context and bail */
1384 		kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
1385 		ctx->cc_provider_private = NULL;
1386 		digest->cd_length = 0;
1387 		return (ret);
1388 	}
1389 
1390 	/*
1391 	 * Do an MD5 final, must be done separately since the digest
1392 	 * type can be different than the input data type.
1393 	 */
1394 	switch (digest->cd_format) {
1395 	case CRYPTO_DATA_RAW:
1396 		MD5Final((unsigned char *)digest->cd_raw.iov_base +
1397 		    digest->cd_offset, &PROV_MD5_CTX(ctx)->mc_md5_ctx);
1398 		break;
1399 	case CRYPTO_DATA_UIO:
1400 		ret = md5_digest_final_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1401 		    digest, MD5_DIGEST_LENGTH, NULL);
1402 		break;
1403 	case CRYPTO_DATA_MBLK:
1404 		ret = md5_digest_final_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1405 		    digest, MD5_DIGEST_LENGTH, NULL);
1406 		break;
1407 	default:
1408 		ret = CRYPTO_ARGUMENTS_BAD;
1409 	}
1410 
1411 	/* all done, free context and return */
1412 
1413 	if (ret == CRYPTO_SUCCESS) {
1414 		digest->cd_length = MD5_DIGEST_LENGTH;
1415 	} else {
1416 		digest->cd_length = 0;
1417 	}
1418 
1419 	kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
1420 	ctx->cc_provider_private = NULL;
1421 	return (ret);
1422 }
1423 
1424 /* ARGSUSED */
1425 static int
1426 md5_digest_update(crypto_ctx_t *ctx, crypto_data_t *data,
1427     crypto_req_handle_t req)
1428 {
1429 	int ret = CRYPTO_SUCCESS;
1430 
1431 	ASSERT(ctx->cc_provider_private != NULL);
1432 
1433 	/*
1434 	 * Do the MD5 update on the specified input data.
1435 	 */
1436 	switch (data->cd_format) {
1437 	case CRYPTO_DATA_RAW:
1438 		MD5Update(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1439 		    data->cd_raw.iov_base + data->cd_offset,
1440 		    data->cd_length);
1441 		break;
1442 	case CRYPTO_DATA_UIO:
1443 		ret = md5_digest_update_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1444 		    data);
1445 		break;
1446 	case CRYPTO_DATA_MBLK:
1447 		ret = md5_digest_update_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1448 		    data);
1449 		break;
1450 	default:
1451 		ret = CRYPTO_ARGUMENTS_BAD;
1452 	}
1453 
1454 	return (ret);
1455 }
1456 
1457 /* ARGSUSED */
1458 static int
1459 md5_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest,
1460     crypto_req_handle_t req)
1461 {
1462 	int ret = CRYPTO_SUCCESS;
1463 
1464 	ASSERT(ctx->cc_provider_private != NULL);
1465 
1466 	/*
1467 	 * We need to just return the length needed to store the output.
1468 	 * We should not destroy the context for the following cases.
1469 	 */
1470 	if ((digest->cd_length == 0) ||
1471 	    (digest->cd_length < MD5_DIGEST_LENGTH)) {
1472 		digest->cd_length = MD5_DIGEST_LENGTH;
1473 		return (CRYPTO_BUFFER_TOO_SMALL);
1474 	}
1475 
1476 	/*
1477 	 * Do an MD5 final.
1478 	 */
1479 	switch (digest->cd_format) {
1480 	case CRYPTO_DATA_RAW:
1481 		MD5Final((unsigned char *)digest->cd_raw.iov_base +
1482 		    digest->cd_offset, &PROV_MD5_CTX(ctx)->mc_md5_ctx);
1483 		break;
1484 	case CRYPTO_DATA_UIO:
1485 		ret = md5_digest_final_uio(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1486 		    digest, MD5_DIGEST_LENGTH, NULL);
1487 		break;
1488 	case CRYPTO_DATA_MBLK:
1489 		ret = md5_digest_final_mblk(&PROV_MD5_CTX(ctx)->mc_md5_ctx,
1490 		    digest, MD5_DIGEST_LENGTH, NULL);
1491 		break;
1492 	default:
1493 		ret = CRYPTO_ARGUMENTS_BAD;
1494 	}
1495 
1496 	/* all done, free context and return */
1497 
1498 	if (ret == CRYPTO_SUCCESS) {
1499 		digest->cd_length = MD5_DIGEST_LENGTH;
1500 	} else {
1501 		digest->cd_length = 0;
1502 	}
1503 
1504 	kmem_free(ctx->cc_provider_private, sizeof (md5_ctx_t));
1505 	ctx->cc_provider_private = NULL;
1506 
1507 	return (ret);
1508 }
1509 
1510 /* ARGSUSED */
1511 static int
1512 md5_digest_atomic(crypto_provider_handle_t provider,
1513     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1514     crypto_data_t *data, crypto_data_t *digest,
1515     crypto_req_handle_t req)
1516 {
1517 	int ret = CRYPTO_SUCCESS;
1518 	MD5_CTX md5_ctx;
1519 
1520 	if (mechanism->cm_type != MD5_MECH_INFO_TYPE)
1521 		return (CRYPTO_MECHANISM_INVALID);
1522 
1523 	/*
1524 	 * Do the MD5 init.
1525 	 */
1526 	MD5Init(&md5_ctx);
1527 
1528 	/*
1529 	 * Do the MD5 update on the specified input data.
1530 	 */
1531 	switch (data->cd_format) {
1532 	case CRYPTO_DATA_RAW:
1533 		MD5Update(&md5_ctx, data->cd_raw.iov_base + data->cd_offset,
1534 		    data->cd_length);
1535 		break;
1536 	case CRYPTO_DATA_UIO:
1537 		ret = md5_digest_update_uio(&md5_ctx, data);
1538 		break;
1539 	case CRYPTO_DATA_MBLK:
1540 		ret = md5_digest_update_mblk(&md5_ctx, data);
1541 		break;
1542 	default:
1543 		ret = CRYPTO_ARGUMENTS_BAD;
1544 	}
1545 
1546 	if (ret != CRYPTO_SUCCESS) {
1547 		/* the update failed, bail */
1548 		digest->cd_length = 0;
1549 		return (ret);
1550 	}
1551 
1552 	/*
1553 	 * Do an MD5 final, must be done separately since the digest
1554 	 * type can be different than the input data type.
1555 	 */
1556 	switch (digest->cd_format) {
1557 	case CRYPTO_DATA_RAW:
1558 		MD5Final((unsigned char *)digest->cd_raw.iov_base +
1559 		    digest->cd_offset, &md5_ctx);
1560 		break;
1561 	case CRYPTO_DATA_UIO:
1562 		ret = md5_digest_final_uio(&md5_ctx, digest,
1563 		    MD5_DIGEST_LENGTH, NULL);
1564 		break;
1565 	case CRYPTO_DATA_MBLK:
1566 		ret = md5_digest_final_mblk(&md5_ctx, digest,
1567 		    MD5_DIGEST_LENGTH, NULL);
1568 		break;
1569 	default:
1570 		ret = CRYPTO_ARGUMENTS_BAD;
1571 	}
1572 
1573 	if (ret == CRYPTO_SUCCESS) {
1574 		digest->cd_length = MD5_DIGEST_LENGTH;
1575 	} else {
1576 		digest->cd_length = 0;
1577 	}
1578 
1579 	return (ret);
1580 }
1581 
1582 /*
1583  * KCF software provider mac entry points.
1584  *
1585  * MD5 HMAC is: MD5(key XOR opad, MD5(key XOR ipad, text))
1586  *
1587  * Init:
1588  * The initialization routine initializes what we denote
1589  * as the inner and outer contexts by doing
1590  * - for inner context: MD5(key XOR ipad)
1591  * - for outer context: MD5(key XOR opad)
1592  *
1593  * Update:
1594  * Each subsequent MD5 HMAC update will result in an
1595  * update of the inner context with the specified data.
1596  *
1597  * Final:
1598  * The MD5 HMAC final will do a MD5 final operation on the
1599  * inner context, and the resulting digest will be used
1600  * as the data for an update on the outer context. Last
1601  * but not least, an MD5 final on the outer context will
1602  * be performed to obtain the MD5 HMAC digest to return
1603  * to the user.
1604  */
1605 
1606 /*
1607  * Initialize a MD5-HMAC context.
1608  */
1609 static void
1610 md5_mac_init_ctx(md5_hmac_ctx_t *ctx, void *keyval, uint_t length_in_bytes)
1611 {
1612 	uint32_t ipad[MD5_HMAC_INTS_PER_BLOCK];
1613 	uint32_t opad[MD5_HMAC_INTS_PER_BLOCK];
1614 	uint_t i;
1615 
1616 	bzero(ipad, MD5_HMAC_BLOCK_SIZE);
1617 	bzero(opad, MD5_HMAC_BLOCK_SIZE);
1618 
1619 	bcopy(keyval, ipad, length_in_bytes);
1620 	bcopy(keyval, opad, length_in_bytes);
1621 
1622 	/* XOR key with ipad (0x36) and opad (0x5c) */
1623 	for (i = 0; i < MD5_HMAC_INTS_PER_BLOCK; i++) {
1624 		ipad[i] ^= 0x36363636;
1625 		opad[i] ^= 0x5c5c5c5c;
1626 	}
1627 
1628 	/* perform MD5 on ipad */
1629 	MD5Init(&ctx->hc_icontext);
1630 	MD5Update(&ctx->hc_icontext, ipad, MD5_HMAC_BLOCK_SIZE);
1631 
1632 	/* perform MD5 on opad */
1633 	MD5Init(&ctx->hc_ocontext);
1634 	MD5Update(&ctx->hc_ocontext, opad, MD5_HMAC_BLOCK_SIZE);
1635 }
1636 
1637 /*
1638  * Initializes a multi-part MAC operation.
1639  */
1640 static int
1641 md5_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
1642     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
1643     crypto_req_handle_t req)
1644 {
1645 	int ret = CRYPTO_SUCCESS;
1646 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
1647 
1648 	if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
1649 	    mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
1650 		return (CRYPTO_MECHANISM_INVALID);
1651 
1652 	/* Add support for key by attributes (RFE 4706552) */
1653 	if (key->ck_format != CRYPTO_KEY_RAW)
1654 		return (CRYPTO_ARGUMENTS_BAD);
1655 
1656 	ctx->cc_provider_private = kmem_alloc(sizeof (md5_hmac_ctx_t),
1657 	    crypto_kmflag(req));
1658 	if (ctx->cc_provider_private == NULL)
1659 		return (CRYPTO_HOST_MEMORY);
1660 
1661 	if (ctx_template != NULL) {
1662 		/* reuse context template */
1663 		bcopy(ctx_template, PROV_MD5_HMAC_CTX(ctx),
1664 		    sizeof (md5_hmac_ctx_t));
1665 	} else {
1666 		/* no context template, compute context */
1667 		if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
1668 			uchar_t digested_key[MD5_DIGEST_LENGTH];
1669 			md5_hmac_ctx_t *hmac_ctx = ctx->cc_provider_private;
1670 
1671 			/*
1672 			 * Hash the passed-in key to get a smaller key.
1673 			 * The inner context is used since it hasn't been
1674 			 * initialized yet.
1675 			 */
1676 			PROV_MD5_DIGEST_KEY(&hmac_ctx->hc_icontext,
1677 			    key->ck_data, keylen_in_bytes, digested_key);
1678 			md5_mac_init_ctx(PROV_MD5_HMAC_CTX(ctx),
1679 			    digested_key, MD5_DIGEST_LENGTH);
1680 		} else {
1681 			md5_mac_init_ctx(PROV_MD5_HMAC_CTX(ctx),
1682 			    key->ck_data, keylen_in_bytes);
1683 		}
1684 	}
1685 
1686 	/*
1687 	 * Get the mechanism parameters, if applicable.
1688 	 */
1689 	PROV_MD5_HMAC_CTX(ctx)->hc_mech_type = mechanism->cm_type;
1690 	if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
1691 		if (mechanism->cm_param == NULL ||
1692 		    mechanism->cm_param_len != sizeof (ulong_t))
1693 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1694 		PROV_MD5_GET_DIGEST_LEN(mechanism,
1695 		    PROV_MD5_HMAC_CTX(ctx)->hc_digest_len);
1696 		if (PROV_MD5_HMAC_CTX(ctx)->hc_digest_len >
1697 		    MD5_DIGEST_LENGTH)
1698 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1699 	}
1700 
1701 	if (ret != CRYPTO_SUCCESS) {
1702 		bzero(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
1703 		kmem_free(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
1704 		ctx->cc_provider_private = NULL;
1705 	}
1706 
1707 	return (ret);
1708 }
1709 
1710 
1711 /* ARGSUSED */
1712 static int
1713 md5_mac_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
1714 {
1715 	int ret = CRYPTO_SUCCESS;
1716 
1717 	ASSERT(ctx->cc_provider_private != NULL);
1718 
1719 	/*
1720 	 * Do an MD5 update of the inner context using the specified
1721 	 * data.
1722 	 */
1723 	switch (data->cd_format) {
1724 	case CRYPTO_DATA_RAW:
1725 		MD5Update(&PROV_MD5_HMAC_CTX(ctx)->hc_icontext,
1726 		    data->cd_raw.iov_base + data->cd_offset,
1727 		    data->cd_length);
1728 		break;
1729 	case CRYPTO_DATA_UIO:
1730 		ret = md5_digest_update_uio(
1731 		    &PROV_MD5_HMAC_CTX(ctx)->hc_icontext, data);
1732 		break;
1733 	case CRYPTO_DATA_MBLK:
1734 		ret = md5_digest_update_mblk(
1735 		    &PROV_MD5_HMAC_CTX(ctx)->hc_icontext, data);
1736 		break;
1737 	default:
1738 		ret = CRYPTO_ARGUMENTS_BAD;
1739 	}
1740 
1741 	return (ret);
1742 }
1743 
1744 /* ARGSUSED */
1745 static int
1746 md5_mac_final(crypto_ctx_t *ctx, crypto_data_t *mac, crypto_req_handle_t req)
1747 {
1748 	int ret = CRYPTO_SUCCESS;
1749 	uchar_t digest[MD5_DIGEST_LENGTH];
1750 	uint32_t digest_len = MD5_DIGEST_LENGTH;
1751 
1752 	ASSERT(ctx->cc_provider_private != NULL);
1753 
1754 	if (PROV_MD5_HMAC_CTX(ctx)->hc_mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE)
1755 	    digest_len = PROV_MD5_HMAC_CTX(ctx)->hc_digest_len;
1756 
1757 	/*
1758 	 * We need to just return the length needed to store the output.
1759 	 * We should not destroy the context for the following cases.
1760 	 */
1761 	if ((mac->cd_length == 0) || (mac->cd_length < digest_len)) {
1762 		mac->cd_length = digest_len;
1763 		return (CRYPTO_BUFFER_TOO_SMALL);
1764 	}
1765 
1766 	/*
1767 	 * Do an MD5 final on the inner context.
1768 	 */
1769 	MD5Final(digest, &PROV_MD5_HMAC_CTX(ctx)->hc_icontext);
1770 
1771 	/*
1772 	 * Do an MD5 update on the outer context, feeding the inner
1773 	 * digest as data.
1774 	 */
1775 	MD5Update(&PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, digest,
1776 	    MD5_DIGEST_LENGTH);
1777 
1778 	/*
1779 	 * Do an MD5 final on the outer context, storing the computing
1780 	 * digest in the users buffer.
1781 	 */
1782 	switch (mac->cd_format) {
1783 	case CRYPTO_DATA_RAW:
1784 		if (digest_len != MD5_DIGEST_LENGTH) {
1785 			/*
1786 			 * The caller requested a short digest. Digest
1787 			 * into a scratch buffer and return to
1788 			 * the user only what was requested.
1789 			 */
1790 			MD5Final(digest,
1791 			    &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext);
1792 			bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
1793 			    mac->cd_offset, digest_len);
1794 		} else {
1795 			MD5Final((unsigned char *)mac->cd_raw.iov_base +
1796 			    mac->cd_offset,
1797 			    &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext);
1798 		}
1799 		break;
1800 	case CRYPTO_DATA_UIO:
1801 		ret = md5_digest_final_uio(
1802 		    &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, mac,
1803 		    digest_len, digest);
1804 		break;
1805 	case CRYPTO_DATA_MBLK:
1806 		ret = md5_digest_final_mblk(
1807 		    &PROV_MD5_HMAC_CTX(ctx)->hc_ocontext, mac,
1808 		    digest_len, digest);
1809 		break;
1810 	default:
1811 		ret = CRYPTO_ARGUMENTS_BAD;
1812 	}
1813 
1814 	if (ret == CRYPTO_SUCCESS) {
1815 		mac->cd_length = digest_len;
1816 	} else {
1817 		mac->cd_length = 0;
1818 	}
1819 
1820 	bzero(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
1821 	kmem_free(ctx->cc_provider_private, sizeof (md5_hmac_ctx_t));
1822 	ctx->cc_provider_private = NULL;
1823 
1824 	return (ret);
1825 }
1826 
1827 #define	MD5_MAC_UPDATE(data, ctx, ret) {				\
1828 	switch (data->cd_format) {					\
1829 	case CRYPTO_DATA_RAW:						\
1830 		MD5Update(&(ctx).hc_icontext,				\
1831 		    data->cd_raw.iov_base + data->cd_offset,		\
1832 		    data->cd_length);					\
1833 		break;							\
1834 	case CRYPTO_DATA_UIO:						\
1835 		ret = md5_digest_update_uio(&(ctx).hc_icontext,	data);	\
1836 		break;							\
1837 	case CRYPTO_DATA_MBLK:						\
1838 		ret = md5_digest_update_mblk(&(ctx).hc_icontext,	\
1839 		    data);						\
1840 		break;							\
1841 	default:							\
1842 		ret = CRYPTO_ARGUMENTS_BAD;				\
1843 	}								\
1844 }
1845 
1846 
1847 /* ARGSUSED */
1848 static int
1849 md5_mac_atomic(crypto_provider_handle_t provider,
1850     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1851     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
1852     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
1853 {
1854 	int ret = CRYPTO_SUCCESS;
1855 	uchar_t digest[MD5_DIGEST_LENGTH];
1856 	md5_hmac_ctx_t md5_hmac_ctx;
1857 	uint32_t digest_len = MD5_DIGEST_LENGTH;
1858 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
1859 
1860 	if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
1861 	    mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
1862 		return (CRYPTO_MECHANISM_INVALID);
1863 
1864 	/* Add support for key by attributes (RFE 4706552) */
1865 	if (key->ck_format != CRYPTO_KEY_RAW)
1866 		return (CRYPTO_ARGUMENTS_BAD);
1867 
1868 	if (ctx_template != NULL) {
1869 		/* reuse context template */
1870 		bcopy(ctx_template, &md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
1871 	} else {
1872 		/* no context template, compute context */
1873 		if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
1874 			/*
1875 			 * Hash the passed-in key to get a smaller key.
1876 			 * The inner context is used since it hasn't been
1877 			 * initialized yet.
1878 			 */
1879 			PROV_MD5_DIGEST_KEY(&md5_hmac_ctx.hc_icontext,
1880 			    key->ck_data, keylen_in_bytes, digest);
1881 			md5_mac_init_ctx(&md5_hmac_ctx, digest,
1882 			    MD5_DIGEST_LENGTH);
1883 		} else {
1884 			md5_mac_init_ctx(&md5_hmac_ctx, key->ck_data,
1885 			    keylen_in_bytes);
1886 		}
1887 	}
1888 
1889 	/*
1890 	 * Get the mechanism parameters, if applicable.
1891 	 */
1892 	if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
1893 		if (mechanism->cm_param == NULL ||
1894 		    mechanism->cm_param_len != sizeof (ulong_t)) {
1895 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1896 			goto bail;
1897 		}
1898 		PROV_MD5_GET_DIGEST_LEN(mechanism, digest_len);
1899 		if (digest_len > MD5_DIGEST_LENGTH) {
1900 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
1901 			goto bail;
1902 		}
1903 	}
1904 
1905 	/* do an MD5 update of the inner context using the specified data */
1906 	MD5_MAC_UPDATE(data, md5_hmac_ctx, ret);
1907 	if (ret != CRYPTO_SUCCESS)
1908 		/* the update failed, free context and bail */
1909 		goto bail;
1910 
1911 	/* do an MD5 final on the inner context */
1912 	MD5Final(digest, &md5_hmac_ctx.hc_icontext);
1913 
1914 	/*
1915 	 * Do an MD5 update on the outer context, feeding the inner
1916 	 * digest as data.
1917 	 */
1918 	MD5Update(&md5_hmac_ctx.hc_ocontext, digest, MD5_DIGEST_LENGTH);
1919 
1920 	/*
1921 	 * Do an MD5 final on the outer context, storing the computed
1922 	 * digest in the users buffer.
1923 	 */
1924 	switch (mac->cd_format) {
1925 	case CRYPTO_DATA_RAW:
1926 		if (digest_len != MD5_DIGEST_LENGTH) {
1927 			/*
1928 			 * The caller requested a short digest. Digest
1929 			 * into a scratch buffer and return to
1930 			 * the user only what was requested.
1931 			 */
1932 			MD5Final(digest, &md5_hmac_ctx.hc_ocontext);
1933 			bcopy(digest, (unsigned char *)mac->cd_raw.iov_base +
1934 			    mac->cd_offset, digest_len);
1935 		} else {
1936 			MD5Final((unsigned char *)mac->cd_raw.iov_base +
1937 			    mac->cd_offset, &md5_hmac_ctx.hc_ocontext);
1938 		}
1939 		break;
1940 	case CRYPTO_DATA_UIO:
1941 		ret = md5_digest_final_uio(&md5_hmac_ctx.hc_ocontext, mac,
1942 		    digest_len, digest);
1943 		break;
1944 	case CRYPTO_DATA_MBLK:
1945 		ret = md5_digest_final_mblk(&md5_hmac_ctx.hc_ocontext, mac,
1946 		    digest_len, digest);
1947 		break;
1948 	default:
1949 		ret = CRYPTO_ARGUMENTS_BAD;
1950 	}
1951 
1952 	if (ret == CRYPTO_SUCCESS) {
1953 		mac->cd_length = digest_len;
1954 	} else {
1955 		mac->cd_length = 0;
1956 	}
1957 	/* Extra paranoia: zeroizing the local context on the stack */
1958 	bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
1959 
1960 	return (ret);
1961 bail:
1962 	bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
1963 	mac->cd_length = 0;
1964 	return (ret);
1965 }
1966 
1967 /* ARGSUSED */
1968 static int
1969 md5_mac_verify_atomic(crypto_provider_handle_t provider,
1970     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1971     crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac,
1972     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
1973 {
1974 	int ret = CRYPTO_SUCCESS;
1975 	uchar_t digest[MD5_DIGEST_LENGTH];
1976 	md5_hmac_ctx_t md5_hmac_ctx;
1977 	uint32_t digest_len = MD5_DIGEST_LENGTH;
1978 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
1979 
1980 	if (mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE &&
1981 	    mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE)
1982 		return (CRYPTO_MECHANISM_INVALID);
1983 
1984 	/* Add support for key by attributes (RFE 4706552) */
1985 	if (key->ck_format != CRYPTO_KEY_RAW)
1986 		return (CRYPTO_ARGUMENTS_BAD);
1987 
1988 	if (ctx_template != NULL) {
1989 		/* reuse context template */
1990 		bcopy(ctx_template, &md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
1991 	} else {
1992 		/* no context template, compute context */
1993 		if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
1994 			/*
1995 			 * Hash the passed-in key to get a smaller key.
1996 			 * The inner context is used since it hasn't been
1997 			 * initialized yet.
1998 			 */
1999 			PROV_MD5_DIGEST_KEY(&md5_hmac_ctx.hc_icontext,
2000 			    key->ck_data, keylen_in_bytes, digest);
2001 			md5_mac_init_ctx(&md5_hmac_ctx, digest,
2002 			    MD5_DIGEST_LENGTH);
2003 		} else {
2004 			md5_mac_init_ctx(&md5_hmac_ctx, key->ck_data,
2005 			    keylen_in_bytes);
2006 		}
2007 	}
2008 
2009 	/*
2010 	 * Get the mechanism parameters, if applicable.
2011 	 */
2012 	if (mechanism->cm_type == MD5_HMAC_GEN_MECH_INFO_TYPE) {
2013 		if (mechanism->cm_param == NULL ||
2014 		    mechanism->cm_param_len != sizeof (ulong_t)) {
2015 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
2016 			goto bail;
2017 		}
2018 		PROV_MD5_GET_DIGEST_LEN(mechanism, digest_len);
2019 		if (digest_len > MD5_DIGEST_LENGTH) {
2020 			ret = CRYPTO_MECHANISM_PARAM_INVALID;
2021 			goto bail;
2022 		}
2023 	}
2024 
2025 	if (mac->cd_length != digest_len) {
2026 		ret = CRYPTO_INVALID_MAC;
2027 		goto bail;
2028 	}
2029 
2030 	/* do an MD5 update of the inner context using the specified data */
2031 	MD5_MAC_UPDATE(data, md5_hmac_ctx, ret);
2032 	if (ret != CRYPTO_SUCCESS)
2033 		/* the update failed, free context and bail */
2034 		goto bail;
2035 
2036 	/* do an MD5 final on the inner context */
2037 	MD5Final(digest, &md5_hmac_ctx.hc_icontext);
2038 
2039 	/*
2040 	 * Do an MD5 update on the outer context, feeding the inner
2041 	 * digest as data.
2042 	 */
2043 	MD5Update(&md5_hmac_ctx.hc_ocontext, digest, MD5_DIGEST_LENGTH);
2044 
2045 	/*
2046 	 * Do an MD5 final on the outer context, storing the computed
2047 	 * digest in the local digest buffer.
2048 	 */
2049 	MD5Final(digest, &md5_hmac_ctx.hc_ocontext);
2050 
2051 	/*
2052 	 * Compare the computed digest against the expected digest passed
2053 	 * as argument.
2054 	 */
2055 	switch (mac->cd_format) {
2056 
2057 	case CRYPTO_DATA_RAW:
2058 		if (bcmp(digest, (unsigned char *)mac->cd_raw.iov_base +
2059 		    mac->cd_offset, digest_len) != 0)
2060 			ret = CRYPTO_INVALID_MAC;
2061 		break;
2062 
2063 	case CRYPTO_DATA_UIO: {
2064 		off_t offset = mac->cd_offset;
2065 		uint_t vec_idx;
2066 		off_t scratch_offset = 0;
2067 		size_t length = digest_len;
2068 		size_t cur_len;
2069 
2070 		/* we support only kernel buffer */
2071 		if (mac->cd_uio->uio_segflg != UIO_SYSSPACE)
2072 			return (CRYPTO_ARGUMENTS_BAD);
2073 
2074 		/* jump to the first iovec containing the expected digest */
2075 		for (vec_idx = 0;
2076 		    offset >= mac->cd_uio->uio_iov[vec_idx].iov_len &&
2077 		    vec_idx < mac->cd_uio->uio_iovcnt;
2078 		    offset -= mac->cd_uio->uio_iov[vec_idx++].iov_len);
2079 		if (vec_idx == mac->cd_uio->uio_iovcnt) {
2080 			/*
2081 			 * The caller specified an offset that is
2082 			 * larger than the total size of the buffers
2083 			 * it provided.
2084 			 */
2085 			ret = CRYPTO_DATA_LEN_RANGE;
2086 			break;
2087 		}
2088 
2089 		/* do the comparison of computed digest vs specified one */
2090 		while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) {
2091 			cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len -
2092 			    offset, length);
2093 
2094 			if (bcmp(digest + scratch_offset,
2095 			    mac->cd_uio->uio_iov[vec_idx].iov_base + offset,
2096 			    cur_len) != 0) {
2097 				ret = CRYPTO_INVALID_MAC;
2098 				break;
2099 			}
2100 
2101 			length -= cur_len;
2102 			vec_idx++;
2103 			scratch_offset += cur_len;
2104 			offset = 0;
2105 		}
2106 		break;
2107 	}
2108 
2109 	case CRYPTO_DATA_MBLK: {
2110 		off_t offset = mac->cd_offset;
2111 		mblk_t *mp;
2112 		off_t scratch_offset = 0;
2113 		size_t length = digest_len;
2114 		size_t cur_len;
2115 
2116 		/* jump to the first mblk_t containing the expected digest */
2117 		for (mp = mac->cd_mp; mp != NULL && offset >= MBLKL(mp);
2118 		    offset -= MBLKL(mp), mp = mp->b_cont);
2119 		if (mp == NULL) {
2120 			/*
2121 			 * The caller specified an offset that is larger than
2122 			 * the total size of the buffers it provided.
2123 			 */
2124 			ret = CRYPTO_DATA_LEN_RANGE;
2125 			break;
2126 		}
2127 
2128 		while (mp != NULL && length > 0) {
2129 			cur_len = MIN(MBLKL(mp) - offset, length);
2130 			if (bcmp(digest + scratch_offset,
2131 			    mp->b_rptr + offset, cur_len) != 0) {
2132 				ret = CRYPTO_INVALID_MAC;
2133 				break;
2134 			}
2135 
2136 			length -= cur_len;
2137 			mp = mp->b_cont;
2138 			scratch_offset += cur_len;
2139 			offset = 0;
2140 		}
2141 		break;
2142 	}
2143 
2144 	default:
2145 		ret = CRYPTO_ARGUMENTS_BAD;
2146 	}
2147 
2148 	bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
2149 	return (ret);
2150 bail:
2151 	bzero(&md5_hmac_ctx, sizeof (md5_hmac_ctx_t));
2152 	mac->cd_length = 0;
2153 	return (ret);
2154 }
2155 
2156 /*
2157  * KCF software provider context management entry points.
2158  */
2159 
2160 /* ARGSUSED */
2161 static int
2162 md5_create_ctx_template(crypto_provider_handle_t provider,
2163     crypto_mechanism_t *mechanism, crypto_key_t *key,
2164     crypto_spi_ctx_template_t *ctx_template, size_t *ctx_template_size,
2165     crypto_req_handle_t req)
2166 {
2167 	md5_hmac_ctx_t *md5_hmac_ctx_tmpl;
2168 	uint_t keylen_in_bytes = CRYPTO_BITS2BYTES(key->ck_length);
2169 
2170 	if ((mechanism->cm_type != MD5_HMAC_MECH_INFO_TYPE) &&
2171 	    (mechanism->cm_type != MD5_HMAC_GEN_MECH_INFO_TYPE))
2172 		return (CRYPTO_MECHANISM_INVALID);
2173 
2174 	/* Add support for key by attributes (RFE 4706552) */
2175 	if (key->ck_format != CRYPTO_KEY_RAW)
2176 		return (CRYPTO_ARGUMENTS_BAD);
2177 
2178 	/*
2179 	 * Allocate and initialize MD5 context.
2180 	 */
2181 	md5_hmac_ctx_tmpl = kmem_alloc(sizeof (md5_hmac_ctx_t),
2182 	    crypto_kmflag(req));
2183 	if (md5_hmac_ctx_tmpl == NULL)
2184 		return (CRYPTO_HOST_MEMORY);
2185 
2186 	if (keylen_in_bytes > MD5_HMAC_BLOCK_SIZE) {
2187 		uchar_t digested_key[MD5_DIGEST_LENGTH];
2188 
2189 		/*
2190 		 * Hash the passed-in key to get a smaller key.
2191 		 * The inner context is used since it hasn't been
2192 		 * initialized yet.
2193 		 */
2194 		PROV_MD5_DIGEST_KEY(&md5_hmac_ctx_tmpl->hc_icontext,
2195 		    key->ck_data, keylen_in_bytes, digested_key);
2196 		md5_mac_init_ctx(md5_hmac_ctx_tmpl, digested_key,
2197 		    MD5_DIGEST_LENGTH);
2198 	} else {
2199 		md5_mac_init_ctx(md5_hmac_ctx_tmpl, key->ck_data,
2200 		    keylen_in_bytes);
2201 	}
2202 
2203 	md5_hmac_ctx_tmpl->hc_mech_type = mechanism->cm_type;
2204 	*ctx_template = (crypto_spi_ctx_template_t)md5_hmac_ctx_tmpl;
2205 	*ctx_template_size = sizeof (md5_hmac_ctx_t);
2206 
2207 	return (CRYPTO_SUCCESS);
2208 }
2209 
2210 static int
2211 md5_free_context(crypto_ctx_t *ctx)
2212 {
2213 	uint_t ctx_len;
2214 	md5_mech_type_t mech_type;
2215 
2216 	if (ctx->cc_provider_private == NULL)
2217 		return (CRYPTO_SUCCESS);
2218 
2219 	/*
2220 	 * We have to free either MD5 or MD5-HMAC contexts, which
2221 	 * have different lengths.
2222 	 */
2223 
2224 	mech_type = PROV_MD5_CTX(ctx)->mc_mech_type;
2225 	if (mech_type == MD5_MECH_INFO_TYPE)
2226 		ctx_len = sizeof (md5_ctx_t);
2227 	else {
2228 		ASSERT(mech_type == MD5_HMAC_MECH_INFO_TYPE ||
2229 		    mech_type == MD5_HMAC_GEN_MECH_INFO_TYPE);
2230 		ctx_len = sizeof (md5_hmac_ctx_t);
2231 	}
2232 
2233 	bzero(ctx->cc_provider_private, ctx_len);
2234 	kmem_free(ctx->cc_provider_private, ctx_len);
2235 	ctx->cc_provider_private = NULL;
2236 
2237 	return (CRYPTO_SUCCESS);
2238 }
2239 
2240 #endif	/* _KERNEL && !_BOOT */
2241