yubikey 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -0
- data/lib/yubikey.rb +3 -1
- data/lib/yubikey/modhex.rb +9 -19
- data/lib/yubikey/otp.rb +18 -15
- metadata +16 -15
- data/ext/yubikey_ext/extconf.rb +0 -7
- data/ext/yubikey_ext/ykaes.c +0 -214
- data/ext/yubikey_ext/ykcrc.c +0 -54
- data/ext/yubikey_ext/yubikey.h +0 -58
- data/ext/yubikey_ext/yubikey_ext.c +0 -53
- data/spec/yubikey_ext_spec.rb +0 -32
data/README.rdoc
CHANGED
data/lib/yubikey.rb
CHANGED
@@ -2,9 +2,11 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
4
|
require 'net/http'
|
5
|
+
require 'crypt/rijndael'
|
5
6
|
require 'openssl'
|
6
7
|
|
7
|
-
|
8
|
+
module Yubikey; end;
|
9
|
+
|
8
10
|
require 'yubikey/hex'
|
9
11
|
require 'yubikey/modhex'
|
10
12
|
require 'yubikey/otp'
|
data/lib/yubikey/modhex.rb
CHANGED
@@ -4,36 +4,26 @@ module Yubikey::ModHex
|
|
4
4
|
|
5
5
|
# Decode a ModHex string into binary data
|
6
6
|
def self.decode(modhex_string)
|
7
|
-
out = ''
|
8
|
-
flag = true # to switch between first and last nibble
|
9
|
-
byte = 0
|
10
|
-
|
11
7
|
raise ArgumentError, "ModHex string length is not even" unless modhex_string.length % 2 == 0
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
else
|
18
|
-
byte = (byte << 4) | x
|
19
|
-
out <<= byte.chr
|
20
|
-
end
|
21
|
-
flag = !flag
|
9
|
+
chars = 'cbdefghijklnrtuv'
|
10
|
+
result = ""
|
11
|
+
modhex_string.scan(/../).each do |c|
|
12
|
+
result += (chars.index(c[0]) * 16 + chars.index(c[1])).chr
|
22
13
|
end
|
23
|
-
|
24
|
-
out
|
14
|
+
result
|
25
15
|
end
|
26
16
|
|
27
17
|
# Encode a binary string into ModHex
|
28
18
|
def self.encode(string)
|
29
|
-
|
19
|
+
result = ''
|
30
20
|
|
31
21
|
string.each_byte do |b|
|
32
|
-
|
33
|
-
|
22
|
+
result <<= TRANS[(b >> 4) & 0xF]
|
23
|
+
result <<= TRANS[b & 0xF]
|
34
24
|
end
|
35
25
|
|
36
|
-
|
26
|
+
result
|
37
27
|
end
|
38
28
|
|
39
29
|
end # Yubikey::ModHex
|
data/lib/yubikey/otp.rb
CHANGED
@@ -22,7 +22,7 @@ class Yubikey::OTP
|
|
22
22
|
# [+otp+] ModHex encoded Yubikey OTP (at least 32 characters)
|
23
23
|
# [+key+] 32-character hex AES key
|
24
24
|
def initialize(otp, key)
|
25
|
-
raise InvalidOTPError, 'OTP must be
|
25
|
+
raise InvalidOTPError, 'OTP must be at least 32 characters of modhex' unless otp.modhex? && otp.length >= 32
|
26
26
|
raise InvalidKeyError, 'Key must be 32 hex characters' unless key.hex? && key.length == 32
|
27
27
|
|
28
28
|
@public_id = otp[0,otp.length-32] if otp.length > 32
|
@@ -30,24 +30,27 @@ class Yubikey::OTP
|
|
30
30
|
@token = Yubikey::ModHex.decode(otp[-32,32])
|
31
31
|
@aes_key = key.to_bin
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
@token = Crypt::Rijndael.new(@aes_key, 128).decrypt_block(@token)
|
34
|
+
|
35
|
+
raise BadCRCError unless crc_valid?
|
36
|
+
|
37
|
+
@secret_id, @insert_counter, @timestamp, @timestamp_lo, @session_counter, @random_number, @crc = @token.unpack('H12vvCCvv')
|
38
|
+
@timestamp += @timestamp_lo * 65536
|
35
39
|
end
|
36
40
|
|
37
41
|
private
|
38
42
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@random_number = @token[13] * 256 + @token[12]
|
43
|
+
def crc_valid?
|
44
|
+
crc = 0xffff
|
45
|
+
@token.each_byte do |b|
|
46
|
+
crc ^= b & 0xff
|
47
|
+
8.times do
|
48
|
+
test = (crc & 1) == 1
|
49
|
+
crc >>= 1
|
50
|
+
crc ^= 0x8408 if test
|
51
|
+
end
|
52
|
+
end
|
53
|
+
crc == 0xf0b8
|
51
54
|
end
|
52
55
|
|
53
56
|
# :stopdoc:
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yubikey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rudenberg
|
@@ -9,27 +9,30 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-08 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: crypt
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
16
25
|
description: A library to verify, decode, decrypt and parse Yubikey one-time passwords.
|
17
26
|
email: jon335@gmail.com
|
18
27
|
executables: []
|
19
28
|
|
20
|
-
extensions:
|
21
|
-
|
29
|
+
extensions: []
|
30
|
+
|
22
31
|
extra_rdoc_files:
|
23
32
|
- LICENSE
|
24
33
|
- README.rdoc
|
25
|
-
- ext/yubikey_ext/yubikey_ext.c
|
26
34
|
files:
|
27
35
|
- examples/otp.rb
|
28
|
-
- ext/yubikey_ext/extconf.rb
|
29
|
-
- ext/yubikey_ext/ykaes.c
|
30
|
-
- ext/yubikey_ext/ykcrc.c
|
31
|
-
- ext/yubikey_ext/yubikey.h
|
32
|
-
- ext/yubikey_ext/yubikey_ext.c
|
33
36
|
- lib/yubikey.rb
|
34
37
|
- lib/yubikey/hex.rb
|
35
38
|
- lib/yubikey/modhex.rb
|
@@ -38,7 +41,6 @@ files:
|
|
38
41
|
- spec/hex_spec.rb
|
39
42
|
- spec/spec.opts
|
40
43
|
- spec/spec_helper.rb
|
41
|
-
- spec/yubikey_ext_spec.rb
|
42
44
|
- spec/yubikey_modhex_spec.rb
|
43
45
|
- spec/yubikey_otp_spec.rb
|
44
46
|
- spec/yubikey_otp_verify_spec.rb
|
@@ -72,14 +74,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
74
|
requirements: []
|
73
75
|
|
74
76
|
rubyforge_project: yubikey
|
75
|
-
rubygems_version: 1.3.
|
77
|
+
rubygems_version: 1.3.5
|
76
78
|
signing_key:
|
77
79
|
specification_version: 3
|
78
80
|
summary: A library to verify, decode, decrypt and parse Yubikey one-time passwords.
|
79
81
|
test_files:
|
80
82
|
- spec/hex_spec.rb
|
81
83
|
- spec/spec_helper.rb
|
82
|
-
- spec/yubikey_ext_spec.rb
|
83
84
|
- spec/yubikey_modhex_spec.rb
|
84
85
|
- spec/yubikey_otp_spec.rb
|
85
86
|
- spec/yubikey_otp_verify_spec.rb
|
data/ext/yubikey_ext/extconf.rb
DELETED
data/ext/yubikey_ext/ykaes.c
DELETED
@@ -1,214 +0,0 @@
|
|
1
|
-
/* ykaes.c --- Implementation of AES-128.
|
2
|
-
*
|
3
|
-
* Copyright (c) 2006, 2007, 2008, 2009 Yubico AB
|
4
|
-
* All rights reserved.
|
5
|
-
*
|
6
|
-
* Redistribution and use in source and binary forms, with or without
|
7
|
-
* modification, are permitted provided that the following conditions are
|
8
|
-
* met:
|
9
|
-
*
|
10
|
-
* * Redistributions of source code must retain the above copyright
|
11
|
-
* notice, this list of conditions and the following disclaimer.
|
12
|
-
*
|
13
|
-
* * Redistributions in binary form must reproduce the above
|
14
|
-
* copyright notice, this list of conditions and the following
|
15
|
-
* disclaimer in the documentation and/or other materials provided
|
16
|
-
* with the distribution.
|
17
|
-
*
|
18
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
-
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
-
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
-
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
-
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
-
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24
|
-
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
-
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
26
|
-
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
-
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*
|
30
|
-
*/
|
31
|
-
|
32
|
-
#include "yubikey.h"
|
33
|
-
|
34
|
-
#define NUMBER_OF_ROUNDS 10
|
35
|
-
|
36
|
-
static const uint8_t RC[] =
|
37
|
-
{ 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 };
|
38
|
-
|
39
|
-
static const uint8_t rijndael_sbox[] = {
|
40
|
-
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
|
41
|
-
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
42
|
-
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
|
43
|
-
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
44
|
-
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
|
45
|
-
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
46
|
-
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
|
47
|
-
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
48
|
-
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
|
49
|
-
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
50
|
-
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
|
51
|
-
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
52
|
-
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
|
53
|
-
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
54
|
-
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
|
55
|
-
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
56
|
-
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
|
57
|
-
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
58
|
-
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
|
59
|
-
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
60
|
-
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
|
61
|
-
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
62
|
-
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
|
63
|
-
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
64
|
-
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
|
65
|
-
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
66
|
-
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
|
67
|
-
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
68
|
-
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
|
69
|
-
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
70
|
-
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
|
71
|
-
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
72
|
-
};
|
73
|
-
|
74
|
-
static const uint8_t rijndael_inv_sbox[] = {
|
75
|
-
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
|
76
|
-
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
77
|
-
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
|
78
|
-
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
|
79
|
-
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
|
80
|
-
0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
|
81
|
-
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
|
82
|
-
0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
|
83
|
-
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
|
84
|
-
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
|
85
|
-
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
|
86
|
-
0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
|
87
|
-
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
|
88
|
-
0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
|
89
|
-
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
|
90
|
-
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
|
91
|
-
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
|
92
|
-
0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
|
93
|
-
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
|
94
|
-
0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
|
95
|
-
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
|
96
|
-
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
|
97
|
-
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
|
98
|
-
0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
|
99
|
-
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
|
100
|
-
0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
|
101
|
-
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
|
102
|
-
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
|
103
|
-
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
|
104
|
-
0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
|
105
|
-
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
|
106
|
-
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
107
|
-
};
|
108
|
-
|
109
|
-
static inline uint8_t
|
110
|
-
xtime (uint8_t b)
|
111
|
-
{
|
112
|
-
return (b & 0x80) ? ((b << 1) ^ 0x1b) : (b << 1);
|
113
|
-
}
|
114
|
-
|
115
|
-
void
|
116
|
-
yubikey_aes_decrypt (uint8_t * state, const uint8_t * key)
|
117
|
-
{
|
118
|
-
uint8_t i, j, round_key[0x10];
|
119
|
-
uint8_t a02x, a13x;
|
120
|
-
uint8_t a02xx, a13xx;
|
121
|
-
uint8_t k1, k2;
|
122
|
-
|
123
|
-
memcpy (round_key, key, sizeof (round_key));
|
124
|
-
for (i = 0; i < NUMBER_OF_ROUNDS; i++)
|
125
|
-
{
|
126
|
-
round_key[0] ^= RC[i];
|
127
|
-
|
128
|
-
round_key[0] ^= rijndael_sbox[round_key[13]];
|
129
|
-
round_key[1] ^= rijndael_sbox[round_key[14]];
|
130
|
-
round_key[2] ^= rijndael_sbox[round_key[15]];
|
131
|
-
round_key[3] ^= rijndael_sbox[round_key[12]];
|
132
|
-
|
133
|
-
for (j = 4; j < 16; j++)
|
134
|
-
round_key[j] ^= round_key[j - 4];
|
135
|
-
}
|
136
|
-
for (i = 0; i < 0x10; i++)
|
137
|
-
state[i] ^= round_key[i];
|
138
|
-
|
139
|
-
for (i = 1; i <= NUMBER_OF_ROUNDS; i++)
|
140
|
-
{
|
141
|
-
// inv_byte_sub_shift_row();
|
142
|
-
|
143
|
-
/* First row: 0 shift, 0 4 8 12 */
|
144
|
-
state[0] = rijndael_inv_sbox[state[0]];
|
145
|
-
state[4] = rijndael_inv_sbox[state[4]];
|
146
|
-
state[8] = rijndael_inv_sbox[state[8]];
|
147
|
-
state[12] = rijndael_inv_sbox[state[12]];
|
148
|
-
|
149
|
-
/* Second row: -1 shift, 1 5 9 13 */
|
150
|
-
j = state[13];
|
151
|
-
state[13] = rijndael_inv_sbox[state[9]];
|
152
|
-
state[9] = rijndael_inv_sbox[state[5]];
|
153
|
-
state[5] = rijndael_inv_sbox[state[1]];
|
154
|
-
state[1] = rijndael_inv_sbox[j];
|
155
|
-
|
156
|
-
/* Third row: -2 shift, 2 6 10 14 */
|
157
|
-
j = state[2];
|
158
|
-
state[2] = rijndael_inv_sbox[state[10]];
|
159
|
-
state[10] = rijndael_inv_sbox[j];
|
160
|
-
j = state[6];
|
161
|
-
state[6] = rijndael_inv_sbox[state[14]];
|
162
|
-
state[14] = rijndael_inv_sbox[j];
|
163
|
-
|
164
|
-
/* Fourth row: -3 shift, 3 7 11 15 */
|
165
|
-
j = state[3];
|
166
|
-
state[3] = rijndael_inv_sbox[state[7]];
|
167
|
-
state[7] = rijndael_inv_sbox[state[11]];
|
168
|
-
state[11] = rijndael_inv_sbox[state[15]];
|
169
|
-
state[15] = rijndael_inv_sbox[j];
|
170
|
-
|
171
|
-
// get_inv_round_key(i);
|
172
|
-
|
173
|
-
for (j = 15; j > 3; j--)
|
174
|
-
round_key[j] ^= round_key[j - 4];
|
175
|
-
|
176
|
-
round_key[0] ^=
|
177
|
-
(RC[NUMBER_OF_ROUNDS - i] ^ rijndael_sbox[round_key[13]]);
|
178
|
-
|
179
|
-
round_key[1] ^= rijndael_sbox[round_key[14]];
|
180
|
-
round_key[2] ^= rijndael_sbox[round_key[15]];
|
181
|
-
round_key[3] ^= rijndael_sbox[round_key[12]];
|
182
|
-
|
183
|
-
for (j = 0; j < 16; j++)
|
184
|
-
state[j] ^= round_key[j];
|
185
|
-
if (i != NUMBER_OF_ROUNDS)
|
186
|
-
{
|
187
|
-
|
188
|
-
//inv_mix_column();
|
189
|
-
|
190
|
-
for (j = 0; j < 16; j += 4)
|
191
|
-
{
|
192
|
-
k1 = state[j] ^ state[j + 2];
|
193
|
-
a02x = xtime (k1);
|
194
|
-
k2 = state[j + 1] ^ state[j + 3];
|
195
|
-
a13x = xtime (k2);
|
196
|
-
|
197
|
-
k1 ^= (k2 ^ xtime (state[j + 1] ^ state[j + 2]));
|
198
|
-
k2 = k1;
|
199
|
-
|
200
|
-
a02xx = xtime (a02x);
|
201
|
-
a13xx = xtime (a13x);
|
202
|
-
|
203
|
-
k1 ^= (xtime (a02xx ^ a13xx) ^ a02xx);
|
204
|
-
k2 ^= (xtime (a02xx ^ a13xx) ^ a13xx);
|
205
|
-
|
206
|
-
state[j] ^= (k1 ^ a02x);
|
207
|
-
state[j + 1] ^= k2;
|
208
|
-
state[j + 2] ^= (k1 ^ a13x);
|
209
|
-
state[j + 3] ^= (k2 ^ a02x ^ a13x);
|
210
|
-
}
|
211
|
-
}
|
212
|
-
|
213
|
-
}
|
214
|
-
}
|
data/ext/yubikey_ext/ykcrc.c
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
/* ykcrc.c --- Implementation of Yubikey CRC-16 function.
|
2
|
-
*
|
3
|
-
* Written by Simon Josefsson <simon@josefsson.org>.
|
4
|
-
* Copyright (c) 2006, 2007, 2008, 2009 Yubico AB
|
5
|
-
* All rights reserved.
|
6
|
-
*
|
7
|
-
* Redistribution and use in source and binary forms, with or without
|
8
|
-
* modification, are permitted provided that the following conditions are
|
9
|
-
* met:
|
10
|
-
*
|
11
|
-
* * Redistributions of source code must retain the above copyright
|
12
|
-
* notice, this list of conditions and the following disclaimer.
|
13
|
-
*
|
14
|
-
* * Redistributions in binary form must reproduce the above
|
15
|
-
* copyright notice, this list of conditions and the following
|
16
|
-
* disclaimer in the documentation and/or other materials provided
|
17
|
-
* with the distribution.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
-
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
-
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
22
|
-
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
-
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
-
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
25
|
-
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
26
|
-
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
27
|
-
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
28
|
-
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
-
*
|
31
|
-
*/
|
32
|
-
|
33
|
-
#include "yubikey.h"
|
34
|
-
|
35
|
-
uint16_t
|
36
|
-
yubikey_crc16 (const uint8_t *buf, size_t buf_size)
|
37
|
-
{
|
38
|
-
uint16_t m_crc = 0xffff;
|
39
|
-
|
40
|
-
while (buf_size--)
|
41
|
-
{
|
42
|
-
int i, j;
|
43
|
-
m_crc ^= (uint8_t) * buf++ & 0xFF;
|
44
|
-
for (i = 0; i < 8; i++)
|
45
|
-
{
|
46
|
-
j = m_crc & 1;
|
47
|
-
m_crc >>= 1;
|
48
|
-
if (j)
|
49
|
-
m_crc ^= 0x8408;
|
50
|
-
}
|
51
|
-
}
|
52
|
-
|
53
|
-
return m_crc;
|
54
|
-
}
|
data/ext/yubikey_ext/yubikey.h
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
/* yubikey.h --- Prototypes for low-level Yubikey OTP functions.
|
2
|
-
*
|
3
|
-
* Written by Simon Josefsson <simon@josefsson.org>.
|
4
|
-
* Copyright (c) 2006, 2007, 2008, 2009 Yubico AB
|
5
|
-
* All rights reserved.
|
6
|
-
*
|
7
|
-
* Redistribution and use in source and binary forms, with or without
|
8
|
-
* modification, are permitted provided that the following conditions are
|
9
|
-
* met:
|
10
|
-
*
|
11
|
-
* * Redistributions of source code must retain the above copyright
|
12
|
-
* notice, this list of conditions and the following disclaimer.
|
13
|
-
*
|
14
|
-
* * Redistributions in binary form must reproduce the above
|
15
|
-
* copyright notice, this list of conditions and the following
|
16
|
-
* disclaimer in the documentation and/or other materials provided
|
17
|
-
* with the distribution.
|
18
|
-
*
|
19
|
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
-
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
-
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
22
|
-
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
-
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
-
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
25
|
-
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
26
|
-
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
27
|
-
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
28
|
-
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
-
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
-
*
|
31
|
-
*/
|
32
|
-
|
33
|
-
#ifndef YUBIKEY_H
|
34
|
-
#define YUBIKEY_H
|
35
|
-
|
36
|
-
#include <stdint.h>
|
37
|
-
#include <string.h>
|
38
|
-
|
39
|
-
#define YUBIKEY_BLOCK_SIZE 16
|
40
|
-
#define YUBIKEY_KEY_SIZE 16
|
41
|
-
#define YUBIKEY_UID_SIZE 6
|
42
|
-
|
43
|
-
#define YUBIKEY_CRC_OK_RESIDUE 0xf0b8
|
44
|
-
|
45
|
-
#define yubikey_crc_ok_p(tok) (yubikey_crc16 ((tok), YUBIKEY_BLOCK_SIZE) == YUBIKEY_CRC_OK_RESIDUE)
|
46
|
-
|
47
|
-
/* Low-level functions; AES. */
|
48
|
-
|
49
|
-
/* AES-decrypt one 16-byte block STATE using the 128-bit KEY, leaving
|
50
|
-
the decrypted output in the STATE buffer. */
|
51
|
-
void yubikey_aes_decrypt(uint8_t *state, const uint8_t *key);
|
52
|
-
|
53
|
-
/*
|
54
|
-
* Low-level functions; CRC.
|
55
|
-
*/
|
56
|
-
uint16_t yubikey_crc16 (const uint8_t *buf, size_t buf_size);
|
57
|
-
|
58
|
-
#endif
|
@@ -1,53 +0,0 @@
|
|
1
|
-
#include "ruby.h"
|
2
|
-
#include "yubikey.h"
|
3
|
-
|
4
|
-
/*
|
5
|
-
* call-seq:
|
6
|
-
* decrypt(state, key) -> plaintext
|
7
|
-
*
|
8
|
-
* Decrypt 16 bytes of binary AES ciphertext to binary plaintext with the Yubico implementation of AES-128 ECB
|
9
|
-
*
|
10
|
-
* [+state+] 16 bytes of binary ciphertext
|
11
|
-
* [+key+] 16-byte binary key
|
12
|
-
*
|
13
|
-
*/
|
14
|
-
static VALUE
|
15
|
-
aes_decrypt(VALUE self, VALUE state, VALUE key) {
|
16
|
-
char* state_ptr = StringValuePtr(state);
|
17
|
-
char* key_ptr = StringValuePtr(key);
|
18
|
-
|
19
|
-
if (RSTRING(state)->len != YUBIKEY_BLOCK_SIZE || RSTRING(key)->len != YUBIKEY_KEY_SIZE)
|
20
|
-
rb_raise(rb_eArgError, "key and state must be 16 bytes");
|
21
|
-
|
22
|
-
yubikey_aes_decrypt((uint8_t*)state_ptr, (uint8_t*)key_ptr);
|
23
|
-
|
24
|
-
return rb_str_new(state_ptr, YUBIKEY_BLOCK_SIZE);
|
25
|
-
}
|
26
|
-
|
27
|
-
/*
|
28
|
-
* call-seq:
|
29
|
-
* valid?(token)
|
30
|
-
*
|
31
|
-
* Check the CRC of a decrypted Yubikey OTP
|
32
|
-
*
|
33
|
-
* [+token+] 16-byte binary token
|
34
|
-
*/
|
35
|
-
static VALUE
|
36
|
-
crc_check(VALUE self, VALUE token) {
|
37
|
-
char* token_ptr = StringValuePtr(token);
|
38
|
-
|
39
|
-
if (RSTRING(token)->len != YUBIKEY_BLOCK_SIZE)
|
40
|
-
rb_raise(rb_eArgError, "token must be 16 bytes");
|
41
|
-
|
42
|
-
return yubikey_crc_ok_p((uint8_t*)token_ptr) ? Qtrue : Qfalse;
|
43
|
-
}
|
44
|
-
|
45
|
-
void
|
46
|
-
Init_yubikey_ext() {
|
47
|
-
VALUE rb_mYubikey = rb_define_module("Yubikey");
|
48
|
-
VALUE rb_mYubikeyAES = rb_define_module_under(rb_mYubikey, "AES");
|
49
|
-
VALUE rb_mYubikeyCRC = rb_define_module_under(rb_mYubikey, "CRC");
|
50
|
-
|
51
|
-
rb_define_module_function(rb_mYubikeyAES, "decrypt", aes_decrypt, 2);
|
52
|
-
rb_define_module_function(rb_mYubikeyCRC, "valid?", crc_check, 1);
|
53
|
-
}
|
data/spec/yubikey_ext_spec.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
|
3
|
-
$:.unshift File.dirname(__FILE__) + '/../ext/yubikey_ext'
|
4
|
-
require 'yubikey_ext.so'
|
5
|
-
|
6
|
-
describe 'yubikey_ext' do
|
7
|
-
it 'should decrypt aes' do
|
8
|
-
key = '72992427a3b8ccd20697493b5532561f'.to_bin
|
9
|
-
state = 'ddf43aec57366784e061a12f767e728a'.to_bin
|
10
|
-
plain = '619dd70df3b30300de1bdb00ffbf6f26'.to_bin
|
11
|
-
|
12
|
-
Yubikey::AES.decrypt(state, key).should == plain
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should raise if aes key or state length is not 16' do
|
16
|
-
lambda { Yubikey::AES.decrypt("i\266H\034\213\253\242\266\016\217\"\027\233X\315V", 'test') }.
|
17
|
-
should raise_error(ArgumentError)
|
18
|
-
|
19
|
-
lambda { Yubikey::AES.decrypt('test', "\354\336\030\333\347o\275\f33\017\0345Hq\333") }.
|
20
|
-
should raise_error(ArgumentError)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should check a crc' do
|
24
|
-
Yubikey::CRC.valid?('619dd70df3b30300de1bdb00ffbf6f26'.to_bin).should == true
|
25
|
-
Yubikey::CRC.valid?('ddf43aec57366784e061a12f767e728a'.to_bin).should == false
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should raise if crc token length not 16' do
|
29
|
-
lambda { Yubikey::CRC.valid?('619dd70df3b30300de1bdb00ffbf6f'.to_bin) }.
|
30
|
-
should raise_error(ArgumentError)
|
31
|
-
end
|
32
|
-
end
|