4
* cipher meta-functions
13
* Copyright (c) 2001-2006, Cisco Systems, Inc.
14
* All rights reserved.
16
* Redistribution and use in source and binary forms, with or without
17
* modification, are permitted provided that the following conditions
20
* Redistributions of source code must retain the above copyright
21
* notice, this list of conditions and the following disclaimer.
23
* Redistributions in binary form must reproduce the above
24
* copyright notice, this list of conditions and the following
25
* disclaimer in the documentation and/or other materials provided
26
* with the distribution.
28
* Neither the name of the Cisco Systems, Inc. nor the names of its
29
* contributors may be used to endorse or promote products derived
30
* from this software without specific prior written permission.
32
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
36
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43
* OF THE POSSIBILITY OF SUCH DAMAGE.
48
#include "rand_source.h" /* used in invertibiltiy tests */
49
#include "alloc.h" /* for crypto_alloc(), crypto_free() */
51
debug_module_t mod_cipher = {
52
0, /* debugging is off by default */
53
"cipher" /* printable module name */
57
cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) {
59
/* zeroize the buffer */
60
octet_string_set_to_zero(buffer, num_octets_to_output);
62
/* exor keystream into buffer */
63
return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output);
66
/* some bookkeeping functions */
69
cipher_get_key_length(const cipher_t *c) {
74
* cipher_type_self_test(ct) tests a cipher of type ct against test cases
75
* provided in an array of values of key, salt, xtd_seq_num_t,
76
* plaintext, and ciphertext that is known to be good
79
#define SELF_TEST_BUF_OCTETS 128
80
#define NUM_RAND_TESTS 128
81
#define MAX_KEY_LEN 64
84
cipher_type_self_test(const cipher_type_t *ct) {
85
const cipher_test_case_t *test_case = ct->test_data;
88
uint8_t buffer[SELF_TEST_BUF_OCTETS];
89
uint8_t buffer2[SELF_TEST_BUF_OCTETS];
91
int i, j, case_num = 0;
93
debug_print(mod_cipher, "running self-test for cipher %s",
97
* check to make sure that we have at least one test case, and
98
* return an error if we don't - we need to be paranoid here
100
if (test_case == NULL)
101
return err_status_cant_check;
104
* loop over all test cases, perform known-answer tests of both the
105
* encryption and decryption functions
107
while (test_case != NULL) {
109
/* allocate cipher */
110
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
115
* test the encrypt function
117
debug_print(mod_cipher, "testing encryption", NULL);
119
/* initialize cipher */
120
status = cipher_init(c, test_case->key, direction_encrypt);
126
/* copy plaintext into test buffer */
127
if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
129
return err_status_bad_param;
131
for (i=0; i < test_case->plaintext_length_octets; i++)
132
buffer[i] = test_case->plaintext[i];
134
debug_print(mod_cipher, "plaintext: %s",
135
octet_string_hex_string(buffer,
136
test_case->plaintext_length_octets));
138
/* set the initialization vector */
139
status = cipher_set_iv(c, test_case->idx);
146
len = test_case->plaintext_length_octets;
147
status = cipher_encrypt(c, buffer, &len);
153
debug_print(mod_cipher, "ciphertext: %s",
154
octet_string_hex_string(buffer,
155
test_case->ciphertext_length_octets));
157
/* compare the resulting ciphertext with that in the test case */
158
if (len != test_case->ciphertext_length_octets)
159
return err_status_algo_fail;
160
status = err_status_ok;
161
for (i=0; i < test_case->ciphertext_length_octets; i++)
162
if (buffer[i] != test_case->ciphertext[i]) {
163
status = err_status_algo_fail;
164
debug_print(mod_cipher, "test case %d failed", case_num);
165
debug_print(mod_cipher, "(failure at byte %d)", i);
170
debug_print(mod_cipher, "c computed: %s",
171
octet_string_hex_string(buffer,
172
2*test_case->plaintext_length_octets));
173
debug_print(mod_cipher, "c expected: %s",
174
octet_string_hex_string(test_case->ciphertext,
175
2*test_case->plaintext_length_octets));
178
return err_status_algo_fail;
182
* test the decrypt function
184
debug_print(mod_cipher, "testing decryption", NULL);
186
/* re-initialize cipher for decryption */
187
status = cipher_init(c, test_case->key, direction_decrypt);
193
/* copy ciphertext into test buffer */
194
if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
196
return err_status_bad_param;
198
for (i=0; i < test_case->ciphertext_length_octets; i++)
199
buffer[i] = test_case->ciphertext[i];
201
debug_print(mod_cipher, "ciphertext: %s",
202
octet_string_hex_string(buffer,
203
test_case->plaintext_length_octets));
205
/* set the initialization vector */
206
status = cipher_set_iv(c, test_case->idx);
213
len = test_case->ciphertext_length_octets;
214
status = cipher_decrypt(c, buffer, &len);
220
debug_print(mod_cipher, "plaintext: %s",
221
octet_string_hex_string(buffer,
222
test_case->plaintext_length_octets));
224
/* compare the resulting plaintext with that in the test case */
225
if (len != test_case->plaintext_length_octets)
226
return err_status_algo_fail;
227
status = err_status_ok;
228
for (i=0; i < test_case->plaintext_length_octets; i++)
229
if (buffer[i] != test_case->plaintext[i]) {
230
status = err_status_algo_fail;
231
debug_print(mod_cipher, "test case %d failed", case_num);
232
debug_print(mod_cipher, "(failure at byte %d)", i);
236
debug_print(mod_cipher, "p computed: %s",
237
octet_string_hex_string(buffer,
238
2*test_case->plaintext_length_octets));
239
debug_print(mod_cipher, "p expected: %s",
240
octet_string_hex_string(test_case->plaintext,
241
2*test_case->plaintext_length_octets));
244
return err_status_algo_fail;
247
/* deallocate the cipher */
248
status = cipher_dealloc(c);
253
* the cipher passed the test case, so move on to the next test
254
* case in the list; if NULL, we'l proceed to the next test
256
test_case = test_case->next_test_case;
260
/* now run some random invertibility tests */
262
/* allocate cipher, using paramaters from the first test case */
263
test_case = ct->test_data;
264
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
270
for (j=0; j < NUM_RAND_TESTS; j++) {
272
unsigned plaintext_len;
273
uint8_t key[MAX_KEY_LEN];
274
uint8_t iv[MAX_KEY_LEN];
276
/* choose a length at random (leaving room for IV and padding) */
277
length = rand() % (SELF_TEST_BUF_OCTETS - 64);
278
debug_print(mod_cipher, "random plaintext length %d\n", length);
279
status = rand_source_get_octet_string(buffer, length);
280
if (status) return status;
282
debug_print(mod_cipher, "plaintext: %s",
283
octet_string_hex_string(buffer, length));
285
/* copy plaintext into second buffer */
286
for (i=0; (unsigned int)i < length; i++)
287
buffer2[i] = buffer[i];
289
/* choose a key at random */
290
if (test_case->key_length_octets > MAX_KEY_LEN)
291
return err_status_cant_check;
292
status = rand_source_get_octet_string(key, test_case->key_length_octets);
293
if (status) return status;
295
/* chose a random initialization vector */
296
status = rand_source_get_octet_string(iv, MAX_KEY_LEN);
297
if (status) return status;
299
/* initialize cipher */
300
status = cipher_init(c, key, direction_encrypt);
306
/* set initialization vector */
307
status = cipher_set_iv(c, test_case->idx);
313
/* encrypt buffer with cipher */
314
plaintext_len = length;
315
status = cipher_encrypt(c, buffer, &length);
320
debug_print(mod_cipher, "ciphertext: %s",
321
octet_string_hex_string(buffer, length));
324
* re-initialize cipher for decryption, re-set the iv, then
325
* decrypt the ciphertext
327
status = cipher_init(c, key, direction_decrypt);
332
status = cipher_set_iv(c, test_case->idx);
337
status = cipher_decrypt(c, buffer, &length);
343
debug_print(mod_cipher, "plaintext[2]: %s",
344
octet_string_hex_string(buffer, length));
346
/* compare the resulting plaintext with the original one */
347
if (length != plaintext_len)
348
return err_status_algo_fail;
349
status = err_status_ok;
350
for (i=0; i < plaintext_len; i++)
351
if (buffer[i] != buffer2[i]) {
352
status = err_status_algo_fail;
353
debug_print(mod_cipher, "random test case %d failed", case_num);
354
debug_print(mod_cipher, "(failure at byte %d)", i);
358
return err_status_algo_fail;
365
return err_status_ok;
370
* cipher_bits_per_second(c, l, t) computes (an estimate of) the
371
* number of bits that a cipher implementation can encrypt in a second
373
* c is a cipher (which MUST be allocated and initialized already), l
374
* is the length in octets of the test data to be encrypted, and t is
375
* the number of trials
377
* if an error is encountered, the value 0 is returned
381
cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) {
385
unsigned char *enc_buf;
386
unsigned int len = octets_in_buffer;
388
enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer);
390
return 0; /* indicate bad parameters by returning null */
392
/* time repeated trials */
393
v128_set_to_zero(&nonce);
395
for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
396
cipher_set_iv(c, &nonce);
397
cipher_encrypt(c, enc_buf, &len);
399
timer = clock() - timer;
401
crypto_free(enc_buf);
408
return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;