Home | History | Annotate | Download | only in crypto
      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 */
    441