802c8a39fd4b03402c1b1091eb022e11de2b15b8
[strongswan.git] / src / libstrongswan / plugins / xcbc / xcbc.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <string.h>
18
19 #include "xcbc.h"
20
21 #include <utils/debug.h>
22 #include <crypto/mac.h>
23 #include <crypto/prfs/mac_prf.h>
24 #include <crypto/signers/mac_signer.h>
25
26 typedef struct private_mac_t private_mac_t;
27
28 /**
29 * Private data of a mac_t object.
30 *
31 * The variable names are the same as in the RFC.
32 */
33 struct private_mac_t {
34
35 /**
36 * Public mac_t interface.
37 */
38 mac_t public;
39
40 /**
41 * Block size, in bytes
42 */
43 u_int8_t b;
44
45 /**
46 * crypter using k1
47 */
48 crypter_t *k1;
49
50 /**
51 * k2
52 */
53 u_int8_t *k2;
54
55 /**
56 * k3
57 */
58 u_int8_t *k3;
59
60 /**
61 * E
62 */
63 u_int8_t *e;
64
65 /**
66 * remaining, unprocessed bytes in append mode
67 */
68 u_int8_t *remaining;
69
70 /**
71 * number of bytes in remaining
72 */
73 int remaining_bytes;
74
75 /**
76 * TRUE if we have zero bytes to xcbc in final()
77 */
78 bool zero;
79 };
80
81 /**
82 * xcbc supplied data, but do not run final operation
83 */
84 static bool update(private_mac_t *this, chunk_t data)
85 {
86 chunk_t iv;
87
88 if (data.len)
89 {
90 this->zero = FALSE;
91 }
92
93 if (this->remaining_bytes + data.len <= this->b)
94 { /* no complete block, just copy into remaining */
95 memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len);
96 this->remaining_bytes += data.len;
97 return TRUE;
98 }
99
100 iv = chunk_alloca(this->b);
101 memset(iv.ptr, 0, iv.len);
102
103 /* (3) For each block M[i], where i = 1 ... n-1:
104 * XOR M[i] with E[i-1], then encrypt the result with Key K1,
105 * yielding E[i].
106 */
107
108 /* append data to remaining bytes, process block M[1] */
109 memcpy(this->remaining + this->remaining_bytes, data.ptr,
110 this->b - this->remaining_bytes);
111 data = chunk_skip(data, this->b - this->remaining_bytes);
112 memxor(this->e, this->remaining, this->b);
113 if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL))
114 {
115 return FALSE;
116 }
117
118 /* process blocks M[2] ... M[n-1] */
119 while (data.len > this->b)
120 {
121 memcpy(this->remaining, data.ptr, this->b);
122 data = chunk_skip(data, this->b);
123 memxor(this->e, this->remaining, this->b);
124 if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b),
125 iv, NULL))
126 {
127 return FALSE;
128 }
129 }
130
131 /* store remaining bytes of block M[n] */
132 memcpy(this->remaining, data.ptr, data.len);
133 this->remaining_bytes = data.len;
134
135 return TRUE;
136 }
137
138 /**
139 * run last round, data is in this->e
140 */
141 static bool final(private_mac_t *this, u_int8_t *out)
142 {
143 chunk_t iv;
144
145 iv = chunk_alloca(this->b);
146 memset(iv.ptr, 0, iv.len);
147
148 /* (4) For block M[n]: */
149 if (this->remaining_bytes == this->b && !this->zero)
150 {
151 /* a) If the blocksize of M[n] is 128 bits:
152 * XOR M[n] with E[n-1] and Key K2, then encrypt the result with
153 * Key K1, yielding E[n].
154 */
155 memxor(this->e, this->remaining, this->b);
156 memxor(this->e, this->k2, this->b);
157 }
158 else
159 {
160 /* b) If the blocksize of M[n] is less than 128 bits:
161 *
162 * i) Pad M[n] with a single "1" bit, followed by the number of
163 * "0" bits (possibly none) required to increase M[n]'s
164 * blocksize to 128 bits.
165 */
166 if (this->remaining_bytes < this->b)
167 {
168 this->remaining[this->remaining_bytes] = 0x80;
169 while (++this->remaining_bytes < this->b)
170 {
171 this->remaining[this->remaining_bytes] = 0x00;
172 }
173 }
174 /* ii) XOR M[n] with E[n-1] and Key K3, then encrypt the result
175 * with Key K1, yielding E[n].
176 */
177 memxor(this->e, this->remaining, this->b);
178 memxor(this->e, this->k3, this->b);
179 }
180 if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL))
181 {
182 return FALSE;
183 }
184
185 memcpy(out, this->e, this->b);
186
187 /* (2) Define E[0] = 0x00000000000000000000000000000000 */
188 memset(this->e, 0, this->b);
189 this->remaining_bytes = 0;
190 this->zero = TRUE;
191
192 return TRUE;
193 }
194
195 METHOD(mac_t, get_mac, bool,
196 private_mac_t *this, chunk_t data, u_int8_t *out)
197 {
198 /* update E, do not process last block */
199 if (!update(this, data))
200 {
201 return FALSE;
202 }
203
204 if (out)
205 { /* if not in append mode, process last block and output result */
206 return final(this, out);
207 }
208 return TRUE;
209 }
210
211 METHOD(mac_t, get_mac_size, size_t,
212 private_mac_t *this)
213 {
214 return this->b;
215 }
216
217 METHOD(mac_t, set_key, bool,
218 private_mac_t *this, chunk_t key)
219 {
220 chunk_t iv, k1, lengthened;
221
222 /* we support variable keys from RFC4434 */
223 if (key.len == this->b)
224 {
225 lengthened = key;
226 }
227 else if (key.len < this->b)
228 { /* pad short keys */
229 lengthened = chunk_alloca(this->b);
230 memset(lengthened.ptr, 0, lengthened.len);
231 memcpy(lengthened.ptr, key.ptr, key.len);
232 }
233 else
234 { /* shorten key using xcbc */
235 lengthened = chunk_alloca(this->b);
236 memset(lengthened.ptr, 0, lengthened.len);
237 if (!set_key(this, lengthened) ||
238 !get_mac(this, key, lengthened.ptr))
239 {
240 return FALSE;
241 }
242 }
243
244 k1 = chunk_alloca(this->b);
245 iv = chunk_alloca(this->b);
246 memset(iv.ptr, 0, iv.len);
247
248 /*
249 * (1) Derive 3 128-bit keys (K1, K2 and K3) from the 128-bit secret
250 * key K, as follows:
251 * K1 = 0x01010101010101010101010101010101 encrypted with Key K
252 * K2 = 0x02020202020202020202020202020202 encrypted with Key K
253 * K3 = 0x03030303030303030303030303030303 encrypted with Key K
254 */
255
256 memset(k1.ptr, 0x01, this->b);
257 memset(this->k2, 0x02, this->b);
258 memset(this->k3, 0x03, this->b);
259
260 if (!this->k1->set_key(this->k1, lengthened) ||
261 !this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL) ||
262 !this->k1->encrypt(this->k1, chunk_create(this->k3, this->b), iv, NULL) ||
263 !this->k1->encrypt(this->k1, k1, iv, NULL) ||
264 !this->k1->set_key(this->k1, k1))
265 {
266 memwipe(k1.ptr, k1.len);
267 return FALSE;
268 }
269 memwipe(k1.ptr, k1.len);
270 return TRUE;
271 }
272
273 METHOD(mac_t, destroy, void,
274 private_mac_t *this)
275 {
276 this->k1->destroy(this->k1);
277 memwipe(this->k2, this->b);
278 free(this->k2);
279 memwipe(this->k3, this->b);
280 free(this->k3);
281 free(this->e);
282 free(this->remaining);
283 free(this);
284 }
285
286 /*
287 * Described in header
288 */
289 static mac_t *xcbc_create(encryption_algorithm_t algo, size_t key_size)
290 {
291 private_mac_t *this;
292 crypter_t *crypter;
293 u_int8_t b;
294
295 crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size);
296 if (!crypter)
297 {
298 return NULL;
299 }
300 b = crypter->get_block_size(crypter);
301 /* input and output of crypter must be equal for xcbc */
302 if (b != key_size)
303 {
304 crypter->destroy(crypter);
305 return NULL;
306 }
307
308 INIT(this,
309 .public = {
310 .get_mac = _get_mac,
311 .get_mac_size = _get_mac_size,
312 .set_key = _set_key,
313 .destroy = _destroy,
314 },
315 .b = b,
316 .k1 = crypter,
317 .k2 = malloc(b),
318 .k3 = malloc(b),
319 .e = malloc(b),
320 .remaining = malloc(b),
321 .zero = TRUE,
322 );
323 memset(this->e, 0, b);
324
325 return &this->public;
326 }
327
328 /*
329 * Described in header.
330 */
331 prf_t *xcbc_prf_create(pseudo_random_function_t algo)
332 {
333 mac_t *xcbc;
334
335 switch (algo)
336 {
337 case PRF_AES128_XCBC:
338 xcbc = xcbc_create(ENCR_AES_CBC, 16);
339 break;
340 case PRF_CAMELLIA128_XCBC:
341 xcbc = xcbc_create(ENCR_CAMELLIA_CBC, 16);
342 break;
343 default:
344 return NULL;
345 }
346 if (xcbc)
347 {
348 return mac_prf_create(xcbc);
349 }
350 return NULL;
351 }
352
353 /*
354 * Described in header
355 */
356 signer_t *xcbc_signer_create(integrity_algorithm_t algo)
357 {
358 size_t trunc;
359 mac_t *xcbc;
360
361 switch (algo)
362 {
363 case AUTH_AES_XCBC_96:
364 xcbc = xcbc_create(ENCR_AES_CBC, 16);
365 trunc = 12;
366 break;
367 case AUTH_CAMELLIA_XCBC_96:
368 xcbc = xcbc_create(ENCR_CAMELLIA_CBC, 16);
369 trunc = 12;
370 break;
371 default:
372 return NULL;
373 }
374 if (xcbc)
375 {
376 return mac_signer_create(xcbc, trunc);
377 }
378 return NULL;
379 }