17c478bd9Sstevel@tonic-gate /* 2*ab9b2e15Sgtb * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 77c478bd9Sstevel@tonic-gate 87c478bd9Sstevel@tonic-gate /* 97c478bd9Sstevel@tonic-gate * Copyright 1993 by OpenVision Technologies, Inc. 107c478bd9Sstevel@tonic-gate * 117c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, distribute, and sell this software 127c478bd9Sstevel@tonic-gate * and its documentation for any purpose is hereby granted without fee, 137c478bd9Sstevel@tonic-gate * provided that the above copyright notice appears in all copies and 147c478bd9Sstevel@tonic-gate * that both that copyright notice and this permission notice appear in 157c478bd9Sstevel@tonic-gate * supporting documentation, and that the name of OpenVision not be used 167c478bd9Sstevel@tonic-gate * in advertising or publicity pertaining to distribution of the software 177c478bd9Sstevel@tonic-gate * without specific, written prior permission. OpenVision makes no 187c478bd9Sstevel@tonic-gate * representations about the suitability of this software for any 197c478bd9Sstevel@tonic-gate * purpose. It is provided "as is" without express or implied warranty. 207c478bd9Sstevel@tonic-gate * 217c478bd9Sstevel@tonic-gate * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 227c478bd9Sstevel@tonic-gate * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 237c478bd9Sstevel@tonic-gate * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 247c478bd9Sstevel@tonic-gate * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 257c478bd9Sstevel@tonic-gate * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 267c478bd9Sstevel@tonic-gate * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 277c478bd9Sstevel@tonic-gate * PERFORMANCE OF THIS SOFTWARE. 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 317c478bd9Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC. 327c478bd9Sstevel@tonic-gate * 337c478bd9Sstevel@tonic-gate * All rights reserved. 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may require 367c478bd9Sstevel@tonic-gate * a specific license from the United States Government. It is the 377c478bd9Sstevel@tonic-gate * responsibility of any person or organization contemplating export to 387c478bd9Sstevel@tonic-gate * obtain such a license before exporting. 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 417c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 427c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 437c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 447c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 457c478bd9Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining 467c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 477c478bd9Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of 487c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 497c478bd9Sstevel@tonic-gate * or implied warranty. 507c478bd9Sstevel@tonic-gate * 517c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 527c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 537c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate /* Solaris Kerberos: order is important here. include gssapiP_krb5.h 577c478bd9Sstevel@tonic-gate * before all others, otherwise we get a LINT error from MALLOC macro 587c478bd9Sstevel@tonic-gate * being redefined in mechglueP.h */ 597c478bd9Sstevel@tonic-gate #include <gssapiP_krb5.h> 607c478bd9Sstevel@tonic-gate #include <k5-int.h> 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* Solaris Kerberos defines memory management macros in <krb5.h> */ 637c478bd9Sstevel@tonic-gate /* #include <memory.h> */ 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* 667c478bd9Sstevel@tonic-gate * $Id: util_crypt.c,v 1.11.6.3 2000/06/03 06:09:45 tlyu Exp $ 677c478bd9Sstevel@tonic-gate */ 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate int 707c478bd9Sstevel@tonic-gate kg_confounder_size(context, key) 717c478bd9Sstevel@tonic-gate krb5_context context; 727c478bd9Sstevel@tonic-gate krb5_keyblock *key; 737c478bd9Sstevel@tonic-gate { 747c478bd9Sstevel@tonic-gate size_t blocksize; 757c478bd9Sstevel@tonic-gate /* We special case rc4*/ 767c478bd9Sstevel@tonic-gate if (key->enctype == ENCTYPE_ARCFOUR_HMAC) 777c478bd9Sstevel@tonic-gate return 8; 787c478bd9Sstevel@tonic-gate if (krb5_c_block_size(context, key->enctype, &blocksize) != 0) 797c478bd9Sstevel@tonic-gate return(-1); /* XXX */ 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate return(blocksize); 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate krb5_error_code 857c478bd9Sstevel@tonic-gate kg_make_confounder(context, key, buf) 867c478bd9Sstevel@tonic-gate krb5_context context; 877c478bd9Sstevel@tonic-gate krb5_keyblock *key; 887c478bd9Sstevel@tonic-gate unsigned char *buf; 897c478bd9Sstevel@tonic-gate { 907c478bd9Sstevel@tonic-gate krb5_error_code code; 917c478bd9Sstevel@tonic-gate size_t blocksize; 927c478bd9Sstevel@tonic-gate krb5_data random; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate if (code = krb5_c_block_size(context, key->enctype, &blocksize)) 957c478bd9Sstevel@tonic-gate return(code); 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate random.length = blocksize; 987c478bd9Sstevel@tonic-gate random.data = (char *) buf; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate return(krb5_c_random_make_octets(context, &random)); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate int 1047c478bd9Sstevel@tonic-gate kg_encrypt_size(context, key, n) 1057c478bd9Sstevel@tonic-gate krb5_context context; 1067c478bd9Sstevel@tonic-gate krb5_keyblock *key; 1077c478bd9Sstevel@tonic-gate int n; 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate size_t enclen; 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate if (krb5_c_encrypt_length(context, key->enctype, n, &enclen) != 0) 1127c478bd9Sstevel@tonic-gate return(-1); /* XXX */ 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate return(enclen); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate krb5_error_code 1187c478bd9Sstevel@tonic-gate kg_encrypt(context, key, usage, iv, in, out, length) 1197c478bd9Sstevel@tonic-gate krb5_context context; 1207c478bd9Sstevel@tonic-gate krb5_keyblock *key; 1217c478bd9Sstevel@tonic-gate int usage; 1227c478bd9Sstevel@tonic-gate krb5_pointer iv; 1237c478bd9Sstevel@tonic-gate krb5_pointer in; 1247c478bd9Sstevel@tonic-gate krb5_pointer out; 125*ab9b2e15Sgtb unsigned int length; 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate krb5_error_code code; 1287c478bd9Sstevel@tonic-gate size_t blocksize; 1297c478bd9Sstevel@tonic-gate krb5_data ivd, *pivd, inputd; 1307c478bd9Sstevel@tonic-gate krb5_enc_data outputd; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_encrypt() start."); 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate if (iv) { 1357c478bd9Sstevel@tonic-gate if (code = krb5_c_block_size(context, key->enctype, &blocksize)) 1367c478bd9Sstevel@tonic-gate return(code); 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate ivd.length = blocksize; 1397c478bd9Sstevel@tonic-gate ivd.data = MALLOC(ivd.length); 1407c478bd9Sstevel@tonic-gate if (ivd.data == NULL) 1417c478bd9Sstevel@tonic-gate return ENOMEM; 1427c478bd9Sstevel@tonic-gate (void) memcpy(ivd.data, iv, ivd.length); 1437c478bd9Sstevel@tonic-gate pivd = &ivd; 1447c478bd9Sstevel@tonic-gate } else { 1457c478bd9Sstevel@tonic-gate pivd = NULL; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate inputd.length = length; 1497c478bd9Sstevel@tonic-gate inputd.data = in; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate outputd.ciphertext.length = length; 1527c478bd9Sstevel@tonic-gate outputd.ciphertext.data = out; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd); 1557c478bd9Sstevel@tonic-gate if (pivd != NULL) 1567c478bd9Sstevel@tonic-gate krb5_free_data_contents(context, pivd); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_encrypt() end. code = %d", code); 1597c478bd9Sstevel@tonic-gate return code; 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate /* length is the length of the cleartext. */ 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate krb5_error_code 1657c478bd9Sstevel@tonic-gate kg_decrypt(context, key, usage, iv, in, out, length) 1667c478bd9Sstevel@tonic-gate krb5_context context; 1677c478bd9Sstevel@tonic-gate krb5_keyblock *key; 1687c478bd9Sstevel@tonic-gate int usage; 1697c478bd9Sstevel@tonic-gate krb5_pointer iv; 1707c478bd9Sstevel@tonic-gate krb5_pointer in; 1717c478bd9Sstevel@tonic-gate krb5_pointer out; 172*ab9b2e15Sgtb unsigned int length; 1737c478bd9Sstevel@tonic-gate { 1747c478bd9Sstevel@tonic-gate krb5_error_code code; 1757c478bd9Sstevel@tonic-gate size_t blocksize; 1767c478bd9Sstevel@tonic-gate krb5_data ivd, *pivd, outputd; 1777c478bd9Sstevel@tonic-gate krb5_enc_data inputd; 1787c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_decrypt() start."); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate if (iv) { 1817c478bd9Sstevel@tonic-gate if (code = krb5_c_block_size(context, key->enctype, &blocksize)) 1827c478bd9Sstevel@tonic-gate return(code); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate ivd.length = blocksize; 1857c478bd9Sstevel@tonic-gate ivd.data = MALLOC(ivd.length); 1867c478bd9Sstevel@tonic-gate if (ivd.data == NULL) 1877c478bd9Sstevel@tonic-gate return ENOMEM; 1887c478bd9Sstevel@tonic-gate (void) memcpy(ivd.data, iv, ivd.length); 1897c478bd9Sstevel@tonic-gate pivd = &ivd; 1907c478bd9Sstevel@tonic-gate } else { 1917c478bd9Sstevel@tonic-gate pivd = NULL; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate inputd.enctype = ENCTYPE_UNKNOWN; 1957c478bd9Sstevel@tonic-gate inputd.ciphertext.length = length; 1967c478bd9Sstevel@tonic-gate inputd.ciphertext.data = in; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate outputd.length = length; 1997c478bd9Sstevel@tonic-gate outputd.data = out; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd); 2027c478bd9Sstevel@tonic-gate if (pivd != NULL) 2037c478bd9Sstevel@tonic-gate krb5_free_data_contents(context, pivd); 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_decrypt() end. code = %d", code); 2067c478bd9Sstevel@tonic-gate return code; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate krb5_error_code 2107c478bd9Sstevel@tonic-gate kg_arcfour_docrypt (krb5_context context, 2117c478bd9Sstevel@tonic-gate const krb5_keyblock *longterm_key , int ms_usage, 2127c478bd9Sstevel@tonic-gate const unsigned char *kd_data, size_t kd_data_len, 2137c478bd9Sstevel@tonic-gate const unsigned char *input_buf, size_t input_len, 2147c478bd9Sstevel@tonic-gate unsigned char *output_buf) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate krb5_error_code code; 2177c478bd9Sstevel@tonic-gate krb5_data input, output; 2187c478bd9Sstevel@tonic-gate krb5_keyblock seq_enc_key, usage_key; 2197c478bd9Sstevel@tonic-gate unsigned char t[4]; 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_arcfour_docrypt() start"); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate bzero(&usage_key, sizeof(krb5_keyblock)); 2247c478bd9Sstevel@tonic-gate bzero(&seq_enc_key, sizeof(krb5_keyblock)); 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate usage_key.length = longterm_key->length; 2277c478bd9Sstevel@tonic-gate usage_key.contents = MALLOC(usage_key.length); 2287c478bd9Sstevel@tonic-gate usage_key.enctype = longterm_key->enctype; 2297c478bd9Sstevel@tonic-gate usage_key.dk_list = NULL; 2307c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate usage_key.kef_mt = longterm_key->kef_mt; 2337c478bd9Sstevel@tonic-gate code = init_key_kef(longterm_key->kef_mt, &usage_key); 2347c478bd9Sstevel@tonic-gate if (code) 2357c478bd9Sstevel@tonic-gate return (code); 2367c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2377c478bd9Sstevel@tonic-gate if (usage_key.contents == NULL) 2387c478bd9Sstevel@tonic-gate return (ENOMEM); 2397c478bd9Sstevel@tonic-gate seq_enc_key.length = longterm_key->length; 2407c478bd9Sstevel@tonic-gate seq_enc_key.contents = MALLOC(seq_enc_key.length); 2417c478bd9Sstevel@tonic-gate seq_enc_key.enctype = longterm_key->enctype; 2427c478bd9Sstevel@tonic-gate seq_enc_key.dk_list = NULL; 2437c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2447c478bd9Sstevel@tonic-gate seq_enc_key.kef_mt = longterm_key->kef_mt; 2457c478bd9Sstevel@tonic-gate code = init_key_kef(longterm_key->kef_mt, &seq_enc_key); 2467c478bd9Sstevel@tonic-gate if (code) 2477c478bd9Sstevel@tonic-gate return (code); 2487c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2497c478bd9Sstevel@tonic-gate if (seq_enc_key.contents == NULL) { 2507c478bd9Sstevel@tonic-gate FREE ((void *) usage_key.contents, usage_key.length); 2517c478bd9Sstevel@tonic-gate return (ENOMEM); 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate t[0] = ms_usage &0xff; 2557c478bd9Sstevel@tonic-gate t[1] = (ms_usage>>8) & 0xff; 2567c478bd9Sstevel@tonic-gate t[2] = (ms_usage>>16) & 0xff; 2577c478bd9Sstevel@tonic-gate t[3] = (ms_usage>>24) & 0xff; 2587c478bd9Sstevel@tonic-gate input.data = (void *) &t; 2597c478bd9Sstevel@tonic-gate input.length = 4; 2607c478bd9Sstevel@tonic-gate output.data = (void *) usage_key.contents; 2617c478bd9Sstevel@tonic-gate output.length = usage_key.length; 2627c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2637c478bd9Sstevel@tonic-gate code = krb5_hmac(context, longterm_key, &input, &output); 2647c478bd9Sstevel@tonic-gate #else 2657c478bd9Sstevel@tonic-gate code = krb5_hmac(context, &krb5int_hash_md5, 2667c478bd9Sstevel@tonic-gate longterm_key, 1, &input, &output); 2677c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2687c478bd9Sstevel@tonic-gate if (code) 2697c478bd9Sstevel@tonic-gate goto cleanup_arcfour; 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate input.data = ( void *) kd_data; 2727c478bd9Sstevel@tonic-gate input.length = kd_data_len; 2737c478bd9Sstevel@tonic-gate output.data = (void *) seq_enc_key.contents; 2747c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2757c478bd9Sstevel@tonic-gate code = krb5_hmac(context, &usage_key, &input, &output); 2767c478bd9Sstevel@tonic-gate #else 2777c478bd9Sstevel@tonic-gate code = krb5_hmac(context, &krb5int_hash_md5, 2787c478bd9Sstevel@tonic-gate &usage_key, 1, &input, &output); 2797c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate if (code) 2827c478bd9Sstevel@tonic-gate goto cleanup_arcfour; 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate input.data = ( void * ) input_buf; 2857c478bd9Sstevel@tonic-gate input.length = input_len; 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate output.data = (char *)output_buf; 2887c478bd9Sstevel@tonic-gate output.length = input_len; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate /* 2917c478bd9Sstevel@tonic-gate * Call the arcfour encryption method directly here, we cannot 2927c478bd9Sstevel@tonic-gate * use the standard "krb5_c_encrypt" interface because we just 2937c478bd9Sstevel@tonic-gate * want the arcfour algorithm applied and not the additional MD5-HMAC 2947c478bd9Sstevel@tonic-gate * which are applied when using the standard interface. 2957c478bd9Sstevel@tonic-gate */ 2967c478bd9Sstevel@tonic-gate code = krb5int_enc_arcfour.encrypt(context, &seq_enc_key, 0, &input, &output); 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate cleanup_arcfour: 2997c478bd9Sstevel@tonic-gate bzero ((void *) seq_enc_key.contents, seq_enc_key.length); 3007c478bd9Sstevel@tonic-gate bzero ((void *) usage_key.contents, usage_key.length); 3017c478bd9Sstevel@tonic-gate FREE ((void *) usage_key.contents, usage_key.length); 3027c478bd9Sstevel@tonic-gate FREE ((void *) seq_enc_key.contents, seq_enc_key.length); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_arcfour_docrypt() end code = %d", code); 3057c478bd9Sstevel@tonic-gate return (code); 3067c478bd9Sstevel@tonic-gate } 307