1 /*
   2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  */
   5 
   6 
   7 /*
   8  * Copyright (C) 1998 by the FundsXpress, INC.
   9  * 
  10  * All rights reserved.
  11  * 
  12  * Export of this software from the United States of America may require
  13  * a specific license from the United States Government.  It is the
  14  * responsibility of any person or organization contemplating export to
  15  * obtain such a license before exporting.
  16  * 
  17  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  18  * distribute this software and its documentation for any purpose and
  19  * without fee is hereby granted, provided that the above copyright
  20  * notice appear in all copies and that both that copyright notice and
  21  * this permission notice appear in supporting documentation, and that
  22  * the name of FundsXpress. not be used in advertising or publicity pertaining
  23  * to distribution of the software without specific, written prior
  24  * permission.  FundsXpress makes no representations about the suitability of
  25  * this software for any purpose.  It is provided "as is" without express
  26  * or implied warranty.
  27  * 
  28  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  29  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  30  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  31  */
  32 
  33 #ifdef  _KERNEL
  34 /* Solaris Kerberos:
  35  * we don't provide these functions to the kernel
  36  */
  37 #define krb5int_des_string_to_key       NULL
  38 #define krb5_dk_string_to_key   NULL
  39 #define krb5int_arcfour_string_to_key   NULL
  40 #endif  /* _KERNEL */
  41 
  42 #include <k5-int.h>
  43 #include <enc_provider.h>
  44 #include <hash_provider.h>
  45 #include <etypes.h>
  46 #include <old.h>
  47 #include <raw.h>
  48 
  49 #include <dk.h>
  50 #include <arcfour.h>
  51 
  52 /* these will be linear searched.  if they ever get big, a binary
  53    search or hash table would be better, which means these would need
  54    to be sorted.  An array would be more efficient, but that assumes
  55    that the keytypes are all near each other.  I'd rather not make
  56    that assumption. */
  57 
  58 struct krb5_keytypes krb5_enctypes_list[] = {
  59     { ENCTYPE_DES_CBC_CRC,
  60       "des-cbc-crc", "DES cbc mode with CRC-32",
  61       &krb5int_enc_des, &krb5int_hash_crc32,
  62       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
  63       CKSUMTYPE_RSA_MD5,
  64 #ifndef _KERNEL
  65       krb5int_des_string_to_key,
  66 #else
  67       SUN_CKM_DES_CBC,
  68       NULL,
  69       CRYPTO_MECH_INVALID,
  70       CRYPTO_MECH_INVALID
  71 #endif /* !_KERNEL */
  72 },
  73     { ENCTYPE_DES_CBC_MD5,
  74       "des-cbc-md5", "DES cbc mode with RSA-MD5",
  75       &krb5int_enc_des, &krb5int_hash_md5,
  76       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
  77       CKSUMTYPE_RSA_MD5,
  78 #ifndef _KERNEL
  79       krb5int_des_string_to_key,
  80 #else
  81       SUN_CKM_DES_CBC,
  82       SUN_CKM_MD5,
  83       CRYPTO_MECH_INVALID,
  84       CRYPTO_MECH_INVALID
  85 #endif /* !_KERNEL */
  86 },
  87     { ENCTYPE_DES_CBC_MD5,
  88       "des", "DES cbc mode with RSA-MD5", /* alias */
  89       &krb5int_enc_des, &krb5int_hash_md5,
  90       krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt,
  91       CKSUMTYPE_RSA_MD5,
  92 #ifndef _KERNEL
  93       krb5int_des_string_to_key,
  94 #else
  95       SUN_CKM_DES_CBC,
  96       SUN_CKM_MD5,
  97       CRYPTO_MECH_INVALID,
  98       CRYPTO_MECH_INVALID
  99 #endif /* _KERNEL */
 100  },
 101     { ENCTYPE_DES_CBC_RAW,
 102       "des-cbc-raw", "DES cbc mode raw",
 103       &krb5int_enc_des, NULL,
 104       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, 0,
 105 #ifndef _KERNEL
 106       krb5int_des_string_to_key,
 107 #else
 108       SUN_CKM_DES_CBC,
 109       NULL,
 110       CRYPTO_MECH_INVALID,
 111       CRYPTO_MECH_INVALID
 112 #endif /* !_KERNEL */
 113 },
 114 
 115     { ENCTYPE_DES3_CBC_RAW,
 116       "des3-cbc-raw", "Triple DES cbc mode raw",
 117       &krb5int_enc_des3, NULL,
 118       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, 0,
 119 #ifndef _KERNEL
 120       krb5int_dk_string_to_key,
 121 #else
 122       SUN_CKM_DES3_CBC,
 123       NULL,
 124       CRYPTO_MECH_INVALID,
 125       CRYPTO_MECH_INVALID
 126 #endif /* !_KERNEL */
 127 },
 128 
 129     { ENCTYPE_DES3_CBC_SHA1,
 130       "des3-cbc-sha1", "Triple DES cbc mode with HMAC/sha1",
 131       &krb5int_enc_des3, &krb5int_hash_sha1,
 132       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 133       CKSUMTYPE_HMAC_SHA1_DES3,
 134 #ifndef _KERNEL
 135       krb5int_dk_string_to_key,
 136 #else
 137       SUN_CKM_DES3_CBC,
 138       SUN_CKM_SHA1_HMAC,
 139       CRYPTO_MECH_INVALID,
 140       CRYPTO_MECH_INVALID
 141 #endif
 142  },
 143     { ENCTYPE_DES3_CBC_SHA1,    /* alias */
 144       "des3-hmac-sha1", "Triple DES cbc mode with HMAC/sha1",
 145       &krb5int_enc_des3, &krb5int_hash_sha1,
 146       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 147       CKSUMTYPE_HMAC_SHA1_DES3,
 148 #ifndef _KERNEL
 149       krb5int_dk_string_to_key,
 150 #else
 151       SUN_CKM_DES3_CBC,
 152       SUN_CKM_SHA1_HMAC,
 153       CRYPTO_MECH_INVALID,
 154       CRYPTO_MECH_INVALID
 155 #endif /* !_KERNEL */
 156 },
 157     { ENCTYPE_DES3_CBC_SHA1,    /* alias */
 158       "des3-cbc-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
 159       &krb5int_enc_des3, &krb5int_hash_sha1,
 160       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 161       CKSUMTYPE_HMAC_SHA1_DES3,
 162 #ifndef _KERNEL
 163       krb5int_dk_string_to_key,
 164 #else
 165       SUN_CKM_DES3_CBC,
 166       SUN_CKM_SHA1_HMAC,
 167       CRYPTO_MECH_INVALID,
 168       CRYPTO_MECH_INVALID
 169 #endif /* !_KERNEL */
 170 },
 171       /* The des3-cbc-hmac-sha1-kd is the official enctype associated with
 172        * 3DES/SHA1 in draft-ietf-krb-wg-crypto-00.txt
 173        */
 174     { ENCTYPE_DES3_CBC_SHA1,    /* alias */
 175       "des3-cbc-hmac-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
 176       &krb5int_enc_des3, &krb5int_hash_sha1,
 177       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 178       CKSUMTYPE_HMAC_SHA1_DES3,
 179 #ifndef _KERNEL
 180       krb5int_dk_string_to_key,
 181 #else
 182       SUN_CKM_DES3_CBC,
 183       SUN_CKM_SHA1_HMAC,
 184       CRYPTO_MECH_INVALID,
 185       CRYPTO_MECH_INVALID
 186 #endif /* !_KERNEL */
 187 },
 188 
 189     { ENCTYPE_DES_HMAC_SHA1,
 190       "des-hmac-sha1", "DES with HMAC/sha1",
 191       &krb5int_enc_des, &krb5int_hash_sha1,
 192       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, 0,
 193 #ifndef _KERNEL
 194       krb5int_dk_string_to_key,
 195 #else
 196       SUN_CKM_DES_CBC,
 197       SUN_CKM_SHA1_HMAC,
 198       CRYPTO_MECH_INVALID,
 199       CRYPTO_MECH_INVALID
 200 #endif /* !_KERNEL */
 201 },
 202     { ENCTYPE_ARCFOUR_HMAC,
 203       "arcfour-hmac","ArcFour with HMAC/md5", &krb5int_enc_arcfour,
 204       &krb5int_hash_md5,
 205 krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 206       krb5_arcfour_decrypt,
 207         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 208 #ifndef _KERNEL
 209         krb5int_arcfour_string_to_key,
 210 #else
 211       SUN_CKM_RC4,
 212       SUN_CKM_MD5_HMAC,
 213       CRYPTO_MECH_INVALID,
 214       CRYPTO_MECH_INVALID
 215 #endif /* !_KERNEL */
 216     },
 217     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
 218       "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
 219       &krb5int_hash_md5,
 220       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 221       krb5_arcfour_decrypt, 
 222         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 223 #ifndef _KERNEL
 224         krb5int_arcfour_string_to_key,
 225 #else
 226       SUN_CKM_RC4,
 227       SUN_CKM_MD5_HMAC,
 228       CRYPTO_MECH_INVALID,
 229       CRYPTO_MECH_INVALID
 230 #endif /* !_KERNEL */
 231     },
 232     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
 233       "arcfour-hmac-md5", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
 234       &krb5int_hash_md5,
 235       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 236       krb5_arcfour_decrypt,
 237         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 238 #ifndef _KERNEL
 239         krb5int_arcfour_string_to_key,
 240 #else
 241       SUN_CKM_RC4,
 242       SUN_CKM_MD5_HMAC,
 243       CRYPTO_MECH_INVALID,
 244       CRYPTO_MECH_INVALID
 245 #endif /* !_KERNEL */
 246     },
 247     { ENCTYPE_ARCFOUR_HMAC_EXP,
 248         "arcfour-hmac-exp", "Exportable ArcFour with HMAC/md5",
 249         &krb5int_enc_arcfour,
 250         &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 251         krb5_arcfour_decrypt,
 252         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 253 #ifndef _KERNEL
 254         krb5int_arcfour_string_to_key,
 255 #else
 256       SUN_CKM_RC4,
 257       SUN_CKM_MD5_HMAC,
 258       CRYPTO_MECH_INVALID,
 259       CRYPTO_MECH_INVALID
 260 #endif /* !_KERNEL */
 261     },
 262     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
 263       "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5",
 264       &krb5int_enc_arcfour,
 265       &krb5int_hash_md5,
 266       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 267       krb5_arcfour_decrypt,
 268         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 269 #ifndef _KERNEL
 270         krb5int_arcfour_string_to_key,
 271 #else
 272       SUN_CKM_RC4,
 273       SUN_CKM_MD5_HMAC,
 274       CRYPTO_MECH_INVALID,
 275       CRYPTO_MECH_INVALID
 276 #endif /* !_KERNEL */
 277     },
 278     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
 279       "arcfour-hmac-md5-exp", "Exportable ArcFour with HMAC/md5",
 280       &krb5int_enc_arcfour,
 281       &krb5int_hash_md5,
 282       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 283       krb5_arcfour_decrypt,
 284         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 285 #ifndef _KERNEL
 286         krb5int_arcfour_string_to_key,
 287 #else
 288       SUN_CKM_RC4,
 289       SUN_CKM_MD5_HMAC,
 290       CRYPTO_MECH_INVALID,
 291       CRYPTO_MECH_INVALID
 292 #endif /* !_KERNEL */
 293     },
 294 
 295     /*
 296      * Note, all AES enctypes must use SUN_CKM_AES_CBC.  See aes_provider.c for
 297      * more info.
 298      */
 299     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
 300       "aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
 301       &krb5int_enc_aes128, &krb5int_hash_sha1,
 302       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 303       CKSUMTYPE_HMAC_SHA1_96_AES128,
 304 #ifndef _KERNEL
 305       krb5int_aes_string_to_key,
 306 #else
 307       SUN_CKM_AES_CBC,
 308       SUN_CKM_SHA1_HMAC,
 309       CRYPTO_MECH_INVALID,
 310       CRYPTO_MECH_INVALID
 311 #endif /* !_KERNEL */
 312     },
 313     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
 314         "aes128-cts", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
 315         &krb5int_enc_aes128, &krb5int_hash_sha1,
 316         krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 317         CKSUMTYPE_HMAC_SHA1_96_AES128,
 318 #ifndef _KERNEL
 319         krb5int_aes_string_to_key,
 320 #else
 321       SUN_CKM_AES_CBC,
 322       SUN_CKM_SHA1_HMAC,
 323       CRYPTO_MECH_INVALID,
 324       CRYPTO_MECH_INVALID
 325 #endif /* !_KERNEL */
 326     },
 327     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
 328       "aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
 329       &krb5int_enc_aes256, &krb5int_hash_sha1,
 330       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 331       CKSUMTYPE_HMAC_SHA1_96_AES256,
 332 #ifndef _KERNEL
 333       krb5int_aes_string_to_key,
 334 #else
 335       SUN_CKM_AES_CBC,
 336       SUN_CKM_SHA1_HMAC,
 337       CRYPTO_MECH_INVALID,
 338       CRYPTO_MECH_INVALID
 339 #endif /* !_KERNEL */
 340     },
 341     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
 342         "aes256-cts", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
 343         &krb5int_enc_aes256, &krb5int_hash_sha1,
 344         krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 345         CKSUMTYPE_HMAC_SHA1_96_AES256,
 346 #ifndef _KERNEL
 347         krb5int_aes_string_to_key,
 348 #else
 349       SUN_CKM_AES_CBC,
 350       SUN_CKM_SHA1_HMAC,
 351       CRYPTO_MECH_INVALID,
 352       CRYPTO_MECH_INVALID
 353 #endif /* !_KERNEL */
 354     },
 355 };
 356 
 357 const int krb5_enctypes_length =
 358 sizeof(krb5_enctypes_list)/sizeof(struct krb5_keytypes);
 359 
 360 #ifdef _KERNEL
 361 
 362 /*
 363  * Routine to pre-fetch the mechanism types from KEF so
 364  * we dont keep doing this step later.
 365  */
 366 void
 367 setup_kef_keytypes()
 368 {
 369         int i;
 370         struct krb5_keytypes *kt;
 371 
 372         for (i=0; i<krb5_enctypes_length; i++) {
 373                 kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
 374                 if (kt->kef_cipher_mt == CRYPTO_MECH_INVALID &&
 375                     kt->mt_e_name != NULL) {
 376                         krb5_enctypes_list[i].kef_cipher_mt =
 377                                 crypto_mech2id(kt->mt_e_name);
 378                 }
 379 
 380                 if (kt->kef_hash_mt == CRYPTO_MECH_INVALID &&
 381                     kt->mt_h_name != NULL) {
 382                         krb5_enctypes_list[i].kef_hash_mt =
 383                                 crypto_mech2id(kt->mt_h_name);
 384                 }
 385                 KRB5_LOG1(KRB5_INFO, "setup_kef_keytypes(): %s ==> %ld",
 386                         kt->mt_e_name,
 387                         (ulong_t) krb5_enctypes_list[i].kef_cipher_mt);
 388         }
 389 }
 390 
 391 /*ARGSUSED*/
 392 crypto_mech_type_t
 393 get_cipher_mech_type(krb5_context context, krb5_keyblock *key)
 394 {
 395         int i;  
 396         struct krb5_keytypes *kt;
 397 
 398         if (key == NULL)
 399                 return (CRYPTO_MECH_INVALID);
 400 
 401         for (i=0; i<krb5_enctypes_length; i++) {
 402                 kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
 403                 if (kt->etype == key->enctype) {
 404                         KRB5_LOG1(KRB5_INFO, "get_cipher_mech_type() "
 405                                 "found %s %ld",
 406                                 kt->mt_e_name,
 407                                 (ulong_t) kt->kef_cipher_mt);
 408                         return (kt->kef_cipher_mt);
 409                 }
 410         }
 411         return (CRYPTO_MECH_INVALID);   
 412 }
 413 
 414 /*ARGSUSED*/
 415 crypto_mech_type_t
 416 get_hash_mech_type(krb5_context context, krb5_keyblock *key)
 417 {
 418         int i;  
 419         struct krb5_keytypes *kt;
 420 
 421         if (key == NULL)
 422                 return (CRYPTO_MECH_INVALID);
 423 
 424         for (i=0; i<krb5_enctypes_length; i++) {
 425                 kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
 426                 if (kt->etype == key->enctype) {
 427                         KRB5_LOG1(KRB5_INFO, "get_hash_mech_type() "
 428                                 "found %s %ld",
 429                                 kt->mt_h_name,
 430                                 (ulong_t) kt->kef_hash_mt);
 431                         return (kt->kef_hash_mt);
 432                 }
 433         }
 434         return (CRYPTO_MECH_INVALID);   
 435 }
 436 
 437 #endif /* _KERNEL */