A Discrete-Event Network Simulator
API
onion-routing.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 
3 #include "onion-routing.h"
4 
5 namespace ns3 {
6 
7 /* ... */
8 
9 
10 //Zagotovi, da se registrira TypeId
11 NS_OBJECT_ENSURE_REGISTERED (OnionRouting);
12 
13 NS_LOG_COMPONENT_DEFINE("onionrouting");
14 
15 
16 TypeId
18 {
19  static TypeId tid = TypeId ("ns3::OnionRouting")
20  .SetParent<Object> ()
21  .SetGroupName("OnionRouting");
22  return tid;
23 
24 }
25 
26 
28 
29 
30 
31 
32 /*
33 *
34 * Constructor method
35 * Used to set:
36 * m_keySize -- size in bytes of encryption keys
37 * m_sealPadding -- size increase of the ciphertext in bytes, intorduced by the encryption method (usually needed in publickey cryptography)
38 * m_addressSize -- size in bytes of the used address type (4-Ipv4, 16-Ipv6)
39 *
40 */
41 
42 
43 OnionRouting::OnionRouting(uint16_t keySize ,uint16_t sealPadding, uint16_t addressSize) {
44  this->m_keySize = keySize;
45  this->m_sealPadding = sealPadding;
46  this->m_addressSize = addressSize; //4B for IPv4
47 }
48 
49 
51 
52 
53 
54 
55 /*
56 *
57 * Method to manage the construction of the onion
58 * manages the output to the log component.
59 *
60 */
61 
62 int
63 OnionRouting::BuildOnion(uint8_t * cipher, uint8_t ** route, uint16_t routeLen, uint8_t ** keys, uint8_t * content = nullptr , uint16_t contentLen = 0)
64 {
65  NS_LOG_INFO("Start creation of the onion");
66 
67  m_onionStream.str("");
68 
69  int status = CreateOnion(cipher,route,routeLen, routeLen,keys,content,contentLen);
70 
71  AddressToStream(route[0]);
72 
73  NS_LOG_INFO(m_onionStream.str() << "\nOnion ready");
74 
75  return status;
76 }
77 
78 
79 /*
80 *
81 * Method to construct the onion of encryption layers
82 * uint8_t * cipher -- pointer to reserved memory to store the onion, to compute the needed space see the method OnionLength()
83 * uint8_t ** route -- array of pointers pointing to ip addresses defining the route of the onion,
84 * the route starts from the first node in the onion path and ends at the last hop in the onion path.
85 * each ip address is given as an array of bytes
86 * uint16_t index -- index used to move through the route for the construction of the onion
87 * uint16_t routeLen -- needed to allow the construction of the onion from a route given in forward order
88 * uint8_t ** keys -- array of pointers pointing to encryption keys, each encryption key is given as an array of bytes
89 * uint8_t * content -- pointer to the memory location when the content is stored. The content must be serialized to an array of bytes
90 * uint16_t contentLen -- number of bytes of the content
91 *
92 *
93 *
94 * !! if content is given -> (contentLen > 0) the innermost layer of the onion will be constructed as <0.0.0.0content>,
95 * symbols <> used to denote the encryption using the encryption key of the last hop given in the route.
96 * 0.0.0.0 is the zero ipv4 address. IF ipv6 is used, the layer will include 16 zero bytes denoting the zero address in ipv6.
97 * !! if content is NOT given (contentLen == 0) the innermost layer of the onion will be constructed as <last ip in the route>,
98 * symbols <> used to denote the encryption using the encryption key of penultimate hop given in the route.
99 */
100 
101 
102 int
103 OnionRouting::CreateOnion(uint8_t * cipher, uint8_t ** route, uint16_t index, uint16_t routeLen, uint8_t ** keys, uint8_t * content = nullptr , uint16_t contentLen = 0){
104 
105 
106  //number of bytes to be encrypted in this layer
107  int plainLayerLen = m_addressSize + OnionLength(index - 1,contentLen);
108 
109 
110  uint8_t * nextHopIp = route[routeLen - index + 1]; //next hop address
111  uint8_t * key = keys[routeLen - index]; //public key to encrypt the current layer
112 
113  m_onionStream << "("; //fancy output
114 
115  if(index <= 2 && contentLen != 0){ //stop recursion
116 
117  //Insert the zero address -- 0.0.0.0 (ipv4)
118  for (int i = 0; i < m_addressSize; ++i)
119  {
120  cipher[m_addressSize + m_sealPadding + m_sealPadding + i] = 0;
121  }
122 
123  //Insert content & encrypt
124  memcpy(&cipher[m_addressSize + m_sealPadding + m_sealPadding + m_addressSize], &content[0], contentLen);
125  EncryptLayer(&cipher[m_addressSize + m_sealPadding],&cipher[m_addressSize + m_sealPadding + m_sealPadding],m_addressSize + contentLen,keys[routeLen - index + 1]);
126 
127  }else if(index > 2){ //recursion
128 
129  CreateOnion(&cipher[ m_sealPadding + m_addressSize ],route, index-1, routeLen, keys,content,contentLen);
130 
131  }
132 
133  //Insert next hop address
134  memcpy(&cipher[m_sealPadding], &nextHopIp[0], m_addressSize);
135 
136  AddressToStream(nextHopIp); //fancy output
137 
138  EncryptLayer(cipher,&cipher[m_sealPadding],plainLayerLen,key); //encrypt
139 
140  m_onionStream << ") "; //fancy output
141  return 0;
142 
143 } //create the onion
144 
145 
146 /*
147 *
148 * Method to decipher the onion and extract the content
149 * uint8_t * onion -- pointer to the array of bytes containing the onion
150 * uint16_t onionLen -- length of the onion in bytes
151 * uint8_t * pk -- pointer to the memory location containing the public key
152 * uint8_t * sk -- pointer to the memory location containing the secret key
153 *
154 * Returns a struct containing the next hop address and the inner onion layer.
155 * the length of the inner onion layer is given in the struct
156 */
157 
158 orLayer * OnionRouting::PeelOnion(uint8_t * onion, uint16_t onionLen, uint8_t * pk, uint8_t * sk)
159 {
160  uint8_t * innerLayer = new uint8_t[onionLen - (m_sealPadding)];
161 
162  DecryptLayer(innerLayer,onion,onionLen,pk,sk);
163 
164  orLayer * layer = new orLayer;
165  layer->nextHopIP = innerLayer;
166  layer->innerLayer = &innerLayer[m_addressSize];
167  layer->innerLayerLen = onionLen - m_sealPadding - m_addressSize;
168 
169  return layer;
170 }
171 
172 
173 
174 
175 /*
176 * Computes the number of bytes needed to store the onion
177 * Input: length of the route & length of the content
178 */
179 
180 uint16_t OnionRouting::OnionLength(uint16_t routeLen,uint16_t contentLen)
181 {
182  routeLen = routeLen - 1;
183  if(contentLen == 0){
184  return routeLen * (m_sealPadding + m_addressSize);
185  }else{
186  return routeLen * (m_sealPadding + m_addressSize) + m_sealPadding + m_addressSize + contentLen;
187  }
188 }
189 
190 
191 
192 
193 
194 
195 /*
196 * Print address on stream
197 * 4 fancy output
198 */
199 
201 {
202  m_onionStream << (int) ip[0];
203  for (int i = 1; i < m_addressSize; ++i)
204  {
205  m_onionStream << "." << (int) ip[i];
206  }
207 }
208 
209 
210 
211 }
212 
ns3::OnionRouting::GetTypeId
static TypeId GetTypeId(void)
Definition: onion-routing.cc:17
ns3::OnionRouting::m_keySize
uint16_t m_keySize
Definition: onion-routing.h:51
ns3
Definition: sensornode-helper.cc:26
ns3::orLayer::nextHopIP
uint8_t * nextHopIP
ip address given in the serialized form
Definition: onion-routing.h:23
ns3::OnionRouting::OnionLength
uint16_t OnionLength(uint16_t routeLen, uint16_t contentLen)
Definition: onion-routing.cc:180
ns3::OnionRouting::PeelOnion
orLayer * PeelOnion(uint8_t *onion, uint16_t onionLen, uint8_t *pk, uint8_t *sk)
Definition: onion-routing.cc:158
ns3::OnionRouting::DecryptLayer
virtual void DecryptLayer(uint8_t *innerLayer, uint8_t *onion, uint16_t onionLen, uint8_t *pk, uint8_t *sk) const =0
onion-routing.h
ns3::OnionRouting::CreateOnion
int CreateOnion(uint8_t *cipher, uint8_t **route, uint16_t index, uint16_t routeLen, uint8_t **keys, uint8_t *content, uint16_t contentLen)
Definition: onion-routing.cc:103
ns3::OnionRouting::m_sealPadding
uint16_t m_sealPadding
size increase of the ciphertext in bytes, intorduced by the encryption method
Definition: onion-routing.h:50
ns3::OnionRouting::m_addressSize
uint16_t m_addressSize
size in bytes of the used address type (4-Ipv4, 16-Ipv6)
Definition: onion-routing.h:52
ns3::orLayer
structure holding details resulting from layer decryption of an onion message
Definition: onion-routing.h:22
ns3::orLayer::innerLayer
uint8_t * innerLayer
inner content of the onion message without the next hop address
Definition: onion-routing.h:24
ns3::OnionRouting::AddressToStream
void AddressToStream(uint8_t *ip)
Definition: onion-routing.cc:200
ns3::orLayer::innerLayerLen
uint16_t innerLayerLen
length of the inner content of the onion message
Definition: onion-routing.h:25
ns3::OnionRouting::~OnionRouting
virtual ~OnionRouting()
Definition: onion-routing.cc:50
ns3::OnionRouting::BuildOnion
int BuildOnion(uint8_t *cipher, uint8_t **route, uint16_t routeLen, uint8_t **keys, uint8_t *content, uint16_t contentLen)
Definition: onion-routing.cc:63
ns3::OnionRouting::EncryptLayer
virtual void EncryptLayer(uint8_t *ciphertext, uint8_t *message, int len, uint8_t *key) const =0
ns3::OnionRouting::m_onionStream
std::stringstream m_onionStream
stringstream used to LOG onion construction
Definition: onion-routing.h:56
ns3::OnionRouting::OnionRouting
OnionRouting()
Definition: onion-routing.cc:27