aboutsummaryrefslogtreecommitdiffstats
path: root/src/libipsec/esp_packet.h
blob: f1941a3ba54a11c552e53525592eb1061c4cd5b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright (C) 2012 Tobias Brunner
 * Copyright (C) 2012 Giuliano Grassi
 * Copyright (C) 2012 Ralf Sager
 * Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

/**
 * @defgroup esp_packet esp_packet
 * @{ @ingroup libipsec
 */

#ifndef ESP_PACKET_H_
#define ESP_PACKET_H_

#include "ip_packet.h"
#include "esp_context.h"

#include <library.h>
#include <networking/host.h>
#include <networking/packet.h>

typedef struct esp_packet_t esp_packet_t;

/**
 *  ESP packet
 */
struct esp_packet_t {

	/**
	 * Implements packet_t interface to access the raw ESP packet
	 */
	packet_t packet;

	/**
	 * Get the source address of this packet
	 *
	 * @return				source host
	 */
	host_t *(*get_source)(esp_packet_t *this);

	/**
	 * Get the destination address of this packet
	 *
	 * @return				destination host
	 */
	host_t *(*get_destination)(esp_packet_t *this);

	/**
	 * Parse the packet header before decryption. Tries to read the SPI
	 * from the packet to find a corresponding SA.
	 *
	 * @param spi			parsed SPI, in network byte order
	 * @return				TRUE when successful, FALSE otherwise (e.g. when the
	 *						length of the packet is invalid)
	 */
	bool (*parse_header)(esp_packet_t *this, u_int32_t *spi);

	/**
	 * Authenticate and decrypt the packet. Also verifies the sequence number
	 * using the supplied ESP context and updates the anti-replay window.
	 *
	 * @param esp_context		ESP context of corresponding inbound IPsec SA
	 * @return					- SUCCESS if successfully authenticated,
	 *							  decrypted and parsed
	 *							- PARSE_ERROR if the length of the packet or the
	 *							  padding is invalid
	 *							- VERIFY_ERROR if the sequence number
	 *							  verification failed
	 *							- FAILED if the ICV (MAC) check or the actual
	 *							  decryption failed
	 */
	status_t (*decrypt)(esp_packet_t *this, esp_context_t *esp_context);

	/**
	 * Encapsulate and encrypt the packet. The sequence number will be generated
	 * using the supplied ESP context.
	 *
	 * @param esp_context		ESP context of corresponding outbound IPsec SA
	 * @param spi				SPI value to use, in network byte order
	 * @return					- SUCCESS if encrypted
	 *							- FAILED if sequence number cycled or any of the
	 *							  cryptographic functions failed
	 *							- NOT_FOUND if no suitable IV generator provided
	 */
	status_t (*encrypt)(esp_packet_t *this, esp_context_t *esp_context,
						u_int32_t spi);

	/**
	 * Get the next header field of a packet.
	 *
	 * @note Packet has to be in the decrypted state.
	 *
	 * @return					next header field
	 */
	u_int8_t (*get_next_header)(esp_packet_t *this);

	/**
	 * Get the plaintext payload of this packet.
	 *
	 * @return					plaintext payload (internal data),
	 *							NULL if not decrypted
	 */
	ip_packet_t *(*get_payload)(esp_packet_t *this);

	/**
	 * Extract the plaintext payload from this packet.
	 *
	 * @return					plaintext payload (has to be destroyed),
	 *							NULL if not decrypted
	 */
	ip_packet_t *(*extract_payload)(esp_packet_t *this);

	/**
	 * Destroy an esp_packet_t
	 */
	void (*destroy)(esp_packet_t *this);

};

/**
 * Create an ESP packet out of data from the wire.
 *
 * @param packet		the packet data as received, gets owned
 * @return				esp_packet_t instance
 */
esp_packet_t *esp_packet_create_from_packet(packet_t *packet);

/**
 * Create an ESP packet from a plaintext payload
 *
 * @param src			source address
 * @param dst			destination address
 * @param payload		plaintext payload, gets owned
 * @return				esp_packet_t instance
 */
esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst,
											 ip_packet_t *payload);

#endif /** ESP_PACKET_H_ @}*/