openssl-ccm 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +4 -0
- data/Rakefile +31 -0
- data/lib/openssl-ccm.rb +164 -0
- data/test/data_1 +0 -0
- data/test/data_1-1_e +1 -0
- data/test/data_1-2_e +1 -0
- data/test/data_1-3_e +1 -0
- data/test/data_1-4_e +1 -0
- data/test/data_2 +2 -0
- data/test/data_2-1_e +0 -0
- data/test/data_2-2_e +1 -0
- data/test/data_2-3_e +1 -0
- data/test/data_2-4_e +2 -0
- data/test/data_3 +0 -0
- data/test/data_3-1_e +0 -0
- data/test/data_3-2_e +0 -0
- data/test/data_3-3_e +0 -0
- data/test/data_3-4_e +0 -0
- data/test/test_ccm.rb +265 -0
- data/test/test_ccm_data.rb +37 -0
- metadata +147 -0
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
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
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
|
data/lib/openssl-ccm.rb
ADDED
@@ -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
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
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:
|