liberasurecode  1.6.1
Erasure Code API library
shss.c
Go to the documentation of this file.
1 /*
2  * Copyright(c) 2015 NTT corp. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice, this
11  * list of conditions and the following disclaimer in the documentation and/or
12  * other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY
13  * THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
14  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
17  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE,
19  * DATA, OR PROFITS;OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
21  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * liberasurecode shss backend
25  *
26  * Please contact us if you are insterested in the NTT backend (welcome!):
27  * Kota Tsuyuzaki <tsuyuzaki.kota@lab.ntt.co.jp>
28  *
29  * vi: set noai tw=79 ts=4 sw=4:
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 
35 #include "erasurecode.h"
36 #include "erasurecode_helpers.h"
37 #include "erasurecode_helpers_ext.h"
38 #include "erasurecode_backend.h"
39 
40 /* Forward declarations */
41 struct ec_backend shss;
42 struct ec_backend_op_stubs shss_ops;
43 struct ec_backend_common backend_shss;
44 
45 typedef int (*shss_encode_func)(char **, size_t, int, int, int, int, long long *);
46 typedef int (*shss_decode_func)(char **, size_t, int *, int, int, int, int, int, long long *);
47 typedef int (*shss_reconstruct_func)(char **, size_t, int *, int, int *, int, int, int, int, int, long long *);
48 
50  /* calls required for init */
54 
55  /* fields needed to hold state */
56  int k;
57  int m;
58  int n;
59  int w;
61 };
62 
63 #define SHSS_LIB_VER_STR "1.0"
64 #define SHSS_LIB_NAME "shss"
65 #if defined(__MACOS__) || defined(__MACOSX__) || defined(__OSX__) || defined(__APPLE__)
66 #define SHSS_SO_NAME "libshss.dylib"
67 #else
68 #define SHSS_SO_NAME "libshss.so.1"
69 #endif
70 #define DEFAULT_W 128
71 #define METADATA 32
72 
73 static int shss_encode(void *desc, char **data, char **parity,
74  int blocksize)
75 {
76  int i;
77  int ret = 0;
78  int priv_bitnum = 128; // privacy bit number 0 or 128(default) or 256
79  int chksum = 0; // chksum 0 or 64
80  char **encoded;
81  long long einfo;
82  struct shss_descriptor *xdesc =
83  (struct shss_descriptor *) desc;
84 
85  if (xdesc->aes_bit_length != -1) {
86  priv_bitnum = xdesc->aes_bit_length;
87  }
88 
89  encoded = alloca(sizeof(char*)*xdesc->n);
90 
91  for (i = 0; i<xdesc->k; i++) encoded[i] = (char*)data[i];
92  for (i = 0; i<xdesc->m; i++) encoded[i+xdesc->k] = (char*)parity[i];
93 
94  ret = xdesc->ssencode((char**)encoded, (size_t)blocksize,
95  xdesc->k, xdesc->m, priv_bitnum, chksum, &einfo);
96 
97  if (ret > 0) {
98  return -ret;
99  }
100 
101  return 0;
102 }
103 
104 static int shss_decode(void *desc, char **data, char **parity,
105  int *missing_idxs, int blocksize)
106 {
107  int i;
108  int missing_size = 0;
109  int ret = 0;
110  int priv_bitnum = 128; // privacy bit number 0 or 128(default) or 256
111  int chksum = 0; // chksum 0 or 64
112  char **decoded;
113  long long einfo;
114  struct shss_descriptor *xdesc =
115  (struct shss_descriptor *) desc;
116 
117  if (xdesc->aes_bit_length != -1) {
118  priv_bitnum = xdesc->aes_bit_length;
119  }
120 
121  decoded = alloca(sizeof(char*)*xdesc->n);
122 
123  for (i = 0; i<xdesc->k; i++) decoded[i] = (char*)data[i];
124  for (i = 0; i<xdesc->m; i++) decoded[i+xdesc->k] = (char*)parity[i];
125  for (i = 0; i<xdesc->n; i++) {
126  if (i == missing_idxs[missing_size]) {
127  missing_size++;
128  }
129  }
130 
131  ret = xdesc->ssdecode((char**)decoded, (size_t)blocksize, missing_idxs, missing_size,
132  xdesc->k, xdesc->m, priv_bitnum, chksum, &einfo);
133 
134  if (ret > 0) {
135  return -ret;
136  }
137 
138  return 0;
139 }
140 
141 static int shss_reconstruct(void *desc, char **data, char **parity,
142  int *missing_idxs, int destination_idx, int blocksize)
143 {
144  int i;
145  int missing_size = 0;
146  int ret = 0;
147  int priv_bitnum = 128; // privacy bit number 0 or 128(default) or 256
148  int chksum = 0; // chksum 0 or 64
149  int dst_size = 1;
150  char **reconstructed;
151  long long einfo;
152  struct shss_descriptor *xdesc =
153  (struct shss_descriptor *) desc;
154 
155  if (xdesc->aes_bit_length != -1) {
156  priv_bitnum = xdesc->aes_bit_length;
157  }
158 
159  reconstructed = alloca(sizeof(char*)*xdesc->n);
160 
161  for (i = 0; i<xdesc->k; i++) reconstructed[i] = (char*)data[i];
162  for (i = 0; i<xdesc->m; i++) reconstructed[i+xdesc->k] = (char*)parity[i];
163  for (i = 0; i<xdesc->n; i++) {
164  if (i == missing_idxs[missing_size]) {
165  missing_size++;
166  }
167  }
168 
169  ret = xdesc->ssreconst((char**)reconstructed, (size_t)blocksize,
170  &destination_idx, dst_size, missing_idxs, missing_size, xdesc->k,
171  xdesc->m, priv_bitnum, chksum, &einfo);
172 
173  if (ret > 0) {
174  return -ret;
175  }
176 
177  return 0;
178 }
179 
180 static int shss_fragments_needed(void *desc, int *missing_idxs,
181  int *fragments_to_exclude, int *fragments_needed)
182 {
183  struct shss_descriptor *xdesc =
184  (struct shss_descriptor *) desc;
185  uint64_t exclude_bm = convert_list_to_bitmap(fragments_to_exclude);
186  uint64_t missing_bm = convert_list_to_bitmap(missing_idxs) | exclude_bm;
187  int i;
188  int j = 0;
189  int ret = -101;
190 
191  for (i = 0; i < xdesc->n; i++) {
192  if (!(missing_bm & (1 << i))) {
193  fragments_needed[j] = i;
194  j++;
195  }
196  if (j == xdesc->k) {
197  ret = 0;
198  fragments_needed[j] = -1;
199  break;
200  }
201  }
202 
203  return ret;
204 }
205 
210 static int shss_element_size(void* desc)
211 {
212  return DEFAULT_W;
213 }
214 
215 static void * shss_init(struct ec_backend_args *args, void *backend_sohandle)
216 {
217  struct shss_descriptor *desc = NULL;
218 
219  desc = (struct shss_descriptor *)
220  malloc(sizeof(struct shss_descriptor));
221  if (NULL == desc) {
222  return NULL;
223  }
224 
225  desc->k = args->uargs.k;
226  desc->m = args->uargs.m;
227  desc->n = args->uargs.k + args->uargs.m;
228  desc->w = DEFAULT_W;
229  args->uargs.w = DEFAULT_W;
230 
231  /* Sample on how to pass extra args to the backend */
232  // TODO: Need discussion how to pass extra args.
233  // tentatively we could pass with priv_args2 as the bit_length
234  int *priv = (int *)args->uargs.priv_args2;
235  if(priv != NULL){
236  desc->aes_bit_length = priv[0]; // AES bit number
237  }else{
238  desc->aes_bit_length = 128;
239  }
240 
241  union {
242  shss_encode_func encodep;
243  shss_decode_func decodep;
244  shss_reconstruct_func reconp;
245  void *vptr;
246  } func_handle;
247 
248  func_handle.vptr = NULL;
249  func_handle.vptr = dlsym(backend_sohandle, "ssencode");
250  desc->ssencode = func_handle.encodep;
251  if (NULL == desc->ssencode) {
252  goto error;
253  }
254 
255  func_handle.vptr = NULL;
256  func_handle.vptr = dlsym(backend_sohandle, "ssdecode");
257  desc->ssdecode = func_handle.decodep;
258  if (NULL == desc->ssdecode) {
259  goto error;
260  }
261 
262  func_handle.vptr = NULL;
263  func_handle.vptr = dlsym(backend_sohandle, "ssreconst");
264  desc->ssreconst = func_handle.reconp;
265  if (NULL == desc->ssreconst) {
266  goto error;
267  }
268 
269  return desc;
270 
271 error:
272  free(desc);
273 
274  return NULL;
275 }
276 
277 static int shss_exit(void *desc)
278 {
279  if (desc != NULL) {
280  free(desc);
281  }
282  return 0;
283 }
284 
285 static bool shss_is_compatible_with(uint32_t version) {
286  return version == backend_shss.ec_backend_version;
287 }
288 
289 static size_t shss_get_backend_metadata_size(void *desc, int blocksize) {
290  return METADATA;
291 }
292 
293 struct ec_backend_op_stubs shss_op_stubs = {
294  .INIT = shss_init,
295  .EXIT = shss_exit,
296  .ENCODE = shss_encode,
297  .DECODE = shss_decode,
298  .FRAGSNEEDED = shss_fragments_needed,
299  .RECONSTRUCT = shss_reconstruct,
300  .ELEMENTSIZE = shss_element_size,
301  .ISCOMPATIBLEWITH = shss_is_compatible_with,
302  .GETMETADATASIZE = shss_get_backend_metadata_size,
303  .GETENCODEOFFSET = get_encode_offset_zero,
304 };
305 
306 struct ec_backend_common backend_shss = {
307  .id = EC_BACKEND_SHSS,
308  .name = SHSS_LIB_NAME,
309  .soname = SHSS_SO_NAME,
310  .soversion = SHSS_LIB_VER_STR,
311  .ops = &shss_op_stubs,
312 };
#define METADATA
Definition: shss.c:71
struct ec_backend_common backend_shss
Definition: shss.c:43
#define SHSS_LIB_VER_STR
Definition: shss.c:63
static int shss_decode(void *desc, char **data, char **parity, int *missing_idxs, int blocksize)
Definition: shss.c:104
struct ec_backend shss
Definition: shss.c:41
int(* shss_decode_func)(char **, size_t, int *, int, int, int, int, int, long long *)
Definition: shss.c:46
static int shss_fragments_needed(void *desc, int *missing_idxs, int *fragments_to_exclude, int *fragments_needed)
Definition: shss.c:180
static int shss_encode(void *desc, char **data, char **parity, int blocksize)
Definition: shss.c:73
#define SHSS_SO_NAME
Definition: shss.c:68
int(* shss_reconstruct_func)(char **, size_t, int *, int, int *, int, int, int, int, int, long long *)
Definition: shss.c:47
int(* shss_encode_func)(char **, size_t, int, int, int, int, long long *)
Definition: shss.c:45
static void * shss_init(struct ec_backend_args *args, void *backend_sohandle)
Definition: shss.c:215
static int shss_exit(void *desc)
Definition: shss.c:277
static bool shss_is_compatible_with(uint32_t version)
Definition: shss.c:285
static int shss_reconstruct(void *desc, char **data, char **parity, int *missing_idxs, int destination_idx, int blocksize)
Definition: shss.c:141
struct ec_backend_op_stubs shss_ops
Definition: shss.c:42
static size_t shss_get_backend_metadata_size(void *desc, int blocksize)
Definition: shss.c:289
#define SHSS_LIB_NAME
Definition: shss.c:64
#define DEFAULT_W
Definition: shss.c:70
static int shss_element_size(void *desc)
Return the element-size, which is the number of bits stored on a given device, per codeword.
Definition: shss.c:210
struct ec_backend_op_stubs shss_op_stubs
Definition: shss.c:293
shss_decode_func ssdecode
Definition: shss.c:52
int aes_bit_length
Definition: shss.c:60
shss_reconstruct_func ssreconst
Definition: shss.c:53
shss_encode_func ssencode
Definition: shss.c:51