tem_ruby 0.10.1 → 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 +2 -0
- data/Manifest +17 -3
- data/lib/tem/apdus/buffers.rb +1 -2
- data/lib/tem/builders/abi.rb +2 -2
- data/lib/tem/builders/assembler.rb +314 -0
- data/lib/tem/builders/crypto.rb +17 -8
- data/lib/tem/builders/isa.rb +120 -0
- data/lib/tem/definitions/abi.rb +8 -10
- data/lib/tem/definitions/assembler.rb +23 -0
- data/lib/tem/definitions/isa.rb +188 -0
- data/lib/tem/ecert.rb +15 -16
- data/lib/tem/sec_exec_error.rb +21 -3
- data/lib/tem/seclosures.rb +9 -5
- data/lib/tem/secpack.rb +50 -30
- data/lib/tem/toolkit.rb +11 -15
- data/lib/tem/transport/jcop_remote_protocol.rb +10 -2
- data/lib/tem_ruby.rb +4 -2
- data/tem_ruby.gemspec +5 -5
- 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_exceptions.rb +1 -2
- data/timings/blank_bound_secpack.rb +3 -5
- data/timings/blank_sec.rb +2 -3
- data/timings/timings.rb +7 -2
- data/timings/vm_perf.rb +9 -10
- data/timings/vm_perf_bound.rb +9 -10
- metadata +35 -9
- data/lib/tem/sec_assembler.rb +0 -90
- data/lib/tem/sec_opcodes.rb +0 -154
- data/test/test_tem.rb +0 -524
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
module TemBoundSecpackTestCase
|
4
|
+
# This is also called from TemYamlSecpackTest.
|
5
|
+
def _test_bound_secpack(yaml_roundtrip = false)
|
6
|
+
keyd = @tem.tk_gen_key
|
7
|
+
pubk = @tem.tk_read_key keyd[:pubk_id], keyd[:authz]
|
8
|
+
|
9
|
+
secret = (0...16).map { |i| (99 * i * i + 51 * i + 33) % 256 }
|
10
|
+
bound_sec = @tem.assemble { |s|
|
11
|
+
s.ldbc secret.length
|
12
|
+
s.outnew
|
13
|
+
s.label :mess_place
|
14
|
+
s.outfxb :size => secret.length, :from => :secret
|
15
|
+
s.halt
|
16
|
+
s.label :secret
|
17
|
+
s.data :tem_ubyte, secret
|
18
|
+
# Make sure the zero_bytes optimization doesn't screw things up.
|
19
|
+
s.zeros :tem_ubyte, 60
|
20
|
+
s.label :plain
|
21
|
+
s.stack 4
|
22
|
+
}
|
23
|
+
|
24
|
+
sb = bound_sec.body
|
25
|
+
secret_found = false
|
26
|
+
0.upto(sb.length - 1) { |i| if secret == sb[i, secret.length] then secret_found = true; break; end }
|
27
|
+
assert secret_found, 'test_bound_secpack needs rethinking: the unbound secpack does not contain the secret'
|
28
|
+
|
29
|
+
bound_sec.bind pubk, :secret, :plain
|
30
|
+
if yaml_roundtrip
|
31
|
+
# same test, except the SECpack is serialized/deserialized
|
32
|
+
yaml_bound_sec = bound_sec.to_yaml_str
|
33
|
+
bound_sec = Tem::SecPack.new_from_yaml_str(yaml_bound_sec)
|
34
|
+
end
|
35
|
+
result = @tem.execute bound_sec, keyd[:privk_id]
|
36
|
+
assert_equal secret, result, 'TEM failed to decrypt secpack'
|
37
|
+
|
38
|
+
sb = bound_sec.body
|
39
|
+
0.upto(sb.length - 1) { |i| assert_not_equal secret, sb[i, secret.length], 'secret found unencrypted in bound secpack' }
|
40
|
+
|
41
|
+
bound_sec.body[bound_sec.label_address(:mess_place)] += 1
|
42
|
+
assert_raise(RuntimeError, 'secpack validation isn\'t working') { @tem.execute bound_sec }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class TemBoundSecpackTest < TemTestCase
|
47
|
+
include TemBoundSecpackTestCase
|
48
|
+
def test_bound_secpack
|
49
|
+
_test_bound_secpack false
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemBranchingTest < TemTestCase
|
4
|
+
def test_branching
|
5
|
+
secpack = @tem.assemble { |s|
|
6
|
+
s.ldbc 24
|
7
|
+
s.outnew
|
8
|
+
|
9
|
+
s.jmp :to => :over_halt
|
10
|
+
s.halt # this gets jumped over
|
11
|
+
s.label :over_halt
|
12
|
+
s.ldbc 4
|
13
|
+
s.label :test_loop
|
14
|
+
s.dupn :n => 1
|
15
|
+
s.outb
|
16
|
+
s.ldbc 1
|
17
|
+
s.sub
|
18
|
+
s.dupn :n=> 1
|
19
|
+
s.jae :to => :test_loop
|
20
|
+
|
21
|
+
failed = 0xFA - (1 << 8)
|
22
|
+
[
|
23
|
+
[:ja, [1, 1, failed], [0, failed, 2], [-1, failed, 3]],
|
24
|
+
[:jae, [1, 4, failed], [0, 5, failed], [-1, failed, 6]],
|
25
|
+
[:jb, [1, failed, 7], [0, failed, 8], [-1, 9, failed]],
|
26
|
+
[:jbe, [1, failed, 10], [0, 11, failed], [-1, 12, failed]],
|
27
|
+
[:jz, [1, failed, 13], [0, 14, failed], [-1, failed, 15]],
|
28
|
+
[:jne, [1, 16, failed], [0, failed, 17], [-1, 18, failed]],
|
29
|
+
].each do |op_line|
|
30
|
+
op = op_line.shift
|
31
|
+
op_line.each_index do |i|
|
32
|
+
then_label = "#{op}_l#{i}_t".to_sym
|
33
|
+
out_label = "#{op}_l#{i}_o".to_sym
|
34
|
+
|
35
|
+
s.ldbc op_line[i][0]
|
36
|
+
s.send op, :to => then_label
|
37
|
+
s.ldbc op_line[i][2]
|
38
|
+
s.jmp :to => out_label
|
39
|
+
s.label then_label
|
40
|
+
s.ldbc op_line[i][1]
|
41
|
+
s.label out_label
|
42
|
+
s.outb
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
s.halt
|
47
|
+
# Test automated stack placement.
|
48
|
+
s.zeros :tem_ubyte, 10
|
49
|
+
}
|
50
|
+
result = @tem.execute secpack
|
51
|
+
assert_equal [0x04, 0x03, 0x02, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
52
|
+
0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
53
|
+
0x10, 0x11, 0x12],
|
54
|
+
result, 'the branching unit isn\'t working well'
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemCryptoAsymmetricTest < TemTestCase
|
4
|
+
def i_crypt(data, key_id, authz, mode = :encrypt, direct_io = true, max_output = nil)
|
5
|
+
if max_output.nil?
|
6
|
+
max_output = case mode
|
7
|
+
when :encrypt
|
8
|
+
((data.length + 239) / 240) * 256
|
9
|
+
when :decrypt
|
10
|
+
data.length
|
11
|
+
when :sign
|
12
|
+
256
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
crypt_opcode = {:encrypt => :kefxb, :decrypt => :kdfxb, :sign => :ksfxb}[mode]
|
17
|
+
ex_sec = @tem.assemble { |s|
|
18
|
+
# buffer
|
19
|
+
s.ldwc :const => max_output
|
20
|
+
s.outnew
|
21
|
+
s.ldbc :const => key_id
|
22
|
+
s.authk :auth => :key_auth
|
23
|
+
s.send crypt_opcode, :from => :data, :size => data.length, :to => (direct_io ? 0xFFFF : :outdata)
|
24
|
+
s.outvlb :from => :outdata unless direct_io
|
25
|
+
s.halt
|
26
|
+
|
27
|
+
s.label :key_auth
|
28
|
+
s.data :tem_ubyte, authz
|
29
|
+
s.label :data
|
30
|
+
s.data :tem_ubyte, data
|
31
|
+
unless direct_io
|
32
|
+
s.label :outdata
|
33
|
+
s.zeros :tem_ubyte, max_output
|
34
|
+
end
|
35
|
+
s.stack 5
|
36
|
+
}
|
37
|
+
return @tem.execute(ex_sec)
|
38
|
+
end
|
39
|
+
|
40
|
+
def i_verify(data, signature, key_id, authz)
|
41
|
+
sign_sec = @tem.assemble { |s|
|
42
|
+
# buffer
|
43
|
+
s.ldbc :const => 1
|
44
|
+
s.outnew
|
45
|
+
s.ldbc :const => key_id
|
46
|
+
s.authk :auth => :key_auth
|
47
|
+
s.kvsfxb :from => :data, :size => data.length, :signature => :signature
|
48
|
+
s.outb
|
49
|
+
s.halt
|
50
|
+
|
51
|
+
s.label :key_auth
|
52
|
+
s.data :tem_ubyte, authz
|
53
|
+
s.label :data
|
54
|
+
s.data :tem_ubyte, data
|
55
|
+
s.label :signature
|
56
|
+
s.data :tem_ubyte, signature
|
57
|
+
s.stack 5
|
58
|
+
}
|
59
|
+
return @tem.execute(sign_sec)[0] == 1
|
60
|
+
end
|
61
|
+
|
62
|
+
def i_test_crypto_pki_ops(pubk_id, privk_id, pubk, privk, authz)
|
63
|
+
garbage = (1...569).map { |i| (i * i * 217 + i * 661 + 393) % 256 }
|
64
|
+
|
65
|
+
# SEC/priv-sign + CPU/pub-verify, direct IO
|
66
|
+
signed_garbage = i_crypt garbage, privk_id, authz, :sign, true
|
67
|
+
assert privk.verify(garbage, signed_garbage),
|
68
|
+
'SEC priv-signing + CPU pub-verify failed on good data'
|
69
|
+
|
70
|
+
# SEC/priv-sign + CPU/pub-verify, indirect IO
|
71
|
+
signed_garbage = i_crypt garbage, privk_id, authz, :sign, false
|
72
|
+
assert privk.verify(garbage, signed_garbage),
|
73
|
+
'SEC priv-signing + CPU pub-verify failed on good data'
|
74
|
+
|
75
|
+
# CPU/priv-sign + SEC/pub-verify
|
76
|
+
signed_garbage = privk.sign garbage
|
77
|
+
assert i_verify(garbage, signed_garbage, pubk_id, authz),
|
78
|
+
'CPU priv-signing + SEC pub-verify failed on good data'
|
79
|
+
|
80
|
+
# CPU/priv-encrypt + SEC/pub-decrypt, indirect IO
|
81
|
+
encrypted_garbage = privk.encrypt garbage
|
82
|
+
decrypted_garbage = i_crypt encrypted_garbage, pubk_id, authz, :decrypt,
|
83
|
+
false
|
84
|
+
assert_equal garbage, decrypted_garbage,
|
85
|
+
'SEC priv-encryption + CPU pub-decryption messed up the data'
|
86
|
+
|
87
|
+
# SEC/pub-encrypt + CPU/priv-decrypt, indirect IO
|
88
|
+
encrypted_garbage = i_crypt garbage, pubk_id, authz, :encrypt, false
|
89
|
+
decrypted_garbage = privk.decrypt encrypted_garbage
|
90
|
+
assert_equal garbage, decrypted_garbage,
|
91
|
+
'SEC priv-encryption + CPU pub-decryption messed up the data'
|
92
|
+
|
93
|
+
# CPU/pub-encrypt + SEC/priv-decrypt, direct-IO
|
94
|
+
encrypted_garbage = pubk.encrypt garbage
|
95
|
+
decrypted_garbage = i_crypt encrypted_garbage, privk_id, authz, :decrypt,
|
96
|
+
true
|
97
|
+
assert_equal garbage, decrypted_garbage,
|
98
|
+
'CPU pub-encryption + SEC priv-decryption messed up the data'
|
99
|
+
|
100
|
+
# SEC/priv-encrypt + CPU/pub-decrypt, direct-IO
|
101
|
+
encrypted_garbage = i_crypt garbage, privk_id, authz, :encrypt, true
|
102
|
+
decrypted_garbage = pubk.decrypt encrypted_garbage
|
103
|
+
assert_equal garbage, decrypted_garbage,
|
104
|
+
'SEC priv-encryption + CPU pub-decryption messed up the data'
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_crypto_asymmetric
|
108
|
+
# crypto run with an internally generated key
|
109
|
+
keyd = @tem.tk_gen_key :asymmetric
|
110
|
+
pubk = @tem.tk_read_key keyd[:pubk_id], keyd[:authz]
|
111
|
+
privk = @tem.tk_read_key keyd[:privk_id], keyd[:authz]
|
112
|
+
i_test_crypto_pki_ops keyd[:pubk_id], keyd[:privk_id], pubk, privk,
|
113
|
+
keyd[:authz]
|
114
|
+
|
115
|
+
# crypto run with an externally generated key
|
116
|
+
ekey = OpenSSL::PKey::RSA.generate(2048, 65537)
|
117
|
+
pubk = Tem::Key.new_from_ssl_key ekey.public_key
|
118
|
+
privk = Tem::Key.new_from_ssl_key ekey
|
119
|
+
pubk_id = @tem.tk_post_key pubk, keyd[:authz]
|
120
|
+
privk_id = @tem.tk_post_key privk, keyd[:authz]
|
121
|
+
i_test_crypto_pki_ops pubk_id, privk_id, pubk, privk, keyd[:authz]
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemCryptoHashTest < TemTestCase
|
4
|
+
def test_crypto_hash
|
5
|
+
garbage1 = (0...8).map { |x| (31 * x * x + 5 * x + 3) % 256 }
|
6
|
+
garbage2 = (0...11).map { |x| (69 * x * x + 62 * x + 10) % 256 }
|
7
|
+
hash_size = 20
|
8
|
+
|
9
|
+
sec = @tem.assemble { |s|
|
10
|
+
s.ldwc hash_size * 3
|
11
|
+
s.outnew
|
12
|
+
s.mdfxb :size => garbage1.length, :from => :garbage1, :to => :hash_area
|
13
|
+
s.outfxb :size => hash_size, :from => :hash_area
|
14
|
+
s.mdfxb :size => garbage2.length, :from => :garbage2, :to => 0xFFFF
|
15
|
+
s.ldwc garbage2.length
|
16
|
+
s.ldwc :garbage2
|
17
|
+
s.ldwc :hash_area
|
18
|
+
s.mdvb
|
19
|
+
s.outfxb :size => hash_size, :from => :hash_area
|
20
|
+
s.halt
|
21
|
+
s.label :garbage1
|
22
|
+
s.data :tem_ubyte, garbage1
|
23
|
+
s.label :garbage2
|
24
|
+
s.data :tem_ubyte, garbage2
|
25
|
+
s.label :hash_area
|
26
|
+
s.zeros :tem_ubyte, hash_size
|
27
|
+
s.stack 5
|
28
|
+
}
|
29
|
+
|
30
|
+
result = @tem.execute sec
|
31
|
+
assert_equal [garbage1, garbage2, garbage2].map { |d| @tem.tem_hash d}.
|
32
|
+
flatten,
|
33
|
+
result, 'cryptographic hashing isn\'t working well'
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemCryptoPstoreTest < TemTestCase
|
4
|
+
def test_crypto_pstore
|
5
|
+
addr1 = (0...(@tem.tem_ps_addr_length)).map { |x| (61 * x * x + 62 * x + 10) % 256 }
|
6
|
+
addr2 = addr1.dup; addr2[addr2.length - 1] += 1
|
7
|
+
random_value = (0...(@tem.tem_ps_value_length)).map { |x| (69 * x * x + 62 * x + 10) % 256 }
|
8
|
+
|
9
|
+
sec = @tem.assemble { |s|
|
10
|
+
s.ldwc 3 * @tem.tem_ushort_length + @tem.tem_ps_value_length * 2
|
11
|
+
s.outnew
|
12
|
+
|
13
|
+
# check that the location is blank
|
14
|
+
s.ldwc :pstore_addr
|
15
|
+
s.pshkvb
|
16
|
+
s.outw
|
17
|
+
|
18
|
+
# write to create the location
|
19
|
+
s.pswrfxb :addr => :pstore_addr, :from => :s_value
|
20
|
+
# check that the location isn't blank anymore
|
21
|
+
s.pshkfxb :addr => :pstore_addr
|
22
|
+
s.outw
|
23
|
+
# re-read (should get what was written)
|
24
|
+
s.ldwc :pstore_addr
|
25
|
+
s.ldwc :s_value2
|
26
|
+
s.psrdvb
|
27
|
+
s.ldwc :s_value2
|
28
|
+
s.outvb
|
29
|
+
|
30
|
+
# drop the location
|
31
|
+
s.ldwc :pstore_addr
|
32
|
+
s.dupn :n => 1
|
33
|
+
s.psrm
|
34
|
+
# check that the location is blank again
|
35
|
+
s.pshkvb
|
36
|
+
s.outw
|
37
|
+
|
38
|
+
s.halt
|
39
|
+
|
40
|
+
s.label :pstore_addr
|
41
|
+
s.data :tem_ubyte, addr1
|
42
|
+
s.label :s_value
|
43
|
+
s.data :tem_ubyte, random_value
|
44
|
+
s.label :s_value2
|
45
|
+
s.zeros :tem_ps_value
|
46
|
+
s.stack 8
|
47
|
+
}
|
48
|
+
expected = @tem.to_tem_ushort(0) + @tem.to_tem_ushort(1) + random_value +
|
49
|
+
@tem.to_tem_ushort(0)
|
50
|
+
result = @tem.execute sec
|
51
|
+
assert_equal expected, result, 'persistent store locations aren\'t working well'
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemCryptoRandomTest < TemTestCase
|
4
|
+
def test_crypto_random
|
5
|
+
sec = @tem.assemble { |s|
|
6
|
+
s.ldbc 16
|
7
|
+
s.outnew
|
8
|
+
s.ldbc 8
|
9
|
+
s.dupn :n => 1
|
10
|
+
s.ldwc :rnd_area
|
11
|
+
s.dupn :n => 2
|
12
|
+
s.rnd
|
13
|
+
s.outvb
|
14
|
+
s.ldbc(-1)
|
15
|
+
s.rnd
|
16
|
+
s.halt
|
17
|
+
s.label :rnd_area
|
18
|
+
s.zeros :tem_ubyte, 8
|
19
|
+
s.stack 5
|
20
|
+
}
|
21
|
+
|
22
|
+
result = @tem.execute sec
|
23
|
+
assert_equal 16, result.length, 'monotonic counters aren\'t working well'
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemEmitTest < TemTestCase
|
4
|
+
def test_emit
|
5
|
+
# try to emit
|
6
|
+
er = @tem.emit
|
7
|
+
assert er != nil, 'TEM emitting failed'
|
8
|
+
|
9
|
+
# now verify that the private key is good and the authorization matches
|
10
|
+
privek = @tem.tk_read_key 0, er[:privek_auth]
|
11
|
+
assert((not privek.is_public?), 'TEM emission failed to produce a proper PrivEK')
|
12
|
+
|
13
|
+
# verify that the public key can be read from the ECert
|
14
|
+
pubek = @tem.pubek
|
15
|
+
assert pubek.is_public?, 'TEM emission failed to produce a proper PubEK'
|
16
|
+
|
17
|
+
# verify the PrivEK against the ECert
|
18
|
+
ecert = @tem.endorsement_cert
|
19
|
+
ecert.verify privek.ssl_key
|
20
|
+
|
21
|
+
@tem.tk_delete_key 0, er[:privek_auth]
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemMemoryTest < TemTestCase
|
4
|
+
def test_memory
|
5
|
+
sec = @tem.assemble { |s|
|
6
|
+
s.label :clobber
|
7
|
+
s.ldbc 32
|
8
|
+
s.label :clobber2
|
9
|
+
s.outnew
|
10
|
+
s.ldwc 0x55AA
|
11
|
+
s.stw :clobber
|
12
|
+
s.ldb :clobber
|
13
|
+
s.outw
|
14
|
+
s.ldw :clobber
|
15
|
+
s.outw
|
16
|
+
s.ldbc 0xA5 - (1 << 8)
|
17
|
+
s.stb :clobber
|
18
|
+
s.ldw :clobber
|
19
|
+
s.outw
|
20
|
+
s.ldwc :clobber2
|
21
|
+
s.dupn :n => 1
|
22
|
+
s.dupn :n => 2
|
23
|
+
s.ldwc 0x9966 - (1 << 16)
|
24
|
+
s.stwv
|
25
|
+
s.ldbv
|
26
|
+
s.outw
|
27
|
+
s.ldbc 0x98 - (1 << 8)
|
28
|
+
s.stbv
|
29
|
+
s.ldwv
|
30
|
+
s.outw
|
31
|
+
s.ldwc 0x1122
|
32
|
+
s.ldwc 0x3344
|
33
|
+
s.ldwc 0x5566
|
34
|
+
s.flipn :n => 3
|
35
|
+
s.outw
|
36
|
+
s.outw
|
37
|
+
s.outw
|
38
|
+
s.halt
|
39
|
+
# Test stack without arguments.
|
40
|
+
s.stack
|
41
|
+
s.zeros :tem_short, 5
|
42
|
+
}
|
43
|
+
result = @tem.execute sec
|
44
|
+
assert_equal [0x00, 0x55, 0x55, 0xAA, 0xA5, 0xAA, 0xFF, 0x99, 0x98, 0x66,
|
45
|
+
0x11, 0x22, 0x33, 0x44, 0x55, 0x66],
|
46
|
+
result, 'the memory unit isn\'t working well'
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
module TemMemoryCompareTestCase
|
4
|
+
# This is also called from TemYamlSecpackTest.
|
5
|
+
def _test_memory_copy_compare(yaml_roundtrip = false)
|
6
|
+
sec = @tem.assemble { |s|
|
7
|
+
s.ldwc :const => 16
|
8
|
+
s.outnew
|
9
|
+
s.ldwc :const => 6
|
10
|
+
s.ldwc :cmp_med
|
11
|
+
s.ldwc :cmp_lo
|
12
|
+
s.mcmpvb
|
13
|
+
s.outw
|
14
|
+
s.mcmpfxb :size => 6, :op1 => :cmp_med, :op2 => :cmp_hi
|
15
|
+
s.outw
|
16
|
+
s.ldwc :const => 4
|
17
|
+
s.ldwc :cmp_lo
|
18
|
+
s.ldwc :cmp_med
|
19
|
+
s.mcmpvb
|
20
|
+
s.outw
|
21
|
+
|
22
|
+
s.mcfxb :size => 6, :from => :cmp_hi, :to => :copy_buf
|
23
|
+
s.pop
|
24
|
+
s.outfxb :size => 6, :from => :copy_buf
|
25
|
+
s.ldwc :const => 4
|
26
|
+
s.ldwc :cmp_hi
|
27
|
+
s.ldwc :copy_buf2
|
28
|
+
s.mcvb
|
29
|
+
s.pop
|
30
|
+
s.outfxb :size => 4, :from => :copy_buf2
|
31
|
+
|
32
|
+
s.halt
|
33
|
+
s.label :cmp_lo
|
34
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2C, 0x12]
|
35
|
+
s.label :cmp_med
|
36
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2D, 0x11]
|
37
|
+
s.label :cmp_hi
|
38
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
39
|
+
s.label :cmp_hi2
|
40
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
41
|
+
s.label :copy_buf
|
42
|
+
s.zeros :tem_ubyte, 6
|
43
|
+
s.label :copy_buf2
|
44
|
+
s.zeros :tem_ubyte, 4
|
45
|
+
s.stack 5
|
46
|
+
}
|
47
|
+
|
48
|
+
if yaml_roundtrip
|
49
|
+
# same test, except the SECpack is serialized/deserialized
|
50
|
+
yaml_sec = sec.to_yaml_str
|
51
|
+
sec = Tem::SecPack.new_from_yaml_str(yaml_sec)
|
52
|
+
end
|
53
|
+
result = @tem.execute sec
|
54
|
+
assert_equal [0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xA3, 0x2C, 0x51, 0x63,
|
55
|
+
0x2E, 0x10, 0xA3, 0x2C, 0x51, 0x63],
|
56
|
+
result, 'memory copy/compare isn\'t working well'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class TemMemoryCompareTest < TemTestCase
|
61
|
+
include TemMemoryCompareTestCase
|
62
|
+
def test_memory_copy_compare
|
63
|
+
_test_memory_copy_compare false
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
class TemOutputTest < TemTestCase
|
4
|
+
def test_output
|
5
|
+
sec = @tem.assemble { |s|
|
6
|
+
s.ldbc 32
|
7
|
+
s.outnew
|
8
|
+
s.outfxb :size => 3, :from => :area1
|
9
|
+
s.ldbc 5
|
10
|
+
s.outvlb :from => :area2
|
11
|
+
s.ldbc 4
|
12
|
+
s.ldwc :area3
|
13
|
+
s.outvb
|
14
|
+
s.ldwc 0x99AA - (1 << 16)
|
15
|
+
s.ldwc 0xFA55 - (1 << 16)
|
16
|
+
s.outb
|
17
|
+
s.outw
|
18
|
+
s.halt
|
19
|
+
s.label :area1
|
20
|
+
s.data :tem_ubyte, [0xFE, 0xCD, 0x9A]
|
21
|
+
s.label :area2
|
22
|
+
s.data :tem_ubyte, [0xAB, 0x95, 0xCE, 0xFD, 0x81]
|
23
|
+
s.label :area3
|
24
|
+
s.data :tem_ubyte, [0xEC, 0xDE, 0xAD, 0xCF]
|
25
|
+
s.stack 5
|
26
|
+
}
|
27
|
+
result = @tem.execute sec
|
28
|
+
assert_equal [0xFE, 0xCD, 0x9A, 0xAB, 0x95, 0xCE, 0xFD, 0x81, 0xEC, 0xDE,
|
29
|
+
0xAD, 0xCF, 0x55, 0x99, 0xAA],
|
30
|
+
result, 'the output unit isn\'t working well'
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test/tem_test_case'
|
2
|
+
|
3
|
+
require 'test/tem_unit/test_tem_bound_secpack'
|
4
|
+
require 'test/tem_unit/test_tem_memory_compare'
|
5
|
+
|
6
|
+
class TemOutputTest < TemTestCase
|
7
|
+
include TemBoundSecpackTestCase
|
8
|
+
include TemMemoryCompareTestCase
|
9
|
+
|
10
|
+
|
11
|
+
def test_yaml_secpack
|
12
|
+
# simple test to ensure that the body is preserved
|
13
|
+
sec = @tem.assemble { |s|
|
14
|
+
s.ldbc 10
|
15
|
+
s.outnew
|
16
|
+
s.ldwc 0x1234
|
17
|
+
s.ldwc 0x5678
|
18
|
+
s.dupn :n => 2
|
19
|
+
s.add
|
20
|
+
s.outw
|
21
|
+
s.sub
|
22
|
+
s.outw
|
23
|
+
s.ldwc 0x0155
|
24
|
+
s.ldwc 0x02AA
|
25
|
+
s.mul
|
26
|
+
s.outw
|
27
|
+
s.ldwc 0x390C
|
28
|
+
s.ldwc 0x00AA
|
29
|
+
s.dupn :n => 2
|
30
|
+
s.div
|
31
|
+
s.outw
|
32
|
+
s.mod
|
33
|
+
s.outw
|
34
|
+
s.halt
|
35
|
+
s.stack 5
|
36
|
+
}
|
37
|
+
yaml_sec = sec.to_yaml_str
|
38
|
+
sec2 = Tem::SecPack.new_from_yaml_str(yaml_sec)
|
39
|
+
assert_equal sec.body, sec2.body,
|
40
|
+
'SECpack body corrupted during serialization'
|
41
|
+
|
42
|
+
# re-run the memory test (reasonably large SECpack) to ensure that de-serialized SECpacks are equivalent to the originals
|
43
|
+
_test_memory_copy_compare true
|
44
|
+
# re-run the memory test (reasonably large SECpack) to ensure that serialization works on bound SECpacks
|
45
|
+
_test_bound_secpack true
|
46
|
+
end
|
47
|
+
end
|
data/test/test_exceptions.rb
CHANGED
@@ -5,16 +5,14 @@ class TemTimings
|
|
5
5
|
s.outnew
|
6
6
|
s.halt
|
7
7
|
s.label :secret
|
8
|
-
s.
|
8
|
+
s.zeros :tem_ubyte, 50
|
9
9
|
s.label :plain
|
10
|
-
s.
|
11
|
-
s.stack
|
12
|
-
s.extra 2
|
10
|
+
s.zeros :tem_ubyte, 220
|
11
|
+
s.stack 1
|
13
12
|
}
|
14
13
|
secpack.bind @tem.pubek, :secret, :plain
|
15
14
|
|
16
15
|
print "SECpack has #{secpack.body.length} bytes, runs 3 instructions and produces 0 bytes\n"
|
17
16
|
do_timing { @tem.execute secpack }
|
18
|
-
|
19
17
|
end
|
20
18
|
end
|
data/timings/blank_sec.rb
CHANGED
data/timings/timings.rb
CHANGED
@@ -44,16 +44,21 @@ class TemTimings
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.all_timings
|
47
|
+
timings = {}
|
47
48
|
t = TemTimings.new
|
48
49
|
t.setup
|
49
50
|
t.methods.select { |m| m =~ /time_/ }.each do |m|
|
50
51
|
print "Timing: #{m[5..-1]}...\n"
|
51
|
-
t.send m.to_sym
|
52
|
+
timings[m] = t.send m.to_sym
|
52
53
|
end
|
53
54
|
t.teardown
|
55
|
+
timings
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
57
59
|
if __FILE__ == $0
|
58
|
-
TemTimings.all_timings
|
60
|
+
timings = TemTimings.all_timings
|
61
|
+
timings.map { |k, v| [k.to_s, v] }.sort.each do |timing|
|
62
|
+
print "#{timing.first}: #{'%.5f' % timing.last}s\n"
|
63
|
+
end
|
59
64
|
end
|
data/timings/vm_perf.rb
CHANGED
@@ -116,24 +116,23 @@ class TemTimings
|
|
116
116
|
s.halt
|
117
117
|
|
118
118
|
s.label :cmp_lo
|
119
|
-
s.
|
119
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2C, 0x12]
|
120
120
|
s.label :cmp_med
|
121
|
-
s.
|
121
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2D, 0x11]
|
122
122
|
s.label :cmp_hi
|
123
|
-
s.
|
123
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
124
124
|
s.label :cmp_hi2
|
125
|
-
s.
|
125
|
+
s.data :tem_ubyte, [0xA3, 0x2C, 0x51, 0x63, 0x2E, 0x10]
|
126
126
|
s.label :copy_buf
|
127
|
-
s.
|
127
|
+
s.zeros :tem_ubyte, 6
|
128
128
|
s.label :copy_buf2
|
129
|
-
s.
|
129
|
+
s.zeros :tem_ubyte, 4
|
130
130
|
s.label :clobber
|
131
|
-
s.
|
131
|
+
s.zeros :tem_ubyte, 2
|
132
132
|
s.label :clobber2
|
133
|
-
s.
|
133
|
+
s.zeros :tem_ubyte, 2
|
134
134
|
s.label :stack
|
135
|
-
s.stack
|
136
|
-
s.extra 24
|
135
|
+
s.stack 12
|
137
136
|
}
|
138
137
|
print "SECpack has #{secpack.body.length} bytes, runs 1020 instructions and produces 470 bytes\n"
|
139
138
|
do_timing { @tem.execute secpack }
|