"Fossies" - the Fresh Open Source Software Archive 
Member "n2n-3.0/src/transform_cc20.c" (27 Oct 2021, 4938 Bytes) of package /linux/misc/n2n-3.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "transform_cc20.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.8_vs_3.0.
1 /**
2 * (C) 2007-21 - ntop.org and contributors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not see see <http://www.gnu.org/licenses/>
16 *
17 */
18
19
20 #include "n2n.h"
21
22
23 // ChaCha20 plaintext preamble
24 #define CC20_PREAMBLE_SIZE (CC20_IV_SIZE)
25
26
27 typedef struct transop_cc20 {
28 cc20_context_t *ctx;
29 } transop_cc20_t;
30
31
32 static int transop_deinit_cc20 (n2n_trans_op_t *arg) {
33
34 transop_cc20_t *priv = (transop_cc20_t *)arg->priv;
35
36 if(priv->ctx)
37 cc20_deinit(priv->ctx);
38
39 if(priv)
40 free(priv);
41
42 return 0;
43 }
44
45
46 // the ChaCha20 packet format consists of
47 //
48 // - a 128-bit random iv
49 // - encrypted payload
50 //
51 // [IIII|DDDDDDDDDDDDDDDDDDDDD]
52 // |<---- encrypted ---->|
53 //
54 static int transop_encode_cc20 (n2n_trans_op_t *arg,
55 uint8_t *outbuf,
56 size_t out_len,
57 const uint8_t *inbuf,
58 size_t in_len,
59 const uint8_t *peer_mac) {
60
61 int len = -1;
62 transop_cc20_t *priv = (transop_cc20_t *)arg->priv;
63
64 if(in_len <= N2N_PKT_BUF_SIZE) {
65 if((in_len + CC20_PREAMBLE_SIZE) <= out_len) {
66 size_t idx = 0;
67
68 traceEvent(TRACE_DEBUG, "encode_cc20 %lu bytes", in_len);
69
70 // full iv sized random value (128 bit)
71 encode_uint64(outbuf, &idx, n2n_rand());
72 encode_uint64(outbuf, &idx, n2n_rand());
73
74 len = in_len;
75 cc20_crypt(outbuf + CC20_PREAMBLE_SIZE,
76 inbuf,
77 in_len,
78 outbuf, /* iv */
79 priv->ctx);
80
81 // size of datacarried in UDP
82 len += CC20_PREAMBLE_SIZE;
83 } else
84 traceEvent(TRACE_ERROR, "encode_cc20 outbuf too small.");
85 } else
86 traceEvent(TRACE_ERROR, "encode_cc20 inbuf too big to encrypt.");
87
88 return len;
89 }
90
91
92 // see transop_encode_cc20 for packet format
93 static int transop_decode_cc20 (n2n_trans_op_t *arg,
94 uint8_t *outbuf,
95 size_t out_len,
96 const uint8_t *inbuf,
97 size_t in_len,
98 const uint8_t *peer_mac) {
99
100 int len = 0;
101 transop_cc20_t *priv = (transop_cc20_t *)arg->priv;
102
103 if(((in_len - CC20_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in assembly */
104 && (in_len >= CC20_PREAMBLE_SIZE)) { /* has at least iv */
105
106 traceEvent(TRACE_DEBUG, "decode_cc20 %lu bytes", in_len);
107
108 len = (in_len - CC20_PREAMBLE_SIZE);
109
110 cc20_crypt(outbuf,
111 inbuf + CC20_PREAMBLE_SIZE,
112 in_len,
113 inbuf, /* iv */
114 priv->ctx);
115 } else
116 traceEvent(TRACE_ERROR, "decode_cc20 inbuf wrong size (%ul) to decrypt.", in_len);
117
118 return len;
119 }
120
121
122 static int setup_cc20_key (transop_cc20_t *priv, const uint8_t *password, ssize_t password_len) {
123
124 uint8_t key_mat[CC20_KEY_BYTES];
125
126 // the input key always gets hashed to make a more unpredictable and more complete use of the key space
127 pearson_hash_256(key_mat, password, password_len);
128
129 if(cc20_init(key_mat, &(priv->ctx))) {
130 traceEvent(TRACE_ERROR, "setup_cc20_key setup unsuccessful");
131 return -1;
132 }
133
134 traceEvent(TRACE_DEBUG, "setup_cc20_key completed");
135
136 return 0;
137 }
138
139
140 static void transop_tick_cc20 (n2n_trans_op_t *arg, time_t now) {
141
142 // no tick action
143 }
144
145
146 // ChaCha20 initialization function
147 int n2n_transop_cc20_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
148
149 transop_cc20_t *priv;
150 const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
151 size_t encrypt_key_len = strlen(conf->encrypt_key);
152
153 memset(ttt, 0, sizeof(*ttt));
154 ttt->transform_id = N2N_TRANSFORM_ID_CHACHA20;
155
156 ttt->tick = transop_tick_cc20;
157 ttt->deinit = transop_deinit_cc20;
158 ttt->fwd = transop_encode_cc20;
159 ttt->rev = transop_decode_cc20;
160
161 priv = (transop_cc20_t*)calloc(1, sizeof(transop_cc20_t));
162 if(!priv) {
163 traceEvent(TRACE_ERROR, "cannot allocate transop_cc20_t memory");
164 return -1;
165 }
166 ttt->priv = priv;
167
168 // setup the cipher and key
169 return setup_cc20_key(priv, encrypt_key, encrypt_key_len);
170 }