📄 crypto.c
字号:
memcpy(out, ivec, len); memcpy(ivec, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE); } else { unsigned char tmp2[AES_BLOCK_SIZE]; unsigned char tmp3[AES_BLOCK_SIZE]; while(len > AES_BLOCK_SIZE * 2) { memcpy(tmp, in, AES_BLOCK_SIZE); AES_decrypt(in, out, key); for (i = 0; i < AES_BLOCK_SIZE; i++) out[i] ^= ivec[i]; memcpy(ivec, tmp, AES_BLOCK_SIZE); len -= AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; } len -= AES_BLOCK_SIZE; memcpy(tmp, in, AES_BLOCK_SIZE); /* save last iv */ AES_decrypt(in, tmp2, key); memcpy(tmp3, in + AES_BLOCK_SIZE, len); memcpy(tmp3 + len, tmp2 + len, AES_BLOCK_SIZE - len); /* xor 0 */ for (i = 0; i < len; i++) out[i + AES_BLOCK_SIZE] = tmp2[i] ^ tmp3[i]; AES_decrypt(tmp3, out, key); for (i = 0; i < AES_BLOCK_SIZE; i++) out[i] ^= ivec[i]; memcpy(ivec, tmp, AES_BLOCK_SIZE); }}static krb5_error_codeAES_CTS_encrypt(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ivec){ struct krb5_aes_schedule *aeskey = key->schedule->data; char local_ivec[AES_BLOCK_SIZE]; AES_KEY *k; if (encryptp) k = &aeskey->ekey; else k = &aeskey->dkey; if (len < AES_BLOCK_SIZE) krb5_abortx(context, "invalid use of AES_CTS_encrypt"); if (len == AES_BLOCK_SIZE) { if (encryptp) AES_encrypt(data, data, k); else AES_decrypt(data, data, k); } else { if(ivec == NULL) { memset(local_ivec, 0, sizeof(local_ivec)); ivec = local_ivec; } _krb5_aes_cts_encrypt(data, data, len, k, ivec, encryptp); } return 0;}/* * section 6 of draft-brezak-win2k-krb-rc4-hmac-03 * * warning: not for small children */static krb5_error_codeARCFOUR_subencrypt(krb5_context context, struct key_data *key, void *data, size_t len, unsigned usage, void *ivec){ struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); Checksum k1_c, k2_c, k3_c, cksum; struct key_data ke; krb5_keyblock kb; unsigned char t[4]; RC4_KEY rc4_key; unsigned char *cdata = data; unsigned char k1_c_data[16], k2_c_data[16], k3_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; k1_c.checksum.length = sizeof(k1_c_data); k1_c.checksum.data = k1_c_data; ret = hmac(NULL, c, t, sizeof(t), 0, key, &k1_c); if (ret) krb5_abortx(context, "hmac failed"); memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data)); k2_c.checksum.length = sizeof(k2_c_data); k2_c.checksum.data = k2_c_data; ke.key = &kb; kb.keyvalue = k2_c.checksum; cksum.checksum.length = 16; cksum.checksum.data = data; ret = hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum); if (ret) krb5_abortx(context, "hmac failed"); ke.key = &kb; kb.keyvalue = k1_c.checksum; k3_c.checksum.length = sizeof(k3_c_data); k3_c.checksum.data = k3_c_data; ret = hmac(NULL, c, data, 16, 0, &ke, &k3_c); if (ret) krb5_abortx(context, "hmac failed"); RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); memset (k1_c_data, 0, sizeof(k1_c_data)); memset (k2_c_data, 0, sizeof(k2_c_data)); memset (k3_c_data, 0, sizeof(k3_c_data)); return 0;}static krb5_error_codeARCFOUR_subdecrypt(krb5_context context, struct key_data *key, void *data, size_t len, unsigned usage, void *ivec){ struct checksum_type *c = _find_checksum (CKSUMTYPE_RSA_MD5); Checksum k1_c, k2_c, k3_c, cksum; struct key_data ke; krb5_keyblock kb; unsigned char t[4]; RC4_KEY rc4_key; unsigned char *cdata = data; unsigned char k1_c_data[16], k2_c_data[16], k3_c_data[16]; unsigned char cksum_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; k1_c.checksum.length = sizeof(k1_c_data); k1_c.checksum.data = k1_c_data; ret = hmac(NULL, c, t, sizeof(t), 0, key, &k1_c); if (ret) krb5_abortx(context, "hmac failed"); memcpy (k2_c_data, k1_c_data, sizeof(k1_c_data)); k2_c.checksum.length = sizeof(k2_c_data); k2_c.checksum.data = k2_c_data; ke.key = &kb; kb.keyvalue = k1_c.checksum; k3_c.checksum.length = sizeof(k3_c_data); k3_c.checksum.data = k3_c_data; ret = hmac(NULL, c, cdata, 16, 0, &ke, &k3_c); if (ret) krb5_abortx(context, "hmac failed"); RC4_set_key (&rc4_key, k3_c.checksum.length, k3_c.checksum.data); RC4 (&rc4_key, len - 16, cdata + 16, cdata + 16); ke.key = &kb; kb.keyvalue = k2_c.checksum; cksum.checksum.length = 16; cksum.checksum.data = cksum_data; ret = hmac(NULL, c, cdata + 16, len - 16, 0, &ke, &cksum); if (ret) krb5_abortx(context, "hmac failed"); memset (k1_c_data, 0, sizeof(k1_c_data)); memset (k2_c_data, 0, sizeof(k2_c_data)); memset (k3_c_data, 0, sizeof(k3_c_data)); if (memcmp (cksum.checksum.data, data, 16) != 0) { krb5_clear_error_string (context); return KRB5KRB_AP_ERR_BAD_INTEGRITY; } else { return 0; }}/* * convert the usage numbers used in * draft-ietf-cat-kerb-key-derivation-00.txt to the ones in * draft-brezak-win2k-krb-rc4-hmac-04.txt */static krb5_error_codeusage2arcfour (krb5_context context, unsigned *usage){ switch (*usage) { case KRB5_KU_AS_REP_ENC_PART : /* 3 */ case KRB5_KU_TGS_REP_ENC_PART_SUB_KEY : /* 9 */ *usage = 8; return 0; case KRB5_KU_USAGE_SEAL : /* 22 */ *usage = 13; return 0; case KRB5_KU_USAGE_SIGN : /* 23 */ *usage = 15; return 0; case KRB5_KU_USAGE_SEQ: /* 24 */ *usage = 0; return 0; default : return 0; }}static krb5_error_codeARCFOUR_encrypt(krb5_context context, struct key_data *key, void *data, size_t len, krb5_boolean encryptp, int usage, void *ivec){ krb5_error_code ret; unsigned keyusage = usage; if((ret = usage2arcfour (context, &keyusage)) != 0) return ret; if (encryptp) return ARCFOUR_subencrypt (context, key, data, len, keyusage, ivec); else return ARCFOUR_subdecrypt (context, key, data, len, keyusage, ivec);}/* * */static krb5_error_codeAES_PRF(krb5_context context, krb5_crypto crypto, const krb5_data *in, krb5_data *out){ struct checksum_type *ct = crypto->et->checksum; krb5_error_code ret; Checksum result; krb5_keyblock *derived; result.cksumtype = ct->type; ret = krb5_data_alloc(&result.checksum, ct->checksumsize); if (ret) { krb5_set_error_string(context, "out memory"); return ret; } (*ct->checksum)(context, NULL, in->data, in->length, 0, &result); if (result.checksum.length < crypto->et->blocksize) krb5_abortx(context, "internal prf error"); derived = NULL; ret = krb5_derive_key(context, crypto->key.key, crypto->et->type, "prf", 3, &derived); if (ret) krb5_abortx(context, "krb5_derive_key"); ret = krb5_data_alloc(out, crypto->et->blocksize); if (ret) krb5_abortx(context, "malloc failed"); { AES_KEY key; AES_set_encrypt_key(derived->keyvalue.data, crypto->et->keytype->bits, &key); AES_encrypt(result.checksum.data, out->data, &key); memset(&key, 0, sizeof(key)); } krb5_data_free(&result.checksum); krb5_free_keyblock(context, derived); return ret;}/* * these should currently be in reverse preference order. * (only relevant for !F_PSEUDO) */static struct encryption_type enctype_null = { ETYPE_NULL, "null", NULL, 1, 1, 0, &keytype_null, &checksum_none, NULL, F_DISABLED, NULL_encrypt, 0, NULL};static struct encryption_type enctype_des_cbc_crc = { ETYPE_DES_CBC_CRC, "des-cbc-crc", NULL, 8, 8, 8, &keytype_des, &checksum_crc32, NULL, 0, DES_CBC_encrypt_key_ivec, 0, NULL};static struct encryption_type enctype_des_cbc_md4 = { ETYPE_DES_CBC_MD4, "des-cbc-md4", NULL, 8, 8, 8, &keytype_des, &checksum_rsa_md4, &checksum_rsa_md4_des, 0, DES_CBC_encrypt_null_ivec, 0, NULL};static struct encryption_type enctype_des_cbc_md5 = { ETYPE_DES_CBC_MD5, "des-cbc-md5", NULL, 8, 8, 8, &keytype_des, &checksum_rsa_md5, &checksum_rsa_md5_des, 0, DES_CBC_encrypt_null_ivec, 0, NULL};static struct encryption_type enctype_arcfour_hmac_md5 = { ETYPE_ARCFOUR_HMAC_MD5, "arcfour-hmac-md5", NULL, 1, 1, 8, &keytype_arcfour, &checksum_hmac_md5, NULL, F_SPECIAL, ARCFOUR_encrypt, 0, NULL};static struct encryption_type enctype_des3_cbc_md5 = { ETYPE_DES3_CBC_MD5, "des3-cbc-md5", NULL, 8, 8, 8, &keytype_des3, &checksum_rsa_md5, &checksum_rsa_md5_des3, 0, DES3_CBC_encrypt, 0, NULL};static struct encryption_type enctype_des3_cbc_sha1 = { ETYPE_DES3_CBC_SHA1, "des3-cbc-sha1", NULL, 8, 8, 8, &keytype_des3_derived, &checksum_sha1, &checksum_hmac_sha1_des3, F_DERIVED, DES3_CBC_encrypt, 0, NULL};static struct encryption_type enctype_old_des3_cbc_sha1 = { ETYPE_OLD_DES3_CBC_SHA1, "old-des3-cbc-sha1", NULL, 8, 8, 8, &keytype_des3, &checksum_sha1, &checksum_hmac_sha1_des3, 0, DES3_CBC_encrypt, 0, NULL};static struct encryption_type enctype_aes128_cts_hmac_sha1 = { ETYPE_AES128_CTS_HMAC_SHA1_96, "aes128-cts-hmac-sha1-96", NULL, 16, 1, 16, &keytype_aes128, &checksum_sha1, &checksum_hmac_sha1_aes128, F_DERIVED, AES_CTS_encrypt, 16, AES_PRF};static struct encryption_type enctype_aes256_cts_hmac_sha1 = { ETYPE_AES256_CTS_HMAC_SHA1_96, "aes256-cts-hmac-sha1-96", NULL, 16, 1, 16, &keytype_aes256, &checksum_sha1, &checksum_hmac_sha1_aes256, F_DERIVED, AES_CTS_encrypt, 16, AES_PRF};static struct encryption_type enctype_des_cbc_none = { ETYPE_DES_CBC_NONE, "des-cbc-none", NULL, 8, 8, 0, &keytype_des, &checksum_none, NULL, F_PSEUDO, DES_CBC_encrypt_null_ivec, 0, NULL};static struct encryption_type enctype_des_cfb64_none = { ETYPE_DES_CFB64_NONE, "des-cfb64-none", NULL, 1, 1, 0, &keytype_des, &checksum_none, NULL, F_PSEUDO, DES_CFB64_encrypt_null_ivec, 0, NULL};static struct encryption_type enctype_des_pcbc_none = { ETYPE_DES_PCBC_NONE, "des-pcbc-none", NULL, 8, 8, 0, &keytype_des, &checksum_none, NULL, F_PSEUDO, DES_PCBC_encrypt_key_ivec, 0, NULL};static struct encryption_type enctype_des3_cbc_none = { ETYPE_DES3_CBC_NONE, "des3-cbc-none", NULL, 8, 8, 0, &keytype_des3_derived, &checksum_none, NULL, F_PSEUDO, DES3_CBC_encrypt, 0, NULL};static struct encryption_type *etypes[] = { &enctype_null, &enctype_des_cbc_crc, &enctype_des_cbc_md4, &enctype_des_cbc_md5, &enctype_arcfour_hmac_md5, &enctype_des3_cbc_md5, &enctype_des3_cbc_sha1, &enctype_old_des3_cbc_sha1, &enctype_aes128_cts_hmac_sha1, &enctype_aes256_cts_hmac_sha1, &enctype_des_cbc_none, &enctype_des_cfb64_none, &enctype_des_pcbc_none, &enctype_des3_cbc_none};static unsigned num_etypes = sizeof(etypes) / sizeof(etypes[0]);static stru
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -