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,
 105       NULL,
 106 #ifndef _KERNEL
 107       krb5int_des_string_to_key,
 108 #else
 109       SUN_CKM_DES_CBC,
 110       NULL,
 111       CRYPTO_MECH_INVALID,
 112       CRYPTO_MECH_INVALID
 113 #endif /* !_KERNEL */
 114 },
 115 
 116     { ENCTYPE_DES3_CBC_RAW,
 117       "des3-cbc-raw", "Triple DES cbc mode raw",
 118       &krb5int_enc_des3, NULL,
 119       krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt,
 120       NULL,
 121 #ifndef _KERNEL
 122       krb5int_dk_string_to_key,
 123 #else
 124       SUN_CKM_DES3_CBC,
 125       NULL,
 126       CRYPTO_MECH_INVALID,
 127       CRYPTO_MECH_INVALID
 128 #endif /* !_KERNEL */
 129 },
 130 
 131     { ENCTYPE_DES3_CBC_SHA1,
 132       "des3-cbc-sha1", "Triple DES cbc mode with HMAC/sha1",
 133       &krb5int_enc_des3, &krb5int_hash_sha1,
 134       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 135       CKSUMTYPE_HMAC_SHA1_DES3,
 136 #ifndef _KERNEL
 137       krb5int_dk_string_to_key,
 138 #else
 139       SUN_CKM_DES3_CBC,
 140       SUN_CKM_SHA1_HMAC,
 141       CRYPTO_MECH_INVALID,
 142       CRYPTO_MECH_INVALID
 143 #endif
 144  },
 145     { ENCTYPE_DES3_CBC_SHA1,    /* alias */
 146       "des3-hmac-sha1", "Triple DES cbc mode with HMAC/sha1",
 147       &krb5int_enc_des3, &krb5int_hash_sha1,
 148       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 149       CKSUMTYPE_HMAC_SHA1_DES3,
 150 #ifndef _KERNEL
 151       krb5int_dk_string_to_key,
 152 #else
 153       SUN_CKM_DES3_CBC,
 154       SUN_CKM_SHA1_HMAC,
 155       CRYPTO_MECH_INVALID,
 156       CRYPTO_MECH_INVALID
 157 #endif /* !_KERNEL */
 158 },
 159     { ENCTYPE_DES3_CBC_SHA1,    /* alias */
 160       "des3-cbc-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
 161       &krb5int_enc_des3, &krb5int_hash_sha1,
 162       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 163       CKSUMTYPE_HMAC_SHA1_DES3,
 164 #ifndef _KERNEL
 165       krb5int_dk_string_to_key,
 166 #else
 167       SUN_CKM_DES3_CBC,
 168       SUN_CKM_SHA1_HMAC,
 169       CRYPTO_MECH_INVALID,
 170       CRYPTO_MECH_INVALID
 171 #endif /* !_KERNEL */
 172 },
 173       /* The des3-cbc-hmac-sha1-kd is the official enctype associated with
 174        * 3DES/SHA1 in draft-ietf-krb-wg-crypto-00.txt
 175        */
 176     { ENCTYPE_DES3_CBC_SHA1,    /* alias */
 177       "des3-cbc-hmac-sha1-kd", "Triple DES cbc mode with HMAC/sha1",
 178       &krb5int_enc_des3, &krb5int_hash_sha1,
 179       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 180       CKSUMTYPE_HMAC_SHA1_DES3,
 181 #ifndef _KERNEL
 182       krb5int_dk_string_to_key,
 183 #else
 184       SUN_CKM_DES3_CBC,
 185       SUN_CKM_SHA1_HMAC,
 186       CRYPTO_MECH_INVALID,
 187       CRYPTO_MECH_INVALID
 188 #endif /* !_KERNEL */
 189 },
 190 
 191     { ENCTYPE_DES_HMAC_SHA1,
 192       "des-hmac-sha1", "DES with HMAC/sha1",
 193       &krb5int_enc_des, &krb5int_hash_sha1,
 194       krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt,
 195       NULL,
 196 #ifndef _KERNEL
 197       krb5int_dk_string_to_key,
 198 #else
 199       SUN_CKM_DES_CBC,
 200       SUN_CKM_SHA1_HMAC,
 201       CRYPTO_MECH_INVALID,
 202       CRYPTO_MECH_INVALID
 203 #endif /* !_KERNEL */
 204 },
 205     { ENCTYPE_ARCFOUR_HMAC,
 206       "arcfour-hmac","ArcFour with HMAC/md5", &krb5int_enc_arcfour,
 207       &krb5int_hash_md5,
 208 krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 209       krb5_arcfour_decrypt,
 210         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 211 #ifndef _KERNEL
 212         krb5int_arcfour_string_to_key,
 213 #else
 214       SUN_CKM_RC4,
 215       SUN_CKM_MD5_HMAC,
 216       CRYPTO_MECH_INVALID,
 217       CRYPTO_MECH_INVALID
 218 #endif /* !_KERNEL */
 219     },
 220     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
 221       "rc4-hmac", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
 222       &krb5int_hash_md5,
 223       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 224       krb5_arcfour_decrypt, 
 225         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 226 #ifndef _KERNEL
 227         krb5int_arcfour_string_to_key,
 228 #else
 229       SUN_CKM_RC4,
 230       SUN_CKM_MD5_HMAC,
 231       CRYPTO_MECH_INVALID,
 232       CRYPTO_MECH_INVALID
 233 #endif /* !_KERNEL */
 234     },
 235     { ENCTYPE_ARCFOUR_HMAC,  /* alias */
 236       "arcfour-hmac-md5", "ArcFour with HMAC/md5", &krb5int_enc_arcfour,
 237       &krb5int_hash_md5,
 238       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 239       krb5_arcfour_decrypt,
 240         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 241 #ifndef _KERNEL
 242         krb5int_arcfour_string_to_key,
 243 #else
 244       SUN_CKM_RC4,
 245       SUN_CKM_MD5_HMAC,
 246       CRYPTO_MECH_INVALID,
 247       CRYPTO_MECH_INVALID
 248 #endif /* !_KERNEL */
 249     },
 250     { ENCTYPE_ARCFOUR_HMAC_EXP,
 251         "arcfour-hmac-exp", "Exportable ArcFour with HMAC/md5",
 252         &krb5int_enc_arcfour,
 253         &krb5int_hash_md5, krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 254         krb5_arcfour_decrypt,
 255         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 256 #ifndef _KERNEL
 257         krb5int_arcfour_string_to_key,
 258 #else
 259       SUN_CKM_RC4,
 260       SUN_CKM_MD5_HMAC,
 261       CRYPTO_MECH_INVALID,
 262       CRYPTO_MECH_INVALID
 263 #endif /* !_KERNEL */
 264     },
 265     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
 266       "rc4-hmac-exp", "Exportable ArcFour with HMAC/md5",
 267       &krb5int_enc_arcfour,
 268       &krb5int_hash_md5,
 269       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 270       krb5_arcfour_decrypt,
 271         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 272 #ifndef _KERNEL
 273         krb5int_arcfour_string_to_key,
 274 #else
 275       SUN_CKM_RC4,
 276       SUN_CKM_MD5_HMAC,
 277       CRYPTO_MECH_INVALID,
 278       CRYPTO_MECH_INVALID
 279 #endif /* !_KERNEL */
 280     },
 281     { ENCTYPE_ARCFOUR_HMAC_EXP, /* alias */
 282       "arcfour-hmac-md5-exp", "Exportable ArcFour with HMAC/md5",
 283       &krb5int_enc_arcfour,
 284       &krb5int_hash_md5,
 285       krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
 286       krb5_arcfour_decrypt,
 287         CKSUMTYPE_HMAC_MD5_ARCFOUR,
 288 #ifndef _KERNEL
 289         krb5int_arcfour_string_to_key,
 290 #else
 291       SUN_CKM_RC4,
 292       SUN_CKM_MD5_HMAC,
 293       CRYPTO_MECH_INVALID,
 294       CRYPTO_MECH_INVALID
 295 #endif /* !_KERNEL */
 296     },
 297 
 298     /*
 299      * Note, all AES enctypes must use SUN_CKM_AES_CBC.  See aes_provider.c for
 300      * more info.
 301      */
 302     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
 303       "aes128-cts-hmac-sha1-96", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
 304       &krb5int_enc_aes128, &krb5int_hash_sha1,
 305       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 306       CKSUMTYPE_HMAC_SHA1_96_AES128,
 307 #ifndef _KERNEL
 308       krb5int_aes_string_to_key,
 309 #else
 310       SUN_CKM_AES_CBC,
 311       SUN_CKM_SHA1_HMAC,
 312       CRYPTO_MECH_INVALID,
 313       CRYPTO_MECH_INVALID
 314 #endif /* !_KERNEL */
 315     },
 316     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
 317         "aes128-cts", "AES-128 CTS mode with 96-bit SHA-1 HMAC",
 318         &krb5int_enc_aes128, &krb5int_hash_sha1,
 319         krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 320         CKSUMTYPE_HMAC_SHA1_96_AES128,
 321 #ifndef _KERNEL
 322         krb5int_aes_string_to_key,
 323 #else
 324       SUN_CKM_AES_CBC,
 325       SUN_CKM_SHA1_HMAC,
 326       CRYPTO_MECH_INVALID,
 327       CRYPTO_MECH_INVALID
 328 #endif /* !_KERNEL */
 329     },
 330     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
 331       "aes256-cts-hmac-sha1-96", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
 332       &krb5int_enc_aes256, &krb5int_hash_sha1,
 333       krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 334       CKSUMTYPE_HMAC_SHA1_96_AES256,
 335 #ifndef _KERNEL
 336       krb5int_aes_string_to_key,
 337 #else
 338       SUN_CKM_AES_CBC,
 339       SUN_CKM_SHA1_HMAC,
 340       CRYPTO_MECH_INVALID,
 341       CRYPTO_MECH_INVALID
 342 #endif /* !_KERNEL */
 343     },
 344     { ENCTYPE_AES256_CTS_HMAC_SHA1_96,
 345         "aes256-cts", "AES-256 CTS mode with 96-bit SHA-1 HMAC",
 346         &krb5int_enc_aes256, &krb5int_hash_sha1,
 347         krb5int_aes_encrypt_length, krb5int_aes_dk_encrypt, krb5int_aes_dk_decrypt,
 348         CKSUMTYPE_HMAC_SHA1_96_AES256,
 349 #ifndef _KERNEL
 350         krb5int_aes_string_to_key,
 351 #else
 352       SUN_CKM_AES_CBC,
 353       SUN_CKM_SHA1_HMAC,
 354       CRYPTO_MECH_INVALID,
 355       CRYPTO_MECH_INVALID
 356 #endif /* !_KERNEL */
 357     },
 358 };
 359 
 360 const int krb5_enctypes_length =
 361 sizeof(krb5_enctypes_list)/sizeof(struct krb5_keytypes);
 362 
 363 #ifdef _KERNEL
 364 
 365 /*
 366  * Routine to pre-fetch the mechanism types from KEF so
 367  * we dont keep doing this step later.
 368  */
 369 void
 370 setup_kef_keytypes()
 371 {
 372         int i;
 373         struct krb5_keytypes *kt;
 374 
 375         for (i=0; i<krb5_enctypes_length; i++) {
 376                 kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
 377                 if (kt->kef_cipher_mt == CRYPTO_MECH_INVALID &&
 378                     kt->mt_e_name != NULL) {
 379                         krb5_enctypes_list[i].kef_cipher_mt =
 380                                 crypto_mech2id(kt->mt_e_name);
 381                 }
 382 
 383                 if (kt->kef_hash_mt == CRYPTO_MECH_INVALID &&
 384                     kt->mt_h_name != NULL) {
 385                         krb5_enctypes_list[i].kef_hash_mt =
 386                                 crypto_mech2id(kt->mt_h_name);
 387                 }
 388                 KRB5_LOG1(KRB5_INFO, "setup_kef_keytypes(): %s ==> %ld",
 389                         kt->mt_e_name,
 390                         (ulong_t) krb5_enctypes_list[i].kef_cipher_mt);
 391         }
 392 }
 393 
 394 /*ARGSUSED*/
 395 crypto_mech_type_t
 396 get_cipher_mech_type(krb5_context context, krb5_keyblock *key)
 397 {
 398         int i;  
 399         struct krb5_keytypes *kt;
 400 
 401         if (key == NULL)
 402                 return (CRYPTO_MECH_INVALID);
 403 
 404         for (i=0; i<krb5_enctypes_length; i++) {
 405                 kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
 406                 if (kt->etype == key->enctype) {
 407                         KRB5_LOG1(KRB5_INFO, "get_cipher_mech_type() "
 408                                 "found %s %ld",
 409                                 kt->mt_e_name,
 410                                 (ulong_t) kt->kef_cipher_mt);
 411                         return (kt->kef_cipher_mt);
 412                 }
 413         }
 414         return (CRYPTO_MECH_INVALID);   
 415 }
 416 
 417 /*ARGSUSED*/
 418 crypto_mech_type_t
 419 get_hash_mech_type(krb5_context context, krb5_keyblock *key)
 420 {
 421         int i;  
 422         struct krb5_keytypes *kt;
 423 
 424         if (key == NULL)
 425                 return (CRYPTO_MECH_INVALID);
 426 
 427         for (i=0; i<krb5_enctypes_length; i++) {
 428                 kt = (struct krb5_keytypes *)&krb5_enctypes_list[i];
 429                 if (kt->etype == key->enctype) {
 430                         KRB5_LOG1(KRB5_INFO, "get_hash_mech_type() "
 431                                 "found %s %ld",
 432                                 kt->mt_h_name,
 433                                 (ulong_t) kt->kef_hash_mt);
 434                         return (kt->kef_hash_mt);
 435                 }
 436         }
 437         return (CRYPTO_MECH_INVALID);   
 438 }
 439 
 440 #endif /* _KERNEL */