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/hive.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
# The TEM's configuation hive
|
5
|
+
module Tem::Hive
|
6
|
+
@@hive_dir = File.join(Gem.user_home, ".tem")
|
7
|
+
|
8
|
+
def self.path_to(*hive_entry)
|
9
|
+
File.join(@@hive_dir, *hive_entry)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create(*hive_entry)
|
13
|
+
path = File.join(@@hive_dir, *hive_entry)
|
14
|
+
FileUtils.mkdir_p File.dirname(path)
|
15
|
+
File.open(path, "w") { |f| }
|
16
|
+
return path
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# :nodoc: namespace
|
2
|
+
module Tem::Keys
|
3
|
+
|
4
|
+
# Wraps a TEM asymmetric key, e.g. an RSA key.
|
5
|
+
class Asymmetric < Tem::Key
|
6
|
+
def self.new_from_array(array)
|
7
|
+
self.new(OpenSSL::PKey::RSA.new(array[0]), *array[1..-1])
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.new_from_yaml_str(yaml_str)
|
11
|
+
array = YAML.load yaml_str
|
12
|
+
new_from_array array
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_array
|
16
|
+
[@ssl_key.to_pem, @padding_type]
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_yaml_str
|
20
|
+
self.to_array.to_yaml.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
# Generate a pair of asymmetric keys.
|
24
|
+
def self.generate_pair
|
25
|
+
ssl_key = OpenSSL::PKey::RSA.generate(2048, 65537)
|
26
|
+
new_pair_from_ssl_key ssl_key
|
27
|
+
end
|
28
|
+
|
29
|
+
# Creates a pair of asymmetric keys wrapping an OpenSSL private key.
|
30
|
+
def self.new_pair_from_ssl_key(ssl_key)
|
31
|
+
{ :public => Tem::Keys::Asymmetric.new(ssl_key.public_key),
|
32
|
+
:private => Tem::Keys::Asymmetric.new(ssl_key) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(ssl_key, padding_type = :pkcs1)
|
36
|
+
super ssl_key
|
37
|
+
@is_public = !ssl_key.d
|
38
|
+
@padding_type = padding_type
|
39
|
+
|
40
|
+
case padding_type
|
41
|
+
when :oaep
|
42
|
+
@padding_id = OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
|
43
|
+
@padding_bytes = 42
|
44
|
+
when :pkcs1
|
45
|
+
@padding_id = OpenSSL::PKey::RSA::PKCS1_PADDING
|
46
|
+
@padding_bytes = 11
|
47
|
+
else
|
48
|
+
raise "Unknown padding type #{padding_type}\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
@size = 0
|
52
|
+
n = @is_public ? @ssl_key.n : (@ssl_key.p * @ssl_key.q)
|
53
|
+
while n != 0 do
|
54
|
+
@size += 1
|
55
|
+
n >>= 8
|
56
|
+
end
|
57
|
+
end
|
58
|
+
public_class_method :new
|
59
|
+
|
60
|
+
def is_public?
|
61
|
+
@is_public
|
62
|
+
end
|
63
|
+
|
64
|
+
def encrypt(data)
|
65
|
+
encrypt_or_decrypt data, @size - @padding_bytes,
|
66
|
+
@is_public ? :public_encrypt : :private_encrypt
|
67
|
+
end
|
68
|
+
|
69
|
+
def decrypt(data)
|
70
|
+
encrypt_or_decrypt data, @size,
|
71
|
+
@is_public ? :public_decrypt : :private_decrypt
|
72
|
+
end
|
73
|
+
|
74
|
+
def sign(data)
|
75
|
+
data = data.pack 'C*' if data.respond_to? :pack
|
76
|
+
# PKCS1-padding is forced in by openssl... sigh!
|
77
|
+
out_data = @ssl_key.sign OpenSSL::Digest::SHA1.new, data
|
78
|
+
data.respond_to?(:pack) ? out_data : out_data.unpack('C*')
|
79
|
+
end
|
80
|
+
|
81
|
+
def verify(data, signature)
|
82
|
+
data = data.pack 'C*' if data.respond_to? :pack
|
83
|
+
signature = signature.pack 'C*' if signature.respond_to? :pack
|
84
|
+
# PKCS1-padding is forced in by openssl... sigh!
|
85
|
+
@ssl_key.verify OpenSSL::Digest::SHA1.new, signature, data
|
86
|
+
end
|
87
|
+
|
88
|
+
def encrypt_or_decrypt(data, in_size, op)
|
89
|
+
chug_data(data, in_size) { |block| @ssl_key.send op, block, @padding_id }
|
90
|
+
end
|
91
|
+
private :encrypt_or_decrypt
|
92
|
+
|
93
|
+
def chug_data(data, in_size, &chug_block)
|
94
|
+
output = data.class.new
|
95
|
+
i = 0
|
96
|
+
while i < data.length do
|
97
|
+
block_size = (data.length - i < in_size) ? data.length - i : in_size
|
98
|
+
if data.kind_of? String
|
99
|
+
block = data[i...(i+block_size)]
|
100
|
+
else
|
101
|
+
block = data[i...(i+block_size)].pack('C*')
|
102
|
+
end
|
103
|
+
o_block = yield block
|
104
|
+
if data.kind_of? String
|
105
|
+
output += o_block
|
106
|
+
else
|
107
|
+
output += o_block.unpack('C*')
|
108
|
+
end
|
109
|
+
i += block_size
|
110
|
+
end
|
111
|
+
return output
|
112
|
+
end
|
113
|
+
private :chug_data
|
114
|
+
end
|
115
|
+
|
116
|
+
end # namespace Tem::Keys
|
data/lib/tem/keys/key.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# Base class for the TEM keys.
|
2
|
+
#
|
3
|
+
# This class consists of stubs describing the interface implemented by
|
4
|
+
# subclasses.
|
5
|
+
class Tem::Key
|
6
|
+
# The OpenSSL key wrapped by this TEM key.
|
7
|
+
attr_reader :ssl_key
|
8
|
+
|
9
|
+
# Creates a new key based on an OpenSSL key.
|
10
|
+
def initialize(ssl_key)
|
11
|
+
@ssl_key = ssl_key
|
12
|
+
end
|
13
|
+
# This class should not be instantiated directly.
|
14
|
+
private_class_method :new
|
15
|
+
|
16
|
+
# Serializes this key to the TEM ABI format.
|
17
|
+
def to_tem_key
|
18
|
+
Tem::Abi.to_tem_key self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Encrypts a block of data into a TEM-friendly format.
|
22
|
+
def encrypt(data)
|
23
|
+
raise "TEM Key class #{self.class.name} didn't implement encrypt"
|
24
|
+
end
|
25
|
+
|
26
|
+
def decrypt(data)
|
27
|
+
raise "TEM Key class #{self.class.name} didn't implement decrypt"
|
28
|
+
end
|
29
|
+
|
30
|
+
def sign(data)
|
31
|
+
raise "TEM Key class #{self.class.name} didn't implement sign"
|
32
|
+
end
|
33
|
+
|
34
|
+
def verify(data)
|
35
|
+
raise "TEM Key class #{self.class.name} didn't implement verify"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Creates a new TEM key wrapper from a SSL key
|
39
|
+
def self.new_from_ssl_key(ssl_key)
|
40
|
+
if ssl_key.kind_of? OpenSSL::PKey::PKey
|
41
|
+
Tem::Keys::Asymmetric.new ssl_key
|
42
|
+
elsif ssl_key.kind_of? OpenSSL::Cipher::Cipher
|
43
|
+
Tem::Keys::Symmetric.new ssl_key
|
44
|
+
else
|
45
|
+
raise "Can't handle keys of class #{ssl_key.class}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# :nodoc: namespace
|
2
|
+
module Tem::Keys
|
3
|
+
|
4
|
+
# Wraps a TEM symmetric key, e.g. an AES key.
|
5
|
+
class Symmetric < Tem::Key
|
6
|
+
@@cipher_mode = 'ECB'
|
7
|
+
|
8
|
+
# Generates a new symmetric key.
|
9
|
+
def self.generate
|
10
|
+
cipher = OpenSSL::Cipher::AES128.new @@cipher_mode
|
11
|
+
key = cipher.random_key
|
12
|
+
self.new key
|
13
|
+
end
|
14
|
+
|
15
|
+
# Creates a new symmetric key based on an OpenSSL Cipher instance, augmented
|
16
|
+
# with a key accessor.
|
17
|
+
def initialize(ssl_key)
|
18
|
+
super ssl_key
|
19
|
+
@key = ssl_key.key
|
20
|
+
@cipher_class = ssl_key.class
|
21
|
+
end
|
22
|
+
public_class_method :new
|
23
|
+
|
24
|
+
def encrypt_or_decrypt(data, do_encrypt)
|
25
|
+
cipher = @cipher_class.new @@cipher_mode
|
26
|
+
do_encrypt ? cipher.encrypt : cipher.decrypt
|
27
|
+
cipher.key = @key
|
28
|
+
cipher.iv = "\0" * 16
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def encrypt(data)
|
33
|
+
cipher.encrypt_or_decrypt data, true
|
34
|
+
end
|
35
|
+
|
36
|
+
def decrypt(data)
|
37
|
+
cipher.encrypt_or_decrypt data, false
|
38
|
+
end
|
39
|
+
|
40
|
+
def sign(data)
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify(data)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end # namespace Tem::Keys
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# raised when executing a SEC
|
2
|
+
class Tem::SecExecError < StandardError
|
3
|
+
attr_reader :line_info
|
4
|
+
attr_reader :buffer_state, :key_state
|
5
|
+
attr_reader :trace
|
6
|
+
|
7
|
+
def initialize(line_info, tem_trace, buffer_state, key_state)
|
8
|
+
super 'SEC execution failed on the TEM'
|
9
|
+
@line_info = line_info
|
10
|
+
line_ip, atom, backtrace = *line_info
|
11
|
+
@atom = atom
|
12
|
+
if tem_trace and tem_trace[:ip]
|
13
|
+
@ip_delta = tem_trace[:ip] - line_ip
|
14
|
+
else
|
15
|
+
@ip_delta = 0
|
16
|
+
end
|
17
|
+
@trace = tem_trace
|
18
|
+
@buffer_state = buffer_state
|
19
|
+
@key_state = key_state
|
20
|
+
set_backtrace backtrace
|
21
|
+
end
|
22
|
+
|
23
|
+
def bstat_str
|
24
|
+
if @buffer_state.nil?
|
25
|
+
"no buffer state available"
|
26
|
+
else
|
27
|
+
@buffer_state.inspect
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def kstat_str
|
32
|
+
if @key_state.nil?
|
33
|
+
"no key state available"
|
34
|
+
else
|
35
|
+
@key_state.inspect
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def trace_str
|
40
|
+
if @trace.nil?
|
41
|
+
"no trace available"
|
42
|
+
else
|
43
|
+
"ip=#{'%04x' % @trace[:ip]} sp=#{'%04x' % @trace[:sp]} out=#{'%04x' % @trace[:out]} pscell=#{'%04x' % @trace[:pscell]}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
string = <<ENDSTRING
|
49
|
+
SECpack execution generated an exception on the TEM
|
50
|
+
|
51
|
+
TEM Trace: #{trace_str}
|
52
|
+
TEM Buffer Status:#{bstat_str}
|
53
|
+
TEM Key Status:#{kstat_str}
|
54
|
+
|
55
|
+
TEM execution error at #{@atom}+#{@ip_delta}
|
56
|
+
ENDSTRING
|
57
|
+
string.strip
|
58
|
+
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
trace_str + "\n" + bstat_str + "\n" + kstat_str
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Tem::SeClosures
|
4
|
+
module MixedMethods
|
5
|
+
def assemble(&block)
|
6
|
+
return Tem::Assembler.assemble(&block)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
include MixedMethods
|
11
|
+
def self.included(klass)
|
12
|
+
klass.extend MixedMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
def sec_trace
|
16
|
+
#begin
|
17
|
+
trace = @transport.applet_apdu! :ins => 0x54
|
18
|
+
if trace.length > 2
|
19
|
+
case read_tem_short(trace, 0) # trace version
|
20
|
+
when 1
|
21
|
+
return {:sp => read_tem_short(trace, 2), :ip => read_tem_short(trace, 4),
|
22
|
+
:out => read_tem_short(trace, 6), :pscell => read_tem_short(trace, 8)}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
return nil # unreadable trace
|
26
|
+
#rescue
|
27
|
+
# return nil
|
28
|
+
#end
|
29
|
+
end
|
30
|
+
|
31
|
+
def solve_psfault
|
32
|
+
# TODO: better strategy, lol
|
33
|
+
next_cell = rand(16)
|
34
|
+
@transport.applet_apdu! :ins => 0x53, :p12 => to_tem_ushort(next_cell)
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute(secpack, key_id = 0)
|
38
|
+
# load SECpack
|
39
|
+
buffer_id = post_buffer(secpack.tem_formatted_body)
|
40
|
+
response = @transport.applet_apdu! :ins => 0x50, :p1 => buffer_id,
|
41
|
+
:p2 => key_id
|
42
|
+
tem_secpack_error(response) if read_tem_byte(response, 0) != 1
|
43
|
+
|
44
|
+
# execute SEC
|
45
|
+
sec_exception = nil
|
46
|
+
loop do
|
47
|
+
response = @transport.applet_apdu! :ins => 0x52
|
48
|
+
sec_status = read_tem_byte(response, 0)
|
49
|
+
case sec_status
|
50
|
+
when 2 # success
|
51
|
+
break
|
52
|
+
when 3 # exception
|
53
|
+
# there is an exception, try to collect the trace
|
54
|
+
b_stat = stat_buffers() rescue nil
|
55
|
+
k_stat = stat_keys() rescue nil
|
56
|
+
trace = sec_trace()
|
57
|
+
if trace and trace[:ip]
|
58
|
+
line_info = secpack.line_info_for_ip(trace[:ip])
|
59
|
+
else
|
60
|
+
line_info = [0, :unknown, Kernel.caller]
|
61
|
+
end
|
62
|
+
sec_exception = Tem::SecExecError.new line_info, trace, b_stat, k_stat
|
63
|
+
break
|
64
|
+
when 4 # persistent store fault
|
65
|
+
solve_psfault
|
66
|
+
else
|
67
|
+
raise "Unrecognized execution engine status #{sec_status}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# unbind SEC
|
72
|
+
response = @transport.applet_apdu! :ins => 0x51
|
73
|
+
raise sec_exception if sec_exception
|
74
|
+
buffer_id = read_tem_byte(response, 0)
|
75
|
+
buffer_length = read_tem_short(response, 1)
|
76
|
+
data_buffer = read_buffer buffer_id
|
77
|
+
release_buffer buffer_id
|
78
|
+
|
79
|
+
return data_buffer[0...buffer_length]
|
80
|
+
end
|
81
|
+
end
|
data/lib/tem/secpack.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class Tem::SecPack
|
4
|
+
@@serialized_ivars = [:body, :labels, :ep, :sp, :extra_bytes, :signed_bytes,
|
5
|
+
:encrypted_bytes, :bound, :lines]
|
6
|
+
|
7
|
+
def self.new_from_array(array)
|
8
|
+
arg_hash = { }
|
9
|
+
@@serialized_ivars.each_with_index { |name, i| arg_hash[name] = array[i] }
|
10
|
+
self.new arg_hash
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.new_from_yaml_str(yaml_str)
|
14
|
+
array = YAML.load yaml_str
|
15
|
+
new_from_array array
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_array
|
19
|
+
@@serialized_ivars.map { |m| self.instance_variable_get :"@#{m}" }
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_yaml_str
|
23
|
+
self.to_array.to_yaml.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :body, :bound
|
27
|
+
attr_reader :lines
|
28
|
+
|
29
|
+
def trim_extra_bytes
|
30
|
+
@extra_bytes = 0
|
31
|
+
while @extra_bytes < @body.length
|
32
|
+
break if @body[-@extra_bytes - 1] != 0
|
33
|
+
@extra_bytes += 1
|
34
|
+
end
|
35
|
+
@body.slice! @body.length - @extra_bytes, @extra_bytes
|
36
|
+
end
|
37
|
+
|
38
|
+
def expand_extra_bytes
|
39
|
+
@body += [0] * @extra_bytes
|
40
|
+
@extra_bytes = 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(args)
|
44
|
+
@@serialized_ivars.map { |m| self.instance_variable_set :"@#{m}", args[m] }
|
45
|
+
@bound ||= false
|
46
|
+
|
47
|
+
@extra_bytes ||= 0
|
48
|
+
# trim_extra_bytes if @extra_bytes == 0
|
49
|
+
end
|
50
|
+
|
51
|
+
def label_address(label_name)
|
52
|
+
@labels[label_name.to_sym]
|
53
|
+
end
|
54
|
+
|
55
|
+
def bind(public_key, encrypt_from = 0, plaintext_from = 0)
|
56
|
+
expand_extra_bytes
|
57
|
+
encrypt_from = @labels[encrypt_from.to_sym] unless encrypt_from.kind_of? Numeric
|
58
|
+
plaintext_from = @labels[plaintext_from.to_sym] unless plaintext_from.kind_of? Numeric
|
59
|
+
|
60
|
+
@signed_bytes = encrypt_from
|
61
|
+
@encrypted_bytes = plaintext_from - encrypt_from
|
62
|
+
|
63
|
+
secpack_sig = Tem::Abi.tem_hash [tem_header, @body[0...plaintext_from]].flatten
|
64
|
+
crypt = public_key.encrypt [@body[encrypt_from...plaintext_from], secpack_sig].flatten
|
65
|
+
@body = [@body[0...encrypt_from], crypt, @body[plaintext_from..-1]].flatten
|
66
|
+
|
67
|
+
label_delta = crypt.length - @encrypted_bytes
|
68
|
+
@labels = Hash[*(@labels.map { |k, v|
|
69
|
+
if v < encrypt_from
|
70
|
+
[k, v]
|
71
|
+
elsif v < plaintext_from
|
72
|
+
[]
|
73
|
+
else
|
74
|
+
[k, v + label_delta]
|
75
|
+
end
|
76
|
+
}.flatten)]
|
77
|
+
|
78
|
+
#trim_extra_bytes
|
79
|
+
@bound = true
|
80
|
+
end
|
81
|
+
|
82
|
+
def tem_header
|
83
|
+
# TODO: use 0x0100 (no tracing) depending on options
|
84
|
+
hh = [0x0101, @signed_bytes || 0, @encrypted_bytes || 0, @extra_bytes, @sp,
|
85
|
+
@ep].map { |n| Tem::Abi.to_tem_ushort n }.flatten
|
86
|
+
hh += Array.new((Tem::Abi.tem_hash [0]).length - hh.length, 0)
|
87
|
+
return hh
|
88
|
+
end
|
89
|
+
private :tem_header
|
90
|
+
|
91
|
+
def tem_formatted_body
|
92
|
+
# HACK: Ideally, we would allocate a bigger buffer, and then only fill part
|
93
|
+
# of it. Realistically, we'll just send in extra_bytes 0s.
|
94
|
+
[tem_header, @body, [0] * @extra_bytes].flatten
|
95
|
+
end
|
96
|
+
|
97
|
+
def line_info_for_ip(ip)
|
98
|
+
return nil unless @lines
|
99
|
+
|
100
|
+
@lines.reverse_each do |info|
|
101
|
+
# If something breaks, it's likely to happen after the opcode of the
|
102
|
+
# offending instruction has been read, so assume offending_ip < ip.
|
103
|
+
return info if ip >= info[0]
|
104
|
+
end
|
105
|
+
return info.first
|
106
|
+
end
|
107
|
+
end
|