@@ -39,6 +39,97 @@ void PNA_IpsecAccelerator::disable() {
3939 _is_enabled = false ;
4040}
4141
42+ void PNA_IpsecAccelerator::cipher (std::vector<unsigned char > input, std::vector<unsigned char > &output,
43+ unsigned char key[16 ], unsigned char iv[16 ], int encrypt) {
44+ EVP_CIPHER_CTX *ctx;
45+
46+ ctx = EVP_CIPHER_CTX_new ();
47+ if (! EVP_CipherInit_ex2 (ctx, EVP_aes_128_cbc (), key, iv, encrypt, NULL )) {
48+ // Error
49+ EVP_CIPHER_CTX_free (ctx);
50+ return ;
51+ }
52+
53+ EVP_CIPHER_CTX_set_padding (ctx, 0 );
54+
55+ int outlen = 0 ;
56+ int tmplen = 0 ;
57+
58+ if (!EVP_CipherUpdate (ctx, output.data (), &outlen, input.data (),
59+ input.size ())) {
60+ EVP_CIPHER_CTX_free (ctx);
61+ ERR_print_errors_fp (stderr);
62+ BMLOG_DEBUG (" Error in CipherUpdate" );
63+ return ;
64+ }
65+
66+ if (!EVP_CipherFinal_ex (ctx, output.data () + outlen, &tmplen)) {
67+ EVP_CIPHER_CTX_free (ctx);
68+ ERR_print_errors_fp (stderr);
69+ BMLOG_DEBUG (" Error in CipherFinal" );
70+ return ;
71+ }
72+
73+ outlen += tmplen;
74+ output.resize (outlen);
75+ EVP_CIPHER_CTX_free (ctx);
76+ }
77+
78+ void PNA_IpsecAccelerator::decrypt (std::string string_key) {
79+ BMLOG_DEBUG (" [IPSEC] In Decrypt" );
80+
81+ std::vector<unsigned char > raw_packet_data;
82+ raw_packet_data.resize (get_packet ().get_data_size (), ' \0 ' );
83+ std::copy (get_packet ().data (),
84+ get_packet ().data () + get_packet ().get_data_size (),
85+ raw_packet_data.begin ());
86+
87+ unsigned int block_size = EVP_CIPHER_block_size (EVP_aes_128_cbc ());
88+
89+ // TODO:
90+ // check the ICV
91+ // compute HMAC
92+ // drop the packet if ICV and the computed hmac are not the same
93+ unsigned char iv[block_size + 1 ] = {0 };
94+ unsigned char key[string_key.length ()];
95+ std::copy (string_key.begin (), string_key.end (), key);
96+
97+ // Copy IV from the packet
98+ std::copy_n (raw_packet_data.begin () + ETH_HEADER_LENGTH + IP_HEADER_LENGTH
99+ + ESP_SPI_LENGTH + ESP_SEQ_LENGTH, block_size, iv);
100+
101+ std::vector<unsigned char > encrypted;
102+
103+ encrypted.resize (raw_packet_data.size () - ETH_HEADER_LENGTH
104+ - IP_HEADER_LENGTH - ESP_SPI_LENGTH
105+ - ESP_SEQ_LENGTH - block_size, ' \0 ' );
106+ std::copy (raw_packet_data.begin () + ETH_HEADER_LENGTH + IP_HEADER_LENGTH
107+ + ESP_SPI_LENGTH + ESP_SEQ_LENGTH + block_size,
108+ raw_packet_data.end (), encrypted.begin ());
109+
110+ std::vector <unsigned char > decrypted;
111+ decrypted.resize (encrypted.size () + block_size, ' \0 ' );
112+
113+ this ->cipher (encrypted, decrypted, key, iv, 0 );
114+
115+ int padding_length = *(decrypted.data () + decrypted.size () - NEXT_HEADER_LENGTH);
116+
117+ // replace payload
118+
119+ // first, remove all the data
120+ get_packet ().remove (get_packet ().get_data_size ());
121+ // make room for the ciphertext and write the ciphertext in it
122+ char *payload_start = get_packet ().prepend ( (size_t ) (decrypted.size ()
123+ + ETH_HEADER_LENGTH - NEXT_HEADER_LENGTH - padding_length) );
124+
125+ std::copy (raw_packet_data.begin (),
126+ raw_packet_data.begin () + ETH_HEADER_LENGTH,
127+ payload_start);
128+ std::copy (decrypted.begin (),
129+ decrypted.end () - NEXT_HEADER_LENGTH - padding_length,
130+ payload_start + ETH_HEADER_LENGTH);
131+ }
132+
42133BM_REGISTER_EXTERN_W_NAME (ipsec_accelerator, PNA_IpsecAccelerator);
43134BM_REGISTER_EXTERN_W_NAME_METHOD (ipsec_accelerator, PNA_IpsecAccelerator, set_sa_index, const Data &);
44135BM_REGISTER_EXTERN_W_NAME_METHOD (ipsec_accelerator, PNA_IpsecAccelerator, enable);
0 commit comments