/ ltc-stream-ciphers.c
ltc-stream-ciphers.c
1 /* 2 * Licensed under the Apache License, Version 2.0 (the "License"); 3 * you may not use this file except in compliance with the License. 4 * See the NOTICE file distributed with this work for additional 5 * information regarding copyright ownership. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Contrary to symmetric ciphers, which implement keys and modes in two 19 * different modules (ltc-sym-keys.c and ltc-sym-ciphers.c), stream ciphers 20 * implement both aspects in this module. It does lead to a somewhat curious 21 * situation, where the are offered both as stand-alone en/decrypt operations 22 * and as key associated operations. But, that'll do. 23 */ 24 25 #include <stdlib.h> 26 #include <string.h> 27 #include <tomcrypt.h> 28 #include <lscrypto/key.h> 29 #include <lscrypto/encrypt.h> 30 #include <lsplugin/mkobject.h> 31 #include <lsplugin/mkoperator.h> 32 #include <lsplugin/param.h> 33 #include "ltc-methods.h" 34 35 #define T(x) LE_status_is_OK(x) 36 37 /********************************************************************* 38 * 39 * Common stream key 40 * 41 * libtomcrypt doesn't have any separate key object for stream ciphers. 42 * Instead, there's only a state. Le'Sec does need a key object, though, 43 * and this implementation uses that to simply save away the input key bits. 44 * 45 *****/ 46 struct stream_key_st { 47 /* Cached key bits */ 48 unsigned char *key_bits; 49 size_t key_bits_len; /* Measured in bits */ 50 51 /* Caches for key data operations */ 52 LSC_key_constructor_t *constructor; 53 LSC_key_extractor_t *extractor; 54 /* Caches for associated operations */ 55 LSC_encryptor_t *encryptor; 56 LSC_decryptor_t *decryptor; 57 }; 58 59 /* 60 * Start with everything that concerns the key, which includes all 61 * functions that are strictly for associated operatiion. 62 */ 63 static LE_STATUS new_key_data(LSC_key_t *key, const void *unused) 64 { 65 if (key == NULL) 66 return LE_STS_ERROR; 67 struct stream_key_st **k = (struct stream_key_st **)&key->lsc_data; 68 69 if (*k == NULL && (*k = malloc(sizeof(**k))) != NULL) 70 memset(*k, 0, sizeof(**k)); 71 if (*k == NULL) 72 return LE_STS_FATAL_ERROR; 73 return LE_STS_SUCCESS; 74 } 75 76 static LE_STATUS scrub_key_data(LSC_key_t *key) 77 { 78 if (key == NULL || key->lsc_data == NULL) 79 return LE_STS_SUCCESS; 80 81 struct stream_key_st *k = key->lsc_data; 82 83 free(k->key_bits); 84 /* DO NOTE that we aren't scrubbing the cached associated operations */ 85 return LE_STS_SUCCESS; 86 } 87 88 static LE_STATUS clean_key_data(LSC_key_t *key) 89 { 90 LE_STATUS sts; 91 92 if (key == NULL || key->lsc_data == NULL) 93 return LE_STS_SUCCESS; 94 if (T(sts = scrub_key_data(key))) { 95 struct stream_key_st *k = key->lsc_data; 96 /* 97 * The constructor, encryptor and decryptor are cached, so they don't 98 * provide a destroy function in the operation object, which means 99 * that the LSC_free_key_{operation}() calls end up doing nothing. 100 * Therefore, we must destroy them now, using their destroy functions 101 * (which do exist) directly. 102 */ 103 LSplugin_destroy_key_constructor(k->constructor); 104 LSplugin_destroy_encryptor(k->encryptor); 105 LSplugin_destroy_decryptor(k->decryptor); 106 free(k); 107 key->lsc_data = NULL; 108 } 109 return sts; 110 } 111 112 static LE_STATUS get_key_size(LSC_key_t *key, size_t *keysize) 113 { 114 struct stream_key_st *k = key->lsc_data; 115 116 if (k->key_bits == NULL) 117 return LE_STS_ERROR; 118 *keysize = k->key_bits_len; 119 return LE_STS_SUCCESS; 120 } 121 122 static LE_STATUS set_key_constructor(LSC_key_t *key, 123 LSC_key_constructor_t *con) 124 { 125 struct stream_key_st *k = key->lsc_data; 126 127 k->constructor = con; 128 return LE_STS_SUCCESS; 129 } 130 131 static LE_STATUS set_key_encryptor(LSC_key_t *key, LSC_encryptor_t *enc) 132 { 133 struct stream_key_st *k = key->lsc_data; 134 135 k->encryptor = enc; 136 return LE_STS_SUCCESS; 137 } 138 139 static LE_STATUS set_key_decryptor(LSC_key_t *key, LSC_decryptor_t *dec) 140 { 141 struct stream_key_st *k = key->lsc_data; 142 143 k->decryptor = dec; 144 return LE_STS_SUCCESS; 145 } 146 147 /* Key constructor operation with support functions */ 148 149 struct stream_key_constructor_st { 150 LSC_key_t *key; 151 152 /* Operational parameters */ 153 154 /* Key bits */ 155 unsigned char *key_bits; 156 size_t key_bits_len; /* Measured in bits */ 157 158 /* True when they've been cached in the key itself */ 159 _Bool key_bits_cached; 160 }; 161 162 static LE_STATUS scrub_key_constructor_data(LSC_key_constructor_t *op) 163 { 164 if (op == NULL || op->lsc_data == NULL) 165 return LE_STS_SUCCESS; 166 167 struct stream_key_constructor_st *c = op->lsc_data; 168 169 memset(c, 0, sizeof(*c)); 170 return LE_STS_SUCCESS; 171 } 172 173 static LE_STATUS new_key_constructor_data(LSC_key_constructor_t *op) 174 { 175 LE_STATUS sts; 176 177 if (op == NULL) 178 return LE_STS_ERROR; 179 180 struct stream_key_constructor_st **c 181 = (struct stream_key_constructor_st **)&op->lsc_data; 182 183 if (*c == NULL && (*c = malloc(sizeof(**c))) != NULL) 184 memset(*c, 0, sizeof(**c)); 185 if (*c == NULL) 186 return LE_STS_FATAL_ERROR; 187 return LE_STS_SUCCESS; 188 } 189 190 static LE_STATUS clean_key_constructor_data(LSC_key_constructor_t *op) 191 { 192 LE_STATUS sts; 193 194 if (op == NULL || op->lsc_data == NULL) 195 return LE_STS_SUCCESS; 196 if (T(sts = scrub_key_constructor_data(op))) { 197 free(op->lsc_data); 198 op->lsc_data = NULL; 199 } 200 return sts; 201 } 202 203 static LE_STATUS set_constructor_key(LSC_key_constructor_t *op, 204 LSC_key_t *key) 205 { 206 LE_STATUS sts; 207 208 if (LE_status_is_OK(sts = new_key_constructor_data(op))) { 209 struct stream_key_constructor_st *c = op->lsc_data; 210 211 c->key = key; 212 } 213 return sts; 214 } 215 216 static LE_STATUS get_constructor_key(LSC_key_constructor_t *op, 217 LSC_key_t **key) 218 { 219 struct stream_key_constructor_st *c = op->lsc_data; 220 221 *key = c->key; 222 return LE_STS_SUCCESS; 223 } 224 225 static LE_STATUS construct_key_data(LSC_key_constructor_t *op) 226 { 227 LE_STATUS sts; 228 struct stream_key_constructor_st *c = op->lsc_data; 229 LSC_key_t *key = c != NULL ? c->key : NULL; 230 struct stream_key_st *k = (key != NULL) ? key->lsc_data : NULL; 231 232 if (c->key_bits_cached) 233 return LE_STS_SUCCESS; 234 if (T(sts = scrub_key_data(key))) { 235 /* Cache the key bits in the key itself too, to support extraction */ 236 k->key_bits = c->key_bits; 237 k->key_bits_len = c->key_bits_len; 238 c->key_bits_cached = true; 239 } 240 return sts; 241 } 242 243 /********************************************************************* 244 * 245 * ChaCha 246 * 247 *****/ 248 249 static LSplugin_param_functions_t chacha_key_bits_fns = { 250 offsetof(struct stream_key_constructor_st, key_bits), 251 offsetof(struct stream_key_constructor_st, key_bits_len), 252 0, false, 253 LSplugin_set_bitstring_param, LSplugin_get_bitstring_param 254 }; 255 #define CHACHA_I_key_bits 1 256 #define CHACHA_P_key_bits \ 257 { "key", CHACHA_I_key_bits, \ 258 { LSC_DT_bit_string, { { 128, 128, 0 }, { 256, 256, 0 }, }, \ 259 .d_auxilliary = { 0 }, }, \ 260 .p_private = &chacha_key_bits_fns } 261 static const LSC_param_desc_t gettable_chacha_constructor_params[] = { 262 CHACHA_P_key_bits, 263 { NULL, } 264 }; 265 static const LSC_param_desc_t settable_chacha_constructor_params[] = { 266 CHACHA_P_key_bits, 267 { NULL, } 268 }; 269 270 static LE_STATUS 271 get_chacha_construction_param_data(LSC_key_constructor_t *op, void **data) 272 { 273 *data = op->lsc_data; 274 return LE_STS_SUCCESS; 275 } 276 277 static LE_STATUS 278 get_gettable_chacha_construction_param_desc(LSC_key_constructor_t *op, 279 const LSC_param_desc_t **param_desc) 280 { 281 assert(op != NULL); 282 assert(param_desc != NULL); 283 *param_desc = gettable_chacha_constructor_params; 284 return LE_STS_SUCCESS; 285 } 286 287 static LE_STATUS 288 get_settable_chacha_construction_param_desc(LSC_key_constructor_t *op, 289 const LSC_param_desc_t **param_desc) 290 { 291 assert(op != NULL); 292 assert(param_desc != NULL); 293 *param_desc = settable_chacha_constructor_params; 294 return LE_STS_SUCCESS; 295 } 296 297 /* Encryptor and decryptor */ 298 299 struct stream_state_chacha_st { 300 /* 301 * Pointer to the associated key, done this way to allow late 302 * construction of the key (i.e. that LSC_construct_key() can 303 * be called after LSC_set_encryptor_key()). 304 * Using the public type allows working with keys from other 305 * plugins (future extension). 306 */ 307 LSC_key_t *key; 308 309 unsigned char *nonce_bits; 310 size_t nonce_bits_len; 311 size_t initial_counter; 312 size_t rounds; 313 314 chacha_state libtomcrypt_data; 315 }; 316 317 static LE_STATUS setup_chacha_data(struct stream_state_chacha_st **state) 318 { 319 if (*state == NULL) { 320 *state = malloc(sizeof(**state)); 321 if (*state == NULL) 322 return LE_STS_FATAL_ERROR; 323 memset(*state, 0, sizeof(**state)); 324 325 /* defaults */ 326 (*state)->rounds = 20; 327 (*state)->initial_counter = 1; 328 } 329 return LE_STS_SUCCESS; 330 } 331 static LE_STATUS setup_chacha_encryptor_data(LSC_encryptor_t *op) 332 { 333 return setup_chacha_data((struct stream_state_chacha_st **)&op->lsc_data); 334 } 335 static LE_STATUS setup_chacha_decryptor_data(LSC_decryptor_t *op) 336 { 337 return setup_chacha_data((struct stream_state_chacha_st **)&op->lsc_data); 338 } 339 340 static LE_STATUS clean_chacha_data(struct stream_state_chacha_st **state) 341 { 342 if (*state != NULL) { 343 free(*state); 344 *state = NULL; 345 } 346 return LE_STS_SUCCESS; 347 } 348 static LE_STATUS clean_chacha_encryptor_data(LSC_encryptor_t *op) 349 { 350 return clean_chacha_data((struct stream_state_chacha_st **)&op->lsc_data); 351 } 352 static LE_STATUS clean_chacha_decryptor_data(LSC_decryptor_t *op) 353 { 354 return clean_chacha_data((struct stream_state_chacha_st **)&op->lsc_data); 355 } 356 357 static LE_STATUS set_chacha_key(struct stream_state_chacha_st *state, 358 LSC_key_t *key) 359 { 360 if (state == NULL) 361 return LE_STS_ERROR; 362 state->key = key; 363 return LE_STS_SUCCESS; 364 } 365 static LE_STATUS set_chacha_encryptor_key(LSC_encryptor_t *op, LSC_key_t *key) 366 { 367 return set_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key); 368 } 369 static LE_STATUS set_chacha_decryptor_key(LSC_decryptor_t *op, LSC_key_t *key) 370 { 371 return set_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key); 372 } 373 374 static LE_STATUS get_chacha_key(struct stream_state_chacha_st *state, 375 LSC_key_t **key) 376 { 377 if (state == NULL) 378 return LE_STS_ERROR; 379 if (key == NULL) 380 return LE_STS_FATAL_ERROR; 381 *key = state->key; 382 return LE_STS_SUCCESS; 383 } 384 static LE_STATUS get_chacha_encryptor_key(LSC_encryptor_t *op, LSC_key_t **key) 385 { 386 return get_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key); 387 } 388 static LE_STATUS get_chacha_decryptor_key(LSC_decryptor_t *op, LSC_key_t **key) 389 { 390 return get_chacha_key((struct stream_state_chacha_st *)op->lsc_data, key); 391 } 392 393 static LSplugin_param_functions_t stream_chacha_nonce_bits_fns = { 394 offsetof(struct stream_state_chacha_st, nonce_bits), 395 offsetof(struct stream_state_chacha_st, nonce_bits_len), 396 0, false, 397 LSplugin_set_bitstring_param, LSplugin_get_bitstring_param 398 }; 399 #define CHACHA_I_nonce_bits 1 400 #define CHACHA_P_nonce_bits \ 401 { "nonce", CHACHA_I_nonce_bits, \ 402 { LSC_DT_bit_string, { { 64, 64, 8 }, { 96, 96, 8 }, }, \ 403 .d_auxilliary = { 0 }, }, \ 404 .p_private = &stream_chacha_nonce_bits_fns } 405 406 static LSplugin_param_functions_t chacha_counter_size_fns = { 407 offsetof(struct stream_state_chacha_st, initial_counter), 0, 0, false, 408 LSplugin_set_size_t_param, LSplugin_get_size_t_param 409 }; 410 #define CHACHA_I_counter 2 411 #define CHACHA_P_counter \ 412 { "counter", CHACHA_I_counter, \ 413 { LSC_DT_integer, \ 414 { { sizeof(size_t), sizeof(size_t) }, }, }, \ 415 .p_private = &chacha_counter_size_fns } 416 static const LSC_param_desc_t gettable_chacha_params[] = { 417 CHACHA_P_nonce_bits, 418 CHACHA_P_counter, 419 { NULL, } 420 }; 421 static const LSC_param_desc_t settable_chacha_params[] = { 422 CHACHA_P_nonce_bits, 423 CHACHA_P_counter, 424 { NULL, } 425 }; 426 427 static LE_STATUS 428 get_encryption_param_data(LSC_encryptor_t *enc, void **data) 429 { 430 *data = enc->lsc_data; 431 return LE_STS_SUCCESS; 432 } 433 434 static LE_STATUS 435 get_decryption_param_data(LSC_decryptor_t *enc, void **data) 436 { 437 *data = enc->lsc_data; 438 return LE_STS_SUCCESS; 439 } 440 441 static LE_STATUS 442 get_gettable_chacha_param_desc(struct stream_state_chacha_st *state, 443 const LSC_param_desc_t **param_desc) 444 { 445 assert(state != NULL); 446 assert(param_desc != NULL); 447 *param_desc = gettable_chacha_params; 448 return LE_STS_SUCCESS; 449 } 450 451 static LE_STATUS 452 get_settable_chacha_param_desc(struct stream_state_chacha_st *state, 453 const LSC_param_desc_t **param_desc) 454 { 455 assert(state != NULL); 456 assert(param_desc != NULL); 457 *param_desc = settable_chacha_params; 458 return LE_STS_SUCCESS; 459 } 460 461 #define get_chacha_encryption_param_data get_encryption_param_data 462 static LE_STATUS 463 get_gettable_chacha_encryption_param_desc(LSC_encryptor_t *enc, 464 const LSC_param_desc_t **param_desc) 465 { 466 return get_gettable_chacha_param_desc(enc->lsc_data, param_desc); 467 } 468 469 static LE_STATUS 470 get_settable_chacha_encryption_param_desc(LSC_encryptor_t *enc, 471 const LSC_param_desc_t **param_desc) 472 { 473 return get_gettable_chacha_param_desc(enc->lsc_data, param_desc); 474 } 475 476 #define get_chacha_decryption_param_data get_decryption_param_data 477 static LE_STATUS 478 get_gettable_chacha_decryption_param_desc(LSC_decryptor_t *dec, 479 const LSC_param_desc_t **param_desc) 480 { 481 return get_gettable_chacha_param_desc(dec->lsc_data, param_desc); 482 } 483 484 static LE_STATUS 485 get_settable_chacha_decryption_param_desc(LSC_decryptor_t *dec, 486 const LSC_param_desc_t **param_desc) 487 { 488 return get_gettable_chacha_param_desc(dec->lsc_data, param_desc); 489 } 490 491 static LE_STATUS start_chacha(struct stream_state_chacha_st *state) 492 { 493 if (state == NULL) 494 return LE_STS_ERROR; 495 if (state->key == NULL || state->nonce_bits == NULL) 496 return LE_STS_ERROR; 497 struct stream_key_st *k = state->key->lsc_data; 498 if (k == NULL) 499 return LE_STS_ERROR; 500 int err; 501 err = chacha_setup(&state->libtomcrypt_data, 502 k->key_bits, k->key_bits_len / 8, 20); 503 if (err != CRYPT_OK) 504 return LE_STS_ERROR; 505 if (state->nonce_bits_len == 96) 506 err = chacha_ivctr32(&state->libtomcrypt_data, state->nonce_bits, 12, 507 (uint64_t)state->initial_counter); 508 else 509 err = chacha_ivctr64(&state->libtomcrypt_data, state->nonce_bits, 8, 510 (uint32_t)state->initial_counter); 511 if (err != CRYPT_OK) 512 return LE_STS_ERROR; 513 return LE_STS_SUCCESS; 514 } 515 static LE_STATUS start_chacha_encryption(LSC_encryptor_t *enc) 516 { 517 return start_chacha((struct stream_state_chacha_st *)enc->lsc_data); 518 } 519 static LE_STATUS start_chacha_decryption(LSC_decryptor_t *dec) 520 { 521 return start_chacha((struct stream_state_chacha_st *)dec->lsc_data); 522 } 523 524 static LE_STATUS perform_chacha(struct stream_state_chacha_st *state, 525 const unsigned char *in, 526 size_t inlen, 527 unsigned char *out, size_t outsize, 528 size_t *outlen) 529 { 530 if (state == NULL) 531 return LE_STS_ERROR; 532 if (outlen != NULL) 533 *outlen = inlen; 534 if (out == NULL) 535 return LE_STS_SUCCESS; 536 if (in == NULL) 537 return LE_STS_ERROR; 538 if (outsize < inlen) 539 return LE_STS_ERROR; 540 541 int err; 542 err = chacha_crypt(&state->libtomcrypt_data, in, inlen, out); 543 if (err != CRYPT_OK) 544 return LE_STS_ERROR; 545 return LE_STS_SUCCESS; 546 } 547 static LE_STATUS perform_chacha_encryption(LSC_encryptor_t *enc, 548 const unsigned char *in, 549 size_t inlen, 550 unsigned char *out, size_t outsize, 551 size_t *outlen) 552 { 553 return perform_chacha((struct stream_state_chacha_st *)enc->lsc_data, 554 in, inlen, out, outsize, outlen); 555 } 556 static LE_STATUS perform_chacha_decryption(LSC_decryptor_t *dec, 557 const unsigned char *in, 558 size_t inlen, 559 unsigned char *out, size_t outsize, 560 size_t *outlen) 561 { 562 return perform_chacha((struct stream_state_chacha_st *)dec->lsc_data, 563 in, inlen, out, outsize, outlen); 564 } 565 566 567 static LE_STATUS finalize_chacha(struct stream_state_chacha_st *state, 568 unsigned char *out, size_t outsize, 569 size_t *outlen) 570 { 571 if (outlen != NULL) 572 *outlen = 0; 573 return LE_STS_SUCCESS; 574 } 575 static LE_STATUS finalize_chacha_encryption(LSC_encryptor_t *enc, 576 unsigned char *out, size_t outsize, 577 size_t *outlen) 578 { 579 return finalize_chacha((struct stream_state_chacha_st *)enc->lsc_data, 580 out, outsize, outlen); 581 } 582 static LE_STATUS finalize_chacha_decryption(LSC_decryptor_t *dec, 583 unsigned char *out, size_t outsize, 584 size_t *outlen) 585 { 586 return finalize_chacha((struct stream_state_chacha_st *)dec->lsc_data, 587 out, outsize, outlen); 588 } 589 590 static LE_STATUS stop_chacha(struct stream_state_chacha_st *state) 591 { 592 if (state == NULL) 593 return LE_STS_ERROR; 594 int err; 595 err = chacha_done(&state->libtomcrypt_data); 596 if (err != CRYPT_OK) 597 return LE_STS_ERROR; 598 return LE_STS_SUCCESS; 599 } 600 static LE_STATUS stop_chacha_encryption(LSC_encryptor_t *enc) 601 { 602 return stop_chacha((struct stream_state_chacha_st *)enc->lsc_data); 603 } 604 static LE_STATUS stop_chacha_decryption(LSC_decryptor_t *dec) 605 { 606 return stop_chacha((struct stream_state_chacha_st *)dec->lsc_data); 607 } 608 609 /********************************************************************* 610 * 611 * RC4 612 * 613 *****/ 614 615 static LSplugin_param_functions_t rc4_key_bits_fns = { 616 offsetof(struct stream_key_constructor_st, key_bits), 617 offsetof(struct stream_key_constructor_st, key_bits_len), 618 0, false, 619 LSplugin_set_bitstring_param, LSplugin_get_bitstring_param 620 }; 621 /* libtomcrypt documents that RC4 takes 5 - 256 byte keys */ 622 #define RC4_I_key_bits 1 623 #define RC4_P_key_bits \ 624 { "key", RC4_I_key_bits, \ 625 { LSC_DT_bit_string, { { 40, 2048, 8 }, }, \ 626 .d_auxilliary = { 0 }, }, \ 627 .p_private = &rc4_key_bits_fns } 628 static const LSC_param_desc_t gettable_rc4_constructor_params[] = { 629 RC4_P_key_bits, 630 631 { NULL, } 632 }; 633 static const LSC_param_desc_t settable_rc4_constructor_params[] = { 634 RC4_P_key_bits, 635 { NULL, } 636 }; 637 638 static LE_STATUS 639 get_rc4_construction_param_data(LSC_key_constructor_t *op, void **data) 640 { 641 *data = op->lsc_data; 642 return LE_STS_SUCCESS; 643 } 644 645 static LE_STATUS 646 get_gettable_rc4_construction_param_desc(LSC_key_constructor_t *op, 647 const LSC_param_desc_t **param_desc) 648 { 649 assert(op != NULL); 650 assert(param_desc != NULL); 651 *param_desc = gettable_rc4_constructor_params; 652 return LE_STS_SUCCESS; 653 } 654 655 static LE_STATUS 656 get_settable_rc4_construction_param_desc(LSC_key_constructor_t *op, 657 const LSC_param_desc_t **param_desc) 658 { 659 assert(op != NULL); 660 assert(param_desc != NULL); 661 *param_desc = settable_rc4_constructor_params; 662 return LE_STS_SUCCESS; 663 } 664 665 /* Encryptor and decryptor */ 666 667 struct stream_state_rc4_st { 668 /* 669 * Pointer to the associated key, done this way to allow late 670 * construction of the key (i.e. that LSC_construct_key() can 671 * be called after LSC_set_encryptor_key()). 672 * Using the public type allows working with keys from other 673 * plugins (future extension). 674 */ 675 LSC_key_t *key; 676 677 rc4_state libtomcrypt_data; 678 }; 679 680 static LE_STATUS setup_rc4_data(struct stream_state_rc4_st **state) 681 { 682 if (*state == NULL) { 683 *state = malloc(sizeof(**state)); 684 if (*state == NULL) 685 return LE_STS_FATAL_ERROR; 686 memset(*state, 0, sizeof(**state)); 687 } 688 return LE_STS_SUCCESS; 689 } 690 static LE_STATUS setup_rc4_encryptor_data(LSC_encryptor_t *op) 691 { 692 return setup_rc4_data((struct stream_state_rc4_st **)&op->lsc_data); 693 } 694 static LE_STATUS setup_rc4_decryptor_data(LSC_decryptor_t *op) 695 { 696 return setup_rc4_data((struct stream_state_rc4_st **)&op->lsc_data); 697 } 698 699 static LE_STATUS clean_rc4_data(struct stream_state_rc4_st **state) 700 { 701 if (*state != NULL) { 702 free(*state); 703 *state = NULL; 704 } 705 return LE_STS_SUCCESS; 706 } 707 static LE_STATUS clean_rc4_encryptor_data(LSC_encryptor_t *op) 708 { 709 return clean_rc4_data((struct stream_state_rc4_st **)&op->lsc_data); 710 } 711 static LE_STATUS clean_rc4_decryptor_data(LSC_decryptor_t *op) 712 { 713 return clean_rc4_data((struct stream_state_rc4_st **)&op->lsc_data); 714 } 715 716 static LE_STATUS set_rc4_key(struct stream_state_rc4_st *state, 717 LSC_key_t *key) 718 { 719 if (state == NULL) 720 return LE_STS_ERROR; 721 state->key = key; 722 return LE_STS_SUCCESS; 723 } 724 static LE_STATUS set_rc4_encryptor_key(LSC_encryptor_t *op, LSC_key_t *key) 725 { 726 return set_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key); 727 } 728 static LE_STATUS set_rc4_decryptor_key(LSC_decryptor_t *op, LSC_key_t *key) 729 { 730 return set_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key); 731 } 732 733 static LE_STATUS get_rc4_key(struct stream_state_rc4_st *state, 734 LSC_key_t **key) 735 { 736 if (state == NULL) 737 return LE_STS_ERROR; 738 if (key == NULL) 739 return LE_STS_FATAL_ERROR; 740 *key = state->key; 741 return LE_STS_SUCCESS; 742 } 743 static LE_STATUS get_rc4_encryptor_key(LSC_encryptor_t *op, LSC_key_t **key) 744 { 745 return get_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key); 746 } 747 static LE_STATUS get_rc4_decryptor_key(LSC_decryptor_t *op, LSC_key_t **key) 748 { 749 return get_rc4_key((struct stream_state_rc4_st *)op->lsc_data, key); 750 } 751 752 #define get_rc4_encryption_param_data NULL 753 #define get_rc4_decryption_param_data NULL 754 #define get_gettable_rc4_encryption_param_desc NULL 755 #define get_settable_rc4_encryption_param_desc NULL 756 #define get_gettable_rc4_decryption_param_desc NULL 757 #define get_settable_rc4_decryption_param_desc NULL 758 759 static LE_STATUS start_rc4(struct stream_state_rc4_st *state) 760 { 761 if (state == NULL) 762 return LE_STS_ERROR; 763 if (state->key == NULL) 764 return LE_STS_ERROR; 765 struct stream_key_st *k = state->key->lsc_data; 766 if (k == NULL) 767 return LE_STS_ERROR; 768 int err; 769 err = rc4_stream_setup(&state->libtomcrypt_data, 770 k->key_bits, k->key_bits_len / 8); 771 if (err != CRYPT_OK) 772 return LE_STS_ERROR; 773 return LE_STS_SUCCESS; 774 } 775 static LE_STATUS start_rc4_encryption(LSC_encryptor_t *enc) 776 { 777 return start_rc4((struct stream_state_rc4_st *)enc->lsc_data); 778 } 779 static LE_STATUS start_rc4_decryption(LSC_decryptor_t *dec) 780 { 781 return start_rc4((struct stream_state_rc4_st *)dec->lsc_data); 782 } 783 784 static LE_STATUS perform_rc4(struct stream_state_rc4_st *state, 785 const unsigned char *in, 786 size_t inlen, 787 unsigned char *out, size_t outsize, 788 size_t *outlen) 789 { 790 if (state == NULL) 791 return LE_STS_ERROR; 792 if (outlen != NULL) 793 *outlen = inlen; 794 if (out == NULL) 795 return LE_STS_SUCCESS; 796 if (in == NULL) 797 return LE_STS_ERROR; 798 if (outsize < inlen) 799 return LE_STS_ERROR; 800 801 int err; 802 err = rc4_stream_crypt(&state->libtomcrypt_data, in, inlen, out); 803 if (err != CRYPT_OK) 804 return LE_STS_ERROR; 805 return LE_STS_SUCCESS; 806 } 807 static LE_STATUS perform_rc4_encryption(LSC_encryptor_t *enc, 808 const unsigned char *in, 809 size_t inlen, 810 unsigned char *out, size_t outsize, 811 size_t *outlen) 812 { 813 return perform_rc4((struct stream_state_rc4_st *)enc->lsc_data, 814 in, inlen, out, outsize, outlen); 815 } 816 static LE_STATUS perform_rc4_decryption(LSC_decryptor_t *dec, 817 const unsigned char *in, 818 size_t inlen, 819 unsigned char *out, size_t outsize, 820 size_t *outlen) 821 { 822 return perform_rc4((struct stream_state_rc4_st *)dec->lsc_data, 823 in, inlen, out, outsize, outlen); 824 } 825 826 827 static LE_STATUS finalize_rc4(struct stream_state_rc4_st *state, 828 unsigned char *out, size_t outsize, 829 size_t *outlen) 830 { 831 if (outlen != NULL) 832 *outlen = 0; 833 return LE_STS_SUCCESS; 834 } 835 static LE_STATUS finalize_rc4_encryption(LSC_encryptor_t *enc, 836 unsigned char *out, size_t outsize, 837 size_t *outlen) 838 { 839 return finalize_rc4((struct stream_state_rc4_st *)enc->lsc_data, 840 out, outsize, outlen); 841 } 842 static LE_STATUS finalize_rc4_decryption(LSC_decryptor_t *dec, 843 unsigned char *out, size_t outsize, 844 size_t *outlen) 845 { 846 return finalize_rc4((struct stream_state_rc4_st *)dec->lsc_data, 847 out, outsize, outlen); 848 } 849 850 static LE_STATUS stop_rc4(struct stream_state_rc4_st *state) 851 { 852 if (state == NULL) 853 return LE_STS_ERROR; 854 int err; 855 err = rc4_stream_done(&state->libtomcrypt_data); 856 if (err != CRYPT_OK) 857 return LE_STS_ERROR; 858 return LE_STS_SUCCESS; 859 } 860 static LE_STATUS stop_rc4_encryption(LSC_encryptor_t *enc) 861 { 862 return stop_rc4((struct stream_state_rc4_st *)enc->lsc_data); 863 } 864 static LE_STATUS stop_rc4_decryption(LSC_decryptor_t *dec) 865 { 866 return stop_rc4((struct stream_state_rc4_st *)dec->lsc_data); 867 } 868 869 /********************************************************************* 870 * 871 * Common operator functions 872 * 873 *****/ 874 875 /* The unit size of a stream cipher is always 1 */ 876 static LE_STATUS get_stream_encryption_unit_size(LSC_encryptor_t *enc, 877 size_t *size) 878 { 879 if (size == NULL) 880 return LE_STS_FATAL_ERROR; 881 *size = 1; 882 return LE_STS_SUCCESS; 883 } 884 static LE_STATUS get_stream_decryption_unit_size(LSC_decryptor_t *enc, 885 size_t *size) 886 { 887 if (size == NULL) 888 return LE_STS_FATAL_ERROR; 889 *size = 1; 890 return LE_STS_SUCCESS; 891 } 892 893 static LE_STATUS get_stream_encryption_input_size(LSC_encryptor_t *enc, 894 size_t *size) 895 { 896 if (size == NULL) 897 return LE_STS_FATAL_ERROR; 898 *size = 0; 899 return LE_STS_SUCCESS; 900 } 901 static LE_STATUS get_stream_decryption_input_size(LSC_decryptor_t *enc, 902 size_t *size) 903 { 904 if (size == NULL) 905 return LE_STS_FATAL_ERROR; 906 *size = 0; 907 return LE_STS_SUCCESS; 908 } 909 910 static LE_STATUS get_stream_encryption_output_size(LSC_encryptor_t *enc, 911 size_t *size) 912 { 913 if (size == NULL) 914 return LE_STS_FATAL_ERROR; 915 *size = 0; 916 return LE_STS_SUCCESS; 917 } 918 static LE_STATUS get_stream_decryption_output_size(LSC_decryptor_t *enc, 919 size_t *size) 920 { 921 if (size == NULL) 922 return LE_STS_FATAL_ERROR; 923 *size = 0; 924 return LE_STS_SUCCESS; 925 } 926 927 /********************************************************************* 928 * 929 * Implementation tables 930 * 931 *****/ 932 933 #define IMPL_chacha_NAME() "chacha" 934 #define IMPL_rc4_NAME() "rc4" 935 #define IMPL_encryptor_COMMANDS() \ 936 LSC_ENCRYPTOR_TYPE_BASE_COMMANDS(), LSC_ENCRYPTOR_SIZE_COMMANDS(), \ 937 LSC_NR_start_encryption, LSC_NR_perform_encryption, \ 938 LSC_NR_stop_encryption 939 #define IMPL_decryptor_COMMANDS() \ 940 LSC_DECRYPTOR_TYPE_BASE_COMMANDS(), LSC_DECRYPTOR_SIZE_COMMANDS(), \ 941 LSC_NR_start_decryption, LSC_NR_perform_decryption, \ 942 LSC_NR_stop_decryption 943 #define IMPL_CIPHER_OP(T1,T2,N) \ 944 const LSplugin_##T1##_desc_t ltc_##N##_##T1##_desc = { \ 945 NULL, IMPL_##N##_NAME(), NULL, IMPL_##N##_NAME(), \ 946 setup_##N##_##T1##_data, clean_##N##_##T1##_data, \ 947 NULL, set_##N##_##T1##_key, get_##N##_##T1##_key, \ 948 (int[]){ IMPL_##T1##_COMMANDS(), 0 }, \ 949 get_##N##_##T2##_param_data, \ 950 get_gettable_##N##_##T2##_param_desc, \ 951 get_settable_##N##_##T2##_param_desc, \ 952 get_stream_##T2##_unit_size, \ 953 get_stream_##T2##_input_size, \ 954 get_stream_##T2##_output_size, \ 955 NULL, /* No perform once */ \ 956 start_##N##_##T2, \ 957 perform_##N##_##T2, \ 958 finalize_##N##_##T2, \ 959 stop_##N##_##T2, \ 960 }; 961 #define IMPL_KEY_CONSTRUCTOR_OP(N) \ 962 static const LSplugin_key_constructor_desc_t \ 963 ltc_##N##_key_constructor_desc = { \ 964 NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ \ 965 new_key_constructor_data, clean_key_constructor_data, \ 966 set_key_constructor, set_constructor_key, get_constructor_key, \ 967 (int[]){ LSC_KEY_TYPE_CONSTRUCTOR_COMMANDS(), \ 968 LSC_NR_get_settable_key_construction_param_desc, \ 969 LSC_NR_set_key_construction_param, \ 970 LSC_NR_get_gettable_key_construction_param_desc, \ 971 LSC_NR_get_key_construction_param, \ 972 LSC_NR_construct_key, 0 }, \ 973 get_##N##_construction_param_data, \ 974 get_gettable_##N##_construction_param_desc, /* gettable */ \ 975 get_settable_##N##_construction_param_desc, /* settable */ \ 976 construct_key_data \ 977 } 978 #define IMPL_KEY_CIPHER_OP(T1,T2,N) \ 979 static const LSplugin_##T1##_desc_t ltc_##N##_key_##T1##_desc = { \ 980 NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ \ 981 NULL, NULL, \ 982 set_key_##T1, set_##N##_##T1##_key, get_##N##_##T1##_key, \ 983 (int[]){ IMPL_##T1##_COMMANDS(), 0 }, \ 984 NULL, NULL, NULL, \ 985 get_stream_##T2##_unit_size, \ 986 NULL, /* No get_##N##_##T##_input_size */ \ 987 NULL, /* No get_##N##_##T##_output_size */ \ 988 NULL, /* No perform once */ \ 989 start_##N##_##T2, \ 990 perform_##N##_##T2, \ 991 finalize_##N##_##T2, \ 992 stop_##N##_##T2, \ 993 } 994 #define IMPL_CIPHER_KEY(N) \ 995 IMPL_KEY_CONSTRUCTOR_OP(N); \ 996 IMPL_KEY_CIPHER_OP(encryptor,encryption,N); \ 997 IMPL_KEY_CIPHER_OP(decryptor,decryption,N); \ 998 const LSplugin_key_desc_t ltc_##N##_desc = { \ 999 NULL, IMPL_##N##_NAME(), NULL, \ 1000 new_key_data, clean_key_data, \ 1001 (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(), \ 1002 LSC_NR_get_key_size, \ 1003 LSC_NR_get_key_constructor, \ 1004 LSC_NR_get_associated_encryptor, \ 1005 LSC_NR_get_associated_decryptor, 0 }, \ 1006 get_key_size, \ 1007 NULL, /* No key generator */ \ 1008 <c_##N##_key_constructor_desc, \ 1009 NULL, /* No key extractor */ \ 1010 <c_##N##_key_encryptor_desc, \ 1011 <c_##N##_key_decryptor_desc, \ 1012 } 1013 #define IMPL_CIPHER(N) \ 1014 IMPL_CIPHER_OP(encryptor,encryption,N); \ 1015 IMPL_CIPHER_OP(decryptor,decryption,N); \ 1016 IMPL_CIPHER_KEY(N) 1017 1018 IMPL_CIPHER(chacha); 1019 IMPL_CIPHER(rc4);