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