A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
qkd-encryptor.cc
Go to the documentation of this file.
1/*
2 * Copyright(c) 2005,2006 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 *
7 *
8 * Author: Miralem Mehic <miralem.mehic@ieee.org>
9 */
10
11#define NS_LOG_APPEND_CONTEXT \
12 if(GetObject<Node>()) { std::clog << "[node " << GetObject<Node>()->GetId() << "] "; }
13
14#include <string>
15#include <cstdarg>
16#include <iostream>
17#include <sstream>
18#include "ns3/packet.h"
19#include "ns3/assert.h"
20#include "ns3/log.h"
21#include "ns3/node.h"
22#include "qkd-encryptor.h"
23
24namespace ns3 {
25
26NS_LOG_COMPONENT_DEFINE("QKDEncryptor");
27
28NS_OBJECT_ENSURE_REGISTERED(QKDEncryptor);
29
30static const std::string base64_chars =
31 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
32 "abcdefghijklmnopqrstuvwxyz"
33 "0123456789+/";
34
35static inline bool is_base64(unsigned char c) {
36 return(isalnum(c) ||(c == '+') ||(c == '/'));
37}
38
39TypeId
41{
42 static TypeId tid = TypeId("ns3::QKDEncryptor")
44 .AddAttribute("CompressionEnabled", "Indicates whether a compression of packets is enabled.",
45 BooleanValue(false),
48 .AddAttribute("EncryptionEnabled", "Indicates whether a real encryption of packets is enabled.",
49 BooleanValue(false),
52
53 .AddTraceSource("PacketEncrypted",
54 "The change trance for currenly ecrypted packet",
56 "ns3::QKDEncryptor::PacketEncrypted")
57 .AddTraceSource("PacketDecrypted",
58 "The change trance for currenly decrypted packet",
60 "ns3::QKDEncryptor::PacketDecrypted")
61
62 .AddTraceSource("PacketAuthenticated",
63 "The change trance for currenly authenticated packet",
65 "ns3::QKDEncryptor::PacketAuthenticated")
66 .AddTraceSource("PacketDeAuthenticated",
67 "The change trance for currenly deauthenticated packet",
69 "ns3::QKDEncryptor::PacketDeAuthenticated")
70 ;
71 return tid;
72}
73
78
84
93
102
103void
108){
109 if(authTagLength != 128 && authTagLength != 256 ){
110 NS_FATAL_ERROR( this << "Crypto++ supports VMAC with 16 or 32 bytes authentication tag length!");
111 }
112
116}
117
118
120{
121 //NS_LOG_FUNCTION (this);
122}
123
124void
126 m_node = node;
127}
130{
131 return m_node;
132}
133
134void
136 m_index = index;
137}
140{
141 return m_index;
142}
143
144std::string
145QKDEncryptor::EncryptMsg(std::string input, std::string key)
146{
147 NS_LOG_FUNCTION(this << m_encryptionType << input.length() << key.length() );
148
149 std::string output;
150 switch(m_encryptionType)
151 {
152 case UNENCRYPTED:
153 output = input;
154 break;
155 case QKDCRYPTO_OTP:
156 output = OTP(key, input);
157 break;
158 case QKDCRYPTO_AES:
159 output = AESEncrypt(key, input);
160 break;
161 }
162 return output;
163}
164
165std::string
166QKDEncryptor::DecryptMsg(std::string input, std::string key)
167{
168 NS_LOG_FUNCTION(this << m_encryptionType << input.length() << key.length() );
169
170 std::string output;
171 switch(m_encryptionType)
172 {
173 case UNENCRYPTED:
174 output = input;
175 break;
176 case QKDCRYPTO_OTP:
177 output = OTP(key, input);
178 break;
179 case QKDCRYPTO_AES:
180 output = AESDecrypt(key, input);
181 break;
182 }
183 return output;
184}
185
186std::string
187QKDEncryptor::Authenticate(std::string& inputString, std::string key)
188{
189 NS_LOG_FUNCTION(this << inputString.length() << key.length());
191 {
192 case UNAUTHENTICATED:
193 break;
195 return VMAC(key, inputString);
196 break;
198 return MD5(inputString);
199 break;
201 return SHA1(inputString);
202 break;
203 }
204 std::string temp;
205 return temp;
206}
207
208bool
209QKDEncryptor::CheckAuthentication(std::string payload, std::string authTag, std::string key)
210{
211 //@toDo: authentication tag is different even though key and received tag are good, and payload seems to be correct!
212 std::string genAuthTag = Authenticate(payload, key);
213 NS_LOG_FUNCTION( this << key << authTag << genAuthTag );
214 return (genAuthTag == authTag);
215}
216
217
218/***************************************************************
219* CRYPTO++ CRYPTOGRAPHIC FUNCTIONS
220***************************************************************/
221
222std::string
224
225 std::string output;
226 CryptoPP::StringSource(input, true,
227 new CryptoPP::Base64Encoder(
228 new CryptoPP::StringSink(output)
229 ) // Base64Encoder
230 ); // StringSource
231 return output;
232}
233
234std::string
236
237 std::string output;
238 CryptoPP::StringSource(input, true,
239 new CryptoPP::Base64Decoder(
240 new CryptoPP::StringSink(output)
241 ) // Base64Dencoder
242 ); // StringSource
243 return output;
244}
245
246std::string
247QKDEncryptor::OTP(const std::string& key, const std::string& cipherText)
248{
249
250 NS_LOG_FUNCTION(this << cipherText.length() << key.length() );
251 std::string output;
252
253 if(key.size() != cipherText.size()){
254 NS_FATAL_ERROR("KEY SIZE DO NOT MATCH FOR OTP! \nKeySize:" << key.size() << "\nCipterText:" << cipherText.size() << "\n" );
256 }else{
257
258 for(std::size_t i = 0; i < cipherText.size(); i++){
259 output.push_back(key[i] ^ cipherText[i]);
260 }
261
262 }
263
264 return output;
265}
266
267static inline unsigned int value(char c)
268{
269 if(c >= '0' && c <= '9') { return c - '0'; }
270 if(c >= 'a' && c <= 'z') { return c - 'a' + 10; }
271 if(c >= 'A' && c <= 'Z') { return c - 'A' + 36; }
272 if(c == '*') {return 62; }
273 if(c == '$') {return 63; }
274 return -1;
275}
276
277std::string
278QKDEncryptor::COTP(const std::string& key, const std::string& input)
279{
280 NS_LOG_FUNCTION(this << input.length() << key.length());
281 static const char alphanum[] =
282 "0123456789"
283 "abcdefghijklmnopqrstuvwxyz"
284 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
285 "*$"; //additional characters
286
287 std::string output;
288 output.reserve(key.length());
289 if(key.size() == input.size()){
290 for(std::size_t i = 0; i < input.size(); i++){
291 unsigned int v = value(key[i]) ^ value(input[i]);
292 NS_ASSERT(v < sizeof alphanum);
293 output.push_back(alphanum[v]);
294 }
295
296 }else
297 NS_FATAL_ERROR(this << "key size != input size");
298
299 NS_LOG_FUNCTION(this << "\nKey:\t" << key << "\nInput:\t" << input << "\nOutput:\t" << output);
300 return output;
301}
302
303
304
305std::string
306QKDEncryptor::AESEncrypt(const std::string& key, const std::string& data)
307{
308 NS_LOG_FUNCTION( this << data.size() << key.length() );
309
310 memset( m_iv, 0x00, CryptoPP::AES::BLOCKSIZE );
311 std::string encryptData;
312
313 // Encryption
314 CryptoPP::CTR_Mode< CryptoPP::AES >::Encryption encryptor;
315 encryptor.SetKeyWithIV((unsigned char*) key.c_str(), key.length(), m_iv);
316 //encryptor.SetKeyWithIV( key, CryptoPP::AES::DEFAULT_KEYLENGTH, m_iv );
317
318 CryptoPP::StreamTransformationFilter stf( encryptor, new CryptoPP::StringSink( encryptData ) );
319 stf.Put((unsigned char*)data.c_str(), data.size() );
320 stf.MessageEnd();
321
322 return encryptData;
323}
324
325std::string
326QKDEncryptor::AESDecrypt(const std::string& key, const std::string& data)
327{
328 NS_LOG_FUNCTION (this << data.size());
329 memset( m_iv, 0x00, CryptoPP::AES::BLOCKSIZE );
330 std::string decryptData;
331
332 // Decryption
333 CryptoPP::CTR_Mode< CryptoPP::AES >::Decryption decryptor;
334 decryptor.SetKeyWithIV((unsigned char*) key.c_str(), key.length(), m_iv);
335 //decryptor.SetKeyWithIV( key, CryptoPP::AES::DEFAULT_KEYLENGTH, m_iv );
336
337 CryptoPP::StreamTransformationFilter stf( decryptor, new CryptoPP::StringSink( decryptData ) );
338 stf.Put((unsigned char*)data.c_str(), data.size() );
339 stf.MessageEnd();
340
341 return decryptData;
342}
343
344
345std::string
346QKDEncryptor::HexEncode(const std::string& data)
347{
348 NS_LOG_FUNCTION (this << data.size());
349
350 std::string encoded;
351 CryptoPP::StringSource ss(
352 (unsigned char*)data.data(), data.size(), true,
353 new CryptoPP::HexEncoder(new CryptoPP::StringSink(encoded))
354 );
355 return encoded;
356}
357
358std::string
359QKDEncryptor::HexDecode(const std::string& data)
360{
361 NS_LOG_FUNCTION (this << data.size());
362
363 std::string decoded;
364 CryptoPP::StringSource ss(
365 (unsigned char*)data.data(), data.size(), true,
366 new CryptoPP::HexDecoder(new CryptoPP::StringSink(decoded))
367 );
368 return decoded;
369}
370
371std::string
372QKDEncryptor::VMAC(std::string& key, std::string& inputString)
373{
374 NS_LOG_FUNCTION(this << inputString.length() << key.length());
375
376 std::string outputString;
377 memset(m_iv, 0x00, CryptoPP::AES::BLOCKSIZE);
378 CryptoPP::VMAC<CryptoPP::AES> vmac;
379 vmac.SetKeyWithIV(
380 reinterpret_cast<const CryptoPP::byte*>(key.data()),
381 key.size(),
382 m_iv,
383 CryptoPP::AES::BLOCKSIZE
384 );
385
386 const size_t tagSize = vmac.DigestSize(); // ← OVO JE ISPRAVNO
387 std::vector<CryptoPP::byte> digestBytes(tagSize);
388
389 vmac.CalculateDigest(
390 digestBytes.data(),
391 reinterpret_cast<const CryptoPP::byte*>(inputString.data()),
392 inputString.size()
393 );
394
395 CryptoPP::HexEncoder encoder;
396 encoder.Attach(new CryptoPP::StringSink(outputString));
397 encoder.Put(digestBytes.data(), digestBytes.size());
398 encoder.MessageEnd();
399
400 return outputString;
401}
402
403std::string
405{
406 NS_LOG_FUNCTION(this << inputString.length() );
407
408 unsigned char digestBytes[CryptoPP::Weak::MD5::DIGESTSIZE];
409
410 CryptoPP::Weak1::MD5 md5;
411 md5.CalculateDigest(digestBytes,(unsigned char *) inputString.c_str(), inputString.length());
412
413 std::string outputString;
414 CryptoPP::HexEncoder encoder;
415
416 encoder.Attach(new CryptoPP::StringSink(outputString));
417 encoder.Put(digestBytes, sizeof(digestBytes));
418 encoder.MessageEnd();
419
421 return outputString;
422}
423
424std::string
426{
427 NS_LOG_FUNCTION(this << inputString.length() );
428
429 unsigned char digestBytes[CryptoPP::SHA1::DIGESTSIZE];
430
431 CryptoPP::SHA1 sha1;
432 sha1.CalculateDigest(digestBytes,(unsigned char *) inputString.c_str(), inputString.length());
433
434 std::string outputString;
435 CryptoPP::HexEncoder encoder;
436
437 encoder.Attach(new CryptoPP::StringSink(outputString));
438 encoder.Put(digestBytes, sizeof(digestBytes));
439 encoder.MessageEnd();
440
442 return outputString;
443}
444
445} // namespace ns3
AttributeValue implementation for Boolean.
Definition boolean.h:26
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
~QKDEncryptor() override
Destructor.
uint32_t m_index
index in the qkd encryptor container
unsigned char m_iv[CryptoPP::AES::BLOCKSIZE]
bool m_encryptionEnabled
real encryption used?
std::string EncryptMsg(std::string input, std::string key)
Perform encryption of plaintext.
std::string HexDecode(const std::string &data)
Help function used to decode string to HEX string.
std::string AESEncrypt(const std::string &key, const std::string &data)
AES encryption.
EncryptionType
Encryption type.
void SetNode(Ptr< Node > node)
Set node on which qkd encryptor is installed.
Ptr< Node > GetNode() const
Get details about the node on which qkd encryptor is installed.
void SetIndex(uint32_t index)
Set internal index identifier in qkd encryptor container.
bool CheckAuthentication(std::string payload, std::string authTag, std::string key="0")
Check Authentication on packet payload for authenticated packet.
std::string Base64Decode(std::string input)
Base64 decoder.
TracedCallback< Ptr< Packet >, std::string > m_authenticationTrace
trace callback for authentication
std::string VMAC(std::string &key, std::string &inputString)
Authentication function in Wegman-Carter fashion.
std::string OTP(const std::string &key, const std::string &data)
One-time cipher.
uint32_t m_authenticationTagLengthInBits
length of the authentication tag in bits(32 by default)
std::string SHA1(std::string &inputString)
SHA1 Authentication function.
TracedCallback< Ptr< Packet >, std::string > m_deauthenticationTrace
trace callback for authentication check
AuthenticationType m_authenticationType
Ptr< Node > m_node
pointer to node on which encryptor is installed
uint32_t GetIndex() const
Get internal index identifier in qkd encryptor container.
TracedCallback< Ptr< Packet > > m_decryptionTrace
trace callback for decryption
AuthenticationType
Authentication type.
TracedCallback< Ptr< Packet > > m_encryptionTrace
trace callback for encryption
std::string HexEncode(const std::string &data)
Help function used to encode string to HEX string.
std::string Authenticate(std::string &, std::string key="0")
Help parent function used for calling child authentication functions.
std::string COTP(const std::string &key, const std::string &input)
One-Time Pad cipher where output is alfabet/number symbols.
void ChangeSettings(EncryptionType type1, AuthenticationType type2, uint32_t authTagLength)
Constructor.
bool m_compressionEnabled
should compression algorithms be used?
std::string DecryptMsg(std::string input, std::string key)
Perform decryption of ciphertext.
static TypeId GetTypeId()
Get the TypeId.
std::string Base64Encode(std::string input)
Base64 encoder.
EncryptionType m_encryptionType
std::string MD5(std::string &inputString)
MD5 Authentication function.
std::string AESDecrypt(const std::string &key, const std::string &data)
AES decryption.
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
static unsigned int value(char c)
static const std::string base64_chars
static bool is_base64(unsigned char c)
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
uint8_t data[writeSize]