camellia-rb 1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ == 1.0 2008-07-18
2
+ the first edition
3
+
4
+ == 1.1 2008-09-09
5
+ Changes from version 1.0
6
+
7
+ * 'the object generation method' and 'the setting method of the encrypting key'
8
+ Camellia.new
9
+ Camellia#set_key('key')
10
+ -> Camellia.new('key')
11
+
12
+ * 'CamelliaError#errno' and 'CamelliaError#error' is deleted
13
+
14
+ * 'CamelliaError' is changed to 'Error'
15
+
16
+ * the directory name of extended library is changed to 'ext'
17
+
18
+ * unused file/directory is deleted from the package
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008
2
+ NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions
6
+ are met:
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer as
9
+ the first lines of this file unmodified.
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
15
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
+ IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
18
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
@@ -0,0 +1,29 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ config/hoe.rb
7
+ config/requirements.rb
8
+ ext/camellia.c
9
+ ext/camellia.c
10
+ ext/camellia.h
11
+ ext/camellia-rb.c
12
+ ext/extconf.rb
13
+ ext/camellia-example.rb
14
+ lib/camellia/version.rb
15
+ script/destroy
16
+ script/destroy.cmd
17
+ script/generate
18
+ script/generate.cmd
19
+ script/txt2html
20
+ script/txt2html.cmd
21
+ setup.rb
22
+ tasks/deployment.rake
23
+ tasks/environment.rake
24
+ tasks/website.rake
25
+ website/index.html
26
+ website/index.txt
27
+ website/javascripts/rounded_corners_lite.inc.js
28
+ website/stylesheets/screen.css
29
+ website/template.rhtml
@@ -0,0 +1,82 @@
1
+ ############################################################
2
+
3
+ camellia_rb
4
+
5
+ ############################################################
6
+
7
+ About Camellia
8
+
9
+ Camellia is a symmetric key block cipher developed jointly in 2000 by world top class encryption
10
+ researchers at NTT and Mitsubishi Electric Corporation. Technologically speaking, Camellia naturally
11
+ has not only a high level of security, but also excellent efficiency and practical characteristics.
12
+ It can be implemented at high performance by software on various platforms. In regard to hardware
13
+ implementation, compact, and low-power consumption type implementation as well as high-speed
14
+ implementation is possible.
15
+
16
+ Based on these technological advantages, Camellia has been internationally recognized,
17
+ for example the selection project on the European recommendation of strong cryptographic primitives,
18
+ NESSIE, evaluated Camellia to have "many similarities to the AES, so much of the analysis for the AES
19
+ is also applicable to Camellia." Currently, Camellia is the only cipher internationally recognized
20
+ which has the same level of security and performance as AES, and is selected for many international
21
+ standard/recommended ciphers. In particular, as Japanese domestic ciphers, this is the first case
22
+ to be approved as IETF standard ciphers (Proposed Standard RFC) .
23
+
24
+ Camellia Website : http://info.isl.ntt.co.jp/crypt/eng/camellia/index.html
25
+
26
+
27
+ About camellia_rb
28
+
29
+ camellia_rb is a Camellia package for Ruby. Camellia engine is implemented in "C".
30
+ Camellia implimentation is imported from
31
+ http://info.isl.ntt.co.jp/crypt/camellia/dl/camellia-BSD-1.2.0.tar.gz
32
+
33
+ Supported key length : 128bit/192bit/256bit
34
+ Supported modes of operation : ECB/CFB/CBC
35
+ license : see License.txt
36
+
37
+
38
+ How to install
39
+
40
+ % ruby extconf.rb
41
+ % make
42
+ % make install
43
+
44
+
45
+ How to use
46
+
47
+ Interfaces
48
+
49
+ Camellia.new('key')
50
+
51
+ #ECB
52
+ Camellia#encrypt('plain text 16byte')
53
+ Camellia#decrypt('cipher text 16byte')
54
+
55
+ #CFB
56
+ Camellia#cfb_salt('salt 16byte')
57
+ Camellia#cfb_encrypt('plain text')
58
+ Camellia#cfb_decrypt('cipher text')
59
+
60
+ #CBC
61
+ Camellia#cbc_salt('salt 16byte')
62
+ Camellia#cbc_pchar('padding character')
63
+ Camellia#cbc_encrypt('plain text')
64
+ Camellia#cbc_decryp('cipher text')
65
+
66
+
67
+ Sample program(camellia-example.rb)
68
+
69
+ # ruby camellia-example.rb
70
+
71
+ deadbeefdeadbeef
72
+ now is the time for all good men to come to the aid of thei.chr country.
73
+ now is the time for all good men to come to the aid of thei.chr country.
74
+
75
+
76
+
77
+ ############################################################
78
+
79
+ * Copyright (c) 2008
80
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
81
+
82
+ ############################################################
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -0,0 +1,75 @@
1
+ require 'camellia/version'
2
+
3
+ AUTHOR = 'FIXME full name' # can also be an array of Authors
4
+ EMAIL = "FIXME email"
5
+ DESCRIPTION = "description of gem"
6
+ GEM_NAME = 'camellia-rb' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'camellia-rb' # The unix name for your project
8
+ #HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ HOMEPATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
11
+
12
+ @config_file = "~/.rubyforge/user-config.yml"
13
+ @config = nil
14
+ RUBYFORGE_USERNAME = "unknown"
15
+ def rubyforge_username
16
+ unless @config
17
+ begin
18
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
19
+ rescue
20
+ puts <<-EOS
21
+ ERROR: No rubyforge config file found: #{@config_file}
22
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
23
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
24
+ EOS
25
+ exit
26
+ end
27
+ end
28
+ RUBYFORGE_USERNAME.replace @config["username"]
29
+ end
30
+
31
+
32
+ REV = nil
33
+ # UNCOMMENT IF REQUIRED:
34
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
35
+ VERS = Camellia::VERSION::STRING + (REV ? ".#{REV}" : "")
36
+ #RDOC_OPTS = ['--quiet', '--title', 'camellia documentation',
37
+ RDOC_OPTS = ['--title', 'camellia documentation',
38
+ "--opname", "index.html",
39
+ "--line-numbers",
40
+ "--main", "README",
41
+ "--inline-source"]
42
+
43
+ class Hoe
44
+ def extra_deps
45
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
46
+ @extra_deps
47
+ end
48
+ end
49
+
50
+ # Generate all the Rake tasks
51
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
52
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
53
+ p.developer(AUTHOR, EMAIL)
54
+ p.description = DESCRIPTION
55
+ p.summary = DESCRIPTION
56
+ p.url = HOMEPATH
57
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
58
+ p.test_globs = ["test/**/test_*.rb"]
59
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
60
+
61
+ # == Optional
62
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
63
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
64
+
65
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
66
+
67
+ p.spec_extras = {
68
+ :extensions => ['ext/extconf.rb'],
69
+ }
70
+ end
71
+
72
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
73
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
74
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
75
+ hoe.rsync_args = '-av --delete --ignore-errors'
@@ -0,0 +1,17 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
16
+
17
+ require 'camellia_rb'
@@ -0,0 +1,44 @@
1
+ #* camellia-example.rb
2
+ #*
3
+ #* Copyright (c) 2008
4
+ #* NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
5
+ #*
6
+ #* Redistribution and use in source and binary forms, with or without
7
+ #* modification, are permitted provided that the following conditions
8
+ #* are met:
9
+ #* 1. Redistributions of source code must retain the above copyright
10
+ #* notice, this list of conditions and the following disclaimer as
11
+ #* the first lines of this file unmodified.
12
+ #* 2. Redistributions in binary form must reproduce the above copyright
13
+ #* notice, this list of conditions and the following disclaimer in the
14
+ #* documentation and/or other materials provided with the distribution.
15
+ #*
16
+ #* THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
17
+ #* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ #* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
+ #* IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ #* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
+ #* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ #* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
+ #* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ #* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
+ #* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ #*
27
+ require "camellia"
28
+
29
+ #ECB
30
+ a=Camellia.new('deadbeefdeadbeefdeadbeefdeadbeef')
31
+ b=a.encrypt("deadbeefdeadbeef")
32
+ print a.decrypt(b),"\n" # should print deadbeefdeadbeef
33
+
34
+ #CFB
35
+ a.cfb_salt('128bitbinaryvalu') # must be a 128-bit BINARY value
36
+ b=a.cfb_encrypt("now is the time for all good men to come to the aid of thei.chr country.\n")
37
+ a.cfb_salt('128bitbinaryvalu') # must be a 128-bit BINARY value
38
+ print a.cfb_decrypt(b)
39
+
40
+ #CBC
41
+ a.cbc_salt('128bitbinaryvalu') # must be a 128-bit BINARY value
42
+ b=a.cbc_encrypt("now is the time for all good men to come to the aid of thei.chr country.\n")
43
+ a.cbc_salt('128bitbinaryvalu') # must be a 128-bit BINARY value
44
+ print a.cbc_decrypt(b)
@@ -0,0 +1,546 @@
1
+ /* camellia-rb.c
2
+ *
3
+ * Copyright (c) 2008
4
+ * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer as
11
+ * the first lines of this file unmodified.
12
+ * 2. Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in the
14
+ * documentation and/or other materials provided with the distribution.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
17
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
+ * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+ #include <ruby.h>
28
+ #include "camellia.h"
29
+ #include <stdio.h>
30
+
31
+ typedef unsigned char u1byte;
32
+
33
+ // error class
34
+ static VALUE eCamellia;
35
+
36
+ // camellia object
37
+ typedef struct {
38
+ int key_len; // key lengh
39
+ KEY_TABLE_TYPE key; // sub keys
40
+ int key_gen; // key initialized flag
41
+ u1byte cfb_blk[16]; // buffer for CFB
42
+ u1byte cfb_crypt[16]; // buffer for CFB
43
+ int cfb128_idx; // index for buffer of CFB
44
+ u1byte cbc_blk[16]; // buffer for CBC
45
+ u1byte cbc_crypt[16]; // buffer for CBC
46
+ int cbc128_idx; // index for buffer of CBC
47
+ u1byte cbc_pchar; // padding char(default:0x05)
48
+ } camelliaObject;
49
+
50
+ /*
51
+ # return a new camellia object
52
+ */
53
+ static VALUE s_new(VALUE self)
54
+ {
55
+ camelliaObject *camellia;
56
+ VALUE camellia_data;
57
+
58
+ camellia = ALLOC(camelliaObject);
59
+ camellia->key_gen = 0; // key is not initialized
60
+ camellia->cfb128_idx = -2; // CFB index is initialized
61
+ camellia->cbc128_idx = -2; // CBC index is initialized
62
+ camellia->cbc_pchar = 0x05;
63
+ camellia->key_gen = 0;
64
+
65
+ camellia_data = Data_Wrap_Struct(self, 0, free, camellia);
66
+
67
+ //rb_obj_call_init(camellia_data, 0, NULL);
68
+ return camellia_data;
69
+ }
70
+
71
+ /*
72
+ # set_key method
73
+ */
74
+ static VALUE set_key(VALUE self, VALUE key)
75
+ {
76
+ unsigned char *skey;
77
+ int skey_len;
78
+ camelliaObject *camellia;
79
+
80
+ Data_Get_Struct(self, camelliaObject, camellia);
81
+
82
+ Check_Type(key, T_STRING);
83
+ skey_len = RSTRING(key)->len;
84
+ skey = (unsigned char *)RSTRING(key)->ptr;
85
+
86
+ // check key length
87
+ if (skey_len != 16 && skey_len != 24 && skey_len != 32)
88
+ {
89
+ rb_raise(rb_eArgError, "wrong key length (must be 16, 24, or 32 bytes,not %d)", skey_len);
90
+ return self;
91
+ }
92
+
93
+ // key generation
94
+ camellia->key_len = skey_len*8;
95
+ Camellia_Ekeygen(camellia->key_len, skey, camellia->key);
96
+ camellia->key_gen = 1; //key is initialized
97
+
98
+ //return self;
99
+ return Qnil;
100
+ }
101
+
102
+ /*
103
+ # encryption method
104
+ */
105
+ static VALUE encrypt(VALUE self, VALUE args)
106
+ {
107
+ camelliaObject *camellia;
108
+ unsigned char *data;
109
+ int data_len;
110
+ u1byte out_blk[16];
111
+
112
+ Check_Type(args, T_STRING);
113
+ data_len = RSTRING(args)->len;
114
+ data = (unsigned char *)RSTRING(args)->ptr;
115
+
116
+ Data_Get_Struct(self, camelliaObject, camellia);
117
+
118
+ // check data length
119
+ if (data_len != 16)
120
+ {
121
+ rb_raise(rb_eArgError, "wrong data length (must be 16 bytes, found %d bytes)", data_len);
122
+ return self;
123
+ }
124
+
125
+ // check if key is initialized
126
+ if (!camellia->key_gen)
127
+ {
128
+ rb_raise(eCamellia,"must set up a key before you can encrypt!");
129
+ return self;
130
+ }
131
+
132
+ // encryption
133
+ Camellia_EncryptBlock(camellia->key_len, data, camellia->key, out_blk);
134
+
135
+ return rb_str_new((char *)out_blk, 16);
136
+ }
137
+
138
+ /*
139
+ # decryption method
140
+ */
141
+ static VALUE decrypt(VALUE self,VALUE args)
142
+ {
143
+ camelliaObject *camellia;
144
+ unsigned char *data;
145
+ int data_len;
146
+ u1byte out_blk[16];
147
+
148
+ Check_Type(args, T_STRING);
149
+ data_len = RSTRING(args)->len;
150
+ data = (unsigned char *)RSTRING(args)->ptr;
151
+
152
+ // check data length
153
+ if (data_len != 16)
154
+ {
155
+ rb_raise(rb_eArgError, "wrong data length (must be 16 bytes, found %d bytes)", data_len);
156
+ return 0;
157
+ }
158
+
159
+ Data_Get_Struct(self, camelliaObject, camellia);
160
+
161
+ // check if key is initialized
162
+ if (!camellia->key_gen)
163
+ {
164
+ rb_raise(eCamellia,"must set up a key before you can decrypt!");
165
+ return 0;
166
+ }
167
+
168
+ // decryption
169
+ Camellia_DecryptBlock(camellia->key_len, data, camellia->key, out_blk);
170
+
171
+ return rb_str_new((char *)out_blk,16);
172
+ }
173
+
174
+ /*
175
+ # CFB IV set method
176
+ */
177
+ static VALUE cfb_salt(VALUE self, VALUE args)
178
+ {
179
+ camelliaObject *camellia;
180
+ unsigned char *src;
181
+ unsigned char *dest;
182
+ int src_len;
183
+ int i;
184
+
185
+ Check_Type(args,T_STRING);
186
+ src = (unsigned char *)RSTRING(args)->ptr;
187
+ src_len = RSTRING(args)->len;
188
+
189
+ // check IV length
190
+ if (src_len != 16)
191
+ {
192
+ rb_raise(rb_eArgError, "wrong data length (must be 16 bytes, found %d bytes)", src_len);
193
+ return self;
194
+ }
195
+
196
+ Data_Get_Struct(self, camelliaObject, camellia);
197
+
198
+ // CFB initial set
199
+ camellia->cfb128_idx = -1;
200
+ dest = camellia->cfb_blk;
201
+ for (i = 0; i < 16; i++)
202
+ {
203
+ *dest++ = *src++;
204
+ }
205
+
206
+ return self;
207
+ }
208
+
209
+ /*
210
+ # CFB encryption method
211
+ */
212
+ static VALUE cfb_encrypt(VALUE self,VALUE args)
213
+ {
214
+ camelliaObject *camellia;
215
+ unsigned char *src;
216
+ unsigned char *destdata;
217
+ int srclen;
218
+ int i,ch;
219
+ VALUE retvalue;
220
+
221
+ Check_Type(args,T_STRING);
222
+ src = (unsigned char *)RSTRING(args)->ptr;
223
+ srclen = RSTRING(args)->len;
224
+
225
+ Data_Get_Struct(self,camelliaObject,camellia);
226
+
227
+ // check if key is initialized
228
+ if (!camellia->key_gen)
229
+ {
230
+ rb_raise(eCamellia,"must set up a key before you can cfb_encrypt!");
231
+ return self;
232
+ }
233
+
234
+ // check if IV is initialized
235
+ if (camellia->cfb128_idx != -1)
236
+ {
237
+ rb_raise(eCamellia,"must set up a salt before you can cfb_encrypt!");
238
+ return self;
239
+ }
240
+
241
+ destdata = (unsigned char *)malloc(srclen);
242
+
243
+ // CFB encryption
244
+ for (i = 0; i < srclen; i++)
245
+ {
246
+ if ((camellia->cfb128_idx < 0) || (camellia->cfb128_idx > 15))
247
+ {
248
+ Camellia_EncryptBlock(camellia->key_len, camellia->cfb_blk, camellia->key, camellia->cfb_crypt);
249
+ camellia->cfb128_idx=0;
250
+ }
251
+ ch = src[i] ^ camellia->cfb_crypt[camellia->cfb128_idx];
252
+ camellia->cfb_blk[camellia->cfb128_idx++] = ch;
253
+ destdata[i] = (unsigned char)ch;
254
+ }
255
+
256
+ retvalue = rb_str_new((char *)destdata, srclen);
257
+ free(destdata);
258
+ return retvalue;
259
+ }
260
+
261
+ /*
262
+ # CFB decryption method
263
+ */
264
+ static VALUE cfb_decrypt(VALUE *self, VALUE args)
265
+ {
266
+ camelliaObject *camellia;
267
+ unsigned char *src;
268
+ unsigned char *destdata;
269
+ int srclen;
270
+ int i;
271
+ unsigned char ch;
272
+ VALUE retvalue;
273
+
274
+ Check_Type(args, T_STRING);
275
+ srclen = RSTRING(args)->len;
276
+ src = (unsigned char *)RSTRING(args)->ptr;
277
+
278
+ Data_Get_Struct(self,camelliaObject, camellia);
279
+
280
+ // check if key is initialized
281
+ if (!camellia->key_gen)
282
+ {
283
+ rb_raise(eCamellia,"must set up a key before you can cfb_decrypt!");
284
+ return 0;
285
+ }
286
+
287
+ // check if IV is initialized
288
+ if (camellia->cfb128_idx != -1)
289
+ {
290
+ rb_raise(eCamellia,"must set up a salt before you can cfb_decrypt!");
291
+ return 0;
292
+ }
293
+
294
+ destdata = (unsigned char *)malloc(srclen);
295
+
296
+ // CFB decryption
297
+ for (i = 0; i < srclen; i++)
298
+ {
299
+ if (camellia->cfb128_idx < 0 || camellia->cfb128_idx > 15)
300
+ {
301
+ Camellia_EncryptBlock(camellia->key_len, camellia->cfb_blk, camellia->key, camellia->cfb_crypt);
302
+ camellia->cfb128_idx=0;
303
+ }
304
+ ch = src[i];
305
+ destdata[i] = ch ^ camellia->cfb_crypt[camellia->cfb128_idx];
306
+ camellia->cfb_blk[camellia->cfb128_idx++] = ch;
307
+ }
308
+
309
+ retvalue=rb_str_new((char *)destdata, srclen);
310
+ free(destdata);
311
+ return retvalue;
312
+ }
313
+
314
+ /*
315
+ # CBC IV set
316
+ */
317
+ static VALUE cbc_salt(VALUE self, VALUE args)
318
+ {
319
+ camelliaObject *camellia;
320
+ unsigned char *src;
321
+ unsigned char *dest, *dest2;
322
+ int src_len;
323
+ int i;
324
+
325
+ Check_Type(args,T_STRING);
326
+ src = (unsigned char *)RSTRING(args)->ptr;
327
+ src_len = RSTRING(args)->len;
328
+
329
+ // check IV length
330
+ if (src_len != 16)
331
+ {
332
+ rb_raise(rb_eArgError, "wrong data length (must be 16 bytes, found %d bytes)", src_len);
333
+ return self;
334
+ }
335
+
336
+ Data_Get_Struct(self, camelliaObject, camellia);
337
+
338
+ // CBC initial set
339
+ camellia->cbc128_idx = -1;
340
+ dest = camellia->cbc_blk;
341
+ dest2 = camellia->cbc_crypt;
342
+ for (i = 0; i < 16; i++)
343
+ {
344
+ *dest++ = *src;
345
+ *dest2++ = *src++;
346
+ }
347
+
348
+ return self;
349
+ }
350
+
351
+ /*
352
+ # CBC padding charactor set
353
+ */
354
+ static VALUE cbc_pchar(VALUE self, VALUE args)
355
+ {
356
+ camelliaObject *camellia;
357
+ unsigned char *src;
358
+ int src_len;
359
+
360
+ Check_Type(args,T_STRING);
361
+ src = (unsigned char *)RSTRING(args)->ptr;
362
+ src_len = RSTRING(args)->len;
363
+
364
+ // check pcharlength
365
+ if (src_len != 1)
366
+ {
367
+ rb_raise(rb_eArgError, "wrong padding data length (must be 1 bytes, found %d bytes)", src_len);
368
+ return self;
369
+ }
370
+
371
+ Data_Get_Struct(self, camelliaObject, camellia);
372
+
373
+ // pchar set
374
+ camellia->cbc_pchar = *src;
375
+
376
+ return self;
377
+ }
378
+
379
+ /*
380
+ # CBC encryption method
381
+ */
382
+ static VALUE cbc_encrypt(VALUE self,VALUE args)
383
+ {
384
+ camelliaObject *camellia;
385
+ unsigned char *src;
386
+ unsigned char *destdata;
387
+ int srclen;
388
+ int i, j, ch, destidx;
389
+ VALUE retvalue;
390
+
391
+ Check_Type(args,T_STRING);
392
+ src = (unsigned char *)RSTRING(args)->ptr;
393
+ srclen = RSTRING(args)->len;
394
+
395
+ Data_Get_Struct(self,camelliaObject,camellia);
396
+
397
+ // check if key is initialized
398
+ if (!camellia->key_gen)
399
+ {
400
+ rb_raise(eCamellia,"must set up a key before you can cbc_encrypt!");
401
+ return self;
402
+ }
403
+
404
+ // check if IV is initialized
405
+ if (camellia->cbc128_idx != -1)
406
+ {
407
+ rb_raise(eCamellia,"must set up a salt before you can cbc_encrypt!");
408
+ return self;
409
+ }
410
+
411
+ if (srclen % 16 == 0)
412
+ destdata = (unsigned char *)malloc(srclen);
413
+ else
414
+ destdata = (unsigned char *)malloc((srclen/16+1)*16);
415
+
416
+ // CBC encryption
417
+ destidx = 0;
418
+ camellia->cbc128_idx = 0;
419
+ for (i = 0; i < srclen; i++)
420
+ {
421
+ ch = src[i] ^ camellia->cbc_crypt[camellia->cbc128_idx];
422
+ camellia->cbc_blk[camellia->cbc128_idx++] = ch;
423
+
424
+ if (camellia->cbc128_idx == 16)
425
+ {
426
+ Camellia_EncryptBlock(camellia->key_len, camellia->cbc_blk, camellia->key, camellia->cbc_crypt);
427
+ camellia->cbc128_idx=0;
428
+ for (j = 0; j < 16; j++)
429
+ {
430
+ destdata[destidx++] = camellia->cbc_crypt[j];
431
+ }
432
+ }
433
+ }
434
+ if (srclen % 16 != 0)
435
+ {
436
+ while (camellia->cbc128_idx < 16)
437
+ {
438
+ camellia->cbc_blk[camellia->cbc128_idx] = camellia->cbc_pchar ^ camellia->cbc_crypt[camellia->cbc128_idx++];
439
+ }
440
+
441
+ Camellia_EncryptBlock(camellia->key_len, camellia->cbc_blk, camellia->key, camellia->cbc_crypt);
442
+ for (j = 0; j < 16; j++)
443
+ {
444
+ destdata[destidx++] = camellia->cbc_crypt[j];
445
+ }
446
+ }
447
+
448
+ if (srclen % 16 == 0)
449
+ retvalue = rb_str_new((char *)destdata, srclen);
450
+ else
451
+ retvalue = rb_str_new((char *)destdata, (srclen/16+1)*16);
452
+ free(destdata);
453
+ return retvalue;
454
+ }
455
+
456
+ /*
457
+ # CBC decryption method
458
+ */
459
+ static VALUE cbc_decrypt(VALUE *self, VALUE args)
460
+ {
461
+ camelliaObject *camellia;
462
+ unsigned char *src;
463
+ unsigned char *destdata;
464
+ int srclen;
465
+ int i, j, destidx;
466
+ u1byte tmp[16];
467
+ VALUE retvalue;
468
+
469
+ Check_Type(args, T_STRING);
470
+ srclen = RSTRING(args)->len;
471
+ src = (unsigned char *)RSTRING(args)->ptr;
472
+
473
+ Data_Get_Struct(self,camelliaObject, camellia);
474
+
475
+ // check if key is initialized
476
+ if (!camellia->key_gen)
477
+ {
478
+ rb_raise(eCamellia,"must set up a key before you can cbc_decrypt!");
479
+ return 0;
480
+ }
481
+
482
+ // check if IV is initialized
483
+ if (camellia->cbc128_idx != -1)
484
+ {
485
+ rb_raise(eCamellia,"must set up a salt before you can cbc_decrypt!");
486
+ return 0;
487
+ }
488
+
489
+ destdata = (unsigned char *)malloc(srclen);
490
+
491
+ // CBC decryption
492
+ destidx = 0;
493
+ camellia->cbc128_idx = 0;
494
+ for (i = 0; i < srclen; i++)
495
+ {
496
+ tmp[camellia->cbc128_idx] = camellia->cbc_blk[camellia->cbc128_idx];
497
+ camellia->cbc_blk[camellia->cbc128_idx++] = src[i];
498
+
499
+ if (camellia->cbc128_idx == 16)
500
+ {
501
+ Camellia_DecryptBlock(camellia->key_len, camellia->cbc_blk, camellia->key, camellia->cbc_crypt);
502
+ camellia->cbc128_idx=0;
503
+
504
+ for (j = 0; j < 16; j++)
505
+ {
506
+ destdata[destidx++] = camellia->cbc_crypt[j] ^ tmp[j];
507
+ }
508
+ }
509
+ }
510
+
511
+ // remove paddingchar
512
+ while (destdata[srclen-1] == camellia->cbc_pchar)
513
+ {
514
+ srclen--;
515
+ }
516
+
517
+ retvalue=rb_str_new((char *)destdata, srclen);
518
+ free(destdata);
519
+ return retvalue;
520
+ }
521
+
522
+ //
523
+ void Init_camellia()
524
+ {
525
+ VALUE cCamellia = rb_define_class("Camellia", rb_cObject);
526
+ rb_define_alloc_func(cCamellia, s_new);
527
+
528
+ //rb_define_singleton_method(cCamellia, "new", s_new, 0);
529
+ rb_define_private_method(cCamellia, "initialize", set_key, 1);
530
+ //rb_define_method(cCamellia, "set_key", set_key, 1);
531
+ rb_define_method(cCamellia, "encrypt", encrypt, 1);
532
+ rb_define_method(cCamellia, "decrypt", decrypt, 1);
533
+ rb_define_method(cCamellia, "cfb_salt", cfb_salt, 1);
534
+ rb_define_method(cCamellia, "cfb_encrypt", cfb_encrypt, 1);
535
+ rb_define_method(cCamellia, "cfb_decrypt", cfb_decrypt, 1);
536
+ rb_define_method(cCamellia, "cbc_salt", cbc_salt, 1);
537
+ rb_define_method(cCamellia, "cbc_pchar", cbc_pchar, 1);
538
+ rb_define_method(cCamellia, "cbc_encrypt", cbc_encrypt, 1);
539
+ rb_define_method(cCamellia, "cbc_decrypt", cbc_decrypt, 1);
540
+
541
+ eCamellia = rb_define_class("Error", rb_eStandardError);
542
+ //rb_define_method(eCamellia, "error", error_error, 0);
543
+ //rb_define_method(eCamellia, "errno", error_errno, 0);
544
+
545
+ rb_define_const(eCamellia, "WRONG_KEY_LENGTH", INT2NUM(1));
546
+ }