openssl-ccm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d66abf07f1338dab11b2447f1021d7cdb8c48a00
4
+ data.tar.gz: ab8339239f00ab678d22094dc4155f7bafe9374d
5
+ SHA512:
6
+ metadata.gz: 0edc78d7cef5c7fbcb6023448c9e92413c86d8ff0aa40016f8a5ecbb13a81b4a528121a84e7e88594f7b2161528f80cca77227604968f689e6ec91efef960847
7
+ data.tar.gz: de45305879ceb9a473e6f02ba05b548212b7cdfe5bf95bce8e212f07a3583253b256151281c76ddbb514e8970c9d5b4602301be85e5d578dc9846978c5bb2fa7
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rdoc', '>=4.1.1'
4
+ gem 'yard', '>=0.8.7.3'
5
+ gem 'rubocop', '>=0.18.1'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 SmallLars
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ openssl-ccm
2
+ ===========
3
+
4
+ Ruby Gem for RFC 3610 - Counter with CBC-MAC (CCM)
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ task :default => :build
5
+
6
+ desc "Run tests"
7
+ Rake::TestTask.new do |t|
8
+ t.libs << 'test'
9
+ end
10
+
11
+ desc "Uninstall gem"
12
+ task (:uninstall) { sh "gem uninstall openssl-ccm" }
13
+
14
+ desc "Development Dependencies"
15
+ task (:devinst) { sh "gem install --dev ./openssl-ccm-0.0.1.gem" }
16
+
17
+ desc "Clean gem"
18
+ task :clean do
19
+ begin; sh "rm ./openssl-ccm-*.gem"; rescue; end
20
+ begin; sh "rm -R ./.yardoc"; rescue; end
21
+ begin; sh "rm -R ./doc"; rescue; end
22
+ end
23
+
24
+ desc "Bundle install"
25
+ task (:bundle) { sh "bundle install" }
26
+
27
+ desc "Create documentation"
28
+ task :doc do
29
+ sh "gem rdoc --rdoc openssl-ccm"
30
+ sh "yardoc"
31
+ end
@@ -0,0 +1,164 @@
1
+ require 'openssl'
2
+
3
+ module OpenSSL
4
+ # TODO
5
+ class CCMError < StandardError
6
+ end
7
+
8
+ # Abstract from http://tools.ietf.org/html/rfc3610:
9
+ #
10
+ # Counter with CBC-MAC (CCM) is a generic authenticated encryption
11
+ # block cipher mode. CCM is defined for use with 128-bit block
12
+ # ciphers, such as the Advanced Encryption Standard (AES).
13
+ #
14
+ # At the moment there is no update function, because length of
15
+ # data and additional_data are needed to start of cipher process.
16
+ # In future init(nonce, data_len, additional_data_len) could
17
+ # be a solution, to solve this problem. After init, update(data)
18
+ # could be used to set additional_data first followed by data.
19
+ class CCM
20
+ # Searches for supported algorithms within OpenSSL
21
+ #
22
+ # @return [Stringlist] of supported algorithms
23
+ def self.ciphers
24
+ l = OpenSSL::Cipher.ciphers.keep_if { |c| c.end_with?('-128-CBC') }
25
+ l.length.times { |i| l[i] = l[i][0..-9] }
26
+ l
27
+ end
28
+
29
+ public
30
+
31
+ # Creates a new CCM object.
32
+ #
33
+ # @param cipher [String] one of the supported algorithms like 'AES'
34
+ # @param key [String] the key used for encryption and decryption
35
+ # @param mac_len [Number] the length of the mac.
36
+ # needs to be in 4, 6, 8, 10, 12, 14, 16
37
+ #
38
+ # @return [Object] the new CCM object
39
+ def initialize(cipher, key, mac_len)
40
+ unless CCM.ciphers.include?(cipher)
41
+ fail CCMError, "unsupported cipher algorithm (#{cipher})"
42
+ end
43
+ fail CCMError, 'invalid key length' unless key.b.length >= 16
44
+ unless (4..16).step(2).include?(mac_len)
45
+ fail CCMError, 'invalid mac length'
46
+ end
47
+
48
+ @cipher = OpenSSL::Cipher.new("#{cipher}-128-CBC")
49
+ @key = key
50
+ @mac_len = mac_len
51
+ end
52
+
53
+ # Encrypts the input data and appends mac for authentication.
54
+ # If there is additional data, its included into mac calculation.
55
+ #
56
+ # @param data [String] the data to encrypt
57
+ # @param nonce [String] the nonce used for encryption
58
+ # @param additional_data [String] additional data to
59
+ # authenticate with mac (not part of the output)
60
+ #
61
+ # @return [String] the encrypted data with appended mac
62
+ def encrypt(data, nonce, additional_data = '')
63
+ valid?(data, nonce, additional_data)
64
+
65
+ crypt(data, nonce) + mac(data, nonce, additional_data)
66
+ end
67
+
68
+ # Decrypts the input data and checks the appended mac.
69
+ # If additional data was used for encryption, its needed
70
+ # for decryption, to check the authentication (mac).
71
+ #
72
+ # @param data [String] the data to decrypt
73
+ # @param nonce [String] the nonce used for decryption
74
+ # @param additional_data [String] additional data to check
75
+ # authentication (not part of the output)
76
+ #
77
+ # @return [String] the decrypted data without mac
78
+ def decrypt(data, nonce, additional_data = '')
79
+ valid?(data, nonce, additional_data)
80
+
81
+ new_data = crypt(data.b[0...-@mac_len], nonce)
82
+ new_mac = mac(new_data, nonce, additional_data)
83
+ return new_data if new_mac == data.b[-@mac_len..-1]
84
+ ''
85
+ end
86
+
87
+ private
88
+
89
+ def valid?(data, nonce, additional_data)
90
+ unless (7..13).include?(nonce.b.length)
91
+ fail CCMError, 'invalid nonce length'
92
+ end
93
+ unless data.b.length < 2**(8 * (15 - nonce.b.length))
94
+ fail CCMError, 'invalid data length'
95
+ end
96
+ unless additional_data.b.length < 2**64
97
+ fail CCMError, 'invalid additional_data length'
98
+ end
99
+ true
100
+ end
101
+
102
+ def crypt(data, nonce)
103
+ result = ''
104
+ data.bytes.each_slice(16).with_index(1) do |block, b|
105
+ counter = get_counter(nonce, b).bytes
106
+ block.length.times { |i| counter[i] ^= block[i] }
107
+ result << counter[0, block.length].pack('C*')
108
+ end
109
+ result
110
+ end
111
+
112
+ def mac(data, nonce, additional_data)
113
+ @cipher.reset
114
+ @cipher.encrypt
115
+ @cipher.key = @key
116
+
117
+ b_0 = Array.new(8, 0)
118
+ b_0[0] = (additional_data.empty? ? 0 : 64) \
119
+ + (8 * ((@mac_len - 2) / 2)) \
120
+ + (14 - nonce.b.length)
121
+ b_0 += [data.b.length].pack('Q').reverse.bytes
122
+ b_0[1, nonce.b.length] = nonce.bytes
123
+ mac = @cipher.update(b_0.pack('C*')).bytes
124
+
125
+ unless additional_data.empty?
126
+ len = additional_data.b.length
127
+ d = case
128
+ when len < (2**16 - 2**8)
129
+ [len].pack('n')
130
+ when len < 2**32
131
+ "\xFF\xFE" + [len].pack('N')
132
+ else
133
+ "\xFF\xFF" + [len].pack('Q').reverse
134
+ end + additional_data
135
+ mac = @cipher.update(d + padding(d)).bytes[-16..-1]
136
+ end
137
+
138
+ unless data.empty?
139
+ mac = @cipher.update(data + padding(data)).bytes[-16..-1]
140
+ end
141
+
142
+ a_0 = get_counter(nonce, 0).bytes
143
+ 16.times { |i| mac[i] ^= a_0[i] }
144
+ mac[0...@mac_len].pack('C*')
145
+ end
146
+
147
+ def padding(data)
148
+ return '' if (data.b.length % 16) == 0
149
+ "\x00" * (16 - (data.b.length % 16))
150
+ end
151
+
152
+ def get_counter(nonce, index)
153
+ a = Array.new(8, 0)
154
+ a[0] = 14 - nonce.b.length
155
+ a += [index].pack('Q').reverse.bytes
156
+ a[1, nonce.b.length] = nonce.bytes
157
+
158
+ @cipher.reset
159
+ @cipher.encrypt
160
+ @cipher.key = @key
161
+ @cipher.update(a.pack('C*'))
162
+ end
163
+ end
164
+ end
data/test/data_1 ADDED
File without changes
data/test/data_1-1_e ADDED
@@ -0,0 +1 @@
1
+ �`��`C� �x�J)�
data/test/data_1-2_e ADDED
@@ -0,0 +1 @@
1
+ �3Qȳ��
data/test/data_1-3_e ADDED
@@ -0,0 +1 @@
1
+ ��#�=�ʵ��ii3
data/test/data_1-4_e ADDED
@@ -0,0 +1 @@
1
+ (����y
data/test/data_2 ADDED
@@ -0,0 +1,2 @@
1
+ Ein kleiner Text
2
+ zum Testen von CCM.
data/test/data_2-1_e ADDED
Binary file
data/test/data_2-2_e ADDED
@@ -0,0 +1 @@
1
+ Dz�p�5{h�5M���A=��%�֧ސ�ii��@���tS,��Ϲ
data/test/data_2-3_e ADDED
@@ -0,0 +1 @@
1
+ `��gM�T�)~>4�x����O��;���� �c���rܮ|��V*���<
data/test/data_2-4_e ADDED
@@ -0,0 +1,2 @@
1
+ �1U��p�b�vA���&pa�6����F=Z�
2
+ s���7UB�~�;�
data/test/data_3 ADDED
Binary file
data/test/data_3-1_e ADDED
Binary file
data/test/data_3-2_e ADDED
Binary file
data/test/data_3-3_e ADDED
Binary file
data/test/data_3-4_e ADDED
Binary file
data/test/test_ccm.rb ADDED
@@ -0,0 +1,265 @@
1
+ require 'test/unit'
2
+ require 'openssl-ccm'
3
+
4
+ # Testclass with Test Vectors from
5
+ # http://tools.ietf.org/html/rfc3610#section-8
6
+ class CCMTest < Test::Unit::TestCase
7
+ KEY = %W(C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF) * 12 \
8
+ + %W(D7828D13B2B0BDC325A76236DF93CC6B) * 12
9
+ NONCE = %W(
10
+ 00000003020100A0A1A2A3A4A5
11
+ 00000004030201A0A1A2A3A4A5
12
+ 00000005040302A0A1A2A3A4A5
13
+ 00000006050403A0A1A2A3A4A5
14
+ 00000007060504A0A1A2A3A4A5
15
+ 00000008070605A0A1A2A3A4A5
16
+ 00000009080706A0A1A2A3A4A5
17
+ 0000000A090807A0A1A2A3A4A5
18
+ 0000000B0A0908A0A1A2A3A4A5
19
+ 0000000C0B0A09A0A1A2A3A4A5
20
+ 0000000D0C0B0AA0A1A2A3A4A5
21
+ 0000000E0D0C0BA0A1A2A3A4A5
22
+ 00412B4EA9CDBE3C9696766CFA
23
+ 0033568EF7B2633C9696766CFA
24
+ 00103FE41336713C9696766CFA
25
+ 00764C63B8058E3C9696766CFA
26
+ 00F8B678094E3B3C9696766CFA
27
+ 00D560912D3F703C9696766CFA
28
+ 0042FFF8F1951C3C9696766CFA
29
+ 00920F40E56CDC3C9696766CFA
30
+ 0027CA0C7120BC3C9696766CFA
31
+ 005B8CCBCD9AF83C9696766CFA
32
+ 003EBE94044B9A3C9696766CFA
33
+ 008D493B30AE8B3C9696766CFA
34
+ )
35
+ DATA = %W(
36
+ 08090A0B0C0D0E0F101112131415161718191A1B1C1D1E
37
+ 08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
38
+ 08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20
39
+ 0C0D0E0F101112131415161718191A1B1C1D1E
40
+ 0C0D0E0F101112131415161718191A1B1C1D1E1F
41
+ 0C0D0E0F101112131415161718191A1B1C1D1E1F20
42
+ 08090A0B0C0D0E0F101112131415161718191A1B1C1D1E
43
+ 08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
44
+ 08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20
45
+ 0C0D0E0F101112131415161718191A1B1C1D1E
46
+ 0C0D0E0F101112131415161718191A1B1C1D1E1F
47
+ 0C0D0E0F101112131415161718191A1B1C1D1E1F20
48
+ 08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C
49
+ 9020EA6F91BDD85AFA0039BA4BAFF9BFB79C7028949CD0EC
50
+ B916E0EACC1C00D7DCEC68EC0B3BBB1A02DE8A2D1AA346132E
51
+ 12DAAC5630EFA5396F770CE1A66B21F7B2101C
52
+ E88B6A46C78D63E52EB8C546EFB5DE6F75E9CC0D
53
+ 6435ACBAFB11A82E2F071D7CA4A5EBD93A803BA87F
54
+ 8A19B950BCF71A018E5E6701C91787659809D67DBEDD18
55
+ 1761433C37C5A35FC1F39F406302EB907C6163BE38C98437
56
+ A434A8E58500C6E41530538862D686EA9E81301B5AE4226BFA
57
+ B96B49E21D621741632875DB7F6C9243D2D7C2
58
+ E2FCFBB880442C731BF95167C8FFD7895E337076
59
+ ABF21C0B02FEB88F856DF4A37381BCE3CC128517D4
60
+ )
61
+ ADD_DATA = %W(0001020304050607) * 3 \
62
+ + %W(000102030405060708090A0B) * 3 \
63
+ + %W(0001020304050607) * 3 \
64
+ + %W(000102030405060708090A0B) * 3 \
65
+ + %W(
66
+ 0BE1A88BACE018B1
67
+ 63018F76DC8A1BCB
68
+ AA6CFA36CAE86B40
69
+ D0D0735C531E1BECF049C244
70
+ 77B60F011C03E1525899BCAE
71
+ CD9044D2B71FDB8120EA60C0
72
+ D85BC7E69F944FB8
73
+ 74A0EBC9069F5B37
74
+ 44A3AA3AAE6475CA
75
+ EC46BB63B02520C33C49FD70
76
+ 47A65AC78B3D594227E85E71
77
+ 6E37A6EF546D955D34AB6059
78
+ )
79
+ CTR0001 = %W(
80
+ 50859D916DCB6DDDE077C2D1D4EC9F97
81
+ 7AC0103DED38F6C0390DBA871C4991F4
82
+ 59B8EFFF46147312B47A1D9D393D3CFF
83
+ AE81666A838B886AEEBF4A5B3284508A
84
+ D0FCF5744D8F31E8895B05054B7C90C3
85
+ 63CCBE1EE01744984564B23A8D245C80
86
+ 093CDBB9C5524FDAC1C5ECD291C470AF
87
+ 737C3391CC8E13DDE0AAC54B6DB7EB98
88
+ 8A5A106BC0299A555B936B0B0EA0DE5A
89
+ 0B392B9B056697063F12568F2B13A10F
90
+ 6B66BC0C90A1F112FCBE6F4E122077BC
91
+ CCF2AED9E04AC974E65855B32B9430BF
92
+ 4451B0117A8482BF0319AEC1595EBDDA
93
+ DCEBF413383C66A05A7255EF98D7FFAD
94
+ 08C4DAC8ECC1C07B4CE1F24C375A47EE
95
+ 0608FF95A694D559F40BB79DEFFA41DF
96
+ BDCE955CCFD3810A91EA77A6A45BC04C
97
+ 64A2C55650CEE04C7A93D8EEF543E88E
98
+ 363834FA28833DB755660D98650D6846
99
+ 4F71A5C11242E37D29F0FEE41BE1025F
100
+ 568A459E40094867EB85E09E6A2E6476
101
+ 88BC194280C1FA3EBEFCEFFB4DC62D54
102
+ 0A7E0A6353C8CF9EBC3B6E63159AD097
103
+ 58DB19B3889AA38B3CA40B16FF422C73
104
+ )
105
+ CTR0002 = %W(
106
+ 7546717AC6DE9AFF640C9C06DE6D0D8F
107
+ D40CDE22D5F92424F7BE9A569DA79F51
108
+ 69F122A078C79B8977894C99975C2378
109
+ D1B19206AC939E2FB6DDCE10A774FD8D
110
+ 72A0D4219F0DE1D40483BC2D3D0CFC2A
111
+ 396DBAA2A7D2CBD4B5E17C107945BBC0
112
+ 11578386E2C472B48ECC8AADAB776FCB
113
+ 74B77177C5AAC53B04A4F8708E92EB2B
114
+ EA05FDE2AB225CFEB77312CB88D9A54A
115
+ 078965252340943B9E69B256CC5EF731
116
+ 979E572BBE658AE5CC2011832A9A9B5B
117
+ A2CAAC1163F407E5E5F6E3B3790F79F8
118
+ 83EB76E13A44847F9220090776B825C5
119
+ 2F542CBA15D66CDFE1EC468F0E68A124
120
+ A7872E6C6DC44E842602504C3FA573C5
121
+ 80553A75783804A9648B68DD7FDCDD7A
122
+ 432EF232AE36D89222BF6337E6B26CE8
123
+ 18E765ACB7B0E9AF092BD0206CA1C83C
124
+ 35E96354871672563F0C08AF784431A9
125
+ 342BD3F17CB77BC1790B05056159272C
126
+ A600AA929203549AAEEF2CCC59137A57
127
+ 3E597DA5AE21CCA4009E4C0C91F62249
128
+ EA2032DA27826E139E1E725C5B0D3EBF
129
+ C32F243D65DC7E9F4B0216AB7FB96B4D
130
+ )
131
+ CIPHER = %W(
132
+ 588C979A61C663D2F066D0C2C0F989806D5F6B61DAC384
133
+ 72C91A36E135F8CF291CA894085C87E3CC15C439C9E43A3B
134
+ 51B1E5F44A197D1DA46B0F8E2D282AE871E838BB64DA859657
135
+ A28C6865939A9A79FAAA5C4C2A9D4A91CDAC8C
136
+ DCF1FB7B5D9E23FB9D4E131253658AD86EBDCA3E
137
+ 6FC1B011F006568B5171A42D953D469B2570A4BD87
138
+ 0135D1B2C95F41D5D1D4FEC185D166B8094E999DFED96C
139
+ 7B75399AC0831DD2F0BBD75879A2FD8F6CAE6B6CD9B7DB24
140
+ 82531A60CC24945A4B8279181AB5C84DF21CE7F9B73F42E197
141
+ 07342594157785152B074098330ABB141B947B
142
+ 676BB20380B0E301E8AB79590A396DA78B834934
143
+ C0FFA0D6F05BDB67F24D43A4338D2AA4BED7B20E43
144
+ 4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8
145
+ 4CCB1E7CA981BEFAA0726C55D378061298C85C92814ABC33
146
+ B1D23A2220DDC0AC900D9AA03C61FCF4A559A4417767089708
147
+ 14D253C3967B70609B7CBB7C49916028324526
148
+ 5545FF1A085EE2EFBF52B2E04BEE1E2336C73E3F
149
+ 009769ECABDF48625594C59251E6035722675E04C8
150
+ BC218DAA947427B6DB386A99AC1AEF23ADE0B52939CB6A
151
+ 5810E6FD25874022E80361A478E3E9CF484AB04F447EFFF6
152
+ F2BEED7BC5098E83FEB5B31608F8E29C38819A89C8E776F154
153
+ 31D750A09DA3ED7FDDD49A2032AABF17EC8EBF
154
+ E882F1DBD38CE3EDA7C23F04DD65071EB41342AC
155
+ F32905B88A641B04B9C9FFB58CC390900F3DA12AB1
156
+ )
157
+ MAC = %W(
158
+ 17E8D12CFDF926E0
159
+ A091D56E10400916
160
+ 4ADAA76FBD9FB0C5
161
+ 96C861B9C9E61EF1
162
+ 51E83F077D9C2D93
163
+ 405A0443AC91CB94
164
+ 048C56602C97ACBB7490
165
+ C17B4433F434963F34B4
166
+ EA9C07E56B5EB17E5F4E
167
+ 566AA9406B4D999988DD
168
+ F53AA2E9107A8B6C022C
169
+ CD1AA31662E7AD65D6DB
170
+ E78CF7CB0CDDD7B3
171
+ C52EE81D7D77C08A
172
+ A776796EDB723506
173
+ 9A6F49975BCADEAF
174
+ 762C0C7744FE7E3C
175
+ 47099E5AE0704551
176
+ 637CF9BEC2408897C6BA
177
+ F0A477CC2FC9BF548944
178
+ 4D4151A4ED3A8B87B9CE
179
+ 7D22C8088C666BE5C197
180
+ DF7E00DCCEC7AE52987D
181
+ 6DCE9E82EFA16DA62059
182
+ )
183
+
184
+ def test_aes_init
185
+ assert_raise(OpenSSL::CCMError) { OpenSSL::CCM.new('', 'A' * 16, 8) }
186
+ assert_raise(OpenSSL::CCMError) { OpenSSL::CCM.new('AE', 'A' * 16, 8) }
187
+
188
+ assert_raise(OpenSSL::CCMError) { OpenSSL::CCM.new('AES', '', 8) }
189
+ assert_raise(OpenSSL::CCMError) { OpenSSL::CCM.new('AES', 'A', 8) }
190
+ assert_raise(OpenSSL::CCMError) { OpenSSL::CCM.new('AES', 'A' * 15, 8) }
191
+
192
+ 3.step(17, 2) do |l|
193
+ assert_raise(OpenSSL::CCMError) { OpenSSL::CCM.new('AES', 'A' * 16, l) }
194
+ end
195
+ end
196
+
197
+ def test_aes_padding
198
+ ccm = OpenSSL::CCM.new('AES', 'A' * 16, 8)
199
+
200
+ assert_equal(''.b , ccm.send(:padding, '').b)
201
+ assert_equal("\x00".b , ccm.send(:padding, 'A' * 15).b)
202
+ assert_equal(''.b , ccm.send(:padding, 'A' * 16).b)
203
+ assert_equal(("\x00" * 15).b, ccm.send(:padding, 'A').b)
204
+ end
205
+
206
+ def test_aes_valid
207
+ ccm = OpenSSL::CCM.new('AES', 'A' * 16, 8)
208
+
209
+ assert(ccm.send(:valid?, '', 'A' * 13, ''))
210
+ assert(ccm.send(:valid?, 'A' * (256**2 - 1), 'A' * 13, ''))
211
+ assert_raise(OpenSSL::CCMError) do
212
+ ccm.send(:valid?, 'A' * 256**2, 'A' * 13, '')
213
+ end
214
+
215
+ assert_raise OpenSSL::CCMError do
216
+ ccm.send(:valid?, 'Hello!', 'A' * 6, '')
217
+ end
218
+ assert(ccm.send(:valid?, '', 'A' * 7, ''))
219
+ assert(ccm.send(:valid?, '', 'A' * 13, ''))
220
+ assert_raise OpenSSL::CCMError do
221
+ ccm.send(:valid?, 'Hello!', 'A' * 14, '')
222
+ end
223
+ end
224
+
225
+ def test_aes_vectors
226
+ assert(OpenSSL::CCM.ciphers.include?('AES'), 'Missing AES-Cipher')
227
+ KEY.length.times do |i|
228
+ ccm = OpenSSL::CCM.new('AES', [KEY[i]].pack('H*'),
229
+ [MAC[i]].pack('H*').b.length)
230
+
231
+ c = ccm.send(:get_counter, [NONCE[i]].pack('H*'), 1)
232
+ assert_equal(CTR0001[i], c.unpack('H*')[0].upcase,
233
+ "Wrong CTR0001 in Vector #{i + 1}")
234
+
235
+ c = ccm.send(:get_counter, [NONCE[i]].pack('H*'), 2)
236
+ assert_equal(CTR0002[i], c.unpack('H*')[0].upcase,
237
+ "Wrong CTR0002 in Vector #{i + 1}")
238
+
239
+ c = ccm.send(:crypt, [DATA[i]].pack('H*'), [NONCE[i]].pack('H*'))
240
+ assert_equal(CIPHER[i], c.unpack('H*')[0].upcase,
241
+ "Wrong CIPHER in Vector #{i + 1}")
242
+
243
+ c = ccm.send(:mac,
244
+ [DATA[i]].pack('H*'),
245
+ [NONCE[i]].pack('H*'),
246
+ [ADD_DATA[i]].pack('H*'))
247
+ assert_equal(MAC[i], c.unpack('H*')[0].upcase,
248
+ "Wrong MAC in Vector #{i + 1}")
249
+
250
+ c = ccm.send(:encrypt,
251
+ [DATA[i]].pack('H*'),
252
+ [NONCE[i]].pack('H*'),
253
+ [ADD_DATA[i]].pack('H*'))
254
+ assert_equal((CIPHER[i] + MAC[i]), c.unpack('H*')[0].upcase,
255
+ "Wrong ENCRYPT in Vector #{i + 1}")
256
+
257
+ c = ccm.send(:decrypt,
258
+ [CIPHER[i] + MAC[i]].pack('H*'),
259
+ [NONCE[i]].pack('H*'),
260
+ [ADD_DATA[i]].pack('H*'))
261
+ assert_equal(DATA[i], c.unpack('H*')[0].upcase,
262
+ "Wrong ENCRYPT in Vector #{i + 1}")
263
+ end
264
+ end
265
+ end
@@ -0,0 +1,37 @@
1
+ require 'test/unit'
2
+ require 'openssl-ccm'
3
+
4
+ # Testclass
5
+ class CCMFilesTest < Test::Unit::TestCase
6
+ KEY = %W(
7
+ 00000000000000000000000000000000
8
+ 001234567890ABCDEFDCAFFEED3921EE
9
+ 001234567890ABCDEFDCAFFEED3921EE
10
+ 11223344AABB00000000000000000000
11
+ )
12
+ NONCE = %W(
13
+ 00000000000000000000000000
14
+ 00112233445566778899
15
+ 001122334455667788990000
16
+ 00112233445566778899
17
+ )
18
+ MAC_LEN = [16, 8, 14, 8]
19
+
20
+ def test_aes
21
+ assert(OpenSSL::CCM.ciphers.include?('AES'), 'Missing AES-Cipher')
22
+ 1.upto(3) do |i|
23
+ open("test/data_#{i}", mode = 'r') do |i_file|
24
+ input = i_file.read
25
+ KEY.length.times do |j|
26
+ open("test/data_#{i}-#{j + 1}_e", mode = 'r') do |o_file|
27
+ output = o_file.read
28
+ ccm = OpenSSL::CCM.new('AES', [KEY[j]].pack('H*'), MAC_LEN[j])
29
+ c = ccm.encrypt(input, [NONCE[j]].pack('H*'))
30
+ assert_equal(output.unpack('H*'), c.unpack('H*'),
31
+ "Wrong ENCRYPT in Vector #{i + 1}")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: openssl-ccm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Lars Schmertmann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 4.1.1
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 4.1.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: yard
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.8'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.8.7.3
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.8'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.8.7.3
53
+ - !ruby/object:Gem::Dependency
54
+ name: rubocop
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.18'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.18.1
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.18'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.18.1
73
+ description: Ruby Gem for RFC 3610 - Counter with CBC-MAC (CCM)
74
+ email: SmallLars@t-online.de
75
+ executables: []
76
+ extensions: []
77
+ extra_rdoc_files:
78
+ - README.md
79
+ - LICENSE
80
+ files:
81
+ - Gemfile
82
+ - LICENSE
83
+ - README.md
84
+ - Rakefile
85
+ - lib/openssl-ccm.rb
86
+ - test/data_1
87
+ - test/data_1-1_e
88
+ - test/data_1-2_e
89
+ - test/data_1-3_e
90
+ - test/data_1-4_e
91
+ - test/data_2
92
+ - test/data_2-1_e
93
+ - test/data_2-2_e
94
+ - test/data_2-3_e
95
+ - test/data_2-4_e
96
+ - test/data_3
97
+ - test/data_3-1_e
98
+ - test/data_3-2_e
99
+ - test/data_3-3_e
100
+ - test/data_3-4_e
101
+ - test/test_ccm.rb
102
+ - test/test_ccm_data.rb
103
+ homepage: ''
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message: Thanks for installing!
108
+ rdoc_options:
109
+ - "-x"
110
+ - test/data_*
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 2.0.0
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.2.2
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: RFC 3610 - CCM
129
+ test_files:
130
+ - test/test_ccm.rb
131
+ - test/test_ccm_data.rb
132
+ - test/data_1-3_e
133
+ - test/data_1-1_e
134
+ - test/data_3
135
+ - test/data_3-4_e
136
+ - test/data_3-2_e
137
+ - test/data_2-2_e
138
+ - test/data_1-2_e
139
+ - test/data_1-4_e
140
+ - test/data_3-1_e
141
+ - test/data_3-3_e
142
+ - test/data_1
143
+ - test/data_2
144
+ - test/data_2-4_e
145
+ - test/data_2-1_e
146
+ - test/data_2-3_e
147
+ has_rdoc: