1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * Copyright (C) 1998 by the FundsXpress, INC. 10 * 11 * All rights reserved. 12 * 13 * Export of this software from the United States of America may require 14 * a specific license from the United States Government. It is the 15 * responsibility of any person or organization contemplating export to 16 * obtain such a license before exporting. 17 * 18 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 19 * distribute this software and its documentation for any purpose and 20 * without fee is hereby granted, provided that the above copyright 21 * notice appear in all copies and that both that copyright notice and 22 * this permission notice appear in supporting documentation, and that 23 * the name of FundsXpress. not be used in advertising or publicity pertaining 24 * to distribution of the software without specific, written prior 25 * permission. FundsXpress makes no representations about the suitability of 26 * this software for any purpose. It is provided "as is" without express 27 * or implied warranty. 28 * 29 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 30 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 31 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 32 */ 33 34 #include <k5-int.h> 35 #include <des_int.h> 36 37 static const mit_des_cblock mit_des_zeroblock[8] = { 38 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 39 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 40 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 41 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 42 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 43 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 44 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 45 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }; 46 47 static void 48 k5_des3_block_size(size_t *blocksize) 49 { 50 KRB5_LOG0(KRB5_INFO, "k5_des3_block_size() start\n"); 51 *blocksize = 8; 52 } 53 54 static void 55 k5_des3_keysize(size_t *keybytes, size_t *keylength) 56 { 57 KRB5_LOG0(KRB5_INFO, "k5_des3_keysize() start\n"); 58 *keybytes = 21; 59 *keylength = 24; 60 } 61 62 static krb5_error_code 63 k5_des3_docrypt(krb5_context context, 64 krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, 65 krb5_const krb5_data *input, krb5_data *output, int encrypt) 66 { 67 /* LINTED */ 68 krb5_error_code ret; 69 70 KRB5_LOG0(KRB5_INFO, "k5_des3_docrypt() start"); 71 72 /* key->enctype was checked by the caller */ 73 74 if (key->length != 24) 75 return(KRB5_BAD_KEYSIZE); 76 if ((input->length%8) != 0) 77 return(KRB5_BAD_MSIZE); 78 if (ivec && (ivec->length != 8)) 79 return(KRB5_BAD_MSIZE); 80 if (input->length != output->length) 81 return(KRB5_BAD_MSIZE); 82 83 ret = mit_des3_cbc_encrypt(context, (krb5_pointer) input->data, 84 (krb5_pointer) output->data, input->length, 85 (krb5_keyblock *)key, 86 ivec?(unsigned char *)ivec->data:(unsigned char *)mit_des_zeroblock, 87 encrypt); 88 89 KRB5_LOG0(KRB5_INFO, "k5_des3_docrypt() end\n"); 90 return(ret); 91 } 92 93 static krb5_error_code 94 k5_des3_encrypt(krb5_context context, 95 krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, 96 krb5_const krb5_data *input, krb5_data *output) 97 { 98 return(k5_des3_docrypt(context, key, ivec, input, output, 1)); 99 } 100 101 static krb5_error_code 102 k5_des3_decrypt(krb5_context context, 103 krb5_const krb5_keyblock *key, krb5_const krb5_data *ivec, 104 krb5_const krb5_data *input, krb5_data *output) 105 { 106 return(k5_des3_docrypt(context, key, ivec, input, output, 0)); 107 } 108 109 static krb5_error_code 110 k5_des3_make_key(krb5_context context, krb5_const krb5_data *randombits, 111 krb5_keyblock *key) 112 { 113 int i; 114 krb5_error_code ret = 0; 115 116 KRB5_LOG0(KRB5_INFO, "k5_des3_make_key() start\n"); 117 118 if (key->length != 24) 119 return(KRB5_BAD_KEYSIZE); 120 if (randombits->length != 21) 121 return(KRB5_CRYPTO_INTERNAL); 122 123 key->magic = KV5M_KEYBLOCK; 124 key->length = 24; 125 key->dk_list = NULL; 126 127 /* take the seven bytes, move them around into the top 7 bits of the 128 8 key bytes, then compute the parity bits. Do this three times. */ 129 130 for (i=0; i<3; i++) { 131 (void) memcpy(key->contents+i*8, randombits->data+i*7, 7); 132 key->contents[i*8+7] = (((key->contents[i*8]&1)<<1) | 133 ((key->contents[i*8+1]&1)<<2) | 134 ((key->contents[i*8+2]&1)<<3) | 135 ((key->contents[i*8+3]&1)<<4) | 136 ((key->contents[i*8+4]&1)<<5) | 137 ((key->contents[i*8+5]&1)<<6) | 138 ((key->contents[i*8+6]&1)<<7)); 139 140 mit_des_fixup_key_parity(key->contents+i*8); 141 } 142 #ifdef _KERNEL 143 key->kef_key.ck_data = NULL; 144 key->key_tmpl = NULL; 145 ret = init_key_kef(context->kef_cipher_mt, key); 146 #else 147 key->hKey = CK_INVALID_HANDLE; 148 ret = init_key_uef(krb_ctx_hSession(context), key); 149 #endif /* _KERNEL */ 150 KRB5_LOG0(KRB5_INFO, "k5_des3_make_key() end\n"); 151 return(ret); 152 } 153 154 const struct krb5_enc_provider krb5_enc_des3 = { 155 k5_des3_block_size, 156 k5_des3_keysize, 157 k5_des3_encrypt, 158 k5_des3_decrypt, 159 k5_des3_make_key, 160 krb5int_des_init_state, 161 krb5int_default_free_state 162 }; 163