1 /* $NetBSD: crypto-des3.c,v 1.5 2018/02/05 16:00:53 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "krb5_locl.h" 37 38 /* 39 * 40 */ 41 42 static void 43 DES3_random_key(krb5_context context, 44 krb5_keyblock *key) 45 { 46 DES_cblock *k = key->keyvalue.data; 47 do { 48 krb5_generate_random_block(k, 3 * sizeof(DES_cblock)); 49 DES_set_odd_parity(&k[0]); 50 DES_set_odd_parity(&k[1]); 51 DES_set_odd_parity(&k[2]); 52 } while(DES_is_weak_key(&k[0]) || 53 DES_is_weak_key(&k[1]) || 54 DES_is_weak_key(&k[2])); 55 } 56 57 static krb5_error_code 58 DES3_prf(krb5_context context, 59 krb5_crypto crypto, 60 const krb5_data *in, 61 krb5_data *out) 62 { 63 struct _krb5_checksum_type *ct = crypto->et->checksum; 64 krb5_error_code ret; 65 Checksum result; 66 krb5_keyblock *derived; 67 68 result.cksumtype = ct->type; 69 ret = krb5_data_alloc(&result.checksum, ct->checksumsize); 70 if (ret) { 71 krb5_set_error_message(context, ret, N_("malloc: out memory", "")); 72 return ret; 73 } 74 75 ret = (*ct->checksum)(context, NULL, in->data, in->length, 0, &result); 76 if (ret) { 77 krb5_data_free(&result.checksum); 78 return ret; 79 } 80 81 if (result.checksum.length < crypto->et->blocksize) 82 krb5_abortx(context, "internal prf error"); 83 84 derived = NULL; 85 ret = krb5_derive_key(context, crypto->key.key, 86 crypto->et->type, "prf", 3, &derived); 87 if (ret) 88 krb5_abortx(context, "krb5_derive_key"); 89 90 ret = krb5_data_alloc(out, crypto->et->prf_length); 91 if (ret) 92 krb5_abortx(context, "malloc failed"); 93 94 { 95 const EVP_CIPHER *c = (*crypto->et->keytype->evp)(); 96 EVP_CIPHER_CTX *ctx; 97 #if OPENSSL_VERSION_NUMBER < 0x10100000UL 98 EVP_CIPHER_CTX ctxst; 99 ctx = &ctxst; 100 EVP_CIPHER_CTX_init(ctx); 101 #else 102 ctx = EVP_CIPHER_CTX_new(); 103 #endif 104 EVP_CipherInit_ex(ctx, c, NULL, derived->keyvalue.data, NULL, 1); 105 EVP_Cipher(ctx, out->data, result.checksum.data, 106 crypto->et->prf_length); 107 #if OPENSSL_VERSION_NUMBER < 0x10100000UL 108 EVP_CIPHER_CTX_cleanup(ctx); 109 #else 110 EVP_CIPHER_CTX_free(ctx); 111 #endif 112 } 113 114 krb5_data_free(&result.checksum); 115 krb5_free_keyblock(context, derived); 116 117 return ret; 118 } 119 120 #ifdef DES3_OLD_ENCTYPE 121 static struct _krb5_key_type keytype_des3 = { 122 ETYPE_OLD_DES3_CBC_SHA1, 123 "des3", 124 168, 125 24, 126 sizeof(struct _krb5_evp_schedule), 127 DES3_random_key, 128 _krb5_evp_schedule, 129 _krb5_des3_salt, 130 _krb5_DES3_random_to_key, 131 _krb5_evp_cleanup, 132 EVP_des_ede3_cbc 133 }; 134 #endif 135 136 static struct _krb5_key_type keytype_des3_derived = { 137 ETYPE_OLD_DES3_CBC_SHA1, 138 "des3", 139 168, 140 24, 141 sizeof(struct _krb5_evp_schedule), 142 DES3_random_key, 143 _krb5_evp_schedule, 144 _krb5_des3_salt_derived, 145 _krb5_DES3_random_to_key, 146 _krb5_evp_cleanup, 147 EVP_des_ede3_cbc 148 }; 149 150 #ifdef DES3_OLD_ENCTYPE 151 static krb5_error_code 152 RSA_MD5_DES3_checksum(krb5_context context, 153 struct _krb5_key_data *key, 154 const void *data, 155 size_t len, 156 unsigned usage, 157 Checksum *C) 158 { 159 return _krb5_des_checksum(context, EVP_md5(), key, data, len, C); 160 } 161 162 static krb5_error_code 163 RSA_MD5_DES3_verify(krb5_context context, 164 struct _krb5_key_data *key, 165 const void *data, 166 size_t len, 167 unsigned usage, 168 Checksum *C) 169 { 170 return _krb5_des_verify(context, EVP_md5(), key, data, len, C); 171 } 172 173 struct _krb5_checksum_type _krb5_checksum_rsa_md5_des3 = { 174 CKSUMTYPE_RSA_MD5_DES3, 175 "rsa-md5-des3", 176 64, 177 24, 178 F_KEYED | F_CPROOF | F_VARIANT, 179 RSA_MD5_DES3_checksum, 180 RSA_MD5_DES3_verify 181 }; 182 #endif 183 184 struct _krb5_checksum_type _krb5_checksum_hmac_sha1_des3 = { 185 CKSUMTYPE_HMAC_SHA1_DES3, 186 "hmac-sha1-des3", 187 64, 188 20, 189 F_KEYED | F_CPROOF | F_DERIVED, 190 _krb5_SP_HMAC_SHA1_checksum, 191 NULL 192 }; 193 194 #ifdef DES3_OLD_ENCTYPE 195 struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5 = { 196 ETYPE_DES3_CBC_MD5, 197 "des3-cbc-md5", 198 NULL, 199 8, 200 8, 201 8, 202 &keytype_des3, 203 &_krb5_checksum_rsa_md5, 204 &_krb5_checksum_rsa_md5_des3, 205 0, 206 _krb5_evp_encrypt, 207 0, 208 NULL 209 }; 210 #endif 211 212 struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = { 213 ETYPE_DES3_CBC_SHA1, 214 "des3-cbc-sha1", 215 NULL, 216 8, 217 8, 218 8, 219 &keytype_des3_derived, 220 &_krb5_checksum_sha1, 221 &_krb5_checksum_hmac_sha1_des3, 222 F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, 223 _krb5_evp_encrypt, 224 16, 225 DES3_prf 226 }; 227 228 #ifdef DES3_OLD_ENCTYPE 229 struct _krb5_encryption_type _krb5_enctype_old_des3_cbc_sha1 = { 230 ETYPE_OLD_DES3_CBC_SHA1, 231 "old-des3-cbc-sha1", 232 NULL, 233 8, 234 8, 235 8, 236 &keytype_des3, 237 &_krb5_checksum_sha1, 238 &_krb5_checksum_hmac_sha1_des3, 239 0, 240 _krb5_evp_encrypt, 241 0, 242 NULL 243 }; 244 #endif 245 246 struct _krb5_encryption_type _krb5_enctype_des3_cbc_none = { 247 ETYPE_DES3_CBC_NONE, 248 "des3-cbc-none", 249 NULL, 250 8, 251 8, 252 0, 253 &keytype_des3_derived, 254 &_krb5_checksum_none, 255 NULL, 256 F_PSEUDO, 257 _krb5_evp_encrypt, 258 0, 259 NULL 260 }; 261 262 void 263 _krb5_DES3_random_to_key(krb5_context context, 264 krb5_keyblock *key, 265 const void *data, 266 size_t size) 267 { 268 unsigned char *x = key->keyvalue.data; 269 const u_char *q = data; 270 DES_cblock *k; 271 int i, j; 272 273 memset(key->keyvalue.data, 0, key->keyvalue.length); 274 for (i = 0; i < 3; ++i) { 275 unsigned char foo; 276 for (j = 0; j < 7; ++j) { 277 unsigned char b = q[7 * i + j]; 278 279 x[8 * i + j] = b; 280 } 281 foo = 0; 282 for (j = 6; j >= 0; --j) { 283 foo |= q[7 * i + j] & 1; 284 foo <<= 1; 285 } 286 x[8 * i + 7] = foo; 287 } 288 k = key->keyvalue.data; 289 for (i = 0; i < 3; i++) { 290 DES_set_odd_parity(&k[i]); 291 if(DES_is_weak_key(&k[i])) 292 _krb5_xor8(k[i], (const unsigned char*)"\0\0\0\0\0\0\0\xf0"); 293 } 294 } 295