1 /* 2 * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "krb5_locl.h" 35 36 #ifdef HEIM_WEAK_CRYPTO 37 38 39 static void 40 krb5_DES_random_key(krb5_context context, 41 krb5_keyblock *key) 42 { 43 DES_cblock *k = key->keyvalue.data; 44 do { 45 krb5_generate_random_block(k, sizeof(DES_cblock)); 46 DES_set_odd_parity(k); 47 } while(DES_is_weak_key(k)); 48 } 49 50 static void 51 krb5_DES_schedule_old(krb5_context context, 52 struct _krb5_key_type *kt, 53 struct _krb5_key_data *key) 54 { 55 DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data); 56 } 57 58 static void 59 krb5_DES_random_to_key(krb5_context context, 60 krb5_keyblock *key, 61 const void *data, 62 size_t size) 63 { 64 DES_cblock *k = key->keyvalue.data; 65 memcpy(k, data, key->keyvalue.length); 66 DES_set_odd_parity(k); 67 if(DES_is_weak_key(k)) 68 _krb5_xor(k, (const unsigned char*)"\0\0\0\0\0\0\0\xf0"); 69 } 70 71 static struct _krb5_key_type keytype_des_old = { 72 ETYPE_DES_CBC_CRC, 73 "des-old", 74 56, 75 8, 76 sizeof(DES_key_schedule), 77 krb5_DES_random_key, 78 krb5_DES_schedule_old, 79 _krb5_des_salt, 80 krb5_DES_random_to_key, 81 NULL, 82 NULL 83 }; 84 85 static struct _krb5_key_type keytype_des = { 86 ETYPE_DES_CBC_CRC, 87 "des", 88 56, 89 8, 90 sizeof(struct _krb5_evp_schedule), 91 krb5_DES_random_key, 92 _krb5_evp_schedule, 93 _krb5_des_salt, 94 krb5_DES_random_to_key, 95 _krb5_evp_cleanup, 96 EVP_des_cbc 97 }; 98 99 static krb5_error_code 100 CRC32_checksum(krb5_context context, 101 struct _krb5_key_data *key, 102 const void *data, 103 size_t len, 104 unsigned usage, 105 Checksum *C) 106 { 107 uint32_t crc; 108 unsigned char *r = C->checksum.data; 109 _krb5_crc_init_table (); 110 crc = _krb5_crc_update (data, len, 0); 111 r[0] = crc & 0xff; 112 r[1] = (crc >> 8) & 0xff; 113 r[2] = (crc >> 16) & 0xff; 114 r[3] = (crc >> 24) & 0xff; 115 return 0; 116 } 117 118 static krb5_error_code 119 RSA_MD4_checksum(krb5_context context, 120 struct _krb5_key_data *key, 121 const void *data, 122 size_t len, 123 unsigned usage, 124 Checksum *C) 125 { 126 if (EVP_Digest(data, len, C->checksum.data, NULL, EVP_md4(), NULL) != 1) 127 krb5_abortx(context, "md4 checksum failed"); 128 return 0; 129 } 130 131 static krb5_error_code 132 RSA_MD4_DES_checksum(krb5_context context, 133 struct _krb5_key_data *key, 134 const void *data, 135 size_t len, 136 unsigned usage, 137 Checksum *cksum) 138 { 139 return _krb5_des_checksum(context, EVP_md4(), key, data, len, cksum); 140 } 141 142 static krb5_error_code 143 RSA_MD4_DES_verify(krb5_context context, 144 struct _krb5_key_data *key, 145 const void *data, 146 size_t len, 147 unsigned usage, 148 Checksum *C) 149 { 150 return _krb5_des_verify(context, EVP_md4(), key, data, len, C); 151 } 152 153 static krb5_error_code 154 RSA_MD5_DES_checksum(krb5_context context, 155 struct _krb5_key_data *key, 156 const void *data, 157 size_t len, 158 unsigned usage, 159 Checksum *C) 160 { 161 return _krb5_des_checksum(context, EVP_md5(), key, data, len, C); 162 } 163 164 static krb5_error_code 165 RSA_MD5_DES_verify(krb5_context context, 166 struct _krb5_key_data *key, 167 const void *data, 168 size_t len, 169 unsigned usage, 170 Checksum *C) 171 { 172 return _krb5_des_verify(context, EVP_md5(), key, data, len, C); 173 } 174 175 struct _krb5_checksum_type _krb5_checksum_crc32 = { 176 CKSUMTYPE_CRC32, 177 "crc32", 178 1, 179 4, 180 0, 181 CRC32_checksum, 182 NULL 183 }; 184 185 struct _krb5_checksum_type _krb5_checksum_rsa_md4 = { 186 CKSUMTYPE_RSA_MD4, 187 "rsa-md4", 188 64, 189 16, 190 F_CPROOF, 191 RSA_MD4_checksum, 192 NULL 193 }; 194 195 struct _krb5_checksum_type _krb5_checksum_rsa_md4_des = { 196 CKSUMTYPE_RSA_MD4_DES, 197 "rsa-md4-des", 198 64, 199 24, 200 F_KEYED | F_CPROOF | F_VARIANT, 201 RSA_MD4_DES_checksum, 202 RSA_MD4_DES_verify 203 }; 204 205 struct _krb5_checksum_type _krb5_checksum_rsa_md5_des = { 206 CKSUMTYPE_RSA_MD5_DES, 207 "rsa-md5-des", 208 64, 209 24, 210 F_KEYED | F_CPROOF | F_VARIANT, 211 RSA_MD5_DES_checksum, 212 RSA_MD5_DES_verify 213 }; 214 215 static krb5_error_code 216 evp_des_encrypt_null_ivec(krb5_context context, 217 struct _krb5_key_data *key, 218 void *data, 219 size_t len, 220 krb5_boolean encryptp, 221 int usage, 222 void *ignore_ivec) 223 { 224 struct _krb5_evp_schedule *ctx = key->schedule->data; 225 EVP_CIPHER_CTX *c; 226 DES_cblock ivec; 227 memset(&ivec, 0, sizeof(ivec)); 228 c = encryptp ? ctx->ectx : ctx->dctx; 229 EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1); 230 EVP_Cipher(c, data, data, len); 231 return 0; 232 } 233 234 static krb5_error_code 235 evp_des_encrypt_key_ivec(krb5_context context, 236 struct _krb5_key_data *key, 237 void *data, 238 size_t len, 239 krb5_boolean encryptp, 240 int usage, 241 void *ignore_ivec) 242 { 243 struct _krb5_evp_schedule *ctx = key->schedule->data; 244 EVP_CIPHER_CTX *c; 245 DES_cblock ivec; 246 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); 247 c = encryptp ? ctx->ectx : ctx->dctx; 248 EVP_CipherInit_ex(c, NULL, NULL, NULL, (void *)&ivec, -1); 249 EVP_Cipher(c, data, data, len); 250 return 0; 251 } 252 253 static krb5_error_code 254 DES_CFB64_encrypt_null_ivec(krb5_context context, 255 struct _krb5_key_data *key, 256 void *data, 257 size_t len, 258 krb5_boolean encryptp, 259 int usage, 260 void *ignore_ivec) 261 { 262 DES_cblock ivec; 263 int num = 0; 264 DES_key_schedule *s = key->schedule->data; 265 memset(&ivec, 0, sizeof(ivec)); 266 267 DES_cfb64_encrypt(data, data, len, s, &ivec, &num, encryptp); 268 return 0; 269 } 270 271 static krb5_error_code 272 DES_PCBC_encrypt_key_ivec(krb5_context context, 273 struct _krb5_key_data *key, 274 void *data, 275 size_t len, 276 krb5_boolean encryptp, 277 int usage, 278 void *ignore_ivec) 279 { 280 DES_cblock ivec; 281 DES_key_schedule *s = key->schedule->data; 282 memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); 283 284 DES_pcbc_encrypt(data, data, len, s, &ivec, encryptp); 285 return 0; 286 } 287 288 struct _krb5_encryption_type _krb5_enctype_des_cbc_crc = { 289 ETYPE_DES_CBC_CRC, 290 "des-cbc-crc", 291 8, 292 8, 293 8, 294 &keytype_des, 295 &_krb5_checksum_crc32, 296 NULL, 297 F_DISABLED|F_WEAK, 298 evp_des_encrypt_key_ivec, 299 0, 300 NULL 301 }; 302 303 struct _krb5_encryption_type _krb5_enctype_des_cbc_md4 = { 304 ETYPE_DES_CBC_MD4, 305 "des-cbc-md4", 306 8, 307 8, 308 8, 309 &keytype_des, 310 &_krb5_checksum_rsa_md4, 311 &_krb5_checksum_rsa_md4_des, 312 F_DISABLED|F_WEAK, 313 evp_des_encrypt_null_ivec, 314 0, 315 NULL 316 }; 317 318 struct _krb5_encryption_type _krb5_enctype_des_cbc_md5 = { 319 ETYPE_DES_CBC_MD5, 320 "des-cbc-md5", 321 8, 322 8, 323 8, 324 &keytype_des, 325 &_krb5_checksum_rsa_md5, 326 &_krb5_checksum_rsa_md5_des, 327 F_DISABLED|F_WEAK, 328 evp_des_encrypt_null_ivec, 329 0, 330 NULL 331 }; 332 333 struct _krb5_encryption_type _krb5_enctype_des_cbc_none = { 334 ETYPE_DES_CBC_NONE, 335 "des-cbc-none", 336 8, 337 8, 338 0, 339 &keytype_des, 340 &_krb5_checksum_none, 341 NULL, 342 F_PSEUDO|F_DISABLED|F_WEAK, 343 evp_des_encrypt_null_ivec, 344 0, 345 NULL 346 }; 347 348 struct _krb5_encryption_type _krb5_enctype_des_cfb64_none = { 349 ETYPE_DES_CFB64_NONE, 350 "des-cfb64-none", 351 1, 352 1, 353 0, 354 &keytype_des_old, 355 &_krb5_checksum_none, 356 NULL, 357 F_PSEUDO|F_DISABLED|F_WEAK, 358 DES_CFB64_encrypt_null_ivec, 359 0, 360 NULL 361 }; 362 363 struct _krb5_encryption_type _krb5_enctype_des_pcbc_none = { 364 ETYPE_DES_PCBC_NONE, 365 "des-pcbc-none", 366 8, 367 8, 368 0, 369 &keytype_des_old, 370 &_krb5_checksum_none, 371 NULL, 372 F_PSEUDO|F_DISABLED|F_WEAK, 373 DES_PCBC_encrypt_key_ivec, 374 0, 375 NULL 376 }; 377 #endif /* HEIM_WEAK_CRYPTO */ 378