📄 crypto.c
字号:
krb5_error_code KRB5_LIB_FUNCTIONkrb5_generate_random_keyblock(krb5_context context, krb5_enctype type, krb5_keyblock *key){ krb5_error_code ret; struct encryption_type *et = _find_enctype(type); if(et == NULL) { krb5_set_error_string(context, "encryption type %d not supported", type); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); if(ret) return ret; key->keytype = type; if(et->keytype->random_key) (*et->keytype->random_key)(context, key); else krb5_generate_random_block(key->keyvalue.data, key->keyvalue.length); return 0;}static krb5_error_code_key_schedule(krb5_context context, struct key_data *key){ krb5_error_code ret; struct encryption_type *et = _find_enctype(key->key->keytype); struct key_type *kt = et->keytype; if(kt->schedule == NULL) return 0; if (key->schedule != NULL) return 0; ALLOC(key->schedule, 1); if(key->schedule == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } ret = krb5_data_alloc(key->schedule, kt->schedule_size); if(ret) { free(key->schedule); key->schedule = NULL; return ret; } (*kt->schedule)(context, key); return 0;}/************************************************************ * * ************************************************************/static voidNONE_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){}static voidCRC32_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ uint32_t crc; unsigned char *r = C->checksum.data; _krb5_crc_init_table (); crc = _krb5_crc_update (data, len, 0); r[0] = crc & 0xff; r[1] = (crc >> 8) & 0xff; r[2] = (crc >> 16) & 0xff; r[3] = (crc >> 24) & 0xff;}static voidRSA_MD4_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ MD4_CTX m; MD4_Init (&m); MD4_Update (&m, data, len); MD4_Final (C->checksum.data, &m);}static voidRSA_MD4_DES_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *cksum){ MD4_CTX md4; DES_cblock ivec; unsigned char *p = cksum->checksum.data; krb5_generate_random_block(p, 8); MD4_Init (&md4); MD4_Update (&md4, p, 8); MD4_Update (&md4, data, len); MD4_Final (p + 8, &md4); memset (&ivec, 0, sizeof(ivec)); DES_cbc_encrypt(p, p, 24, key->schedule->data, &ivec, DES_ENCRYPT);}static krb5_error_codeRSA_MD4_DES_verify(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ MD4_CTX md4; unsigned char tmp[24]; unsigned char res[16]; DES_cblock ivec; krb5_error_code ret = 0; memset(&ivec, 0, sizeof(ivec)); DES_cbc_encrypt(C->checksum.data, (void*)tmp, C->checksum.length, key->schedule->data, &ivec, DES_DECRYPT); MD4_Init (&md4); MD4_Update (&md4, tmp, 8); /* confounder */ MD4_Update (&md4, data, len); MD4_Final (res, &md4); if(memcmp(res, tmp + 8, sizeof(res)) != 0) { krb5_clear_error_string (context); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } memset(tmp, 0, sizeof(tmp)); memset(res, 0, sizeof(res)); return ret;}static voidRSA_MD5_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ MD5_CTX m; MD5_Init (&m); MD5_Update(&m, data, len); MD5_Final (C->checksum.data, &m);}static voidRSA_MD5_DES_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ MD5_CTX md5; DES_cblock ivec; unsigned char *p = C->checksum.data; krb5_generate_random_block(p, 8); MD5_Init (&md5); MD5_Update (&md5, p, 8); MD5_Update (&md5, data, len); MD5_Final (p + 8, &md5); memset (&ivec, 0, sizeof(ivec)); DES_cbc_encrypt(p, p, 24, key->schedule->data, &ivec, DES_ENCRYPT);}static krb5_error_codeRSA_MD5_DES_verify(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ MD5_CTX md5; unsigned char tmp[24]; unsigned char res[16]; DES_cblock ivec; DES_key_schedule *sched = key->schedule->data; krb5_error_code ret = 0; memset(&ivec, 0, sizeof(ivec)); DES_cbc_encrypt(C->checksum.data, (void*)tmp, C->checksum.length, &sched[0], &ivec, DES_DECRYPT); MD5_Init (&md5); MD5_Update (&md5, tmp, 8); /* confounder */ MD5_Update (&md5, data, len); MD5_Final (res, &md5); if(memcmp(res, tmp + 8, sizeof(res)) != 0) { krb5_clear_error_string (context); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } memset(tmp, 0, sizeof(tmp)); memset(res, 0, sizeof(res)); return ret;}static voidRSA_MD5_DES3_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ MD5_CTX md5; DES_cblock ivec; unsigned char *p = C->checksum.data; DES_key_schedule *sched = key->schedule->data; krb5_generate_random_block(p, 8); MD5_Init (&md5); MD5_Update (&md5, p, 8); MD5_Update (&md5, data, len); MD5_Final (p + 8, &md5); memset (&ivec, 0, sizeof(ivec)); DES_ede3_cbc_encrypt(p, p, 24, &sched[0], &sched[1], &sched[2], &ivec, DES_ENCRYPT);}static krb5_error_codeRSA_MD5_DES3_verify(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ MD5_CTX md5; unsigned char tmp[24]; unsigned char res[16]; DES_cblock ivec; DES_key_schedule *sched = key->schedule->data; krb5_error_code ret = 0; memset(&ivec, 0, sizeof(ivec)); DES_ede3_cbc_encrypt(C->checksum.data, (void*)tmp, C->checksum.length, &sched[0], &sched[1], &sched[2], &ivec, DES_DECRYPT); MD5_Init (&md5); MD5_Update (&md5, tmp, 8); /* confounder */ MD5_Update (&md5, data, len); MD5_Final (res, &md5); if(memcmp(res, tmp + 8, sizeof(res)) != 0) { krb5_clear_error_string (context); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } memset(tmp, 0, sizeof(tmp)); memset(res, 0, sizeof(res)); return ret;}static voidSHA1_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *C){ SHA_CTX m; SHA1_Init(&m); SHA1_Update(&m, data, len); SHA1_Final(C->checksum.data, &m);}/* HMAC according to RFC2104 */static krb5_error_codehmac(krb5_context context, struct checksum_type *cm, const void *data, size_t len, unsigned usage, struct key_data *keyblock, Checksum *result){ unsigned char *ipad, *opad; unsigned char *key; size_t key_len; int i; ipad = malloc(cm->blocksize + len); if (ipad == NULL) return ENOMEM; opad = malloc(cm->blocksize + cm->checksumsize); if (opad == NULL) { free(ipad); return ENOMEM; } memset(ipad, 0x36, cm->blocksize); memset(opad, 0x5c, cm->blocksize); if(keyblock->key->keyvalue.length > cm->blocksize){ (*cm->checksum)(context, keyblock, keyblock->key->keyvalue.data, keyblock->key->keyvalue.length, usage, result); key = result->checksum.data; key_len = result->checksum.length; } else { key = keyblock->key->keyvalue.data; key_len = keyblock->key->keyvalue.length; } for(i = 0; i < key_len; i++){ ipad[i] ^= key[i]; opad[i] ^= key[i]; } memcpy(ipad + cm->blocksize, data, len); (*cm->checksum)(context, keyblock, ipad, cm->blocksize + len, usage, result); memcpy(opad + cm->blocksize, result->checksum.data, result->checksum.length); (*cm->checksum)(context, keyblock, opad, cm->blocksize + cm->checksumsize, usage, result); memset(ipad, 0, cm->blocksize + len); free(ipad); memset(opad, 0, cm->blocksize + cm->checksumsize); free(opad); return 0;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_hmac(krb5_context context, krb5_cksumtype cktype, const void *data, size_t len, unsigned usage, krb5_keyblock *key, Checksum *result){ struct checksum_type *c = _find_checksum(cktype); struct key_data kd; krb5_error_code ret; if (c == NULL) { krb5_set_error_string (context, "checksum type %d not supported", cktype); return KRB5_PROG_SUMTYPE_NOSUPP; } kd.key = key; kd.schedule = NULL; ret = hmac(context, c, data, len, usage, &kd, result); if (kd.schedule) krb5_free_data(context, kd.schedule); return ret; }static voidSP_HMAC_SHA1_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *result){ struct checksum_type *c = _find_checksum(CKSUMTYPE_SHA1); Checksum res; char sha1_data[20]; krb5_error_code ret; res.checksum.data = sha1_data; res.checksum.length = sizeof(sha1_data); ret = hmac(context, c, data, len, usage, key, &res); if (ret) krb5_abortx(context, "hmac failed"); memcpy(result->checksum.data, res.checksum.data, result->checksum.length);}/* * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt */static voidHMAC_MD5_checksum(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *result){ MD5_CTX md5; struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); const char signature[] = "signaturekey"; Checksum ksign_c; struct key_data ksign; krb5_keyblock kb; unsigned char t[4]; unsigned char tmp[16]; unsigned char ksign_c_data[16]; krb5_error_code ret; ksign_c.checksum.length = sizeof(ksign_c_data); ksign_c.checksum.data = ksign_c_data; ret = hmac(context, c, signature, sizeof(signature), 0, key, &ksign_c); if (ret) krb5_abortx(context, "hmac failed"); ksign.key = &kb; kb.keyvalue = ksign_c.checksum; MD5_Init (&md5); t[0] = (usage >> 0) & 0xFF; t[1] = (usage >> 8) & 0xFF; t[2] = (usage >> 16) & 0xFF; t[3] = (usage >> 24) & 0xFF; MD5_Update (&md5, t, 4); MD5_Update (&md5, data, len); MD5_Final (tmp, &md5); ret = hmac(context, c, tmp, sizeof(tmp), 0, &ksign, result); if (ret) krb5_abortx(context, "hmac failed");}/* * same as previous but being used while encrypting. */static voidHMAC_MD5_checksum_enc(krb5_context context, struct key_data *key, const void *data, size_t len, unsigned usage, Checksum *result){ struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); Checksum ksign_c; struct key_data ksign; krb5_keyblock kb; unsigned char t[4]; unsigned char ksign_c_data[16]; krb5_error_code ret; t[0] = (usage >> 0) & 0xFF; t[1] = (usage >> 8) & 0xFF; t[2] = (usage >> 16) & 0xFF; t[3] = (usage >> 24) & 0xFF; ksign_c.checksum.length = sizeof(ksign_c_data); ksign_c.checksum.data = ksign_c_data; ret = hmac(context, c, t, sizeof(t), 0, key, &ksign_c); if (ret) krb5_abortx(context, "hmac failed"); ksign.key = &kb; kb.keyvalue = ksign_c.checksum; ret = hmac(context, c, data, len, 0, &ksign, result); if (ret) krb5_abortx(context, "hmac failed");}static struct checksum_type checksum_none = { CKSUMTYPE_NONE, "none", 1, 0, 0, NONE_checksum, NULL};static struct checksum_type checksum_crc32 = { CKSUMTYPE_CRC32, "crc32", 1, 4, 0, CRC32_checksum, NULL};static struct checksum_type checksum_rsa_md4 = { CKSUMTYPE_RSA_MD4, "rsa-md4", 64, 16, F_CPROOF, RSA_MD4_checksum, NULL};static struct checksum_type checksum_rsa_md4_des = { CKSUMTYPE_RSA_MD4_DES, "rsa-md4-des", 64, 24, F_KEYED | F_CPROOF | F_VARIANT, RSA_MD4_DES_checksum, RSA_MD4_DES_verify};#if 0static struct checksum_type checksum_des_mac = { CKSUMTYPE_DES_MAC, "des-mac", 0, 0, 0, DES_MAC_checksum};static struct checksum_type checksum_des_mac_k = { CKSUMTYPE_DES_MAC_K, "des-mac-k", 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -