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