costan-tem_ruby 0.10.2
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.
- 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
|