]> git.ipfire.org Git - thirdparty/strongswan.git/blob - scripts/crypt_burn.c
quick-mode: Get a reference when adopting the reqid of a rekeyed CHILD_SA
[thirdparty/strongswan.git] / scripts / crypt_burn.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 *
4 * Copyright (C) secunet Security Networks AG
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 <stdio.h>
18 #include <library.h>
19
20 static int burn_crypter(const proposal_token_t *token, u_int limit, u_int len)
21 {
22 chunk_t iv, key, data;
23 crypter_t *crypter;
24 int i = 0;
25 bool ok;
26
27 crypter = lib->crypto->create_crypter(lib->crypto, token->algorithm,
28 token->keysize / 8);
29 if (!crypter)
30 {
31 fprintf(stderr, "%N-%zu not supported\n",
32 encryption_algorithm_names, token->algorithm, token->keysize);
33 return FALSE;
34 }
35
36 iv = chunk_alloc(crypter->get_iv_size(crypter));
37 memset(iv.ptr, 0xFF, iv.len);
38 data = chunk_alloc(round_up(len, crypter->get_block_size(crypter)));
39 memset(data.ptr, 0xDD, data.len);
40 key = chunk_alloc(crypter->get_key_size(crypter));
41 memset(key.ptr, 0xAA, key.len);
42
43 ok = crypter->set_key(crypter, key);
44 while (ok)
45 {
46 if (!crypter->encrypt(crypter, data, iv, NULL))
47 {
48 fprintf(stderr, "encryption failed!\n");
49 ok = FALSE;
50 break;
51 }
52 if (!crypter->decrypt(crypter, data, iv, NULL))
53 {
54 fprintf(stderr, "decryption failed!\n");
55 ok = FALSE;
56 break;
57 }
58 if (limit && ++i == limit)
59 {
60 break;
61 }
62 }
63 crypter->destroy(crypter);
64
65 free(iv.ptr);
66 free(data.ptr);
67 free(key.ptr);
68
69 return ok;
70 }
71
72 static bool burn_aead(const proposal_token_t *token, u_int limit, u_int len)
73 {
74 chunk_t iv, key, data, dataicv, assoc;
75 aead_t *aead;
76 int i = 0;
77 bool ok;
78
79 aead = lib->crypto->create_aead(lib->crypto, token->algorithm,
80 token->keysize / 8, 0);
81 if (!aead)
82 {
83 fprintf(stderr, "%N-%zu not supported\n",
84 encryption_algorithm_names, token->algorithm, token->keysize);
85 return FALSE;
86 }
87
88 iv = chunk_alloc(aead->get_iv_size(aead));
89 memset(iv.ptr, 0xFF, iv.len);
90 dataicv = chunk_alloc(round_up(len, aead->get_block_size(aead)) +
91 aead->get_icv_size(aead));
92 data = chunk_create(dataicv.ptr, dataicv.len - aead->get_icv_size(aead));
93 memset(data.ptr, 0xDD, data.len);
94 assoc = chunk_alloc(13);
95 memset(assoc.ptr, 0xCC, assoc.len);
96 key = chunk_alloc(aead->get_key_size(aead));
97 memset(key.ptr, 0xAA, key.len);
98
99 ok = aead->set_key(aead, key);
100 while (ok)
101 {
102 if (!aead->encrypt(aead, data, assoc, iv, NULL))
103 {
104 fprintf(stderr, "aead encryption failed!\n");
105 ok = FALSE;
106 break;
107 }
108 if (!aead->decrypt(aead, dataicv, assoc, iv, NULL))
109 {
110 fprintf(stderr, "aead integrity check failed!\n");
111 ok = FALSE;
112 break;
113 }
114 if (limit && ++i == limit)
115 {
116 break;
117 }
118 }
119 aead->destroy(aead);
120
121 free(iv.ptr);
122 free(data.ptr);
123 free(key.ptr);
124 free(assoc.ptr);
125
126 return ok;
127 }
128
129 static int burn_signer(const proposal_token_t *token, u_int limit, u_int len)
130 {
131 chunk_t key, data, sig;
132 signer_t *signer;
133 int i = 0;
134 bool ok;
135
136 signer = lib->crypto->create_signer(lib->crypto, token->algorithm);
137 if (!signer)
138 {
139 fprintf(stderr, "%N not supported\n",
140 integrity_algorithm_names, token->algorithm);
141 return FALSE;
142 }
143
144 data = chunk_alloc(len);
145 memset(data.ptr, 0xDD, data.len);
146 key = chunk_alloc(signer->get_key_size(signer));
147 memset(key.ptr, 0xAA, key.len);
148 sig = chunk_alloc(signer->get_block_size(signer));
149
150 ok = signer->set_key(signer, key);
151 while (ok)
152 {
153 if (!signer->get_signature(signer, data, sig.ptr))
154 {
155 fprintf(stderr, "creating signature failed!\n");
156 ok = FALSE;
157 break;
158 }
159 if (!signer->verify_signature(signer, data, sig))
160 {
161 fprintf(stderr, "verifying signature failed!\n");
162 ok = FALSE;
163 break;
164 }
165 if (limit && ++i == limit)
166 {
167 break;
168 }
169 }
170 signer->destroy(signer);
171
172 free(data.ptr);
173 free(key.ptr);
174 free(sig.ptr);
175
176 return ok;
177 }
178
179 int main(int argc, char *argv[])
180 {
181 const proposal_token_t *token;
182 u_int limit = 0, len = 1024;
183 bool ok;
184
185 library_init(NULL, "crypt_burn");
186 lib->plugins->load(lib->plugins, getenv("PLUGINS") ?: PLUGINS);
187 atexit(library_deinit);
188
189 fprintf(stderr, "loaded: %s\n", lib->plugins->loaded_plugins(lib->plugins));
190
191 if (argc < 2)
192 {
193 fprintf(stderr, "usage: %s <algorithm> [buflen=%u] [rounds=%u]\n",
194 argv[0], len, limit);
195 return 1;
196 }
197 if (argc > 2)
198 {
199 len = atoi(argv[2]);
200 if (len > (1 << 30))
201 {
202 fprintf(stderr, "buffer too large (1 GiB limit)\n");
203 return 1;
204 }
205 }
206 if (argc > 3)
207 {
208 limit = atoi(argv[3]);
209 }
210
211 token = lib->proposal->get_token(lib->proposal, argv[1]);
212 if (!token)
213 {
214 fprintf(stderr, "algorithm '%s' unknown!\n", argv[1]);
215 return 1;
216 }
217
218 switch (token->type)
219 {
220 case ENCRYPTION_ALGORITHM:
221 if (encryption_algorithm_is_aead(token->algorithm))
222 {
223 ok = burn_aead(token, limit, len);
224 }
225 else
226 {
227 ok = burn_crypter(token, limit, len);
228 }
229 break;
230 case INTEGRITY_ALGORITHM:
231 ok = burn_signer(token, limit, len);
232 break;
233 default:
234 fprintf(stderr, "'%s' is not a crypter/aead algorithm!\n", argv[1]);
235 ok = FALSE;
236 break;
237 }
238 return !ok;
239 }