⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crypto.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 1997 - 2005 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  */#include "krb5_locl.h"RCSID("$Id: crypto.c 22200 2007-12-07 13:48:01Z lha $");#undef CRYPTO_DEBUG#ifdef CRYPTO_DEBUGstatic void krb5_crypto_debug(krb5_context, int, size_t, krb5_keyblock*);#endifstruct key_data {    krb5_keyblock *key;    krb5_data *schedule;};struct key_usage {    unsigned usage;    struct key_data key;};struct krb5_crypto_data {    struct encryption_type *et;    struct key_data key;    int num_key_usage;    struct key_usage *key_usage;};#define CRYPTO_ETYPE(C) ((C)->et->type)/* bits for `flags' below */#define F_KEYED		 1	/* checksum is keyed */#define F_CPROOF	 2	/* checksum is collision proof */#define F_DERIVED	 4	/* uses derived keys */#define F_VARIANT	 8	/* uses `variant' keys (6.4.3) */#define F_PSEUDO	16	/* not a real protocol type */#define F_SPECIAL	32	/* backwards */#define F_DISABLED	64	/* enctype/checksum disabled */struct salt_type {    krb5_salttype type;    const char *name;    krb5_error_code (*string_to_key)(krb5_context, krb5_enctype, krb5_data, 				     krb5_salt, krb5_data, krb5_keyblock*);};struct key_type {    krb5_keytype type; /* XXX */    const char *name;    size_t bits;    size_t size;    size_t schedule_size;#if 0    krb5_enctype best_etype;#endif    void (*random_key)(krb5_context, krb5_keyblock*);    void (*schedule)(krb5_context, struct key_data *);    struct salt_type *string_to_key;    void (*random_to_key)(krb5_context, krb5_keyblock*, const void*, size_t);};struct checksum_type {    krb5_cksumtype type;    const char *name;    size_t blocksize;    size_t checksumsize;    unsigned flags;    void (*checksum)(krb5_context context,		     struct key_data *key,		     const void *buf, size_t len,		     unsigned usage,		     Checksum *csum);    krb5_error_code (*verify)(krb5_context context,			      struct key_data *key,			      const void *buf, size_t len,			      unsigned usage,			      Checksum *csum);};struct encryption_type {    krb5_enctype type;    const char *name;    heim_oid *oid;    size_t blocksize;    size_t padsize;    size_t confoundersize;    struct key_type *keytype;    struct checksum_type *checksum;    struct checksum_type *keyed_checksum;    unsigned flags;    krb5_error_code (*encrypt)(krb5_context context,			       struct key_data *key,			       void *data, size_t len,			       krb5_boolean encryptp,			       int usage,			       void *ivec);    size_t prf_length;    krb5_error_code (*prf)(krb5_context,			   krb5_crypto, const krb5_data *, krb5_data *);};#define ENCRYPTION_USAGE(U) (((U) << 8) | 0xAA)#define INTEGRITY_USAGE(U) (((U) << 8) | 0x55)#define CHECKSUM_USAGE(U) (((U) << 8) | 0x99)static struct checksum_type *_find_checksum(krb5_cksumtype type);static struct encryption_type *_find_enctype(krb5_enctype type);static struct key_type *_find_keytype(krb5_keytype type);static krb5_error_code _get_derived_key(krb5_context, krb5_crypto, 					unsigned, struct key_data**);static struct key_data *_new_derived_key(krb5_crypto crypto, unsigned usage);static krb5_error_code derive_key(krb5_context context,				  struct encryption_type *et,				  struct key_data *key,				  const void *constant,				  size_t len);static krb5_error_code hmac(krb5_context context,			    struct checksum_type *cm, 			    const void *data, 			    size_t len, 			    unsigned usage,			    struct key_data *keyblock,			    Checksum *result);static void free_key_data(krb5_context context, struct key_data *key);static krb5_error_code usage2arcfour (krb5_context, unsigned *);static void xor (DES_cblock *, const unsigned char *);/************************************************************ *                                                          * ************************************************************/static HEIMDAL_MUTEX crypto_mutex = HEIMDAL_MUTEX_INITIALIZER;static voidkrb5_DES_random_key(krb5_context context,	       krb5_keyblock *key){    DES_cblock *k = key->keyvalue.data;    do {	krb5_generate_random_block(k, sizeof(DES_cblock));	DES_set_odd_parity(k);    } while(DES_is_weak_key(k));}static voidkrb5_DES_schedule(krb5_context context,		  struct key_data *key){    DES_set_key(key->key->keyvalue.data, key->schedule->data);}#ifdef ENABLE_AFS_STRING_TO_KEY/* This defines the Andrew string_to_key function.  It accepts a password * string as input and converts it via a one-way encryption algorithm to a DES * encryption key.  It is compatible with the original Andrew authentication * service password database. *//* * Short passwords, i.e 8 characters or less. */static voidkrb5_DES_AFS3_CMU_string_to_key (krb5_data pw,			    krb5_data cell,			    DES_cblock *key){    char  password[8+1];	/* crypt is limited to 8 chars anyway */    int   i;        for(i = 0; i < 8; i++) {	char c = ((i < pw.length) ? ((char*)pw.data)[i] : 0) ^		 ((i < cell.length) ?		  tolower(((unsigned char*)cell.data)[i]) : 0);	password[i] = c ? c : 'X';    }    password[8] = '\0';    memcpy(key, crypt(password, "p1") + 2, sizeof(DES_cblock));    /* parity is inserted into the LSB so left shift each byte up one       bit. This allows ascii characters with a zero MSB to retain as       much significance as possible. */    for (i = 0; i < sizeof(DES_cblock); i++)	((unsigned char*)key)[i] <<= 1;    DES_set_odd_parity (key);}/* * Long passwords, i.e 9 characters or more. */static voidkrb5_DES_AFS3_Transarc_string_to_key (krb5_data pw,				 krb5_data cell,				 DES_cblock *key){    DES_key_schedule schedule;    DES_cblock temp_key;    DES_cblock ivec;    char password[512];    size_t passlen;    memcpy(password, pw.data, min(pw.length, sizeof(password)));    if(pw.length < sizeof(password)) {	int len = min(cell.length, sizeof(password) - pw.length);	int i;	memcpy(password + pw.length, cell.data, len);	for (i = pw.length; i < pw.length + len; ++i)	    password[i] = tolower((unsigned char)password[i]);    }    passlen = min(sizeof(password), pw.length + cell.length);    memcpy(&ivec, "kerberos", 8);    memcpy(&temp_key, "kerberos", 8);    DES_set_odd_parity (&temp_key);    DES_set_key (&temp_key, &schedule);    DES_cbc_cksum ((void*)password, &ivec, passlen, &schedule, &ivec);    memcpy(&temp_key, &ivec, 8);    DES_set_odd_parity (&temp_key);    DES_set_key (&temp_key, &schedule);    DES_cbc_cksum ((void*)password, key, passlen, &schedule, &ivec);    memset(&schedule, 0, sizeof(schedule));    memset(&temp_key, 0, sizeof(temp_key));    memset(&ivec, 0, sizeof(ivec));    memset(password, 0, sizeof(password));    DES_set_odd_parity (key);}static krb5_error_codeDES_AFS3_string_to_key(krb5_context context,		       krb5_enctype enctype,		       krb5_data password,		       krb5_salt salt,		       krb5_data opaque,		       krb5_keyblock *key){    DES_cblock tmp;    if(password.length > 8)	krb5_DES_AFS3_Transarc_string_to_key(password, salt.saltvalue, &tmp);    else	krb5_DES_AFS3_CMU_string_to_key(password, salt.saltvalue, &tmp);    key->keytype = enctype;    krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));    memset(&key, 0, sizeof(key));    return 0;}#endif /* ENABLE_AFS_STRING_TO_KEY */static voidDES_string_to_key_int(unsigned char *data, size_t length, DES_cblock *key){    DES_key_schedule schedule;    int i;    int reverse = 0;    unsigned char *p;    unsigned char swap[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 			     0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };    memset(key, 0, 8);        p = (unsigned char*)key;    for (i = 0; i < length; i++) {	unsigned char tmp = data[i];	if (!reverse)	    *p++ ^= (tmp << 1);	else	    *--p ^= (swap[tmp & 0xf] << 4) | swap[(tmp & 0xf0) >> 4];	if((i % 8) == 7)	    reverse = !reverse;    }    DES_set_odd_parity(key);    if(DES_is_weak_key(key))	(*key)[7] ^= 0xF0;    DES_set_key(key, &schedule);    DES_cbc_cksum((void*)data, key, length, &schedule, key);    memset(&schedule, 0, sizeof(schedule));    DES_set_odd_parity(key);    if(DES_is_weak_key(key))	(*key)[7] ^= 0xF0;}static krb5_error_codekrb5_DES_string_to_key(krb5_context context,		  krb5_enctype enctype,		  krb5_data password,		  krb5_salt salt,		  krb5_data opaque,		  krb5_keyblock *key){    unsigned char *s;    size_t len;    DES_cblock tmp;#ifdef ENABLE_AFS_STRING_TO_KEY    if (opaque.length == 1) {	unsigned long v;	_krb5_get_int(opaque.data, &v, 1);	if (v == 1)	    return DES_AFS3_string_to_key(context, enctype, password,					  salt, opaque, key);    }#endif    len = password.length + salt.saltvalue.length;    s = malloc(len);    if(len > 0 && s == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	return ENOMEM;    }    memcpy(s, password.data, password.length);    memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);    DES_string_to_key_int(s, len, &tmp);    key->keytype = enctype;    krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp));    memset(&tmp, 0, sizeof(tmp));    memset(s, 0, len);    free(s);    return 0;}static voidkrb5_DES_random_to_key(krb5_context context,		       krb5_keyblock *key,		       const void *data,		       size_t size){    DES_cblock *k = key->keyvalue.data;    memcpy(k, data, key->keyvalue.length);    DES_set_odd_parity(k);    if(DES_is_weak_key(k))	xor(k, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");}/* * */static voidDES3_random_key(krb5_context context,		krb5_keyblock *key){    DES_cblock *k = key->keyvalue.data;    do {	krb5_generate_random_block(k, 3 * sizeof(DES_cblock));	DES_set_odd_parity(&k[0]);	DES_set_odd_parity(&k[1]);	DES_set_odd_parity(&k[2]);    } while(DES_is_weak_key(&k[0]) ||	    DES_is_weak_key(&k[1]) ||	    DES_is_weak_key(&k[2]));}static voidDES3_schedule(krb5_context context,	      struct key_data *key){    DES_cblock *k = key->key->keyvalue.data;    DES_key_schedule *s = key->schedule->data;    DES_set_key(&k[0], &s[0]);    DES_set_key(&k[1], &s[1]);    DES_set_key(&k[2], &s[2]);}/* * A = A xor B. A & B are 8 bytes. */static voidxor (DES_cblock *key, const unsigned char *b){    unsigned char *a = (unsigned char*)key;    a[0] ^= b[0];    a[1] ^= b[1];    a[2] ^= b[2];    a[3] ^= b[3];    a[4] ^= b[4];    a[5] ^= b[5];    a[6] ^= b[6];    a[7] ^= b[7];}static krb5_error_codeDES3_string_to_key(krb5_context context,		   krb5_enctype enctype,		   krb5_data password,		   krb5_salt salt,		   krb5_data opaque,		   krb5_keyblock *key){    char *str;    size_t len;    unsigned char tmp[24];    DES_cblock keys[3];    krb5_error_code ret;        len = password.length + salt.saltvalue.length;    str = malloc(len);    if(len != 0 && str == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	return ENOMEM;    }    memcpy(str, password.data, password.length);    memcpy(str + password.length, salt.saltvalue.data, salt.saltvalue.length);    {	DES_cblock ivec;	DES_key_schedule s[3];	int i;		ret = _krb5_n_fold(str, len, tmp, 24);	if (ret) {	    memset(str, 0, len);	    free(str);	    krb5_set_error_string(context, "out of memory");	    return ret;	}		for(i = 0; i < 3; i++){	    memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));	    DES_set_odd_parity(keys + i);	    if(DES_is_weak_key(keys + i))		xor(keys + i, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");	    DES_set_key(keys + i, &s[i]);	}	memset(&ivec, 0, sizeof(ivec));	DES_ede3_cbc_encrypt(tmp,			     tmp, sizeof(tmp), 			     &s[0], &s[1], &s[2], &ivec, DES_ENCRYPT);	memset(s, 0, sizeof(s));	memset(&ivec, 0, sizeof(ivec));	for(i = 0; i < 3; i++){	    memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));	    DES_set_odd_parity(keys + i);	    if(DES_is_weak_key(keys + i))		xor(keys + i, (const unsigned char*)"\0\0\0\0\0\0\0\xf0");	}	memset(tmp, 0, sizeof(tmp));    }    key->keytype = enctype;    krb5_data_copy(&key->keyvalue, keys, sizeof(keys));    memset(keys, 0, sizeof(keys));    memset(str, 0, len);    free(str);    return 0;}static krb5_error_codeDES3_string_to_key_derived(krb5_context context,			   krb5_enctype enctype,			   krb5_data password,			   krb5_salt salt,			   krb5_data opaque,			   krb5_keyblock *key){    krb5_error_code ret;    size_t len = password.length + salt.saltvalue.length;    char *s;    s = malloc(len);    if(len != 0 && s == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	return ENOMEM;    }    memcpy(s, password.data, password.length);    memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length);    ret = krb5_string_to_key_derived(context,				     s,				     len,				     enctype,				     key);    memset(s, 0, len);    free(s);    return ret;}static voidDES3_random_to_key(krb5_context context,		   krb5_keyblock *key,		   const void *data,		   size_t size){    unsigned char *x = key->keyvalue.data;    const u_char *q = data;    DES_cblock *k;    int i, j;    memset(x, 0, sizeof(x));    for (i = 0; i < 3; ++i) {	unsigned char foo;	for (j = 0; j < 7; ++j) {	    unsigned char b = q[7 * i + j];	    x[8 * i + j] = b;	}	foo = 0;	for (j = 6; j >= 0; --j) {	    foo |= q[7 * i + j] & 1;	    foo <<= 1;	}	x[8 * i + 7] = foo;    }    k = key->keyvalue.data;    for (i = 0; i < 3; i++) {	DES_set_odd_parity(&k[i]);	if(DES_is_weak_key(&k[i]))	    xor(&k[i], (const unsigned char*)"\0\0\0\0\0\0\0\xf0");    }    }/* * ARCFOUR */static voidARCFOUR_schedule(krb5_context context, 		 struct key_data *kd){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -