costan-tem_ruby 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +45 -0
- data/LICENSE +21 -0
- data/Manifest +75 -0
- data/README +8 -0
- data/Rakefile +23 -0
- data/bin/tem_bench +9 -0
- data/bin/tem_ca +13 -0
- data/bin/tem_irb +11 -0
- data/bin/tem_proxy +65 -0
- data/bin/tem_stat +35 -0
- data/dev_ca/ca_cert.cer +0 -0
- data/dev_ca/ca_cert.pem +32 -0
- data/dev_ca/ca_key.pem +27 -0
- data/dev_ca/config.yml +14 -0
- data/lib/tem/_cert.rb +158 -0
- data/lib/tem/apdus/buffers.rb +89 -0
- data/lib/tem/apdus/keys.rb +64 -0
- data/lib/tem/apdus/lifecycle.rb +13 -0
- data/lib/tem/apdus/tag.rb +38 -0
- data/lib/tem/auto_conf.rb +25 -0
- data/lib/tem/builders/abi.rb +482 -0
- data/lib/tem/builders/assembler.rb +314 -0
- data/lib/tem/builders/crypto.rb +124 -0
- data/lib/tem/builders/isa.rb +120 -0
- data/lib/tem/ca.rb +114 -0
- data/lib/tem/definitions/abi.rb +65 -0
- data/lib/tem/definitions/assembler.rb +23 -0
- data/lib/tem/definitions/isa.rb +188 -0
- data/lib/tem/ecert.rb +77 -0
- data/lib/tem/hive.rb +18 -0
- data/lib/tem/keys/asymmetric.rb +116 -0
- data/lib/tem/keys/key.rb +48 -0
- data/lib/tem/keys/symmetric.rb +47 -0
- data/lib/tem/sec_exec_error.rb +63 -0
- data/lib/tem/seclosures.rb +81 -0
- data/lib/tem/secpack.rb +107 -0
- data/lib/tem/tem.rb +31 -0
- data/lib/tem/toolkit.rb +101 -0
- data/lib/tem/transport/auto_configurator.rb +87 -0
- data/lib/tem/transport/java_card_mixin.rb +99 -0
- data/lib/tem/transport/jcop_remote_protocol.rb +59 -0
- data/lib/tem/transport/jcop_remote_server.rb +171 -0
- data/lib/tem/transport/jcop_remote_transport.rb +65 -0
- data/lib/tem/transport/pcsc_transport.rb +87 -0
- data/lib/tem/transport/transport.rb +10 -0
- data/lib/tem_ruby.rb +47 -0
- data/tem_ruby.gemspec +35 -0
- data/test/_test_cert.rb +70 -0
- data/test/builders/test_abi_builder.rb +298 -0
- data/test/tem_test_case.rb +26 -0
- data/test/tem_unit/test_tem_alu.rb +33 -0
- data/test/tem_unit/test_tem_bound_secpack.rb +51 -0
- data/test/tem_unit/test_tem_branching.rb +56 -0
- data/test/tem_unit/test_tem_crypto_asymmetric.rb +123 -0
- data/test/tem_unit/test_tem_crypto_hash.rb +35 -0
- data/test/tem_unit/test_tem_crypto_pstore.rb +53 -0
- data/test/tem_unit/test_tem_crypto_random.rb +25 -0
- data/test/tem_unit/test_tem_emit.rb +23 -0
- data/test/tem_unit/test_tem_memory.rb +48 -0
- data/test/tem_unit/test_tem_memory_compare.rb +65 -0
- data/test/tem_unit/test_tem_output.rb +32 -0
- data/test/tem_unit/test_tem_yaml_secpack.rb +47 -0
- data/test/test_driver.rb +108 -0
- data/test/test_exceptions.rb +35 -0
- data/test/transport/test_auto_configurator.rb +114 -0
- data/test/transport/test_java_card_mixin.rb +90 -0
- data/test/transport/test_jcop_remote.rb +82 -0
- data/timings/blank_bound_secpack.rb +18 -0
- data/timings/blank_sec.rb +14 -0
- data/timings/devchip_decrypt.rb +9 -0
- data/timings/post_buffer.rb +10 -0
- data/timings/simple_apdu.rb +5 -0
- data/timings/timings.rb +64 -0
- data/timings/vm_perf.rb +140 -0
- data/timings/vm_perf_bound.rb +141 -0
- metadata +201 -0
data/lib/tem/ca.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
# Certificate Authority (CA) functionality for TEM manufacturers
|
5
|
+
module Tem::CA
|
6
|
+
# creates an Endorsement Certificate for a TEM's Public Endorsement Key
|
7
|
+
def new_ecert(pubek)
|
8
|
+
ca_cert = Tem::CA.ca_cert
|
9
|
+
ca_key = Tem::CA.ca_key
|
10
|
+
conf = Tem::CA.config
|
11
|
+
|
12
|
+
dn = OpenSSL::X509::Name.new conf[:issuer].merge(conf[:subject]).to_a
|
13
|
+
now = Time.now
|
14
|
+
ecert = OpenSSL::X509::Certificate.new
|
15
|
+
ecert.issuer = ca_cert.subject
|
16
|
+
ecert.subject = dn
|
17
|
+
ecert.not_before = now;
|
18
|
+
ecert.not_after = now + conf[:ecert_validity_days] * 60 * 60 * 24;
|
19
|
+
ecert.public_key = pubek
|
20
|
+
ecert.version = 2
|
21
|
+
cf = OpenSSL::X509::ExtensionFactory.new
|
22
|
+
cf.subject_certificate = ecert
|
23
|
+
cf.issuer_certificate = ca_cert
|
24
|
+
ecert.add_extension cf.create_extension("basicConstraints", "CA:true", true)
|
25
|
+
ecert.add_extension cf.create_extension("authorityKeyIdentifier", "keyid,issuer")
|
26
|
+
ecert.add_extension cf.create_extension("keyUsage", "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign")
|
27
|
+
ecert.add_extension cf.create_extension("extendedKeyUsage", "serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,msCodeInd,msCodeCom,msCTLSign,msSGC,msEFS,nsSGC")
|
28
|
+
ecert.add_extension cf.create_extension("nsCertType", "client,server,email,objsign,sslCA,emailCA,objCA")
|
29
|
+
ecert.add_extension cf.create_extension("subjectKeyIdentifier", "hash")
|
30
|
+
ecert.sign ca_key, OpenSSL::Digest::SHA1.new
|
31
|
+
|
32
|
+
return ecert
|
33
|
+
end
|
34
|
+
|
35
|
+
@@dev_dir = File.join(File.dirname(__FILE__), "..", "..", "dev_ca")
|
36
|
+
|
37
|
+
# retrieves the TEM CA configuration
|
38
|
+
def self.config
|
39
|
+
cpath = Tem::Hive.path_to 'ca/config.yml'
|
40
|
+
cpath = File.join(@@dev_dir, 'config.yml') unless File.exists? cpath
|
41
|
+
|
42
|
+
# try to open it in the base folder
|
43
|
+
scaffold_config unless File.exists? cpath
|
44
|
+
return File.open(cpath, 'r') { |f| YAML.load f }
|
45
|
+
end
|
46
|
+
|
47
|
+
# retrieves the TEM CA certificate
|
48
|
+
def self.ca_cert
|
49
|
+
cpath = Tem::Hive.path_to 'ca/ca_cert.pem'
|
50
|
+
cpath = File.join(@@dev_dir, 'ca_cert.pem') unless File.exists? cpath
|
51
|
+
return OpenSSL::X509::Certificate.new(File.open(cpath, 'r') { |f| f.read })
|
52
|
+
end
|
53
|
+
|
54
|
+
# retrieves the TEM CA key pair (needed for signing)
|
55
|
+
def self.ca_key
|
56
|
+
cpath = Tem::Hive.path_to 'ca/ca_key.pem'
|
57
|
+
cpath = File.join(@@dev_dir, 'ca_key.pem') unless File.exists? cpath
|
58
|
+
return OpenSSL::PKey::RSA.new(File.open(cpath, 'r') { |f| f.read })
|
59
|
+
end
|
60
|
+
|
61
|
+
# scaffolds the structures needed for a TEM CA
|
62
|
+
def self.scaffold_ca
|
63
|
+
conf = config
|
64
|
+
|
65
|
+
# generate and write key
|
66
|
+
ca_key = Tem::CryptoAbi.generate_ssl_kp
|
67
|
+
key_path = Tem::Hive.create 'ca/ca_key.pem'
|
68
|
+
File.open(key_path, 'w') { |f| f.write ca_key.to_pem }
|
69
|
+
|
70
|
+
# create the CA certificate
|
71
|
+
dn = OpenSSL::X509::Name.new conf[:issuer].to_a
|
72
|
+
now = Time.now
|
73
|
+
cert = OpenSSL::X509::Certificate.new
|
74
|
+
cert.subject = cert.issuer = dn
|
75
|
+
cert.not_before = now;
|
76
|
+
cert.not_after = now + conf[:ca_validity_days] * 60 * 60 * 24;
|
77
|
+
cert.public_key = ca_key.public_key
|
78
|
+
cert.version = 2
|
79
|
+
cf = OpenSSL::X509::ExtensionFactory.new
|
80
|
+
cf.subject_certificate = cf.issuer_certificate = cert
|
81
|
+
cert.add_extension cf.create_extension("basicConstraints", "CA:true", true)
|
82
|
+
cert.add_extension cf.create_extension("authorityKeyIdentifier", "keyid,issuer")
|
83
|
+
cert.add_extension cf.create_extension("keyUsage", "cRLSign,keyCertSign")
|
84
|
+
cert.add_extension cf.create_extension("nsCertType", "emailCA,sslCA")
|
85
|
+
cert.add_extension cf.create_extension("subjectKeyIdentifier", "hash")
|
86
|
+
cert.sign ca_key, OpenSSL::Digest::SHA1.new
|
87
|
+
|
88
|
+
# write the CA certificate
|
89
|
+
cert_path = Tem::Hive.create 'ca/ca_cert.pem'
|
90
|
+
File.open(cert_path, 'w') { |f| f.write cert.to_pem }
|
91
|
+
cert_path = Tem::Hive.create 'ca/ca_cert.cer'
|
92
|
+
File.open(cert_path, 'wb') { |f| f.write cert.to_der }
|
93
|
+
end
|
94
|
+
|
95
|
+
# scaffolds a TEM CA configuration
|
96
|
+
def self.scaffold_config
|
97
|
+
def_config = {
|
98
|
+
:issuer => {
|
99
|
+
'C' => 'US', 'ST' => 'Massachusetts', 'L' => 'Cambridge',
|
100
|
+
'O' => 'Massachusetts Insitute of Technology',
|
101
|
+
'OU' => 'Computer Science and Artificial Intelligence Laboratory',
|
102
|
+
'CN' => 'Trusted Execution Module Development CA'
|
103
|
+
},
|
104
|
+
:subject => {
|
105
|
+
'CN' => 'Trusted Execution Module DevChip'
|
106
|
+
},
|
107
|
+
:ca_validity_days => 3652,
|
108
|
+
:ecert_validity_days => 365 * 2,
|
109
|
+
}
|
110
|
+
|
111
|
+
cpath = Tem::Hive.create 'ca/config.yml'
|
112
|
+
File.open(cpath, 'w') { |f| YAML.dump def_config, f }
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'digest/sha1'
|
3
|
+
|
4
|
+
|
5
|
+
module Tem::Abi
|
6
|
+
Tem::Builders::Abi.define_abi self do |abi|
|
7
|
+
abi.fixed_length_number :tem_byte, 1, :signed => true, :big_endian => true
|
8
|
+
abi.fixed_length_number :tem_ubyte, 1, :signed => false, :big_endian => true
|
9
|
+
abi.fixed_length_number :tem_short, 2, :signed => true, :big_endian => true
|
10
|
+
abi.fixed_length_number :tem_ushort, 2, :signed => false,
|
11
|
+
:big_endian => true
|
12
|
+
abi.fixed_length_number :tem_ps_addr, 20, :signed => false,
|
13
|
+
:big_endian => true
|
14
|
+
abi.fixed_length_number :tem_ps_value, 20, :signed => false,
|
15
|
+
:big_endian => true
|
16
|
+
|
17
|
+
abi.packed_variable_length_numbers :tem_privrsa_numbers, :tem_ushort,
|
18
|
+
[:p, :q, :dmp1, :dmq1, :iqmp], :signed => false, :big_endian => true
|
19
|
+
abi.packed_variable_length_numbers :tem_pubrsa_numbers, :tem_ushort,
|
20
|
+
[:e, :n], :signed => false, :big_endian => true
|
21
|
+
abi.fixed_length_string :tem_aes_key_string, 16
|
22
|
+
end
|
23
|
+
|
24
|
+
Tem::Builders::Crypto.define_crypto self do |crypto|
|
25
|
+
crypto.crypto_hash :tem_hash, Digest::SHA1
|
26
|
+
|
27
|
+
crypto.asymmetric_key :tem_rsa, OpenSSL::PKey::RSA, :tem_privrsa_numbers,
|
28
|
+
:tem_pubrsa_numbers,
|
29
|
+
:read_private => lambda { |key|
|
30
|
+
# The TEM uses the Chinese Remainder Theorem form of RSA keys, while
|
31
|
+
# OpenSSL uses the straightforward form (n, e, d).
|
32
|
+
|
33
|
+
# Rebuild the straightforward form from the CRT form.
|
34
|
+
key.n = key.p * key.q
|
35
|
+
p1, q1 = key.p - 1, key.q - 1
|
36
|
+
p1q1 = p1 * q1
|
37
|
+
# HACK(costan): I haven't figured out how to restore d from dmp1 and
|
38
|
+
# dmq1, so I'm betting on the fact that e must be a small prime.
|
39
|
+
emp1 = key.dmp1.mod_inverse p1
|
40
|
+
emq1 = key.dmq1.mod_inverse q1
|
41
|
+
key.e = (emp1 < emq1) ? emp1 : emq1
|
42
|
+
key.d = key.e.mod_inverse p1q1
|
43
|
+
Tem::Keys::Asymmetric.new key
|
44
|
+
}
|
45
|
+
|
46
|
+
crypto.symmetric_key :tem_aes_key, OpenSSL::Cipher::AES, 'ECB',
|
47
|
+
:tem_aes_key_string
|
48
|
+
|
49
|
+
crypto.conditional_wrapper :tem_key, 1,
|
50
|
+
[{:tag => [0x99], :type => :tem_key,
|
51
|
+
:class => Tem::Keys::Symmetric },
|
52
|
+
{:tag => [0xAA], :type => :public_tem_rsa,
|
53
|
+
:class => Tem::Keys::Asymmetric,
|
54
|
+
:predicate => lambda { |k| k.ssl_key.kind_of?(OpenSSL::PKey::RSA) &&
|
55
|
+
k.is_public? } },
|
56
|
+
{:tag => [0x55], :type => :private_tem_rsa,
|
57
|
+
:class => Tem::Keys::Asymmetric,
|
58
|
+
:predicate => lambda { |k| k.ssl_key.kind_of?(OpenSSL::PKey::RSA) } }]
|
59
|
+
end
|
60
|
+
|
61
|
+
# For convenience, include the Abi methods in Tem::Session's namespace.
|
62
|
+
def self.included(klass)
|
63
|
+
klass.extend Tem::Abi
|
64
|
+
end
|
65
|
+
end # module Tem::Abi
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Tem::Assembler
|
2
|
+
Tem::Builders::Assembler.define_assembler self do |assembler|
|
3
|
+
assembler.target_isa Tem::Isa
|
4
|
+
assembler.stack_directive :stack, :label => :__stack,
|
5
|
+
:slot_type => :tem_short
|
6
|
+
assembler.label_directive :label
|
7
|
+
assembler.special_label_directive :entry, :__entry
|
8
|
+
assembler.zeros_directive :zeros
|
9
|
+
assembler.data_directive :data
|
10
|
+
end
|
11
|
+
|
12
|
+
class Builder
|
13
|
+
def done_assembling(proxy)
|
14
|
+
assembled = super
|
15
|
+
bytes = assembled[:bytes]
|
16
|
+
labels = assembled[:labels]
|
17
|
+
Tem::SecPack.new :body => bytes,
|
18
|
+
:labels => labels, :ep => labels[:__entry] || 0,
|
19
|
+
:sp => labels[:__stack] || bytes.length,
|
20
|
+
:lines => assembled[:line_info]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module Tem::Isa
|
2
|
+
Tem::Builders::Isa.define_isa self, Tem::Abi,
|
3
|
+
:opcode_type => :tem_ubyte do |isa|
|
4
|
+
# 2 ST -> 1 ST
|
5
|
+
isa.instruction 0x10, :add
|
6
|
+
# 2 ST -> 1 ST
|
7
|
+
isa.instruction 0x11, :sub
|
8
|
+
# 2 ST -> 1 ST
|
9
|
+
isa.instruction 0x12, :mul
|
10
|
+
# 2 ST -> 1 ST
|
11
|
+
isa.instruction 0x13, :div
|
12
|
+
# 2 ST -> 1 ST
|
13
|
+
isa.instruction 0x14, :mod
|
14
|
+
# 2 ST -> 1 ST
|
15
|
+
isa.instruction 0x1E, :rnd
|
16
|
+
|
17
|
+
|
18
|
+
# 2 ST -> 1 ST
|
19
|
+
isa.instruction 0x3A, :stbv
|
20
|
+
# 2 ST -> 1 ST
|
21
|
+
isa.instruction 0x3B, :stwv
|
22
|
+
|
23
|
+
# 2 ST -> 1 ST
|
24
|
+
isa.instruction 0x5B, :stk
|
25
|
+
|
26
|
+
|
27
|
+
# 1 ST, 1 IM -> 1 ST
|
28
|
+
isa.instruction 0x38, :stb, {:name => :to, :type => :tem_ushort}
|
29
|
+
# 1 ST, 1 IM -> 1 ST
|
30
|
+
isa.instruction 0x39, :stw, {:name => :to, :type => :tem_ushort}
|
31
|
+
|
32
|
+
|
33
|
+
# 2 IM -> 1 ST
|
34
|
+
isa.instruction 0x48, :psupfxb, {:name => :addr, :type => :tem_ushort},
|
35
|
+
{:name => :from, :type => :tem_ushort}
|
36
|
+
# 2 ST -> 1 ST
|
37
|
+
isa.instruction 0x49, :psupvb
|
38
|
+
# 2 IM -> 1 ST
|
39
|
+
isa.instruction 0x4A, :pswrfxb, {:name => :addr, :type => :tem_ushort},
|
40
|
+
{:name => :from, :type => :tem_ushort}
|
41
|
+
# 2 ST -> 1 ST
|
42
|
+
isa.instruction 0x4B, :pswrvb
|
43
|
+
# 2 IM -> 1 ST
|
44
|
+
isa.instruction 0x4C, :psrdfxb, {:name => :addr, :type => :tem_ushort},
|
45
|
+
{:name => :to, :type => :tem_ushort}
|
46
|
+
# 2 ST -> 1 ST
|
47
|
+
isa.instruction 0x4D, :psrdvb
|
48
|
+
# 2 IM -> 1 ST
|
49
|
+
isa.instruction 0x4E, :pshkfxb, {:name => :addr, :type => :tem_ushort}
|
50
|
+
# 2 ST -> 1 ST
|
51
|
+
isa.instruction 0x4F, :pshkvb
|
52
|
+
|
53
|
+
|
54
|
+
# 3 IM -> 1 ST
|
55
|
+
isa.instruction 0x18, :mdfxb, {:name => :size, :type => :tem_ushort},
|
56
|
+
{:name => :from, :type => :tem_ushort},
|
57
|
+
{:name => :to, :type => :tem_ushort}
|
58
|
+
# 3 ST -> 1 ST
|
59
|
+
isa.instruction 0x19, :mdvb
|
60
|
+
# 3 IM -> 1 ST
|
61
|
+
isa.instruction 0x1A, :mcmpfxb, {:name => :size, :type => :tem_ushort},
|
62
|
+
{:name => :op1, :type => :tem_ushort},
|
63
|
+
{:name => :op2, :type => :tem_ushort}
|
64
|
+
# 3 ST -> 1 ST
|
65
|
+
isa.instruction 0x1B, :mcmpvb
|
66
|
+
# 3 IM -> 1 ST
|
67
|
+
isa.instruction 0x1C, :mcfxb, {:name => :size, :type => :tem_ushort},
|
68
|
+
{:name => :from, :type => :tem_ushort},
|
69
|
+
{:name => :to, :type => :tem_ushort}
|
70
|
+
# 3 ST -> 1 ST
|
71
|
+
isa.instruction 0x1D, :mcvb
|
72
|
+
|
73
|
+
# 1 ST, 3 IM -> 1 ST
|
74
|
+
isa.instruction 0x50, :kefxb, {:name => :size, :type => :tem_ushort},
|
75
|
+
{:name => :from, :type => :tem_ushort},
|
76
|
+
{:name => :to, :type => :tem_ushort}
|
77
|
+
# 4 ST -> 1 ST
|
78
|
+
isa.instruction 0x51, :kevb
|
79
|
+
# 1 ST, 3 IM -> 1 ST
|
80
|
+
isa.instruction 0x52, :kdfxb, {:name => :size, :type => :tem_ushort},
|
81
|
+
{:name => :from, :type => :tem_ushort},
|
82
|
+
{:name => :to, :type => :tem_ushort}
|
83
|
+
# 4 ST -> 1 ST
|
84
|
+
isa.instruction 0x53, :kdvb
|
85
|
+
# 1 ST, 3 IM -> 1 ST
|
86
|
+
isa.instruction 0x54, :ksfxb, {:name => :size, :type => :tem_ushort},
|
87
|
+
{:name => :from, :type => :tem_ushort},
|
88
|
+
{:name => :to, :type => :tem_ushort}
|
89
|
+
# 4 ST -> 1 ST
|
90
|
+
isa.instruction 0x55, :ksvb
|
91
|
+
# 1 ST, 3 IM -> 1 ST
|
92
|
+
isa.instruction 0x56, :kvsfxb, {:name => :size, :type => :tem_ushort},
|
93
|
+
{:name => :from, :type => :tem_ushort},
|
94
|
+
{:name => :signature, :type => :tem_ushort}
|
95
|
+
# 4 ST -> 1 ST
|
96
|
+
isa.instruction 0x57, :kvsvb
|
97
|
+
|
98
|
+
|
99
|
+
# 0 ST -> 0 ST; IP
|
100
|
+
isa.instruction 0x27, :jmp, {:name => :to, :type => :tem_ushort,
|
101
|
+
:reladdr => 2}
|
102
|
+
# 1 ST -> 0 ST; IP
|
103
|
+
isa.instruction 0x21, :jz, {:name => :to, :type => :tem_ushort,
|
104
|
+
:reladdr => 2}
|
105
|
+
isa.instruction 0x21, :je, {:name => :to, :type => :tem_ushort,
|
106
|
+
:reladdr => 2}
|
107
|
+
# 1 ST -> 0 ST; IP
|
108
|
+
isa.instruction 0x26, :jnz, {:name => :to, :type => :tem_ushort,
|
109
|
+
:reladdr => 2}
|
110
|
+
isa.instruction 0x26, :jne, {:name => :to, :type => :tem_ushort,
|
111
|
+
:reladdr => 2}
|
112
|
+
# 1 ST -> 0 ST; IP
|
113
|
+
isa.instruction 0x22, :ja, {:name => :to, :type => :tem_ushort,
|
114
|
+
:reladdr => 2}
|
115
|
+
isa.instruction 0x22, :jg, {:name => :to, :type => :tem_ushort,
|
116
|
+
:reladdr => 2}
|
117
|
+
# 1 ST -> 0 ST; IP
|
118
|
+
isa.instruction 0x23, :jae, {:name => :to, :type => :tem_ushort,
|
119
|
+
:reladdr => 2}
|
120
|
+
isa.instruction 0x23, :jge, {:name => :to, :type => :tem_ushort,
|
121
|
+
:reladdr => 2}
|
122
|
+
# 1 ST -> 0 ST; IP
|
123
|
+
isa.instruction 0x24, :jb, {:name => :to, :type => :tem_ushort,
|
124
|
+
:reladdr => 2}
|
125
|
+
isa.instruction 0x24, :jl, {:name => :to, :type => :tem_ushort,
|
126
|
+
:reladdr => 2}
|
127
|
+
# 1 ST -> 0 ST; IP
|
128
|
+
isa.instruction 0x25, :jbe, {:name => :to, :type => :tem_ushort,
|
129
|
+
:reladdr => 2}
|
130
|
+
isa.instruction 0x25, :jle, {:name => :to, :type => :tem_ushort,
|
131
|
+
:reladdr => 2}
|
132
|
+
|
133
|
+
# 1 IM_B -> 1 ST
|
134
|
+
isa.instruction 0x30, :ldbc, {:name => :const, :type => :tem_byte}
|
135
|
+
# 1 IM -> 1 ST
|
136
|
+
isa.instruction 0x31, :ldwc, {:name => :const, :type => :tem_short}
|
137
|
+
# 1 ST -> 1 ST
|
138
|
+
isa.instruction 0x32, :ldb, {:name => :from, :type => :tem_ushort}
|
139
|
+
# 1 ST -> 1 ST
|
140
|
+
isa.instruction 0x33, :ldw, {:name => :from, :type => :tem_ushort}
|
141
|
+
# 1 ST -> 1 ST
|
142
|
+
isa.instruction 0x36, :ldbv
|
143
|
+
# 1 ST -> 1 ST
|
144
|
+
isa.instruction 0x37, :ldwv
|
145
|
+
|
146
|
+
# 1 ST -> 0 ST
|
147
|
+
isa.instruction 0x42, :outnew
|
148
|
+
# 1 ST -> 0 ST
|
149
|
+
isa.instruction 0x44, :outb
|
150
|
+
# 1 ST -> 0 ST
|
151
|
+
isa.instruction 0x45, :outw
|
152
|
+
|
153
|
+
# 1 ST -> 0 ST
|
154
|
+
isa.instruction 0x34, :pop
|
155
|
+
# 2 ST -> 0 ST
|
156
|
+
isa.instruction 0x35, :pop2
|
157
|
+
|
158
|
+
# 1 IM, x ST -> 2x ST
|
159
|
+
isa.instruction 0x3C, :dupn, {:name => :n, :type => :tem_ubyte}
|
160
|
+
# 1 IM, x ST -> x ST
|
161
|
+
isa.instruction 0x3D, :flipn, {:name => :n, :type => :tem_ubyte}
|
162
|
+
|
163
|
+
# 2 IM -> 0 ST
|
164
|
+
isa.instruction 0x40, :outfxb, {:name => :size, :type => :tem_ushort},
|
165
|
+
{:name => :from, :type => :tem_ushort}
|
166
|
+
# 2 ST -> 0 ST
|
167
|
+
isa.instruction 0x41, :outvlb, {:name => :from, :type => :tem_ushort}
|
168
|
+
|
169
|
+
|
170
|
+
# 1 IM, 1 ST -> 0 ST
|
171
|
+
isa.instruction 0x43, :outvb
|
172
|
+
# 0 ST -> 0 ST;;
|
173
|
+
isa.instruction 0x46, :halt
|
174
|
+
# 1 ST -> 0 ST
|
175
|
+
isa.instruction 0x47, :psrm
|
176
|
+
|
177
|
+
# 1 ST -> 1 ST
|
178
|
+
isa.instruction 0x5A, :rdk
|
179
|
+
# 1 ST -> 0 ST
|
180
|
+
isa.instruction 0x5C, :relk
|
181
|
+
|
182
|
+
isa.instruction 0x5D, :ldkl
|
183
|
+
# 1 IM_B -> 2 ST
|
184
|
+
isa.instruction 0x5E, :genkp, {:name => :type, :type => :tem_ubyte }
|
185
|
+
# 1 ST, 1 IM -> 1 ST
|
186
|
+
isa.instruction 0x5F, :authk, {:name => :auth, :type => :tem_ushort }
|
187
|
+
end
|
188
|
+
end
|
data/lib/tem/ecert.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module Tem::ECert
|
4
|
+
# Writes an Endorsement Certificate to the TEM's tag.
|
5
|
+
def set_ecert(ecert)
|
6
|
+
set_tag ecert.to_der.unpack('C*')
|
7
|
+
end
|
8
|
+
|
9
|
+
# Retrieves the TEM's Endorsement Certificate.
|
10
|
+
def endorsement_cert
|
11
|
+
OpenSSL::X509::Certificate.new get_tag[2..-1].pack('C*')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Retrieves the certificate of the TEM's Manfacturer (CA).
|
15
|
+
def manufacturer_cert
|
16
|
+
Tem::CA.ca_cert
|
17
|
+
end
|
18
|
+
|
19
|
+
# Retrieves the TEM's Public Endorsement Key.
|
20
|
+
def pubek
|
21
|
+
Tem::Key.new_from_ssl_key endorsement_cert.public_key
|
22
|
+
end
|
23
|
+
|
24
|
+
# Drives a TEM though the emitting process.
|
25
|
+
def emit
|
26
|
+
emit_sec = assemble do |s|
|
27
|
+
# Generate Endorsement Key pair, should end up in slots (0, 1).
|
28
|
+
s.genkp :type => 0
|
29
|
+
s.ldbc 1
|
30
|
+
s.sub
|
31
|
+
s.jne :to => :not_ok
|
32
|
+
s.ldbc 0
|
33
|
+
s.sub
|
34
|
+
s.jne :to => :not_ok
|
35
|
+
|
36
|
+
# Generate and output random authorization for PrivEK.
|
37
|
+
s.ldbc 20
|
38
|
+
s.dupn :n => 1
|
39
|
+
s.outnew
|
40
|
+
s.ldwc :privek_auth
|
41
|
+
s.dupn :n => 2
|
42
|
+
s.rnd
|
43
|
+
s.outvb
|
44
|
+
# Set authorizations for PrivEK and PubkEK.
|
45
|
+
s.ldbc 0
|
46
|
+
s.authk :auth => :privek_auth
|
47
|
+
s.ldbc 1 # PubEK always has its initial authorization be all zeroes.
|
48
|
+
s.authk :auth => :pubek_auth
|
49
|
+
s.halt
|
50
|
+
|
51
|
+
# Emitting didn't go well, return nothing and leave.
|
52
|
+
s.label :not_ok
|
53
|
+
s.ldbc 0
|
54
|
+
s.outnew
|
55
|
+
s.halt
|
56
|
+
|
57
|
+
s.label :privek_auth
|
58
|
+
s.zeros :tem_ubyte, 20
|
59
|
+
s.label :pubek_auth
|
60
|
+
s.zeros :tem_ubyte, 20
|
61
|
+
s.stack 4
|
62
|
+
end
|
63
|
+
|
64
|
+
r = execute emit_sec
|
65
|
+
if r.length == 0
|
66
|
+
return nil
|
67
|
+
else
|
68
|
+
privk_auth = r[0...20]
|
69
|
+
pubek_auth = (0...20).map {|i| 0}
|
70
|
+
pubek = tk_read_key 1, pubek_auth
|
71
|
+
tk_delete_key 1, pubek_auth
|
72
|
+
ecert = new_ecert pubek.ssl_key
|
73
|
+
set_ecert ecert
|
74
|
+
return { :privek_auth => privk_auth }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|