LibIpv6_Interface_Functions.ttcn 52.3 KB
Newer Older
mullers's avatar
mullers committed

		/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - CareOfTest
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendCot(template CareOfTest p_msg)
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
		var CareOfTest v_ipPkt;
		v_ipPkt := valueof(p_msg);
mullers's avatar
mullers committed
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);

		//set extensionHeaders
		if(f_setExtensionHeaders(	v_ipPkt,
									v_ipPkt.ipv6Hdr.sourceAddress,
									v_ipPkt.ipv6Hdr.destinationAddress) != e_success) {
			log(" **** f_sendCoti: Error when calculating length of extension headers ****");
			return e_error;
		}

mullers's avatar
mullers committed
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendCot

			/*
	 * @desc 	This sends a IPv6 packet with MipExtHdr - Fast Nbr Adv
	 *			from an IPv6 node to any NUT.
	 *			
	 * @remark  
	 * @param 	p_msg MIPHeader to be sent	
	 * @return 	execution status
	*/
	function f_sendFastNbrAdv(template FastNeighborAdvertisement p_msg)
mullers's avatar
mullers committed
	runs on LibIpv6Node
	return FncRetCode {
		//Variables
mullers's avatar
mullers committed
		v_ipPkt := valueof(p_msg);
mullers's avatar
mullers committed
		//calc payloadLen
		v_ipPkt.ipv6Hdr.payloadLength := fx_payloadLength (v_ipPkt);

		//set extensionHeaders
		if(f_setExtensionHeaders(	v_ipPkt,
									v_ipPkt.ipv6Hdr.sourceAddress,
									v_ipPkt.ipv6Hdr.destinationAddress) != e_success) {
			log(" **** f_sendFastNbrAdv: Error when calculating length of extension headers ****");
			return e_error;
		}

mullers's avatar
mullers committed
		//send
		ipPort.send(v_ipPkt);

		return e_success;
	}//end f_sendFastNbrAdv

}//end group rfc3775Mipv6_ExtHdrFunctions


group rfc4303Esp_ExtHdrFunctions {
	
mullers's avatar
mullers committed
	function f_init_ipSecParams()
berge's avatar
berge committed
	runs on LibIpv6Node
	return FncRetCode {
mullers's avatar
mullers committed
		var FncRetCode v_ret := e_error;

berge's avatar
berge committed
//		if( (f_getEncryptionIvLen(PX_ENCRYPTION_ALGO) != 0) and (f_getEncryptionIvLen(PX_ENCRYPTION_ALGO) != lengthof(PX_IV))) {
//			v_ret := e_error;
//			log("**** fx_setSecurityParameters: ERROR: Incorrect IV length for the selected encryption algorithm ****");
//		}
berge's avatar
berge committed
		if( f_checkEncryptionKeyLen(PX_ENCRYPTION_ALGO,lengthof(PX_ESP_ENCR_KEY)) != true) {
berge's avatar
berge committed
			log("**** f_init_ipSecParams: ERROR: Incorrect key length for the selected encryption algorithm ****");
			return e_error;
berge's avatar
berge committed
		if( f_checkIntegrityKeyLen(PX_INTEGRITY_ALGO, lengthof(PX_INTEGRITY_KEY)) != true) {
berge's avatar
berge committed
			log("**** f_init_ipSecParams: ERROR: Incorrect key length for the selected integrity algorithm ****");
			return e_error;
		// SAD-OUT
		vc_sad[c_saOut] := {
			spi := PX_SPI/*f_createSpi()*/,
			seqNr := c_uInt32Zero,
			// AH Integrity
			ahIntegrityAlgo := PX_INTEGRITY_ALGO,
			ahIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			icvLen := f_getIcvLen(PX_INTEGRITY_ALGO),
			icvPadLen := f_getIcvPadLen(PX_INTEGRITY_ALGO),
			// ESP encryption
			espEncryptionAlgo := PX_ENCRYPTION_ALGO,
			espEncryptionKey := PX_ESP_ENCR_KEY/*f_createSecretKey()*/,
			// ESP integrity
			espIntegrityAlgo := PX_INTEGRITY_ALGO,
			espIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// Combined mode
			espCombinedModeAlgo := PX_COMBINED_MODE_ALGO,
			espCombinedModeKey := PX_COMBINED_MODE_KEY/*f_createSecretKey()*/,
			// Protocol mode
			ipSecProtocolMode := PX_IP_SEC_PROTOCOL_MODE
		}

		// SAD-IN
		vc_sad[c_saIn] := {
mullers's avatar
mullers committed
			seqNr := c_uInt32Zero,
			// AH Integrity
			ahIntegrityAlgo := PX_INTEGRITY_ALGO,
mullers's avatar
mullers committed
			ahIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			icvLen := f_getIcvLen(PX_INTEGRITY_ALGO),
			icvPadLen := f_getIcvPadLen(PX_INTEGRITY_ALGO),
			// ESP encryption
			espEncryptionAlgo := PX_ENCRYPTION_ALGO,
mullers's avatar
mullers committed
			espEncryptionKey := PX_ESP_ENCR_KEY/*f_createSecretKey()*/,
			// ESP integrity
			espIntegrityAlgo := PX_INTEGRITY_ALGO,
mullers's avatar
mullers committed
			espIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// Combined mode
			espCombinedModeAlgo := PX_COMBINED_MODE_ALGO,
mullers's avatar
mullers committed
			espCombinedModeKey := PX_COMBINED_MODE_KEY/*f_createSecretKey()*/,
			// Protocol mode
			ipSecProtocolMode := PX_IP_SEC_PROTOCOL_MODE
		}
		// SAD-OUT
		vc_sad[c_saRrpOut] := {
			spi := c_saRrpOut/*f_createSpi()*/,
			seqNr := c_uInt32Zero,
			// AH Integrity
			ahIntegrityAlgo := PX_INTEGRITY_ALGO,
			ahIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			icvLen := f_getIcvLen(PX_INTEGRITY_ALGO),
			icvPadLen := f_getIcvPadLen(PX_INTEGRITY_ALGO),
			// ESP encryption
			espEncryptionAlgo := PX_ENCRYPTION_ALGO,
			espEncryptionKey := PX_ESP_ENCR_KEY/*f_createSecretKey()*/,
			// ESP integrity
			espIntegrityAlgo := PX_INTEGRITY_ALGO,
			espIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// Combined mode
			espCombinedModeAlgo := PX_COMBINED_MODE_ALGO,
			espCombinedModeKey := PX_COMBINED_MODE_KEY/*f_createSecretKey()*/,
			// Protocol mode
			ipSecProtocolMode := PX_IP_SEC_PROTOCOL_MODE
		}

		// SAD-IN
		vc_sad[c_saRrpIn] := {
			spi := c_saRrpIn/*f_createSpi()*/,
			seqNr := c_uInt32Zero,
			// AH Integrity
			ahIntegrityAlgo := PX_INTEGRITY_ALGO,
			ahIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			icvLen := f_getIcvLen(PX_INTEGRITY_ALGO),
			icvPadLen := f_getIcvPadLen(PX_INTEGRITY_ALGO),
			// ESP encryption
			espEncryptionAlgo := PX_ENCRYPTION_ALGO,
			espEncryptionKey := PX_ESP_ENCR_KEY/*f_createSecretKey()*/,
			// ESP integrity
			espIntegrityAlgo := PX_INTEGRITY_ALGO,
			espIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// Combined mode
			espCombinedModeAlgo := PX_COMBINED_MODE_ALGO,
			espCombinedModeKey := PX_COMBINED_MODE_KEY/*f_createSecretKey()*/,
			// Protocol mode
			ipSecProtocolMode := PX_IP_SEC_PROTOCOL_MODE
		}
		
		// SAD-OUT
		vc_sad[c_saCnOut] := {
			spi := c_saCnOut/*f_createSpi()*/,
			seqNr := c_uInt32Zero,
			// AH Integrity
			ahIntegrityAlgo := PX_INTEGRITY_ALGO,
			ahIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			icvLen := f_getIcvLen(PX_INTEGRITY_ALGO),
			icvPadLen := f_getIcvPadLen(PX_INTEGRITY_ALGO),
			// ESP encryption
			espEncryptionAlgo := PX_ENCRYPTION_ALGO,
			espEncryptionKey := PX_ESP_ENCR_KEY/*f_createSecretKey()*/,
			// ESP integrity
			espIntegrityAlgo := PX_INTEGRITY_ALGO,
			espIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// Combined mode
			espCombinedModeAlgo := PX_COMBINED_MODE_ALGO,
			espCombinedModeKey := PX_COMBINED_MODE_KEY/*f_createSecretKey()*/,
			// Protocol mode
			ipSecProtocolMode := PX_IP_SEC_PROTOCOL_MODE
		}
		// SAD-IN
		vc_sad[c_saCnIn] := {
			spi := c_saCnIn/*f_createSpi()*/,
			seqNr := c_uInt32Zero,
			// AH Integrity
			ahIntegrityAlgo := PX_INTEGRITY_ALGO,
			ahIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			icvLen := f_getIcvLen(PX_INTEGRITY_ALGO),
			icvPadLen := f_getIcvPadLen(PX_INTEGRITY_ALGO),
			// ESP encryption
			espEncryptionAlgo := PX_ENCRYPTION_ALGO,
			espEncryptionKey := PX_ESP_ENCR_KEY/*f_createSecretKey()*/,
			// ESP integrity
			espIntegrityAlgo := PX_INTEGRITY_ALGO,
			espIntegrityKey := PX_INTEGRITY_KEY/*f_createSecretKey()*/,
			// Combined mode
			espCombinedModeAlgo := PX_COMBINED_MODE_ALGO,
			espCombinedModeKey := PX_COMBINED_MODE_KEY/*f_createSecretKey()*/,
			// Protocol mode
			ipSecProtocolMode := PX_IP_SEC_PROTOCOL_MODE
		}		
mullers's avatar
mullers committed
		//TODO chose in function of PX_SPI the SAD to be used for testing
//		v_ret := fx_setSecurityParameters(Sad:{vc_sad[c_saOut]});
		v_ret := fx_setSecurityParameters(vc_sad);
berge's avatar
berge committed
		if (v_ret != e_success) {log("f_init_ipSecParams: Error when setting security parameters");}
		
		return v_ret;
mullers's avatar
mullers committed
	}//end f_init_ipSecParams
mullers's avatar
mullers committed
	//in units of octets
	function f_getIcvLen(IntegrityAlgo p_integrityAlgo)
	runs on LibIpv6Node
	return UInt8 {
		if(p_integrityAlgo == e_sha1) {
			return 20;
		}
		else if (p_integrityAlgo == e_hmac_sha1_64){
			return 8;
		}
mullers's avatar
mullers committed
		else if(p_integrityAlgo == e_null) {
			return 0;	
		}
mullers's avatar
mullers committed
	//in units of octets
	function f_getIcvPadLen(IntegrityAlgo p_integrityAlgo)
	runs on LibIpv6Node
	return UInt8 {
		if(p_integrityAlgo == e_sha1) {
			return 0;
		}
		else if (p_integrityAlgo == e_hmac_sha1_64){
			return 4;
		}
mullers's avatar
mullers committed
		else if(p_integrityAlgo == e_null) {
mullers's avatar
mullers committed
			//ICV is omit, but padding is needed
			return 4;	
mullers's avatar
mullers committed
		}
	//in units of octets
	function f_checkIntegrityKeyLen(IntegrityAlgo p_integrityAlgo, UInt8 p_keyLen)
	runs on LibIpv6Node
	return boolean {
		if((p_integrityAlgo == e_sha1) and (p_keyLen != 20)) {
			return false;
		}
berge's avatar
berge committed
		else if ((p_integrityAlgo == e_sha1_96) and (p_keyLen != 20)){
			return false;
		}
		else if ((p_integrityAlgo == e_hmac_sha1_64) and (p_keyLen != 20)){
			return false;
		}
berge's avatar
berge committed
		else if ((p_integrityAlgo == e_hmac_sha1_96) and (p_keyLen != 20)){
			return false;
		}
		else if((p_integrityAlgo == e_hmac_md5_96) and (p_keyLen != 16)) {
			return false;	
		}
	
		return true;
	}
	//in units of octets
	function f_getEncryptionIvLen(EncryptionAlgo p_encryptionAlgo)
	runs on LibIpv6Node
	return UInt8 {
		if(p_encryptionAlgo == e_tripleDes_cbc) {
			return 8;
		}
		else if (p_encryptionAlgo == e_aes_cbc){
			return 16;
		}
		else if(p_encryptionAlgo == e_aes_ctr) {
			return 8;	
		}
		else if(p_encryptionAlgo == e_des_cbc) {
			return 8;	
		}
		return 0;
	}

	//in units of octets
	function f_checkEncryptionKeyLen(EncryptionAlgo p_encryptionAlgo, UInt8 p_keyLen)
	runs on LibIpv6Node
	return boolean {
		if((p_encryptionAlgo == e_tripleDes_cbc) and (p_keyLen != 24)){
			return false;
		}
berge's avatar
berge committed
		else if ((p_encryptionAlgo == e_aes_cbc) and ((p_keyLen < 0) or (p_keyLen > 32))){
			return false;
		}
		else if((p_encryptionAlgo == e_aes_ctr) 
				and (p_keyLen != 20) and (p_keyLen != 28) and (p_keyLen != 36)){
			return false;	
		}
		else if((p_encryptionAlgo == e_des_cbc) and (p_keyLen != 8)){
			return false;	
		}
		return true;
	}

	/*
	 * @desc 	This generates Security Parameters Index
	 * @return 	Security Parameters Index
	*/
	function f_createSpi()
	runs on LibIpv6Node
	return UInt32 {
		var Oct4 v_spi := int2oct(float2int(int2float(20000-5000)*rnd())+5000, 4);

		return oct2int(v_spi);
	}//end f_createSpi

	/*
	 * @desc 	This generates a secret key
	 * @return 	Secret key
	*/
	function f_createSecretKey()
	runs on LibIpv6Node
	return octetstring {
		var Oct20 v_key := int2oct(float2int(int2float(20000-5000)*rnd())+5000, 20);

		return v_key;
	}//end f_createSecretKey

	/*
	 * @desc 	
	 *			This function is used when sending messages.
	 * @param 	p_msg ExtensionHeaderList to be treated	
	 * @return 	execution status 
	*/
	function f_getOriginalIpv6Packet(	in Ipv6Packet p_ipv6Packet,
										in EspHeader p_espHeader,
										out Ipv6Packet p_originalIpv6Packet)
	runs on LibIpv6Node
	return FncRetCode {
		var UInt8 i;
		var boolean v_loop := true;

		if (not(ispresent(p_espHeader.espPayload.espIpDatagram.extHdrList))
			and not(ispresent(p_espHeader.espPayload.espIpDatagram.ipv6Payload))) {
berge's avatar
berge committed
				log("**** f_setEspHeader: EspHeader.espPayload.espIpDatagram received that does neither contain extHdrList not ipv6Payload => EspHeader is not constructed correctly ****")	;			
				return e_error;
		}

		//Build original packet
		p_originalIpv6Packet.ipv6Hdr := p_ipv6Packet.ipv6Hdr;
		if (ispresent(p_espHeader.espPayload.espIpDatagram.extHdrList)) {
			p_originalIpv6Packet.extHdrList := p_espHeader.espPayload.espIpDatagram.extHdrList;
		}
		if (ispresent(p_espHeader.espPayload.espIpDatagram.ipv6Payload)) {
			p_originalIpv6Packet.ipv6Payload := p_espHeader.espPayload.espIpDatagram.ipv6Payload;
		}

		// is a tunneledIpv6Hdr in the extHdrList? If yes, then it becomes the Ipv6Hdr of the original packet
berge's avatar
berge committed
		// FIXME: check only the first extHdr
		if (ispresent(p_espHeader.espPayload.espIpDatagram.extHdrList)) {
			for (i:=0; i<sizeof(p_espHeader.espPayload.espIpDatagram.extHdrList) and v_loop ;i:=i+1) {
				if (ischosen(p_espHeader.espPayload.espIpDatagram.extHdrList[i].tunneledIpv6)) {
					p_originalIpv6Packet.ipv6Hdr := p_espHeader.espPayload.espIpDatagram.extHdrList[i].tunneledIpv6;
					v_loop := false;
				}
				else {
					p_originalIpv6Packet.extHdrList[i] := p_espHeader.espPayload.espIpDatagram.extHdrList[i];	
				}
			}
		}

		p_originalIpv6Packet.ipv6Hdr.payloadLength := fx_payloadLength (p_originalIpv6Packet);

		return e_success;

	}//end f_setEspHeader

mullers's avatar
mullers committed
	/*
mullers's avatar
mullers committed
	 *			This function is used when sending messages.
	 * @param 	p_msg ExtensionHeaderList to be treated	
	 * @return 	execution status 
	*/
/*	function f_setEspHeader(	in Ipv6Packet p_ipv6Packet,
								inout EspHeader p_espHeader)
mullers's avatar
mullers committed
	runs on LibIpv6Node
	return FncRetCode {
		var Ipv6Header v_originalIpv6Hdr;
		var EchoRequest v_originalEchoRequest;
		var EchoReply v_originalEchoReply;

		//treat MipHdr and other ext
		if (ispresent(p_espHeader.espPayload.espIpDatagram.extHdrList)) {
			
			
		}

mullers's avatar
mullers committed
		if (ispresent(p_espHeader.espPayload.espIpDatagram.ipv6Payload)) {
			if (ischosen(p_espHeader.espPayload.espIpDatagram.ipv6Payload.echoRequestMsg)) {	
				if (ischosen(p_espHeader.espPayload.espIpDatagram.extHdrList[0].tunneledIpv6)) {//tunnelMode
					v_originalIpv6Hdr := p_espHeader.espPayload.espIpDatagram.extHdrList[0].tunneledIpv6;
				}
				else { //transportMode
					v_originalIpv6Hdr := p_ipv6Packet.ipv6Hdr;
				}
				//build original packet
				v_originalEchoRequest := {
					ipv6Hdr := v_originalIpv6Hdr,
					extHdrList := omit,
					ipv6Payload := p_espHeader.espPayload.espIpDatagram.ipv6Payload
				}
				//calc checksum 
				if (v_originalEchoRequest.ipv6Payload.echoRequestMsg.checksum != c_2ZeroBytes) {
					//calc checksum
					v_originalEchoRequest.ipv6Payload.echoRequestMsg.checksum := fx_icmpv6Checksum(v_originalEchoRequest);
				}
				//assign checksum
				p_espHeader.espPayload.espIpDatagram.ipv6Payload.echoRequestMsg.checksum := v_originalEchoRequest.ipv6Payload.echoRequestMsg.checksum;
			}
			else if (ischosen(p_espHeader.espPayload.espIpDatagram.ipv6Payload.echoReplyMsg)) {
				if (ischosen(p_espHeader.espPayload.espIpDatagram.extHdrList[0].tunneledIpv6)) {//tunnelMode
					v_originalIpv6Hdr := p_espHeader.espPayload.espIpDatagram.extHdrList[0].tunneledIpv6;
				}
				else { //transportMode
					v_originalIpv6Hdr := p_ipv6Packet.ipv6Hdr;
				}
				//build original packet
				v_originalEchoReply := {
					ipv6Hdr := v_originalIpv6Hdr,
					extHdrList := omit,
					ipv6Payload := p_espHeader.espPayload.espIpDatagram.ipv6Payload
				}
				//calc checksum 
				if (v_originalEchoReply.ipv6Payload.echoReplyMsg.checksum != c_2ZeroBytes) {
					//calc checksum
					v_originalEchoReply.ipv6Payload.echoReplyMsg.checksum := fx_icmpv6Checksum(v_originalEchoReply);
				}
				//assign checksum
				p_espHeader.espPayload.espIpDatagram.ipv6Payload.echoReplyMsg.checksum := v_originalEchoReply.ipv6Payload.echoReplyMsg.checksum;
			}
mullers's avatar
mullers committed
		return e_success;
mullers's avatar
mullers committed
	}//end f_setEspHeader
	
}//end group rfc4303Esp_ExtHdrFunctions

	
} // end module LibIpv6_Interface_Functions