implemented XCBC algorithms (signer, prf) for IKE on top of a crypter
[strongswan.git] / src / libstrongswan / plugins / xcbc / xcbc.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General xcbc License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General xcbc License
13 * for more details.
14 *
15 * $Id: xcbc.c 3589 2008-03-13 14:14:44Z martin $
16 */
17
18 #include <string.h>
19
20 #include "xcbc.h"
21
22 #include <debug.h>
23
24 typedef struct private_xcbc_t private_xcbc_t;
25
26 /**
27 * Private data of a xcbc_t object.
28 *
29 * The variable names are the same as in the RFC.
30 */
31 struct private_xcbc_t {
32 /**
33 * Public xcbc_t interface.
34 */
35 xcbc_t xcbc;
36
37 /**
38 * Block size, in bytes
39 */
40 u_int8_t b;
41
42 /**
43 * crypter using k1
44 */
45 crypter_t *k1;
46
47 /**
48 * k2
49 */
50 u_int8_t *k2;
51
52 /**
53 * k3
54 */
55 u_int8_t *k3;
56 };
57
58 /**
59 * Implementation of xcbc_t.get_mac.
60 */
61 static void get_mac(private_xcbc_t *this, chunk_t data, u_int8_t *e)
62 {
63 int n, i, padding;
64 u_int8_t *m;
65 chunk_t iv;
66
67 if (e == NULL)
68 {
69 DBG1("XCBC append mode not implemented!");
70 /* TODO: append mode */
71 return;
72 }
73
74 n = data.len / this->b;
75 padding = data.len % this->b;
76 if (padding || data.len == 0)
77 { /* do an additional block if we have padding or zero-length data */
78 n++;
79 }
80 iv = chunk_alloca(this->b);
81 memset(iv.ptr, 0, iv.len);
82 m = data.ptr;
83
84 /* (2) Define E[0] = 0x00000000000000000000000000000000 */
85 memset(e, 0, this->b);
86
87 /* (3) For each block M[i], where i = 1 ... n-1:
88 * XOR M[i] with E[i-1], then encrypt the result with Key K1,
89 * yielding E[i].
90 */
91 for (i = 1; i < n; i++)
92 {
93 memxor(e, m + (i - 1) * this->b, this->b);
94 this->k1->encrypt(this->k1, chunk_create(e, this->b), iv, NULL);
95 }
96
97 /* (4) For block M[n]: */
98 if (data.len && padding == 0)
99 {
100 /* a) If the blocksize of M[n] is 128 bits:
101 * XOR M[n] with E[n-1] and Key K2, then encrypt the result with
102 * Key K1, yielding E[n].
103 */
104 memxor(e, m + (i - 1) * this->b, this->b);
105 memxor(e, this->k2, this->b);
106 this->k1->encrypt(this->k1, chunk_create(e, this->b), iv, NULL);
107 }
108 else
109 {
110 /* b) If the blocksize of M[n] is less than 128 bits:
111 *
112 * i) Pad M[n] with a single "1" bit, followed by the number of
113 * "0" bits (possibly none) required to increase M[n]'s
114 * blocksize to 128 bits.
115 */
116 u_int8_t *mn = alloca(this->b);
117 memcpy(mn, m + (n - 1) * this->b, padding);
118 mn[padding] = 0x80;
119 while (++padding < this->b)
120 {
121 mn[padding] = 0x00;
122 }
123 /* ii) XOR M[n] with E[n-1] and Key K3, then encrypt the result
124 * with Key K1, yielding E[n].
125 */
126 memxor(e, mn, this->b);
127 memxor(e, this->k3, this->b);
128 this->k1->encrypt(this->k1, chunk_create(e, this->b), iv, NULL);
129 }
130 }
131
132 /**
133 * Implementation of xcbc_t.get_block_size.
134 */
135 static size_t get_block_size(private_xcbc_t *this)
136 {
137 return this->b;
138 }
139
140 /**
141 * Implementation of xcbc_t.set_key.
142 */
143 static void set_key(private_xcbc_t *this, chunk_t key)
144 {
145 chunk_t iv, k1, lengthened;
146
147 /* we support variable keys from RFC4434 */
148 if (key.len == this->b)
149 {
150 lengthened = key;
151 }
152 else if (key.len < this->b)
153 { /* pad short keys */
154 lengthened = chunk_alloca(this->b);
155 memset(lengthened.ptr, 0, lengthened.len);
156 memcpy(lengthened.ptr, key.ptr, key.len);
157 }
158 else
159 { /* shorten key using xcbc */
160 lengthened = chunk_alloca(this->b);
161 memset(lengthened.ptr, 0, lengthened.len);
162 set_key(this, lengthened);
163 get_mac(this, key, lengthened.ptr);
164 }
165
166 k1 = chunk_alloca(this->b);
167 iv = chunk_alloca(this->b);
168 memset(iv.ptr, 0, iv.len);
169
170 /*
171 * (1) Derive 3 128-bit keys (K1, K2 and K3) from the 128-bit secret
172 * key K, as follows:
173 * K1 = 0x01010101010101010101010101010101 encrypted with Key K
174 * K2 = 0x02020202020202020202020202020202 encrypted with Key K
175 * K3 = 0x03030303030303030303030303030303 encrypted with Key K
176 */
177 this->k1->set_key(this->k1, lengthened);
178 memset(this->k2, 0x02, this->b);
179 this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL);
180 memset(this->k3, 0x03, this->b);
181 this->k1->encrypt(this->k1, chunk_create(this->k3, this->b), iv, NULL);
182 memset(k1.ptr, 0x01, this->b);
183 this->k1->encrypt(this->k1, k1, iv, NULL);
184 this->k1->set_key(this->k1, k1);
185 }
186
187 /**
188 * Implementation of xcbc_t.destroy.
189 */
190 static void destroy(private_xcbc_t *this)
191 {
192 this->k1->destroy(this->k1);
193 free(this->k2);
194 free(this->k3);
195 free(this);
196 }
197
198 /*
199 * Described in header
200 */
201 xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size)
202 {
203 private_xcbc_t *this;
204 crypter_t *crypter;
205
206 crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size);
207 if (!crypter)
208 {
209 return NULL;
210 }
211 /* input and output of crypter must be equal for xcbc */
212 if (crypter->get_block_size(crypter) != key_size)
213 {
214 crypter->destroy(crypter);
215 return NULL;
216 }
217
218 this = malloc_thing(private_xcbc_t);
219 this->xcbc.get_mac = (void (*)(xcbc_t *,chunk_t,u_int8_t*))get_mac;
220 this->xcbc.get_block_size = (size_t (*)(xcbc_t *))get_block_size;
221 this->xcbc.set_key = (void (*)(xcbc_t *,chunk_t))set_key;
222 this->xcbc.destroy = (void (*)(xcbc_t *))destroy;
223
224 this->b = crypter->get_block_size(crypter);
225 this->k1 = crypter;
226 this->k2 = malloc(this->b);
227 this->k3 = malloc(this->b);
228
229 return &this->xcbc;
230 }
231