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

📄 ikev2_common.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * IKEv2 common routines for initiator and responder * Copyright (c) 2007, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include "common.h"#include "sha1.h"#include "md5.h"#include "crypto.h"#include "ikev2_common.h"static struct ikev2_integ_alg ikev2_integ_algs[] = {	{ AUTH_HMAC_SHA1_96, 20, 12 },	{ AUTH_HMAC_MD5_96, 16, 12 }};#define NUM_INTEG_ALGS (sizeof(ikev2_integ_algs) / sizeof(ikev2_integ_algs[0]))static struct ikev2_prf_alg ikev2_prf_algs[] = {	{ PRF_HMAC_SHA1, 20, 20 },	{ PRF_HMAC_MD5, 16, 16 }};#define NUM_PRF_ALGS (sizeof(ikev2_prf_algs) / sizeof(ikev2_prf_algs[0]))static struct ikev2_encr_alg ikev2_encr_algs[] = {	{ ENCR_AES_CBC, 16, 16 }, /* only 128-bit keys supported for now */	{ ENCR_3DES, 24, 8 }};#define NUM_ENCR_ALGS (sizeof(ikev2_encr_algs) / sizeof(ikev2_encr_algs[0]))const struct ikev2_integ_alg * ikev2_get_integ(int id){	size_t i;	for (i = 0; i < NUM_INTEG_ALGS; i++) {		if (ikev2_integ_algs[i].id == id)			return &ikev2_integ_algs[i];	}	return NULL;}int ikev2_integ_hash(int alg, const u8 *key, size_t key_len, const u8 *data,		     size_t data_len, u8 *hash){	u8 tmphash[IKEV2_MAX_HASH_LEN];	switch (alg) {	case AUTH_HMAC_SHA1_96:		if (key_len != 20)			return -1;		hmac_sha1(key, key_len, data, data_len, tmphash);		os_memcpy(hash, tmphash, 12);		break;	case AUTH_HMAC_MD5_96:		if (key_len != 16)			return -1;		hmac_md5(key, key_len, data, data_len, tmphash);		os_memcpy(hash, tmphash, 12);		break;	default:		return -1;	}	return 0;}const struct ikev2_prf_alg * ikev2_get_prf(int id){	size_t i;	for (i = 0; i < NUM_PRF_ALGS; i++) {		if (ikev2_prf_algs[i].id == id)			return &ikev2_prf_algs[i];	}	return NULL;}int ikev2_prf_hash(int alg, const u8 *key, size_t key_len,		   size_t num_elem, const u8 *addr[], const size_t *len,		   u8 *hash){	switch (alg) {	case PRF_HMAC_SHA1:		hmac_sha1_vector(key, key_len, num_elem, addr, len, hash);		break;	case PRF_HMAC_MD5:		hmac_md5_vector(key, key_len, num_elem, addr, len, hash);		break;	default:		return -1;	}	return 0;}int ikev2_prf_plus(int alg, const u8 *key, size_t key_len,		   const u8 *data, size_t data_len,		   u8 *out, size_t out_len){	u8 hash[IKEV2_MAX_HASH_LEN];	size_t hash_len;	u8 iter, *pos, *end;	const u8 *addr[3];	size_t len[3];	const struct ikev2_prf_alg *prf;	int res;	prf = ikev2_get_prf(alg);	if (prf == NULL)		return -1;	hash_len = prf->hash_len;	addr[0] = hash;	len[0] = hash_len;	addr[1] = data;	len[1] = data_len;	addr[2] = &iter;	len[2] = 1;	pos = out;	end = out + out_len;	iter = 1;	while (pos < end) {		size_t clen;		if (iter == 1)			res = ikev2_prf_hash(alg, key, key_len, 2, &addr[1],					     &len[1], hash);		else			res = ikev2_prf_hash(alg, key, key_len, 3, addr, len,					     hash);		if (res < 0)			return -1;		clen = hash_len;		if ((int) clen > end - pos)			clen = end - pos;		os_memcpy(pos, hash, clen);		pos += clen;		iter++;	}	return 0;}const struct ikev2_encr_alg * ikev2_get_encr(int id){	size_t i;	for (i = 0; i < NUM_ENCR_ALGS; i++) {		if (ikev2_encr_algs[i].id == id)			return &ikev2_encr_algs[i];	}	return NULL;}#ifdef CCNS_PL/* from des.c */struct des3_key_s {	u32 ek[3][32];	u32 dk[3][32];};void des3_key_setup(const u8 *key, struct des3_key_s *dkey);void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt);void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain);#endif /* CCNS_PL */int ikev2_encr_encrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,		       const u8 *plain, u8 *crypt, size_t len){	struct crypto_cipher *cipher;	int encr_alg;#ifdef CCNS_PL	if (alg == ENCR_3DES) {		struct des3_key_s des3key;		size_t i, blocks;		u8 *pos;		/* ECB mode is used incorrectly for 3DES!? */		if (key_len != 24) {			wpa_printf(MSG_INFO, "IKEV2: Invalid encr key length");			return -1;		}		des3_key_setup(key, &des3key);		blocks = len / 8;		pos = crypt;		for (i = 0; i < blocks; i++) {			des3_encrypt(pos, &des3key, pos);			pos += 8;		}	} else {#endif /* CCNS_PL */	switch (alg) {	case ENCR_3DES:		encr_alg = CRYPTO_CIPHER_ALG_3DES;		break;	case ENCR_AES_CBC:		encr_alg = CRYPTO_CIPHER_ALG_AES;		break;	default:		wpa_printf(MSG_DEBUG, "IKEV2: Unsupported encr alg %d", alg);		return -1;	}	cipher = crypto_cipher_init(encr_alg, iv, key, key_len);	if (cipher == NULL) {		wpa_printf(MSG_INFO, "IKEV2: Failed to initialize cipher");		return -1;	}	if (crypto_cipher_encrypt(cipher, plain, crypt, len) < 0) {		wpa_printf(MSG_INFO, "IKEV2: Encryption failed");		crypto_cipher_deinit(cipher);		return -1;	}	crypto_cipher_deinit(cipher);#ifdef CCNS_PL	}#endif /* CCNS_PL */	return 0;}int ikev2_encr_decrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,		       const u8 *crypt, u8 *plain, size_t len){	struct crypto_cipher *cipher;	int encr_alg;#ifdef CCNS_PL	if (alg == ENCR_3DES) {		struct des3_key_s des3key;		size_t i, blocks;		/* ECB mode is used incorrectly for 3DES!? */		if (key_len != 24) {			wpa_printf(MSG_INFO, "IKEV2: Invalid encr key length");			return -1;		}		des3_key_setup(key, &des3key);		if (len % 8) {			wpa_printf(MSG_INFO, "IKEV2: Invalid encrypted "				   "length");			return -1;		}		blocks = len / 8;		for (i = 0; i < blocks; i++) {			des3_decrypt(crypt, &des3key, plain);			plain += 8;			crypt += 8;		}	} else {#endif /* CCNS_PL */	switch (alg) {	case ENCR_3DES:		encr_alg = CRYPTO_CIPHER_ALG_3DES;		break;	case ENCR_AES_CBC:		encr_alg = CRYPTO_CIPHER_ALG_AES;		break;	default:		wpa_printf(MSG_DEBUG, "IKEV2: Unsupported encr alg %d", alg);		return -1;	}	cipher = crypto_cipher_init(encr_alg, iv, key, key_len);	if (cipher == NULL) {		wpa_printf(MSG_INFO, "IKEV2: Failed to initialize cipher");		return -1;	}	if (crypto_cipher_decrypt(cipher, crypt, plain, len) < 0) {		wpa_printf(MSG_INFO, "IKEV2: Decryption failed");		crypto_cipher_deinit(cipher);		return -1;	}	crypto_cipher_deinit(cipher);#ifdef CCNS_PL	}#endif /* CCNS_PL */	return 0;}int ikev2_parse_payloads(struct ikev2_payloads *payloads,			 u8 next_payload, const u8 *pos, const u8 *end){	const struct ikev2_payload_hdr *phdr;	os_memset(payloads, 0, sizeof(*payloads));	while (next_payload != IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) {		int plen, pdatalen;		const u8 *pdata;		wpa_printf(MSG_DEBUG, "IKEV2: Processing payload %u",			   next_payload);		if (end - pos < (int) sizeof(*phdr)) {			wpa_printf(MSG_INFO, "IKEV2:   Too short message for "				   "payload header (left=%ld)",				   (long) (end - pos));		}		phdr = (const struct ikev2_payload_hdr *) pos;		plen = WPA_GET_BE16(phdr->payload_length);		if (plen < (int) sizeof(*phdr) || pos + plen > end) {			wpa_printf(MSG_INFO, "IKEV2:   Invalid payload header "				   "length %d", plen);			return -1;		}		wpa_printf(MSG_DEBUG, "IKEV2:   Next Payload: %u  Flags: 0x%x"			   "  Payload Length: %d",			   phdr->next_payload, phdr->flags, plen);		pdata = (const u8 *) (phdr + 1);		pdatalen = plen - sizeof(*phdr);		switch (next_payload) {		case IKEV2_PAYLOAD_SA:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Security "				   "Association");			payloads->sa = pdata;			payloads->sa_len = pdatalen;			break;		case IKEV2_PAYLOAD_KEY_EXCHANGE:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Key "				   "Exchange");			payloads->ke = pdata;			payloads->ke_len = pdatalen;			break;		case IKEV2_PAYLOAD_IDi:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: IDi");			payloads->idi = pdata;			payloads->idi_len = pdatalen;			break;		case IKEV2_PAYLOAD_IDr:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: IDr");			payloads->idr = pdata;			payloads->idr_len = pdatalen;			break;		case IKEV2_PAYLOAD_CERTIFICATE:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Certificate");			payloads->cert = pdata;			payloads->cert_len = pdatalen;			break;		case IKEV2_PAYLOAD_AUTHENTICATION:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: "				   "Authentication");			payloads->auth = pdata;			payloads->auth_len = pdatalen;			break;		case IKEV2_PAYLOAD_NONCE:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Nonce");			payloads->nonce = pdata;			payloads->nonce_len = pdatalen;			break;		case IKEV2_PAYLOAD_ENCRYPTED:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: Encrypted");			payloads->encrypted = pdata;			payloads->encrypted_len = pdatalen;			break;		case IKEV2_PAYLOAD_NOTIFICATION:			wpa_printf(MSG_DEBUG, "IKEV2:   Payload: "				   "Notification");			payloads->notification = pdata;			payloads->notification_len = pdatalen;			break;		default:			if (phdr->flags & IKEV2_PAYLOAD_FLAGS_CRITICAL) {

⌨️ 快捷键说明

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