ruby-mcrypt 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Manifest +14 -0
- data/README.rdoc +84 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/ext/.gitignore +8 -0
- data/ext/extconf.rb +46 -0
- data/ext/mcrypt_wrapper.c +588 -0
- data/lib/.gitignore +3 -0
- data/lib/mcrypt.rb +472 -0
- data/ruby-mcrypt.gemspec +147 -0
- data/test/generate/.gitignore +3 -0
- data/test/generate/Makefile +11 -0
- data/test/generate/generate_testcases.c +389 -0
- data/test/helper.rb +13 -0
- data/test/test_basics.rb +216 -0
- data/test/test_brute.rb +3386 -0
- data/test/test_reciprocity.rb +50 -0
- metadata +174 -0
data/ruby-mcrypt.gemspec
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ruby-mcrypt}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Philip Garrett"]
|
12
|
+
s.date = %q{2010-08-23}
|
13
|
+
s.description = %q{= Mcrypt - libmcrypt bindings for Ruby
|
14
|
+
|
15
|
+
Mcrypt provides Ruby-language bindings for libmcrypt(3), a
|
16
|
+
symmetric cryptography library. {Libmcrypt}[http://mcrypt.sourceforge.net/]
|
17
|
+
supports lots of different ciphers and encryption modes.
|
18
|
+
|
19
|
+
== You will need
|
20
|
+
|
21
|
+
* A working Ruby installation (>= 1.8.6 or 1.9)
|
22
|
+
* A working libmcrypt installation (2.5.x or 2.6.x, tested with 2.5.8)
|
23
|
+
* A sane build environment
|
24
|
+
|
25
|
+
== Installation
|
26
|
+
|
27
|
+
Install the gem:
|
28
|
+
gem install ruby-mcrypt --test -- --with-mcrypt-dir=/path/to/mcrypt/prefix
|
29
|
+
|
30
|
+
If you want to run the longer test suite, do this instead:
|
31
|
+
MCRYPT_TEST_BRUTE=1 \
|
32
|
+
gem install ruby-mcrypt --test -- --with-mcrypt-dir=/path/to/mcrypt/prefix
|
33
|
+
|
34
|
+
Put this in your code:
|
35
|
+
require 'rubygems'
|
36
|
+
require 'mcrypt'
|
37
|
+
|
38
|
+
Or in Rails' environment.rb:
|
39
|
+
gem "ruby-mcrypt", :lib => "mcrypt"
|
40
|
+
|
41
|
+
== Usage
|
42
|
+
|
43
|
+
crypto = Mcrypt.new(:twofish, :cbc, MY_KEY, MY_IV, :pkcs)
|
44
|
+
|
45
|
+
# encryption and decryption in one step
|
46
|
+
ciphertext = crypto.encrypt(plaintext)
|
47
|
+
plaintext = crypto.decrypt(ciphertext)
|
48
|
+
|
49
|
+
# encrypt in smaller steps
|
50
|
+
while chunk = $stdin.read(4096)
|
51
|
+
$stdout << crypto.encrypt_more(chunk)
|
52
|
+
end
|
53
|
+
$stdout << crypto.encrypt_finish
|
54
|
+
|
55
|
+
# or decrypt:
|
56
|
+
while chunk = $stdin.read(4096)
|
57
|
+
$stdout << crypto.decrypt_more(chunk)
|
58
|
+
end
|
59
|
+
$stdout << crypto.decrypt_finish
|
60
|
+
|
61
|
+
== Known Issues
|
62
|
+
|
63
|
+
* Test coverage is lacking.
|
64
|
+
|
65
|
+
If you find any bugs, please let the author know.
|
66
|
+
|
67
|
+
== Wish List
|
68
|
+
|
69
|
+
* IO-like behavior, e.g. crypto.open($stdin) { |stream| ... }
|
70
|
+
|
71
|
+
== Author
|
72
|
+
|
73
|
+
* Philip Garrett <philgarr at gmail.com>
|
74
|
+
|
75
|
+
== Copyright and License
|
76
|
+
|
77
|
+
Copyright (c) 2009-2010 Philip Garrett.
|
78
|
+
|
79
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
80
|
+
copy of this software and associated documentation files (the
|
81
|
+
"Software"), to deal in the Software without restriction, including
|
82
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
83
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
84
|
+
permit persons to whom the Software is furnished to do so, subject to
|
85
|
+
the following conditions:
|
86
|
+
|
87
|
+
The above copyright notice and this permission notice shall be included
|
88
|
+
in all copies or substantial portions of the Software.
|
89
|
+
|
90
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
91
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
92
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
93
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
94
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
95
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
96
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
97
|
+
}
|
98
|
+
s.email = %q{philgarr@gmail.com}
|
99
|
+
s.extensions = ["ext/extconf.rb"]
|
100
|
+
s.extra_rdoc_files = [
|
101
|
+
"README.rdoc"
|
102
|
+
]
|
103
|
+
s.files = [
|
104
|
+
".gitignore",
|
105
|
+
"Manifest",
|
106
|
+
"README.rdoc",
|
107
|
+
"Rakefile",
|
108
|
+
"VERSION",
|
109
|
+
"ext/.gitignore",
|
110
|
+
"ext/extconf.rb",
|
111
|
+
"ext/mcrypt_wrapper.c",
|
112
|
+
"lib/.gitignore",
|
113
|
+
"lib/mcrypt.rb",
|
114
|
+
"ruby-mcrypt.gemspec",
|
115
|
+
"test/generate/.gitignore",
|
116
|
+
"test/generate/Makefile",
|
117
|
+
"test/generate/generate_testcases.c",
|
118
|
+
"test/helper.rb",
|
119
|
+
"test/test_basics.rb",
|
120
|
+
"test/test_brute.rb",
|
121
|
+
"test/test_reciprocity.rb"
|
122
|
+
]
|
123
|
+
s.homepage = %q{http://github.com/kingpong/ruby-mcrypt}
|
124
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
125
|
+
s.require_paths = ["lib"]
|
126
|
+
s.required_ruby_version = Gem::Requirement.new(">= 1.8.6")
|
127
|
+
s.requirements = ["libmcrypt (2.5.x or 2.6.x, tested with 2.5.8)"]
|
128
|
+
s.rubygems_version = %q{1.3.7}
|
129
|
+
s.summary = %q{Ruby bindings for libmcrypt}
|
130
|
+
s.test_files = [
|
131
|
+
"test/helper.rb",
|
132
|
+
"test/test_basics.rb",
|
133
|
+
"test/test_brute.rb",
|
134
|
+
"test/test_reciprocity.rb"
|
135
|
+
]
|
136
|
+
|
137
|
+
if s.respond_to? :specification_version then
|
138
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
139
|
+
s.specification_version = 3
|
140
|
+
|
141
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
142
|
+
else
|
143
|
+
end
|
144
|
+
else
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
@@ -0,0 +1,389 @@
|
|
1
|
+
/*
|
2
|
+
* generate_testcases.c
|
3
|
+
*
|
4
|
+
* Generates a list of known-good inputs/outputs to be compared against the
|
5
|
+
* output of ruby-mcrypt.
|
6
|
+
*
|
7
|
+
* Copyright (c) 2009 Philip Garrett.
|
8
|
+
*
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a
|
10
|
+
* copy of this software and associated documentation files (the
|
11
|
+
* "Software"), to deal in the Software without restriction, including
|
12
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
13
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
14
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
15
|
+
* the following conditions:
|
16
|
+
*
|
17
|
+
* The above copyright notice and this permission notice shall be included
|
18
|
+
* in all copies or substantial portions of the Software.
|
19
|
+
*
|
20
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21
|
+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
23
|
+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
24
|
+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
25
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
26
|
+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
|
+
*/
|
28
|
+
|
29
|
+
#include <stdio.h>
|
30
|
+
#include <stdlib.h>
|
31
|
+
#include <string.h>
|
32
|
+
|
33
|
+
#include <mcrypt.h>
|
34
|
+
|
35
|
+
typedef enum { PADDING_NONE, PADDING_PKCS7, PADDING_ZEROS } padding_t;
|
36
|
+
const char *padding_name(padding_t padding);
|
37
|
+
|
38
|
+
unsigned char *gen_rand_data(unsigned int len);
|
39
|
+
char *dump_value(void *buffer, int len);
|
40
|
+
|
41
|
+
void dump_testcase(char *algo, char *mode);
|
42
|
+
void dump_testcase_keysize(MCRYPT td, int key_size);
|
43
|
+
void dump_testcase_block(MCRYPT td, unsigned char *key, int key_size,
|
44
|
+
unsigned char *iv, int iv_size, int block_size,
|
45
|
+
padding_t padding);
|
46
|
+
|
47
|
+
int *list_key_sizes(MCRYPT td);
|
48
|
+
|
49
|
+
static char testing_algo[128];
|
50
|
+
static char testing_mode[128];
|
51
|
+
|
52
|
+
int main() {
|
53
|
+
char **algos, **modes;
|
54
|
+
int n_algos, n_modes,
|
55
|
+
i_algo, i_mode;
|
56
|
+
|
57
|
+
/* get consistent output even though it's "random" */
|
58
|
+
srand48(1153616166L);
|
59
|
+
|
60
|
+
algos = mcrypt_list_algorithms(NULL, &n_algos);
|
61
|
+
if (algos == NULL) {
|
62
|
+
fprintf(stderr, "Unable to list algorithms.\n");
|
63
|
+
exit(1);
|
64
|
+
}
|
65
|
+
|
66
|
+
modes = mcrypt_list_modes(NULL, &n_modes);
|
67
|
+
if (modes == NULL) {
|
68
|
+
fprintf(stderr, "Unable to list modes.\n");
|
69
|
+
exit(1);
|
70
|
+
}
|
71
|
+
|
72
|
+
for (i_algo = 0; i_algo < n_algos; i_algo++) {
|
73
|
+
for (i_mode = 0; i_mode < n_modes; i_mode++) {
|
74
|
+
dump_testcase(algos[i_algo],modes[i_mode]);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
mcrypt_free_p(algos, n_algos);
|
79
|
+
mcrypt_free_p(modes, n_modes);
|
80
|
+
|
81
|
+
return 0;
|
82
|
+
}
|
83
|
+
|
84
|
+
void dump_testcase(char *algo, char *mode) {
|
85
|
+
MCRYPT td;
|
86
|
+
int *key_sizes, *cur_size;
|
87
|
+
|
88
|
+
/* globalize this for easier access below */
|
89
|
+
strcpy(testing_algo, algo);
|
90
|
+
strcpy(testing_mode, mode);
|
91
|
+
|
92
|
+
td = mcrypt_module_open(algo, NULL, mode, NULL);
|
93
|
+
if (td == MCRYPT_FAILED) {
|
94
|
+
/* assume that this algorithm just doesn't support this mode */
|
95
|
+
return;
|
96
|
+
}
|
97
|
+
|
98
|
+
cur_size = key_sizes = list_key_sizes(td);
|
99
|
+
if (key_sizes == NULL) {
|
100
|
+
return;
|
101
|
+
}
|
102
|
+
|
103
|
+
while (*cur_size != 0) {
|
104
|
+
dump_testcase_keysize(td, *cur_size);
|
105
|
+
cur_size++;
|
106
|
+
}
|
107
|
+
free(key_sizes);
|
108
|
+
|
109
|
+
mcrypt_module_close(td);
|
110
|
+
}
|
111
|
+
|
112
|
+
void dump_testcase_keysize(MCRYPT td, int key_size) {
|
113
|
+
unsigned char *key, *iv = NULL;
|
114
|
+
int iv_size, block_size;
|
115
|
+
int mc_ret;
|
116
|
+
padding_t padding;
|
117
|
+
|
118
|
+
key = gen_rand_data(key_size);
|
119
|
+
|
120
|
+
iv_size = mcrypt_enc_get_iv_size(td);
|
121
|
+
if (iv_size != 0) {
|
122
|
+
iv = gen_rand_data(iv_size);
|
123
|
+
}
|
124
|
+
|
125
|
+
/*
|
126
|
+
* Generate a test case for these plaintext sizes:
|
127
|
+
*
|
128
|
+
* * empty: test behavior of padding on empty blocks
|
129
|
+
* * 5-byte: odd, and smaller than any block size
|
130
|
+
* * block_size - 1: edge case
|
131
|
+
* * block_size: generally guaranteed to work
|
132
|
+
* * block_size * 2 - 1: multiblock edge case
|
133
|
+
* * block_size * 3: more multiblock
|
134
|
+
*/
|
135
|
+
block_size = mcrypt_enc_get_block_size(td);
|
136
|
+
|
137
|
+
padding = mcrypt_enc_is_block_mode(td) ? PADDING_PKCS7 : PADDING_NONE;
|
138
|
+
|
139
|
+
for (; padding <= PADDING_ZEROS; padding++) {
|
140
|
+
dump_testcase_block(td, key, key_size, iv, iv_size, 0, padding);
|
141
|
+
dump_testcase_block(td, key, key_size, iv, iv_size, 5, padding);
|
142
|
+
dump_testcase_block(td, key, key_size, iv, iv_size, block_size - 1,
|
143
|
+
padding);
|
144
|
+
dump_testcase_block(td, key, key_size, iv, iv_size, block_size,
|
145
|
+
padding);
|
146
|
+
dump_testcase_block(td, key, key_size, iv, iv_size,
|
147
|
+
block_size * 2 - 1, padding);
|
148
|
+
dump_testcase_block(td, key, key_size, iv, iv_size, block_size * 3,
|
149
|
+
padding);
|
150
|
+
}
|
151
|
+
|
152
|
+
free(key);
|
153
|
+
if (iv) free(iv);
|
154
|
+
|
155
|
+
return;
|
156
|
+
}
|
157
|
+
|
158
|
+
void dump_testcase_block(MCRYPT td, unsigned char *key, int key_size,
|
159
|
+
unsigned char *iv, int iv_size, int data_size,
|
160
|
+
padding_t padding) {
|
161
|
+
int mc_ret;
|
162
|
+
int is_block, block_size, block_overlap, block_fill;
|
163
|
+
int i;
|
164
|
+
unsigned char *plaintext, *ciphertext;
|
165
|
+
|
166
|
+
mc_ret = mcrypt_generic_init(td, (void *)key, key_size, (void *)iv);
|
167
|
+
if (mc_ret < 0) {
|
168
|
+
mcrypt_perror(mc_ret);
|
169
|
+
return;
|
170
|
+
}
|
171
|
+
|
172
|
+
plaintext = gen_rand_data(data_size);
|
173
|
+
if (plaintext == NULL) {
|
174
|
+
return;
|
175
|
+
}
|
176
|
+
|
177
|
+
is_block = mcrypt_enc_is_block_mode(td);
|
178
|
+
if (is_block) {
|
179
|
+
block_size = mcrypt_enc_get_block_size(td);
|
180
|
+
block_overlap = data_size % block_size;
|
181
|
+
block_fill = block_size - block_overlap;
|
182
|
+
if (padding == PADDING_NONE) {
|
183
|
+
/* do nothing */
|
184
|
+
}
|
185
|
+
else if (padding == PADDING_PKCS7) {
|
186
|
+
if (block_fill == 0) {
|
187
|
+
/* ALWAYS add padding */
|
188
|
+
block_fill = block_size;
|
189
|
+
}
|
190
|
+
plaintext = (unsigned char *)realloc(plaintext,
|
191
|
+
data_size + block_fill);
|
192
|
+
for (i = 0; i < block_fill; i++) {
|
193
|
+
plaintext[data_size+i] = block_fill;
|
194
|
+
}
|
195
|
+
data_size = data_size + block_fill;
|
196
|
+
if ((data_size % block_size) != 0) {
|
197
|
+
fprintf(stderr, "bad data size!\n");
|
198
|
+
exit(1);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
else if (padding == PADDING_ZEROS) {
|
202
|
+
if (block_overlap != 0) {
|
203
|
+
plaintext = (unsigned char *)realloc(plaintext,
|
204
|
+
data_size + block_fill);
|
205
|
+
for (i = 0; i < block_fill; i++) {
|
206
|
+
plaintext[data_size+i] = '\0';
|
207
|
+
}
|
208
|
+
data_size = data_size + block_fill;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
else {
|
212
|
+
fprintf(stderr, "bad error\n");
|
213
|
+
exit(1);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
ciphertext = malloc(data_size);
|
218
|
+
if (ciphertext == NULL) {
|
219
|
+
fprintf(stderr, "Out of memory\n");
|
220
|
+
return;
|
221
|
+
}
|
222
|
+
|
223
|
+
memcpy( (void *)ciphertext, (void *)plaintext, data_size);
|
224
|
+
|
225
|
+
mc_ret = mcrypt_generic(td, ciphertext, data_size);
|
226
|
+
if (mc_ret == 0) {
|
227
|
+
char *enc_key, *enc_iv, *enc_pt, *enc_ct;
|
228
|
+
enc_key = dump_value( (void *)key, key_size );
|
229
|
+
enc_iv = dump_value( (void *)iv, iv_size );
|
230
|
+
enc_pt = dump_value( (void *)plaintext, data_size );
|
231
|
+
enc_ct = dump_value( (void *)ciphertext, data_size );
|
232
|
+
|
233
|
+
printf("algo=%s,mode=%s,key=%s,iv=%s,padding=%s,pt=%s,ct=%s\n",
|
234
|
+
testing_algo, testing_mode, enc_key, enc_iv,
|
235
|
+
padding_name(padding), enc_pt, enc_ct);
|
236
|
+
|
237
|
+
free(enc_key);
|
238
|
+
free(enc_iv);
|
239
|
+
free(enc_pt);
|
240
|
+
free(enc_ct);
|
241
|
+
}
|
242
|
+
|
243
|
+
free(plaintext);
|
244
|
+
free(ciphertext);
|
245
|
+
|
246
|
+
mc_ret = mcrypt_generic_deinit(td);
|
247
|
+
if (mc_ret < 0) {
|
248
|
+
fprintf(stderr, "Error %d during deinit of %s in %s mode"
|
249
|
+
" (%d-byte key)\n", mc_ret, testing_algo, testing_mode, key_size);
|
250
|
+
return;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
/*
|
255
|
+
* padding_name(padding)
|
256
|
+
*
|
257
|
+
* Returns the string name for the padding type.
|
258
|
+
*
|
259
|
+
*/
|
260
|
+
|
261
|
+
const char *padding_name(padding_t padding) {
|
262
|
+
switch(padding) {
|
263
|
+
case PADDING_NONE: return "none";
|
264
|
+
case PADDING_PKCS7: return "pkcs";
|
265
|
+
case PADDING_ZEROS: return "zeros";
|
266
|
+
default: fprintf(stderr, "Invalid padding type\n");
|
267
|
+
exit(1);
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
|
272
|
+
/*
|
273
|
+
* list_key_sizes(td)
|
274
|
+
*
|
275
|
+
* Returns a pointer to an array of integer key sizes for the mcrypt
|
276
|
+
* handle. This returns the actual list, as opposed to
|
277
|
+
* mcrypt_enc_get_supported_key_sizes which sometimes just returns a
|
278
|
+
* formula to create the list.
|
279
|
+
*
|
280
|
+
* The list is terminated with a zero.
|
281
|
+
*
|
282
|
+
*/
|
283
|
+
int *list_key_sizes(MCRYPT td) {
|
284
|
+
int *list;
|
285
|
+
int *key_sizes, n_key_sizes, i;
|
286
|
+
|
287
|
+
key_sizes = mcrypt_enc_get_supported_key_sizes(td, &n_key_sizes);
|
288
|
+
|
289
|
+
if (!key_sizes && !n_key_sizes) {
|
290
|
+
int max_size = mcrypt_enc_get_key_size(td);
|
291
|
+
list = malloc( (max_size + 1) * sizeof(int) );
|
292
|
+
if (!list) {
|
293
|
+
fprintf(stderr, "Out of memory\n");
|
294
|
+
return NULL;
|
295
|
+
}
|
296
|
+
|
297
|
+
for (i = 0; i < max_size; i++) {
|
298
|
+
list[i] = i;
|
299
|
+
}
|
300
|
+
list[max_size] = 0;
|
301
|
+
}
|
302
|
+
else {
|
303
|
+
list = malloc( (n_key_sizes + 1) * sizeof(int) );
|
304
|
+
if (!list) {
|
305
|
+
fprintf(stderr, "Out of memory\n");
|
306
|
+
return NULL;
|
307
|
+
}
|
308
|
+
|
309
|
+
for (i = 0; i < n_key_sizes; i++) {
|
310
|
+
list[i] = key_sizes[i];
|
311
|
+
}
|
312
|
+
list[n_key_sizes] = 0;
|
313
|
+
|
314
|
+
free(key_sizes);
|
315
|
+
}
|
316
|
+
|
317
|
+
return list;
|
318
|
+
}
|
319
|
+
|
320
|
+
|
321
|
+
/*
|
322
|
+
* gen_rand_data(len)
|
323
|
+
*
|
324
|
+
* Returns a random key of byte length len. You need to free it when
|
325
|
+
* you're done with it.
|
326
|
+
*
|
327
|
+
* This isn't truly random but it doesn't have to be as it's just
|
328
|
+
* generating test cases.
|
329
|
+
*
|
330
|
+
*/
|
331
|
+
unsigned char *gen_rand_data(unsigned int len) {
|
332
|
+
unsigned char *key, *p;
|
333
|
+
unsigned int i;
|
334
|
+
|
335
|
+
p = key = malloc(len);
|
336
|
+
if (key == NULL) {
|
337
|
+
return NULL;
|
338
|
+
}
|
339
|
+
|
340
|
+
for (i = 0; i < len; i++) {
|
341
|
+
*p++ = (unsigned char)(255L * drand48());
|
342
|
+
}
|
343
|
+
|
344
|
+
return key;
|
345
|
+
}
|
346
|
+
|
347
|
+
|
348
|
+
/*
|
349
|
+
* dump_value(void *buffer, int len)
|
350
|
+
*
|
351
|
+
* Returns a string containing the buffer's contents encoded as
|
352
|
+
* two-character hexadecimal bytes separated by spaces.
|
353
|
+
*
|
354
|
+
* Free it when you're done.
|
355
|
+
*
|
356
|
+
*/
|
357
|
+
|
358
|
+
char *dump_value(void *buffer, int len) {
|
359
|
+
char *enc, *p;
|
360
|
+
unsigned char *buf;
|
361
|
+
int i;
|
362
|
+
const char hex_digits[] = { '0','1','2','3','4','5','6','7','8','9',
|
363
|
+
'a','b','c','d','e','f' };
|
364
|
+
|
365
|
+
buf = (unsigned char *)buffer;
|
366
|
+
|
367
|
+
if (len == 0) {
|
368
|
+
return strdup("");
|
369
|
+
}
|
370
|
+
|
371
|
+
p = enc = malloc(len * 3);
|
372
|
+
if (enc == NULL) {
|
373
|
+
return NULL;
|
374
|
+
}
|
375
|
+
|
376
|
+
*p = '\0';
|
377
|
+
|
378
|
+
for(i = 0; i < len; i++) {
|
379
|
+
if (i != 0) {
|
380
|
+
(*p++) = ' ';
|
381
|
+
}
|
382
|
+
(*p++) = hex_digits[buf[i] >> 4];
|
383
|
+
(*p++) = hex_digits[buf[i] & 0xF];
|
384
|
+
}
|
385
|
+
(*p++) = '\0';
|
386
|
+
|
387
|
+
return enc;
|
388
|
+
}
|
389
|
+
|