/ 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 }