📄 crypto.c
字号:
0, 0, DES_MAC_K_checksum};static struct checksum_type checksum_rsa_md4_des_k = { CKSUMTYPE_RSA_MD4_DES_K, "rsa-md4-des-k", 0, 0, 0, RSA_MD4_DES_K_checksum, RSA_MD4_DES_K_verify};#endifstatic struct checksum_type checksum_rsa_md5 = { CKSUMTYPE_RSA_MD5, "rsa-md5", 64, 16, F_CPROOF, RSA_MD5_checksum, NULL};static struct checksum_type checksum_rsa_md5_des = { CKSUMTYPE_RSA_MD5_DES, "rsa-md5-des", 64, 24, F_KEYED | F_CPROOF | F_VARIANT, RSA_MD5_DES_checksum, RSA_MD5_DES_verify};static struct checksum_type checksum_rsa_md5_des3 = { CKSUMTYPE_RSA_MD5_DES3, "rsa-md5-des3", 64, 24, F_KEYED | F_CPROOF | F_VARIANT, RSA_MD5_DES3_checksum, RSA_MD5_DES3_verify};static struct checksum_type checksum_sha1 = { CKSUMTYPE_SHA1, "sha1", 64, 20, F_CPROOF, SHA1_checksum, NULL};static struct checksum_type checksum_hmac_sha1_des3 = { CKSUMTYPE_HMAC_SHA1_DES3, "hmac-sha1-des3", 64, 20, F_KEYED | F_CPROOF | F_DERIVED, SP_HMAC_SHA1_checksum, NULL};static struct checksum_type checksum_hmac_sha1_aes128 = { CKSUMTYPE_HMAC_SHA1_96_AES_128, "hmac-sha1-96-aes128", 64, 12, F_KEYED | F_CPROOF | F_DERIVED, SP_HMAC_SHA1_checksum, NULL};static struct checksum_type checksum_hmac_sha1_aes256 = { CKSUMTYPE_HMAC_SHA1_96_AES_256, "hmac-sha1-96-aes256", 64, 12, F_KEYED | F_CPROOF | F_DERIVED, SP_HMAC_SHA1_checksum, NULL};static struct checksum_type checksum_hmac_md5 = { CKSUMTYPE_HMAC_MD5, "hmac-md5", 64, 16, F_KEYED | F_CPROOF, HMAC_MD5_checksum, NULL};static struct checksum_type checksum_hmac_md5_enc = { CKSUMTYPE_HMAC_MD5_ENC, "hmac-md5-enc", 64, 16, F_KEYED | F_CPROOF | F_PSEUDO, HMAC_MD5_checksum_enc, NULL};static struct checksum_type *checksum_types[] = { &checksum_none, &checksum_crc32, &checksum_rsa_md4, &checksum_rsa_md4_des,#if 0 &checksum_des_mac, &checksum_des_mac_k, &checksum_rsa_md4_des_k,#endif &checksum_rsa_md5, &checksum_rsa_md5_des, &checksum_rsa_md5_des3, &checksum_sha1, &checksum_hmac_sha1_des3, &checksum_hmac_sha1_aes128, &checksum_hmac_sha1_aes256, &checksum_hmac_md5, &checksum_hmac_md5_enc};static int num_checksums = sizeof(checksum_types) / sizeof(checksum_types[0]);static struct checksum_type *_find_checksum(krb5_cksumtype type){ int i; for(i = 0; i < num_checksums; i++) if(checksum_types[i]->type == type) return checksum_types[i]; return NULL;}static krb5_error_codeget_checksum_key(krb5_context context, krb5_crypto crypto, unsigned usage, /* not krb5_key_usage */ struct checksum_type *ct, struct key_data **key){ krb5_error_code ret = 0; if(ct->flags & F_DERIVED) ret = _get_derived_key(context, crypto, usage, key); else if(ct->flags & F_VARIANT) { int i; *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */); if(*key == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key); if(ret) return ret; for(i = 0; i < (*key)->key->keyvalue.length; i++) ((unsigned char*)(*key)->key->keyvalue.data)[i] ^= 0xF0; } else { *key = &crypto->key; } if(ret == 0) ret = _key_schedule(context, *key); return ret;}static krb5_error_codecreate_checksum (krb5_context context, struct checksum_type *ct, krb5_crypto crypto, unsigned usage, void *data, size_t len, Checksum *result){ krb5_error_code ret; struct key_data *dkey; int keyed_checksum; if (ct->flags & F_DISABLED) { krb5_clear_error_string (context); return KRB5_PROG_SUMTYPE_NOSUPP; } keyed_checksum = (ct->flags & F_KEYED) != 0; if(keyed_checksum && crypto == NULL) { krb5_set_error_string (context, "Checksum type %s is keyed " "but no crypto context (key) was passed in", ct->name); return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ } if(keyed_checksum) { ret = get_checksum_key(context, crypto, usage, ct, &dkey); if (ret) return ret; } else dkey = NULL; result->cksumtype = ct->type; ret = krb5_data_alloc(&result->checksum, ct->checksumsize); if (ret) return (ret); (*ct->checksum)(context, dkey, data, len, usage, result); return 0;}static intarcfour_checksum_p(struct checksum_type *ct, krb5_crypto crypto){ return (ct->type == CKSUMTYPE_HMAC_MD5) && (crypto->key.key->keytype == KEYTYPE_ARCFOUR);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_create_checksum(krb5_context context, krb5_crypto crypto, krb5_key_usage usage, int type, void *data, size_t len, Checksum *result){ struct checksum_type *ct = NULL; unsigned keyusage; /* type 0 -> pick from crypto */ if (type) { ct = _find_checksum(type); } else if (crypto) { ct = crypto->et->keyed_checksum; if (ct == NULL) ct = crypto->et->checksum; } if(ct == NULL) { krb5_set_error_string (context, "checksum type %d not supported", type); return KRB5_PROG_SUMTYPE_NOSUPP; } if (arcfour_checksum_p(ct, crypto)) { keyusage = usage; usage2arcfour(context, &keyusage); } else keyusage = CHECKSUM_USAGE(usage); return create_checksum(context, ct, crypto, keyusage, data, len, result);}static krb5_error_codeverify_checksum(krb5_context context, krb5_crypto crypto, unsigned usage, /* not krb5_key_usage */ void *data, size_t len, Checksum *cksum){ krb5_error_code ret; struct key_data *dkey; int keyed_checksum; Checksum c; struct checksum_type *ct; ct = _find_checksum(cksum->cksumtype); if (ct == NULL || (ct->flags & F_DISABLED)) { krb5_set_error_string (context, "checksum type %d not supported", cksum->cksumtype); return KRB5_PROG_SUMTYPE_NOSUPP; } if(ct->checksumsize != cksum->checksum.length) { krb5_clear_error_string (context); return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */ } keyed_checksum = (ct->flags & F_KEYED) != 0; if(keyed_checksum && crypto == NULL) { krb5_set_error_string (context, "Checksum type %s is keyed " "but no crypto context (key) was passed in", ct->name); return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ } if(keyed_checksum) ret = get_checksum_key(context, crypto, usage, ct, &dkey); else dkey = NULL; if(ct->verify) return (*ct->verify)(context, dkey, data, len, usage, cksum); ret = krb5_data_alloc (&c.checksum, ct->checksumsize); if (ret) return ret; (*ct->checksum)(context, dkey, data, len, usage, &c); if(c.checksum.length != cksum->checksum.length || memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) { krb5_clear_error_string (context); ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } else { ret = 0; } krb5_data_free (&c.checksum); return ret;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_verify_checksum(krb5_context context, krb5_crypto crypto, krb5_key_usage usage, void *data, size_t len, Checksum *cksum){ struct checksum_type *ct; unsigned keyusage; ct = _find_checksum(cksum->cksumtype); if(ct == NULL) { krb5_set_error_string (context, "checksum type %d not supported", cksum->cksumtype); return KRB5_PROG_SUMTYPE_NOSUPP; } if (arcfour_checksum_p(ct, crypto)) { keyusage = usage; usage2arcfour(context, &keyusage); } else keyusage = CHECKSUM_USAGE(usage); return verify_checksum(context, crypto, keyusage, data, len, cksum);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_crypto_get_checksum_type(krb5_context context, krb5_crypto crypto, krb5_cksumtype *type){ struct checksum_type *ct = NULL; if (crypto != NULL) { ct = crypto->et->keyed_checksum; if (ct == NULL) ct = crypto->et->checksum; } if (ct == NULL) { krb5_set_error_string (context, "checksum type not found"); return KRB5_PROG_SUMTYPE_NOSUPP; } *type = ct->type; return 0; }krb5_error_code KRB5_LIB_FUNCTIONkrb5_checksumsize(krb5_context context, krb5_cksumtype type, size_t *size){ struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { krb5_set_error_string (context, "checksum type %d not supported", type); return KRB5_PROG_SUMTYPE_NOSUPP; } *size = ct->checksumsize; return 0;}krb5_boolean KRB5_LIB_FUNCTIONkrb5_checksum_is_keyed(krb5_context context, krb5_cksumtype type){ struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) krb5_set_error_string (context, "checksum type %d not supported", type); return KRB5_PROG_SUMTYPE_NOSUPP; } return ct->flags & F_KEYED;}krb5_boolean KRB5_LIB_FUNCTIONkrb5_checksum_is_collision_proof(krb5_context context, krb5_cksumtype type){ struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) krb5_set_error_string (context, "checksum type %d not supported", type); return KRB5_PROG_SUMTYPE_NOSUPP; } return ct->flags & F_CPROOF;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_checksum_disable(krb5_context context, krb5_cksumtype type){ struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) krb5_set_error_string (context, "checksum type %d not supported", type); return KRB5_PROG_SUMTYPE_NOSUPP; } ct->flags |= F_DISABLED; return 0;}/************************************************************ * * ************************************************************/static krb5_error_codeNULL_encrypt(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ivec){ return 0;}static krb5_error_codeDES_CBC_encrypt_null_ivec(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ignore_ivec){ DES_cblock ivec; DES_key_schedule *s = key->schedule->data; memset(&ivec, 0, sizeof(ivec)); DES_cbc_encrypt(data, data, len, s, &ivec, encryptp); return 0;}static krb5_error_codeDES_CBC_encrypt_key_ivec(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ignore_ivec){ DES_cblock ivec; DES_key_schedule *s = key->schedule->data; memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); DES_cbc_encrypt(data, data, len, s, &ivec, encryptp); return 0;}static krb5_error_codeDES3_CBC_encrypt(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ivec){ DES_cblock local_ivec; DES_key_schedule *s = key->schedule->data; if(ivec == NULL) { ivec = &local_ivec; memset(local_ivec, 0, sizeof(local_ivec)); } DES_ede3_cbc_encrypt(data, data, len, &s[0], &s[1], &s[2], ivec, encryptp); return 0;}static krb5_error_codeDES_CFB64_encrypt_null_ivec(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ignore_ivec){ DES_cblock ivec; int num = 0; DES_key_schedule *s = key->schedule->data; memset(&ivec, 0, sizeof(ivec)); DES_cfb64_encrypt(data, data, len, s, &ivec, &num, encryptp); return 0;}static krb5_error_codeDES_PCBC_encrypt_key_ivec(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ignore_ivec){ DES_cblock ivec; DES_key_schedule *s = key->schedule->data; memcpy(&ivec, key->key->keyvalue.data, sizeof(ivec)); DES_pcbc_encrypt(data, data, len, s, &ivec, encryptp); return 0;}/* * AES draft-raeburn-krb-rijndael-krb-02 */void KRB5_LIB_FUNCTION_krb5_aes_cts_encrypt(const unsigned char *in, unsigned char *out, size_t len, const AES_KEY *key, unsigned char *ivec, const int encryptp){ unsigned char tmp[AES_BLOCK_SIZE]; int i; /* * In the framework of kerberos, the length can never be shorter * then at least one blocksize. */ if (encryptp) { while(len > AES_BLOCK_SIZE) { for (i = 0; i < AES_BLOCK_SIZE; i++) tmp[i] = in[i] ^ ivec[i]; AES_encrypt(tmp, out, key); memcpy(ivec, out, AES_BLOCK_SIZE); len -= AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } for (i = 0; i < len; i++) tmp[i] = in[i] ^ ivec[i]; for (; i < AES_BLOCK_SIZE; i++) tmp[i] = 0 ^ ivec[i]; AES_encrypt(tmp, out - AES_BLOCK_SIZE, key);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -