1 /* $NetBSD: crypto-des3.c,v 1.7 2023/06/19 21:41:44 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 if (!EVP_CipherInit_ex(ctx, c, NULL, derived->keyvalue.data, NULL, 1)) 105 krb5_abortx(context, "can't initialize cipher"); 106 EVP_Cipher(ctx, out->data, result.checksum.data, 107 crypto->et->prf_length); 108 #if OPENSSL_VERSION_NUMBER < 0x10100000UL 109 EVP_CIPHER_CTX_cleanup(ctx); 110 #else 111 EVP_CIPHER_CTX_free(ctx); 112 #endif 113 } 114 115 krb5_data_free(&result.checksum); 116 krb5_free_keyblock(context, derived); 117 118 return ret; 119 } 120 121 #ifdef DES3_OLD_ENCTYPE 122 static struct _krb5_key_type keytype_des3 = { 123 ETYPE_OLD_DES3_CBC_SHA1, 124 "des3", 125 168, 126 24, 127 sizeof(struct _krb5_evp_schedule), 128 DES3_random_key, 129 _krb5_evp_schedule, 130 _krb5_des3_salt, 131 _krb5_DES3_random_to_key, 132 _krb5_evp_cleanup, 133 EVP_des_ede3_cbc 134 }; 135 #endif 136 137 static struct _krb5_key_type keytype_des3_derived = { 138 ETYPE_OLD_DES3_CBC_SHA1, 139 "des3", 140 168, 141 24, 142 sizeof(struct _krb5_evp_schedule), 143 DES3_random_key, 144 _krb5_evp_schedule, 145 _krb5_des3_salt_derived, 146 _krb5_DES3_random_to_key, 147 _krb5_evp_cleanup, 148 EVP_des_ede3_cbc 149 }; 150 151 #ifdef DES3_OLD_ENCTYPE 152 static krb5_error_code 153 RSA_MD5_DES3_checksum(krb5_context context, 154 struct _krb5_key_data *key, 155 const void *data, 156 size_t len, 157 unsigned usage, 158 Checksum *C) 159 { 160 return _krb5_des_checksum(context, EVP_md5(), key, data, len, C); 161 } 162 163 static krb5_error_code 164 RSA_MD5_DES3_verify(krb5_context context, 165 struct _krb5_key_data *key, 166 const void *data, 167 size_t len, 168 unsigned usage, 169 Checksum *C) 170 { 171 return _krb5_des_verify(context, EVP_md5(), key, data, len, C); 172 } 173 174 struct _krb5_checksum_type _krb5_checksum_rsa_md5_des3 = { 175 CKSUMTYPE_RSA_MD5_DES3, 176 "rsa-md5-des3", 177 64, 178 24, 179 F_KEYED | F_CPROOF | F_VARIANT, 180 RSA_MD5_DES3_checksum, 181 RSA_MD5_DES3_verify 182 }; 183 #endif 184 185 struct _krb5_checksum_type _krb5_checksum_hmac_sha1_des3 = { 186 CKSUMTYPE_HMAC_SHA1_DES3, 187 "hmac-sha1-des3", 188 64, 189 20, 190 F_KEYED | F_CPROOF | F_DERIVED, 191 _krb5_SP_HMAC_SHA1_checksum, 192 NULL 193 }; 194 195 #ifdef DES3_OLD_ENCTYPE 196 struct _krb5_encryption_type _krb5_enctype_des3_cbc_md5 = { 197 ETYPE_DES3_CBC_MD5, 198 "des3-cbc-md5", 199 NULL, 200 8, 201 8, 202 8, 203 &keytype_des3, 204 &_krb5_checksum_rsa_md5, 205 &_krb5_checksum_rsa_md5_des3, 206 0, 207 _krb5_evp_encrypt, 208 0, 209 NULL 210 }; 211 #endif 212 213 struct _krb5_encryption_type _krb5_enctype_des3_cbc_sha1 = { 214 ETYPE_DES3_CBC_SHA1, 215 "des3-cbc-sha1", 216 NULL, 217 8, 218 8, 219 8, 220 &keytype_des3_derived, 221 &_krb5_checksum_sha1, 222 &_krb5_checksum_hmac_sha1_des3, 223 F_DERIVED | F_RFC3961_ENC | F_RFC3961_KDF, 224 _krb5_evp_encrypt, 225 16, 226 DES3_prf 227 }; 228 229 #ifdef DES3_OLD_ENCTYPE 230 struct _krb5_encryption_type _krb5_enctype_old_des3_cbc_sha1 = { 231 ETYPE_OLD_DES3_CBC_SHA1, 232 "old-des3-cbc-sha1", 233 NULL, 234 8, 235 8, 236 8, 237 &keytype_des3, 238 &_krb5_checksum_sha1, 239 &_krb5_checksum_hmac_sha1_des3, 240 0, 241 _krb5_evp_encrypt, 242 0, 243 NULL 244 }; 245 #endif 246 247 struct _krb5_encryption_type _krb5_enctype_des3_cbc_none = { 248 ETYPE_DES3_CBC_NONE, 249 "des3-cbc-none", 250 NULL, 251 8, 252 8, 253 0, 254 &keytype_des3_derived, 255 &_krb5_checksum_none, 256 NULL, 257 F_PSEUDO, 258 _krb5_evp_encrypt, 259 0, 260 NULL 261 }; 262 263 void 264 _krb5_DES3_random_to_key(krb5_context context, 265 krb5_keyblock *key, 266 const void *data, 267 size_t size) 268 { 269 unsigned char *x = key->keyvalue.data; 270 const u_char *q = data; 271 DES_cblock *k; 272 int i, j; 273 274 memset(key->keyvalue.data, 0, key->keyvalue.length); 275 for (i = 0; i < 3; ++i) { 276 unsigned char foo; 277 for (j = 0; j < 7; ++j) { 278 unsigned char b = q[7 * i + j]; 279 280 x[8 * i + j] = b; 281 } 282 foo = 0; 283 for (j = 6; j >= 0; --j) { 284 foo |= q[7 * i + j] & 1; 285 foo <<= 1; 286 } 287 x[8 * i + 7] = foo; 288 } 289 k = key->keyvalue.data; 290 for (i = 0; i < 3; i++) { 291 DES_set_odd_parity(&k[i]); 292 if(DES_is_weak_key(&k[i])) 293 _krb5_xor8(k[i], (const unsigned char*)"\0\0\0\0\0\0\0\xf0"); 294 } 295 } 296