costan-tem_ruby 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/CHANGELOG +45 -0
  2. data/LICENSE +21 -0
  3. data/Manifest +75 -0
  4. data/README +8 -0
  5. data/Rakefile +23 -0
  6. data/bin/tem_bench +9 -0
  7. data/bin/tem_ca +13 -0
  8. data/bin/tem_irb +11 -0
  9. data/bin/tem_proxy +65 -0
  10. data/bin/tem_stat +35 -0
  11. data/dev_ca/ca_cert.cer +0 -0
  12. data/dev_ca/ca_cert.pem +32 -0
  13. data/dev_ca/ca_key.pem +27 -0
  14. data/dev_ca/config.yml +14 -0
  15. data/lib/tem/_cert.rb +158 -0
  16. data/lib/tem/apdus/buffers.rb +89 -0
  17. data/lib/tem/apdus/keys.rb +64 -0
  18. data/lib/tem/apdus/lifecycle.rb +13 -0
  19. data/lib/tem/apdus/tag.rb +38 -0
  20. data/lib/tem/auto_conf.rb +25 -0
  21. data/lib/tem/builders/abi.rb +482 -0
  22. data/lib/tem/builders/assembler.rb +314 -0
  23. data/lib/tem/builders/crypto.rb +124 -0
  24. data/lib/tem/builders/isa.rb +120 -0
  25. data/lib/tem/ca.rb +114 -0
  26. data/lib/tem/definitions/abi.rb +65 -0
  27. data/lib/tem/definitions/assembler.rb +23 -0
  28. data/lib/tem/definitions/isa.rb +188 -0
  29. data/lib/tem/ecert.rb +77 -0
  30. data/lib/tem/hive.rb +18 -0
  31. data/lib/tem/keys/asymmetric.rb +116 -0
  32. data/lib/tem/keys/key.rb +48 -0
  33. data/lib/tem/keys/symmetric.rb +47 -0
  34. data/lib/tem/sec_exec_error.rb +63 -0
  35. data/lib/tem/seclosures.rb +81 -0
  36. data/lib/tem/secpack.rb +107 -0
  37. data/lib/tem/tem.rb +31 -0
  38. data/lib/tem/toolkit.rb +101 -0
  39. data/lib/tem/transport/auto_configurator.rb +87 -0
  40. data/lib/tem/transport/java_card_mixin.rb +99 -0
  41. data/lib/tem/transport/jcop_remote_protocol.rb +59 -0
  42. data/lib/tem/transport/jcop_remote_server.rb +171 -0
  43. data/lib/tem/transport/jcop_remote_transport.rb +65 -0
  44. data/lib/tem/transport/pcsc_transport.rb +87 -0
  45. data/lib/tem/transport/transport.rb +10 -0
  46. data/lib/tem_ruby.rb +47 -0
  47. data/tem_ruby.gemspec +35 -0
  48. data/test/_test_cert.rb +70 -0
  49. data/test/builders/test_abi_builder.rb +298 -0
  50. data/test/tem_test_case.rb +26 -0
  51. data/test/tem_unit/test_tem_alu.rb +33 -0
  52. data/test/tem_unit/test_tem_bound_secpack.rb +51 -0
  53. data/test/tem_unit/test_tem_branching.rb +56 -0
  54. data/test/tem_unit/test_tem_crypto_asymmetric.rb +123 -0
  55. data/test/tem_unit/test_tem_crypto_hash.rb +35 -0
  56. data/test/tem_unit/test_tem_crypto_pstore.rb +53 -0
  57. data/test/tem_unit/test_tem_crypto_random.rb +25 -0
  58. data/test/tem_unit/test_tem_emit.rb +23 -0
  59. data/test/tem_unit/test_tem_memory.rb +48 -0
  60. data/test/tem_unit/test_tem_memory_compare.rb +65 -0
  61. data/test/tem_unit/test_tem_output.rb +32 -0
  62. data/test/tem_unit/test_tem_yaml_secpack.rb +47 -0
  63. data/test/test_driver.rb +108 -0
  64. data/test/test_exceptions.rb +35 -0
  65. data/test/transport/test_auto_configurator.rb +114 -0
  66. data/test/transport/test_java_card_mixin.rb +90 -0
  67. data/test/transport/test_jcop_remote.rb +82 -0
  68. data/timings/blank_bound_secpack.rb +18 -0
  69. data/timings/blank_sec.rb +14 -0
  70. data/timings/devchip_decrypt.rb +9 -0
  71. data/timings/post_buffer.rb +10 -0
  72. data/timings/simple_apdu.rb +5 -0
  73. data/timings/timings.rb +64 -0
  74. data/timings/vm_perf.rb +140 -0
  75. data/timings/vm_perf_bound.rb +141 -0
  76. 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