1 /******************************************************************************
2  * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3  * Copyright (C) 2009-2013 Sourcefire, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License Version 2 as
7  * published by the Free Software Foundation.  You may not use, modify or
8  * distribute this program under any other version of the GNU General
9  * Public License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  *
20  ******************************************************************************/
21 
22 #ifndef __OBFUSCATION_H__
23 #define __OBFUSCATION_H__
24 
25 #include <daq.h>
26 #include "decode.h"
27 
28 
29 /*******************************************************************************
30  * Macros
31  ******************************************************************************/
32 /* This should be defined to be greater than or equal to the maximum
33  * amount of data expected to be obfuscated */
34 #define OB_LENGTH_MAX  UINT16_MAX
35 
36 
37 /*******************************************************************************
38  * Types
39  ******************************************************************************/
40 typedef uint8_t   ob_char_t;
41 typedef uint16_t  ob_size_t;
42 
43 typedef enum _ObRet
44 {
45     OB_RET_SUCCESS,
46     OB_RET_ERROR,
47     OB_RET_OVERFLOW
48 
49 } ObRet;
50 
51 
52 /*******************************************************************************
53  * Callback to use for obfuscating payload or stream segments - see API below.
54  *
55  * The first chunk of a payload or stream segment whether needing obfuscation
56  * or not will pass a valid pcap_pkthdr struct. Subsequent calls will pass NULL
57  * for this structure.  This is useful, especially for the stream segment API
58  * call to know when a new segment begins.  Any new "payload" will have a valid
59  * pcap_pkthdr struct.
60  *
61  * If the slice sent in has a non-NULL packet data pointer, the data should *NOT*
62  * be obfuscated.
63  *
64  * If the chunk sent in has a NULL packet data pointer, then that chunk of data
65  * should be obfuscated with the obfuscation character.
66  *
67  * The length passed in is the amount of data that should be copied from the
68  * packet data pointer or the amount of data that should be written with the
69  * obfuscation character.
70  *
71  * Arguments
72  *  DAQ_PktHdr_t *pkth
73  *   The pcap header that contains the packet caplen and timestamps
74  *  uint8_t *packet_data
75  *   A pointer to the current offset into the packet data.  NULL if
76  *   obfuscation of the payload slice is required.
77  *  ob_char_t ob_char
78  *   The obfuscation character to use if packet_data is NULL.
79  *  ob_size_t length
80  *   The amount of data to be logged or obfuscated.
81  *  void *user_data
82  *   The user data passed in to the API functions obfuscatePayload() or
83  *   obfuscateStreamSegments below.
84  *
85  * Returns
86  *  OB_RET_SUCCESS  if all is good
87  *  OB_RET_ERROR  if the rest of the obfuscation should not be done
88  *
89  ******************************************************************************/
90 typedef ObRet (*ObfuscationCallback)
91     (
92      const DAQ_PktHdr_t *pkth,
93      const uint8_t *packet_data,
94      ob_size_t length,
95      ob_char_t ob_char,
96      void *user_data
97     );
98 
99 
100 /*******************************************************************************
101  * Obfuscation API
102  ******************************************************************************/
103 typedef struct _ObfuscationApi
104 {
105     /*
106      * Resets/clears any entries that have been added
107      * Should be done per packet aquisition
108      *
109      * Arguments
110      *  None
111      *
112      * Returns
113      *  None
114      */
115 
116     void (*resetObfuscationEntries)(void);
117 
118 
119     /*
120      * Adds an obfuscation entry to the queue
121      *
122      * Arguments
123      *  Packet *p
124      *   The Packet struct that has the payload data that should be obfuscated
125      *  ob_size_t offset
126      *   The offset from the beginning of the payload to start obfuscation
127      *  ob_size_t length
128      *   The amount of data to obfuscate
129      *  ob_char_t ob_char
130      *   The character to use when obfuscating
131      *
132      * There are two types of entries that can be added.  A slice entry that
133      * has an offset and length less than OB_LENGTH_MAX and an entry with
134      * length OB_LENGTH_MAX that implies obfuscating from offset to the end
135      * of the packet data.
136      *
137      * NOTE --
138      * There is a fixed size of slice entries and OB_LENGTH_MAX entries.
139      * If OB_RET_OVERFLOW is returned when attempting to add a slice entry,
140      * a second call can be made to add an OB_LENGTH_MAX entry.  Only one
141      * OB_LENGTH_MAX entry can be associated with each Packet.  If there is
142      * already an OB_LENGTH_MAX entry for the packet, the lower of the two
143      * offsets will be used.  Although you should check for OB_RET_OVERFLOW
144      * when attempting to add an OB_LENGTH_MAX entry, the fixed size should
145      * be more than enough space to store an entry for each possible packet
146      * that could be in the system at the time.
147      *
148      * Returns
149      *  OB_RET_SUCCESS on sucess
150      *  OB_RET_ERROR  on error
151      *  OB_RET_OVERFLOW  if there is no space left to add an entry
152      */
153 
154     ObRet (*addObfuscationEntry)(Packet *p, ob_size_t offset,
155             ob_size_t length, ob_char_t ob_char);
156 
157 
158     /*
159      * Determines if there are any obfuscation entries associated with
160      * the given Packet
161      *
162      * Arguments
163      *  Packet *
164      *   The Packet to check
165      *
166      * Returns
167      *  1  if the packet requires obfuscation
168      *  0  if it doesn't
169      */
170 
171     int (*payloadObfuscationRequired)(Packet *p);
172 
173 
174     /*
175      * Obfuscate the payload associated with the Packet.  Mainly for use by the
176      * output system to print or log an obfuscated payload.  The callback will
177      * be called for both payload segments that need obfuscation and those that
178      * don't.  See comment on ObfuscationCallback above.
179      *
180      * Arguments
181      *  Packet *
182      *   The Packet whose payload should be obfuscated
183      *  ObfuscationCallback
184      *   The function that will be called for each obfuscated and
185      *   non-obfuscated segment in the payload
186      *  void *
187      *   User data that will be passed to the callback
188      *
189      * Returns
190      *  OB_RET_SUCCESS  on sucess
191      *  OB_RET_ERROR  on error
192      */
193 
194     ObRet (*obfuscatePacket)(Packet *p,
195             ObfuscationCallback callback, void *user_data);
196 
197 
198     /*
199      * Obfuscate the stream segments associated with the Packet.  Mainly for use
200      * by the output system to print or log the stream segments associated with
201      * a Packet that have been marked as needing obfuscation.  The callback will
202      * be called for both stream segments that need obfuscation and those that
203      * don't.  It will be called for all stream segments.  See comment on
204      * ObfuscationCallback above.
205      *
206      * Arguments
207      *  Packet *
208      *   The Packet whose stream segments should be obfuscated
209      *  ObfuscationCallback
210      *   The function that will be called for each obfuscated and
211      *   non-obfuscated part of the stream segments.
212      *  void *
213      *   User data that will be passed to the callback
214      *
215      * Returns
216      *  OB_RET_SUCCESS  on sucess
217      *  OB_RET_ERROR  on error
218      */
219 
220     ObRet (*obfuscatePacketStreamSegments)(Packet *p,
221             ObfuscationCallback callback, void *user_data);
222 
223 
224     /*
225      * Obfuscates the Packet payload and returns payload and payload length
226      * in parameters
227      *
228      * NOTE
229      * *payload will be set to NULL, so don't pass in an already
230      *      allocated pointer.
231      * *payload_len will be zeroed.
232      *
233      * The payload returned is dynamically allocated and MUST be free'd.
234      *
235      * Arguments
236      *  Packet *
237      *   The Packet whose payload should be obfuscated
238      *  uint8_t **payload
239      *   A pointer to a payload pointer so it can be allocated, returned
240      *   and accessed.
241      *  ob_size_t *payload_len
242      *   A pointer to an ob_size_t so the length can be returned.
243      *
244      * Returns
245      *  OB_RET_ERROR  if the payload could not be obfuscated
246      *                the pointers to payload and payload_len will not be valid
247      *  OB_RET_SUCCESS  if the payload was obfuscated
248      *                  the pointers to payload and payload_len will be valid
249      */
250 
251     ObRet (*getObfuscatedPayload)(Packet *p, uint8_t **payload,
252             ob_size_t *payload_len);
253 
254     /*
255      * Prints the current obfuscation entries.
256      *
257      * Arguments
258      *  int sorted
259      *   Print the sorted entries and sort if necessary.
260      *
261      * Returns
262      *  None
263      */
264 
265     void (*printObfuscationEntries)(int sorted);
266 
267 } ObfuscationApi;
268 
269 /* For access when including header */
270 extern ObfuscationApi *obApi;
271 
272 #endif  /* __OBFUSCATION_H__ */
273