17c478bd9Sstevel@tonic-gate /* 2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate 77c478bd9Sstevel@tonic-gate /* 8*159d09a2SMark Phalan * Copyright2001 by the Massachusetts Institute of Technology. 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 { 74*159d09a2SMark Phalan krb5_error_code code; 757c478bd9Sstevel@tonic-gate size_t blocksize; 767c478bd9Sstevel@tonic-gate /* We special case rc4*/ 777c478bd9Sstevel@tonic-gate if (key->enctype == ENCTYPE_ARCFOUR_HMAC) 78*159d09a2SMark Phalan return 8; 79*159d09a2SMark Phalan code = krb5_c_block_size(context, key->enctype, &blocksize); 80*159d09a2SMark Phalan if (code) 817c478bd9Sstevel@tonic-gate return(-1); /* XXX */ 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate return(blocksize); 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate krb5_error_code 877c478bd9Sstevel@tonic-gate kg_make_confounder(context, key, buf) 887c478bd9Sstevel@tonic-gate krb5_context context; 897c478bd9Sstevel@tonic-gate krb5_keyblock *key; 907c478bd9Sstevel@tonic-gate unsigned char *buf; 917c478bd9Sstevel@tonic-gate { 927c478bd9Sstevel@tonic-gate krb5_error_code code; 937c478bd9Sstevel@tonic-gate size_t blocksize; 94*159d09a2SMark Phalan krb5_data lrandom; 957c478bd9Sstevel@tonic-gate 96*159d09a2SMark Phalan code = krb5_c_block_size(context, key->enctype, &blocksize); 97*159d09a2SMark Phalan if (code) 987c478bd9Sstevel@tonic-gate return(code); 997c478bd9Sstevel@tonic-gate 100*159d09a2SMark Phalan lrandom.length = blocksize; 101*159d09a2SMark Phalan lrandom.data = (char *) buf; 1027c478bd9Sstevel@tonic-gate 103*159d09a2SMark Phalan return(krb5_c_random_make_octets(context, &lrandom)); 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate int 1077c478bd9Sstevel@tonic-gate kg_encrypt_size(context, key, n) 1087c478bd9Sstevel@tonic-gate krb5_context context; 1097c478bd9Sstevel@tonic-gate krb5_keyblock *key; 1107c478bd9Sstevel@tonic-gate int n; 1117c478bd9Sstevel@tonic-gate { 1127c478bd9Sstevel@tonic-gate size_t enclen; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate if (krb5_c_encrypt_length(context, key->enctype, n, &enclen) != 0) 1157c478bd9Sstevel@tonic-gate return(-1); /* XXX */ 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate return(enclen); 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate krb5_error_code 1217c478bd9Sstevel@tonic-gate kg_encrypt(context, key, usage, iv, in, out, length) 1227c478bd9Sstevel@tonic-gate krb5_context context; 1237c478bd9Sstevel@tonic-gate krb5_keyblock *key; 1247c478bd9Sstevel@tonic-gate int usage; 1257c478bd9Sstevel@tonic-gate krb5_pointer iv; 126*159d09a2SMark Phalan krb5_const_pointer in; 1277c478bd9Sstevel@tonic-gate krb5_pointer out; 128ab9b2e15Sgtb unsigned int length; 1297c478bd9Sstevel@tonic-gate { 1307c478bd9Sstevel@tonic-gate krb5_error_code code; 1317c478bd9Sstevel@tonic-gate size_t blocksize; 1327c478bd9Sstevel@tonic-gate krb5_data ivd, *pivd, inputd; 1337c478bd9Sstevel@tonic-gate krb5_enc_data outputd; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_encrypt() start."); 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate if (iv) { 138*159d09a2SMark Phalan code = krb5_c_block_size(context, key->enctype, &blocksize); 139*159d09a2SMark Phalan if (code) 1407c478bd9Sstevel@tonic-gate return(code); 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate ivd.length = blocksize; 1437c478bd9Sstevel@tonic-gate ivd.data = MALLOC(ivd.length); 1447c478bd9Sstevel@tonic-gate if (ivd.data == NULL) 1457c478bd9Sstevel@tonic-gate return ENOMEM; 1467c478bd9Sstevel@tonic-gate (void) memcpy(ivd.data, iv, ivd.length); 1477c478bd9Sstevel@tonic-gate pivd = &ivd; 1487c478bd9Sstevel@tonic-gate } else { 1497c478bd9Sstevel@tonic-gate pivd = NULL; 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate inputd.length = length; 153*159d09a2SMark Phalan inputd.data = (char *)in; /* Solaris Kerberos */ 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate outputd.ciphertext.length = length; 1567c478bd9Sstevel@tonic-gate outputd.ciphertext.data = out; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd); 1597c478bd9Sstevel@tonic-gate if (pivd != NULL) 1607c478bd9Sstevel@tonic-gate krb5_free_data_contents(context, pivd); 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_encrypt() end. code = %d", code); 1637c478bd9Sstevel@tonic-gate return code; 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* length is the length of the cleartext. */ 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate krb5_error_code 1697c478bd9Sstevel@tonic-gate kg_decrypt(context, key, usage, iv, in, out, length) 1707c478bd9Sstevel@tonic-gate krb5_context context; 1717c478bd9Sstevel@tonic-gate krb5_keyblock *key; 1727c478bd9Sstevel@tonic-gate int usage; 1737c478bd9Sstevel@tonic-gate krb5_pointer iv; 174*159d09a2SMark Phalan krb5_const_pointer in; 1757c478bd9Sstevel@tonic-gate krb5_pointer out; 176ab9b2e15Sgtb unsigned int length; 1777c478bd9Sstevel@tonic-gate { 1787c478bd9Sstevel@tonic-gate krb5_error_code code; 1797c478bd9Sstevel@tonic-gate size_t blocksize; 1807c478bd9Sstevel@tonic-gate krb5_data ivd, *pivd, outputd; 1817c478bd9Sstevel@tonic-gate krb5_enc_data inputd; 1827c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_decrypt() start."); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (iv) { 185*159d09a2SMark Phalan code = krb5_c_block_size(context, key->enctype, &blocksize); 186*159d09a2SMark Phalan if (code) 1877c478bd9Sstevel@tonic-gate return(code); 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate ivd.length = blocksize; 1907c478bd9Sstevel@tonic-gate ivd.data = MALLOC(ivd.length); 1917c478bd9Sstevel@tonic-gate if (ivd.data == NULL) 1927c478bd9Sstevel@tonic-gate return ENOMEM; 1937c478bd9Sstevel@tonic-gate (void) memcpy(ivd.data, iv, ivd.length); 1947c478bd9Sstevel@tonic-gate pivd = &ivd; 1957c478bd9Sstevel@tonic-gate } else { 1967c478bd9Sstevel@tonic-gate pivd = NULL; 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate inputd.enctype = ENCTYPE_UNKNOWN; 2007c478bd9Sstevel@tonic-gate inputd.ciphertext.length = length; 201*159d09a2SMark Phalan inputd.ciphertext.data = (char *)in; /* Solaris Kerberos */ 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate outputd.length = length; 2047c478bd9Sstevel@tonic-gate outputd.data = out; 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd); 2077c478bd9Sstevel@tonic-gate if (pivd != NULL) 2087c478bd9Sstevel@tonic-gate krb5_free_data_contents(context, pivd); 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_decrypt() end. code = %d", code); 2117c478bd9Sstevel@tonic-gate return code; 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate krb5_error_code 2157c478bd9Sstevel@tonic-gate kg_arcfour_docrypt (krb5_context context, 2167c478bd9Sstevel@tonic-gate const krb5_keyblock *longterm_key , int ms_usage, 2177c478bd9Sstevel@tonic-gate const unsigned char *kd_data, size_t kd_data_len, 2187c478bd9Sstevel@tonic-gate const unsigned char *input_buf, size_t input_len, 2197c478bd9Sstevel@tonic-gate unsigned char *output_buf) 2207c478bd9Sstevel@tonic-gate { 2217c478bd9Sstevel@tonic-gate krb5_error_code code; 2227c478bd9Sstevel@tonic-gate krb5_data input, output; 2237c478bd9Sstevel@tonic-gate krb5_keyblock seq_enc_key, usage_key; 2247c478bd9Sstevel@tonic-gate unsigned char t[4]; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate KRB5_LOG0(KRB5_INFO, "kg_arcfour_docrypt() start"); 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate bzero(&usage_key, sizeof(krb5_keyblock)); 2297c478bd9Sstevel@tonic-gate bzero(&seq_enc_key, sizeof(krb5_keyblock)); 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate usage_key.length = longterm_key->length; 2327c478bd9Sstevel@tonic-gate usage_key.contents = MALLOC(usage_key.length); 2337c478bd9Sstevel@tonic-gate usage_key.enctype = longterm_key->enctype; 2347c478bd9Sstevel@tonic-gate usage_key.dk_list = NULL; 2357c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate usage_key.kef_mt = longterm_key->kef_mt; 2387c478bd9Sstevel@tonic-gate code = init_key_kef(longterm_key->kef_mt, &usage_key); 2397c478bd9Sstevel@tonic-gate if (code) 2407c478bd9Sstevel@tonic-gate return (code); 2417c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2427c478bd9Sstevel@tonic-gate if (usage_key.contents == NULL) 2437c478bd9Sstevel@tonic-gate return (ENOMEM); 2447c478bd9Sstevel@tonic-gate seq_enc_key.length = longterm_key->length; 2457c478bd9Sstevel@tonic-gate seq_enc_key.contents = MALLOC(seq_enc_key.length); 2467c478bd9Sstevel@tonic-gate seq_enc_key.enctype = longterm_key->enctype; 2477c478bd9Sstevel@tonic-gate seq_enc_key.dk_list = NULL; 2487c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2497c478bd9Sstevel@tonic-gate seq_enc_key.kef_mt = longterm_key->kef_mt; 2507c478bd9Sstevel@tonic-gate code = init_key_kef(longterm_key->kef_mt, &seq_enc_key); 2517c478bd9Sstevel@tonic-gate if (code) 2527c478bd9Sstevel@tonic-gate return (code); 2537c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2547c478bd9Sstevel@tonic-gate if (seq_enc_key.contents == NULL) { 2557c478bd9Sstevel@tonic-gate FREE ((void *) usage_key.contents, usage_key.length); 2567c478bd9Sstevel@tonic-gate return (ENOMEM); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate t[0] = ms_usage &0xff; 2607c478bd9Sstevel@tonic-gate t[1] = (ms_usage>>8) & 0xff; 2617c478bd9Sstevel@tonic-gate t[2] = (ms_usage>>16) & 0xff; 2627c478bd9Sstevel@tonic-gate t[3] = (ms_usage>>24) & 0xff; 2637c478bd9Sstevel@tonic-gate input.data = (void *) &t; 2647c478bd9Sstevel@tonic-gate input.length = 4; 2657c478bd9Sstevel@tonic-gate output.data = (void *) usage_key.contents; 2667c478bd9Sstevel@tonic-gate output.length = usage_key.length; 2677c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2687c478bd9Sstevel@tonic-gate code = krb5_hmac(context, longterm_key, &input, &output); 2697c478bd9Sstevel@tonic-gate #else 2707c478bd9Sstevel@tonic-gate code = krb5_hmac(context, &krb5int_hash_md5, 2717c478bd9Sstevel@tonic-gate longterm_key, 1, &input, &output); 2727c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2737c478bd9Sstevel@tonic-gate if (code) 2747c478bd9Sstevel@tonic-gate goto cleanup_arcfour; 275*159d09a2SMark Phalan 2767c478bd9Sstevel@tonic-gate input.data = ( void *) kd_data; 2777c478bd9Sstevel@tonic-gate input.length = kd_data_len; 2787c478bd9Sstevel@tonic-gate output.data = (void *) seq_enc_key.contents; 2797c478bd9Sstevel@tonic-gate #ifdef _KERNEL 2807c478bd9Sstevel@tonic-gate code = krb5_hmac(context, &usage_key, &input, &output); 2817c478bd9Sstevel@tonic-gate #else 2827c478bd9Sstevel@tonic-gate code = krb5_hmac(context, &krb5int_hash_md5, 2837c478bd9Sstevel@tonic-gate &usage_key, 1, &input, &output); 2847c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate if (code) 2877c478bd9Sstevel@tonic-gate goto cleanup_arcfour; 2887c478bd9Sstevel@tonic-gate input.data = ( void * ) input_buf; 2897c478bd9Sstevel@tonic-gate input.length = input_len; 290*159d09a2SMark Phalan output.data = (void * ) output_buf; 2917c478bd9Sstevel@tonic-gate output.length = input_len; 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate /* 2947c478bd9Sstevel@tonic-gate * Call the arcfour encryption method directly here, we cannot 2957c478bd9Sstevel@tonic-gate * use the standard "krb5_c_encrypt" interface because we just 2967c478bd9Sstevel@tonic-gate * want the arcfour algorithm applied and not the additional MD5-HMAC 2977c478bd9Sstevel@tonic-gate * which are applied when using the standard interface. 2987c478bd9Sstevel@tonic-gate */ 2997c478bd9Sstevel@tonic-gate code = krb5int_enc_arcfour.encrypt(context, &seq_enc_key, 0, &input, &output); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate cleanup_arcfour: 3027c478bd9Sstevel@tonic-gate bzero ((void *) seq_enc_key.contents, seq_enc_key.length); 3037c478bd9Sstevel@tonic-gate bzero ((void *) usage_key.contents, usage_key.length); 3047c478bd9Sstevel@tonic-gate FREE ((void *) usage_key.contents, usage_key.length); 3057c478bd9Sstevel@tonic-gate FREE ((void *) seq_enc_key.contents, seq_enc_key.length); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate KRB5_LOG(KRB5_INFO, "kg_arcfour_docrypt() end code = %d", code); 3087c478bd9Sstevel@tonic-gate return (code); 3097c478bd9Sstevel@tonic-gate } 310*159d09a2SMark Phalan 311