PyORAm
[iotcloud.git] / PyORAM / src / pyoram / encrypted_storage / encrypted_heap_storage.py
1 __all__ = ('EncryptedHeapStorage',)
2
3 import struct
4
5 from pyoram.util.virtual_heap import SizedVirtualHeap
6 from pyoram.storage.heap_storage import \
7     (HeapStorageInterface,
8      HeapStorage)
9 from pyoram.encrypted_storage.encrypted_block_storage import \
10     (EncryptedBlockStorageInterface,
11      EncryptedBlockStorage)
12
13 class EncryptedHeapStorageInterface(HeapStorageInterface):
14
15     #
16     # Abstract Interface
17     #
18
19     @property
20     def key(self, *args, **kwds):
21         raise NotImplementedError                      # pragma: no cover
22     @property
23     def raw_storage(self, *args, **kwds):
24         raise NotImplementedError                      # pragma: no cover
25
26 class EncryptedHeapStorage(HeapStorage,
27                            EncryptedHeapStorageInterface):
28
29     def __init__(self, storage, **kwds):
30
31         if isinstance(storage, EncryptedBlockStorageInterface):
32             if len(kwds):
33                 raise ValueError(
34                     "Keywords not used when initializing "
35                     "with a storage device: %s"
36                     % (str(kwds)))
37         else:
38             storage = EncryptedBlockStorage(storage, **kwds)
39
40         super(EncryptedHeapStorage, self).__init__(storage)
41
42     #
43     # Define EncryptedHeapStorageInterface Methods
44     #
45
46     @property
47     def key(self):
48         return self._storage.key
49
50     @property
51     def raw_storage(self):
52         return self._storage.raw_storage
53
54     #
55     # Define HeapStorageInterface Methods
56     # (override what is defined on HeapStorage)
57
58     def clone_device(self):
59         return EncryptedHeapStorage(self._storage.clone_device())
60
61     @classmethod
62     def compute_storage_size(cls,
63                              block_size,
64                              heap_height,
65                              blocks_per_bucket=1,
66                              heap_base=2,
67                              ignore_header=False,
68                              **kwds):
69         assert (block_size > 0) and (block_size == int(block_size))
70         assert heap_height >= 0
71         assert blocks_per_bucket >= 1
72         assert heap_base >= 2
73         assert 'block_count' not in kwds
74         vheap = SizedVirtualHeap(
75             heap_base,
76             heap_height,
77             blocks_per_bucket=blocks_per_bucket)
78         if ignore_header:
79             return EncryptedBlockStorage.compute_storage_size(
80                 vheap.blocks_per_bucket * block_size,
81                 vheap.bucket_count(),
82                 ignore_header=True,
83                 **kwds)
84         else:
85             return cls._header_offset + \
86                    EncryptedBlockStorage.compute_storage_size(
87                        vheap.blocks_per_bucket * block_size,
88                        vheap.bucket_count(),
89                        ignore_header=False,
90                        **kwds)
91
92     @classmethod
93     def setup(cls,
94               storage_name,
95               block_size,
96               heap_height,
97               blocks_per_bucket=1,
98               heap_base=2,
99               **kwds):
100         if 'block_count' in kwds:
101             raise ValueError("'block_count' keyword is not accepted")
102         if heap_height < 0:
103             raise ValueError(
104                 "heap height must be 0 or greater. Invalid value: %s"
105                 % (heap_height))
106         if blocks_per_bucket < 1:
107             raise ValueError(
108                 "blocks_per_bucket must be 1 or greater. "
109                 "Invalid value: %s" % (blocks_per_bucket))
110         if heap_base < 2:
111             raise ValueError(
112                 "heap base must be 2 or greater. Invalid value: %s"
113                 % (heap_base))
114
115         vheap = SizedVirtualHeap(
116             heap_base,
117             heap_height,
118             blocks_per_bucket=blocks_per_bucket)
119
120         user_header_data = kwds.pop('header_data', bytes())
121         if type(user_header_data) is not bytes:
122             raise TypeError(
123                 "'header_data' must be of type bytes. "
124                 "Invalid type: %s" % (type(user_header_data)))
125         kwds['header_data'] = \
126             struct.pack(cls._header_struct_string,
127                         heap_base,
128                         heap_height,
129                         blocks_per_bucket) + \
130             user_header_data
131
132         return EncryptedHeapStorage(
133             EncryptedBlockStorage.setup(
134                 storage_name,
135                 vheap.blocks_per_bucket * block_size,
136                 vheap.bucket_count(),
137                 **kwds))
138
139     #@property
140     #def header_data(...)
141
142     #@property
143     #def bucket_count(...)
144
145     #@property
146     #def bucket_size(...)
147
148     #@property
149     #def blocks_per_bucket(...)
150
151     #@property
152     #def storage_name(...)
153
154     #@property
155     #def virtual_heap(...)
156
157     #@property
158     #def bucket_storage(...)
159
160     #def update_header_data(...)
161
162     #def close(...)
163
164     #def read_path(...)
165
166     #def write_path(...)
167
168     #@property
169     #def bytes_sent(...)
170
171     #@property
172     #def bytes_received(...)