/ sigs.c
sigs.c
  1  #include <stdlib.h>
  2  #include <string.h>
  3  #include <lscore/index.h>
  4  #include <lscore/plugin.h>
  5  #include <lsplugin/mkobject.h>
  6  #include <lsplugin/mkoperator.h>
  7  #include <lsplugin/param.h>
  8  #include <oqs/sig.h>
  9  #include "local.h"
 10  
 11  /* The live key structure */
 12  struct oqs_key_st {
 13    uint8_t *sec; size_t sec_len; /* secret (private) key */
 14    uint8_t *pub; size_t pub_len; /* public key */
 15  };
 16  
 17  /* All data and descriptor structures for one OQS algorithm */
 18  struct oqs_impl_st {
 19    /* The self-standing signer and verifier...  really just for convenience */
 20    LSplugin_signer_desc_t signer;
 21    LSplugin_verifier_desc_t verifier;
 22    /* The key associated signer and verifier */
 23    LSplugin_signer_desc_t assoc_signer;
 24    LSplugin_verifier_desc_t assoc_verifier;
 25    LSplugin_key_generator_desc_t assoc_generator;
 26    LSplugin_key_constructor_desc_t assoc_constructor;
 27    LSplugin_key_extractor_desc_t assoc_extractor;
 28    /* The key itself */
 29    LSplugin_key_desc_t key;
 30  
 31    /* The parameters, made as a substructure to get pointers easily */
 32    struct oqs_data_st {
 33      OQS_SIG *sig;
 34      LSC_param_desc_t param_desc[3]; /* Space for the sec and pub key, and NULL */
 35    } _;
 36  };
 37  
 38  /* Param helpers */
 39  
 40  static LSplugin_param_functions_t sec_fns = {
 41    offsetof(struct oqs_key_st, sec),
 42    offsetof(struct oqs_key_st, sec_len),
 43    0, false,
 44    LSplugin_set_octetstring_param, LSplugin_get_octetstring_param
 45  };
 46  static LSplugin_param_functions_t pub_fns = {
 47    offsetof(struct oqs_key_st, pub),
 48    offsetof(struct oqs_key_st, pub_len),
 49    0, false,
 50    LSplugin_set_octetstring_param, LSplugin_get_octetstring_param
 51  };
 52  
 53  /*
 54   * The set of functions that actually do something
 55   */
 56  
 57  /* For signer operations */
 58  
 59  static LE_STATUS set_sig_key(LSC_signer_t *op, LSC_key_t *key)
 60  {
 61    op->lsc_data = key;
 62    return LE_STS_SUCCESS;
 63  }
 64  static LE_STATUS get_sig_key(LSC_signer_t *op, LSC_key_t **key)
 65  {
 66    *key = op->lsc_data;
 67    return LE_STS_SUCCESS;
 68  }
 69  
 70  static LE_STATUS get_sig_input_size(LSC_signer_t *sig, size_t *size)
 71  {
 72    *size = 0;
 73    return LE_STS_SUCCESS;
 74  }
 75  static LE_STATUS get_sig_signature_size(LSC_signer_t *sig, size_t *size)
 76  {
 77    const LSplugin_signer_desc_t *desc = sig->lsc_dispatch_data;
 78    const struct oqs_data_st *data = desc->lsp_priv_desc;
 79    *size = data->sig->length_signature;
 80    return LE_STS_SUCCESS;
 81  }
 82  static LE_STATUS perform_sig_once(LSC_signer_t *op,
 83                                    const unsigned char *msg,
 84                                    size_t msglen,
 85                                    unsigned char *sig,
 86                                    size_t sigsize,
 87                                    size_t *siglen)
 88  {
 89    LSC_key_t *key = op->lsc_data;
 90    struct oqs_key_st *k = key->lsc_data;
 91    const LSplugin_signer_desc_t *desc = op->lsc_dispatch_data;
 92    const struct oqs_data_st *data = desc->lsp_priv_desc;
 93    OQS_STATUS oqssts = OQS_SIG_sign(data->sig, sig, siglen, msg, msglen, k->sec);
 94    return oqssts == OQS_SUCCESS ? LE_STS_SUCCESS : LE_STS_ERROR;
 95  }
 96  
 97  /* For verifier operations */
 98  
 99  static LE_STATUS set_ver_key(LSC_verifier_t *op, LSC_key_t *key)
100  {
101    op->lsc_data = key;
102    return LE_STS_SUCCESS;
103  }
104  static LE_STATUS get_ver_key(LSC_verifier_t *op, LSC_key_t **key)
105  {
106    *key = op->lsc_data;
107    return LE_STS_SUCCESS;
108  }
109  static LE_STATUS get_ver_input_size(LSC_verifier_t *op, size_t *size)
110  {
111    *size = 0;
112    return LE_STS_SUCCESS;
113  }
114  static LE_STATUS get_ver_signature_size(LSC_verifier_t *op, size_t *size)
115  {
116    const LSplugin_verifier_desc_t *desc = op->lsc_dispatch_data;
117    const struct oqs_data_st *data = desc->lsp_priv_desc;
118    const OQS_SIG *sig = desc->lsp_priv_desc;
119    *size = data->sig->length_signature;
120    return LE_STS_SUCCESS;
121  }
122  static LE_STATUS perform_ver_once(LSC_verifier_t *op, 
123                                    const unsigned char *msg,
124                                    size_t msglen,
125                                    const unsigned char *sig,
126                                    size_t siglen,
127                                    _Bool *confirmed)
128  {
129    LSC_key_t *key = op->lsc_data;
130    struct oqs_key_st *k = key->lsc_data;
131    const LSplugin_signer_desc_t *desc = op->lsc_dispatch_data;
132    const const struct oqs_data_st *data = desc->lsp_priv_desc;
133    OQS_STATUS oqssts = OQS_SIG_verify(data->sig, msg, msglen, sig, siglen, k->pub);
134    /*
135     * Unfortunately, the OQS API conflates "no" with errors, so we need to
136     * interpret what OQS_ERROR actually means.  Since there's no other data
137     * to go on, were forced to interpret it as "no", and hope that no actual
138     * error every occurs.
139     */
140    *confirmed = oqssts == OQS_SUCCESS;
141    return LE_STS_SUCCESS;
142  }
143  
144  /* For generator operations */
145  
146  static LE_STATUS set_gen_key(LSC_key_generator_t *op, LSC_key_t *key)
147  {
148    op->lsc_data = key;
149    return LE_STS_SUCCESS;
150  }
151  
152  static LE_STATUS get_gen_key(LSC_key_generator_t *op, LSC_key_t **key)
153  {
154    *key = op->lsc_data;
155    return LE_STS_SUCCESS;
156  }
157  
158  static LE_STATUS generate_key(LSC_key_generator_t *op)
159  {
160    LSC_key_t *key = op->lsc_data;
161    struct oqs_key_st *k = key->lsc_data;
162    const LSplugin_key_generator_desc_t *desc = op->lsc_dispatch_data;
163    const struct oqs_data_st *data = desc->lsp_priv_desc;
164    k->sec = realloc(k->sec, data->sig->length_secret_key);
165    k->pub = realloc(k->pub, data->sig->length_public_key);
166    if (k->sec == NULL || k->pub == NULL)
167      return LE_STS_FATAL_ERROR;
168    OQS_STATUS oqssts = OQS_SIG_keypair(data->sig, k->pub, k->sec);
169    if (oqssts != OQS_SUCCESS)
170      return LE_STS_ERROR;
171    k->sec_len = data->sig->length_secret_key;
172    k->pub_len = data->sig->length_public_key;
173    return LE_STS_SUCCESS;
174  }
175  
176  /* For constructor operations */
177  
178  static LE_STATUS set_con_key(LSC_key_constructor_t *op, LSC_key_t *key)
179  {
180    op->lsc_data = key;
181    return LE_STS_SUCCESS;
182  }
183  
184  static LE_STATUS get_con_key(LSC_key_constructor_t *op, LSC_key_t **key)
185  {
186    *key = op->lsc_data;
187    return LE_STS_SUCCESS;
188  }
189  
190  static LE_STATUS get_con_param_data(LSC_key_constructor_t *op, void **data)
191  {
192    LSC_key_t *key = op->lsc_data;
193    *data = key->lsc_data;
194    return LE_STS_SUCCESS;
195  }
196  
197  static LE_STATUS
198  get_settable_con_param_desc(LSC_key_constructor_t *op,
199                              const LSC_param_desc_t **param_desc)
200  {
201    const LSplugin_key_constructor_desc_t *desc = op->lsc_dispatch_data;
202    const struct oqs_data_st *data = desc->lsp_priv_desc;
203    *param_desc = data->param_desc;
204    return LE_STS_SUCCESS;
205  }
206  
207  /* For extractor operations */
208  
209  static LE_STATUS set_ext_key(LSC_key_extractor_t *op, LSC_key_t *key)
210  {
211    op->lsc_data = key;
212    return LE_STS_SUCCESS;
213  }
214  
215  static LE_STATUS get_ext_key(LSC_key_extractor_t *op, LSC_key_t **key)
216  {
217    *key = op->lsc_data;
218    return LE_STS_SUCCESS;
219  }
220  
221  static LE_STATUS get_ext_param_data(LSC_key_extractor_t *op, void **data)
222  {
223    LSC_key_t *key = op->lsc_data;
224    *data = key->lsc_data;
225    return LE_STS_SUCCESS;
226  }
227  
228  static LE_STATUS
229  get_gettable_ext_param_desc(LSC_key_extractor_t *op,
230                              const LSC_param_desc_t **param_desc)
231  {
232    const LSplugin_key_extractor_desc_t *desc = op->lsc_dispatch_data;
233    const struct oqs_data_st *data = desc->lsp_priv_desc;
234    *param_desc = data->param_desc;
235    return LE_STS_SUCCESS;
236  }
237  
238  /* For the key objects */
239  
240  static LE_STATUS setup_key_data(LSC_key_t *key, const void *priv_desc)
241  {
242    const struct oqs_data_st *data = priv_desc;
243    struct oqs_key_st **k = (struct oqs_key_st **)&(key->lsc_data);
244    if (*k == NULL) {
245      (*k) = malloc(sizeof(**k));
246      memset(*k, 0, sizeof(**k));
247    }
248    return LE_STS_SUCCESS;
249  }
250  
251  static LE_STATUS clean_key_data(LSC_key_t *key)
252  {
253    struct oqs_key_st **k = (struct oqs_key_st **)&(key->lsc_data);
254    if (*k != NULL) {
255      free((*k)->sec); (*k)->sec = NULL;
256      free((*k)->pub); (*k)->pub = NULL;
257      free((*k));      *k = NULL;
258    }
259    return LE_STS_SUCCESS;
260  }
261  
262  /*
263   * Create the list of struct oqs_sig_st, save that list in our environment,
264   * and register all the algorithms in the plugin's parent environment
265   */
266  
267  static struct oqs_impl_st *mksiglist(void)
268  {
269    int nsigs = OQS_SIG_alg_count();
270    struct oqs_impl_st *sigs = calloc(nsigs + 1, sizeof(*sigs));
271  
272    if (sigs)
273      for (int i = 0, j = 0; i < nsigs; i++) {
274        const char *name = OQS_SIG_alg_identifier(i);
275        if (!OQS_SIG_alg_is_enabled(name))
276          continue;
277        OQS_SIG *sig = OQS_SIG_new(name);
278        if (sig == NULL)
279          continue;
280        size_t seclen = sig->length_secret_key;
281        size_t publen = sig->length_public_key;
282  
283        sigs[j] = (struct oqs_impl_st){
284          /* Descriptors for the free standing implementations */
285          .signer = {
286            NULL, name, &sigs[j]._, name,
287            NULL, NULL,
288            NULL,                   /* No lsp_set_key_signer */
289            set_sig_key,
290            get_sig_key,
291            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),
292                     LSC_SIGNER_SIZE_COMMANDS(),
293                     LSC_NR_perform_signature_once, 0 },
294            NULL,
295            NULL,
296            NULL,
297            get_sig_input_size,
298            get_sig_signature_size,
299            perform_sig_once,
300          },
301          .verifier = {
302            NULL, name, &sigs[j]._, name,
303            NULL, NULL,
304            NULL,                   /* No lsp_set_key_verification */
305            set_ver_key,
306            get_ver_key,
307            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),
308                     LSC_VERIFIER_SIZE_COMMANDS(),
309                     LSC_NR_perform_verification_once, 0 },
310            NULL,
311            NULL,
312            NULL,
313            get_ver_input_size,
314            get_ver_signature_size,
315            perform_ver_once,
316          },
317  
318          /* Descriptors for the key associated implementations */
319          .assoc_signer = {
320            NULL, NULL, &sigs[j]._, NULL,
321            NULL, NULL,
322            NULL,                   /* No lsp_set_key_signer */
323            set_sig_key,
324            get_sig_key,
325            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),
326                     LSC_SIGNER_SIZE_COMMANDS(),
327                     LSC_NR_perform_signature_once, 0 },
328            NULL,
329            NULL,
330            NULL,
331            get_sig_input_size,
332            get_sig_signature_size,
333            perform_sig_once,
334          },
335          .assoc_verifier = {
336            NULL, NULL, &sigs[j]._, NULL,
337            NULL, NULL,
338            NULL,                   /* No lsp_set_key_verification */
339            set_ver_key,
340            get_ver_key,
341            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),
342                     LSC_VERIFIER_SIZE_COMMANDS(),
343                     LSC_NR_perform_verification_once, 0 },
344            NULL,
345            NULL,
346            NULL,
347            get_ver_input_size,
348            get_ver_signature_size,
349            perform_ver_once,
350          },
351  
352          /* Descriptors for the key generator */
353          .assoc_generator = {
354            NULL, NULL, &sigs[j]._, NULL,
355            NULL, NULL,
356            NULL,                   /* No lsp_set_key_generator */
357            set_gen_key,
358            get_gen_key,
359            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),
360                     LSC_NR_generate_key, 0 },
361            NULL,
362            NULL,                   /* No gettable */
363            NULL,                   /* No settable */
364            generate_key,
365          },
366  
367          /* Descriptors for the key constructor */
368          .assoc_constructor = {
369            NULL, NULL, &sigs[j]._, NULL,
370            NULL, NULL,
371            NULL,                   /* No lsp_set_key_verification */
372            set_con_key,
373            get_con_key,
374            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),
375                     LSC_NR_construct_key, 0 },
376            get_con_param_data,
377            NULL,                   /* No gettable */
378            get_settable_con_param_desc,
379            NULL,                   /* No constructor function */
380          },
381  
382          /* Descriptors for the key extractor */
383          .assoc_extractor = {
384            NULL, NULL, &sigs[j]._, NULL,
385            NULL, NULL,
386            NULL,                   /* No lsp_set_key_verification */
387            set_ext_key,
388            get_ext_key,
389            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(), 0 },
390            get_ext_param_data,
391            get_gettable_ext_param_desc,
392            NULL,                   /* No settable */
393          },
394  
395          /* Descriptors for the key itself */
396          .key = {
397            NULL, name, &sigs[j]._,
398            setup_key_data, clean_key_data,
399            (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),
400                     LSC_NR_get_key_generator,
401                     LSC_NR_get_key_constructor,
402                     LSC_NR_get_key_extractor,
403                     LSC_NR_get_associated_signer,
404                     LSC_NR_get_associated_verifier, 0 },
405            NULL,                   /* No get_key_size */
406            &sigs[j].assoc_generator,
407            &sigs[j].assoc_constructor,
408            &sigs[j].assoc_extractor,
409            NULL,
410            NULL,
411            &sigs[j].assoc_signer,
412            &sigs[j].assoc_verifier,
413          },
414  
415          ._ = {
416            sig,
417            {
418              { "sec", 1,
419                { LSC_DT_octet_string,
420                  { sig->length_secret_key, sig->length_secret_key } },
421                &sec_fns,
422                "The secret key" },
423              { "pub", 2,
424                { LSC_DT_octet_string,
425                  { sig->length_public_key, sig->length_public_key } },
426                &pub_fns,
427                "The public key" },
428              { NULL, 0 }                        
429            }
430          }
431        };
432        j++;
433      }
434  
435    return sigs;
436  }
437  
438  static void freesiglist(struct oqs_impl_st *sigs)
439  {
440    if (sigs) {
441      for (struct oqs_impl_st *s = sigs; s->key.lsp_id != NULL; s++)
442        OQS_SIG_free(s->_.sig);
443      free(sigs);
444    }
445  }
446  
447  /* The tag to get an index could be better... */
448  static const char *tag = "oqs-sigs";
449  
450  LE_STATUS oqs_register_sigs(LSC_env_t *env, LSC_plugin_t *plugin)
451  {
452    LE_STATUS sts;
453    int index;
454    struct oqs_impl_st *sigs = mksiglist();
455  
456    if (sigs == NULL)
457      return LE_STS_ALLOC_FAILURE;
458    if (LE_status_is_OK(sts = LSC_get_index(env, "oqs-sigs", &index))
459        && LE_status_is_OK(sts = LSC_set_plugin_application_data(plugin, index, sigs)))
460      for (struct oqs_impl_st *s = sigs; s->key.lsp_id != NULL; s++) {
461        sts = LSC_register_signer_implementation(env, plugin,
462                                                 s->signer.lsp_id,
463                                                 LSplugin_signer_dispatch,
464                                                 LSplugin_destroy_signer,
465                                                 &s->signer,
466                                                 s->signer.lsp_docstring);
467        if (!LE_status_is_OK(sts))
468          break;
469        sts = LSC_register_verifier_implementation(env, plugin,
470                                                   s->verifier.lsp_id,
471                                                   LSplugin_verifier_dispatch,
472                                                   LSplugin_destroy_verifier,
473                                                   &s->verifier,
474                                                   s->verifier.lsp_docstring);
475        if (!LE_status_is_OK(sts))
476          break;
477        sts = LSC_register_key_implementation(env, plugin,
478                                              s->key.lsp_id,
479                                              LSplugin_key_dispatch,
480                                              LSplugin_destroy_key,
481                                              &s->key,
482                                              s->key.lsp_docstring);
483        if (!LE_status_is_OK(sts))
484          break;
485      }
486    
487    return sts;
488  }
489  
490  LE_STATUS oqs_deregister_sigs(LSC_env_t *env, LSC_plugin_t *plugin)
491  {
492    LE_STATUS sts;
493    int index;
494    struct oqs_impl_st *sigs = NULL;
495  
496    if (LE_status_is_OK(sts = LSC_get_index(env, "oqs-sigs", &index))
497        && LE_status_is_OK(sts = LSC_get_plugin_application_data(plugin, index, &sigs))) {
498      for (struct oqs_impl_st *s = sigs; s->key.lsp_id != NULL; s++) {
499        sts = LSC_deregister_signer_implementation(env, plugin,
500                                                   s->signer.lsp_id,
501                                                   LSplugin_signer_dispatch,
502                                                   LSplugin_destroy_signer,
503                                                   &s->signer,
504                                                   s->signer.lsp_docstring);
505        if (!LE_status_is_OK(sts))
506          break;
507        sts = LSC_deregister_verifier_implementation(env, plugin,
508                                                     s->verifier.lsp_id,
509                                                     LSplugin_verifier_dispatch,
510                                                     LSplugin_destroy_verifier,
511                                                     &s->verifier,
512                                                     s->verifier.lsp_docstring);
513        if (!LE_status_is_OK(sts))
514          break;
515        sts = LSC_deregister_key_implementation(env, plugin,
516                                                s->key.lsp_id,
517                                                LSplugin_key_dispatch,
518                                                LSplugin_destroy_key,
519                                                &s->key,
520                                                s->key.lsp_docstring);
521        if (!LE_status_is_OK(sts))
522          break;
523      }
524      freesiglist(sigs);
525    }
526    return sts;
527  }