cryptopp 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. data/.gitignore +8 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README +7 -0
  4. data/Rakefile +42 -0
  5. data/cryptopp.gemspec +199 -0
  6. data/ext/.gitignore +5 -0
  7. data/ext/Rakefile +16 -0
  8. data/ext/ciphers.cpp +1402 -0
  9. data/ext/cryptopp.cpp +285 -0
  10. data/ext/cryptopp_ruby_api.h +139 -0
  11. data/ext/defs/block_modes.def +10 -0
  12. data/ext/defs/checksums.def +10 -0
  13. data/ext/defs/ciphers.def +136 -0
  14. data/ext/defs/hashes.def +78 -0
  15. data/ext/defs/hmacs.def +54 -0
  16. data/ext/defs/paddings.def +9 -0
  17. data/ext/defs/rngs.def +7 -0
  18. data/ext/digests.cpp +1120 -0
  19. data/ext/extconf.rb +39 -0
  20. data/ext/j3way.cpp +22 -0
  21. data/ext/j3way.h +29 -0
  22. data/ext/jadler32.h +32 -0
  23. data/ext/jaes.cpp +22 -0
  24. data/ext/jaes.h +31 -0
  25. data/ext/jarc4.cpp +22 -0
  26. data/ext/jarc4.h +37 -0
  27. data/ext/jbase.cpp +172 -0
  28. data/ext/jbase.h +92 -0
  29. data/ext/jbasiccipherinfo.h +74 -0
  30. data/ext/jblowfish.cpp +22 -0
  31. data/ext/jblowfish.h +29 -0
  32. data/ext/jcamellia.cpp +24 -0
  33. data/ext/jcamellia.h +33 -0
  34. data/ext/jcast128.cpp +22 -0
  35. data/ext/jcast128.h +31 -0
  36. data/ext/jcast256.cpp +22 -0
  37. data/ext/jcast256.h +31 -0
  38. data/ext/jcipher.cpp +112 -0
  39. data/ext/jcipher.h +42 -0
  40. data/ext/jcipher_t.h +469 -0
  41. data/ext/jconfig.h +127 -0
  42. data/ext/jconstants.h +189 -0
  43. data/ext/jcrc32.h +32 -0
  44. data/ext/jdes.cpp +22 -0
  45. data/ext/jdes.h +31 -0
  46. data/ext/jdes_ede2.cpp +22 -0
  47. data/ext/jdes_ede2.h +31 -0
  48. data/ext/jdes_ede3.cpp +22 -0
  49. data/ext/jdes_ede3.h +31 -0
  50. data/ext/jdes_xex3.cpp +22 -0
  51. data/ext/jdes_xex3.h +31 -0
  52. data/ext/jdiamond2.cpp +22 -0
  53. data/ext/jdiamond2.h +31 -0
  54. data/ext/jdiamond2lite.cpp +22 -0
  55. data/ext/jdiamond2lite.h +31 -0
  56. data/ext/jexception.h +20 -0
  57. data/ext/jgost.cpp +22 -0
  58. data/ext/jgost.h +31 -0
  59. data/ext/jhash.cpp +92 -0
  60. data/ext/jhash.h +54 -0
  61. data/ext/jhash_t.h +121 -0
  62. data/ext/jhaval.h +64 -0
  63. data/ext/jhelpers.cpp +90 -0
  64. data/ext/jhelpers.h +38 -0
  65. data/ext/jhmac.cpp +44 -0
  66. data/ext/jhmac.h +34 -0
  67. data/ext/jhmac_t.h +125 -0
  68. data/ext/jidea.cpp +22 -0
  69. data/ext/jidea.h +31 -0
  70. data/ext/jmarc4.cpp +22 -0
  71. data/ext/jmarc4.h +37 -0
  72. data/ext/jmars.cpp +22 -0
  73. data/ext/jmars.h +31 -0
  74. data/ext/jmd2.h +56 -0
  75. data/ext/jmd4.h +56 -0
  76. data/ext/jmd5.h +56 -0
  77. data/ext/jpanamacipher.cpp +32 -0
  78. data/ext/jpanamacipher.h +46 -0
  79. data/ext/jpanamahash.h +44 -0
  80. data/ext/jrc2.cpp +44 -0
  81. data/ext/jrc2.h +39 -0
  82. data/ext/jrc5.cpp +22 -0
  83. data/ext/jrc5.h +31 -0
  84. data/ext/jrc6.cpp +22 -0
  85. data/ext/jrc6.h +31 -0
  86. data/ext/jripemd160.h +113 -0
  87. data/ext/jsafer.cpp +32 -0
  88. data/ext/jsafer.h +42 -0
  89. data/ext/jseal.cpp +32 -0
  90. data/ext/jseal.h +42 -0
  91. data/ext/jserpent.cpp +22 -0
  92. data/ext/jserpent.h +31 -0
  93. data/ext/jsha.h +122 -0
  94. data/ext/jshacal2.cpp +22 -0
  95. data/ext/jshacal2.h +31 -0
  96. data/ext/jshark.cpp +24 -0
  97. data/ext/jshark.h +33 -0
  98. data/ext/jsink.cpp +90 -0
  99. data/ext/jsink.h +154 -0
  100. data/ext/jskipjack.cpp +22 -0
  101. data/ext/jskipjack.h +31 -0
  102. data/ext/jsquare.cpp +22 -0
  103. data/ext/jsquare.h +31 -0
  104. data/ext/jstream.cpp +8 -0
  105. data/ext/jstream.h +20 -0
  106. data/ext/jstream_t.h +175 -0
  107. data/ext/jtea.cpp +22 -0
  108. data/ext/jtea.h +31 -0
  109. data/ext/jtiger.h +52 -0
  110. data/ext/jtwofish.cpp +22 -0
  111. data/ext/jtwofish.h +31 -0
  112. data/ext/jwhirlpool.h +52 -0
  113. data/ext/utils.cpp +8 -0
  114. data/extras/parser_c.rb +114 -0
  115. data/test/ciphers_test.rb +37 -0
  116. data/test/data/ciphers/3desval.dat +7 -0
  117. data/test/data/ciphers/3wayval.dat +6 -0
  118. data/test/data/ciphers/arc4.dat +8 -0
  119. data/test/data/ciphers/blowfish.dat +5 -0
  120. data/test/data/ciphers/camellia.dat +7 -0
  121. data/test/data/ciphers/cast128v.dat +5 -0
  122. data/test/data/ciphers/cast256v.dat +5 -0
  123. data/test/data/ciphers/descert.dat +198 -0
  124. data/test/data/ciphers/diamond.dat +9 -0
  125. data/test/data/ciphers/gostval.dat +10 -0
  126. data/test/data/ciphers/ideaval.dat +13 -0
  127. data/test/data/ciphers/marsval.dat +11 -0
  128. data/test/data/ciphers/panamac.dat +7 -0
  129. data/test/data/ciphers/rc2val.dat +10 -0
  130. data/test/data/ciphers/rc5val.dat +7 -0
  131. data/test/data/ciphers/rc6val.dat +8 -0
  132. data/test/data/ciphers/rijndael.dat +11 -0
  133. data/test/data/ciphers/saferval.dat +27 -0
  134. data/test/data/ciphers/seal.dat +3 -0
  135. data/test/data/ciphers/serpentv.dat +11 -0
  136. data/test/data/ciphers/shacal2.dat +7 -0
  137. data/test/data/ciphers/sharkval.dat +9 -0
  138. data/test/data/ciphers/skipjack.dat +3 -0
  139. data/test/data/ciphers/squareva.dat +10 -0
  140. data/test/data/ciphers/twofishv.dat +11 -0
  141. data/test/data/digests/adler32.dat +8 -0
  142. data/test/data/digests/crc32.dat +10 -0
  143. data/test/data/digests/haval.dat +4 -0
  144. data/test/data/digests/havalcer.dat +23 -0
  145. data/test/data/digests/md2.dat +9 -0
  146. data/test/data/digests/md4.dat +9 -0
  147. data/test/data/digests/md5.dat +9 -0
  148. data/test/data/digests/panamah.dat +8 -0
  149. data/test/data/digests/ripemd.dat +43 -0
  150. data/test/data/digests/sha.dat +19 -0
  151. data/test/data/digests/tiger.dat +11 -0
  152. data/test/data/digests/whirlpool.dat +13 -0
  153. data/test/data/hmacs/hmac.dat +6 -0
  154. data/test/digests_test.rb +29 -0
  155. data/test/hmacs_test.rb +38 -0
  156. data/test/test_helper.rb +42 -0
  157. metadata +220 -0
@@ -0,0 +1,8 @@
1
+ ext/*.bundle
2
+ ext/*.o
3
+ doc
4
+ *.kpf
5
+ *~
6
+ .DS_Store
7
+ *tmp*
8
+ pkg/
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2002-2010 J Smith <dark.panda@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,7 @@
1
+ == cryptopp-ruby
2
+
3
+ cryptopp-ruby is a collection of strong encryption routines for Ruby
4
+ built on Wei Dai's Crypto++ library. Included in the extension are
5
+ algorithms for symmetric block and stream ciphers, checksums, digests
6
+ and HMACs.
7
+
@@ -0,0 +1,42 @@
1
+
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'rake/gempackagetask'
6
+ require 'rake/testtask'
7
+ require 'rake/rdoctask'
8
+
9
+ $:.push 'lib'
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "cryptopp"
15
+ gem.version = "0.0.4"
16
+ gem.summary = "cryptopp is a cryptographic library for Ruby built on Wei Dai's Crypto++."
17
+ gem.description = gem.summary
18
+ gem.email = "dark.panda@gmail.com"
19
+ gem.homepage = "http://github.com/dark-panda/ruby-cryptopp"
20
+ gem.authors = [ "J Smith" ]
21
+ end
22
+ Jeweler::GemcutterTasks.new
23
+ rescue LoadError
24
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
25
+ end
26
+
27
+ desc 'Test cryptopp interface'
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'lib'
30
+ t.pattern = 'test/**/*_test.rb'
31
+ t.verbose = false
32
+ end
33
+
34
+ desc 'Build docs'
35
+ Rake::RDocTask.new do |t|
36
+ require 'rdoc/rdoc'
37
+ require 'extras/parser_c.rb'
38
+ t.main = 'README'
39
+ t.rdoc_dir = 'doc'
40
+ t.rdoc_files.include('README', 'ext/cryptopp.cpp', 'ext/ciphers.cpp', 'ext/digests.cpp')
41
+ end
42
+
@@ -0,0 +1,199 @@
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{cryptopp}
8
+ s.version = "0.0.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["J Smith"]
12
+ s.date = %q{2010-07-01}
13
+ s.description = %q{cryptopp is a cryptographic library for Ruby built on Wei Dai's Crypto++.}
14
+ s.email = %q{dark.panda@gmail.com}
15
+ s.extensions = ["ext/extconf.rb"]
16
+ s.extra_rdoc_files = [
17
+ "README"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "MIT-LICENSE",
22
+ "README",
23
+ "Rakefile",
24
+ "cryptopp.gemspec",
25
+ "ext/.gitignore",
26
+ "ext/Rakefile",
27
+ "ext/ciphers.cpp",
28
+ "ext/cryptopp.cpp",
29
+ "ext/cryptopp_ruby_api.h",
30
+ "ext/defs/block_modes.def",
31
+ "ext/defs/checksums.def",
32
+ "ext/defs/ciphers.def",
33
+ "ext/defs/hashes.def",
34
+ "ext/defs/hmacs.def",
35
+ "ext/defs/paddings.def",
36
+ "ext/defs/rngs.def",
37
+ "ext/digests.cpp",
38
+ "ext/extconf.rb",
39
+ "ext/j3way.cpp",
40
+ "ext/j3way.h",
41
+ "ext/jadler32.h",
42
+ "ext/jaes.cpp",
43
+ "ext/jaes.h",
44
+ "ext/jarc4.cpp",
45
+ "ext/jarc4.h",
46
+ "ext/jbase.cpp",
47
+ "ext/jbase.h",
48
+ "ext/jbasiccipherinfo.h",
49
+ "ext/jblowfish.cpp",
50
+ "ext/jblowfish.h",
51
+ "ext/jcamellia.cpp",
52
+ "ext/jcamellia.h",
53
+ "ext/jcast128.cpp",
54
+ "ext/jcast128.h",
55
+ "ext/jcast256.cpp",
56
+ "ext/jcast256.h",
57
+ "ext/jcipher.cpp",
58
+ "ext/jcipher.h",
59
+ "ext/jcipher_t.h",
60
+ "ext/jconfig.h",
61
+ "ext/jconstants.h",
62
+ "ext/jcrc32.h",
63
+ "ext/jdes.cpp",
64
+ "ext/jdes.h",
65
+ "ext/jdes_ede2.cpp",
66
+ "ext/jdes_ede2.h",
67
+ "ext/jdes_ede3.cpp",
68
+ "ext/jdes_ede3.h",
69
+ "ext/jdes_xex3.cpp",
70
+ "ext/jdes_xex3.h",
71
+ "ext/jdiamond2.cpp",
72
+ "ext/jdiamond2.h",
73
+ "ext/jdiamond2lite.cpp",
74
+ "ext/jdiamond2lite.h",
75
+ "ext/jexception.h",
76
+ "ext/jgost.cpp",
77
+ "ext/jgost.h",
78
+ "ext/jhash.cpp",
79
+ "ext/jhash.h",
80
+ "ext/jhash_t.h",
81
+ "ext/jhaval.h",
82
+ "ext/jhelpers.cpp",
83
+ "ext/jhelpers.h",
84
+ "ext/jhmac.cpp",
85
+ "ext/jhmac.h",
86
+ "ext/jhmac_t.h",
87
+ "ext/jidea.cpp",
88
+ "ext/jidea.h",
89
+ "ext/jmarc4.cpp",
90
+ "ext/jmarc4.h",
91
+ "ext/jmars.cpp",
92
+ "ext/jmars.h",
93
+ "ext/jmd2.h",
94
+ "ext/jmd4.h",
95
+ "ext/jmd5.h",
96
+ "ext/jpanamacipher.cpp",
97
+ "ext/jpanamacipher.h",
98
+ "ext/jpanamahash.h",
99
+ "ext/jrc2.cpp",
100
+ "ext/jrc2.h",
101
+ "ext/jrc5.cpp",
102
+ "ext/jrc5.h",
103
+ "ext/jrc6.cpp",
104
+ "ext/jrc6.h",
105
+ "ext/jripemd160.h",
106
+ "ext/jsafer.cpp",
107
+ "ext/jsafer.h",
108
+ "ext/jseal.cpp",
109
+ "ext/jseal.h",
110
+ "ext/jserpent.cpp",
111
+ "ext/jserpent.h",
112
+ "ext/jsha.h",
113
+ "ext/jshacal2.cpp",
114
+ "ext/jshacal2.h",
115
+ "ext/jshark.cpp",
116
+ "ext/jshark.h",
117
+ "ext/jsink.cpp",
118
+ "ext/jsink.h",
119
+ "ext/jskipjack.cpp",
120
+ "ext/jskipjack.h",
121
+ "ext/jsquare.cpp",
122
+ "ext/jsquare.h",
123
+ "ext/jstream.cpp",
124
+ "ext/jstream.h",
125
+ "ext/jstream_t.h",
126
+ "ext/jtea.cpp",
127
+ "ext/jtea.h",
128
+ "ext/jtiger.h",
129
+ "ext/jtwofish.cpp",
130
+ "ext/jtwofish.h",
131
+ "ext/jwhirlpool.h",
132
+ "ext/utils.cpp",
133
+ "extras/parser_c.rb",
134
+ "test/ciphers_test.rb",
135
+ "test/data/ciphers/3desval.dat",
136
+ "test/data/ciphers/3wayval.dat",
137
+ "test/data/ciphers/arc4.dat",
138
+ "test/data/ciphers/blowfish.dat",
139
+ "test/data/ciphers/camellia.dat",
140
+ "test/data/ciphers/cast128v.dat",
141
+ "test/data/ciphers/cast256v.dat",
142
+ "test/data/ciphers/descert.dat",
143
+ "test/data/ciphers/diamond.dat",
144
+ "test/data/ciphers/gostval.dat",
145
+ "test/data/ciphers/ideaval.dat",
146
+ "test/data/ciphers/marsval.dat",
147
+ "test/data/ciphers/panamac.dat",
148
+ "test/data/ciphers/rc2val.dat",
149
+ "test/data/ciphers/rc5val.dat",
150
+ "test/data/ciphers/rc6val.dat",
151
+ "test/data/ciphers/rijndael.dat",
152
+ "test/data/ciphers/saferval.dat",
153
+ "test/data/ciphers/seal.dat",
154
+ "test/data/ciphers/serpentv.dat",
155
+ "test/data/ciphers/shacal2.dat",
156
+ "test/data/ciphers/sharkval.dat",
157
+ "test/data/ciphers/skipjack.dat",
158
+ "test/data/ciphers/squareva.dat",
159
+ "test/data/ciphers/twofishv.dat",
160
+ "test/data/digests/adler32.dat",
161
+ "test/data/digests/crc32.dat",
162
+ "test/data/digests/haval.dat",
163
+ "test/data/digests/havalcer.dat",
164
+ "test/data/digests/md2.dat",
165
+ "test/data/digests/md4.dat",
166
+ "test/data/digests/md5.dat",
167
+ "test/data/digests/panamah.dat",
168
+ "test/data/digests/ripemd.dat",
169
+ "test/data/digests/sha.dat",
170
+ "test/data/digests/tiger.dat",
171
+ "test/data/digests/whirlpool.dat",
172
+ "test/data/hmacs/hmac.dat",
173
+ "test/digests_test.rb",
174
+ "test/hmacs_test.rb",
175
+ "test/test_helper.rb"
176
+ ]
177
+ s.homepage = %q{http://github.com/dark-panda/ruby-cryptopp}
178
+ s.rdoc_options = ["--charset=UTF-8"]
179
+ s.require_paths = ["lib"]
180
+ s.rubygems_version = %q{1.3.6}
181
+ s.summary = %q{cryptopp is a cryptographic library for Ruby built on Wei Dai's Crypto++.}
182
+ s.test_files = [
183
+ "test/ciphers_test.rb",
184
+ "test/digests_test.rb",
185
+ "test/hmacs_test.rb",
186
+ "test/test_helper.rb"
187
+ ]
188
+
189
+ if s.respond_to? :specification_version then
190
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
191
+ s.specification_version = 3
192
+
193
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
194
+ else
195
+ end
196
+ else
197
+ end
198
+ end
199
+
@@ -0,0 +1,5 @@
1
+ *.o
2
+ *.so
3
+ mkmf.log
4
+ Makefile
5
+
@@ -0,0 +1,16 @@
1
+
2
+ require 'rake/clean'
3
+
4
+ CLEAN.include '*.o', 'Makefile', 'mkmf.log'
5
+ CLOBBER.include 'cryptopp.so'
6
+
7
+ task :default => ['cryptopp.so']
8
+
9
+ file 'cryptopp.so' => [ 'Makefile' ] do
10
+ sh 'make'
11
+ end
12
+
13
+ file 'Makefile' do
14
+ ruby 'extconf.rb'
15
+ end
16
+
@@ -0,0 +1,1402 @@
1
+
2
+ /*
3
+ * Copyright (c) 2002-2010 J Smith <dark.panda@gmail.com>
4
+ * Crypto++ copyright (c) 1995-2010 Wei Dai
5
+ * See COPYING for the extact license
6
+ */
7
+
8
+ #include "j3way.h"
9
+ #include "jaes.h"
10
+ #include "jblowfish.h"
11
+ #include "jcamellia.h"
12
+ #include "jcast128.h"
13
+ #include "jcast256.h"
14
+ #include "jdes.h"
15
+ #include "jdes_ede2.h"
16
+ #include "jdes_ede3.h"
17
+ #include "jdes_xex3.h"
18
+ #include "jdiamond2.h"
19
+ #include "jdiamond2lite.h"
20
+ #include "jgost.h"
21
+ #include "jidea.h"
22
+ #include "jmars.h"
23
+ #include "jrc2.h"
24
+ #include "jrc5.h"
25
+ #include "jrc6.h"
26
+ #include "jsafer.h"
27
+ #include "jserpent.h"
28
+ #include "jshacal2.h"
29
+ #include "jshark.h"
30
+ #include "jskipjack.h"
31
+ #include "jsquare.h"
32
+ #include "jtea.h"
33
+ #include "jtwofish.h"
34
+
35
+
36
+ // stream cipher algorithms:
37
+
38
+ #include "jarc4.h"
39
+ #include "jmarc4.h"
40
+ #include "jpanamacipher.h"
41
+ #include "jseal.h"
42
+
43
+ #include "jbasiccipherinfo.h"
44
+ #include "jexception.h"
45
+
46
+ #include "cryptopp_ruby_api.h"
47
+
48
+ extern void cipher_mark(JBase *c);
49
+ extern void cipher_free(JBase *c);
50
+
51
+ // forward declarations
52
+
53
+ static CipherEnum cipher_sym_to_const(VALUE cipher);
54
+ static ModeEnum mode_sym_to_const(VALUE m);
55
+ static PaddingEnum padding_sym_to_const(VALUE p);
56
+ static RNGEnum rng_sym_to_const(VALUE rng);
57
+
58
+ static bool cipher_enabled(CipherEnum cipher);
59
+ static void cipher_options(VALUE self, VALUE options);
60
+ static JBase* cipher_factory(long algorithm);
61
+ static VALUE wrap_cipher_in_ruby(JBase* cipher);
62
+ static void cipher_rand_iv(VALUE self, VALUE l);
63
+ static string cipher_iv_eq(VALUE self, VALUE iv, bool hex);
64
+ static string cipher_iv(VALUE self, bool hex);
65
+ static string cipher_plaintext_eq(VALUE self, VALUE plaintext, bool hex);
66
+ static string cipher_plaintext(VALUE self, bool hex);
67
+ static string cipher_ciphertext_eq(VALUE self, VALUE ciphertext, bool hex);
68
+ static string cipher_ciphertext(VALUE self, bool hex);
69
+ static string cipher_key_eq(VALUE self, VALUE key, bool hex);
70
+ static string cipher_key(VALUE self, bool hex);
71
+ static VALUE cipher_encrypt(VALUE self, bool hex);
72
+ static VALUE cipher_decrypt(VALUE self, bool hex);
73
+
74
+ static CipherEnum cipher_sym_to_const(VALUE c)
75
+ {
76
+ CipherEnum cipher = UNKNOWN_CIPHER;
77
+ ID id = SYM2ID(c);
78
+
79
+ if (id == rb_intern("rijndael")) {
80
+ cipher = AES_CIPHER;
81
+ }
82
+ else if (id == rb_intern("panama")) {
83
+ cipher = PANAMA_CIPHER;
84
+ }
85
+ else if (id == rb_intern("seal")) {
86
+ cipher = SEAL_CIPHER;
87
+ }
88
+ # define CIPHER_ALGORITHM_X_FORCE 1
89
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
90
+ else if (id == rb_intern(# s)) { \
91
+ cipher = r ## _CIPHER; \
92
+ }
93
+ # include "defs/ciphers.def"
94
+ return cipher;
95
+ }
96
+
97
+
98
+ static ModeEnum mode_sym_to_const(VALUE m)
99
+ {
100
+ ModeEnum mode = UNKNOWN_MODE;
101
+ ID id = SYM2ID(m);
102
+
103
+ if (id == rb_intern("counter")) {
104
+ mode = CTR_MODE;
105
+ }
106
+ # define BLOCK_MODE_X(c, s) \
107
+ else if (id == rb_intern(# s)) { \
108
+ mode = c ## _MODE; \
109
+ }
110
+ # include "defs/block_modes.def"
111
+ return mode;
112
+ }
113
+
114
+ static PaddingEnum padding_sym_to_const(VALUE p)
115
+ {
116
+ PaddingEnum padding = UNKNOWN_PADDING;
117
+ ID id = SYM2ID(p);
118
+
119
+ if (id == rb_intern("none")) {
120
+ padding = NO_PADDING;
121
+ }
122
+ else if (id == rb_intern("zeroes")) {
123
+ padding = ZEROS_PADDING;
124
+ }
125
+ else if (id == rb_intern("one_and_zeroes")) {
126
+ padding = ONE_AND_ZEROS_PADDING;
127
+ }
128
+ # define PADDING_X(c, s) \
129
+ else if (id == rb_intern(# s)) { \
130
+ padding = c ## _PADDING; \
131
+ }
132
+ # include "defs/paddings.def"
133
+ return padding;
134
+ }
135
+
136
+ static RNGEnum rng_sym_to_const(VALUE r)
137
+ {
138
+ RNGEnum rng = UNKNOWN_RNG;
139
+ ID id = SYM2ID(r);
140
+
141
+ if (false) {
142
+ // no-op so we can use our x-macro
143
+ }
144
+ # define RNG_X(c, s) \
145
+ else if (id == rb_intern(# s)) { \
146
+ rng = c ## _RNG; \
147
+ }
148
+ # include "defs/rngs.def"
149
+ return rng;
150
+ }
151
+
152
+
153
+ /* See if a cipher algorithm is enabled. */
154
+ static bool cipher_enabled(CipherEnum cipher)
155
+ {
156
+ switch (cipher) {
157
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
158
+ case r ##_CIPHER:
159
+ # include "defs/ciphers.def"
160
+ return true;
161
+ }
162
+ return false;
163
+ }
164
+
165
+
166
+ /* Figure out options for a cipher. We only check for Symbols, not Strings. */
167
+ static void cipher_options(VALUE self, VALUE options)
168
+ {
169
+ Check_Type(options, T_HASH);
170
+
171
+ {
172
+ VALUE plaintext = rb_hash_aref(options, ID2SYM(rb_intern("plaintext")));
173
+ VALUE plaintext_hex = rb_hash_aref(options, ID2SYM(rb_intern("plaintext_hex")));
174
+ if (!NIL_P(plaintext) && !NIL_P(plaintext_hex)) {
175
+ rb_raise(rb_eCryptoPP_Error, "can't set both plaintext and plaintext_hex in options");
176
+ }
177
+ else if (!NIL_P(plaintext)) {
178
+ cipher_plaintext_eq(self, plaintext, false);
179
+ }
180
+ else if (!NIL_P(plaintext_hex)) {
181
+ cipher_plaintext_eq(self, plaintext_hex, true);
182
+ }
183
+ }
184
+
185
+ {
186
+ VALUE ciphertext = rb_hash_aref(options, ID2SYM(rb_intern("ciphertext")));
187
+ VALUE ciphertext_hex = rb_hash_aref(options, ID2SYM(rb_intern("ciphertext_hex")));
188
+ if (!NIL_P(ciphertext) && !NIL_P(ciphertext_hex)) {
189
+ rb_raise(rb_eCryptoPP_Error, "can't set both ciphertext and ciphertext_hex in options");
190
+ }
191
+ else if (!NIL_P(ciphertext)) {
192
+ cipher_ciphertext_eq(self, ciphertext, false);
193
+ }
194
+ else if (!NIL_P(ciphertext_hex)) {
195
+ cipher_ciphertext_eq(self, ciphertext_hex, true);
196
+ }
197
+ }
198
+
199
+ {
200
+ VALUE key = rb_hash_aref(options, ID2SYM(rb_intern("key")));
201
+ VALUE key_hex = rb_hash_aref(options, ID2SYM(rb_intern("key_hex")));
202
+ if (!NIL_P(key) && !NIL_P(key_hex)) {
203
+ rb_raise(rb_eCryptoPP_Error, "can't set both key and key_hex in options");
204
+ }
205
+ else if (!NIL_P(key)) {
206
+ cipher_key_eq(self, key, false);
207
+ }
208
+ else if (!NIL_P(key_hex)) {
209
+ cipher_key_eq(self, key_hex, true);
210
+ }
211
+ }
212
+
213
+ {
214
+ VALUE key_length = rb_hash_aref(options, ID2SYM(rb_intern("key_length")));
215
+ if (!NIL_P(key_length)) {
216
+ rb_cipher_key_length_eq(self, key_length);
217
+ }
218
+ }
219
+
220
+ # if ENABLED_RC2_CIPHER
221
+ {
222
+ VALUE effective_key_length = rb_hash_aref(options, ID2SYM(rb_intern("effective_key_length")));
223
+ if (!NIL_P(effective_key_length)) {
224
+ rb_cipher_effective_key_length_eq(self, effective_key_length);
225
+ }
226
+ }
227
+ # endif
228
+
229
+ {
230
+ VALUE rounds = rb_hash_aref(options, ID2SYM(rb_intern("rounds")));
231
+ if (!NIL_P(rounds)) {
232
+ rb_cipher_rounds_eq(self, rounds);
233
+ }
234
+ }
235
+
236
+ {
237
+ VALUE rng = rb_hash_aref(options, ID2SYM(rb_intern("rng")));
238
+ if (!NIL_P(rng)) {
239
+ rb_cipher_rng_eq(self, rng);
240
+ }
241
+ }
242
+
243
+ {
244
+ VALUE rand_iv = rb_hash_aref(options, ID2SYM(rb_intern("rand_iv")));
245
+ VALUE iv = rb_hash_aref(options, ID2SYM(rb_intern("iv")));
246
+ VALUE iv_hex = rb_hash_aref(options, ID2SYM(rb_intern("iv_hex")));
247
+
248
+ if (!NIL_P(rand_iv) && (!NIL_P(iv) || !NIL_P(iv_hex))) {
249
+ rb_raise(rb_eCryptoPP_Error, "can't set both rand_iv and iv or iv_hex in options");
250
+ }
251
+ else if (!NIL_P(iv) && !NIL_P(iv_hex)) {
252
+ rb_raise(rb_eCryptoPP_Error, "can't set both iv and iv_hex in options");
253
+ }
254
+ else if (!NIL_P(rand_iv)) {
255
+ cipher_rand_iv(self, rand_iv);
256
+ }
257
+ else if (!NIL_P(iv)) {
258
+ cipher_iv_eq(self, iv, false);
259
+ }
260
+ else if (!NIL_P(iv_hex)) {
261
+ cipher_iv_eq(self, iv_hex, true);
262
+ }
263
+ }
264
+
265
+ {
266
+ VALUE block_mode = rb_hash_aref(options, ID2SYM(rb_intern("block_mode")));
267
+ if (!NIL_P(block_mode)) {
268
+ rb_cipher_block_mode_eq(self, block_mode);
269
+ }
270
+ }
271
+
272
+ {
273
+ VALUE padding = rb_hash_aref(options, ID2SYM(rb_intern("padding")));
274
+ if (!NIL_P(padding)) {
275
+ rb_cipher_padding_eq(self, padding);
276
+ }
277
+ }
278
+ }
279
+
280
+
281
+ /* Creates a new Crypto++ cipher. May throw a JException if no suitable cipher
282
+ * is found. May throw a JException if no suitable cipher is found. */
283
+ static JBase* cipher_factory(VALUE algorithm)
284
+ {
285
+ try {
286
+ switch (cipher_sym_to_const(algorithm)) {
287
+ default:
288
+ throw JException("the requested algorithm cannot be found");
289
+ break;
290
+
291
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
292
+ case r ## _CIPHER: \
293
+ return static_cast<c*>(new c);
294
+ # include "defs/ciphers.def"
295
+ }
296
+ }
297
+ catch (Exception e) {
298
+ throw JException("Crypto++ exception: " + e.GetWhat());
299
+ }
300
+ }
301
+
302
+ /* Wraps a Cipher object into a Ruby object. May throw a JException if no
303
+ * suitable Cipher is found. */
304
+ static VALUE wrap_cipher_in_ruby(JBase* cipher)
305
+ {
306
+ const type_info& info = typeid(*cipher);
307
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
308
+ if (info == typeid(c)) { \
309
+ return Data_Wrap_Struct(rb_cCryptoPP_Cipher_## r, cipher_mark, cipher_free, cipher); \
310
+ } \
311
+ else
312
+ # include "defs/ciphers.def"
313
+ {
314
+ throw JException("the requested algorithm has been disabled");
315
+ }
316
+ }
317
+
318
+ /**
319
+ * call-seq:
320
+ * cipher_factory(algorithm) => Cipher
321
+ * cipher_factory(algorithm, options) => Cipher
322
+ *
323
+ * Creates a new Cipher object.
324
+ *
325
+ * See the Cipher class for available options.
326
+ */
327
+ VALUE rb_module_cipher_factory(int argc, VALUE *argv, VALUE self)
328
+ {
329
+ VALUE algorithm, options, retval;
330
+ rb_scan_args(argc, argv, "11", &algorithm, &options);
331
+ try {
332
+ retval = wrap_cipher_in_ruby(cipher_factory(algorithm));
333
+ }
334
+ catch (Exception& e) {
335
+ rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str());
336
+ }
337
+ if (!NIL_P(options)) {
338
+ cipher_options(retval, options);
339
+ }
340
+ return retval;
341
+ }
342
+
343
+ #define CIPHER_ALGORITHM_X(klass, r, n, s) \
344
+ VALUE rb_cipher_ ## r ##_new(int argc, VALUE *argv, VALUE self) \
345
+ { \
346
+ VALUE options, retval; \
347
+ rb_scan_args(argc, argv, "01", &options); \
348
+ try { \
349
+ retval = wrap_cipher_in_ruby(cipher_factory(ID2SYM(rb_intern(# s)))); \
350
+ } \
351
+ catch (Exception& e) { \
352
+ rb_raise(rb_eCryptoPP_Error, e.GetWhat().c_str()); \
353
+ } \
354
+ if (!NIL_P(options)) { \
355
+ cipher_options(retval, options); \
356
+ } \
357
+ return retval; \
358
+ }
359
+ #include "defs/ciphers.def"
360
+
361
+
362
+ /* Creates a random initialization vector on the cipher. */
363
+ static void cipher_rand_iv(VALUE self, VALUE l)
364
+ {
365
+ JBase *cipher = NULL;
366
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
367
+ Data_Get_Struct(self, JBase, cipher);
368
+ cipher->setRandIV(length);
369
+ }
370
+
371
+ /**
372
+ * call-seq:
373
+ * rand_iv(length) => nil
374
+ *
375
+ * Sets a random initialization vector on the Cipher. This method uses the
376
+ * random number generator set on the Cipher to produce the IV, so be sure to
377
+ * set the RNG before you try creating a random IV.
378
+ *
379
+ * The random IV created will is returned in binary.
380
+ */
381
+ VALUE rb_cipher_rand_iv(VALUE self, VALUE l)
382
+ {
383
+ JBase *cipher = NULL;
384
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
385
+ Data_Get_Struct(self, JBase, cipher);
386
+ cipher->setRandIV(length);
387
+ return l;
388
+ }
389
+
390
+
391
+ /* Sets an IV on the cipher. */
392
+ static string cipher_iv_eq(VALUE self, VALUE iv, bool hex)
393
+ {
394
+ JBase *cipher = NULL;
395
+ Check_Type(iv, T_STRING);
396
+ Data_Get_Struct(self, JBase, cipher);
397
+ cipher->setIV(string(StringValuePtr(iv), RSTRING(iv)->len), hex);
398
+ return cipher->getIV(hex);
399
+ }
400
+
401
+ /**
402
+ * call-seq:
403
+ * iv=(iv) => String
404
+ *
405
+ * Set an initialization vector on the Cipher.
406
+ */
407
+ VALUE rb_cipher_iv_eq(VALUE self, VALUE iv)
408
+ {
409
+ cipher_iv_eq(self, iv, false);
410
+ return iv;
411
+ }
412
+
413
+ /**
414
+ * call-seq:
415
+ * iv_hex=(iv) => String
416
+ *
417
+ * Set an initialization vector on the Cipher. This method uses hex data and
418
+ * returns the IV as set.
419
+ */
420
+ VALUE rb_cipher_iv_hex_eq(VALUE self, VALUE iv)
421
+ {
422
+ cipher_iv_eq(self, iv, true);
423
+ return iv;
424
+ }
425
+
426
+
427
+ /* Gets the IV. */
428
+ static string cipher_iv(VALUE self, bool hex)
429
+ {
430
+ JBase *cipher = NULL;
431
+ Data_Get_Struct(self, JBase, cipher);
432
+ return cipher->getIV(hex);
433
+ }
434
+
435
+ /**
436
+ * call-seq:
437
+ * iv => String
438
+ *
439
+ * Returns the Cipher's IV in binary.
440
+ */
441
+ VALUE rb_cipher_iv(VALUE self)
442
+ {
443
+ string retval = cipher_iv(self, false);
444
+ return rb_tainted_str_new(retval.data(), retval.length());
445
+ }
446
+
447
+ /**
448
+ * call-seq:
449
+ * iv => String
450
+ *
451
+ * Returns the Cipher's IV in hex.
452
+ */
453
+ VALUE rb_cipher_iv_hex(VALUE self)
454
+ {
455
+ string retval = cipher_iv(self, true);
456
+ return rb_tainted_str_new(retval.data(), retval.length());
457
+ }
458
+
459
+
460
+ /**
461
+ * call-seq:
462
+ * block_mode=(mode) => Symbol
463
+ *
464
+ * Set the block mode on block ciphers. Returns the mode as set and may raise
465
+ * a CryptoPPError if the mode is invalid or you are using a stream cipher.
466
+ */
467
+ VALUE rb_cipher_block_mode_eq(VALUE self, VALUE m)
468
+ {
469
+ JBase *cipher = NULL;
470
+ ModeEnum mode = mode_sym_to_const(m);
471
+
472
+ if (!VALID_MODE(mode)) {
473
+ rb_raise(rb_eCryptoPP_Error, "invalid cipher mode");
474
+ }
475
+ Data_Get_Struct(self, JBase, cipher);
476
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
477
+ rb_raise(rb_eCryptoPP_Error, "can't set mode on stream ciphers");
478
+ }
479
+ else {
480
+ ((JCipher*) cipher)->setMode(mode);
481
+ return m;
482
+ }
483
+ }
484
+
485
+
486
+ /**
487
+ * call-seq:
488
+ * block_mode => Fixnum
489
+ *
490
+ * Get the block mode. Returns <tt>nil</tt> if you try to use this on a stream
491
+ * cipher.
492
+ */
493
+ VALUE rb_cipher_block_mode(VALUE self)
494
+ {
495
+ JBase *cipher = NULL;
496
+ Data_Get_Struct(self, JBase, cipher);
497
+ ModeEnum mode = ((JCipher*) cipher)->getMode();
498
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
499
+ return Qnil;
500
+ }
501
+ # define BLOCK_MODE_X(c, s) \
502
+ else if (mode == c ## _MODE) { \
503
+ return ID2SYM(rb_intern(# s)); \
504
+ }
505
+ # include "defs/block_modes.def"
506
+ }
507
+
508
+
509
+ /**
510
+ * call-seq:
511
+ * padding=(padding) => Symbol
512
+ *
513
+ * Set the padding on block ciphers.
514
+ *
515
+ * Note that not all block cipher modes can use all of the padding types.
516
+ * A CryptoPPError will be raised if you try to set an invalid padding. Also
517
+ * note that the padding should be set <i>AFTER</i> the block mode, as setting
518
+ * the mode causes the padding to revert to its default setting.
519
+ *
520
+ * Returns the padding as set.
521
+ */
522
+ VALUE rb_cipher_padding_eq(VALUE self, VALUE p)
523
+ {
524
+ JBase *cipher = NULL;
525
+ PaddingEnum padding = padding_sym_to_const(p);
526
+
527
+ if (!VALID_PADDING(padding)) {
528
+ rb_raise(rb_eCryptoPP_Error, "invalid cipher padding");
529
+ }
530
+ Data_Get_Struct(self, JBase, cipher);
531
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
532
+ rb_raise(rb_eCryptoPP_Error, "can't set padding on stream ciphers");
533
+ }
534
+ else {
535
+ ((JCipher*) cipher)->setPadding(padding);
536
+ if (((JCipher*) cipher)->getPadding() != padding) {
537
+ rb_raise(rb_eCryptoPP_Error, "Padding '%s' cannot be used with mode '%s'", JCipher::getPaddingName(padding).c_str(), ((JCipher*) cipher)->getModeName().c_str());
538
+ }
539
+ else {
540
+ return p;
541
+ }
542
+ }
543
+ }
544
+
545
+
546
+ /**
547
+ * call-seq:
548
+ * padding => Fixnum
549
+ *
550
+ * Get the cipher padding being used. Returns <tt>nil</tt> if you try to use
551
+ * this on a stream cipher.
552
+ */
553
+ VALUE rb_cipher_padding(VALUE self)
554
+ {
555
+ JBase *cipher = NULL;
556
+ Data_Get_Struct(self, JBase, cipher);
557
+ PaddingEnum padding = ((JCipher*) cipher)->getPadding();
558
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
559
+ return Qnil;
560
+ }
561
+ # define PADDING_X(c, s) \
562
+ else if (padding == c ## _PADDING) { \
563
+ return ID2SYM(rb_intern(# s)); \
564
+ }
565
+ # include "defs/paddings.def"
566
+ }
567
+
568
+
569
+ /**
570
+ * call-seq:
571
+ * rng=(rng) => Symbol
572
+ *
573
+ * Set the random number generator to use for IVs. A CryptoPPError will be
574
+ * raised if an RNG is not available on the system.
575
+ *
576
+ * RNGs are used to create random initialization vectors using
577
+ * <tt>rand_iv</tt>. The default is a non-blocking RNG, such as
578
+ * <tt>/dev/urandom</tt> on UNIX-alikes or CryptoAPI on Microsoft systems.
579
+ */
580
+ VALUE rb_cipher_rng_eq(VALUE self, VALUE r)
581
+ {
582
+ JBase *cipher = NULL;
583
+ RNGEnum rng = rng_sym_to_const(r);
584
+
585
+ if (!VALID_RNG(rng)) {
586
+ rb_raise(rb_eCryptoPP_Error, "invalid cipher RNG");
587
+ }
588
+ Data_Get_Struct(self, JBase, cipher);
589
+ ((JCipher*) cipher)->setRNG(rng);
590
+ if (((JCipher*) cipher)->getRNG() != rng) {
591
+ rb_raise(rb_eCryptoPP_Error, "RNG '%s' is unavailable", JBase::getRNGName(rng).c_str());
592
+ }
593
+ else {
594
+ return r;
595
+ }
596
+ }
597
+
598
+
599
+ /**
600
+ * call-seq:
601
+ * rng => Fixnum
602
+ *
603
+ * Get the RNG being used.
604
+ */
605
+ VALUE rb_cipher_rng(VALUE self)
606
+ {
607
+ JBase *cipher = NULL;
608
+ Data_Get_Struct(self, JBase, cipher);
609
+ RNGEnum rng = ((JCipher*) cipher)->getRNG();
610
+ if (false) {
611
+ // no-op so we can use our x-macro
612
+ }
613
+ # define RNG_X(c, s) \
614
+ else if (rng == c ## _RNG) { \
615
+ return ID2SYM(rb_intern(# s)); \
616
+ }
617
+ # include "defs/rngs.def"
618
+ }
619
+
620
+
621
+ /* Set the plaintext. */
622
+ static string cipher_plaintext_eq(VALUE self, VALUE plaintext, bool hex)
623
+ {
624
+ JBase *cipher = NULL;
625
+ Check_Type(plaintext, T_STRING);
626
+ Data_Get_Struct(self, JBase, cipher);
627
+ cipher->setPlaintext(string(StringValuePtr(plaintext), RSTRING(plaintext)->len), hex);
628
+ return cipher->getPlaintext(hex);
629
+ }
630
+
631
+ /**
632
+ * call-seq:
633
+ * plaintext=(string) => String
634
+ *
635
+ * Sets the plaintext on the Cipher in binary and returns the same.
636
+ */
637
+ VALUE rb_cipher_plaintext_eq(VALUE self, VALUE plaintext)
638
+ {
639
+ cipher_plaintext_eq(self, plaintext, false);
640
+ return plaintext;
641
+ }
642
+
643
+ /**
644
+ * call-seq:
645
+ * plaintext_hex=(string) => String
646
+ *
647
+ * Sets the plaintext on the Cipher in hex and returns the same.
648
+ */
649
+ VALUE rb_cipher_plaintext_hex_eq(VALUE self, VALUE plaintext)
650
+ {
651
+ cipher_plaintext_eq(self, plaintext, true);
652
+ return plaintext;
653
+ }
654
+
655
+
656
+ /* Get the plaintext. */
657
+ static string cipher_plaintext(VALUE self, bool hex)
658
+ {
659
+ JBase *cipher = NULL;
660
+ Data_Get_Struct(self, JBase, cipher);
661
+ return cipher->getPlaintext(hex);
662
+ }
663
+
664
+ /**
665
+ * call-seq:
666
+ * plaintext => String
667
+ *
668
+ * Gets the plaintext from the Cipher in binary.
669
+ */
670
+ VALUE rb_cipher_plaintext(VALUE self)
671
+ {
672
+ string retval = cipher_plaintext(self, false);
673
+ return rb_tainted_str_new(retval.data(), retval.length());
674
+ }
675
+
676
+ /**
677
+ * call-seq:
678
+ * plaintext_hex => String
679
+ *
680
+ * Gets the plaintext from the Cipher in hex.
681
+ */
682
+ VALUE rb_cipher_plaintext_hex(VALUE self)
683
+ {
684
+ string retval = cipher_plaintext(self, true);
685
+ return rb_tainted_str_new(retval.data(), retval.length());
686
+ }
687
+
688
+
689
+ /* Set the ciphertext. */
690
+ static string cipher_ciphertext_eq(VALUE self, VALUE ciphertext, bool hex)
691
+ {
692
+ JBase *cipher = NULL;
693
+ Check_Type(ciphertext, T_STRING);
694
+ Data_Get_Struct(self, JBase, cipher);
695
+ cipher->setCiphertext(string(StringValuePtr(ciphertext), RSTRING(ciphertext)->len), hex);
696
+ return cipher->getCiphertext(hex);
697
+ }
698
+
699
+ /**
700
+ * call-seq:
701
+ * ciphertext=(string) => String
702
+ *
703
+ * Sets the ciphertext on the Cipher in binary and returns the same.
704
+ */
705
+ VALUE rb_cipher_ciphertext_eq(VALUE self, VALUE ciphertext)
706
+ {
707
+ cipher_ciphertext_eq(self, ciphertext, false);
708
+ return ciphertext;
709
+ }
710
+
711
+ /**
712
+ * call-seq:
713
+ * ciphertext_hex=(string) => String
714
+ *
715
+ * Sets the ciphertext on the Cipher in hex and returns the same.
716
+ */
717
+ VALUE rb_cipher_ciphertext_hex_eq(VALUE self, VALUE ciphertext)
718
+ {
719
+ cipher_ciphertext_eq(self, ciphertext, true);
720
+ return ciphertext;
721
+ }
722
+
723
+
724
+ /* Get the ciphertext. */
725
+ static string cipher_ciphertext(VALUE self, bool hex)
726
+ {
727
+ JBase *cipher = NULL;
728
+ Data_Get_Struct(self, JBase, cipher);
729
+ return cipher->getCiphertext(hex);
730
+ }
731
+
732
+ /**
733
+ * call-seq:
734
+ * ciphertext => String
735
+ *
736
+ * Gets the ciphertext from the Cipher in binary.
737
+ */
738
+ VALUE rb_cipher_ciphertext(VALUE self)
739
+ {
740
+ string retval = cipher_ciphertext(self, false);
741
+ return rb_tainted_str_new(retval.data(), retval.length());
742
+ }
743
+
744
+ /**
745
+ * call-seq:
746
+ * ciphertext_hex => String
747
+ *
748
+ * Gets the ciphertext from the Cipher in hex.
749
+ */
750
+ VALUE rb_cipher_ciphertext_hex(VALUE self)
751
+ {
752
+ string retval = cipher_ciphertext(self, true);
753
+ return rb_tainted_str_new(retval.data(), retval.length());
754
+ }
755
+
756
+
757
+ /* Set the key. The true length of the key might not be what you expect,
758
+ * as different algorithms behave differently, i.e. 3Way has a fixed keylength
759
+ * of 12 bytes, while Blowfish can use keys of 1 to 72 bytes. */
760
+ static string cipher_key_eq(VALUE self, VALUE key, bool hex)
761
+ {
762
+ JBase *cipher = NULL;
763
+ Check_Type(key, T_STRING);
764
+ Data_Get_Struct(self, JBase, cipher);
765
+ cipher->setKey(string(StringValuePtr(key), RSTRING(key)->len), hex);
766
+ return cipher->getKey(hex);
767
+ }
768
+
769
+ /**
770
+ * call-seq:
771
+ * key=(string) => String
772
+ *
773
+ * Sets the key on the Cipher in binary and returns the same. Note that the
774
+ * key try to set may be truncated or padded depending on its length. Some
775
+ * ciphers have fixed key lengths while others have specific requirements on
776
+ * their size. For instance, the Threeway cipher has a fixed key length of 12
777
+ * bytes, while Blowfish can use keys of 1 to 72 bytes.
778
+ *
779
+ * When the key being used is shorter than an allowed key length, the key
780
+ * will be padded with \0's before being set. When the key is longer than
781
+ * an allowed key length, the key will be truncated before being set.
782
+ *
783
+ * In both cases, this happens automatically. You should check the actual
784
+ * key that is set using <tt>#key</tt>.
785
+ */
786
+ VALUE rb_cipher_key_eq(VALUE self, VALUE key)
787
+ {
788
+ cipher_key_eq(self, key, false);
789
+ return key;
790
+ }
791
+
792
+ /**
793
+ * call-seq:
794
+ * key_hex=(string) => String
795
+ *
796
+ * Sets the key on the Cipher in hex and returns the same. Note that the
797
+ * key try to set may be truncated or padded depending on its length. Some
798
+ * ciphers have fixed key lengths while others have specific requirements on
799
+ * their size. For instance, the Threeway cipher has a fixed key length of 12
800
+ * bytes, while Blowfish can use keys of 1 to 72 bytes.
801
+ *
802
+ * When the key being used is shorter than an allowed key length, the key
803
+ * will be padded with \0's before being set. When the key is longer than
804
+ * an allowed key length, the key will be truncated before being set.
805
+ *
806
+ * In both cases, this happens automatically. You should check the actual
807
+ * key that is set using <tt>#key</tt>.
808
+ */
809
+ VALUE rb_cipher_key_hex_eq(VALUE self, VALUE key)
810
+ {
811
+ cipher_key_eq(self, key, true);
812
+ return key;
813
+ }
814
+
815
+
816
+ /* Get the key. */
817
+ static string cipher_key(VALUE self, bool hex)
818
+ {
819
+ JBase *cipher = NULL;
820
+ Data_Get_Struct(self, JBase, cipher);
821
+ return cipher->getKey(hex);
822
+ }
823
+
824
+ /**
825
+ * call-seq:
826
+ * key => String
827
+ *
828
+ * Returns the key set on the Cipher in binary.
829
+ */
830
+ VALUE rb_cipher_key(VALUE self)
831
+ {
832
+ string retval = cipher_key(self, false);
833
+ return rb_tainted_str_new(retval.data(), retval.length());
834
+ }
835
+
836
+ /**
837
+ * call-seq:
838
+ * key => String
839
+ *
840
+ * Returns the key set on the Cipher in hex.
841
+ */
842
+ VALUE rb_cipher_key_hex(VALUE self)
843
+ {
844
+ string retval = cipher_key(self, true);
845
+ return rb_tainted_str_new(retval.data(), retval.length());
846
+ }
847
+
848
+
849
+ /**
850
+ * call-seq:
851
+ * key_length=(length) => Fixnum
852
+ *
853
+ * Sets the key length. Some ciphers require rather specific key lengths,
854
+ * and if the key length you attempt to set is invalid, an exception will
855
+ * be thrown. The key length being set is set in terms of bytes in binary, not
856
+ * hex characters.
857
+ */
858
+ VALUE rb_cipher_key_length_eq(VALUE self, VALUE l)
859
+ {
860
+ JBase *cipher = NULL;
861
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
862
+ Data_Get_Struct(self, JBase, cipher);
863
+ cipher->setKeylength(length);
864
+ if (cipher->getKeylength() != length) {
865
+ rb_raise(rb_eCryptoPP_Error, "tried to set a key length of %d but %d was used", length, cipher->getKeylength());
866
+ }
867
+ else {
868
+ return l;
869
+ }
870
+ }
871
+
872
+
873
+ /**
874
+ * call-seq:
875
+ * key_length => Fixnum
876
+ *
877
+ * Gets the key length. The key length being returned in terms of bytes
878
+ * in binary, not hex characters.
879
+ */
880
+ VALUE rb_cipher_key_length(VALUE self)
881
+ {
882
+ JBase *cipher = NULL;
883
+ Data_Get_Struct(self, JBase, cipher);
884
+ return rb_fix_new(cipher->getKeylength());
885
+ }
886
+
887
+
888
+ /**
889
+ * Returns the default key length.
890
+ */
891
+ VALUE rb_cipher_default_key_length(VALUE self)
892
+ {
893
+ JBase *cipher = NULL;
894
+ Data_Get_Struct(self, JBase, cipher);
895
+ return rb_fix_new(cipher->getDefaultKeylength());
896
+ }
897
+
898
+ /**
899
+ * Returns the minimum key length.
900
+ */
901
+ VALUE rb_cipher_min_key_length(VALUE self)
902
+ {
903
+ JBase *cipher = NULL;
904
+ Data_Get_Struct(self, JBase, cipher);
905
+ return rb_fix_new(cipher->getMinKeylength());
906
+ }
907
+
908
+ /**
909
+ * Returns the maximum key length.
910
+ */
911
+ VALUE rb_cipher_max_key_length(VALUE self)
912
+ {
913
+ JBase *cipher = NULL;
914
+ Data_Get_Struct(self, JBase, cipher);
915
+ return rb_fix_new(cipher->getMaxKeylength());
916
+ }
917
+
918
+ /**
919
+ * Returns the multiplier used for the key length.
920
+ */
921
+ VALUE rb_cipher_mult_key_length(VALUE self)
922
+ {
923
+ JBase *cipher = NULL;
924
+ Data_Get_Struct(self, JBase, cipher);
925
+ return rb_fix_new(cipher->getMultKeylength());
926
+ }
927
+
928
+ /**
929
+ * Returns the closest valid key length without actually setting it.
930
+ */
931
+ VALUE rb_cipher_valid_key_length(VALUE self, VALUE l)
932
+ {
933
+ JBase *cipher = NULL;
934
+ unsigned int length = NUM2UINT(l);
935
+ Data_Get_Struct(self, JBase, cipher);
936
+ return rb_fix_new(cipher->getValidKeylength(length));
937
+ }
938
+
939
+
940
+ #if ENABLED_RC2_CIPHER
941
+ /**
942
+ * call-seq:
943
+ * effect_key_length=(length) => Fixnum
944
+ *
945
+ * Set the effective keylength on the RC2 algorithm. This function can
946
+ * only be used with RC2. Returns the actual effective keylength set. The
947
+ * default is 1024, which is also the maximum.
948
+ */
949
+ VALUE rb_cipher_effective_key_length_eq(VALUE self, VALUE l)
950
+ {
951
+ JBase *cipher = NULL;
952
+ unsigned int length = NUM2UINT(rb_funcall(l, rb_intern("to_i"), 0));
953
+ Data_Get_Struct(self, JBase, cipher);
954
+ if (cipher->getCipherType() != RC2_CIPHER) {
955
+ rb_raise(rb_eCryptoPP_Error, "effective key lengths can only be used with the RC2 cipher");
956
+ }
957
+ else {
958
+ ((JRC2*) cipher)->setEffectiveKeylength(length);
959
+ if (((JRC2*) cipher)->getEffectiveKeylength() != length) {
960
+ rb_raise(rb_eCryptoPP_Error, "tried to set an effective key length of %d but %d was used", length, ((JRC2*) cipher)->getEffectiveKeylength());
961
+ }
962
+ else {
963
+ return l;
964
+ }
965
+ }
966
+ }
967
+
968
+
969
+ /**
970
+ * Gets the key length. The key length being returned in terms of bytes in
971
+ * binary, not hex characters.
972
+ */
973
+ VALUE rb_cipher_effective_key_length(VALUE self)
974
+ {
975
+ JBase *cipher = NULL;
976
+ Data_Get_Struct(self, JBase, cipher);
977
+ return rb_fix_new(((JRC2*) cipher)->getEffectiveKeylength());
978
+ }
979
+ #endif
980
+
981
+
982
+ /**
983
+ * call-seq:
984
+ * block_size => Fixnum
985
+ *
986
+ * Gets the block size.
987
+ */
988
+ VALUE rb_cipher_block_size(VALUE self)
989
+ {
990
+ JBase *cipher = NULL;
991
+ Data_Get_Struct(self, JBase, cipher);
992
+ return rb_fix_new(cipher->getBlockSize());
993
+ }
994
+
995
+
996
+ /**
997
+ * call-seq:
998
+ * rounds=(rounds) => Fixnum
999
+ *
1000
+ * Sets the number of rounds to perform on block ciphers. Some block ciphers
1001
+ * have different requirements for their rounds than others. An exception
1002
+ * will be raised on invalid round settings.
1003
+ */
1004
+ VALUE rb_cipher_rounds_eq(VALUE self, VALUE r)
1005
+ {
1006
+ JBase *cipher = NULL;
1007
+ unsigned int rounds = NUM2UINT(rb_funcall(r, rb_intern("to_i"), 0));
1008
+ Data_Get_Struct(self, JBase, cipher);
1009
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1010
+ rb_raise(rb_eCryptoPP_Error, "can't set rounds on stream ciphers");
1011
+ }
1012
+ else {
1013
+ ((JCipher*) cipher)->setRounds(rounds);
1014
+ if (((JCipher*) cipher)->getRounds() != rounds) {
1015
+ rb_raise(rb_eCryptoPP_Error, "tried set the number of rounds to %d but %d was used instead", rounds, ((JCipher*) cipher)->getRounds());
1016
+ }
1017
+ else {
1018
+ return r;
1019
+ }
1020
+ }
1021
+ }
1022
+
1023
+
1024
+ /**
1025
+ * call-seq:
1026
+ * rounts => Fixnum
1027
+ *
1028
+ * Gets the number of rounds to perform on block ciphers. Returns nil if you
1029
+ * try to use this on a stream cipher.
1030
+ */
1031
+ VALUE rb_cipher_rounds(VALUE self)
1032
+ {
1033
+ JBase *cipher = NULL;
1034
+ Data_Get_Struct(self, JBase, cipher);
1035
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1036
+ return Qnil;
1037
+ }
1038
+ else {
1039
+ return rb_fix_new(((JCipher*) cipher)->getRounds());
1040
+ }
1041
+ }
1042
+
1043
+
1044
+ /* Encrypt the plaintext using the options set on the Cipher. This method will
1045
+ * return the ciphertext in binary or hex accordingly, but the raw ciphertext
1046
+ * will always be available through the ciphertext methods regardless. */
1047
+ static VALUE cipher_encrypt(VALUE self, bool hex)
1048
+ {
1049
+ JBase *cipher = NULL;
1050
+ Data_Get_Struct(self, JBase, cipher);
1051
+ try {
1052
+ cipher->encrypt();
1053
+ return rb_tainted_str_new(cipher->getCiphertext(hex).data(), cipher->getCiphertext(hex).length());
1054
+ }
1055
+ catch (Exception e) {
1056
+ rb_raise(rb_eCryptoPP_Error, string("Crypto++ exception: " + e.GetWhat()).c_str());
1057
+ }
1058
+ }
1059
+
1060
+ /**
1061
+ * call-seq:
1062
+ * encrypt => String
1063
+ *
1064
+ * Encrypt the plaintext using the options set on the Cipher. This method will
1065
+ * return the ciphertext in binary. The raw ciphertext will always be available
1066
+ * through the ciphertext and ciphertext_hex afterwards.
1067
+ */
1068
+ VALUE rb_cipher_encrypt(VALUE self)
1069
+ {
1070
+ return cipher_encrypt(self, false);
1071
+ }
1072
+
1073
+ /**
1074
+ * call-seq:
1075
+ * encrypt_hex => String
1076
+ *
1077
+ * Encrypt the plaintext using the options set on the Cipher. This method will
1078
+ * return the ciphertext in hex. The raw ciphertext will always be available
1079
+ * through the ciphertext and ciphertext_hex afterwards.
1080
+ */
1081
+ VALUE rb_cipher_encrypt_hex(VALUE self)
1082
+ {
1083
+ return cipher_encrypt(self, true);
1084
+ }
1085
+
1086
+
1087
+ /* Decrypt the ciphertext using the options set on the Cipher and store
1088
+ * it in the plaintext attribute. This method will return the plaintext
1089
+ * in binary or hex accordingly, but the raw plaintext will always be
1090
+ * available through the plaintext methods regardless. */
1091
+ static VALUE cipher_decrypt(VALUE self, bool hex)
1092
+ {
1093
+ JBase *cipher = NULL;
1094
+ Data_Get_Struct(self, JBase, cipher);
1095
+ try {
1096
+ cipher->decrypt();
1097
+ string retval = cipher->getPlaintext(hex);
1098
+ return rb_tainted_str_new(retval.data(), retval.length());
1099
+ }
1100
+ catch (Exception e) {
1101
+ rb_raise(rb_eCryptoPP_Error, "Crypto++ exception: %s", e.GetWhat().c_str());
1102
+ }
1103
+ }
1104
+
1105
+ /**
1106
+ * call-seq:
1107
+ * decrypt => String
1108
+ *
1109
+ * Decrypt the ciphertext using the options set on the Cipher. This method
1110
+ * will return the plaintext in binary. The raw plaintext will always be
1111
+ * available through the plaintext and plaintext_hex methods afterwards.
1112
+ */
1113
+ VALUE rb_cipher_decrypt(VALUE self)
1114
+ {
1115
+ return cipher_decrypt(self, false);
1116
+ }
1117
+
1118
+ /**
1119
+ * call-seq:
1120
+ * decrypt_hex => String
1121
+ *
1122
+ * Decrypt the ciphertext using the options set on the Cipher. This method
1123
+ * will return the plaintext in hex. The raw plaintext will always be
1124
+ * available through the plaintext and plaintext_hex methods afterwards.
1125
+ */
1126
+ VALUE rb_cipher_decrypt_hex(VALUE self)
1127
+ {
1128
+ return cipher_decrypt(self, true);
1129
+ }
1130
+
1131
+
1132
+ /**
1133
+ * call-seq:
1134
+ * encrypt_io(in, out) => true
1135
+ *
1136
+ * Encrypts a Ruby IO object and spits the result into another one. You can use
1137
+ * any sort of Ruby object as long as it implements <tt>eof?</tt>,
1138
+ * <tt>read</tt>, <tt>write</tt> and <tt>flush</tt>.
1139
+ *
1140
+ * Examples:
1141
+ *
1142
+ * cipher.encrypt_io(File.open("http://example.com/"), File.open("test.out", 'w'))
1143
+ *
1144
+ * output = StringIO.new
1145
+ * cipher.encrypt_io(File.open('test.enc'), output)
1146
+ */
1147
+ VALUE rb_cipher_encrypt_io(VALUE self, VALUE in, VALUE out)
1148
+ {
1149
+ JBase *cipher = NULL;
1150
+ Data_Get_Struct(self, JBase, cipher);
1151
+ try {
1152
+ cipher->encryptRubyIO(&in, &out);
1153
+ return Qtrue;
1154
+ }
1155
+ catch (Exception e) {
1156
+ rb_raise(rb_eCryptoPP_Error, "Crypto++ exception: %s in %s()", e.GetWhat().c_str());
1157
+ }
1158
+ }
1159
+
1160
+
1161
+ /**
1162
+ * call-seq:
1163
+ * decrypt_io(in, out) => true
1164
+ *
1165
+ * Decrypts a Ruby IO object and spits the result into another one. You can use
1166
+ * any sort of Ruby object as long as it implements <tt>eof?</tt>,
1167
+ * <tt>read</tt>, <tt>write</tt> and <tt>flush</tt>.
1168
+ *
1169
+ * Examples:
1170
+ *
1171
+ * cipher.decrypt_io(File.open("http://example.com/"), File.open("test.out", 'w'))
1172
+ *
1173
+ * output = StringIO.new
1174
+ * cipher.decrypt_io(File.open('test.enc'), output)
1175
+ */
1176
+ VALUE rb_cipher_decrypt_io(VALUE self, VALUE in, VALUE out)
1177
+ {
1178
+ JBase *cipher = NULL;
1179
+ Data_Get_Struct(self, JBase, cipher);
1180
+ try {
1181
+ cipher->decryptRubyIO(&in, &out);
1182
+ return Qtrue;
1183
+ }
1184
+ catch (Exception e) {
1185
+ rb_raise(rb_eCryptoPP_Error, "Crypto++ exception: %s in %s()", e.GetWhat().c_str());
1186
+ }
1187
+ }
1188
+
1189
+
1190
+ /**
1191
+ * call-seq:
1192
+ * cipher_name(algorithm) => String
1193
+ *
1194
+ * Returns the name of a Cipher.
1195
+ */
1196
+ VALUE rb_module_cipher_name(VALUE self, VALUE c)
1197
+ {
1198
+ switch (cipher_sym_to_const(c)) {
1199
+ default:
1200
+ rb_raise(rb_eCryptoPP_Error, "could not find a valid cipher type");
1201
+ break;
1202
+
1203
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1204
+ case r ## _CIPHER: \
1205
+ return rb_tainted_str_new2(c::getStaticCipherName().c_str());
1206
+ # include "defs/ciphers.def"
1207
+ }
1208
+ }
1209
+
1210
+
1211
+ /**
1212
+ * call-seq:
1213
+ * algorithm_name() => String
1214
+ *
1215
+ * Returns the name of the cipher algorithm being used.
1216
+ */
1217
+ VALUE rb_cipher_algorithm_name(VALUE self)
1218
+ {
1219
+ JBase *cipher = NULL;
1220
+ Data_Get_Struct(self, JBase, cipher);
1221
+ return rb_tainted_str_new2(cipher->getCipherName().c_str());
1222
+ }
1223
+
1224
+
1225
+ /**
1226
+ * call-seq:
1227
+ * block_mode_name(block_mode) => String
1228
+ *
1229
+ * Singleton method to return the name of a block cipher mode.
1230
+ */
1231
+ VALUE rb_module_block_mode_name(VALUE self, VALUE m)
1232
+ {
1233
+ return rb_tainted_str_new2(JCipher::getModeName(mode_sym_to_const(m)).c_str());
1234
+ }
1235
+
1236
+
1237
+ /**
1238
+ * call-seq:
1239
+ * block_mode_name() => String
1240
+ *
1241
+ * Returns the name of the mode being used.
1242
+ */
1243
+ VALUE rb_cipher_block_mode_name(VALUE self)
1244
+ {
1245
+ JBase *cipher = NULL;
1246
+ Data_Get_Struct(self, JBase, cipher);
1247
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1248
+ return Qnil;
1249
+ }
1250
+ else {
1251
+ return rb_tainted_str_new2(JCipher::getModeName(((JCipher*) cipher)->getMode()).c_str());
1252
+ }
1253
+ }
1254
+
1255
+
1256
+ /**
1257
+ * call-seq:
1258
+ * padding_name(padding) => String
1259
+ *
1260
+ * Singleton method to return the name of the a block cipher padding mode.
1261
+ */
1262
+ VALUE rb_module_padding_name(VALUE self, VALUE p)
1263
+ {
1264
+ return rb_tainted_str_new2(JCipher::getPaddingName(padding_sym_to_const(p)).c_str());
1265
+ }
1266
+
1267
+
1268
+ /**
1269
+ * call-seq:
1270
+ * padding_name() => String
1271
+ *
1272
+ * Returns the name of the padding being used.
1273
+ */
1274
+ VALUE rb_cipher_padding_name(VALUE self)
1275
+ {
1276
+ JBase *cipher = NULL;
1277
+ Data_Get_Struct(self, JBase, cipher);
1278
+ if (IS_STREAM_CIPHER(cipher->getCipherType())) {
1279
+ return Qnil;
1280
+ }
1281
+ else {
1282
+ return rb_tainted_str_new2(JCipher::getPaddingName(((JCipher*) cipher)->getPadding()).c_str());
1283
+ }
1284
+ }
1285
+
1286
+
1287
+ /**
1288
+ * call-seq:
1289
+ * rng_name(rng) => String
1290
+ *
1291
+ * Singleton method to return the name of the random number generator being
1292
+ * used.
1293
+ */
1294
+ VALUE rb_module_rng_name(VALUE self, VALUE r)
1295
+ {
1296
+ return rb_tainted_str_new2(JCipher::getRNGName(rng_sym_to_const(r)).c_str());
1297
+ }
1298
+
1299
+
1300
+ /**
1301
+ * call-seq:
1302
+ * rng_name() => String
1303
+ *
1304
+ * Returns the name of the random number generator being used.
1305
+ */
1306
+ VALUE rb_cipher_rng_name(VALUE self)
1307
+ {
1308
+ JBase *cipher = NULL;
1309
+ Data_Get_Struct(self, JBase, cipher);
1310
+ return rb_tainted_str_new2(JCipher::getRNGName(cipher->getRNG()).c_str());
1311
+ }
1312
+
1313
+
1314
+ /**
1315
+ * call-seq:
1316
+ * cipher_type() => Symbol
1317
+ *
1318
+ * Returns the type of cipher being used as a Symbol.
1319
+ */
1320
+ VALUE rb_cipher_cipher_type(VALUE self)
1321
+ {
1322
+ JBase *cipher = NULL;
1323
+ Data_Get_Struct(self, JBase, cipher);
1324
+
1325
+ switch (cipher->getCipherType()) {
1326
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1327
+ case r ## _CIPHER: \
1328
+ return ID2SYM(rb_intern(# s));
1329
+ # include "defs/ciphers.def"
1330
+
1331
+ default:
1332
+ return Qnil;
1333
+ }
1334
+ }
1335
+
1336
+
1337
+ /**
1338
+ * call-seq:
1339
+ * cipher_enabled?(algorithm) => boolean
1340
+ *
1341
+ * Singleton method to check for the availability of a cipher algorithm.
1342
+ */
1343
+ VALUE rb_module_cipher_enabled(VALUE self, VALUE c)
1344
+ {
1345
+ switch (cipher_sym_to_const(c)) {
1346
+ default:
1347
+ return Qfalse;
1348
+
1349
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1350
+ case r ## _CIPHER:
1351
+ # include "defs/ciphers.def"
1352
+ return Qtrue;
1353
+ }
1354
+ }
1355
+
1356
+
1357
+ /**
1358
+ * call-seq:
1359
+ * rng_available?(rng) => boolean
1360
+ *
1361
+ * Singleton method to check for the availability of a random number generator.
1362
+ */
1363
+ VALUE rb_module_rng_available(VALUE self, VALUE r)
1364
+ {
1365
+ ID id = SYM2ID(r);
1366
+ if (id == rb_intern("rand")) {
1367
+ return Qtrue;
1368
+ }
1369
+ # ifdef NONBLOCKING_RNG_AVAILABLE
1370
+ else if (id == rb_intern("non_blocking")) {
1371
+ return Qtrue;
1372
+ }
1373
+ # endif
1374
+
1375
+ # ifdef BLOCKING_RNG_AVAILABLE
1376
+ else if (id == rb_intern("blocking")) {
1377
+ return Qtrue;
1378
+ }
1379
+ # endif
1380
+
1381
+ else {
1382
+ return Qfalse;
1383
+ }
1384
+ }
1385
+
1386
+
1387
+ /**
1388
+ * call-seq:
1389
+ * cipher_list() => Array
1390
+ *
1391
+ * Returns an Array of available ciphers.
1392
+ */
1393
+ VALUE rb_module_cipher_list(VALUE self)
1394
+ {
1395
+ VALUE ary = rb_ary_new();
1396
+
1397
+ # define CIPHER_ALGORITHM_X(klass, r, c, s) \
1398
+ rb_ary_push(ary, ID2SYM(rb_intern(# s)));
1399
+ # include "defs/ciphers.def"
1400
+
1401
+ return ary;
1402
+ }