openssl-ccm 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|